- Got rid of the main.c bugfix (it is now in CVS).
[rsync/rsync-patches.git] / fuzzy.diff
CommitLineData
241013b4 1From: Rusty Russell <rusty@rustcorp.com.au>
241013b4 2Date: Wed, 03 Apr 2002 17:08:57 +1000
241013b4 3
f74d2272
WD
4Found old patch on google, and updated it for 2.5.4 (I know, but that's what
5apt-get source gave me).
241013b4
MP
6
7Compiles, otherwise untested.
8Rusty.
f74d2272
WD
9
10[Updated for current CVS version by Wayne Davison. Passes *MOST* of the
11test suite, but otherwise UNTESTED.]
241013b4
MP
12--
13 Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
14
fe6407b5 15--- Makefile.in 15 May 2004 00:48:11 -0000 1.101
7628f156 16+++ Makefile.in 18 Jun 2004 17:32:53 -0000
54691942 17@@ -32,7 +32,7 @@ ZLIBOBJ=zlib/deflate.o zlib/infblock.o z
241013b4 18 zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
f74d2272
WD
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
7628f156
WD
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;
29 extern int size_only;
30 extern int io_timeout;
31 extern int protocol_version;
241013b4 32+extern int fuzzy;
7628f156
WD
33 extern int always_checksum;
34 extern char *compare_dest;
35 extern int link_dest;
36@@ -259,7 +260,61 @@ static void generate_and_send_sums(struc
f74d2272 37 }
241013b4
MP
38 }
39
40+/* Returns -1 for can't open (null file), -2 for skip */
f74d2272 41+static int open_base_file(struct file_struct *file, char *fname, int statret,
241013b4
MP
42+ STRUCT_STAT *st)
43+{
44+ int fd = -1;
7628f156 45
241013b4
MP
46+ if (statret == 0) {
47+ if (S_ISREG(st->st_mode)) {
48+ if (update_only
49+ && cmp_modtime(st->st_mtime, file->modtime) > 0) {
50+ if (verbose > 1)
f74d2272 51+ rprintf(FINFO, "%s is newer\n", fname);
241013b4
MP
52+ return -2;
53+ }
54+ if (skip_file(fname, file, st)) {
7f2baf27 55+ set_perms(fname, file, st, PERMS_REPORT);
241013b4
MP
56+ return -2;
57+ }
58+ fd = do_open(fname, O_RDONLY, 0);
59+ if (fd == -1) {
fe6407b5
WD
60+ rsyserr(FERROR, errno, "failed to open %s, continuing",
61+ full_fname(fname));
241013b4 62+ return -1;
f74d2272
WD
63+ }
64+ return fd;
241013b4
MP
65+ } else {
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 */
70+ } else {
71+ if (delete_file(fname) != 0) {
72+ if (fd != -1)
73+ close(fd);
74+ return -2;
75+ }
76+ }
77+ }
78+ }
79+
80+ if (fd == -1 && compare_dest != NULL)
81+ fd = open_alternate_base_comparedir(fname);
7b675ff5 82+
241013b4
MP
83+ if (fd == -1 && fuzzy)
84+ fd = open_alternate_base_fuzzy(fname);
85+
86+ /* Update stat to understand size */
87+ if (fd != -1) {
f74d2272 88+ if (do_fstat(fd, st) != 0) {
fe6407b5 89+ rsyserr(FERROR, errno, "fstat %s", full_fname(fname));
f74d2272 90+ }
241013b4 91+ }
7628f156 92+
241013b4
MP
93+ return fd;
94+}
95
f74d2272
WD
96 /**
97 * Acts on file number @p i from @p flist, whose name is @p fname.
7628f156 98@@ -275,8 +330,6 @@ void recv_generator(char *fname, struct
f74d2272
WD
99 STRUCT_STAT st;
100 struct map_struct *mapbuf;
241013b4 101 int statret;
241013b4
MP
102- char *fnamecmp;
103- char fnamecmpbuf[MAXPATHLEN];
54691942
WD
104
105 if (list_only)
106 return;
7628f156 107@@ -416,109 +469,39 @@ void recv_generator(char *fname, struct
241013b4 108 }
f74d2272 109 #endif
241013b4 110
f74d2272
WD
111- if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
112- return;
113-
114- if (!S_ISREG(file->mode)) {
115- rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
116- return;
117- }
118-
241013b4
MP
119- fnamecmp = fname;
120-
f74d2272 121- if (statret == -1 && compare_dest != NULL) {
241013b4
MP
122- /* try the file at compare_dest instead */
123- int saveerrno = errno;
f74d2272 124- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
7628f156 125- statret = link_stat(fnamecmpbuf, &st, 0);
241013b4
MP
126- if (!S_ISREG(st.st_mode))
127- statret = -1;
128- if (statret == -1)
129- errno = saveerrno;
f74d2272
WD
130-#if HAVE_LINK
131- else if (link_dest && !dry_run) {
132- if (do_link(fnamecmpbuf, fname) != 0) {
133- if (verbose > 0) {
fe6407b5
WD
134- rsyserr(FINFO, errno, "link %s => %s",
135- fnamecmpbuf, fname);
f74d2272
WD
136- }
137- }
138- fnamecmp = fnamecmpbuf;
139- }
140-#endif
241013b4
MP
141- else
142- fnamecmp = fnamecmpbuf;
143- }
144-
145- if (statret == -1) {
f74d2272
WD
146- if (preserve_hard_links && hard_link_check(file, HL_SKIP))
147- return;
241013b4
MP
148- if (errno == ENOENT) {
149- write_int(f_out,i);
7628f156
WD
150- if (!dry_run)
151- write_sum_head(f_out, NULL);
f74d2272
WD
152- } else if (verbose > 1) {
153+ /* Failed to stat for some reason besides "not found". */
154+ if (statret == -1 && errno != ENOENT) {
fe6407b5
WD
155+ if (verbose > 1) {
156 rsyserr(FERROR, errno,
157- "recv_generator: failed to open %s",
158+ "recv_generator failed to stat %s",
159 full_fname(fname));
160 }
f74d2272
WD
161 return;
162 }
163
241013b4
MP
164- if (!S_ISREG(st.st_mode)) {
165- if (delete_file(fname) != 0) {
166- return;
167- }
7628f156
WD
168+ if ((fd = open_base_file(file, fname, statret, &st)) == -2)
169+ return;
170
241013b4 171- /* now pretend the file didn't exist */
7628f156
WD
172+ if ((disable_deltas_p() || dry_run) && fd != -1) {
173+ close(fd);
174+ fd = -1;
175+ }
176+
177+ if (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))
180 return;
241013b4 181- write_int(f_out,i);
7628f156
WD
182+ write_int(f_out, i);
183 if (!dry_run)
184 write_sum_head(f_out, NULL);
fe6407b5 185- return;
241013b4
MP
186- }
187-
f74d2272 188- if (opt_ignore_existing && fnamecmp == fname) {
241013b4
MP
189- if (verbose > 1)
190- rprintf(FINFO,"%s exists\n",fname);
7b675ff5 191- return;
f74d2272 192- }
7628f156
WD
193+ return;
194+ }
195
241013b4 196- if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
f74d2272 197- if (verbose > 1)
241013b4 198- rprintf(FINFO,"%s is newer\n",fname);
f74d2272 199- return;
7b675ff5
WD
200- }
201-
241013b4
MP
202- if (skip_file(fname, file, &st)) {
203- if (fnamecmp == fname)
7f2baf27 204- set_perms(fname, file, &st, PERMS_REPORT);
241013b4
MP
205- return;
206- }
207-
208- if (dry_run) {
209- write_int(f_out,i);
7628f156 210- return;
241013b4 211- }
7628f156 212-
f74d2272 213- if (disable_deltas_p()) {
241013b4 214- write_int(f_out,i);
f74d2272 215- write_sum_head(f_out, NULL);
7628f156
WD
216+ if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
217 return;
218- }
7b675ff5 219
f74d2272 220- /* open the file */
241013b4 221- fd = do_open(fnamecmp, O_RDONLY, 0);
f74d2272 222-
7628f156 223- if (fd == -1) {
fe6407b5
WD
224- rsyserr(FERROR, errno, "failed to open %s, continuing",
225- full_fname(fnamecmp));
241013b4 226- /* pretend the file didn't exist */
7628f156
WD
227- if (preserve_hard_links && hard_link_check(file, HL_SKIP))
228- return;
f74d2272
WD
229- write_int(f_out,i);
230- write_sum_head(f_out, NULL);
f74d2272
WD
231+ if (!S_ISREG(file->mode)) {
232+ rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
241013b4
MP
233 return;
234 }
235
7628f156 236@@ -528,7 +511,7 @@ void recv_generator(char *fname, struct
f74d2272 237 mapbuf = NULL;
241013b4 238
f74d2272
WD
239 if (verbose > 3) {
240- rprintf(FINFO,"gen mapped %s of size %.0f\n", fnamecmp,
241+ rprintf(FINFO, "gen mapped %s of size %.0f\n", fname,
242 (double)st.st_size);
243 }
241013b4 244
7628f156
WD
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;
f74d2272
WD
248 int modify_window = 0;
249 int blocking_io = -1;
250 int checksum_seed = 0;
251+int fuzzy = 0;
252 unsigned int block_size = 0;
241013b4 253
241013b4 254
7628f156 255@@ -270,6 +271,7 @@ void usage(enum logcode F)
f0533c4c
WD
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");
7628f156 263@@ -368,6 +370,7 @@ static struct poptOption long_options[]
f0533c4c
WD
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 },
f74d2272 267+ {"fuzzy", 0, POPT_ARG_NONE, &fuzzy, 0, 0, 0 },
f0533c4c
WD
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 },
7628f156 271@@ -989,6 +992,9 @@ void server_options(char **args,int *arg
f74d2272 272 }
241013b4 273 }
7b675ff5 274
241013b4
MP
275+ if (fuzzy && am_sender)
276+ args[ac++] = "--fuzzy";
7b675ff5 277+
241013b4 278 *argc = ac;
f74d2272 279 return;
7b675ff5 280
7628f156
WD
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;
54691942 284 extern int orig_umask;
7f2baf27 285 extern int keep_partial;
7b675ff5 286 extern int checksum_seed;
241013b4
MP
287+extern int fuzzy;
288
f74d2272
WD
289 static void delete_one(char *fn, int is_dir)
290 {
7628f156 291@@ -300,8 +301,6 @@ int recv_files(int f_in,struct file_list
f74d2272 292 char *fname, fbuf[MAXPATHLEN];
241013b4
MP
293 char template[MAXPATHLEN];
294 char fnametmp[MAXPATHLEN];
295- char *fnamecmp;
296- char fnamecmpbuf[MAXPATHLEN];
f74d2272 297 struct map_struct *mapbuf;
241013b4 298 struct file_struct *file;
7628f156
WD
299 struct stats initial_stats;
300@@ -364,35 +363,31 @@ int recv_files(int f_in,struct file_list
241013b4
MP
301 if (verbose > 2)
302 rprintf(FINFO,"recv_files(%s)\n",fname);
303
304- fnamecmp = fname;
305-
f74d2272 306 /* open the file */
241013b4
MP
307- fd1 = do_open(fnamecmp, O_RDONLY, 0);
308+ fd1 = do_open(fname, O_RDONLY, 0);
309
f74d2272 310- if (fd1 == -1 && compare_dest != NULL) {
241013b4 311- /* try the file at compare_dest instead */
f74d2272
WD
312- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
313- compare_dest, fname);
241013b4
MP
314- fnamecmp = fnamecmpbuf;
315- fd1 = do_open(fnamecmp, O_RDONLY, 0);
316- }
317+ if (fd1 == -1 && compare_dest != NULL)
318+ fd1 = open_alternate_base_comparedir(fname);
319+
320+ if (fd1 == -1 && fuzzy)
321+ fd1 = open_alternate_base_fuzzy(fname);
322
323 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
fe6407b5
WD
324 rsyserr(FERROR, errno, "fstat %s failed",
325- full_fname(fnamecmp));
326+ full_fname(fname));
241013b4
MP
327 receive_data(f_in,NULL,-1,NULL,file->length);
328 close(fd1);
329 continue;
330 }
331
f74d2272
WD
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
337 * with directories
338 */
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);
241013b4
MP
343 close(fd1);
344 continue;
7628f156 345@@ -413,8 +408,10 @@ int recv_files(int f_in,struct file_list
f74d2272 346
241013b4 347 if (fd1 != -1 && st.st_size > 0) {
f74d2272
WD
348 mapbuf = map_file(fd1,st.st_size);
349- if (verbose > 2)
241013b4 350- rprintf(FINFO,"recv mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
f74d2272
WD
351+ if (verbose > 2) {
352+ rprintf(FINFO, "recv mapped %s of size %.0f\n",
353+ fname, (double)st.st_size);
354+ }
355 } else
356 mapbuf = NULL;
357
7628f156
WD
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(
f0533c4c
WD
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