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 15 May 2004 00:48:11 -0000 1.101
16 +++ Makefile.in 18 Jun 2004 17:32:53 -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 18 Jun 2004 16:30:24 -0000 1.88
27 +++ generator.c 18 Jun 2004 17:32:53 -0000
28 @@ -41,6 +41,7 @@ extern int ignore_times;
30 extern int io_timeout;
31 extern int protocol_version;
33 extern int always_checksum;
34 extern char *compare_dest;
36 @@ -259,7 +260,61 @@ 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, PERMS_REPORT);
58 + fd = do_open(fname, O_RDONLY, 0);
60 + rsyserr(FERROR, errno, "failed to open %s, continuing",
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 + rsyserr(FERROR, errno, "fstat %s", full_fname(fname));
97 * Acts on file number @p i from @p flist, whose name is @p fname.
98 @@ -275,8 +330,6 @@ void recv_generator(char *fname, struct
100 struct map_struct *mapbuf;
103 - char fnamecmpbuf[MAXPATHLEN];
107 @@ -416,109 +469,39 @@ void recv_generator(char *fname, struct
111 - if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
114 - if (!S_ISREG(file->mode)) {
115 - rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
121 - if (statret == -1 && compare_dest != NULL) {
122 - /* try the file at compare_dest instead */
123 - int saveerrno = errno;
124 - pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
125 - statret = link_stat(fnamecmpbuf, &st, 0);
126 - if (!S_ISREG(st.st_mode))
131 - else if (link_dest && !dry_run) {
132 - if (do_link(fnamecmpbuf, fname) != 0) {
134 - rsyserr(FINFO, errno, "link %s => %s",
135 - fnamecmpbuf, fname);
138 - fnamecmp = fnamecmpbuf;
142 - fnamecmp = fnamecmpbuf;
145 - if (statret == -1) {
146 - if (preserve_hard_links && hard_link_check(file, HL_SKIP))
148 - if (errno == ENOENT) {
149 - write_int(f_out,i);
151 - write_sum_head(f_out, NULL);
152 - } else if (verbose > 1) {
153 + /* Failed to stat for some reason besides "not found". */
154 + if (statret == -1 && errno != ENOENT) {
156 rsyserr(FERROR, errno,
157 - "recv_generator: failed to open %s",
158 + "recv_generator failed to stat %s",
164 - if (!S_ISREG(st.st_mode)) {
165 - if (delete_file(fname) != 0) {
168 + if ((fd = open_base_file(file, fname, statret, &st)) == -2)
171 - /* now pretend the file didn't exist */
172 + if ((disable_deltas_p() || dry_run) && fd != -1) {
178 + /* the file didn't exist, or we can pretend it doesn't */
179 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
181 - write_int(f_out,i);
182 + write_int(f_out, i);
184 write_sum_head(f_out, NULL);
188 - if (opt_ignore_existing && fnamecmp == fname) {
190 - rprintf(FINFO,"%s exists\n",fname);
196 - if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
198 - rprintf(FINFO,"%s is newer\n",fname);
202 - if (skip_file(fname, file, &st)) {
203 - if (fnamecmp == fname)
204 - set_perms(fname, file, &st, PERMS_REPORT);
209 - write_int(f_out,i);
213 - if (disable_deltas_p()) {
214 - write_int(f_out,i);
215 - write_sum_head(f_out, NULL);
216 + if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
220 - /* open the file */
221 - fd = do_open(fnamecmp, O_RDONLY, 0);
224 - rsyserr(FERROR, errno, "failed to open %s, continuing",
225 - full_fname(fnamecmp));
226 - /* pretend the file didn't exist */
227 - if (preserve_hard_links && hard_link_check(file, HL_SKIP))
229 - write_int(f_out,i);
230 - write_sum_head(f_out, NULL);
231 + if (!S_ISREG(file->mode)) {
232 + rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
236 @@ -528,7 +511,7 @@ void recv_generator(char *fname, struct
240 - rprintf(FINFO,"gen mapped %s of size %.0f\n", fnamecmp,
241 + rprintf(FINFO, "gen mapped %s of size %.0f\n", fname,
245 --- options.c 7 Jun 2004 22:05:22 -0000 1.156
246 +++ options.c 18 Jun 2004 17:32:54 -0000
247 @@ -94,6 +94,7 @@ int ignore_errors = 0;
248 int modify_window = 0;
249 int blocking_io = -1;
250 int checksum_seed = 0;
252 unsigned int block_size = 0;
255 @@ -270,6 +271,7 @@ void usage(enum logcode F)
256 rprintf(F," -T --temp-dir=DIR create temporary files in directory DIR\n");
257 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
258 rprintf(F," --link-dest=DIR create hardlinks to DIR for unchanged files\n");
259 + rprintf(F," --fuzzy use similar file as basis if basis doesn't exist\n");
260 rprintf(F," -P equivalent to --partial --progress\n");
261 rprintf(F," -z, --compress compress file data\n");
262 rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
263 @@ -368,6 +370,7 @@ static struct poptOption long_options[]
264 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
265 {"compare-dest", 0, POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
266 {"link-dest", 0, POPT_ARG_STRING, &compare_dest, OPT_LINK_DEST, 0, 0 },
267 + {"fuzzy", 0, POPT_ARG_NONE, &fuzzy, 0, 0, 0 },
268 /* TODO: Should this take an optional int giving the compression level? */
269 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
270 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
271 @@ -989,6 +992,9 @@ void server_options(char **args,int *arg
275 + if (fuzzy && am_sender)
276 + args[ac++] = "--fuzzy";
281 --- receiver.c 14 Jun 2004 15:09:36 -0000 1.82
282 +++ receiver.c 18 Jun 2004 17:32:54 -0000
283 @@ -48,6 +48,7 @@ extern int ignore_errors;
284 extern int orig_umask;
285 extern int keep_partial;
286 extern int checksum_seed;
289 static void delete_one(char *fn, int is_dir)
291 @@ -300,8 +301,6 @@ int recv_files(int f_in,struct file_list
292 char *fname, fbuf[MAXPATHLEN];
293 char template[MAXPATHLEN];
294 char fnametmp[MAXPATHLEN];
296 - char fnamecmpbuf[MAXPATHLEN];
297 struct map_struct *mapbuf;
298 struct file_struct *file;
299 struct stats initial_stats;
300 @@ -364,35 +363,31 @@ int recv_files(int f_in,struct file_list
302 rprintf(FINFO,"recv_files(%s)\n",fname);
307 - fd1 = do_open(fnamecmp, O_RDONLY, 0);
308 + fd1 = do_open(fname, O_RDONLY, 0);
310 - if (fd1 == -1 && compare_dest != NULL) {
311 - /* try the file at compare_dest instead */
312 - pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
313 - compare_dest, fname);
314 - fnamecmp = fnamecmpbuf;
315 - fd1 = do_open(fnamecmp, O_RDONLY, 0);
317 + if (fd1 == -1 && compare_dest != NULL)
318 + fd1 = open_alternate_base_comparedir(fname);
320 + if (fd1 == -1 && fuzzy)
321 + fd1 = open_alternate_base_fuzzy(fname);
323 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
324 rsyserr(FERROR, errno, "fstat %s failed",
325 - full_fname(fnamecmp));
326 + full_fname(fname));
327 receive_data(f_in,NULL,-1,NULL,file->length);
332 - if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) {
333 + if (fd1 != -1 && S_ISDIR(st.st_mode)) {
334 /* this special handling for directories
335 * wouldn't be necessary if robust_rename()
336 * and the underlying robust_unlink could cope
339 rprintf(FERROR,"recv_files: %s is a directory\n",
340 - full_fname(fnamecmp));
341 + full_fname(fname));
342 receive_data(f_in, NULL, -1, NULL, file->length);
345 @@ -413,8 +408,10 @@ int recv_files(int f_in,struct file_list
347 if (fd1 != -1 && st.st_size > 0) {
348 mapbuf = map_file(fd1,st.st_size);
350 - rprintf(FINFO,"recv mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
352 + rprintf(FINFO, "recv mapped %s of size %.0f\n",
353 + fname, (double)st.st_size);
358 --- rsync.yo 5 Jun 2004 16:16:30 -0000 1.171
359 +++ rsync.yo 18 Jun 2004 17:32:54 -0000
360 @@ -325,6 +325,7 @@ verb(
361 -T --temp-dir=DIR create temporary files in directory DIR
362 --compare-dest=DIR also compare received files relative to DIR
363 --link-dest=DIR create hardlinks to DIR for unchanged files
364 + --fuzzy use similar file as basis if basis is gone
365 -P equivalent to --partial --progress
366 -z, --compress compress file data
367 -C, --cvs-exclude auto ignore files in the same way CVS does