1 Depends-On-Patch: g2r-basis-filename.diff
3 The changes to generator.c were greatly simplified, making the patch
4 easier to maintain and fixing the failing test in the testsuite.
7 Be sure to run "make proto" before "make".
9 --- orig/generator.c 2004-07-22 00:05:38
10 +++ generator.c 2004-07-20 21:49:24
11 @@ -41,6 +41,7 @@ extern int ignore_times;
13 extern int io_timeout;
14 extern int protocol_version;
16 extern int always_checksum;
17 extern char *compare_dest;
19 @@ -248,6 +249,94 @@ static void generate_and_send_sums(int f
23 +static void split_names(char *fname, char **dirname, char **basename)
25 + char *slash = strrchr(fname, '/');
29 + *basename = slash+1;
37 +static unsigned int measure_name(const char *name, const char *basename,
40 + int namelen = strlen(name);
41 + int extlen = strlen(ext);
42 + unsigned int score = 0;
44 + /* Extensions must match */
45 + if (namelen <= extlen || strcmp(name + namelen - extlen, ext) != 0)
48 + /* Now score depends on similarity of prefix */
49 + for (; *name == *basename && *name; name++, basename++)
55 +static int find_fuzzy(char **fname_ptr, char *buf, STRUCT_STAT *st_ptr)
59 + char *basename, *dirname;
60 + char mangled_name[MAXPATHLEN];
61 + char bestname[MAXPATHLEN];
62 + unsigned int bestscore = 0;
65 + strlcpy(mangled_name, *fname_ptr, sizeof mangled_name);
67 + split_names(mangled_name, &dirname, &basename);
68 + if (!(d = opendir(dirname))) {
69 + rsyserr(FERROR, errno, "recv_generator opendir(%s)", dirname);
73 + /* Get final extension, eg. .gz; never full basename though. */
74 + ext = strrchr(basename + 1, '.');
76 + ext = basename + strlen(basename); /* ext = "" */
78 + while ((di = readdir(d)) != NULL) {
79 + const char *dname = d_name(di);
82 + if (dname[0] == '.' && (dname[1] == '\0'
83 + || (dname[1] == '.' && dname[2] == '\0')))
86 + score = measure_name(dname, basename, ext);
88 + rprintf(FINFO, "[%s] fuzzy score for %s = %u\n",
89 + who_am_i(), dname, score);
91 + if (score > bestscore) {
92 + strlcpy(bestname, dname, sizeof bestname);
98 + /* Found a candidate. */
99 + if (bestscore != 0) {
100 + pathjoin(buf, MAXPATHLEN, dirname, bestname);
102 + rprintf(FINFO, "[%s] fuzzy match %s->%s\n",
103 + who_am_i(), *fname_ptr, buf);
106 + return link_stat(buf, st_ptr, 0);
113 * Acts on file number @p i from @p flist, whose name is @p fname.
114 @@ -262,7 +351,7 @@ static void recv_generator(char *fname,
119 + int statret, fuzzy_file = 0;
121 char fnamecmpbuf[MAXPATHLEN];
123 @@ -442,6 +531,14 @@ static void recv_generator(char *fname,
127 + if (statret == -1 && fuzzy) {
128 + statret = find_fuzzy(&fnamecmp, fnamecmpbuf, &st);
129 + if (!S_ISREG(st.st_mode))
136 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
138 @@ -479,7 +576,7 @@ static void recv_generator(char *fname,
142 - if (skip_file(fname, file, &st)) {
143 + if (!fuzzy_file && skip_file(fname, file, &st)) {
145 set_perms(fname, file, &st, PERMS_REPORT);
147 --- orig/main.c 2004-07-22 00:10:43
148 +++ main.c 2004-07-22 00:32:31
149 @@ -47,6 +47,7 @@ extern int keep_dirlinks;
150 extern int preserve_hard_links;
151 extern int protocol_version;
154 extern int relative_paths;
155 extern int rsync_port;
156 extern int whole_file;
157 @@ -456,7 +457,7 @@ static int do_recv(int f_in,int f_out,st
160 int error_pipe[2], name_pipe[2];
161 - int need_name_pipe = compare_dest;
162 + int need_name_pipe = compare_dest || fuzzy;
164 if (preserve_hard_links)
165 init_hard_links(flist);
166 --- orig/options.c 2004-07-21 23:59:35
167 +++ options.c 2004-07-16 20:14:12
168 @@ -85,6 +85,7 @@ int safe_symlinks = 0;
169 int copy_unsafe_links = 0;
173 size_t bwlimit_writemax = 0;
174 int delete_after = 0;
175 int only_existing = 0;
176 @@ -276,6 +277,7 @@ void usage(enum logcode F)
177 rprintf(F," -T --temp-dir=DIR create temporary files in directory DIR\n");
178 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
179 rprintf(F," --link-dest=DIR create hardlinks to DIR for unchanged files\n");
180 + rprintf(F," --fuzzy use similar file as basis if basis doesn't exist\n");
181 rprintf(F," -P equivalent to --partial --progress\n");
182 rprintf(F," -z, --compress compress file data\n");
183 rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
184 @@ -375,6 +377,7 @@ static struct poptOption long_options[]
185 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
186 {"compare-dest", 0, POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
187 {"link-dest", 0, POPT_ARG_STRING, &compare_dest, OPT_LINK_DEST, 0, 0 },
188 + {"fuzzy", 0, POPT_ARG_NONE, &fuzzy, 0, 0, 0 },
189 /* TODO: Should this take an optional int giving the compression level? */
190 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
191 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
192 @@ -1024,6 +1027,9 @@ void server_options(char **args,int *arg
196 + if (fuzzy && am_sender)
197 + args[ac++] = "--fuzzy";
202 --- orig/receiver.c 2004-07-22 00:20:50
203 +++ receiver.c 2004-07-03 20:09:05
204 @@ -38,7 +38,6 @@ extern int preserve_perms;
205 extern int cvs_exclude;
208 -extern char *compare_dest;
209 extern int make_backups;
210 extern int do_progress;
211 extern char *backup_dir;
212 --- orig/rsync.yo 2004-07-20 21:36:08
213 +++ rsync.yo 2004-07-03 19:27:25
214 @@ -326,6 +326,7 @@ verb(
215 -T --temp-dir=DIR create temporary files in directory DIR
216 --compare-dest=DIR also compare received files relative to DIR
217 --link-dest=DIR create hardlinks to DIR for unchanged files
218 + --fuzzy use similar file as basis if basis is gone
219 -P equivalent to --partial --progress
220 -z, --compress compress file data
221 -C, --cvs-exclude auto ignore files in the same way CVS does