Fixed for latest source.
[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-07-17 15:20:05
11+++ generator.c 2004-07-17 10:23:13
12@@ -251,7 +251,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@@ -418,8 +418,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@@ -427,18 +429,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_byte(f_nameout, 0);
56 write_int(f_out,i);
57 if (!dry_run)
58 write_sum_head(f_out, NULL);
59@@ -458,19 +464,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_byte(f_nameout, 0);
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@@ -478,17 +486,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_byte(f_nameout, 0);
96 write_int(f_out,i);
97 return;
98 }
99
100 if (whole_file > 0) {
101+ if (f_nameout >= 0)
102+ write_byte(f_nameout, 0);
103 write_int(f_out,i);
104 write_sum_head(f_out, NULL);
105 return;
106@@ -503,6 +515,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_byte(f_nameout, 0);
112 write_int(f_out,i);
113 write_sum_head(f_out, NULL);
114 return;
115@@ -521,6 +535,22 @@ 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+ uchar lenbuf[3], *lb = lenbuf;
121+ int len = strlen(fnamecmpbuf);
122+ if (len > 127) {
123+#if MAXPATHLEN > 32767
124+ *lb++ = len / 0x10000 + 0x80;
125+ *lb++ = len / 0x100;
126+#else
127+ *lb++ = len / 0x100 + 0x80;
128+#endif
129+ }
130+ *lb = len;
131+ write_buf(f_nameout, lenbuf, lb - lenbuf + 1);
132+ write_buf(f_nameout, fnamecmpbuf, len);
133+ }
134+
135 write_int(f_out,i);
136 generate_and_send_sums(mapbuf, st.st_size, f_out);
137
138@@ -530,7 +560,8 @@ static void recv_generator(char *fname,
139 }
140
141
142-void generate_files(int f_out, struct file_list *flist, char *local_name)
143+void generate_files(int f_out, struct file_list *flist, char *local_name,
144+ int f_nameout)
145 {
146 int i;
147 int phase = 0;
148@@ -571,7 +602,7 @@ void generate_files(int f_out, struct fi
149 }
150
151 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
152- file, i, f_out);
153+ file, i, f_out, f_nameout);
154 }
155
156 phase++;
157@@ -588,7 +619,7 @@ void generate_files(int f_out, struct fi
158 while ((i = get_redo_num()) != -1) {
159 struct file_struct *file = flist->files[i];
160 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
161- file, i, f_out);
162+ file, i, f_out, f_nameout);
163 }
164
165 phase++;
166@@ -607,7 +638,7 @@ void generate_files(int f_out, struct fi
167 if (!file->basename || !S_ISDIR(file->mode))
168 continue;
169 recv_generator(local_name ? local_name : f_name(file),
170- file, i, -1);
171+ file, i, -1, -1);
172 }
173
174 if (verbose > 2)
175--- orig/main.c 2004-07-17 15:20:05
176+++ main.c 2004-07-17 15:22:08
177@@ -444,7 +444,7 @@ static int do_recv(int f_in,int f_out,st
178 {
179 int pid;
180 int status = 0;
181- int error_pipe[2];
182+ int error_pipe[2], name_pipe[2];
183
184 if (preserve_hard_links)
185 init_hard_links(flist);
186@@ -456,8 +456,8 @@ static int do_recv(int f_in,int f_out,st
187 }
188 }
189
190- if (fd_pair(error_pipe) < 0) {
191- rprintf(FERROR,"error pipe failed in do_recv\n");
192+ if (fd_pair(error_pipe) < 0 || fd_pair(name_pipe) < 0) {
193+ rprintf(FERROR, "fd_pair() failed in do_recv\n");
194 exit_cleanup(RERR_SOCKETIO);
195 }
196
197@@ -465,8 +465,10 @@ static int do_recv(int f_in,int f_out,st
198
199 if ((pid = do_fork()) == 0) {
200 close(error_pipe[0]);
201+ close(name_pipe[1]);
202 if (f_in != f_out)
203 close(f_out);
204+ set_blocking(name_pipe[0]);
205
206 /* we can't let two processes write to the socket at one time */
207 io_multiplexing_close();
208@@ -474,7 +476,7 @@ static int do_recv(int f_in,int f_out,st
209 /* set place to send errors */
210 set_msg_fd_out(error_pipe[1]);
211
212- recv_files(f_in,flist,local_name);
213+ recv_files(f_in, flist, local_name, name_pipe[0]);
214 io_flush(FULL_FLUSH);
215 report(f_in);
216
217@@ -492,14 +494,16 @@ static int do_recv(int f_in,int f_out,st
218 stop_write_batch();
219
220 close(error_pipe[1]);
221+ close(name_pipe[0]);
222 if (f_in != f_out)
223 close(f_in);
224+ set_nonblocking(name_pipe[1]);
225
226 io_start_buffering_out();
227
228 set_msg_fd_in(error_pipe[0]);
229
230- generate_files(f_out, flist, local_name);
231+ generate_files(f_out, flist, local_name, name_pipe[1]);
232
233 get_redo_num(); /* Read final MSG_DONE and any prior messages. */
234 report(-1);
235--- orig/receiver.c 2004-07-16 20:07:22
236+++ receiver.c 2004-07-17 11:05:36
237@@ -304,7 +304,8 @@ static int receive_data(int f_in,struct
238 * main routine for receiver process.
239 *
240 * Receiver process runs on the same host as the generator process. */
241-int recv_files(int f_in, struct file_list *flist, char *local_name)
242+int recv_files(int f_in, struct file_list *flist, char *local_name,
243+ int f_name)
244 {
245 int fd1,fd2;
246 STRUCT_STAT st;
247@@ -317,7 +318,7 @@ int recv_files(int f_in, struct file_lis
248 struct file_struct *file;
249 struct stats initial_stats;
250 int save_make_backups = make_backups;
251- int i, recv_ok, phase = 0;
252+ int i, len, recv_ok, phase = 0;
253
254 if (verbose > 2)
255 rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
256@@ -373,19 +374,25 @@ int recv_files(int f_in, struct file_lis
257 if (verbose > 2)
258 rprintf(FINFO,"recv_files(%s)\n",fname);
259
260- fnamecmp = fname;
261+ len = read_byte(f_name);
262+ if (len & 0x80) {
263+#if MAXPATHLEN > 32767
264+ read_buf(f_name, fnamecmpbuf, 2);
265+ len = (len & ~0x80) * 0x10000
266+ + fnamecmpbuf[0] * 0x100 + fnamecmpbuf[1];
267+#else
268+ len = (len & ~0x80) * 0x100 + read_byte(f_name);
269+#endif
270+ }
271+ if (len) {
272+ read_sbuf(f_name, fnamecmpbuf, len);
273+ fnamecmp = fnamecmpbuf;
274+ } else
275+ fnamecmp = fname;
276
277 /* open the file */
278 fd1 = do_open(fnamecmp, O_RDONLY, 0);
279
280- if (fd1 == -1 && compare_dest != NULL) {
281- /* try the file at compare_dest instead */
282- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
283- compare_dest, fname);
284- fnamecmp = fnamecmpbuf;
285- fd1 = do_open(fnamecmp, O_RDONLY, 0);
286- }
287-
288 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
289 rsyserr(FERROR, errno, "fstat %s failed",
290 full_fname(fnamecmp));