- Needed to move the partial-dir check in the generator.
[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
2f5fa77e 12--- orig/generator.c 2004-07-22 00:05:38
495f1899 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;
2f5fa77e 23@@ -79,13 +79,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
c2530f70 42@@ -413,13 +412,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';
2f5fa77e
WD
66--- orig/main.c 2004-07-22 00:10:43
67+++ main.c 2004-07-22 00:30:38
68@@ -58,7 +58,7 @@ extern int filesfrom_fd;
495f1899
WD
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;
c2530f70 77@@ -458,7 +458,7 @@ static int do_recv(int f_in,int f_out,st
495f1899
WD
78 int pid;
79 int status = 0;
80 int error_pipe[2], name_pipe[2];
c2530f70
WD
81- BOOL need_name_pipe = compare_dest && !dry_run;
82+ BOOL need_name_pipe = compare_dest[0] && !dry_run;
495f1899
WD
83
84 if (preserve_hard_links)
85 init_hard_links(flist);
c2530f70 86--- orig/options.c 2004-07-23 17:16:13
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
c2530f70 106@@ -315,7 +317,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};
c2530f70 115@@ -374,8 +376,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 },
c2530f70 126@@ -591,8 +593,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
c2530f70 163@@ -690,6 +720,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;
c2530f70 175@@ -718,8 +753,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)
c2530f70 184@@ -825,8 +858,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;
c2530f70 194@@ -1004,13 +1037,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)) {
2f5fa77e 214--- orig/receiver.c 2004-07-22 00:20:50
824abc86 215+++ receiver.c 2004-07-03 20:14:37
2f5fa77e 216@@ -38,7 +38,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;
c2530f70 224--- orig/rsync.h 2004-07-23 17:16:13
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