1 From: Rusty Russell <rusty@rustcorp.com.au>
2 Date: Wed, 03 Apr 2002 17:08:57 +1000
4 Found old patch on google, and updated it for 2.5.4 (I know, but that's what
5 apt-get source gave me).
7 Compiles, otherwise untested.
10 [Updated for current CVS version by Wayne Davison. Passes *MOST* of the
11 test suite, but otherwise UNTESTED.]
13 Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
15 --- Makefile.in 10 Feb 2004 17:06:11 -0000 1.98
16 +++ Makefile.in 22 Apr 2004 23:48:20 -0000
17 @@ -32,7 +32,7 @@ ZLIBOBJ=zlib/deflate.o zlib/infblock.o z
18 zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
19 zlib/zutil.o zlib/adler32.o
20 OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \
21 - main.o checksum.o match.o syscall.o log.o backup.o
22 + main.o checksum.o match.o syscall.o log.o backup.o alternate.o
23 OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
24 fileio.o batch.o clientname.o
25 OBJS3=progress.o pipe.o
26 --- generator.c 15 Apr 2004 16:55:23 -0000 1.79
27 +++ generator.c 22 Apr 2004 23:48:20 -0000
28 @@ -50,6 +50,7 @@ extern int list_only;
29 extern int only_existing;
30 extern int orig_umask;
31 extern int safe_symlinks;
35 /* choose whether to skip a particular file */
36 @@ -255,7 +256,62 @@ static void generate_and_send_sums(struc
40 +/* Returns -1 for can't open (null file), -2 for skip */
41 +static int open_base_file(struct file_struct *file, char *fname, int statret,
47 + if (S_ISREG(st->st_mode)) {
49 + && cmp_modtime(st->st_mtime, file->modtime) > 0) {
51 + rprintf(FINFO, "%s is newer\n", fname);
54 + if (skip_file(fname, file, st)) {
55 + set_perms(fname, file, st, 1);
58 + fd = do_open(fname, O_RDONLY, 0);
60 + rprintf(FERROR, "failed to open %s, continuing : %s\n",
61 + full_fname(fname), strerror(errno));
66 + /* Try to use symlink contents */
67 + if (S_ISLNK(st->st_mode)) {
68 + fd = do_open_regular(fname);
69 + /* Don't delete yet; receiver will need it */
71 + if (delete_file(fname) != 0) {
80 + if (fd == -1 && compare_dest != NULL)
81 + fd = open_alternate_base_comparedir(fname);
83 + if (fd == -1 && fuzzy)
84 + fd = open_alternate_base_fuzzy(fname);
86 + /* Update stat to understand size */
88 + if (do_fstat(fd, st) != 0) {
89 + rprintf(FERROR, "fstat %s : %s\n",
90 + full_fname(fname), strerror(errno));
98 * Acts on file number @p i from @p flist, whose name is @p fname.
99 @@ -271,8 +327,6 @@ void recv_generator(char *fname, struct
101 struct map_struct *mapbuf;
104 - char fnamecmpbuf[MAXPATHLEN];
108 @@ -396,108 +450,38 @@ void recv_generator(char *fname, struct
112 - if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
115 - if (!S_ISREG(file->mode)) {
116 - rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
122 - if (statret == -1 && compare_dest != NULL) {
123 - /* try the file at compare_dest instead */
124 - int saveerrno = errno;
125 - pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
126 - statret = link_stat(fnamecmpbuf,&st);
127 - if (!S_ISREG(st.st_mode))
132 - else if (link_dest && !dry_run) {
133 - if (do_link(fnamecmpbuf, fname) != 0) {
135 - rprintf(FINFO,"link %s => %s : %s\n",
136 - fnamecmpbuf, fname,
140 - fnamecmp = fnamecmpbuf;
144 - fnamecmp = fnamecmpbuf;
147 - if (statret == -1) {
148 - if (preserve_hard_links && hard_link_check(file, HL_SKIP))
150 - if (errno == ENOENT) {
151 - write_int(f_out,i);
152 - if (!dry_run) write_sum_head(f_out, NULL);
153 - } else if (verbose > 1) {
154 + /* Failed to stat for some reason besides "not found". */
155 + if (statret == -1 && errno != ENOENT) {
158 - "recv_generator: failed to open %s: %s\n",
159 + "recv_generator failed to stat %s: %s\n",
160 full_fname(fname), strerror(errno));
165 - if (!S_ISREG(st.st_mode)) {
166 - if (delete_file(fname) != 0) {
170 - /* now pretend the file didn't exist */
171 - if (preserve_hard_links && hard_link_check(file, HL_SKIP))
173 - write_int(f_out,i);
174 - if (!dry_run) write_sum_head(f_out, NULL);
175 + if ((fd = open_base_file(file, fname, statret, &st)) == -2)
179 - if (opt_ignore_existing && fnamecmp == fname) {
181 - rprintf(FINFO,"%s exists\n",fname);
185 - if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
187 - rprintf(FINFO,"%s is newer\n",fname);
189 + if ((disable_deltas_p() || dry_run) && fd != -1) {
194 - if (skip_file(fname, file, &st)) {
195 - if (fnamecmp == fname)
196 - set_perms(fname,file,&st,1);
201 - write_int(f_out,i);
205 - if (disable_deltas_p()) {
206 - write_int(f_out,i);
207 - write_sum_head(f_out, NULL);
211 - /* open the file */
212 - fd = do_open(fnamecmp, O_RDONLY, 0);
215 - rprintf(FERROR, "failed to open %s, continuing: %s\n",
216 - full_fname(fnamecmp), strerror(errno));
217 - /* pretend the file didn't exist */
218 + /* the file didn't exist, or we can pretend it doesn't */
219 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
221 - write_int(f_out,i);
222 - write_sum_head(f_out, NULL);
223 + write_int(f_out, i);
225 + write_sum_head(f_out, NULL);
229 + if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
232 + if (!S_ISREG(file->mode)) {
233 + rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
237 @@ -507,7 +491,7 @@ void recv_generator(char *fname, struct
241 - rprintf(FINFO,"gen mapped %s of size %.0f\n", fnamecmp,
242 + rprintf(FINFO, "gen mapped %s of size %.0f\n", fname,
246 --- options.c 17 Apr 2004 17:07:23 -0000 1.147
247 +++ options.c 22 Apr 2004 23:48:20 -0000
248 @@ -91,6 +91,7 @@ int ignore_errors = 0;
249 int modify_window = 0;
250 int blocking_io = -1;
251 int checksum_seed = 0;
253 unsigned int block_size = 0;
256 @@ -290,6 +291,7 @@ void usage(enum logcode F)
257 rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
258 rprintf(F," --write-batch=PREFIX write batch fileset starting with PREFIX\n");
259 rprintf(F," --read-batch=PREFIX read batch fileset starting with PREFIX\n");
260 + rprintf(F," --fuzzy use similar file as basis if it does't exist\n");
261 rprintf(F," -h, --help show this help screen\n");
263 rprintf(F," -4 prefer IPv4\n");
264 @@ -385,6 +387,7 @@ static struct poptOption long_options[]
265 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
266 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
267 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
268 + {"fuzzy", 0, POPT_ARG_NONE, &fuzzy, 0, 0, 0 },
269 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
271 {0, '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
272 @@ -964,6 +967,9 @@ void server_options(char **args,int *arg
273 args[ac++] = "--from0";
277 + if (fuzzy && am_sender)
278 + args[ac++] = "--fuzzy";
282 --- receiver.c 23 Mar 2004 16:50:40 -0000 1.75
283 +++ receiver.c 22 Apr 2004 23:48:20 -0000
284 @@ -45,6 +45,7 @@ extern int cleanup_got_literal;
285 extern int module_id;
286 extern int ignore_errors;
287 extern int orig_umask;
290 static void delete_one(char *fn, int is_dir)
292 @@ -292,8 +293,6 @@ int recv_files(int f_in,struct file_list
293 char *fname, fbuf[MAXPATHLEN];
294 char template[MAXPATHLEN];
295 char fnametmp[MAXPATHLEN];
297 - char fnamecmpbuf[MAXPATHLEN];
298 struct map_struct *mapbuf;
300 struct file_struct *file;
301 @@ -356,35 +355,31 @@ int recv_files(int f_in,struct file_list
303 rprintf(FINFO,"recv_files(%s)\n",fname);
308 - fd1 = do_open(fnamecmp, O_RDONLY, 0);
309 + fd1 = do_open(fname, O_RDONLY, 0);
311 - if (fd1 == -1 && compare_dest != NULL) {
312 - /* try the file at compare_dest instead */
313 - pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
314 - compare_dest, fname);
315 - fnamecmp = fnamecmpbuf;
316 - fd1 = do_open(fnamecmp, O_RDONLY, 0);
318 + if (fd1 == -1 && compare_dest != NULL)
319 + fd1 = open_alternate_base_comparedir(fname);
321 + if (fd1 == -1 && fuzzy)
322 + fd1 = open_alternate_base_fuzzy(fname);
324 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
325 rprintf(FERROR, "fstat %s failed: %s\n",
326 - full_fname(fnamecmp), strerror(errno));
327 + full_fname(fname), strerror(errno));
328 receive_data(f_in,NULL,-1,NULL,file->length);
333 - if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) {
334 + if (fd1 != -1 && S_ISDIR(st.st_mode)) {
335 /* this special handling for directories
336 * wouldn't be necessary if robust_rename()
337 * and the underlying robust_unlink could cope
340 rprintf(FERROR,"recv_files: %s is a directory\n",
341 - full_fname(fnamecmp));
342 + full_fname(fname));
343 receive_data(f_in, NULL, -1, NULL, file->length);
346 @@ -405,8 +400,10 @@ int recv_files(int f_in,struct file_list
348 if (fd1 != -1 && st.st_size > 0) {
349 mapbuf = map_file(fd1,st.st_size);
351 - rprintf(FINFO,"recv mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
353 + rprintf(FINFO, "recv mapped %s of size %.0f\n",
354 + fname, (double)st.st_size);