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