Incorporated the g2r-basis-filename.diff changes so that we don't
[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
10--- generator.c 29 Jun 2004 19:19:00 -0000 1.92
11+++ generator.c 29 Jun 2004 19:24:22 -0000
12@@ -267,7 +267,7 @@ static void generate_and_send_sums(struc
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;
21@@ -431,8 +431,10 @@ static void recv_generator(char *fname,
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) {
33@@ -440,18 +442,22 @@ static void recv_generator(char *fname,
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);
59@@ -471,19 +477,21 @@ static void recv_generator(char *fname,
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);
83@@ -491,17 +499,21 @@ static void recv_generator(char *fname,
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
100 if (disable_deltas_p()) {
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;
106@@ -516,6 +528,8 @@ static void recv_generator(char *fname,
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;
115@@ -534,6 +548,8 @@ static void recv_generator(char *fname,
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
124@@ -543,10 +559,11 @@ static void recv_generator(char *fname,
125 }
126
127
128-void generate_files(int f, struct file_list *flist, char *local_name)
129+void generate_files(int f, struct file_list *flist, char *local_name,
130+ int f_nameout)
131 {
132 int i;
133- int phase=0;
134+ int phase = 0;
135 char fbuf[MAXPATHLEN];
136
137 if (verbose > 2) {
138@@ -584,7 +601,7 @@ void generate_files(int f, struct file_l
139 }
140
141 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
142- file, i, f);
143+ file, i, f, f_nameout);
144 }
145
146 phase++;
147@@ -601,7 +618,7 @@ void generate_files(int f, struct file_l
148 while ((i = get_redo_num()) != -1) {
149 struct file_struct *file = flist->files[i];
150 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
151- file, i, f);
152+ file, i, f, f_nameout);
153 }
154
155 phase++;
156@@ -620,7 +637,7 @@ void generate_files(int f, struct file_l
157 if (!file->basename || !S_ISDIR(file->mode))
158 continue;
159 recv_generator(local_name ? local_name : f_name(file),
160- file, i, -1);
161+ file, i, -1, -1);
162 }
163
164 if (verbose > 2)
165--- main.c 28 Jun 2004 17:45:40 -0000 1.201
166+++ main.c 29 Jun 2004 19:24:22 -0000
167@@ -428,8 +428,8 @@ static void do_server_sender(int f_in, i
168 static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
169 {
170 int pid;
171- int status=0;
172- int error_pipe[2];
173+ int status = 0;
174+ int error_pipe[2], name_pipe[2];
175
176 if (preserve_hard_links)
177 init_hard_links(flist);
178@@ -441,17 +441,19 @@ static int do_recv(int f_in,int f_out,st
179 }
180 }
181
182- if (fd_pair(error_pipe) < 0) {
183- rprintf(FERROR,"error pipe failed in do_recv\n");
184+ if (fd_pair(error_pipe) < 0 || fd_pair(name_pipe) < 0) {
185+ rprintf(FERROR, "fd_pair() failed in do_recv\n");
186 exit_cleanup(RERR_SOCKETIO);
187 }
188
189 io_flush(NORMAL_FLUSH);
190
191- if ((pid=do_fork()) == 0) {
192+ if ((pid = do_fork()) == 0) {
193 close(error_pipe[0]);
194+ close(name_pipe[1]);
195 if (f_in != f_out)
196 close(f_out);
197+ set_blocking(name_pipe[0]);
198
199 /* we can't let two processes write to the socket at one time */
200 io_multiplexing_close();
201@@ -459,7 +461,7 @@ static int do_recv(int f_in,int f_out,st
202 /* set place to send errors */
203 set_msg_fd_out(error_pipe[1]);
204
205- recv_files(f_in,flist,local_name);
206+ recv_files(f_in, flist, local_name, name_pipe[0]);
207 io_flush(FULL_FLUSH);
208 report(f_in);
209
210@@ -475,14 +477,16 @@ static int do_recv(int f_in,int f_out,st
211 am_generator = 1;
212
213 close(error_pipe[1]);
214+ close(name_pipe[0]);
215 if (f_in != f_out)
216 close(f_in);
217+ set_blocking(name_pipe[1]);
218
219 io_start_buffering_out(f_out);
220
221 set_msg_fd_in(error_pipe[0]);
222
223- generate_files(f_out, flist, local_name);
224+ generate_files(f_out, flist, local_name, name_pipe[1]);
225
226 get_redo_num(); /* Read final MSG_DONE and any prior messages. */
227 report(-1);
228--- receiver.c 29 Jun 2004 15:12:01 -0000 1.83
229+++ receiver.c 29 Jun 2004 19:24:22 -0000
230@@ -293,14 +293,15 @@ static int receive_data(int f_in,struct
231 * main routine for receiver process.
232 *
233 * Receiver process runs on the same host as the generator process. */
234-int recv_files(int f_in,struct file_list *flist,char *local_name)
235+int recv_files(int f_in, struct file_list *flist, char *local_name,
236+ int f_name)
237 {
238 int fd1,fd2;
239 STRUCT_STAT st;
240 char *fname, fbuf[MAXPATHLEN];
241 char template[MAXPATHLEN];
242 char fnametmp[MAXPATHLEN];
243- char *fnamecmp;
244+ char *fnamecmp, *cp;
245 char fnamecmpbuf[MAXPATHLEN];
246 struct map_struct *mapbuf;
247 struct file_struct *file;
248@@ -364,19 +365,19 @@ int recv_files(int f_in,struct file_list
249 if (verbose > 2)
250 rprintf(FINFO,"recv_files(%s)\n",fname);
251
252- fnamecmp = fname;
253+ for (cp = fnamecmpbuf; ; cp++) {
254+ if (read(f_name, cp, 1) <= 0) {
255+ rsyserr(FERROR, errno, "fname-pipe read failed");
256+ exit_cleanup(RERR_PROTOCOL);
257+ }
258+ if (!*cp)
259+ break;
260+ }
261+ fnamecmp = *fnamecmpbuf ? fnamecmpbuf : fname;
262
263 /* open the file */
264 fd1 = do_open(fnamecmp, O_RDONLY, 0);
265
266- if (fd1 == -1 && compare_dest != NULL) {
267- /* try the file at compare_dest instead */
268- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
269- compare_dest, fname);
270- fnamecmp = fnamecmpbuf;
271- fd1 = do_open(fnamecmp, O_RDONLY, 0);
272- }
273-
274 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
275 rsyserr(FERROR, errno, "fstat %s failed",
276 full_fname(fnamecmp));
277@@ -385,7 +386,7 @@ int recv_files(int f_in,struct file_list
278 continue;
279 }
280
281- if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) {
282+ if (fd1 != -1 && S_ISDIR(st.st_mode) && !*fnamecmpbuf) {
283 /* this special handling for directories
284 * wouldn't be necessary if robust_rename()
285 * and the underlying robust_unlink could cope