Moved the mkfifo() and socket-making stuff from tru64.diff to here so
[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-09-20 19:50:13
11+++ generator.c 2004-09-20 19:57:58
12@@ -254,14 +254,15 @@ 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, f_copy;
20+ int fd = -1, f_copy;
21 STRUCT_STAT st, partial_st;
22 struct file_struct *back_file;
23 int statret, stat_errno;
24 char *fnamecmp, *partialptr, *backupptr;
25 char fnamecmpbuf[MAXPATHLEN];
26+ uchar fnamecmp_type;
27
28 if (list_only)
29 return;
30@@ -423,6 +424,7 @@ static void recv_generator(char *fname,
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 */
38@@ -439,10 +441,14 @@ static void recv_generator(char *fname,
39 safe_fname(fname));
40 }
41 fnamecmp = fnamecmpbuf;
42+ fnamecmp_type = 0;
43 }
44 } else
45 #endif
46+ {
47 fnamecmp = fnamecmpbuf;
48+ fnamecmp_type = 0;
49+ }
50 statret = 0;
51 }
52 }
53@@ -465,11 +471,9 @@ static void recv_generator(char *fname,
54 if (statret == -1) {
55 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
56 return;
57- if (stat_errno == ENOENT) {
58- write_int(f_out,i);
59- if (!dry_run && !read_batch)
60- write_sum_head(f_out, NULL);
61- } else if (verbose > 1) {
62+ if (stat_errno == ENOENT)
63+ goto notify_others;
64+ if (verbose > 1) {
65 rsyserr(FERROR, stat_errno,
66 "recv_generator: failed to stat %s",
67 full_fname(fname));
68@@ -477,13 +481,13 @@ static void recv_generator(char *fname,
69 return;
70 }
71
72- if (opt_ignore_existing && fnamecmp == fname) {
73+ if (opt_ignore_existing && fnamecmp_type == G2R_FNAME) {
74 if (verbose > 1)
75 rprintf(FINFO, "%s exists\n", safe_fname(fname));
76 return;
77 }
78
79- if (update_only && fnamecmp == fname
80+ if (update_only && fnamecmp_type == G2R_FNAME
81 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
82 if (verbose > 1)
83 rprintf(FINFO, "%s is newer\n", safe_fname(fname));
84@@ -491,26 +495,23 @@ static void recv_generator(char *fname,
85 }
86
87 if (skip_file(fnamecmp, file, &st)) {
88- if (fnamecmp == fname)
89+ if (fnamecmp_type == G2R_FNAME)
90 set_perms(fname, file, &st, PERMS_REPORT);
91 return;
92 }
93
94 prepare_to_open:
95- if (dry_run || read_batch) {
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;
106+ goto notify_others;
107 }
108+ if (read_batch)
109+ goto notify_others;
110
111 if (partialptr) {
112 st = partial_st;
113 fnamecmp = partialptr;
114+ fnamecmp_type = G2R_PARTIAL_DIR;
115 }
116
117 /* open the file */
118@@ -523,9 +524,8 @@ prepare_to_open:
119 /* pretend the file didn't exist */
120 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
121 return;
122- write_int(f_out,i);
123- write_sum_head(f_out, NULL);
124- return;
125+ statret = -1;
126+ goto notify_others;
127 }
128
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,22 +567,38 @@ prepare_to_open:
139 if (verbose > 2)
140 rprintf(FINFO, "generating and sending sums for %d\n", i);
141
142- write_int(f_out,i);
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- if (verbose > 1)
149- rprintf(FINFO, "backed up %s to %s\n", fname, backupptr);
150- free(back_file);
151+notify_others:
152+ if (f_out_name >= 0) {
153+ write_byte(f_out_name, fnamecmp_type);
154+ io_flush(NORMAL_FLUSH); /* XXX make this more efficient! */
155 }
156
157- close(fd);
158+ write_int(f_out, i);
159+
160+ if (dry_run || read_batch)
161+ return;
162+
163+ if (statret == 0) {
164+ generate_and_send_sums(fd, st.st_size, f_out, f_copy);
165+
166+ if (f_copy >= 0) {
167+ close(f_copy);
168+ set_perms(backupptr, back_file, NULL, 0);
169+ if (verbose > 1) {
170+ rprintf(FINFO, "backed up %s to %s\n",
171+ fname, backupptr);
172+ }
173+ free(back_file);
174+ }
175+
176+ close(fd);
177+ } else
178+ write_sum_head(f_out, NULL);
179 }
180
181
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,
184+ int f_out_name)
185 {
186 int i;
187 int phase = 0;
188@@ -622,7 +639,7 @@ void generate_files(int f_out, struct fi
189 }
190
191 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
192- file, i, f_out);
193+ file, i, f_out, f_out_name);
194 }
195
196 phase++;
197@@ -639,7 +656,7 @@ void generate_files(int f_out, struct fi
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),
201- file, i, f_out);
202+ file, i, f_out, f_out_name);
203 }
204
205 phase++;
206@@ -658,7 +675,7 @@ void generate_files(int f_out, struct fi
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)
215--- orig/main.c 2004-09-18 01:49:33
216+++ main.c 2004-07-22 00:10:43
217@@ -59,6 +59,7 @@ extern int filesfrom_fd;
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;
225@@ -461,7 +462,8 @@ static int do_recv(int f_in,int f_out,st
226 {
227 int pid;
228 int status = 0;
229- int error_pipe[2];
230+ int error_pipe[2], name_pipe[2];
231+ BOOL need_name_pipe = compare_dest && !dry_run;
232
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. */
235@@ -476,8 +478,9 @@ static int do_recv(int f_in,int f_out,st
236 delete_files(flist);
237 }
238
239- if (fd_pair(error_pipe) < 0) {
240- rprintf(FERROR,"error pipe failed in do_recv\n");
241+ if (fd_pair(error_pipe) < 0
242+ || (need_name_pipe && fd_pair(name_pipe) < 0)) {
243+ rprintf(FERROR, "fd_pair() failed in do_recv\n");
244 exit_cleanup(RERR_SOCKETIO);
245 }
246
247@@ -485,6 +488,11 @@ static int do_recv(int f_in,int f_out,st
248
249 if ((pid = do_fork()) == 0) {
250 close(error_pipe[0]);
251+ if (need_name_pipe) {
252+ close(name_pipe[1]);
253+ set_blocking(name_pipe[0]);
254+ } else
255+ name_pipe[0] = -1;
256 if (f_in != f_out)
257 close(f_out);
258
259@@ -494,7 +502,7 @@ static int do_recv(int f_in,int f_out,st
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
268@@ -513,6 +521,11 @@ static int do_recv(int f_in,int f_out,st
269 stop_write_batch();
270
271 close(error_pipe[1]);
272+ if (need_name_pipe) {
273+ close(name_pipe[0]);
274+ set_nonblocking(name_pipe[1]);
275+ } else
276+ name_pipe[1] = -1;
277 if (f_in != f_out)
278 close(f_in);
279
280@@ -520,7 +533,7 @@ static int do_recv(int f_in,int f_out,st
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);
289--- orig/receiver.c 2004-09-21 09:40:27
290+++ receiver.c 2004-09-07 21:57:20
291@@ -329,7 +329,8 @@ static void discard_receive_data(int f_i
292 * main routine for receiver process.
293 *
294 * Receiver process runs on the same host as the generator process. */
295-int recv_files(int f_in, struct file_list *flist, char *local_name)
296+int recv_files(int f_in, struct file_list *flist, char *local_name,
297+ int f_in_name)
298 {
299 int next_gen_i = -1;
300 int fd1,fd2;
301@@ -358,8 +359,13 @@ int recv_files(int f_in, struct file_lis
302 i = read_int(f_in);
303 if (i == -1) {
304 if (read_batch) {
305- if (next_gen_i != flist->count)
306- while (read_int(batch_gen_fd) != -1) {}
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);
313+ }
314 next_gen_i = -1;
315 }
316
317@@ -407,6 +413,8 @@ int recv_files(int f_in, struct file_lis
318
319 if (read_batch) {
320 while (i > next_gen_i) {
321+ if (f_in_name >= 0 && next_gen_i >= 0)
322+ read_byte(f_in_name);
323 next_gen_i = read_int(batch_gen_fd);
324 if (next_gen_i == -1)
325 next_gen_i = flist->count;
326@@ -417,6 +425,7 @@ int recv_files(int f_in, struct file_lis
327 discard_receive_data(f_in, file->length);
328 continue;
329 }
330+ next_gen_i = -1;
331 }
332
333 if (server_exclude_list.head
334@@ -426,35 +435,31 @@ int recv_files(int f_in, struct file_lis
335 exit_cleanup(RERR_PROTOCOL);
336 }
337
338- if (partial_dir) {
339- if ((partialptr = partial_dir_fname(fname)) != NULL)
340- fnamecmp = partialptr;
341- else
342+ partialptr = partial_dir ? partial_dir_fname(fname) : fname;
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;
352+ case G2R_BACKUP:
353+ fnamecmp = get_backup_name(fname);
354+ break;
355+ default:
356+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
357+ compare_dest, fname);
358+ fnamecmp = fnamecmpbuf;
359+ break;
360+ }
361 } else
362- fnamecmp = partialptr = fname;
363-
364- if (inplace && make_backups) {
365- if (!(fnamecmp = get_backup_name(fname)))
366- fnamecmp = partialptr;
367- }
368+ fnamecmp = fname;
369
370 /* open the file */
371 fd1 = do_open(fnamecmp, O_RDONLY, 0);
372
373- if (fd1 == -1 && fnamecmp != fname) {
374- fnamecmp = fname;
375- fd1 = do_open(fnamecmp, O_RDONLY, 0);
376- }
377-
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));
389--- orig/rsync.h 2004-08-03 15:41:32
390+++ rsync.h 2004-09-07 21:52:22
391@@ -118,6 +118,10 @@
392 #define PDIR_CREATE 1
393 #define PDIR_DELETE 0
394
395+#define G2R_FNAME 0x80
396+#define G2R_PARTIAL_DIR 0x81
397+#define G2R_BACKUP 0x82
398+
399
400 /* Log-message categories. FLOG is only used on the daemon side to
401 * output messages to the log file. */