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