Added a variable to t_stub.c so that "make test" works.
[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
a6587818
WD
10--- orig/generator.c 2004-09-20 19:50:13
11+++ generator.c 2004-09-20 19:57:58
ccfe7463 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;
b857cf41 104+ if (dry_run || whole_file > 0) {
0bd6d59f 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;
a6587818 138@@ -566,22 +567,38 @@ 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);
a6587818
WD
148- if (verbose > 1)
149- rprintf(FINFO, "backed up %s to %s\n", fname, backupptr);
ccfe7463 150- free(back_file);
d24c084d 151+notify_others:
d6e18487 152+ if (f_out_name >= 0) {
65021ef6 153+ write_byte(f_out_name, fnamecmp_type);
d6e18487 154+ io_flush(NORMAL_FLUSH); /* XXX make this more efficient! */
ccfe7463 155 }
2f5fa77e
WD
156
157- close(fd);
ccfe7463
WD
158+ write_int(f_out, i);
159+
65021ef6
WD
160+ if (dry_run || read_batch)
161+ return;
162+
0bd6d59f 163+ if (statret == 0) {
ccfe7463 164+ generate_and_send_sums(fd, st.st_size, f_out, f_copy);
ccfe7463
WD
165+
166+ if (f_copy >= 0) {
167+ close(f_copy);
168+ set_perms(backupptr, back_file, NULL, 0);
a6587818
WD
169+ if (verbose > 1) {
170+ rprintf(FINFO, "backed up %s to %s\n",
171+ fname, backupptr);
172+ }
ccfe7463
WD
173+ free(back_file);
174+ }
a6587818
WD
175+
176+ close(fd);
d6e18487 177+ } else
0bd6d59f 178+ write_sum_head(f_out, NULL);
77945073
WD
179 }
180
181
9be39c35
WD
182-void generate_files(int f_out, struct file_list *flist, char *local_name)
183+void generate_files(int f_out, struct file_list *flist, char *local_name,
d6e18487 184+ int f_out_name)
77945073
WD
185 {
186 int i;
8cec1ead 187 int phase = 0;
a6587818 188@@ -622,7 +639,7 @@ void generate_files(int f_out, struct fi
77945073
WD
189 }
190
191 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
9be39c35 192- file, i, f_out);
d6e18487 193+ file, i, f_out, f_out_name);
77945073
WD
194 }
195
196 phase++;
a6587818 197@@ -639,7 +656,7 @@ void generate_files(int f_out, struct fi
77945073
WD
198 while ((i = get_redo_num()) != -1) {
199 struct file_struct *file = flist->files[i];
200 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
9be39c35 201- file, i, f_out);
d6e18487 202+ file, i, f_out, f_out_name);
77945073
WD
203 }
204
205 phase++;
a6587818 206@@ -658,7 +675,7 @@ void generate_files(int f_out, struct fi
77945073
WD
207 if (!file->basename || !S_ISDIR(file->mode))
208 continue;
209 recv_generator(local_name ? local_name : f_name(file),
210- file, i, -1);
211+ file, i, -1, -1);
212 }
213
214 if (verbose > 2)
a60267ab 215--- orig/main.c 2004-09-29 17:58:26
2f5fa77e 216+++ main.c 2004-07-22 00:10:43
d5753a22 217@@ -59,6 +59,7 @@ extern int filesfrom_fd;
0bd6d59f
WD
218 extern pid_t cleanup_child_pid;
219 extern char *files_from;
220 extern char *remote_filesfrom_file;
221+extern char *compare_dest;
222 extern char *rsync_path;
223 extern char *shell_cmd;
224 extern char *batch_name;
f635ed27 225@@ -461,7 +462,8 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
226 {
227 int pid;
8cec1ead 228 int status = 0;
77945073 229- int error_pipe[2];
77945073 230+ int error_pipe[2], name_pipe[2];
d6e18487 231+ BOOL need_name_pipe = compare_dest && !dry_run;
77945073 232
d5753a22
WD
233 /* The receiving side mustn't obey this, or an existing symlink that
234 * points to an identical file won't be replaced by the referent. */
f635ed27 235@@ -476,8 +478,9 @@ static int do_recv(int f_in,int f_out,st
d24c084d 236 delete_files(flist);
77945073
WD
237 }
238
239- if (fd_pair(error_pipe) < 0) {
240- rprintf(FERROR,"error pipe failed in do_recv\n");
0bd6d59f
WD
241+ if (fd_pair(error_pipe) < 0
242+ || (need_name_pipe && fd_pair(name_pipe) < 0)) {
77945073
WD
243+ rprintf(FERROR, "fd_pair() failed in do_recv\n");
244 exit_cleanup(RERR_SOCKETIO);
245 }
246
f635ed27 247@@ -485,6 +488,11 @@ static int do_recv(int f_in,int f_out,st
77945073 248
8cec1ead 249 if ((pid = do_fork()) == 0) {
77945073 250 close(error_pipe[0]);
0bd6d59f
WD
251+ if (need_name_pipe) {
252+ close(name_pipe[1]);
253+ set_blocking(name_pipe[0]);
254+ } else
255+ name_pipe[0] = -1;
77945073
WD
256 if (f_in != f_out)
257 close(f_out);
77945073 258
f635ed27 259@@ -494,7 +502,7 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
260 /* set place to send errors */
261 set_msg_fd_out(error_pipe[1]);
262
263- recv_files(f_in,flist,local_name);
264+ recv_files(f_in, flist, local_name, name_pipe[0]);
265 io_flush(FULL_FLUSH);
266 report(f_in);
267
f635ed27 268@@ -513,6 +521,11 @@ static int do_recv(int f_in,int f_out,st
9be39c35 269 stop_write_batch();
77945073
WD
270
271 close(error_pipe[1]);
0bd6d59f
WD
272+ if (need_name_pipe) {
273+ close(name_pipe[0]);
274+ set_nonblocking(name_pipe[1]);
275+ } else
276+ name_pipe[1] = -1;
77945073
WD
277 if (f_in != f_out)
278 close(f_in);
77945073 279
f635ed27 280@@ -520,7 +533,7 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
281
282 set_msg_fd_in(error_pipe[0]);
283
284- generate_files(f_out, flist, local_name);
285+ generate_files(f_out, flist, local_name, name_pipe[1]);
286
287 get_redo_num(); /* Read final MSG_DONE and any prior messages. */
288 report(-1);
a6587818 289--- orig/receiver.c 2004-09-21 09:40:27
ccfe7463 290+++ receiver.c 2004-09-07 21:57:20
a6587818 291@@ -329,7 +329,8 @@ static void discard_receive_data(int f_i
77945073
WD
292 * main routine for receiver process.
293 *
294 * Receiver process runs on the same host as the generator process. */
9be39c35 295-int recv_files(int f_in, struct file_list *flist, char *local_name)
77945073 296+int recv_files(int f_in, struct file_list *flist, char *local_name,
d6e18487 297+ int f_in_name)
77945073 298 {
2f5fa77e 299 int next_gen_i = -1;
77945073 300 int fd1,fd2;
a6587818 301@@ -358,8 +359,13 @@ int recv_files(int f_in, struct file_lis
0bd6d59f
WD
302 i = read_int(f_in);
303 if (i == -1) {
2f5fa77e
WD
304 if (read_batch) {
305- if (next_gen_i != flist->count)
306- while (read_int(batch_gen_fd) != -1) {}
65021ef6
WD
307+ if (next_gen_i != flist->count) {
308+ do {
309+ if (f_in_name >= 0
310+ && next_gen_i >= 0)
311+ read_byte(f_in_name);
312+ } while (read_int(batch_gen_fd) != -1);
0bd6d59f 313+ }
2f5fa77e
WD
314 next_gen_i = -1;
315 }
5823d322 316
a6587818 317@@ -407,6 +413,8 @@ int recv_files(int f_in, struct file_lis
77945073 318
2f5fa77e
WD
319 if (read_batch) {
320 while (i > next_gen_i) {
65021ef6
WD
321+ if (f_in_name >= 0 && next_gen_i >= 0)
322+ read_byte(f_in_name);
2f5fa77e
WD
323 next_gen_i = read_int(batch_gen_fd);
324 if (next_gen_i == -1)
325 next_gen_i = flist->count;
a6587818 326@@ -417,6 +425,7 @@ int recv_files(int f_in, struct file_lis
2f5fa77e
WD
327 discard_receive_data(f_in, file->length);
328 continue;
329 }
0bd6d59f 330+ next_gen_i = -1;
2f5fa77e
WD
331 }
332
5823d322 333 if (server_exclude_list.head
a6587818 334@@ -426,35 +435,31 @@ int recv_files(int f_in, struct file_lis
65021ef6 335 exit_cleanup(RERR_PROTOCOL);
b952a177
WD
336 }
337
338- if (partial_dir) {
339- if ((partialptr = partial_dir_fname(fname)) != NULL)
340- fnamecmp = partialptr;
341- else
b952a177 342+ partialptr = partial_dir ? partial_dir_fname(fname) : fname;
65021ef6
WD
343+
344+ if (f_in_name >= 0) {
345+ switch (read_byte(f_in_name)) {
346+ case G2R_FNAME:
347 fnamecmp = fname;
348+ break;
349+ case G2R_PARTIAL_DIR:
350+ fnamecmp = partialptr ? partialptr : fname;
351+ break;
ccfe7463
WD
352+ case G2R_BACKUP:
353+ fnamecmp = get_backup_name(fname);
354+ break;
65021ef6
WD
355+ default:
356+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
357+ compare_dest, fname);
358+ fnamecmp = fnamecmpbuf;
359+ break;
360+ }
361 } else
362- fnamecmp = partialptr = fname;
ccfe7463
WD
363-
364- if (inplace && make_backups) {
365- if (!(fnamecmp = get_backup_name(fname)))
366- fnamecmp = partialptr;
367- }
65021ef6 368+ fnamecmp = fname;
b952a177 369
77945073
WD
370 /* open the file */
371 fd1 = do_open(fnamecmp, O_RDONLY, 0);
372
65021ef6
WD
373- if (fd1 == -1 && fnamecmp != fname) {
374- fnamecmp = fname;
375- fd1 = do_open(fnamecmp, O_RDONLY, 0);
376- }
377-
77945073
WD
378- if (fd1 == -1 && compare_dest != NULL) {
379- /* try the file at compare_dest instead */
380- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
381- compare_dest, fname);
382- fnamecmp = fnamecmpbuf;
383- fd1 = do_open(fnamecmp, O_RDONLY, 0);
384- }
385-
386 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
387 rsyserr(FERROR, errno, "fstat %s failed",
388 full_fname(fnamecmp));
b857cf41 389--- orig/rsync.h 2004-09-22 08:47:31
ccfe7463 390+++ rsync.h 2004-09-07 21:52:22
b857cf41 391@@ -119,6 +119,10 @@
65021ef6
WD
392 #define PDIR_CREATE 1
393 #define PDIR_DELETE 0
394
395+#define G2R_FNAME 0x80
396+#define G2R_PARTIAL_DIR 0x81
ccfe7463 397+#define G2R_BACKUP 0x82
65021ef6
WD
398+
399
400 /* Log-message categories. FLOG is only used on the daemon side to
401 * output messages to the log file. */