This is now in CVS.
[rsync/rsync-patches.git] / remove-sent-files.diff
1 --- io.c        16 Jan 2004 16:31:47 -0000      1.119
2 +++ io.c        23 Feb 2004 18:16:25 -0000
3 @@ -222,6 +222,14 @@ static void read_msg_fd(void)
4                 read_loop(fd, buf, 4);
5                 redo_list_add(IVAL(buf,0));
6                 break;
7 +       case MSG_SUCCESS:
8 +               if (len != 4) {
9 +                       rprintf(FERROR, "invalid message %d:%d\n", tag, len);
10 +                       exit_cleanup(RERR_STREAMIO);
11 +               }
12 +               read_loop(fd, buf, len);
13 +               io_multiplex_write(MSG_SUCCESS, buf, len);
14 +               break;
15         case MSG_INFO:
16         case MSG_ERROR:
17         case MSG_LOG:
18 @@ -637,6 +645,16 @@ static int read_unbuffered(int fd, char 
19                         }
20                         read_loop(fd, buffer, remaining);
21                         bufferIdx = 0;
22 +                       break;
23 +               case MSG_SUCCESS:
24 +                       if (remaining != 4) {
25 +                               rprintf(FERROR, "invalid multi-message %d:%ld\n",
26 +                                       tag, (long)remaining);
27 +                               exit_cleanup(RERR_STREAMIO);
28 +                       }
29 +                       read_loop(fd, line, remaining);
30 +                       successful_send(IVAL(line, 0));
31 +                       remaining = 0;
32                         break;
33                 case MSG_INFO:
34                 case MSG_ERROR:
35 --- main.c      10 Feb 2004 03:54:47 -0000      1.192
36 +++ main.c      23 Feb 2004 18:16:25 -0000
37 @@ -42,6 +42,7 @@ extern int list_only;
38  extern int local_server;
39  extern int log_got_error;
40  extern int module_id;
41 +extern int need_messages_from_generator;
42  extern int orig_umask;
43  extern int preserve_hard_links;
44  extern int protocol_version;
45 @@ -567,6 +568,8 @@ void start_server(int f_in, int f_out, i
46                 io_start_multiplex_out(f_out);
47  
48         if (am_sender) {
49 +               if (need_messages_from_generator)
50 +                       io_start_multiplex_in(f_in);
51                 if (!read_batch) {
52                         recv_exclude_list(f_in);
53                         if (cvs_exclude)
54 @@ -632,6 +635,9 @@ int client_run(int f_in, int f_out, pid_
55                 io_flush(FULL_FLUSH);
56                 exit_cleanup(status);
57         }
58 +
59 +       if (need_messages_from_generator)
60 +               io_start_multiplex_out(f_out);
61  
62         if (argc == 0) {
63                 list_only = 1;
64 --- options.c   22 Feb 2004 08:56:43 -0000      1.139
65 +++ options.c   23 Feb 2004 18:16:25 -0000
66 @@ -82,6 +82,7 @@ int copy_unsafe_links = 0;
67  int size_only = 0;
68  int bwlimit = 0;
69  int delete_after = 0;
70 +int delete_sent_files = 0;
71  int only_existing = 0;
72  int opt_ignore_existing = 0;
73  int max_delete = 0;
74 @@ -89,6 +90,7 @@ int ignore_errors = 0;
75  int modify_window = 0;
76  int blocking_io = -1;
77  int checksum_seed = 0;
78 +int need_messages_from_generator = 0;
79  unsigned int block_size = 0;
80  
81  
82 @@ -252,6 +254,7 @@ void usage(enum logcode F)
83    rprintf(F,"     --delete                delete files that don't exist on the sending side\n");
84    rprintf(F,"     --delete-excluded       also delete excluded files on the receiving side\n");
85    rprintf(F,"     --delete-after          receiver deletes after transferring, not before\n");
86 +  rprintf(F,"     --delete-sent-files     updated/sent files are removed from sending side\n");
87    rprintf(F,"     --ignore-errors         delete even if there are I/O errors\n");
88    rprintf(F,"     --max-delete=NUM        don't delete more than NUM files\n");
89    rprintf(F,"     --partial               keep partially transferred files\n");
90 @@ -301,8 +304,8 @@ void usage(enum logcode F)
91  }
92  
93  enum {OPT_VERSION = 1000, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
94 -      OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
95 -      OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
96 +      OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_DELETE_SENT_FILES,
97 +      OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_LINK_DEST, OPT_MODIFY_WINDOW,
98        OPT_READ_BATCH, OPT_WRITE_BATCH,
99        OPT_REFUSED_BASE = 9000};
100  
101 @@ -321,6 +324,7 @@ static struct poptOption long_options[] 
102    {"ignore-existing",  0,  POPT_ARG_NONE,   &opt_ignore_existing, 0, 0, 0 },
103    {"delete-after",     0,  POPT_ARG_NONE,   0,              OPT_DELETE_AFTER, 0, 0 },
104    {"delete-excluded",  0,  POPT_ARG_NONE,   0,              OPT_DELETE_EXCLUDED, 0, 0 },
105 +  {"delete-sent-files",0,  POPT_ARG_NONE,   0,              OPT_DELETE_SENT_FILES, 0, 0 },
106    {"force",            0,  POPT_ARG_NONE,   &force_delete, 0, 0, 0 },
107    {"numeric-ids",      0,  POPT_ARG_NONE,   &numeric_ids, 0, 0, 0 },
108    {"exclude",          0,  POPT_ARG_STRING, 0,              OPT_EXCLUDE, 0, 0 },
109 @@ -506,6 +510,11 @@ int parse_arguments(int *argc, const cha
110                         delete_mode = 1;
111                         break;
112  
113 +               case OPT_DELETE_SENT_FILES:
114 +                       delete_sent_files = 1;
115 +                       need_messages_from_generator = 1;
116 +                       break;
117 +
118                 case OPT_EXCLUDE:
119                         add_exclude(&exclude_list, poptGetOptArg(pc),
120                                     ADD_EXCLUDE);
121 @@ -945,6 +954,9 @@ void server_options(char **args,int *arg
122                         args[ac++] = "--from0";
123                 }
124         }
125 +
126 +       if (delete_sent_files)
127 +               args[ac++] = "--delete-sent-files";
128  
129         *argc = ac;
130         return;
131 --- proto.h     17 Feb 2004 23:13:06 -0000      1.184
132 +++ proto.h     23 Feb 2004 18:16:25 -0000
133 @@ -199,6 +199,7 @@ void sig_int(void);
134  void finish_transfer(char *fname, char *fnametmp, struct file_struct *file);
135  const char *who_am_i(void);
136  void read_sum_head(int f, struct sum_struct *sum);
137 +void successful_send(int i);
138  void send_files(struct file_list *flist, int f_out, int f_in);
139  int try_bind_local(int s, int ai_family, int ai_socktype,
140                    const char *bind_address);
141 --- receiver.c  10 Feb 2004 17:28:59 -0000      1.72
142 +++ receiver.c  23 Feb 2004 18:16:26 -0000
143 @@ -39,6 +39,7 @@ extern char *backup_dir;
144  extern char *backup_suffix;
145  extern int backup_suffix_len;
146  extern int cleanup_got_literal;
147 +extern int delete_sent_files;
148  
149  static void delete_one(char *fn, int is_dir)
150  {
151 @@ -288,7 +289,7 @@ int recv_files(int f_in,struct file_list
152         char *fname, fbuf[MAXPATHLEN];
153         char template[MAXPATHLEN];
154         char fnametmp[MAXPATHLEN];
155 -       char *fnamecmp;
156 +       char *fnamecmp, numbuf[4];
157         char fnamecmpbuf[MAXPATHLEN];
158         struct map_struct *mapbuf;
159         int i;
160 @@ -467,16 +468,20 @@ int recv_files(int f_in,struct file_list
161  
162                 cleanup_disable();
163  
164 -               if (!recv_ok) {
165 +               if (recv_ok) {
166 +                       if (delete_sent_files) {
167 +                               SIVAL(numbuf, 0, i);
168 +                               send_msg(MSG_SUCCESS, numbuf, 4);
169 +                       }
170 +               } else {
171                         if (csum_length == SUM_LENGTH) {
172                                 rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
173                                         full_fname(fname));
174                         } else {
175 -                               char buf[4];
176                                 if (verbose > 1)
177                                         rprintf(FINFO,"redoing %s(%d)\n",fname,i);
178 -                               SIVAL(buf, 0, i);
179 -                               send_msg(MSG_REDO, buf, 4);
180 +                               SIVAL(numbuf, 0, i);
181 +                               send_msg(MSG_REDO, numbuf, 4);
182                         }
183                 }
184         }
185 --- rsync.1     2 Feb 2004 18:23:09 -0000       1.163
186 +++ rsync.1     23 Feb 2004 18:16:26 -0000
187 @@ -349,6 +349,7 @@ to the detailed description below for a 
188       --delete                delete files that don\&'t exist on sender
189       --delete-excluded       also delete excluded files on receiver
190       --delete-after          receiver deletes after transfer, not before
191 +     --delete-sent-files     updated/sent files are removed from sender
192       --ignore-errors         delete even if there are I/O errors
193       --max-delete=NUM        don\&'t delete more than NUM files
194       --partial               keep partially transferred files
195 @@ -673,6 +674,12 @@ By default rsync does file deletions on 
196  receiving side before transferring files to try to ensure that there is
197  sufficient space on the receiving filesystem\&. If you want to delete
198  after transferring, use the --delete-after switch\&. Implies --delete\&.
199 +.IP 
200 +.IP "\fB--delete-sent-files\fP" 
201 +This tells rsync to remove the source files
202 +on the sending side that are successfully transferred to the receiving
203 +side\&.  Directories are not removed, nor are files that are identical on
204 +both systems\&.
205  .IP 
206  .IP "\fB--ignore-errors\fP" 
207  Tells --delete to go ahead and delete files
208 --- rsync.h     11 Feb 2004 08:01:21 -0000      1.186
209 +++ rsync.h     23 Feb 2004 18:16:26 -0000
210 @@ -59,6 +59,7 @@
211  #define FLAG_TOP_DIR (1<<0)
212  #define FLAG_HLINK_EOL (1<<1)  /* generator only */
213  #define FLAG_MOUNT_POINT (1<<2)        /* sender only */
214 +#define FLAG_SENT (1<<7)       /* sender only */
215  
216  /* update this if you make incompatible changes */
217  #define PROTOCOL_VERSION 28
218 @@ -124,6 +125,7 @@ enum msgcode {
219         MSG_ERROR=FERROR, MSG_INFO=FINFO, MSG_LOG=FLOG, /* remote logging */
220         MSG_REDO=4,     /* reprocess indicated flist index */
221         MSG_DONE=5,     /* current phase is done */
222 +       MSG_SUCCESS=6,  /* successfully updated indicated flist index */
223  };
224  
225  #include "errcode.h"
226 --- rsync.yo    2 Feb 2004 18:23:09 -0000       1.147
227 +++ rsync.yo    23 Feb 2004 18:16:27 -0000
228 @@ -312,6 +312,7 @@ verb(
229       --delete                delete files that don't exist on sender
230       --delete-excluded       also delete excluded files on receiver
231       --delete-after          receiver deletes after transfer, not before
232 +     --delete-sent-files     updated/sent files are removed from sender
233       --ignore-errors         delete even if there are I/O errors
234       --max-delete=NUM        don't delete more than NUM files
235       --partial               keep partially transferred files
236 @@ -585,6 +586,11 @@ dit(bf(--delete-after)) By default rsync
237  receiving side before transferring files to try to ensure that there is
238  sufficient space on the receiving filesystem. If you want to delete
239  after transferring, use the --delete-after switch. Implies --delete.
240 +
241 +dit(bf(--delete-sent-files)) This tells rsync to remove the source files
242 +on the sending side that are successfully transferred to the receiving
243 +side.  Directories are not removed, nor are files that are identical on
244 +both systems.
245  
246  dit(bf(--ignore-errors)) Tells --delete to go ahead and delete files
247  even when there are I/O errors.
248 --- sender.c    17 Feb 2004 21:57:44 -0000      1.38
249 +++ sender.c    23 Feb 2004 18:16:27 -0000
250 @@ -27,6 +27,7 @@ extern int dry_run;
251  extern int am_server;
252  extern int am_daemon;
253  extern int protocol_version;
254 +extern int delete_sent_files;
255  
256  
257  /**
258 @@ -104,7 +105,29 @@ static struct sum_struct *receive_sums(i
259         return s;
260  }
261  
262 +static struct file_list *the_flist;
263  
264 +void successful_send(int i)
265 +{
266 +       char fname[MAXPATHLEN];
267 +       struct file_struct *file;
268 +       unsigned int offset;
269 +
270 +       if (!the_flist)
271 +               return;
272 +
273 +       file = the_flist->files[i];
274 +       if (!(file->flags & FLAG_SENT))
275 +               return; /* We didn't send it -- impossible! */
276 +       if (file->basedir) {
277 +               offset = stringjoin(fname, sizeof fname,
278 +                                   file->basedir, "/", NULL);
279 +       } else
280 +               offset = 0;
281 +       f_name_to(file, fname + offset);
282 +       if (delete_sent_files && do_unlink(fname) == 0 && verbose > 0)
283 +               rprintf(FINFO, "sender removed %s\n", fname + offset);
284 +}
285  
286  void send_files(struct file_list *flist, int f_out, int f_in)
287  {
288 @@ -129,6 +152,8 @@ void send_files(struct file_list *flist,
289         if (verbose > 2)
290                 rprintf(FINFO, "send_files starting\n");
291  
292 +       the_flist = flist;
293 +
294         while (1) {
295                 unsigned int offset;
296  
297 @@ -302,6 +327,9 @@ void send_files(struct file_list *flist,
298  
299                 if (verbose > 2)
300                         rprintf(FINFO, "sender finished %s\n", fname);
301 +
302 +               /* Flag that we actually sent this entry. */
303 +               file->flags |= FLAG_SENT;
304         }
305  
306         if (verbose > 2)