Updated for latest generator/receiver changes.
[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
ccfe7463
WD
10--- orig/generator.c 2004-09-07 21:45:30
11+++ generator.c 2004-09-07 21:55:02
12@@ -254,14 +254,15 @@ 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 {
ccfe7463
WD
19- int fd, f_copy;
20+ int fd = -1, f_copy;
21 STRUCT_STAT st, partial_st;
22 struct file_struct *back_file;
b952a177 23 int statret, stat_errno;
ccfe7463
WD
24 char *fnamecmp, *partialptr, *backupptr;
25 char fnamecmpbuf[MAXPATHLEN];
65021ef6
WD
26+ uchar fnamecmp_type;
27
28 if (list_only)
29 return;
ccfe7463 30@@ -423,6 +424,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 */
ccfe7463 38@@ -439,10 +441,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 }
ccfe7463 53@@ -465,11 +471,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));
ccfe7463 68@@ -477,13 +481,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));
ccfe7463 84@@ -491,26 +495,23 @@ 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
ccfe7463 94 prepare_to_open:
2f5fa77e 95- if (dry_run || read_batch) {
0bd6d59f
WD
96- write_int(f_out,i);
97- return;
98- }
99-
100- if (whole_file > 0) {
101- write_int(f_out,i);
102- write_sum_head(f_out, NULL);
103- return;
104+ if (dry_run || whole_file) {
105+ statret = -1;
d24c084d 106+ goto notify_others;
77945073 107 }
0bd6d59f 108+ if (read_batch)
d24c084d 109+ goto notify_others;
77945073 110
ccfe7463
WD
111 if (partialptr) {
112 st = partial_st;
113 fnamecmp = partialptr;
114+ fnamecmp_type = G2R_PARTIAL_DIR;
65021ef6
WD
115 }
116
ccfe7463
WD
117 /* open the file */
118@@ -523,9 +524,8 @@ prepare_to_open:
77945073
WD
119 /* pretend the file didn't exist */
120 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
121 return;
0bd6d59f
WD
122- write_int(f_out,i);
123- write_sum_head(f_out, NULL);
124- return;
125+ statret = -1;
d24c084d 126+ goto notify_others;
0bd6d59f
WD
127 }
128
ccfe7463
WD
129 if (inplace && make_backups) {
130@@ -552,6 +552,7 @@ prepare_to_open:
131 close(fd);
132 return;
133 }
134+ fnamecmp_type = G2R_BACKUP;
135 } else {
136 backupptr = NULL;
137 back_file = NULL;
138@@ -566,20 +567,33 @@ prepare_to_open:
77945073
WD
139 if (verbose > 2)
140 rprintf(FINFO, "generating and sending sums for %d\n", i);
141
0bd6d59f 142- write_int(f_out,i);
ccfe7463
WD
143- generate_and_send_sums(fd, st.st_size, f_out, f_copy);
144-
145- if (f_copy >= 0) {
146- close(f_copy);
147- set_perms(backupptr, back_file, NULL, 0);
148- free(back_file);
d24c084d 149+notify_others:
d6e18487 150+ if (f_out_name >= 0) {
65021ef6 151+ write_byte(f_out_name, fnamecmp_type);
d6e18487 152+ io_flush(NORMAL_FLUSH); /* XXX make this more efficient! */
ccfe7463 153 }
2f5fa77e
WD
154
155- close(fd);
ccfe7463
WD
156+ write_int(f_out, i);
157+
65021ef6
WD
158+ if (dry_run || read_batch)
159+ return;
160+
0bd6d59f 161+ if (statret == 0) {
ccfe7463 162+ generate_and_send_sums(fd, st.st_size, f_out, f_copy);
0bd6d59f 163+ close(fd);
ccfe7463
WD
164+
165+ if (f_copy >= 0) {
166+ close(f_copy);
167+ set_perms(backupptr, back_file, NULL, 0);
168+ free(back_file);
169+ }
d6e18487 170+ } else
0bd6d59f 171+ write_sum_head(f_out, NULL);
77945073
WD
172 }
173
174
9be39c35
WD
175-void generate_files(int f_out, struct file_list *flist, char *local_name)
176+void generate_files(int f_out, struct file_list *flist, char *local_name,
d6e18487 177+ int f_out_name)
77945073
WD
178 {
179 int i;
8cec1ead 180 int phase = 0;
ccfe7463 181@@ -620,7 +634,7 @@ void generate_files(int f_out, struct fi
77945073
WD
182 }
183
184 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
9be39c35 185- file, i, f_out);
d6e18487 186+ file, i, f_out, f_out_name);
77945073
WD
187 }
188
189 phase++;
ccfe7463 190@@ -637,7 +651,7 @@ void generate_files(int f_out, struct fi
77945073
WD
191 while ((i = get_redo_num()) != -1) {
192 struct file_struct *file = flist->files[i];
193 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
9be39c35 194- file, i, f_out);
d6e18487 195+ file, i, f_out, f_out_name);
77945073
WD
196 }
197
198 phase++;
ccfe7463 199@@ -656,7 +670,7 @@ void generate_files(int f_out, struct fi
77945073
WD
200 if (!file->basename || !S_ISDIR(file->mode))
201 continue;
202 recv_generator(local_name ? local_name : f_name(file),
203- file, i, -1);
204+ file, i, -1, -1);
205 }
206
207 if (verbose > 2)
f635ed27 208--- orig/main.c 2004-08-05 18:24:21
2f5fa77e 209+++ main.c 2004-07-22 00:10:43
d5753a22 210@@ -59,6 +59,7 @@ extern int filesfrom_fd;
0bd6d59f
WD
211 extern pid_t cleanup_child_pid;
212 extern char *files_from;
213 extern char *remote_filesfrom_file;
214+extern char *compare_dest;
215 extern char *rsync_path;
216 extern char *shell_cmd;
217 extern char *batch_name;
f635ed27 218@@ -461,7 +462,8 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
219 {
220 int pid;
8cec1ead 221 int status = 0;
77945073 222- int error_pipe[2];
77945073 223+ int error_pipe[2], name_pipe[2];
d6e18487 224+ BOOL need_name_pipe = compare_dest && !dry_run;
77945073 225
d5753a22
WD
226 /* The receiving side mustn't obey this, or an existing symlink that
227 * points to an identical file won't be replaced by the referent. */
f635ed27 228@@ -476,8 +478,9 @@ static int do_recv(int f_in,int f_out,st
d24c084d 229 delete_files(flist);
77945073
WD
230 }
231
232- if (fd_pair(error_pipe) < 0) {
233- rprintf(FERROR,"error pipe failed in do_recv\n");
0bd6d59f
WD
234+ if (fd_pair(error_pipe) < 0
235+ || (need_name_pipe && fd_pair(name_pipe) < 0)) {
77945073
WD
236+ rprintf(FERROR, "fd_pair() failed in do_recv\n");
237 exit_cleanup(RERR_SOCKETIO);
238 }
239
f635ed27 240@@ -485,6 +488,11 @@ static int do_recv(int f_in,int f_out,st
77945073 241
8cec1ead 242 if ((pid = do_fork()) == 0) {
77945073 243 close(error_pipe[0]);
0bd6d59f
WD
244+ if (need_name_pipe) {
245+ close(name_pipe[1]);
246+ set_blocking(name_pipe[0]);
247+ } else
248+ name_pipe[0] = -1;
77945073
WD
249 if (f_in != f_out)
250 close(f_out);
77945073 251
f635ed27 252@@ -494,7 +502,7 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
253 /* set place to send errors */
254 set_msg_fd_out(error_pipe[1]);
255
256- recv_files(f_in,flist,local_name);
257+ recv_files(f_in, flist, local_name, name_pipe[0]);
258 io_flush(FULL_FLUSH);
259 report(f_in);
260
f635ed27 261@@ -513,6 +521,11 @@ static int do_recv(int f_in,int f_out,st
9be39c35 262 stop_write_batch();
77945073
WD
263
264 close(error_pipe[1]);
0bd6d59f
WD
265+ if (need_name_pipe) {
266+ close(name_pipe[0]);
267+ set_nonblocking(name_pipe[1]);
268+ } else
269+ name_pipe[1] = -1;
77945073
WD
270 if (f_in != f_out)
271 close(f_in);
77945073 272
f635ed27 273@@ -520,7 +533,7 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
274
275 set_msg_fd_in(error_pipe[0]);
276
277- generate_files(f_out, flist, local_name);
278+ generate_files(f_out, flist, local_name, name_pipe[1]);
279
280 get_redo_num(); /* Read final MSG_DONE and any prior messages. */
281 report(-1);
ccfe7463
WD
282--- orig/receiver.c 2004-09-07 21:45:30
283+++ receiver.c 2004-09-07 21:57:20
65021ef6 284@@ -333,7 +333,8 @@ static void discard_receive_data(int f_i
77945073
WD
285 * main routine for receiver process.
286 *
287 * Receiver process runs on the same host as the generator process. */
9be39c35 288-int recv_files(int f_in, struct file_list *flist, char *local_name)
77945073 289+int recv_files(int f_in, struct file_list *flist, char *local_name,
d6e18487 290+ int f_in_name)
77945073 291 {
2f5fa77e 292 int next_gen_i = -1;
77945073 293 int fd1,fd2;
65021ef6 294@@ -362,8 +363,13 @@ int recv_files(int f_in, struct file_lis
0bd6d59f
WD
295 i = read_int(f_in);
296 if (i == -1) {
2f5fa77e
WD
297 if (read_batch) {
298- if (next_gen_i != flist->count)
299- while (read_int(batch_gen_fd) != -1) {}
65021ef6
WD
300+ if (next_gen_i != flist->count) {
301+ do {
302+ if (f_in_name >= 0
303+ && next_gen_i >= 0)
304+ read_byte(f_in_name);
305+ } while (read_int(batch_gen_fd) != -1);
0bd6d59f 306+ }
2f5fa77e
WD
307 next_gen_i = -1;
308 }
5823d322 309
65021ef6 310@@ -411,6 +417,8 @@ int recv_files(int f_in, struct file_lis
77945073 311
2f5fa77e
WD
312 if (read_batch) {
313 while (i > next_gen_i) {
65021ef6
WD
314+ if (f_in_name >= 0 && next_gen_i >= 0)
315+ read_byte(f_in_name);
2f5fa77e
WD
316 next_gen_i = read_int(batch_gen_fd);
317 if (next_gen_i == -1)
318 next_gen_i = flist->count;
65021ef6 319@@ -421,6 +429,7 @@ int recv_files(int f_in, struct file_lis
2f5fa77e
WD
320 discard_receive_data(f_in, file->length);
321 continue;
322 }
0bd6d59f 323+ next_gen_i = -1;
2f5fa77e
WD
324 }
325
5823d322 326 if (server_exclude_list.head
ccfe7463 327@@ -430,35 +439,31 @@ int recv_files(int f_in, struct file_lis
65021ef6 328 exit_cleanup(RERR_PROTOCOL);
b952a177
WD
329 }
330
331- if (partial_dir) {
332- if ((partialptr = partial_dir_fname(fname)) != NULL)
333- fnamecmp = partialptr;
334- else
b952a177 335+ partialptr = partial_dir ? partial_dir_fname(fname) : fname;
65021ef6
WD
336+
337+ if (f_in_name >= 0) {
338+ switch (read_byte(f_in_name)) {
339+ case G2R_FNAME:
340 fnamecmp = fname;
341+ break;
342+ case G2R_PARTIAL_DIR:
343+ fnamecmp = partialptr ? partialptr : fname;
344+ break;
ccfe7463
WD
345+ case G2R_BACKUP:
346+ fnamecmp = get_backup_name(fname);
347+ break;
65021ef6
WD
348+ default:
349+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
350+ compare_dest, fname);
351+ fnamecmp = fnamecmpbuf;
352+ break;
353+ }
354 } else
355- fnamecmp = partialptr = fname;
ccfe7463
WD
356-
357- if (inplace && make_backups) {
358- if (!(fnamecmp = get_backup_name(fname)))
359- fnamecmp = partialptr;
360- }
65021ef6 361+ fnamecmp = fname;
b952a177 362
77945073
WD
363 /* open the file */
364 fd1 = do_open(fnamecmp, O_RDONLY, 0);
365
65021ef6
WD
366- if (fd1 == -1 && fnamecmp != fname) {
367- fnamecmp = fname;
368- fd1 = do_open(fnamecmp, O_RDONLY, 0);
369- }
370-
77945073
WD
371- if (fd1 == -1 && compare_dest != NULL) {
372- /* try the file at compare_dest instead */
373- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
374- compare_dest, fname);
375- fnamecmp = fnamecmpbuf;
376- fd1 = do_open(fnamecmp, O_RDONLY, 0);
377- }
378-
379 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
380 rsyserr(FERROR, errno, "fstat %s failed",
381 full_fname(fnamecmp));
d5753a22 382--- orig/rsync.h 2004-08-03 15:41:32
ccfe7463
WD
383+++ rsync.h 2004-09-07 21:52:22
384@@ -118,6 +118,10 @@
65021ef6
WD
385 #define PDIR_CREATE 1
386 #define PDIR_DELETE 0
387
388+#define G2R_FNAME 0x80
389+#define G2R_PARTIAL_DIR 0x81
ccfe7463 390+#define G2R_BACKUP 0x82
65021ef6
WD
391+
392
393 /* Log-message categories. FLOG is only used on the daemon side to
394 * output messages to the log file. */