Got rid of fuzz.
[rsync/rsync-patches.git] / g2r-basis-filename.diff
... / ...
CommitLineData
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
10--- orig/generator.c 2004-08-03 15:41:32
11+++ generator.c 2004-07-30 07:18:03
12@@ -249,13 +249,13 @@ static void generate_and_send_sums(int f
13 * out. It might be wrong.
14 */
15 static void recv_generator(char *fname, struct file_struct *file, int i,
16- int f_out)
17+ int f_out, int f_out_name)
18 {
19- int fd;
20+ int fd = -1;
21 STRUCT_STAT st;
22 int statret, stat_errno;
23- char *fnamecmp;
24- char fnamecmpbuf[MAXPATHLEN];
25+ char *fnamecmp, fnamecmpbuf[MAXPATHLEN];
26+ uchar fnamecmp_type;
27
28 if (list_only)
29 return;
30@@ -411,6 +411,7 @@ static void recv_generator(char *fname,
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 */
38@@ -427,10 +428,14 @@ static void recv_generator(char *fname,
39 safe_fname(fname));
40 }
41 fnamecmp = fnamecmpbuf;
42+ fnamecmp_type = 0;
43 }
44 } else
45 #endif
46+ {
47 fnamecmp = fnamecmpbuf;
48+ fnamecmp_type = 0;
49+ }
50 statret = 0;
51 }
52 }
53@@ -445,11 +450,9 @@ static void recv_generator(char *fname,
54 if (statret == -1) {
55 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
56 return;
57- if (stat_errno == ENOENT) {
58- write_int(f_out,i);
59- if (!dry_run && !read_batch)
60- write_sum_head(f_out, NULL);
61- } else if (verbose > 1) {
62+ if (stat_errno == ENOENT)
63+ goto notify_others;
64+ if (verbose > 1) {
65 rsyserr(FERROR, stat_errno,
66 "recv_generator: failed to stat %s",
67 full_fname(fname));
68@@ -457,13 +460,13 @@ static void recv_generator(char *fname,
69 return;
70 }
71
72- if (opt_ignore_existing && fnamecmp == fname) {
73+ if (opt_ignore_existing && fnamecmp_type == G2R_FNAME) {
74 if (verbose > 1)
75 rprintf(FINFO, "%s exists\n", safe_fname(fname));
76 return;
77 }
78
79- if (update_only && fnamecmp == fname
80+ if (update_only && fnamecmp_type == G2R_FNAME
81 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
82 if (verbose > 1)
83 rprintf(FINFO, "%s is newer\n", safe_fname(fname));
84@@ -471,21 +474,17 @@ static void recv_generator(char *fname,
85 }
86
87 if (skip_file(fnamecmp, file, &st)) {
88- if (fnamecmp == fname)
89+ if (fnamecmp_type == G2R_FNAME)
90 set_perms(fname, file, &st, PERMS_REPORT);
91 return;
92 }
93
94- if (dry_run || read_batch) {
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;
105+ goto notify_others;
106 }
107+ if (read_batch)
108+ goto notify_others;
109
110 if (partial_dir) {
111 STRUCT_STAT st2;
112@@ -494,6 +493,7 @@ static void recv_generator(char *fname,
113 && S_ISREG(st2.st_mode)) {
114 st = st2;
115 fnamecmp = partialptr;
116+ fnamecmp_type = G2R_PARTIAL_DIR;
117 }
118 }
119
120@@ -506,9 +506,8 @@ static void recv_generator(char *fname,
121 /* pretend the file didn't exist */
122 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
123 return;
124- write_int(f_out,i);
125- write_sum_head(f_out, NULL);
126- return;
127+ statret = -1;
128+ goto notify_others;
129 }
130
131 if (verbose > 3) {
132@@ -519,14 +518,28 @@ static void recv_generator(char *fname,
133 if (verbose > 2)
134 rprintf(FINFO, "generating and sending sums for %d\n", i);
135
136- write_int(f_out,i);
137- generate_and_send_sums(fd, st.st_size, f_out);
138+notify_others:
139+ if (f_out_name >= 0) {
140+ write_byte(f_out_name, fnamecmp_type);
141+ io_flush(NORMAL_FLUSH); /* XXX make this more efficient! */
142+ }
143+
144+ write_int(f_out, i);
145
146- close(fd);
147+ if (dry_run || read_batch)
148+ return;
149+
150+ if (statret == 0) {
151+ generate_and_send_sums(fd, st.st_size, f_out);
152+
153+ close(fd);
154+ } else
155+ write_sum_head(f_out, NULL);
156 }
157
158
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,
161+ int f_out_name)
162 {
163 int i;
164 int phase = 0;
165@@ -567,7 +580,7 @@ void generate_files(int f_out, struct fi
166 }
167
168 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
169- file, i, f_out);
170+ file, i, f_out, f_out_name);
171 }
172
173 phase++;
174@@ -584,7 +597,7 @@ void generate_files(int f_out, struct fi
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),
178- file, i, f_out);
179+ file, i, f_out, f_out_name);
180 }
181
182 phase++;
183@@ -603,7 +616,7 @@ void generate_files(int f_out, struct fi
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)
192--- orig/main.c 2004-07-31 16:41:04
193+++ main.c 2004-07-22 00:10:43
194@@ -59,6 +59,7 @@ extern int filesfrom_fd;
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;
202@@ -457,7 +458,8 @@ static int do_recv(int f_in,int f_out,st
203 {
204 int pid;
205 int status = 0;
206- int error_pipe[2];
207+ int error_pipe[2], name_pipe[2];
208+ BOOL need_name_pipe = compare_dest && !dry_run;
209
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
213 delete_files(flist);
214 }
215
216- if (fd_pair(error_pipe) < 0) {
217- rprintf(FERROR,"error pipe failed in do_recv\n");
218+ if (fd_pair(error_pipe) < 0
219+ || (need_name_pipe && fd_pair(name_pipe) < 0)) {
220+ rprintf(FERROR, "fd_pair() failed in do_recv\n");
221 exit_cleanup(RERR_SOCKETIO);
222 }
223
224@@ -481,6 +484,11 @@ static int do_recv(int f_in,int f_out,st
225
226 if ((pid = do_fork()) == 0) {
227 close(error_pipe[0]);
228+ if (need_name_pipe) {
229+ close(name_pipe[1]);
230+ set_blocking(name_pipe[0]);
231+ } else
232+ name_pipe[0] = -1;
233 if (f_in != f_out)
234 close(f_out);
235
236@@ -490,7 +498,7 @@ static int do_recv(int f_in,int f_out,st
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
245@@ -509,6 +517,11 @@ static int do_recv(int f_in,int f_out,st
246 stop_write_batch();
247
248 close(error_pipe[1]);
249+ if (need_name_pipe) {
250+ close(name_pipe[0]);
251+ set_nonblocking(name_pipe[1]);
252+ } else
253+ name_pipe[1] = -1;
254 if (f_in != f_out)
255 close(f_in);
256
257@@ -516,7 +529,7 @@ static int do_recv(int f_in,int f_out,st
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);
266--- orig/receiver.c 2004-08-03 15:34:32
267+++ receiver.c 2004-07-30 07:17:48
268@@ -333,7 +333,8 @@ static void discard_receive_data(int f_i
269 * main routine for receiver process.
270 *
271 * Receiver process runs on the same host as the generator process. */
272-int recv_files(int f_in, struct file_list *flist, char *local_name)
273+int recv_files(int f_in, struct file_list *flist, char *local_name,
274+ int f_in_name)
275 {
276 int next_gen_i = -1;
277 int fd1,fd2;
278@@ -362,8 +363,13 @@ int recv_files(int f_in, struct file_lis
279 i = read_int(f_in);
280 if (i == -1) {
281 if (read_batch) {
282- if (next_gen_i != flist->count)
283- while (read_int(batch_gen_fd) != -1) {}
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);
290+ }
291 next_gen_i = -1;
292 }
293
294@@ -411,6 +417,8 @@ int recv_files(int f_in, struct file_lis
295
296 if (read_batch) {
297 while (i > next_gen_i) {
298+ if (f_in_name >= 0 && next_gen_i >= 0)
299+ read_byte(f_in_name);
300 next_gen_i = read_int(batch_gen_fd);
301 if (next_gen_i == -1)
302 next_gen_i = flist->count;
303@@ -421,6 +429,7 @@ int recv_files(int f_in, struct file_lis
304 discard_receive_data(f_in, file->length);
305 continue;
306 }
307+ next_gen_i = -1;
308 }
309
310 if (server_exclude_list.head
311@@ -430,30 +439,28 @@ int recv_files(int f_in, struct file_lis
312 exit_cleanup(RERR_PROTOCOL);
313 }
314
315- if (partial_dir) {
316- if ((partialptr = partial_dir_fname(fname)) != NULL)
317- fnamecmp = partialptr;
318- else
319+ partialptr = partial_dir ? partial_dir_fname(fname) : fname;
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;
338
339 /* open the file */
340 fd1 = do_open(fnamecmp, O_RDONLY, 0);
341
342- if (fd1 == -1 && fnamecmp != fname) {
343- fnamecmp = fname;
344- fd1 = do_open(fnamecmp, O_RDONLY, 0);
345- }
346-
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));
358--- orig/rsync.h 2004-08-03 15:41:32
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. */