Fixed failed 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 2 May 2004 17:04:14 -0000       1.100
16 +++ Makefile.in 13 May 2004 19:15:31 -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 13 May 2004 06:55:01 -0000      1.82
27 +++ generator.c 13 May 2004 19:15:31 -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,62 @@ 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 +                               rprintf(FERROR, "failed to open %s, continuing : %s\n",
61 +                                   full_fname(fname), strerror(errno));
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 +                       rprintf(FERROR, "fstat %s : %s\n",
90 +                           full_fname(fname), strerror(errno));
91 +               }
92 +       }
93 +
94 +       return fd;
95 +}
96  
97  /**
98   * Acts on file number @p i from @p flist, whose name is @p fname.
99 @@ -272,8 +328,6 @@ void recv_generator(char *fname, struct 
100         STRUCT_STAT st;
101         struct map_struct *mapbuf;
102         int statret;
103 -       char *fnamecmp;
104 -       char fnamecmpbuf[MAXPATHLEN];
105  
106         if (list_only)
107                 return;
108 @@ -398,108 +452,38 @@ void recv_generator(char *fname, struct 
109         }
110  #endif
111  
112 -       if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
113 -               return;
114 -
115 -       if (!S_ISREG(file->mode)) {
116 -               rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
117 -               return;
118 -       }
119 -
120 -       fnamecmp = fname;
121 -
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))
128 -                       statret = -1;
129 -               if (statret == -1)
130 -                       errno = saveerrno;
131 -#if HAVE_LINK
132 -               else if (link_dest && !dry_run) {
133 -                       if (do_link(fnamecmpbuf, fname) != 0) {
134 -                               if (verbose > 0) {
135 -                                       rprintf(FINFO,"link %s => %s : %s\n",
136 -                                               fnamecmpbuf, fname,
137 -                                               strerror(errno));
138 -                               }
139 -                       }
140 -                       fnamecmp = fnamecmpbuf;
141 -               }
142 -#endif
143 -               else
144 -                       fnamecmp = fnamecmpbuf;
145 -       }
146 -
147 -       if (statret == -1) {
148 -               if (preserve_hard_links && hard_link_check(file, HL_SKIP))
149 -                       return;
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) {
156 +               if (verbose > 1)
157                         rprintf(FERROR,
158 -                               "recv_generator: failed to open %s: %s\n",
159 +                               "recv_generator failed to stat %s: %s\n",
160                                 full_fname(fname), strerror(errno));
161 -               }
162                 return;
163         }
164  
165 -       if (!S_ISREG(st.st_mode)) {
166 -               if (delete_file(fname) != 0) {
167 -                       return;
168 -               }
169 -
170 -               /* now pretend the file didn't exist */
171 -               if (preserve_hard_links && hard_link_check(file, HL_SKIP))
172 -                       return;
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)
176                 return;
177 -       }
178 -
179 -       if (opt_ignore_existing && fnamecmp == fname) {
180 -               if (verbose > 1)
181 -                       rprintf(FINFO,"%s exists\n",fname);
182 -               return;
183 -       }
184  
185 -       if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
186 -               if (verbose > 1)
187 -                       rprintf(FINFO,"%s is newer\n",fname);
188 -               return;
189 +       if ((disable_deltas_p() || dry_run) && fd != -1) {
190 +               close(fd);
191 +               fd = -1;
192         }
193  
194 -       if (skip_file(fname, file, &st)) {
195 -               if (fnamecmp == fname)
196 -                       set_perms(fname, file, &st, PERMS_REPORT);
197 -               return;
198 -       }
199 -
200 -       if (dry_run) {
201 -               write_int(f_out,i);
202 -               return;
203 -       }
204 -
205 -       if (disable_deltas_p()) {
206 -               write_int(f_out,i);
207 -               write_sum_head(f_out, NULL);
208 -               return;
209 -       }
210 -
211 -       /* open the file */
212 -       fd = do_open(fnamecmp, O_RDONLY, 0);
213 -
214         if (fd == -1) {
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))
220                         return;
221 -               write_int(f_out,i);
222 -               write_sum_head(f_out, NULL);
223 +               write_int(f_out, i);
224 +               if (!dry_run)
225 +                       write_sum_head(f_out, NULL);
226 +               return;
227 +       }
228 +
229 +       if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
230 +               return;
231 +
232 +       if (!S_ISREG(file->mode)) {
233 +               rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
234                 return;
235         }
236  
237 @@ -509,7 +493,7 @@ void recv_generator(char *fname, struct 
238                 mapbuf = NULL;
239  
240         if (verbose > 3) {
241 -               rprintf(FINFO,"gen mapped %s of size %.0f\n", fnamecmp,
242 +               rprintf(FINFO, "gen mapped %s of size %.0f\n", fname,
243                         (double)st.st_size);
244         }
245  
246 --- options.c   6 May 2004 21:08:01 -0000       1.148
247 +++ options.c   13 May 2004 19:15:32 -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;
252 +int fuzzy = 0;
253  unsigned int block_size = 0;
254  
255  
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  #ifdef INET6
262    rprintf(F," -4  --ipv4                  prefer IPv4\n");
263    rprintf(F," -6  --ipv6                  prefer IPv6\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 },
270  #ifdef INET6
271    {"ipv4",            '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";
274                 }
275         }
276 +
277 +       if (fuzzy && am_sender)
278 +               args[ac++] = "--fuzzy";
279  
280         *argc = ac;
281         return;
282 --- receiver.c  13 May 2004 07:08:22 -0000      1.77
283 +++ receiver.c  13 May 2004 19:15:32 -0000
284 @@ -46,6 +46,7 @@ extern int module_id;
285  extern int ignore_errors;
286  extern int orig_umask;
287  extern int keep_partial;
288 +extern int fuzzy;
289  
290  static void delete_one(char *fn, int is_dir)
291  {
292 @@ -293,8 +294,6 @@ int recv_files(int f_in,struct file_list
293         char *fname, fbuf[MAXPATHLEN];
294         char template[MAXPATHLEN];
295         char fnametmp[MAXPATHLEN];
296 -       char *fnamecmp;
297 -       char fnamecmpbuf[MAXPATHLEN];
298         struct map_struct *mapbuf;
299         int i;
300         struct file_struct *file;
301 @@ -357,35 +356,31 @@ int recv_files(int f_in,struct file_list
302                 if (verbose > 2)
303                         rprintf(FINFO,"recv_files(%s)\n",fname);
304  
305 -               fnamecmp = fname;
306 -
307                 /* open the file */
308 -               fd1 = do_open(fnamecmp, O_RDONLY, 0);
309 +               fd1 = do_open(fname, O_RDONLY, 0);
310  
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);
317 -               }
318 +               if (fd1 == -1 && compare_dest != NULL)
319 +                       fd1 = open_alternate_base_comparedir(fname);
320 +
321 +               if (fd1 == -1 && fuzzy)
322 +                       fd1 = open_alternate_base_fuzzy(fname);
323  
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);
329                         close(fd1);
330                         continue;
331                 }
332  
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
338                          * with directories
339                          */
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);
344                         close(fd1);
345                         continue;
346 @@ -406,8 +401,10 @@ int recv_files(int f_in,struct file_list
347  
348                 if (fd1 != -1 && st.st_size > 0) {
349                         mapbuf = map_file(fd1,st.st_size);
350 -                       if (verbose > 2)
351 -                               rprintf(FINFO,"recv mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
352 +                       if (verbose > 2) {
353 +                               rprintf(FINFO, "recv mapped %s of size %.0f\n",
354 +                                   fname, (double)st.st_size);
355 +                       }
356                 } else
357                         mapbuf = NULL;
358