Browse Source

-n --no-delete option

Enrico Tassi 8 years ago
parent
commit
f8b3929a95
12 changed files with 101 additions and 10 deletions
  1. 8
    2
      mddiff.1.txt
  2. 16
    2
      mddiff.c
  3. 4
    0
      smd-common
  4. 11
    0
      smd-config.5.txt
  5. 1
    1
      smd-pull
  6. 3
    1
      smd-pull.1.txt
  7. 1
    1
      smd-push
  8. 3
    1
      smd-push.1.txt
  9. 8
    2
      smd-server
  10. 1
    0
      smd-server.1.txt
  11. 29
    0
      tests.d/mddiff/09-no-delete
  12. 16
    0
      tests.d/pull-push/25-pull-nodel

+ 8
- 2
mddiff.1.txt View File

@@ -2,8 +2,8 @@ NAME
2 2
   mddiff - computes diff for maildirs
3 3
 SYNOPSIS
4 4
   mddiff [--max-mailno mno] [--db-file dbf] [-l|--list] [-s|--symlink]
5
-         [--exclude globexpr] [-v|--verbose] [-d|--dry-run] [--help]
6
-         [--sha1sum] paths
5
+         [--exclude globexpr] [-v|--verbose] [-d|--dry-run] 
6
+         [-n|--no-delete] [--help] [--sha1sum] paths
7 7
 DESCRIPTION
8 8
   mddiff computes the delta from an old status of a maildir (previously
9 9
   recorded in a support file, called db file) and the current status, 
@@ -54,6 +54,11 @@ DESCRIPTION
54 54
   entered. If the match is successful, the directory and all its 
55 55
   subedirectories are skipped.
56 56
 
57
+  The --no-delete option tells mddiff to not output a DELETE action for
58
+  files that disappear. Note that a DELETE action is anyway generated for
59
+  files that are moved (i.e. move is COPY plus DELETE). The result is that
60
+  deletions are not propagated to the other endpoint.
61
+
57 62
 OPTIONS
58 63
   --max-mailno mno      Estimation of max mail message number (defaults to the
59 64
                         number of messages in the db-file + 1000 or 500000
@@ -69,6 +74,7 @@ OPTIONS
69 74
   -s --symlink          Create symlinks for paths read on the input fifo
70 75
   -v --verbose          Increase program verbosity (printed on stderr)
71 76
   -d --dry-run          Do not generate a new db-file
77
+  -n --no-delete        Do not track deleted files
72 78
   --help                This help screen
73 79
 
74 80
 NOTES

+ 16
- 2
mddiff.c View File

@@ -138,6 +138,8 @@ STATIC char* txtURL(const char* string, char* outbuff) {
138 138
 	return outbuff;
139 139
 }
140 140
 
141
+#define PROMOTE(what,from,to) ((what) = ((what) == (from)) ? (to) : (from))
142
+
141 143
 // flags used to mark struct mail so that at the end of the scanning 
142 144
 // we output commands lookig that flag
143 145
 enum sight {
@@ -188,6 +190,7 @@ STATIC int only_mkdirp;
188 190
 STATIC int only_mkfifo;
189 191
 STATIC int n_excludes;
190 192
 STATIC char **excludes;
193
+STATIC int no_delete;
191 194
 
192 195
 // ============================ helpers =====================================
193 196
 
@@ -623,10 +626,12 @@ STATIC void analyze_file(const char* dir,const char* file) {
623 626
 	if (bodyalias != 0) {
624 627
 		if (hsha_equal(GPTR(bodyalias), GPTR(m))) {
625 628
 			COMMAND_COPY(bodyalias,m);
629
+			PROMOTE(mail(bodyalias)->seen, NOT_SEEN, MOVED);
626 630
 			mail(m)->seen=SEEN;
627 631
 			return;
628 632
 		} else {
629 633
 			COMMAND_COPYBODY(bodyalias,m);
634
+			PROMOTE(mail(bodyalias)->seen, NOT_SEEN, MOVED);
630 635
 			mail(m)->seen=SEEN;
631 636
 			return;
632 637
 		}
@@ -727,7 +732,11 @@ STATIC void generate_deletions(){
727 732
 	size_t m;
728 733
 
729 734
 	for(m=1; m < mailno; m++){
730
-		if (mail(m)->seen == NOT_SEEN) 
735
+		if (!no_delete && (mail(m)->seen == NOT_SEEN || mail(m)->seen == MOVED))
736
+			// normally moved or removed mails are deleted
737
+			COMMAND_DELETE(m);
738
+		else if (no_delete && mail(m)->seen == MOVED)
739
+			// if --no-delete only moved mails should be deleted
731 740
 			COMMAND_DELETE(m);
732 741
 		else 
733 742
 			VERBOSE(seen,"STATUS OF %s %s %s IS %s\n",
@@ -841,6 +850,7 @@ STATIC struct option long_options[] = {
841 850
 	{"symlink"   , no_argument      , NULL, 's'},
842 851
 	{"verbose"   , no_argument      , NULL, 'v'},
843 852
 	{"dry-run"   , no_argument      , NULL, 'd'},
853
+	{"no-delete" , no_argument      , NULL, 'n'},
844 854
 	{"help"      , no_argument      , NULL, 'h'},
845 855
 	{NULL        , no_argument      , NULL, 0},
846 856
 };
@@ -866,6 +876,7 @@ STATIC const char* long_options_doc[] = {
866 876
 			"Symbolic Link generation mode (short -s)",
867 877
 			"Increase program verbosity (printed on stderr, short -v)",
868 878
 			"Do not generate a new db file (short -d)",
879
+			"Do not track deletions (short -n)",
869 880
 			"This help screen",
870 881
 			NULL
871 882
 };
@@ -919,7 +930,7 @@ int main(int argc, char *argv[]) {
919 930
 	g_assert(MAIL(GPTR(1)) == 1);
920 931
 
921 932
 	for(;;) {
922
-		c = getopt_long(argc, argv, "vhdls", long_options, &option_index);
933
+		c = getopt_long(argc, argv, "vhndls", long_options, &option_index);
923 934
 		if (c == -1) break; // no more args
924 935
 		switch (c) {
925 936
 			case OPT_MAX_MAILNO:
@@ -948,6 +959,9 @@ int main(int argc, char *argv[]) {
948 959
 			case 'd':
949 960
 				dry_run = 1;
950 961
 			break;
962
+			case 'n':
963
+				no_delete = 1;
964
+			break;
951 965
 			case 'l':
952 966
 				only_list_subfolders = 1;
953 967
 			break;

+ 4
- 0
smd-common View File

@@ -83,6 +83,7 @@ init() {
83 83
 	REMOTEEXCLUDE=
84 84
 	LOCALEXCLUDE=
85 85
 	SMDCLIENTOPTS=
86
+	SMDSERVEROPTS=
86 87
 
87 88
 	# default values for the configuration file
88 89
 	DEBUG=false
@@ -246,6 +247,9 @@ parse_args() {
246 247
 				VERBOSE=1
247 248
 				SHOWTAGS=1
248 249
 			;;
250
+			-n|--no-delete)
251
+				SMDSERVEROPTS="$SMDSERVEROPTS -n"
252
+			;;
249 253
 			-*)
250 254
 				cat <<-EOT
251 255
 				usage: `basename $0` [options] [endpoint]

+ 11
- 0
smd-config.5.txt View File

@@ -116,6 +116,17 @@ LOCAL SYNCHRONIZATION
116 116
 
117 117
   SMDCLIENTOPTS=-l
118 118
 
119
+DELETIONS
120
+
121
+  In some cases, usually unidirectional synchronizations, one may want
122
+  to not propagate deletions. E.g. one keeps a slim working mailbox but
123
+  pushes to a backup mailbox to save every email. For that scenario
124
+  smd-pull and smd-push accept a -n, --no-delete, option. 
125
+  To avoid specifying this option every time one can put it in the
126
+  configuration file:
127
+
128
+  SMDSERVEROPTS=-n
129
+
119 130
 FILES
120 131
 
121 132
   ~/.smd/config.*

+ 1
- 1
smd-pull View File

@@ -57,7 +57,7 @@ CLIENT=$!
57 57
 atexit_kill $CLIENT
58 58
 
59 59
 EXITCODE=0
60
-($SSH $SERVERNAME $REMOTESMDSERVER $REMOTEEXCLUDE $CHILDSARGS $CLIENTNAME $MAILBOX_REMOTE < $LtS 2> $SL) > $StL  || EXITCODE=1
60
+($SSH $SERVERNAME $REMOTESMDSERVER $REMOTEEXCLUDE $CHILDSARGS $SMDSERVEROPTS $CLIENTNAME $MAILBOX_REMOTE < $LtS 2> $SL) > $StL  || EXITCODE=1
61 61
 
62 62
 wait $CLIENT || EXITCODE=1 
63 63
 wait $REPORTER || EXITCODE=1 

+ 3
- 1
smd-pull.1.txt View File

@@ -2,7 +2,8 @@ NAME
2 2
   smd-pull - syncs the local mail dir letting the remote one untouched
3 3
 
4 4
 SYNOPSIS
5
-  smd-pull [-d|--dry-run] [-v|--verbose] [-s|--show-tags] [-t|--template-only] [endpoint]
5
+  smd-pull [-d|--dry-run] [-v|--verbose] [-s|--show-tags] [-t|--template-only] 
6
+           [-n|--no-delete] [endpoint]
6 7
 
7 8
 DESCRIPTION
8 9
   smd-pull performs in the local maildir all the changes that
@@ -16,6 +17,7 @@ OPTIONS
16 17
   -v --verbose        Verbose output
17 18
   -s --show-tags      Machine readable output
18 19
   -d --dry-run        Do not perform any action for real
20
+  -n --no-delete      Do not propagate deletions
19 21
   -t --template-only  Just create a template configuration file if none
20 22
   endpoint            Is the suffix for the name of the configuration file to 
21 23
 		      use. If it is omitted, the configuration file

+ 1
- 1
smd-push View File

@@ -54,7 +54,7 @@ atexit_kill $REPORTER
54 54
 
55 55
 setup_workarea
56 56
 
57
-(cd $WORKAREA; $SMDSERVER $CHILDSARGS $CLIENTNAME $MAILBOX_REMOTE < $LtC 2>> $CL) > $CtL &
57
+(cd $WORKAREA; $SMDSERVER $CHILDSARGS $SMDSERVEROPTS $CLIENTNAME $MAILBOX_REMOTE < $LtC 2>> $CL) > $CtL &
58 58
 CLIENT=$!
59 59
 atexit_kill $CLIENT
60 60
 

+ 3
- 1
smd-push.1.txt View File

@@ -2,7 +2,8 @@ NAME
2 2
   smd-push - syncs the remote mail dir letting the local one untouched
3 3
 
4 4
 SYNOPSIS
5
-  smd-push [-d|--dry-run] [-v|--verbose] [-s|--show-tags] [-t|--template-only] [endpoint]
5
+  smd-push [-d|--dry-run] [-v|--verbose] [-s|--show-tags] [-t|--template-only]
6
+           [-n|--no-delete] [endpoint]
6 7
 
7 8
 DESCRIPTION
8 9
   smd-push performs in the remote maildir all the changes that
@@ -16,6 +17,7 @@ OPTIONS
16 17
   -v --verbose        Verbose output
17 18
   -s --show-tags      Machine readable output
18 19
   -d --dry-run        Do not perform any action for real
20
+  -n --no-delete      Do not propagate deletions
19 21
   -t --template-only  Just create a template configuration file if none
20 22
   endpoint            Is the suffix for the name of the configuration file to
21 23
                       use. If it is omitted, the configuration file 

+ 8
- 2
smd-server View File

@@ -18,8 +18,9 @@ function main()
18 18
 
19 19
 	-- argument parsing
20 20
 	local exclude = {}
21
+	local no_delete = false
21 22
 	local usage = "Usage: "..arg[0]:match('[^/]+$')..
22
-		" [-vd] endpointname mailboxes...\n"
23
+		" [-vdn] endpointname mailboxes...\n"
23 24
 	while #arg > 2 do
24 25
 		if arg[1] == '-v' or arg[1] == '--verbose' then
25 26
 			set_verbose(true)
@@ -27,6 +28,9 @@ function main()
27 28
 		elseif arg[1] == '-d' or arg[1] == '--dry-run' then
28 29
 			set_dry_run(true)
29 30
 			table.remove(arg,1)
31
+		elseif arg[1] == '-n' or arg[1] == '--no-delete' then
32
+			no_delete = true
33
+			table.remove(arg,1)
30 34
 		elseif arg[1] == '--exclude' then
31 35
 			exclude[#exclude + 1] = arg[1]
32 36
 			exclude[#exclude + 1] = arg[2]
@@ -52,6 +56,8 @@ function main()
52 56
 
53 57
 	local database_opt = '--db-file '.. dbfile
54 58
 	local mailbox_opt = table.concat(arg,' ')
59
+	local no_delete_opt = ''
60
+	if no_delete then no_delete_opt = '-n' end
55 61
 	local dry_opt = ''
56 62
 	if dry_run() then dry_opt = '-d' end
57 63
 	local exclude_opt = table.concat(exclude, ' ')
@@ -61,7 +67,7 @@ function main()
61 67
 	
62 68
 	-- run mddiff and send the output to the client
63 69
 	local mddiff = MDDIFF..' '..dry_opt..' '..database_opt..' '..
64
-		exclude_opt..' '..mailbox_opt
70
+		exclude_opt..' '..no_delete_opt..' '..mailbox_opt
65 71
 	local r = io.popen(mddiff,"r")
66 72
 	local sent = 0
67 73
 	while true do

+ 1
- 0
smd-server.1.txt View File

@@ -18,6 +18,7 @@ DESCRIPTION
18 18
 OPTIONS
19 19
   -v --verbose    Increase program verbosity (printed on stderr)
20 20
   -d --dry-run    Do not perform any action for real
21
+  -n --no-delete  Do not track deleted files
21 22
   --exclude glob  Exclude paths matching glob
22 23
 
23 24
 NOTES

+ 29
- 0
tests.d/mddiff/09-no-delete View File

@@ -0,0 +1,29 @@
1
+#!/bin/sh
2
+
3
+mdiff Mail
4
+assert $? 0 "mdiff failed"
5
+
6
+mv db.txt.new db.txt
7
+mv db.txt.mtime.new db.txt.mtime
8
+
9
+ls Mail/cur | head -n 2 > mails
10
+exec 7<mails
11
+read MAIL1 <&7
12
+read MAIL2 <&7
13
+exec 7<&-
14
+
15
+rm Mail/cur/$MAIL1
16
+mv Mail/cur/$MAIL2 Mail/cur/foo
17
+
18
+mdiff Mail
19
+N=`cat log.mddiff | wc -l`
20
+assert $N 3 "too many commands: $N"
21
+N=`cat log.mddiff | grep ^DELETE | wc -l`
22
+assert $N 2 "too few DELETE commands: $N"
23
+N=`cat log.mddiff | grep ^COPY | wc -l`
24
+assert $N 1 "not 1 COPY command: $N"
25
+mdiff -n Mail
26
+N=`cat log.mddiff | grep ^DELETE | wc -l`
27
+assert $N 1 "too many DELETE commands: $N"
28
+N=`cat log.mddiff | grep ^DELETE | grep $MAIL1 | wc -l`
29
+assert $N 0 "deletes aven if -n"

+ 16
- 0
tests.d/pull-push/25-pull-nodel View File

@@ -0,0 +1,16 @@
1
+#!/bin/sh
2
+
3
+mpull -t
4
+assert $? 0 "failed mpull -t"
5
+echo DEBUG=true >> target/.smd/config.default
6
+
7
+mpull
8
+assert $? 0 "failed mpull"
9
+test_eq Mail target/Mail 
10
+
11
+cp -r target/Mail target/Mail.bak
12
+rm Mail/cur/`ls Mail/cur|head -n1`
13
+mpull -n
14
+assert $? 0 "failed mpull after deletion"
15
+test_eq target/Mail target/Mail.bak 
16
+

Loading…
Cancel
Save