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