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