Fixed failing hunks.
[rsync/rsync-patches.git] / fuzzy.diff
1 From: Rusty Russell <rusty@rustcorp.com.au>
2 Date: Wed, 03 Apr 2002 17:08:57 +1000
3
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).
6
7 Compiles, otherwise untested.
8 Rusty.
9
10 [Updated for current CVS version by Wayne Davison.  Passes *MOST* of the
11 test suite, but otherwise UNTESTED.]
12 --
13   Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
14
15 --- Makefile.in 15 May 2004 00:48:11 -0000      1.101
16 +++ Makefile.in 15 May 2004 20:47:12 -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 May 2004 19:31:10 -0000      1.83
27 +++ generator.c 15 May 2004 20:47:12 -0000
28 @@ -51,6 +51,7 @@ extern int list_only;
29  extern int only_existing;
30  extern int orig_umask;
31  extern int safe_symlinks;
32 +extern int fuzzy;
33  
34  
35  /* choose whether to skip a particular file */
36 @@ -256,7 +257,61 @@ static void generate_and_send_sums(struc
37         }
38  }
39  
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,
42 +                         STRUCT_STAT *st)
43 +{
44 +       int fd = -1;
45 +
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)
51 +                                       rprintf(FINFO, "%s is newer\n", fname);
52 +                               return -2;
53 +                       }
54 +                       if (skip_file(fname, file, st)) {
55 +                               set_perms(fname, file, st, PERMS_REPORT);
56 +                               return -2;
57 +                       }
58 +                       fd = do_open(fname, O_RDONLY, 0);
59 +                       if (fd == -1) {
60 +                               rsyserr(FERROR, errno, "failed to open %s, continuing",
61 +                                   full_fname(fname));
62 +                               return -1;
63 +                       }
64 +                       return fd;
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);
82  
83 +       if (fd == -1 && fuzzy)
84 +               fd = open_alternate_base_fuzzy(fname);
85 +
86 +       /* Update stat to understand size */
87 +       if (fd != -1) {
88 +               if (do_fstat(fd, st) != 0) {
89 +                       rsyserr(FERROR, errno, "fstat %s", full_fname(fname));
90 +               }
91 +       }
92 +
93 +       return fd;
94 +}
95  
96  /**
97   * Acts on file number @p i from @p flist, whose name is @p fname.
98 @@ -272,8 +327,6 @@ void recv_generator(char *fname, struct 
99         STRUCT_STAT st;
100         struct map_struct *mapbuf;
101         int statret;
102 -       char *fnamecmp;
103 -       char fnamecmpbuf[MAXPATHLEN];
104  
105         if (list_only)
106                 return;
107 @@ -400,107 +453,39 @@ void recv_generator(char *fname, struct 
108         }
109  #endif
110  
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 -
119 -       fnamecmp = fname;
120 -
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);
126 -               if (!S_ISREG(st.st_mode))
127 -                       statret = -1;
128 -               if (statret == -1)
129 -                       errno = saveerrno;
130 -#if HAVE_LINK
131 -               else if (link_dest && !dry_run) {
132 -                       if (do_link(fnamecmpbuf, fname) != 0) {
133 -                               if (verbose > 0) {
134 -                                       rsyserr(FINFO, errno, "link %s => %s",
135 -                                               fnamecmpbuf, fname);
136 -                               }
137 -                       }
138 -                       fnamecmp = fnamecmpbuf;
139 -               }
140 -#endif
141 -               else
142 -                       fnamecmp = fnamecmpbuf;
143 -       }
144 -
145 -       if (statret == -1) {
146 -               if (preserve_hard_links && hard_link_check(file, HL_SKIP))
147 -                       return;
148 -               if (errno == ENOENT) {
149 -                       write_int(f_out,i);
150 -                       if (!dry_run) write_sum_head(f_out, NULL);
151 -               } else if (verbose > 1) {
152 +       /* Failed to stat for some reason besides "not found". */
153 +       if (statret == -1 && errno != ENOENT) {
154 +               if (verbose > 1) {
155                         rsyserr(FERROR, errno,
156 -                               "recv_generator: failed to open %s",
157 +                               "recv_generator failed to stat %s",
158                                 full_fname(fname));
159                 }
160                 return;
161         }
162  
163 -       if (!S_ISREG(st.st_mode)) {
164 -               if (delete_file(fname) != 0) {
165 -                       return;
166 -               }
167 -
168 -               /* now pretend the file didn't exist */
169 -               if (preserve_hard_links && hard_link_check(file, HL_SKIP))
170 -                       return;
171 -               write_int(f_out,i);
172 -               if (!dry_run) write_sum_head(f_out, NULL);
173 -               return;
174 -       }
175 -
176 -       if (opt_ignore_existing && fnamecmp == fname) {
177 -               if (verbose > 1)
178 -                       rprintf(FINFO,"%s exists\n",fname);
179 +       if ((fd = open_base_file(file, fname, statret, &st)) == -2)
180                 return;
181 -       }
182  
183 -       if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
184 -               if (verbose > 1)
185 -                       rprintf(FINFO,"%s is newer\n",fname);
186 -               return;
187 +       if ((disable_deltas_p() || dry_run) && fd != -1) {
188 +               close(fd);
189 +               fd = -1;
190         }
191  
192 -       if (skip_file(fname, file, &st)) {
193 -               if (fnamecmp == fname)
194 -                       set_perms(fname, file, &st, PERMS_REPORT);
195 -               return;
196 -       }
197 -
198 -       if (dry_run) {
199 -               write_int(f_out,i);
200 -               return;
201 -       }
202 -
203 -       if (disable_deltas_p()) {
204 -               write_int(f_out,i);
205 -               write_sum_head(f_out, NULL);
206 -               return;
207 -       }
208 -
209 -       /* open the file */
210 -       fd = do_open(fnamecmp, O_RDONLY, 0);
211 -
212         if (fd == -1) {
213 -               rsyserr(FERROR, errno, "failed to open %s, continuing",
214 -                       full_fname(fnamecmp));
215 -               /* pretend the file didn't exist */
216 +               /* the file didn't exist, or we can pretend it doesn't */
217                 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
218                         return;
219 -               write_int(f_out,i);
220 -               write_sum_head(f_out, NULL);
221 +               write_int(f_out, i);
222 +               if (!dry_run)
223 +                       write_sum_head(f_out, NULL);
224 +               return;
225 +       }
226 +
227 +       if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
228 +               return;
229 +
230 +       if (!S_ISREG(file->mode)) {
231 +               rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
232                 return;
233         }
234  
235 @@ -510,7 +495,7 @@ void recv_generator(char *fname, struct 
236                 mapbuf = NULL;
237  
238         if (verbose > 3) {
239 -               rprintf(FINFO,"gen mapped %s of size %.0f\n", fnamecmp,
240 +               rprintf(FINFO, "gen mapped %s of size %.0f\n", fname,
241                         (double)st.st_size);
242         }
243  
244 --- options.c   6 May 2004 21:08:01 -0000       1.148
245 +++ options.c   15 May 2004 20:47:13 -0000
246 @@ -91,6 +91,7 @@ int ignore_errors = 0;
247  int modify_window = 0;
248  int blocking_io = -1;
249  int checksum_seed = 0;
250 +int fuzzy = 0;
251  unsigned int block_size = 0;
252  
253  
254 @@ -290,6 +291,7 @@ void usage(enum logcode F)
255    rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth, KBytes per second\n");
256    rprintf(F,"     --write-batch=PREFIX    write batch fileset starting with PREFIX\n");
257    rprintf(F,"     --read-batch=PREFIX     read batch fileset starting with PREFIX\n");
258 +  rprintf(F,"     --fuzzy                 use similar file as basis if it does't exist\n");
259  #ifdef INET6
260    rprintf(F," -4  --ipv4                  prefer IPv4\n");
261    rprintf(F," -6  --ipv6                  prefer IPv6\n");
262 @@ -385,6 +387,7 @@ static struct poptOption long_options[] 
263    {"files-from",       0,  POPT_ARG_STRING, &files_from, 0, 0, 0 },
264    {"from0",           '0', POPT_ARG_NONE,   &eol_nulls, 0, 0, 0},
265    {"no-implied-dirs",  0,  POPT_ARG_VAL,    &implied_dirs, 0, 0, 0 },
266 +  {"fuzzy",            0,  POPT_ARG_NONE,   &fuzzy, 0, 0, 0 },
267    {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
268  #ifdef INET6
269    {"ipv4",            '4', POPT_ARG_VAL,    &default_af_hint, AF_INET, 0, 0 },
270 @@ -964,6 +967,9 @@ void server_options(char **args,int *arg
271                         args[ac++] = "--from0";
272                 }
273         }
274 +
275 +       if (fuzzy && am_sender)
276 +               args[ac++] = "--fuzzy";
277  
278         *argc = ac;
279         return;
280 --- receiver.c  15 May 2004 19:31:10 -0000      1.78
281 +++ receiver.c  15 May 2004 20:47:13 -0000
282 @@ -46,6 +46,7 @@ extern int module_id;
283  extern int ignore_errors;
284  extern int orig_umask;
285  extern int keep_partial;
286 +extern int fuzzy;
287  
288  static void delete_one(char *fn, int is_dir)
289  {
290 @@ -294,8 +295,6 @@ int recv_files(int f_in,struct file_list
291         char *fname, fbuf[MAXPATHLEN];
292         char template[MAXPATHLEN];
293         char fnametmp[MAXPATHLEN];
294 -       char *fnamecmp;
295 -       char fnamecmpbuf[MAXPATHLEN];
296         struct map_struct *mapbuf;
297         int i;
298         struct file_struct *file;
299 @@ -358,35 +357,31 @@ int recv_files(int f_in,struct file_list
300                 if (verbose > 2)
301                         rprintf(FINFO,"recv_files(%s)\n",fname);
302  
303 -               fnamecmp = fname;
304 -
305                 /* open the file */
306 -               fd1 = do_open(fnamecmp, O_RDONLY, 0);
307 +               fd1 = do_open(fname, O_RDONLY, 0);
308  
309 -               if (fd1 == -1 && compare_dest != NULL) {
310 -                       /* try the file at compare_dest instead */
311 -                       pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
312 -                                compare_dest, fname);
313 -                       fnamecmp = fnamecmpbuf;
314 -                       fd1 = do_open(fnamecmp, O_RDONLY, 0);
315 -               }
316 +               if (fd1 == -1 && compare_dest != NULL)
317 +                       fd1 = open_alternate_base_comparedir(fname);
318 +
319 +               if (fd1 == -1 && fuzzy)
320 +                       fd1 = open_alternate_base_fuzzy(fname);
321  
322                 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
323                         rsyserr(FERROR, errno, "fstat %s failed",
324 -                               full_fname(fnamecmp));
325 +                               full_fname(fname));
326                         receive_data(f_in,NULL,-1,NULL,file->length);
327                         close(fd1);
328                         continue;
329                 }
330  
331 -               if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) {
332 +               if (fd1 != -1 && S_ISDIR(st.st_mode)) {
333                         /* this special handling for directories
334                          * wouldn't be necessary if robust_rename()
335                          * and the underlying robust_unlink could cope
336                          * with directories
337                          */
338                         rprintf(FERROR,"recv_files: %s is a directory\n",
339 -                               full_fname(fnamecmp));
340 +                               full_fname(fname));
341                         receive_data(f_in, NULL, -1, NULL, file->length);
342                         close(fd1);
343                         continue;
344 @@ -407,8 +402,10 @@ int recv_files(int f_in,struct file_list
345  
346                 if (fd1 != -1 && st.st_size > 0) {
347                         mapbuf = map_file(fd1,st.st_size);
348 -                       if (verbose > 2)
349 -                               rprintf(FINFO,"recv mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
350 +                       if (verbose > 2) {
351 +                               rprintf(FINFO, "recv mapped %s of size %.0f\n",
352 +                                   fname, (double)st.st_size);
353 +                       }
354                 } else
355                         mapbuf = NULL;
356