Update Makefile.in so that all targets that use syscall.o now include
[rsync/rsync-patches.git] / compare-dest.diff
... / ...
CommitLineData
1Depends-On-Patch: g2r-basis-filename.diff
2
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
7order your arguments appropriately (the args are searched in the order
8they are suppled).
9
10Before compiling, be sure to run "make proto".
11
12--- orig/generator.c 2004-09-20 19:57:58
13+++ generator.c 2004-07-30 07:28:13
14@@ -45,7 +45,7 @@ extern int io_timeout;
15 extern int protocol_version;
16 extern int always_checksum;
17 extern char *partial_dir;
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;
23@@ -426,11 +426,19 @@ static void recv_generator(char *fname,
24 fnamecmp = fname;
25 fnamecmp_type = G2R_FNAME;
26
27- if (statret == -1 && compare_dest != NULL) {
28+ if (statret == -1 && compare_dest[0] != NULL) {
29 /* try the file at compare_dest instead */
30- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
31- if (link_stat(fnamecmpbuf, &st, 0) == 0
32- && S_ISREG(st.st_mode)) {
33+ int i = 0;
34+ do {
35+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
36+ compare_dest[i], fname);
37+ if (link_stat(fnamecmpbuf, &st, 0) == 0
38+ && S_ISREG(st.st_mode)) {
39+ statret = 0;
40+ break;
41+ }
42+ } while (compare_dest[++i] != NULL);
43+ if (statret == 0) {
44 #if HAVE_LINK
45 if (link_dest && !dry_run) {
46 if (do_link(fnamecmpbuf, fname) < 0) {
47@@ -441,15 +449,14 @@ static void recv_generator(char *fname,
48 safe_fname(fname));
49 }
50 fnamecmp = fnamecmpbuf;
51- fnamecmp_type = 0;
52+ fnamecmp_type = i;
53 }
54 } else
55 #endif
56 {
57 fnamecmp = fnamecmpbuf;
58- fnamecmp_type = 0;
59+ fnamecmp_type = i;
60 }
61- statret = 0;
62 }
63 }
64
65--- orig/main.c 2004-07-22 00:10:43
66+++ main.c 2004-07-30 07:23:54
67@@ -59,7 +59,7 @@ extern int filesfrom_fd;
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;
76@@ -463,7 +463,7 @@ static int do_recv(int f_in,int f_out,st
77 int pid;
78 int status = 0;
79 int error_pipe[2], name_pipe[2];
80- BOOL need_name_pipe = compare_dest && !dry_run;
81+ BOOL need_name_pipe = compare_dest[0] && !dry_run;
82
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-09-20 05:10:48
86+++ options.c 2004-08-13 07:55:37
87@@ -114,12 +114,13 @@ int write_batch = 0;
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;
93
94 char *backup_suffix = NULL;
95 char *tmpdir = NULL;
96 char *partial_dir = NULL;
97-char *compare_dest = NULL;
98+char *compare_dest[MAX_COMP_DEST+1];
99 char *config_file = NULL;
100 char *shell_cmd = NULL;
101 char *log_format = NULL;
102@@ -140,6 +141,7 @@ char *batch_name = NULL;
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
110@@ -317,7 +319,7 @@ void usage(enum logcode F)
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};
119@@ -376,8 +378,8 @@ static struct poptOption long_options[]
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 },
130@@ -605,8 +607,28 @@ int parse_arguments(int *argc, const cha
131 select_timeout = io_timeout;
132 break;
133
134+ case OPT_COMPARE_DEST:
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 = sanitize_path(NULL, arg, NULL, 0);
142+ compare_dest[num_comp_dest++] = (char *)arg;
143+ saw_compare_dest = 1;
144+ break;
145+
146 case OPT_LINK_DEST:
147 #if HAVE_LINK
148+ if (num_comp_dest >= MAX_COMP_DEST-1) {
149+ rprintf(FERROR, "ERROR: %s\n", "too many --link-dest args given");
150+ return 0;
151+ }
152+ arg = poptGetOptArg(pc);
153+ if (sanitize_paths)
154+ arg = sanitize_path(NULL, arg, NULL, 0);
155+ compare_dest[num_comp_dest++] = (char *)arg;
156 link_dest = 1;
157 break;
158 #else
159@@ -699,6 +721,11 @@ int parse_arguments(int *argc, const cha
160 return 0;
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;
171@@ -729,8 +756,6 @@ int parse_arguments(int *argc, const cha
172 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
173 if (partial_dir)
174 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
175- if (compare_dest)
176- compare_dest = sanitize_path(NULL, compare_dest, NULL, 0);
177 if (backup_dir)
178 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
179 if (files_from)
180@@ -738,6 +763,7 @@ int parse_arguments(int *argc, const cha
181 }
182 if (server_exclude_list.head && !am_sender) {
183 struct exclude_list_struct *elp = &server_exclude_list;
184+ int i;
185 if (tmpdir) {
186 clean_fname(tmpdir, 1);
187 if (check_exclude(elp, tmpdir, 1) < 0)
188@@ -748,9 +774,9 @@ int parse_arguments(int *argc, const cha
189 if (check_exclude(elp, partial_dir, 1) < 0)
190 goto options_rejected;
191 }
192- if (compare_dest) {
193- clean_fname(compare_dest, 1);
194- if (check_exclude(elp, compare_dest, 1) < 0)
195+ for (i = 0; i < num_comp_dest; i++) {
196+ clean_fname(compare_dest[i], 1);
197+ if (check_exclude(elp, compare_dest[i], 1) < 0)
198 goto options_rejected;
199 }
200 if (backup_dir) {
201@@ -890,8 +916,8 @@ int parse_arguments(int *argc, const cha
202 **/
203 void server_options(char **args,int *argc)
204 {
205+ static char argstr[50+MAX_COMP_DEST*2];
206 int ac = *argc;
207- static char argstr[50];
208 char *arg;
209
210 int i, x;
211@@ -1074,13 +1100,16 @@ void server_options(char **args,int *arg
212 args[ac++] = tmpdir;
213 }
214
215- if (compare_dest && am_sender) {
216+ if (compare_dest[0] && am_sender) {
217 /* the server only needs this option if it is not the sender,
218 * and it may be an older version that doesn't know this
219 * option, so don't send it if client is the sender.
220 */
221- args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
222- args[ac++] = compare_dest;
223+ int i;
224+ for (i = 0; i < num_comp_dest; i++) {
225+ args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
226+ args[ac++] = compare_dest[i];
227+ }
228 }
229
230 if (files_from && (!am_sender || remote_filesfrom_file)) {
231--- orig/receiver.c 2004-09-07 21:57:20
232+++ receiver.c 2004-07-30 07:31:12
233@@ -38,7 +38,7 @@ extern int cvs_exclude;
234 extern int io_error;
235 extern char *tmpdir;
236 extern char *partial_dir;
237-extern char *compare_dest;
238+extern char *compare_dest[];
239 extern int make_backups;
240 extern int do_progress;
241 extern char *backup_dir;
242@@ -438,7 +438,8 @@ int recv_files(int f_in, struct file_lis
243 partialptr = partial_dir ? partial_dir_fname(fname) : fname;
244
245 if (f_in_name >= 0) {
246- switch (read_byte(f_in_name)) {
247+ uchar j;
248+ switch (j = read_byte(f_in_name)) {
249 case G2R_FNAME:
250 fnamecmp = fname;
251 break;
252@@ -450,7 +451,7 @@ int recv_files(int f_in, struct file_lis
253 break;
254 default:
255 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
256- compare_dest, fname);
257+ compare_dest[j], fname);
258 fnamecmp = fnamecmpbuf;
259 break;
260 }
261--- orig/rsync.h 2004-09-07 21:52:22
262+++ rsync.h 2004-07-30 07:23:54
263@@ -98,6 +98,8 @@
264
265 #define MAX_ARGS 1000
266
267+#define MAX_COMP_DEST 20
268+
269 #define MPLEX_BASE 7
270
271 #define NO_EXCLUDES 0