Updated.
[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
f6c3b300 10--- orig/generator.c 2004-07-16 19:35:29
13bed3dd 11+++ generator.c 2004-07-03 20:08:07
f6c3b300 12@@ -251,7 +251,7 @@ static void generate_and_send_sums(struc
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)
17+ int f_out, int f_nameout)
18 {
19 int fd;
20 STRUCT_STAT st;
f6c3b300 21@@ -418,8 +418,10 @@ static void recv_generator(char *fname,
77945073
WD
22 statret = link_stat(fnamecmpbuf, &st, 0);
23 if (!S_ISREG(st.st_mode))
24 statret = -1;
25- if (statret == -1)
26+ if (statret < 0) {
27 errno = saveerrno;
28+ *fnamecmpbuf = '\0';
29+ }
30 #if HAVE_LINK
31 else if (link_dest && !dry_run) {
32 if (do_link(fnamecmpbuf, fname) != 0) {
f6c3b300 33@@ -427,18 +429,22 @@ static void recv_generator(char *fname,
77945073
WD
34 rsyserr(FINFO, errno, "link %s => %s",
35 fnamecmpbuf, fname);
36 }
37- }
38- fnamecmp = fnamecmpbuf;
39+ fnamecmp = fnamecmpbuf;
40+ } else
41+ *fnamecmpbuf = '\0';
42 }
43 #endif
44 else
45 fnamecmp = fnamecmpbuf;
46- }
47+ } else
48+ *fnamecmpbuf = '\0';
49
50 if (statret == -1) {
51 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
52 return;
53 if (errno == ENOENT) {
54+ if (f_nameout >= 0)
55+ write(f_nameout, "", 1);
56 write_int(f_out,i);
57 if (!dry_run)
58 write_sum_head(f_out, NULL);
f6c3b300 59@@ -458,19 +464,21 @@ static void recv_generator(char *fname,
77945073
WD
60 /* now pretend the file didn't exist */
61 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
62 return;
63+ if (f_nameout >= 0)
64+ write(f_nameout, "", 1);
65 write_int(f_out,i);
66 if (!dry_run)
67 write_sum_head(f_out, NULL);
68 return;
69 }
70
71- if (opt_ignore_existing && fnamecmp == fname) {
72+ if (opt_ignore_existing && !*fnamecmpbuf) {
73 if (verbose > 1)
74 rprintf(FINFO,"%s exists\n",fname);
75 return;
76 }
77
78- if (update_only && fnamecmp == fname
79+ if (update_only && !*fnamecmpbuf
80 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
81 if (verbose > 1)
82 rprintf(FINFO,"%s is newer\n",fname);
f6c3b300 83@@ -478,17 +486,21 @@ static void recv_generator(char *fname,
77945073
WD
84 }
85
86 if (skip_file(fname, file, &st)) {
87- if (fnamecmp == fname)
88+ if (!*fnamecmpbuf)
89 set_perms(fname, file, &st, PERMS_REPORT);
90 return;
91 }
92
93 if (dry_run) {
94+ if (f_nameout >= 0)
95+ write(f_nameout, "", 1);
96 write_int(f_out,i);
97 return;
98 }
99
9be39c35 100 if (whole_file > 0) {
77945073
WD
101+ if (f_nameout >= 0)
102+ write(f_nameout, "", 1);
103 write_int(f_out,i);
104 write_sum_head(f_out, NULL);
105 return;
f6c3b300 106@@ -503,6 +515,8 @@ static void recv_generator(char *fname,
77945073
WD
107 /* pretend the file didn't exist */
108 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
109 return;
110+ if (f_nameout >= 0)
111+ write(f_nameout, "", 1);
112 write_int(f_out,i);
113 write_sum_head(f_out, NULL);
114 return;
f6c3b300 115@@ -521,6 +535,8 @@ static void recv_generator(char *fname,
77945073
WD
116 if (verbose > 2)
117 rprintf(FINFO, "generating and sending sums for %d\n", i);
118
119+ if (f_nameout >= 0)
120+ write(f_nameout, fnamecmpbuf, strlen(fnamecmpbuf) + 1);
121 write_int(f_out,i);
122 generate_and_send_sums(mapbuf, st.st_size, f_out);
123
f6c3b300 124@@ -530,7 +546,8 @@ static void recv_generator(char *fname,
77945073
WD
125 }
126
127
9be39c35
WD
128-void generate_files(int f_out, struct file_list *flist, char *local_name)
129+void generate_files(int f_out, struct file_list *flist, char *local_name,
77945073
WD
130+ int f_nameout)
131 {
132 int i;
8cec1ead 133 int phase = 0;
f6c3b300 134@@ -571,7 +588,7 @@ void generate_files(int f_out, struct fi
77945073
WD
135 }
136
137 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
9be39c35
WD
138- file, i, f_out);
139+ file, i, f_out, f_nameout);
77945073
WD
140 }
141
142 phase++;
f6c3b300 143@@ -588,7 +605,7 @@ void generate_files(int f_out, struct fi
77945073
WD
144 while ((i = get_redo_num()) != -1) {
145 struct file_struct *file = flist->files[i];
146 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
9be39c35
WD
147- file, i, f_out);
148+ file, i, f_out, f_nameout);
77945073
WD
149 }
150
151 phase++;
f6c3b300 152@@ -607,7 +624,7 @@ void generate_files(int f_out, struct fi
77945073
WD
153 if (!file->basename || !S_ISDIR(file->mode))
154 continue;
155 recv_generator(local_name ? local_name : f_name(file),
156- file, i, -1);
157+ file, i, -1, -1);
158 }
159
160 if (verbose > 2)
9be39c35 161--- orig/main.c 2004-07-15 17:02:03
13bed3dd 162+++ main.c 2004-07-03 20:08:07
9be39c35 163@@ -443,7 +443,7 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
164 {
165 int pid;
8cec1ead 166 int status = 0;
77945073 167- int error_pipe[2];
77945073
WD
168+ int error_pipe[2], name_pipe[2];
169
170 if (preserve_hard_links)
171 init_hard_links(flist);
9be39c35 172@@ -455,8 +455,8 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
173 }
174 }
175
176- if (fd_pair(error_pipe) < 0) {
177- rprintf(FERROR,"error pipe failed in do_recv\n");
178+ if (fd_pair(error_pipe) < 0 || fd_pair(name_pipe) < 0) {
179+ rprintf(FERROR, "fd_pair() failed in do_recv\n");
180 exit_cleanup(RERR_SOCKETIO);
181 }
182
9be39c35 183@@ -464,8 +464,10 @@ static int do_recv(int f_in,int f_out,st
77945073 184
8cec1ead 185 if ((pid = do_fork()) == 0) {
77945073
WD
186 close(error_pipe[0]);
187+ close(name_pipe[1]);
188 if (f_in != f_out)
189 close(f_out);
190+ set_blocking(name_pipe[0]);
191
192 /* we can't let two processes write to the socket at one time */
193 io_multiplexing_close();
9be39c35 194@@ -473,7 +475,7 @@ static int do_recv(int f_in,int f_out,st
77945073
WD
195 /* set place to send errors */
196 set_msg_fd_out(error_pipe[1]);
197
198- recv_files(f_in,flist,local_name);
199+ recv_files(f_in, flist, local_name, name_pipe[0]);
200 io_flush(FULL_FLUSH);
201 report(f_in);
202
9be39c35
WD
203@@ -491,14 +493,16 @@ static int do_recv(int f_in,int f_out,st
204 stop_write_batch();
77945073
WD
205
206 close(error_pipe[1]);
207+ close(name_pipe[0]);
208 if (f_in != f_out)
209 close(f_in);
210+ set_blocking(name_pipe[1]);
211
212 io_start_buffering_out(f_out);
213
214 set_msg_fd_in(error_pipe[0]);
215
216- generate_files(f_out, flist, local_name);
217+ generate_files(f_out, flist, local_name, name_pipe[1]);
218
219 get_redo_num(); /* Read final MSG_DONE and any prior messages. */
220 report(-1);
f6c3b300 221--- orig/receiver.c 2004-07-16 20:07:22
13bed3dd 222+++ receiver.c 2004-07-03 20:08:07
f6c3b300 223@@ -304,14 +304,15 @@ static int receive_data(int f_in,struct
77945073
WD
224 * main routine for receiver process.
225 *
226 * Receiver process runs on the same host as the generator process. */
9be39c35 227-int recv_files(int f_in, struct file_list *flist, char *local_name)
77945073
WD
228+int recv_files(int f_in, struct file_list *flist, char *local_name,
229+ int f_name)
230 {
231 int fd1,fd2;
232 STRUCT_STAT st;
233 char *fname, fbuf[MAXPATHLEN];
234 char template[MAXPATHLEN];
235 char fnametmp[MAXPATHLEN];
236- char *fnamecmp;
237+ char *fnamecmp, *cp;
238 char fnamecmpbuf[MAXPATHLEN];
239 struct map_struct *mapbuf;
240 struct file_struct *file;
f6c3b300 241@@ -373,19 +374,19 @@ int recv_files(int f_in, struct file_lis
77945073
WD
242 if (verbose > 2)
243 rprintf(FINFO,"recv_files(%s)\n",fname);
244
245- fnamecmp = fname;
246+ for (cp = fnamecmpbuf; ; cp++) {
247+ if (read(f_name, cp, 1) <= 0) {
248+ rsyserr(FERROR, errno, "fname-pipe read failed");
249+ exit_cleanup(RERR_PROTOCOL);
250+ }
251+ if (!*cp)
252+ break;
253+ }
254+ fnamecmp = *fnamecmpbuf ? fnamecmpbuf : fname;
255
256 /* open the file */
257 fd1 = do_open(fnamecmp, O_RDONLY, 0);
258
259- if (fd1 == -1 && compare_dest != NULL) {
260- /* try the file at compare_dest instead */
261- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
262- compare_dest, fname);
263- fnamecmp = fnamecmpbuf;
264- fd1 = do_open(fnamecmp, O_RDONLY, 0);
265- }
266-
267 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
268 rsyserr(FERROR, errno, "fstat %s failed",
269 full_fname(fnamecmp));
f6c3b300 270@@ -394,7 +395,7 @@ int recv_files(int f_in, struct file_lis
77945073
WD
271 continue;
272 }
273
274- if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) {
275+ if (fd1 != -1 && S_ISDIR(st.st_mode) && !*fnamecmpbuf) {
276 /* this special handling for directories
277 * wouldn't be necessary if robust_rename()
278 * and the underlying robust_unlink could cope