1 After applying this patch and running configure, you MUST run this
7 --- orig/generator.c 2005-02-15 20:40:53
8 +++ generator.c 2005-02-15 20:43:59
9 @@ -38,6 +38,7 @@ extern int preserve_gid;
10 extern int preserve_times;
11 extern int omit_dir_times;
12 extern int delete_during;
13 +extern int remove_sent_files;
14 extern int update_only;
15 extern int opt_ignore_existing;
17 @@ -524,6 +525,11 @@ static void recv_generator(char *fname,
18 itemize_changes ? "" : safe_fname(fname),
19 safe_fname(file->u.link));
21 + if (remove_sent_files) {
23 + SIVAL(numbuf, 0, ndx);
24 + io_multiplex_write(MSG_SUCCESS, numbuf, 4);
29 --- orig/io.c 2005-02-03 02:04:20
30 +++ io.c 2005-02-15 20:43:59
31 @@ -244,6 +244,14 @@ static void read_msg_fd(void)
32 read_loop(fd, buf, 4);
33 redo_list_add(IVAL(buf,0));
37 + rprintf(FERROR, "invalid message %d:%d\n", tag, len);
38 + exit_cleanup(RERR_STREAMIO);
40 + read_loop(fd, buf, len);
41 + io_multiplex_write(MSG_SUCCESS, buf, len);
46 @@ -677,6 +685,16 @@ static int readfd_unbuffered(int fd, cha
47 read_loop(fd, iobuf_in, remaining);
51 + if (remaining != 4) {
52 + rprintf(FERROR, "invalid multi-message %d:%ld\n",
53 + tag, (long)remaining);
54 + exit_cleanup(RERR_STREAMIO);
56 + read_loop(fd, line, remaining);
57 + successful_send(IVAL(line, 0));
62 if (remaining >= sizeof line) {
63 --- orig/main.c 2005-02-15 19:27:04
64 +++ main.c 2005-02-15 20:43:59
65 @@ -33,12 +33,14 @@ extern int verbose;
66 extern int itemize_changes;
67 extern int blocking_io;
68 extern int delete_before;
69 +extern int remove_sent_files;
70 extern int daemon_over_rsh;
74 extern int log_got_error;
76 +extern int need_messages_from_generator;
77 extern int orig_umask;
78 extern int copy_links;
79 extern int keep_dirlinks;
80 @@ -442,6 +444,12 @@ static void do_server_sender(int f_in, i
81 exit_cleanup(RERR_SYNTAX);
84 + if (am_daemon && lp_read_only(module_id) && remove_sent_files) {
86 + "ERROR: --remove-sent-files cannot be used with a read-only module\n");
87 + exit_cleanup(RERR_SYNTAX);
91 if (!relative_paths && !push_dir(dir)) {
92 rsyserr(FERROR, errno, "push_dir#3 %s failed",
93 @@ -673,6 +681,8 @@ void start_server(int f_in, int f_out, i
96 keep_dirlinks = 0; /* Must be disabled on the sender. */
97 + if (need_messages_from_generator)
98 + io_start_multiplex_in();
100 recv_filter_list(f_in);
101 do_server_sender(f_in, f_out, argc, argv);
102 @@ -750,6 +760,9 @@ int client_run(int f_in, int f_out, pid_
103 exit_cleanup(status);
106 + if (need_messages_from_generator && !read_batch)
107 + io_start_multiplex_out();
112 --- orig/options.c 2005-02-15 19:27:05
113 +++ options.c 2005-02-15 20:44:00
114 @@ -59,6 +59,7 @@ int delete_during = 0;
115 int delete_before = 0;
116 int delete_after = 0;
117 int delete_excluded = 0;
118 +int remove_sent_files = 0;
119 int one_file_system = 0;
120 int protocol_version = PROTOCOL_VERSION;
121 int sparse_files = 0;
122 @@ -93,6 +94,7 @@ int fuzzy_basis = 0;
123 size_t bwlimit_writemax = 0;
124 int only_existing = 0;
125 int opt_ignore_existing = 0;
126 +int need_messages_from_generator = 0;
129 int ignore_errors = 0;
130 @@ -285,6 +287,7 @@ void usage(enum logcode F)
131 rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
132 rprintf(F," --existing only update files that already exist on receiver\n");
133 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
134 + rprintf(F," --remove-sent-files updated/sent files are removed from sending side\n");
135 rprintf(F," --del an alias for --delete-during\n");
136 rprintf(F," --delete delete files that don't exist on the sending side\n");
137 rprintf(F," --delete-before receiver deletes before transfer (default)\n");
138 @@ -368,6 +371,7 @@ static struct poptOption long_options[]
139 {"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
140 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
141 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
142 + {"remove-sent-files",0, POPT_ARG_NONE, &remove_sent_files, 0, 0, 0 },
143 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
144 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
145 {"filter", 'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
146 @@ -961,6 +965,14 @@ int parse_arguments(int *argc, const cha
150 + if (remove_sent_files) {
151 + if (refused_delete) {
152 + create_refuse_error(refused_delete);
155 + need_messages_from_generator = 1;
158 *argv = poptGetArgs(pc);
159 *argc = count_args(*argv);
161 @@ -1393,6 +1405,9 @@ void server_options(char **args,int *arg
162 if (fuzzy_basis && am_sender)
163 args[ac++] = "--fuzzy";
165 + if (remove_sent_files)
166 + args[ac++] = "--remove-sent-files";
171 --- orig/receiver.c 2005-02-15 19:27:05
172 +++ receiver.c 2005-02-15 20:44:00
173 @@ -42,6 +42,7 @@ extern int basis_dir_cnt;
174 extern int make_backups;
175 extern int do_progress;
176 extern int cleanup_got_literal;
177 +extern int remove_sent_files;
178 extern int module_id;
179 extern int ignore_errors;
180 extern int orig_umask;
181 @@ -307,7 +308,7 @@ int recv_files(int f_in, struct file_lis
182 char *fname, fbuf[MAXPATHLEN];
183 char template[MAXPATHLEN];
184 char fnametmp[MAXPATHLEN];
185 - char *fnamecmp, *partialptr;
186 + char *fnamecmp, *partialptr, numbuf[4];
187 char fnamecmpbuf[MAXPATHLEN];
188 uchar *delayed_bits = NULL;
189 struct file_struct *file;
190 @@ -569,7 +570,12 @@ int recv_files(int f_in, struct file_lis
196 + if (remove_sent_files) {
197 + SIVAL(numbuf, 0, i);
198 + send_msg(MSG_SUCCESS, numbuf, 4);
201 int msgtype = csum_length == SUM_LENGTH || read_batch ?
203 if (msgtype == FERROR || verbose) {
204 @@ -593,9 +599,8 @@ int recv_files(int f_in, struct file_lis
207 if (csum_length != SUM_LENGTH) {
210 - send_msg(MSG_REDO, buf, 4);
211 + SIVAL(numbuf, 0, i);
212 + send_msg(MSG_REDO, numbuf, 4);
216 --- orig/rsync.h 2005-02-15 19:27:05
217 +++ rsync.h 2005-02-15 20:44:00
219 #define FLAG_MOUNT_POINT (1<<2) /* sender only */
220 #define FLAG_NO_FUZZY (1<<2) /* generator only */
221 #define FLAG_DEL_HERE (1<<3) /* receiver/generator */
222 +#define FLAG_SENT (1<<7) /* sender only */
224 /* update this if you make incompatible changes */
225 #define PROTOCOL_VERSION 29
226 @@ -144,6 +145,7 @@ enum logcode { FERROR=1, FINFO=2, FLOG=3
227 /* Messages types that are sent over the message channel. The logcode
228 * values must all be present here with identical numbers. */
230 + MSG_SUCCESS=6, /* successfully updated indicated flist index */
231 MSG_DONE=5, /* current phase is done */
232 MSG_REDO=4, /* reprocess indicated flist index */
233 MSG_ERROR=FERROR, MSG_INFO=FINFO, MSG_LOG=FLOG, /* remote logging */
234 --- orig/rsync.yo 2005-02-15 20:42:04
235 +++ rsync.yo 2005-02-15 20:44:02
236 @@ -332,6 +332,7 @@ to the detailed description below for a
237 --rsync-path=PATH specify path to rsync on the remote machine
238 --existing only update files that already exist
239 --ignore-existing ignore files that already exist on receiver
240 + --remove-sent-files sent files/symlinks are removed from sender
241 --del an alias for --delete-during
242 --delete delete files that don't exist on sender
243 --delete-before receiver deletes before transfer (default)
244 @@ -665,6 +666,11 @@ dit(bf(--ignore-existing))
245 This tells rsync not to update files that already exist on
248 +dit(bf(--remove-sent-files)) This tells rsync to remove the source files
249 +on the sending side that are successfully transferred to the receiving
250 +side. Directories and devices are not removed, nor are files/symlinks
251 +whose content was not updated (just changing attributes does not count).
253 dit(bf(--delete)) This tells rsync to delete extraneous files from the
254 receiving side (ones that aren't on the sending side), but only for the
255 directories that are being synchronized. You must have asked rsync to
256 --- orig/sender.c 2005-02-15 19:27:05
257 +++ sender.c 2005-02-15 20:44:02
258 @@ -27,6 +27,7 @@ extern int io_error;
260 extern int am_server;
261 extern int am_daemon;
262 +extern int remove_sent_files;
263 extern int protocol_version;
264 extern int updating_basis_file;
265 extern int make_backups;
266 @@ -95,7 +96,32 @@ static struct sum_struct *receive_sums(i
270 +static struct file_list *the_flist;
272 +void successful_send(int i)
274 + char fname[MAXPATHLEN];
275 + struct file_struct *file;
276 + unsigned int offset;
278 + if (!the_flist || i < 0 || i >= the_flist->count)
281 + file = the_flist->files[i];
282 + /* The generator can tell us about symlinks we didn't send. */
283 + if (!(file->flags & FLAG_SENT) && !S_ISLNK(file->mode))
284 + return; /* We didn't send it -- impossible! */
285 + if (file->dir.root) {
286 + offset = stringjoin(fname, sizeof fname,
287 + file->dir.root, "/", NULL);
290 + f_name_to(file, fname + offset);
291 + if (remove_sent_files && do_unlink(fname) == 0 && verbose) {
292 + rprintf(FINFO, "sender removed %s\n",
293 + safe_fname(fname + offset));
297 void send_files(struct file_list *flist, int f_out, int f_in)
299 @@ -114,6 +140,8 @@ void send_files(struct file_list *flist,
301 rprintf(FINFO, "send_files starting\n");
308 @@ -256,6 +284,9 @@ void send_files(struct file_list *flist,
309 rprintf(FINFO, "sender finished %s\n",
313 + /* Flag that we actually sent this entry. */
314 + file->flags |= FLAG_SENT;
316 make_backups = save_make_backups;