Got rid of the extra compare_dest scan in skip_file().
[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-07-29 16:08:03
11+++ generator.c 2004-07-28 10:14:15
12@@ -259,9 +259,9 @@ 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@@ -437,13 +437,16 @@ static void recv_generator(char *fname,
25 safe_fname(fname));
26 }
27 fnamecmp = fnamecmpbuf;
28- }
29+ } else
30+ *fnamecmpbuf = '\0';
31 } else
32 #endif
33 fnamecmp = fnamecmpbuf;
34 statret = 0;
35- }
36- }
37+ } else
38+ *fnamecmpbuf = '\0';
39+ } else
40+ *fnamecmpbuf = '\0';
41
42 if (statret == 0 && !S_ISREG(st.st_mode)) {
43 if (delete_file(fname) != 0)
44@@ -455,11 +458,9 @@ static void recv_generator(char *fname,
45 if (statret == -1) {
46 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
47 return;
48- if (stat_errno == ENOENT) {
49- write_int(f_out,i);
50- if (!dry_run && !read_batch)
51- write_sum_head(f_out, NULL);
52- } else if (verbose > 1) {
53+ if (stat_errno == ENOENT)
54+ goto notify_others;
55+ if (verbose > 1) {
56 rsyserr(FERROR, stat_errno,
57 "recv_generator: failed to stat %s",
58 full_fname(fname));
59@@ -467,13 +468,13 @@ static void recv_generator(char *fname,
60 return;
61 }
62
63- if (opt_ignore_existing && fnamecmp == fname) {
64+ if (opt_ignore_existing && !*fnamecmpbuf) {
65 if (verbose > 1)
66 rprintf(FINFO, "%s exists\n", safe_fname(fname));
67 return;
68 }
69
70- if (update_only && fnamecmp == fname
71+ if (update_only && !*fnamecmpbuf
72 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
73 if (verbose > 1)
74 rprintf(FINFO, "%s is newer\n", safe_fname(fname));
75@@ -481,21 +482,17 @@ static void recv_generator(char *fname,
76 }
77
78 if (skip_file(fname, file, &st)) {
79- if (fnamecmp == fname)
80+ if (!*fnamecmpbuf)
81 set_perms(fname, file, &st, PERMS_REPORT);
82 return;
83 }
84
85- if (dry_run || read_batch) {
86- write_int(f_out,i);
87- return;
88- }
89-
90- if (whole_file > 0) {
91- write_int(f_out,i);
92- write_sum_head(f_out, NULL);
93- return;
94+ if (dry_run || whole_file) {
95+ statret = -1;
96+ goto notify_others;
97 }
98+ if (read_batch)
99+ goto notify_others;
100
101 if (partial_dir) {
102 STRUCT_STAT st2;
103@@ -516,9 +513,8 @@ static void recv_generator(char *fname,
104 /* pretend the file didn't exist */
105 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
106 return;
107- write_int(f_out,i);
108- write_sum_head(f_out, NULL);
109- return;
110+ statret = -1;
111+ goto notify_others;
112 }
113
114 if (verbose > 3) {
115@@ -529,14 +525,41 @@ static void recv_generator(char *fname,
116 if (verbose > 2)
117 rprintf(FINFO, "generating and sending sums for %d\n", i);
118
119- write_int(f_out,i);
120- generate_and_send_sums(fd, st.st_size, f_out);
121+notify_others:
122+ if (f_out_name >= 0) {
123+ uchar lenbuf[3], *lb = lenbuf;
124+ int len = statret == -1 ? 0 : strlen(fnamecmpbuf);
125+ if (len > 0x7F) {
126+#if MAXPATHLEN > 0x7FFF
127+ *lb++ = len / 0x10000 + 0x80;
128+ *lb++ = len / 0x100;
129+#else
130+ *lb++ = len / 0x100 + 0x80;
131+#endif
132+ }
133+ *lb = len;
134+ write_buf(f_out_name, lenbuf, lb - lenbuf + 1);
135+ if (len)
136+ write_buf(f_out_name, fnamecmpbuf, len);
137+ io_flush(NORMAL_FLUSH); /* XXX make this more efficient! */
138+ }
139+
140+ write_int(f_out, i);
141+
142+ if (dry_run || read_batch)
143+ return;
144
145- close(fd);
146+ if (statret == 0) {
147+ generate_and_send_sums(fd, st.st_size, f_out);
148+
149+ close(fd);
150+ } else
151+ write_sum_head(f_out, NULL);
152 }
153
154
155-void generate_files(int f_out, struct file_list *flist, char *local_name)
156+void generate_files(int f_out, struct file_list *flist, char *local_name,
157+ int f_out_name)
158 {
159 int i;
160 int phase = 0;
161@@ -577,7 +600,7 @@ void generate_files(int f_out, struct fi
162 }
163
164 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
165- file, i, f_out);
166+ file, i, f_out, f_out_name);
167 }
168
169 phase++;
170@@ -594,7 +617,7 @@ void generate_files(int f_out, struct fi
171 while ((i = get_redo_num()) != -1) {
172 struct file_struct *file = flist->files[i];
173 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
174- file, i, f_out);
175+ file, i, f_out, f_out_name);
176 }
177
178 phase++;
179@@ -613,7 +636,7 @@ void generate_files(int f_out, struct fi
180 if (!file->basename || !S_ISDIR(file->mode))
181 continue;
182 recv_generator(local_name ? local_name : f_name(file),
183- file, i, -1);
184+ file, i, -1, -1);
185 }
186
187 if (verbose > 2)
188--- orig/main.c 2004-07-29 16:08:03
189+++ main.c 2004-07-22 00:10:43
190@@ -58,6 +58,7 @@ extern int filesfrom_fd;
191 extern pid_t cleanup_child_pid;
192 extern char *files_from;
193 extern char *remote_filesfrom_file;
194+extern char *compare_dest;
195 extern char *rsync_path;
196 extern char *shell_cmd;
197 extern char *batch_name;
198@@ -456,7 +457,8 @@ static int do_recv(int f_in,int f_out,st
199 {
200 int pid;
201 int status = 0;
202- int error_pipe[2];
203+ int error_pipe[2], name_pipe[2];
204+ BOOL need_name_pipe = compare_dest && !dry_run;
205
206 if (preserve_hard_links)
207 init_hard_links(flist);
208@@ -467,8 +469,9 @@ static int do_recv(int f_in,int f_out,st
209 delete_files(flist);
210 }
211
212- if (fd_pair(error_pipe) < 0) {
213- rprintf(FERROR,"error pipe failed in do_recv\n");
214+ if (fd_pair(error_pipe) < 0
215+ || (need_name_pipe && fd_pair(name_pipe) < 0)) {
216+ rprintf(FERROR, "fd_pair() failed in do_recv\n");
217 exit_cleanup(RERR_SOCKETIO);
218 }
219
220@@ -476,6 +479,11 @@ static int do_recv(int f_in,int f_out,st
221
222 if ((pid = do_fork()) == 0) {
223 close(error_pipe[0]);
224+ if (need_name_pipe) {
225+ close(name_pipe[1]);
226+ set_blocking(name_pipe[0]);
227+ } else
228+ name_pipe[0] = -1;
229 if (f_in != f_out)
230 close(f_out);
231
232@@ -485,7 +493,7 @@ static int do_recv(int f_in,int f_out,st
233 /* set place to send errors */
234 set_msg_fd_out(error_pipe[1]);
235
236- recv_files(f_in,flist,local_name);
237+ recv_files(f_in, flist, local_name, name_pipe[0]);
238 io_flush(FULL_FLUSH);
239 report(f_in);
240
241@@ -504,6 +512,11 @@ static int do_recv(int f_in,int f_out,st
242 stop_write_batch();
243
244 close(error_pipe[1]);
245+ if (need_name_pipe) {
246+ close(name_pipe[0]);
247+ set_nonblocking(name_pipe[1]);
248+ } else
249+ name_pipe[1] = -1;
250 if (f_in != f_out)
251 close(f_in);
252
253@@ -511,7 +524,7 @@ static int do_recv(int f_in,int f_out,st
254
255 set_msg_fd_in(error_pipe[0]);
256
257- generate_files(f_out, flist, local_name);
258+ generate_files(f_out, flist, local_name, name_pipe[1]);
259
260 get_redo_num(); /* Read final MSG_DONE and any prior messages. */
261 report(-1);
262--- orig/receiver.c 2004-07-29 16:08:03
263+++ receiver.c 2004-07-23 21:59:07
264@@ -323,6 +323,30 @@ static int receive_data(int f_in, char *
265 }
266
267
268+static char *read_gen_name(int fd, char *buf, char *realname)
269+{
270+ int len = read_byte(fd);
271+ if (len & 0x80) {
272+#if MAXPATHLEN > 32767
273+ uchar lenbuf[2];
274+ read_buf(fd, (char *)lenbuf, 2);
275+ len = (len & ~0x80) * 0x10000 + lenbuf[0] * 0x100 + lenbuf[1];
276+#else
277+ len = (len & ~0x80) * 0x100 + read_byte(fd);
278+#endif
279+ }
280+ if (len) {
281+ if (len >= MAXPATHLEN) {
282+ rprintf(FERROR, "bogus data on generator name pipe\n");
283+ exit_cleanup(RERR_PROTOCOL);
284+ }
285+ read_sbuf(fd, buf, len);
286+ return buf;
287+ }
288+ return realname;
289+}
290+
291+
292 static void discard_receive_data(int f_in, OFF_T length)
293 {
294 receive_data(f_in, NULL, -1, 0, NULL, -1, length);
295@@ -333,7 +357,8 @@ static void discard_receive_data(int f_i
296 * main routine for receiver process.
297 *
298 * Receiver process runs on the same host as the generator process. */
299-int recv_files(int f_in, struct file_list *flist, char *local_name)
300+int recv_files(int f_in, struct file_list *flist, char *local_name,
301+ int f_in_name)
302 {
303 int next_gen_i = -1;
304 int fd1,fd2;
305@@ -362,8 +387,15 @@ int recv_files(int f_in, struct file_lis
306 i = read_int(f_in);
307 if (i == -1) {
308 if (read_batch) {
309- if (next_gen_i != flist->count)
310- while (read_int(batch_gen_fd) != -1) {}
311+ while (next_gen_i < flist->count) {
312+ if (f_in_name >= 0 && next_gen_i >= 0) {
313+ read_gen_name(f_in_name,
314+ fnamecmpbuf, NULL);
315+ }
316+ next_gen_i = read_int(batch_gen_fd);
317+ if (next_gen_i < 0)
318+ break;
319+ }
320 next_gen_i = -1;
321 }
322
323@@ -411,6 +443,10 @@ int recv_files(int f_in, struct file_lis
324
325 if (read_batch) {
326 while (i > next_gen_i) {
327+ if (f_in_name >= 0 && next_gen_i >= 0) {
328+ read_gen_name(f_in_name, fnamecmpbuf,
329+ NULL);
330+ }
331 next_gen_i = read_int(batch_gen_fd);
332 if (next_gen_i == -1)
333 next_gen_i = flist->count;
334@@ -421,8 +457,14 @@ int recv_files(int f_in, struct file_lis
335 discard_receive_data(f_in, file->length);
336 continue;
337 }
338+ next_gen_i = -1;
339 }
340
341+ if (f_in_name >= 0)
342+ fnamecmp = read_gen_name(f_in_name, fnamecmpbuf, fname);
343+ else
344+ fnamecmp = fname;
345+
346 if (server_exclude_list.head
347 && check_exclude(&server_exclude_list, fname,
348 S_ISDIR(file->mode)) < 0) {
349@@ -435,13 +477,7 @@ int recv_files(int f_in, struct file_lis
350 continue;
351 }
352
353- if (partial_dir) {
354- if ((partialptr = partial_dir_fname(fname)) != NULL)
355- fnamecmp = partialptr;
356- else
357- fnamecmp = fname;
358- } else
359- fnamecmp = partialptr = fname;
360+ partialptr = partial_dir ? partial_dir_fname(fname) : fname;
361
362 /* open the file */
363 fd1 = do_open(fnamecmp, O_RDONLY, 0);
364@@ -451,14 +487,6 @@ int recv_files(int f_in, struct file_lis
365 fd1 = do_open(fnamecmp, O_RDONLY, 0);
366 }
367
368- if (fd1 == -1 && compare_dest != NULL) {
369- /* try the file at compare_dest instead */
370- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
371- compare_dest, fname);
372- fnamecmp = fnamecmpbuf;
373- fd1 = do_open(fnamecmp, O_RDONLY, 0);
374- }
375-
376 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
377 rsyserr(FERROR, errno, "fstat %s failed",
378 full_fname(fnamecmp));