Got rid of fuzz.
[rsync/rsync-patches.git] / g2r-basis-filename.diff
CommitLineData
77945073
WD
1Added a pipe from the generator to the receiver that communicates
2what basis file we used to generate the file data (if it was not
3the default name). This optimizes away the basis-file search in
4the receiver and makes future options that do more basis-file
5searching more efficient (such as the --fuzzy option and the
6support for multiple --compare-dest options).
7
8You must run "make proto" before compiling.
9
d5753a22 10--- orig/generator.c 2004-08-03 15:41:32
65021ef6 11+++ generator.c 2004-07-30 07:18:03
d5753a22 12@@ -249,13 +249,13 @@ static void generate_and_send_sums(int f
77945073
WD
13 * out. It might be wrong.
14 */
15 static void recv_generator(char *fname, struct file_struct *file, int i,
16- int f_out)
d6e18487 17+ int f_out, int f_out_name)
77945073 18 {
0bd6d59f
WD
19- int fd;
20+ int fd = -1;
77945073 21 STRUCT_STAT st;
b952a177 22 int statret, stat_errno;
65021ef6
WD
23- char *fnamecmp;
24- char fnamecmpbuf[MAXPATHLEN];
25+ char *fnamecmp, fnamecmpbuf[MAXPATHLEN];
26+ uchar fnamecmp_type;
27
28 if (list_only)
29 return;
d5753a22 30@@ -411,6 +411,7 @@ static void recv_generator(char *fname,
65021ef6
WD
31 }
32
33 fnamecmp = fname;
34+ fnamecmp_type = G2R_FNAME;
35
36 if (statret == -1 && compare_dest != NULL) {
37 /* try the file at compare_dest instead */
d5753a22 38@@ -427,10 +428,14 @@ static void recv_generator(char *fname,
b952a177
WD
39 safe_fname(fname));
40 }
41 fnamecmp = fnamecmpbuf;
65021ef6
WD
42+ fnamecmp_type = 0;
43 }
b952a177 44 } else
77945073 45 #endif
65021ef6 46+ {
b952a177 47 fnamecmp = fnamecmpbuf;
65021ef6
WD
48+ fnamecmp_type = 0;
49+ }
b952a177 50 statret = 0;
65021ef6
WD
51 }
52 }
d5753a22 53@@ -445,11 +450,9 @@ static void recv_generator(char *fname,
77945073
WD
54 if (statret == -1) {
55 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
56 return;
b952a177 57- if (stat_errno == ENOENT) {
0bd6d59f 58- write_int(f_out,i);
2f5fa77e 59- if (!dry_run && !read_batch)
0bd6d59f
WD
60- write_sum_head(f_out, NULL);
61- } else if (verbose > 1) {
b952a177 62+ if (stat_errno == ENOENT)
d24c084d 63+ goto notify_others;
0bd6d59f 64+ if (verbose > 1) {
b952a177
WD
65 rsyserr(FERROR, stat_errno,
66 "recv_generator: failed to stat %s",
0bd6d59f 67 full_fname(fname));
d5753a22 68@@ -457,13 +460,13 @@ static void recv_generator(char *fname,
b952a177 69 return;
77945073
WD
70 }
71
72- if (opt_ignore_existing && fnamecmp == fname) {
65021ef6 73+ if (opt_ignore_existing && fnamecmp_type == G2R_FNAME) {
77945073 74 if (verbose > 1)
b952a177 75 rprintf(FINFO, "%s exists\n", safe_fname(fname));
77945073
WD
76 return;
77 }
78
79- if (update_only && fnamecmp == fname
65021ef6 80+ if (update_only && fnamecmp_type == G2R_FNAME
77945073
WD
81 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
82 if (verbose > 1)
b952a177 83 rprintf(FINFO, "%s is newer\n", safe_fname(fname));
d5753a22 84@@ -471,21 +474,17 @@ static void recv_generator(char *fname,
77945073
WD
85 }
86
ec8473c6 87 if (skip_file(fnamecmp, file, &st)) {
77945073 88- if (fnamecmp == fname)
65021ef6 89+ if (fnamecmp_type == G2R_FNAME)
77945073
WD
90 set_perms(fname, file, &st, PERMS_REPORT);
91 return;
92 }
93
2f5fa77e 94- if (dry_run || read_batch) {
0bd6d59f
WD
95- write_int(f_out,i);
96- return;
97- }
98-
99- if (whole_file > 0) {
100- write_int(f_out,i);
101- write_sum_head(f_out, NULL);
102- return;
103+ if (dry_run || whole_file) {
104+ statret = -1;
d24c084d 105+ goto notify_others;
77945073 106 }
0bd6d59f 107+ if (read_batch)
d24c084d 108+ goto notify_others;
77945073 109
b952a177
WD
110 if (partial_dir) {
111 STRUCT_STAT st2;
d5753a22 112@@ -494,6 +493,7 @@ static void recv_generator(char *fname,
65021ef6
WD
113 && S_ISREG(st2.st_mode)) {
114 st = st2;
115 fnamecmp = partialptr;
116+ fnamecmp_type = G2R_PARTIAL_DIR;
117 }
118 }
119
d5753a22 120@@ -506,9 +506,8 @@ static void recv_generator(char *fname,
77945073
WD
121 /* pretend the file didn't exist */
122 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
123 return;
0bd6d59f
WD
124- write_int(f_out,i);
125- write_sum_head(f_out, NULL);
126- return;
127+ statret = -1;
d24c084d 128+ goto notify_others;
0bd6d59f
WD
129 }
130
0bd6d59f 131 if (verbose > 3) {
d5753a22 132@@ -519,14 +518,28 @@ static void recv_generator(char *fname,
77945073
WD
133 if (verbose > 2)
134 rprintf(FINFO, "generating and sending sums for %d\n", i);
135
0bd6d59f 136- write_int(f_out,i);
dc3ae351 137- generate_and_send_sums(fd, st.st_size, f_out);
d24c084d 138+notify_others:
d6e18487 139+ if (f_out_name >= 0) {
65021ef6 140+ write_byte(f_out_name, fnamecmp_type);
d6e18487 141+ io_flush(NORMAL_FLUSH); /* XXX make this more efficient! */
0b32df42 142+ }
0bd6d59f
WD
143+
144+ write_int(f_out, i);
2f5fa77e
WD
145
146- close(fd);
65021ef6
WD
147+ if (dry_run || read_batch)
148+ return;
149+
0bd6d59f 150+ if (statret == 0) {
dc3ae351 151+ generate_and_send_sums(fd, st.st_size, f_out);
0bd6d59f
WD
152+
153+ close(fd);
d6e18487 154+ } else
0bd6d59f 155+ write_sum_head(f_out, NULL);
77945073
WD
156 }
157
158
9be39c35
WD
159-void generate_files(int f_out, struct file_list *flist, char *local_name)
160+void generate_files(int f_out, struct file_list *flist, char *local_name,
d6e18487 161+ int f_out_name)
77945073
WD
162 {
163 int i;
8cec1ead 164 int phase = 0;
d5753a22 165@@ -567,7 +580,7 @@ void generate_files(int f_out, struct fi
77945073
WD
166 }
167
168 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
9be39c35 169- file, i, f_out);
d6e18487 170+ file, i, f_out, f_out_name);
77945073
WD
171 }
172
173 phase++;
d5753a22 174@@ -584,7 +597,7 @@ void generate_files(int f_out, struct fi
77945073
WD
175 while ((i = get_redo_num()) != -1) {
176 struct file_struct *file = flist->files[i];
177 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
9be39c35 178- file, i, f_out);
d6e18487 179+ file, i, f_out, f_out_name);
77945073
WD
180 }
181
182 phase++;
d5753a22 183@@ -603,7 +616,7 @@ void generate_files(int f_out, struct fi
77945073
WD
184 if (!file->basename || !S_ISDIR(file->mode))
185 continue;
186 recv_generator(local_name ? local_name : f_name(file),
187- file, i, -1);
188+ file, i, -1, -1);
189 }
190
191 if (verbose > 2)
d5753a22 192--- orig/main.c 2004-07-31 16:41:04
2f5fa77e 193+++ main.c 2004-07-22 00:10:43
d5753a22 194@@ -59,6 +59,7 @@ extern int filesfrom_fd;
0bd6d59f
WD
195 extern pid_t cleanup_child_pid;
196 extern char *files_from;
197 extern char *remote_filesfrom_file;
198+extern char *compare_dest;
199 extern char *rsync_path;
200 extern char *shell_cmd;
201 extern char *batch_name;
d5753a22 202@@ -457,7 +458,8 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
203 {
204 int pid;
8cec1ead 205 int status = 0;
77945073 206- int error_pipe[2];
77945073 207+ int error_pipe[2], name_pipe[2];
d6e18487 208+ BOOL need_name_pipe = compare_dest && !dry_run;
77945073 209
d5753a22
WD
210 /* The receiving side mustn't obey this, or an existing symlink that
211 * points to an identical file won't be replaced by the referent. */
212@@ -472,8 +474,9 @@ static int do_recv(int f_in,int f_out,st
d24c084d 213 delete_files(flist);
77945073
WD
214 }
215
216- if (fd_pair(error_pipe) < 0) {
217- rprintf(FERROR,"error pipe failed in do_recv\n");
0bd6d59f
WD
218+ if (fd_pair(error_pipe) < 0
219+ || (need_name_pipe && fd_pair(name_pipe) < 0)) {
77945073
WD
220+ rprintf(FERROR, "fd_pair() failed in do_recv\n");
221 exit_cleanup(RERR_SOCKETIO);
222 }
223
d5753a22 224@@ -481,6 +484,11 @@ static int do_recv(int f_in,int f_out,st
77945073 225
8cec1ead 226 if ((pid = do_fork()) == 0) {
77945073 227 close(error_pipe[0]);
0bd6d59f
WD
228+ if (need_name_pipe) {
229+ close(name_pipe[1]);
230+ set_blocking(name_pipe[0]);
231+ } else
232+ name_pipe[0] = -1;
77945073
WD
233 if (f_in != f_out)
234 close(f_out);
77945073 235
d5753a22 236@@ -490,7 +498,7 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
237 /* set place to send errors */
238 set_msg_fd_out(error_pipe[1]);
239
240- recv_files(f_in,flist,local_name);
241+ recv_files(f_in, flist, local_name, name_pipe[0]);
242 io_flush(FULL_FLUSH);
243 report(f_in);
244
d5753a22 245@@ -509,6 +517,11 @@ static int do_recv(int f_in,int f_out,st
9be39c35 246 stop_write_batch();
77945073
WD
247
248 close(error_pipe[1]);
0bd6d59f
WD
249+ if (need_name_pipe) {
250+ close(name_pipe[0]);
251+ set_nonblocking(name_pipe[1]);
252+ } else
253+ name_pipe[1] = -1;
77945073
WD
254 if (f_in != f_out)
255 close(f_in);
77945073 256
d5753a22 257@@ -516,7 +529,7 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
258
259 set_msg_fd_in(error_pipe[0]);
260
261- generate_files(f_out, flist, local_name);
262+ generate_files(f_out, flist, local_name, name_pipe[1]);
263
264 get_redo_num(); /* Read final MSG_DONE and any prior messages. */
265 report(-1);
d5753a22 266--- orig/receiver.c 2004-08-03 15:34:32
65021ef6
WD
267+++ receiver.c 2004-07-30 07:17:48
268@@ -333,7 +333,8 @@ static void discard_receive_data(int f_i
77945073
WD
269 * main routine for receiver process.
270 *
271 * Receiver process runs on the same host as the generator process. */
9be39c35 272-int recv_files(int f_in, struct file_list *flist, char *local_name)
77945073 273+int recv_files(int f_in, struct file_list *flist, char *local_name,
d6e18487 274+ int f_in_name)
77945073 275 {
2f5fa77e 276 int next_gen_i = -1;
77945073 277 int fd1,fd2;
65021ef6 278@@ -362,8 +363,13 @@ int recv_files(int f_in, struct file_lis
0bd6d59f
WD
279 i = read_int(f_in);
280 if (i == -1) {
2f5fa77e
WD
281 if (read_batch) {
282- if (next_gen_i != flist->count)
283- while (read_int(batch_gen_fd) != -1) {}
65021ef6
WD
284+ if (next_gen_i != flist->count) {
285+ do {
286+ if (f_in_name >= 0
287+ && next_gen_i >= 0)
288+ read_byte(f_in_name);
289+ } while (read_int(batch_gen_fd) != -1);
0bd6d59f 290+ }
2f5fa77e
WD
291 next_gen_i = -1;
292 }
5823d322 293
65021ef6 294@@ -411,6 +417,8 @@ int recv_files(int f_in, struct file_lis
77945073 295
2f5fa77e
WD
296 if (read_batch) {
297 while (i > next_gen_i) {
65021ef6
WD
298+ if (f_in_name >= 0 && next_gen_i >= 0)
299+ read_byte(f_in_name);
2f5fa77e
WD
300 next_gen_i = read_int(batch_gen_fd);
301 if (next_gen_i == -1)
302 next_gen_i = flist->count;
65021ef6 303@@ -421,6 +429,7 @@ int recv_files(int f_in, struct file_lis
2f5fa77e
WD
304 discard_receive_data(f_in, file->length);
305 continue;
306 }
0bd6d59f 307+ next_gen_i = -1;
2f5fa77e
WD
308 }
309
5823d322 310 if (server_exclude_list.head
65021ef6
WD
311@@ -430,30 +439,28 @@ int recv_files(int f_in, struct file_lis
312 exit_cleanup(RERR_PROTOCOL);
b952a177
WD
313 }
314
315- if (partial_dir) {
316- if ((partialptr = partial_dir_fname(fname)) != NULL)
317- fnamecmp = partialptr;
318- else
b952a177 319+ partialptr = partial_dir ? partial_dir_fname(fname) : fname;
65021ef6
WD
320+
321+ if (f_in_name >= 0) {
322+ switch (read_byte(f_in_name)) {
323+ case G2R_FNAME:
324 fnamecmp = fname;
325+ break;
326+ case G2R_PARTIAL_DIR:
327+ fnamecmp = partialptr ? partialptr : fname;
328+ break;
329+ default:
330+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
331+ compare_dest, fname);
332+ fnamecmp = fnamecmpbuf;
333+ break;
334+ }
335 } else
336- fnamecmp = partialptr = fname;
337+ fnamecmp = fname;
b952a177 338
77945073
WD
339 /* open the file */
340 fd1 = do_open(fnamecmp, O_RDONLY, 0);
341
65021ef6
WD
342- if (fd1 == -1 && fnamecmp != fname) {
343- fnamecmp = fname;
344- fd1 = do_open(fnamecmp, O_RDONLY, 0);
345- }
346-
77945073
WD
347- if (fd1 == -1 && compare_dest != NULL) {
348- /* try the file at compare_dest instead */
349- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
350- compare_dest, fname);
351- fnamecmp = fnamecmpbuf;
352- fd1 = do_open(fnamecmp, O_RDONLY, 0);
353- }
354-
355 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
356 rsyserr(FERROR, errno, "fstat %s failed",
357 full_fname(fnamecmp));
d5753a22 358--- orig/rsync.h 2004-08-03 15:41:32
65021ef6
WD
359+++ rsync.h 2004-07-30 07:16:38
360@@ -118,6 +118,9 @@
361 #define PDIR_CREATE 1
362 #define PDIR_DELETE 0
363
364+#define G2R_FNAME 0x80
365+#define G2R_PARTIAL_DIR 0x81
366+
367
368 /* Log-message categories. FLOG is only used on the daemon side to
369 * output messages to the log file. */