Fixed failing hunks.
[rsync/rsync-patches.git] / remove-sent-files.diff
CommitLineData
8a529471
WD
1After applying this patch and running configure, you MUST run this
2command before "make":
3
4 make proto
5
6
1d15f8d9 7--- orig/generator.c 2005-02-20 00:02:23
a43816ef 8+++ generator.c 2005-02-15 21:33:51
1d15f8d9 9@@ -42,6 +42,7 @@ extern int preserve_gid;
766b3582
WD
10 extern int preserve_times;
11 extern int omit_dir_times;
12 extern int delete_during;
6074c90a 13+extern int remove_sent_files;
766b3582
WD
14 extern int update_only;
15 extern int opt_ignore_existing;
16 extern int inplace;
1d15f8d9
WD
17@@ -559,6 +560,11 @@ static void recv_generator(char *fname,
18 rprintf(code, "%s -> %s\n", safe_fname(fname),
4e75164f 19 safe_fname(file->u.link));
766b3582 20 }
a43816ef 21+ if (remove_sent_files && !dry_run) {
766b3582
WD
22+ char numbuf[4];
23+ SIVAL(numbuf, 0, ndx);
24+ io_multiplex_write(MSG_SUCCESS, numbuf, 4);
25+ }
26 }
27 #endif
28 return;
23b2dbfc 29--- orig/io.c 2005-02-19 09:27:48
a43816ef 30+++ io.c 2005-02-15 21:33:51
23b2dbfc
WD
31@@ -256,6 +256,14 @@ static void read_msg_fd(void)
32 read_loop(fd, buf, len);
33 io_multiplex_write(MSG_DELETED, buf, len);
c57f4101
WD
34 break;
35+ case MSG_SUCCESS:
23b2dbfc 36+ if (len != 4 || !am_generator) {
c57f4101
WD
37+ rprintf(FERROR, "invalid message %d:%d\n", tag, len);
38+ exit_cleanup(RERR_STREAMIO);
39+ }
40+ read_loop(fd, buf, len);
41+ io_multiplex_write(MSG_SUCCESS, buf, len);
42+ break;
43 case MSG_INFO:
44 case MSG_ERROR:
45 case MSG_LOG:
23b2dbfc
WD
46@@ -704,6 +712,16 @@ static int readfd_unbuffered(int fd, cha
47 log_delete(line, S_IFREG);
48 remaining = 0;
7b675ff5 49 break;
c57f4101
WD
50+ case MSG_SUCCESS:
51+ if (remaining != 4) {
52+ rprintf(FERROR, "invalid multi-message %d:%ld\n",
53+ tag, (long)remaining);
54+ exit_cleanup(RERR_STREAMIO);
55+ }
56+ read_loop(fd, line, remaining);
57+ successful_send(IVAL(line, 0));
58+ remaining = 0;
7b675ff5 59+ break;
c57f4101
WD
60 case MSG_INFO:
61 case MSG_ERROR:
7b675ff5 62 if (remaining >= sizeof line) {
1d15f8d9
WD
63--- orig/main.c 2005-02-20 00:02:23
64+++ main.c 2005-02-20 00:09:59
65@@ -33,7 +33,9 @@ extern int am_generator;
66 extern int am_daemon;
c5a8a208 67 extern int blocking_io;
8af144e1 68 extern int delete_before;
6074c90a 69+extern int remove_sent_files;
8af144e1 70 extern int daemon_over_rsh;
1d15f8d9 71+extern int need_messages_from_generator;
8af144e1 72 extern int do_stats;
c57f4101
WD
73 extern int log_got_error;
74 extern int module_id;
23b2dbfc 75@@ -441,6 +443,12 @@ static void do_server_sender(int f_in, i
8af144e1
WD
76 exit_cleanup(RERR_SYNTAX);
77 return;
78 }
6074c90a 79+ if (am_daemon && lp_read_only(module_id) && remove_sent_files) {
8af144e1 80+ rprintf(FERROR,
6074c90a 81+ "ERROR: --remove-sent-files cannot be used with a read-only module\n");
8af144e1
WD
82+ exit_cleanup(RERR_SYNTAX);
83+ return;
84+ }
85
86 if (!relative_paths && !push_dir(dir)) {
87 rsyserr(FERROR, errno, "push_dir#3 %s failed",
23b2dbfc 88@@ -672,6 +680,8 @@ void start_server(int f_in, int f_out, i
c57f4101
WD
89
90 if (am_sender) {
7628f156 91 keep_dirlinks = 0; /* Must be disabled on the sender. */
c57f4101 92+ if (need_messages_from_generator)
580f70f0 93+ io_start_multiplex_in();
9be39c35 94
4f9b6a01 95 recv_filter_list(f_in);
c5a8a208 96 do_server_sender(f_in, f_out, argc, argv);
23b2dbfc 97@@ -749,6 +759,9 @@ int client_run(int f_in, int f_out, pid_
c57f4101
WD
98 exit_cleanup(status);
99 }
7b675ff5 100
dc8e6f70 101+ if (need_messages_from_generator && !read_batch)
580f70f0 102+ io_start_multiplex_out();
7b675ff5 103+
fe6407b5 104 if (argc == 0)
786384c2 105 list_only |= 1;
7b675ff5 106
1d15f8d9 107--- orig/options.c 2005-02-20 00:02:23
a43816ef 108+++ options.c 2005-02-15 21:33:52
c5a8a208 109@@ -59,6 +59,7 @@ int delete_during = 0;
786384c2 110 int delete_before = 0;
c57f4101 111 int delete_after = 0;
786384c2 112 int delete_excluded = 0;
6074c90a 113+int remove_sent_files = 0;
786384c2
WD
114 int one_file_system = 0;
115 int protocol_version = PROTOCOL_VERSION;
116 int sparse_files = 0;
3d1facaa 117@@ -93,6 +94,7 @@ int fuzzy_basis = 0;
786384c2 118 size_t bwlimit_writemax = 0;
c57f4101
WD
119 int only_existing = 0;
120 int opt_ignore_existing = 0;
f6c3b300 121+int need_messages_from_generator = 0;
c57f4101 122 int max_delete = 0;
58a9031f 123 OFF_T max_size = 0;
f6c3b300 124 int ignore_errors = 0;
1d15f8d9 125@@ -288,6 +290,7 @@ void usage(enum logcode F)
6074c90a
WD
126 rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
127 rprintf(F," --existing only update files that already exist on receiver\n");
128 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
a43816ef 129+ rprintf(F," --remove-sent-files sent files/symlinks are removed from sending side\n");
6074c90a
WD
130 rprintf(F," --del an alias for --delete-during\n");
131 rprintf(F," --delete delete files that don't exist on the sending side\n");
132 rprintf(F," --delete-before receiver deletes before transfer (default)\n");
1d15f8d9 133@@ -371,6 +374,7 @@ static struct poptOption long_options[]
ac23c334 134 {"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
786384c2
WD
135 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
136 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
6074c90a 137+ {"remove-sent-files",0, POPT_ARG_NONE, &remove_sent_files, 0, 0, 0 },
c57f4101
WD
138 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
139 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
ac23c334 140 {"filter", 'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
1d15f8d9 141@@ -978,6 +982,17 @@ int parse_arguments(int *argc, const cha
27a7053c
WD
142 return 0;
143 }
c57f4101 144
6074c90a 145+ if (remove_sent_files) {
4e75164f
WD
146+ /* We only want to infer this refusal of --remove-sent-files
147+ * via the refusal of "delete", not any of the "delete-FOO"
148+ * options. */
a43816ef 149+ if (refused_delete && am_sender) {
caf2928e
WD
150+ create_refuse_error(refused_delete);
151+ return 0;
152+ }
4945df2c 153+ need_messages_from_generator = 1;
caf2928e 154+ }
c57f4101 155+
4945df2c
WD
156 *argv = poptGetArgs(pc);
157 *argc = count_args(*argv);
158
1d15f8d9 159@@ -1435,6 +1450,9 @@ void server_options(char **args,int *arg
3d1facaa
WD
160 if (fuzzy_basis && am_sender)
161 args[ac++] = "--fuzzy";
7b675ff5 162
6074c90a
WD
163+ if (remove_sent_files)
164+ args[ac++] = "--remove-sent-files";
7b675ff5 165+
c57f4101
WD
166 *argc = ac;
167 return;
7b675ff5 168
1d15f8d9 169--- orig/receiver.c 2005-02-20 00:02:23
a43816ef 170+++ receiver.c 2005-02-15 21:33:52
1d15f8d9 171@@ -45,6 +45,7 @@ extern int basis_dir_cnt;
b76d92e6
WD
172 extern int make_backups;
173 extern int do_progress;
f6c3b300 174 extern int cleanup_got_literal;
6074c90a 175+extern int remove_sent_files;
f6c3b300
WD
176 extern int module_id;
177 extern int ignore_errors;
178 extern int orig_umask;
1d15f8d9 179@@ -312,7 +313,7 @@ int recv_files(int f_in, struct file_lis
c57f4101
WD
180 char *fname, fbuf[MAXPATHLEN];
181 char template[MAXPATHLEN];
182 char fnametmp[MAXPATHLEN];
afbebe13
WD
183- char *fnamecmp, *partialptr;
184+ char *fnamecmp, *partialptr, numbuf[4];
c57f4101 185 char fnamecmpbuf[MAXPATHLEN];
8af144e1 186 uchar *delayed_bits = NULL;
7628f156 187 struct file_struct *file;
1d15f8d9 188@@ -595,7 +596,12 @@ int recv_files(int f_in, struct file_lis
c57f4101
WD
189
190 cleanup_disable();
191
192- if (!recv_ok) {
193+ if (recv_ok) {
6074c90a 194+ if (remove_sent_files) {
c57f4101
WD
195+ SIVAL(numbuf, 0, i);
196+ send_msg(MSG_SUCCESS, numbuf, 4);
197+ }
198+ } else {
8075fb75
WD
199 int msgtype = csum_length == SUM_LENGTH || read_batch ?
200 FERROR : FINFO;
201 if (msgtype == FERROR || verbose) {
1d15f8d9 202@@ -619,9 +625,8 @@ int recv_files(int f_in, struct file_lis
982426b8 203 keptstr, redostr);
8075fb75
WD
204 }
205 if (csum_length != SUM_LENGTH) {
c57f4101 206- char buf[4];
c57f4101
WD
207- SIVAL(buf, 0, i);
208- send_msg(MSG_REDO, buf, 4);
209+ SIVAL(numbuf, 0, i);
210+ send_msg(MSG_REDO, numbuf, 4);
211 }
212 }
213 }
23b2dbfc 214--- orig/rsync.yo 2005-02-19 09:27:49
a43816ef 215+++ rsync.yo 2005-02-15 21:33:55
6074c90a
WD
216@@ -332,6 +332,7 @@ to the detailed description below for a
217 --rsync-path=PATH specify path to rsync on the remote machine
218 --existing only update files that already exist
219 --ignore-existing ignore files that already exist on receiver
220+ --remove-sent-files sent files/symlinks are removed from sender
221 --del an alias for --delete-during
222 --delete delete files that don't exist on sender
223 --delete-before receiver deletes before transfer (default)
23b2dbfc 224@@ -674,6 +675,11 @@ dit(bf(--ignore-existing))
6074c90a
WD
225 This tells rsync not to update files that already exist on
226 the destination.
7b675ff5 227
a43816ef
WD
228+dit(bf(--remove-sent-files)) This tells rsync to remove from the sending
229+side the files and/or symlinks that are newly created or whose content is
230+updated on the receiving side. Directories and devices are not removed,
231+nor are files/symlinks whose attributes are merely changed.
7b675ff5 232+
6074c90a
WD
233 dit(bf(--delete)) This tells rsync to delete extraneous files from the
234 receiving side (ones that aren't on the sending side), but only for the
235 directories that are being synchronized. You must have asked rsync to
1d15f8d9 236--- orig/rsyncd.conf.yo 2005-02-20 00:02:23
a43816ef 237+++ rsyncd.conf.yo 2005-02-15 21:33:55
23b2dbfc 238@@ -459,6 +459,10 @@ quote(tt( refuse options = c delete))
a43816ef
WD
239
240 The reason the above refuses all delete options is that the options imply
241 bf(--delete), and implied options are refused just like explicit options.
242+As an additional safety feature, the refusal of "delete" also refuses
243+bf(remove-sent-files) when the daemon is the sender; if you want the latter
244+without the former, instead refuse "delete-*" -- that refuses all the
245+delete modes without affecting bf(--remove-sent-files).
246
247 When an option is refused, the server prints an error message and exits.
248 To prevent all compression, you can use "dont compress = *" (see below)
1d15f8d9
WD
249--- orig/sender.c 2005-02-20 00:02:23
250+++ sender.c 2005-02-20 00:10:24
251@@ -30,6 +30,7 @@ extern int csum_length;
252 extern struct stats stats;
253 extern int io_error;
f6c3b300 254 extern int protocol_version;
1d15f8d9 255+extern int remove_sent_files;
0b2fb126 256 extern int updating_basis_file;
a6587818 257 extern int make_backups;
1d15f8d9
WD
258 extern int do_progress;
259@@ -99,7 +100,32 @@ static struct sum_struct *receive_sums(i
c57f4101
WD
260 return s;
261 }
262
263+static struct file_list *the_flist;
264
265+void successful_send(int i)
266+{
267+ char fname[MAXPATHLEN];
268+ struct file_struct *file;
269+ unsigned int offset;
270+
4945df2c 271+ if (!the_flist || i < 0 || i >= the_flist->count)
c57f4101
WD
272+ return;
273+
274+ file = the_flist->files[i];
4e75164f 275+ /* The generator might tell us about symlinks we didn't send. */
766b3582 276+ if (!(file->flags & FLAG_SENT) && !S_ISLNK(file->mode))
4e75164f 277+ return;
f9d7f3e9 278+ if (file->dir.root) {
c57f4101 279+ offset = stringjoin(fname, sizeof fname,
f9d7f3e9 280+ file->dir.root, "/", NULL);
c57f4101
WD
281+ } else
282+ offset = 0;
283+ f_name_to(file, fname + offset);
6074c90a
WD
284+ if (remove_sent_files && do_unlink(fname) == 0 && verbose) {
285+ rprintf(FINFO, "sender removed %s\n",
286+ safe_fname(fname + offset));
287+ }
c57f4101
WD
288+}
289
290 void send_files(struct file_list *flist, int f_out, int f_in)
291 {
1d15f8d9 292@@ -120,6 +146,8 @@ void send_files(struct file_list *flist,
c57f4101
WD
293 if (verbose > 2)
294 rprintf(FINFO, "send_files starting\n");
295
296+ the_flist = flist;
297+
298 while (1) {
299 unsigned int offset;
300
1d15f8d9 301@@ -286,6 +314,9 @@ void send_files(struct file_list *flist,
982426b8
WD
302 rprintf(FINFO, "sender finished %s\n",
303 safe_fname(fname));
304 }
c57f4101
WD
305+
306+ /* Flag that we actually sent this entry. */
307+ file->flags |= FLAG_SENT;
308 }
a6587818 309 make_backups = save_make_backups;
c57f4101 310