38143e42fb1f30bacae4c56fe5678cc09db8a5b8
[rsync/rsync-patches.git] / remove-sent-files.diff
1 --- io.c        8 May 2004 18:03:43 -0000       1.120
2 +++ io.c        8 May 2004 18:48:44 -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      8 May 2004 18:48:45 -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   6 May 2004 21:08:01 -0000       1.148
65 +++ options.c   8 May 2004 18:48:45 -0000
66 @@ -84,6 +84,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 @@ -91,6 +92,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 @@ -254,6 +256,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 @@ -303,8 +306,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 @@ -323,6 +326,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 @@ -509,6 +513,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), 0);
120                         break;
121 @@ -964,6 +973,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     22 Apr 2004 09:58:09 -0000      1.189
132 +++ proto.h     8 May 2004 18:48:45 -0000
133 @@ -197,6 +197,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  27 Apr 2004 19:51:33 -0000      1.76
142 +++ receiver.c  8 May 2004 18:48:45 -0000
143 @@ -45,6 +45,7 @@ extern int cleanup_got_literal;
144  extern int module_id;
145  extern int ignore_errors;
146  extern int orig_umask;
147 +extern int delete_sent_files;
148  
149  static void delete_one(char *fn, int is_dir)
150  {
151 @@ -292,7 +293,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 @@ -471,16 +472,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.h     8 May 2004 18:48:09 -0000       1.201
186 +++ rsync.h     8 May 2004 18:48:45 -0000
187 @@ -60,6 +60,7 @@
188  #define FLAG_TOP_DIR (1<<0)
189  #define FLAG_HLINK_EOL (1<<1)  /* generator only */
190  #define FLAG_MOUNT_POINT (1<<2)        /* sender only */
191 +#define FLAG_SENT (1<<7)       /* sender only */
192  
193  /* update this if you make incompatible changes */
194  #define PROTOCOL_VERSION 28
195 @@ -120,6 +121,7 @@ enum logcode { FERROR=1, FINFO=2, FLOG=3
196  /* Messages types that are sent over the message channel.  The logcode
197   * values must all be present here with identical numbers. */
198  enum msgcode {
199 +       MSG_SUCCESS=6,  /* successfully updated indicated flist index */
200         MSG_DONE=5,     /* current phase is done */
201         MSG_REDO=4,     /* reprocess indicated flist index */
202         MSG_ERROR=FERROR, MSG_INFO=FINFO, MSG_LOG=FLOG, /* remote logging */
203 --- rsync.yo    7 May 2004 00:18:37 -0000       1.169
204 +++ rsync.yo    8 May 2004 18:48:46 -0000
205 @@ -312,6 +312,7 @@ verb(
206       --delete                delete files that don't exist on sender
207       --delete-excluded       also delete excluded files on receiver
208       --delete-after          receiver deletes after transfer, not before
209 +     --delete-sent-files     updated/sent files are removed from sender
210       --ignore-errors         delete even if there are I/O errors
211       --max-delete=NUM        don't delete more than NUM files
212       --partial               keep partially transferred files
213 @@ -596,6 +597,11 @@ dit(bf(--delete-after)) By default rsync
214  receiving side before transferring files to try to ensure that there is
215  sufficient space on the receiving filesystem. If you want to delete
216  after transferring, use the --delete-after switch. Implies --delete.
217 +
218 +dit(bf(--delete-sent-files)) This tells rsync to remove the source files
219 +on the sending side that are successfully transferred to the receiving
220 +side.  Directories are not removed, nor are files that are identical on
221 +both systems.
222  
223  dit(bf(--ignore-errors)) Tells --delete to go ahead and delete files
224  even when there are I/O errors.
225 --- sender.c    17 Feb 2004 21:57:44 -0000      1.38
226 +++ sender.c    8 May 2004 18:48:46 -0000
227 @@ -27,6 +27,7 @@ extern int dry_run;
228  extern int am_server;
229  extern int am_daemon;
230  extern int protocol_version;
231 +extern int delete_sent_files;
232  
233  
234  /**
235 @@ -104,7 +105,29 @@ static struct sum_struct *receive_sums(i
236         return s;
237  }
238  
239 +static struct file_list *the_flist;
240  
241 +void successful_send(int i)
242 +{
243 +       char fname[MAXPATHLEN];
244 +       struct file_struct *file;
245 +       unsigned int offset;
246 +
247 +       if (!the_flist)
248 +               return;
249 +
250 +       file = the_flist->files[i];
251 +       if (!(file->flags & FLAG_SENT))
252 +               return; /* We didn't send it -- impossible! */
253 +       if (file->basedir) {
254 +               offset = stringjoin(fname, sizeof fname,
255 +                                   file->basedir, "/", NULL);
256 +       } else
257 +               offset = 0;
258 +       f_name_to(file, fname + offset);
259 +       if (delete_sent_files && do_unlink(fname) == 0 && verbose > 0)
260 +               rprintf(FINFO, "sender removed %s\n", fname + offset);
261 +}
262  
263  void send_files(struct file_list *flist, int f_out, int f_in)
264  {
265 @@ -129,6 +152,8 @@ void send_files(struct file_list *flist,
266         if (verbose > 2)
267                 rprintf(FINFO, "send_files starting\n");
268  
269 +       the_flist = flist;
270 +
271         while (1) {
272                 unsigned int offset;
273  
274 @@ -302,6 +327,9 @@ void send_files(struct file_list *flist,
275  
276                 if (verbose > 2)
277                         rprintf(FINFO, "sender finished %s\n", fname);
278 +
279 +               /* Flag that we actually sent this entry. */
280 +               file->flags |= FLAG_SENT;
281         }
282  
283         if (verbose > 2)