Got rid of fuzz.
[rsync/rsync-patches.git] / compare-dest.diff
CommitLineData
824abc86
WD
1Depends-On-Patch: g2r-basis-filename.diff
2
09add1ae
WD
3This patch allows multiple --compare-dest or --link-dest options to be
4used, making the transfer of some files more optimal. Note that the
5algorithm does NOT search for the best match -- it stops at the first
6match and uses that as the basis file for the transfer, so be sure to
8dd60649
WD
7order your arguments appropriately (the args are searched in the order
8they are suppled).
09add1ae 9
8dd60649
WD
10Before compiling, be sure to run "make proto".
11
d2fa0b30
WD
12--- orig/generator.c 2004-07-30 07:18:03
13+++ generator.c 2004-07-30 07:28:13
b952a177 14@@ -43,7 +43,7 @@ extern int io_timeout;
09add1ae
WD
15 extern int protocol_version;
16 extern int always_checksum;
b952a177 17 extern char *partial_dir;
09add1ae
WD
18-extern char *compare_dest;
19+extern char *compare_dest[];
20 extern int link_dest;
21 extern int whole_file;
22 extern int local_server;
d5753a22 23@@ -413,11 +413,19 @@ static void recv_generator(char *fname,
09add1ae 24 fnamecmp = fname;
d2fa0b30 25 fnamecmp_type = G2R_FNAME;
09add1ae
WD
26
27- if (statret == -1 && compare_dest != NULL) {
28+ if (statret == -1 && compare_dest[0] != NULL) {
29 /* try the file at compare_dest instead */
09add1ae 30- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
b952a177
WD
31- if (link_stat(fnamecmpbuf, &st, 0) == 0
32- && S_ISREG(st.st_mode)) {
b543b4de
WD
33+ int i = 0;
34+ do {
af96621e
WD
35+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
36+ compare_dest[i], fname);
b952a177
WD
37+ if (link_stat(fnamecmpbuf, &st, 0) == 0
38+ && S_ISREG(st.st_mode)) {
39+ statret = 0;
40+ break;
09add1ae 41+ }
b543b4de 42+ } while (compare_dest[++i] != NULL);
b952a177
WD
43+ if (statret == 0) {
44 #if HAVE_LINK
45 if (link_dest && !dry_run) {
46 if (do_link(fnamecmpbuf, fname) < 0) {
d5753a22 47@@ -428,15 +436,14 @@ static void recv_generator(char *fname,
d2fa0b30
WD
48 safe_fname(fname));
49 }
50 fnamecmp = fnamecmpbuf;
51- fnamecmp_type = 0;
52+ fnamecmp_type = i;
53 }
b952a177
WD
54 } else
55 #endif
d2fa0b30 56 {
b952a177 57 fnamecmp = fnamecmpbuf;
d2fa0b30
WD
58- fnamecmp_type = 0;
59+ fnamecmp_type = i;
60 }
b952a177 61- statret = 0;
d2fa0b30
WD
62 }
63 }
64
2f5fa77e 65--- orig/main.c 2004-07-22 00:10:43
d2fa0b30 66+++ main.c 2004-07-30 07:23:54
d5753a22 67@@ -59,7 +59,7 @@ extern int filesfrom_fd;
495f1899
WD
68 extern pid_t cleanup_child_pid;
69 extern char *files_from;
70 extern char *remote_filesfrom_file;
71-extern char *compare_dest;
72+extern char *compare_dest[];
73 extern char *rsync_path;
74 extern char *shell_cmd;
75 extern char *batch_name;
d5753a22 76@@ -459,7 +459,7 @@ static int do_recv(int f_in,int f_out,st
495f1899
WD
77 int pid;
78 int status = 0;
79 int error_pipe[2], name_pipe[2];
c2530f70
WD
80- BOOL need_name_pipe = compare_dest && !dry_run;
81+ BOOL need_name_pipe = compare_dest[0] && !dry_run;
495f1899 82
d5753a22
WD
83 /* The receiving side mustn't obey this, or an existing symlink that
84 * points to an identical file won't be replaced by the referent. */
85--- orig/options.c 2004-08-03 15:41:32
d2fa0b30 86+++ options.c 2004-07-30 07:23:54
d5753a22 87@@ -115,12 +115,13 @@ int write_batch = 0;
b952a177
WD
88 int read_batch = 0;
89 int backup_dir_len = 0;
90 int backup_suffix_len;
91+int num_comp_dest = 0;
92 unsigned int backup_dir_remainder;
09add1ae
WD
93
94 char *backup_suffix = NULL;
95 char *tmpdir = NULL;
b952a177 96 char *partial_dir = NULL;
09add1ae
WD
97-char *compare_dest = NULL;
98+char *compare_dest[MAX_COMP_DEST+1];
09add1ae
WD
99 char *config_file = NULL;
100 char *shell_cmd = NULL;
101 char *log_format = NULL;
d5753a22 102@@ -141,6 +142,7 @@ char *batch_name = NULL;
09add1ae
WD
103
104 static int daemon_opt; /* sets am_daemon after option error-reporting */
105 static int modify_window_set;
106+static int saw_compare_dest = 0;
107
108 /** Local address to bind. As a character string because it's
109 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
d5753a22 110@@ -318,7 +320,7 @@ void usage(enum logcode F)
09add1ae
WD
111 }
112
113 enum {OPT_VERSION = 1000, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
114- OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
115+ OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_COMPARE_DEST, OPT_LINK_DEST,
116 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
117 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT,
118 OPT_REFUSED_BASE = 9000};
d5753a22 119@@ -377,8 +379,8 @@ static struct poptOption long_options[]
09add1ae
WD
120 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
121 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
122 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
123- {"compare-dest", 0, POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
124- {"link-dest", 0, POPT_ARG_STRING, &compare_dest, OPT_LINK_DEST, 0, 0 },
125+ {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
126+ {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
127 /* TODO: Should this take an optional int giving the compression level? */
128 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
129 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
d5753a22 130@@ -607,8 +609,28 @@ int parse_arguments(int *argc, const cha
09add1ae
WD
131 select_timeout = io_timeout;
132 break;
133
134+ case OPT_COMPARE_DEST:
09add1ae
WD
135+ if (num_comp_dest >= MAX_COMP_DEST-1) {
136+ rprintf(FERROR, "ERROR: %s\n", "too many --compare-dest args given");
137+ return 0;
138+ }
139+ arg = poptGetOptArg(pc);
140+ if (sanitize_paths)
141+ arg = alloc_sanitize_path(arg, curr_dir);
142+ compare_dest[num_comp_dest++] = (char *)arg;
143+ saw_compare_dest = 1;
144+ break;
09add1ae
WD
145+
146 case OPT_LINK_DEST:
147 #if HAVE_LINK
148+ if (num_comp_dest >= MAX_COMP_DEST-1) {
90bcf59b 149+ rprintf(FERROR, "ERROR: %s\n", "too many --link-dest args given");
09add1ae
WD
150+ return 0;
151+ }
152+ arg = poptGetOptArg(pc);
153+ if (sanitize_paths)
154+ arg = alloc_sanitize_path(arg, curr_dir);
155+ compare_dest[num_comp_dest++] = (char *)arg;
156 link_dest = 1;
157 break;
158 #else
d5753a22
WD
159@@ -701,6 +723,11 @@ int parse_arguments(int *argc, const cha
160 return 0;
09add1ae
WD
161 }
162
163+ if (saw_compare_dest && link_dest) {
164+ rprintf(FINFO,
165+ "WARNING: promoting --compare-dest options to --link-dest.\n");
166+ }
167+
168 if (archive_mode) {
169 if (!files_from)
170 recurse = 1;
d5753a22 171@@ -731,8 +758,6 @@ int parse_arguments(int *argc, const cha
09add1ae 172 tmpdir = alloc_sanitize_path(tmpdir, curr_dir);
b952a177
WD
173 if (partial_dir)
174 partial_dir = alloc_sanitize_path(partial_dir, curr_dir);
09add1ae
WD
175- if (compare_dest)
176- compare_dest = alloc_sanitize_path(compare_dest, curr_dir);
177 if (backup_dir)
178 backup_dir = alloc_sanitize_path(backup_dir, curr_dir);
179 if (files_from)
d5753a22 180@@ -882,8 +907,8 @@ int parse_arguments(int *argc, const cha
09add1ae
WD
181 **/
182 void server_options(char **args,int *argc)
183 {
184+ static char argstr[50+MAX_COMP_DEST*2];
185 int ac = *argc;
186- static char argstr[50];
187 char *arg;
188
189 int i, x;
d5753a22 190@@ -1067,13 +1092,16 @@ void server_options(char **args,int *arg
09add1ae
WD
191 args[ac++] = tmpdir;
192 }
193
194- if (compare_dest && am_sender) {
195+ if (compare_dest[0] && am_sender) {
196 /* the server only needs this option if it is not the sender,
197 * and it may be an older version that doesn't know this
198 * option, so don't send it if client is the sender.
199 */
200- args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
201- args[ac++] = compare_dest;
202+ int i;
203+ for (i = 0; i < num_comp_dest; i++) {
204+ args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
205+ args[ac++] = compare_dest[i];
206+ }
207 }
208
209 if (files_from && (!am_sender || remote_filesfrom_file)) {
d2fa0b30
WD
210--- orig/receiver.c 2004-07-30 07:17:48
211+++ receiver.c 2004-07-30 07:31:12
d5753a22 212@@ -38,7 +38,7 @@ extern int cvs_exclude;
09add1ae
WD
213 extern int io_error;
214 extern char *tmpdir;
b952a177 215 extern char *partial_dir;
09add1ae 216-extern char *compare_dest;
d2fa0b30 217+extern char *compare_dest[];
09add1ae
WD
218 extern int make_backups;
219 extern int do_progress;
220 extern char *backup_dir;
d2fa0b30
WD
221@@ -442,7 +442,8 @@ int recv_files(int f_in, struct file_lis
222 partialptr = partial_dir ? partial_dir_fname(fname) : fname;
223
224 if (f_in_name >= 0) {
225- switch (read_byte(f_in_name)) {
226+ uchar j;
227+ switch (j = read_byte(f_in_name)) {
228 case G2R_FNAME:
229 fnamecmp = fname;
230 break;
231@@ -451,7 +452,7 @@ int recv_files(int f_in, struct file_lis
232 break;
233 default:
234 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
235- compare_dest, fname);
236+ compare_dest[j], fname);
237 fnamecmp = fnamecmpbuf;
238 break;
239 }
240--- orig/rsync.h 2004-07-30 07:16:38
241+++ rsync.h 2004-07-30 07:23:54
09add1ae
WD
242@@ -98,6 +98,8 @@
243
244 #define MAX_ARGS 1000
245
246+#define MAX_COMP_DEST 20
247+
248 #define MPLEX_BASE 7
249
250 #define NO_EXCLUDES 0