Updated.
[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
824abc86
WD
12--- orig/generator.c 2004-07-03 20:08:07
13+++ generator.c 2004-07-03 20:14:37
09add1ae
WD
14@@ -42,7 +42,7 @@ extern int size_only;
15 extern int io_timeout;
16 extern int protocol_version;
17 extern int always_checksum;
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;
f6c3b300 23@@ -80,13 +80,12 @@ static int skip_file(char *fname, struct
09add1ae
WD
24 if (always_checksum && S_ISREG(st->st_mode)) {
25 char sum[MD4_SUM_LENGTH];
26 char fnamecmpdest[MAXPATHLEN];
27+ int i;
28
29- if (compare_dest != NULL) {
30- if (access(fname, 0) != 0) {
31- pathjoin(fnamecmpdest, sizeof fnamecmpdest,
32- compare_dest, fname);
33- fname = fnamecmpdest;
34- }
4c189bcd 35+ for (i = 0; compare_dest[i] != NULL && access(fname, 0) < 0; i++) {
09add1ae
WD
36+ pathjoin(fnamecmpdest, sizeof fnamecmpdest,
37+ compare_dest[i], fname);
38+ fname = fnamecmpdest;
39 }
40 file_checksum(fname,sum,st->st_size);
41 return memcmp(sum, file->u.sum, protocol_version < 21 ? 2
f6c3b300 42@@ -411,13 +410,18 @@ static void recv_generator(char *fname,
09add1ae
WD
43
44 fnamecmp = fname;
45
46- if (statret == -1 && compare_dest != NULL) {
47+ if (statret == -1 && compare_dest[0] != NULL) {
48 /* try the file at compare_dest instead */
49 int saveerrno = errno;
50- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
51- statret = link_stat(fnamecmpbuf, &st, 0);
52- if (!S_ISREG(st.st_mode))
53- statret = -1;
54+ int i;
55+ for (i = 0; compare_dest[i] != NULL; i++) {
56+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest[i], fname);
57+ if ((statret = link_stat(fnamecmpbuf, &st, 0)) == 0) {
58+ if (S_ISREG(st.st_mode))
59+ break;
60+ statret = -1;
61+ }
62+ }
824abc86 63 if (statret < 0) {
09add1ae 64 errno = saveerrno;
824abc86 65 *fnamecmpbuf = '\0';
f6c3b300 66--- orig/options.c 2004-07-16 20:07:22
824abc86 67+++ options.c 2004-07-03 17:33:30
f6c3b300 68@@ -118,7 +118,8 @@ unsigned int backup_dir_remainder;
09add1ae
WD
69
70 char *backup_suffix = NULL;
71 char *tmpdir = NULL;
72-char *compare_dest = NULL;
73+char *compare_dest[MAX_COMP_DEST+1];
74+int num_comp_dest = 0;
75 char *config_file = NULL;
76 char *shell_cmd = NULL;
77 char *log_format = NULL;
f6c3b300 78@@ -139,6 +140,7 @@ char *batch_name = NULL;
09add1ae
WD
79
80 static int daemon_opt; /* sets am_daemon after option error-reporting */
81 static int modify_window_set;
82+static int saw_compare_dest = 0;
83
84 /** Local address to bind. As a character string because it's
85 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
f6c3b300 86@@ -314,7 +316,7 @@ void usage(enum logcode F)
09add1ae
WD
87 }
88
89 enum {OPT_VERSION = 1000, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
90- OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
91+ OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_COMPARE_DEST, OPT_LINK_DEST,
92 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
93 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT,
94 OPT_REFUSED_BASE = 9000};
f6c3b300 95@@ -373,8 +375,8 @@ static struct poptOption long_options[]
09add1ae
WD
96 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
97 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
98 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
99- {"compare-dest", 0, POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
100- {"link-dest", 0, POPT_ARG_STRING, &compare_dest, OPT_LINK_DEST, 0, 0 },
101+ {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
102+ {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
103 /* TODO: Should this take an optional int giving the compression level? */
104 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
105 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
f6c3b300 106@@ -590,8 +592,36 @@ int parse_arguments(int *argc, const cha
09add1ae
WD
107 select_timeout = io_timeout;
108 break;
109
110+ case OPT_COMPARE_DEST:
111+#if HAVE_LINK
112+ if (num_comp_dest >= MAX_COMP_DEST-1) {
113+ rprintf(FERROR, "ERROR: %s\n", "too many --compare-dest args given");
114+ return 0;
115+ }
116+ arg = poptGetOptArg(pc);
117+ if (sanitize_paths)
118+ arg = alloc_sanitize_path(arg, curr_dir);
119+ compare_dest[num_comp_dest++] = (char *)arg;
120+ saw_compare_dest = 1;
121+ break;
122+#else
123+ snprintf(err_buf, sizeof err_buf,
124+ "hard links are not supported on this %s\n",
125+ am_server ? "server" : "client");
126+ rprintf(FERROR, "ERROR: %s", err_buf);
127+ return 0;
128+#endif
129+
130 case OPT_LINK_DEST:
131 #if HAVE_LINK
132+ if (num_comp_dest >= MAX_COMP_DEST-1) {
90bcf59b 133+ rprintf(FERROR, "ERROR: %s\n", "too many --link-dest args given");
09add1ae
WD
134+ return 0;
135+ }
136+ arg = poptGetOptArg(pc);
137+ if (sanitize_paths)
138+ arg = alloc_sanitize_path(arg, curr_dir);
139+ compare_dest[num_comp_dest++] = (char *)arg;
140 link_dest = 1;
141 break;
142 #else
f6c3b300 143@@ -684,6 +714,11 @@ int parse_arguments(int *argc, const cha
09add1ae
WD
144 exit_cleanup(RERR_SYNTAX);
145 }
146
147+ if (saw_compare_dest && link_dest) {
148+ rprintf(FINFO,
149+ "WARNING: promoting --compare-dest options to --link-dest.\n");
150+ }
151+
152 if (archive_mode) {
153 if (!files_from)
154 recurse = 1;
f6c3b300 155@@ -712,8 +747,6 @@ int parse_arguments(int *argc, const cha
09add1ae
WD
156 (*argv)[i] = alloc_sanitize_path((*argv)[i], NULL);
157 if (tmpdir)
158 tmpdir = alloc_sanitize_path(tmpdir, curr_dir);
159- if (compare_dest)
160- compare_dest = alloc_sanitize_path(compare_dest, curr_dir);
161 if (backup_dir)
162 backup_dir = alloc_sanitize_path(backup_dir, curr_dir);
163 if (files_from)
f6c3b300 164@@ -819,8 +852,8 @@ int parse_arguments(int *argc, const cha
09add1ae
WD
165 **/
166 void server_options(char **args,int *argc)
167 {
168+ static char argstr[50+MAX_COMP_DEST*2];
169 int ac = *argc;
170- static char argstr[50];
171 char *arg;
172
173 int i, x;
f6c3b300 174@@ -998,13 +1031,16 @@ void server_options(char **args,int *arg
09add1ae
WD
175 args[ac++] = tmpdir;
176 }
177
178- if (compare_dest && am_sender) {
179+ if (compare_dest[0] && am_sender) {
180 /* the server only needs this option if it is not the sender,
181 * and it may be an older version that doesn't know this
182 * option, so don't send it if client is the sender.
183 */
184- args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
185- args[ac++] = compare_dest;
186+ int i;
187+ for (i = 0; i < num_comp_dest; i++) {
188+ args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
189+ args[ac++] = compare_dest[i];
190+ }
191 }
192
193 if (files_from && (!am_sender || remote_filesfrom_file)) {
824abc86
WD
194--- orig/receiver.c 2004-07-03 20:08:07
195+++ receiver.c 2004-07-03 20:14:37
8dd60649 196@@ -36,7 +36,6 @@ extern int preserve_perms;
09add1ae
WD
197 extern int cvs_exclude;
198 extern int io_error;
199 extern char *tmpdir;
200-extern char *compare_dest;
09add1ae
WD
201 extern int make_backups;
202 extern int do_progress;
203 extern char *backup_dir;
f6c3b300 204--- orig/rsync.h 2004-07-16 20:07:23
824abc86 205+++ rsync.h 2004-07-03 17:33:30
09add1ae
WD
206@@ -98,6 +98,8 @@
207
208 #define MAX_ARGS 1000
209
210+#define MAX_COMP_DEST 20
211+
212 #define MPLEX_BASE 7
213
214 #define NO_EXCLUDES 0