Fix failing hunks.
[rsync/rsync-patches.git] / compare-dest.diff
CommitLineData
b952a177 1Depends-On-Patch: partial-dir.diff
824abc86
WD
2Depends-On-Patch: g2r-basis-filename.diff
3
09add1ae
WD
4This patch allows multiple --compare-dest or --link-dest options to be
5used, making the transfer of some files more optimal. Note that the
6algorithm does NOT search for the best match -- it stops at the first
7match and uses that as the basis file for the transfer, so be sure to
8dd60649
WD
8order your arguments appropriately (the args are searched in the order
9they are suppled).
09add1ae 10
8dd60649
WD
11Before compiling, be sure to run "make proto".
12
b952a177
WD
13--- orig/generator.c 2004-07-28 10:14:15
14+++ generator.c 2004-07-28 10:19:57
15@@ -43,7 +43,7 @@ extern int io_timeout;
09add1ae
WD
16 extern int protocol_version;
17 extern int always_checksum;
b952a177 18 extern char *partial_dir;
09add1ae
WD
19-extern char *compare_dest;
20+extern char *compare_dest[];
21 extern int link_dest;
22 extern int whole_file;
23 extern int local_server;
b952a177 24@@ -80,13 +80,12 @@ static int skip_file(char *fname, struct
09add1ae
WD
25 if (always_checksum && S_ISREG(st->st_mode)) {
26 char sum[MD4_SUM_LENGTH];
27 char fnamecmpdest[MAXPATHLEN];
28+ int i;
29
30- if (compare_dest != NULL) {
31- if (access(fname, 0) != 0) {
32- pathjoin(fnamecmpdest, sizeof fnamecmpdest,
33- compare_dest, fname);
34- fname = fnamecmpdest;
35- }
4c189bcd 36+ for (i = 0; compare_dest[i] != NULL && access(fname, 0) < 0; i++) {
09add1ae
WD
37+ pathjoin(fnamecmpdest, sizeof fnamecmpdest,
38+ compare_dest[i], fname);
39+ fname = fnamecmpdest;
40 }
41 file_checksum(fname,sum,st->st_size);
42 return memcmp(sum, file->u.sum, protocol_version < 21 ? 2
b952a177 43@@ -422,11 +421,18 @@ static void recv_generator(char *fname,
09add1ae
WD
44
45 fnamecmp = fname;
46
47- if (statret == -1 && compare_dest != NULL) {
48+ if (statret == -1 && compare_dest[0] != NULL) {
49 /* try the file at compare_dest instead */
09add1ae 50- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
b952a177
WD
51- if (link_stat(fnamecmpbuf, &st, 0) == 0
52- && S_ISREG(st.st_mode)) {
09add1ae
WD
53+ int i;
54+ for (i = 0; compare_dest[i] != NULL; i++) {
55+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest[i], fname);
b952a177
WD
56+ if (link_stat(fnamecmpbuf, &st, 0) == 0
57+ && S_ISREG(st.st_mode)) {
58+ statret = 0;
59+ break;
09add1ae
WD
60+ }
61+ }
b952a177
WD
62+ if (statret == 0) {
63 #if HAVE_LINK
64 if (link_dest && !dry_run) {
65 if (do_link(fnamecmpbuf, fname) < 0) {
66@@ -442,7 +448,6 @@ static void recv_generator(char *fname,
67 } else
68 #endif
69 fnamecmp = fnamecmpbuf;
70- statret = 0;
71 } else
824abc86 72 *fnamecmpbuf = '\0';
b952a177 73 } else
2f5fa77e
WD
74--- orig/main.c 2004-07-22 00:10:43
75+++ main.c 2004-07-22 00:30:38
76@@ -58,7 +58,7 @@ extern int filesfrom_fd;
495f1899
WD
77 extern pid_t cleanup_child_pid;
78 extern char *files_from;
79 extern char *remote_filesfrom_file;
80-extern char *compare_dest;
81+extern char *compare_dest[];
82 extern char *rsync_path;
83 extern char *shell_cmd;
84 extern char *batch_name;
c2530f70 85@@ -458,7 +458,7 @@ static int do_recv(int f_in,int f_out,st
495f1899
WD
86 int pid;
87 int status = 0;
88 int error_pipe[2], name_pipe[2];
c2530f70
WD
89- BOOL need_name_pipe = compare_dest && !dry_run;
90+ BOOL need_name_pipe = compare_dest[0] && !dry_run;
495f1899
WD
91
92 if (preserve_hard_links)
93 init_hard_links(flist);
b952a177
WD
94--- orig/options.c 2004-07-26 16:43:48
95+++ options.c 2004-07-23 22:04:42
96@@ -114,12 +114,13 @@ int write_batch = 0;
97 int read_batch = 0;
98 int backup_dir_len = 0;
99 int backup_suffix_len;
100+int num_comp_dest = 0;
101 unsigned int backup_dir_remainder;
09add1ae
WD
102
103 char *backup_suffix = NULL;
104 char *tmpdir = NULL;
b952a177 105 char *partial_dir = NULL;
09add1ae
WD
106-char *compare_dest = NULL;
107+char *compare_dest[MAX_COMP_DEST+1];
09add1ae
WD
108 char *config_file = NULL;
109 char *shell_cmd = NULL;
110 char *log_format = NULL;
b952a177 111@@ -140,6 +141,7 @@ char *batch_name = NULL;
09add1ae
WD
112
113 static int daemon_opt; /* sets am_daemon after option error-reporting */
114 static int modify_window_set;
115+static int saw_compare_dest = 0;
116
117 /** Local address to bind. As a character string because it's
118 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
b952a177 119@@ -317,7 +319,7 @@ void usage(enum logcode F)
09add1ae
WD
120 }
121
122 enum {OPT_VERSION = 1000, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
123- OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
124+ OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_COMPARE_DEST, OPT_LINK_DEST,
125 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
126 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT,
127 OPT_REFUSED_BASE = 9000};
b952a177 128@@ -376,8 +378,8 @@ static struct poptOption long_options[]
09add1ae
WD
129 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
130 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
131 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
132- {"compare-dest", 0, POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
133- {"link-dest", 0, POPT_ARG_STRING, &compare_dest, OPT_LINK_DEST, 0, 0 },
134+ {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
135+ {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
136 /* TODO: Should this take an optional int giving the compression level? */
137 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
138 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
b952a177 139@@ -594,8 +596,36 @@ int parse_arguments(int *argc, const cha
09add1ae
WD
140 select_timeout = io_timeout;
141 break;
142
143+ case OPT_COMPARE_DEST:
144+#if HAVE_LINK
145+ if (num_comp_dest >= MAX_COMP_DEST-1) {
146+ rprintf(FERROR, "ERROR: %s\n", "too many --compare-dest args given");
147+ return 0;
148+ }
149+ arg = poptGetOptArg(pc);
150+ if (sanitize_paths)
151+ arg = alloc_sanitize_path(arg, curr_dir);
152+ compare_dest[num_comp_dest++] = (char *)arg;
153+ saw_compare_dest = 1;
154+ break;
155+#else
156+ snprintf(err_buf, sizeof err_buf,
157+ "hard links are not supported on this %s\n",
158+ am_server ? "server" : "client");
159+ rprintf(FERROR, "ERROR: %s", err_buf);
160+ return 0;
161+#endif
162+
163 case OPT_LINK_DEST:
164 #if HAVE_LINK
165+ if (num_comp_dest >= MAX_COMP_DEST-1) {
90bcf59b 166+ rprintf(FERROR, "ERROR: %s\n", "too many --link-dest args given");
09add1ae
WD
167+ return 0;
168+ }
169+ arg = poptGetOptArg(pc);
170+ if (sanitize_paths)
171+ arg = alloc_sanitize_path(arg, curr_dir);
172+ compare_dest[num_comp_dest++] = (char *)arg;
173 link_dest = 1;
174 break;
175 #else
b952a177 176@@ -693,6 +723,11 @@ int parse_arguments(int *argc, const cha
09add1ae
WD
177 exit_cleanup(RERR_SYNTAX);
178 }
179
180+ if (saw_compare_dest && link_dest) {
181+ rprintf(FINFO,
182+ "WARNING: promoting --compare-dest options to --link-dest.\n");
183+ }
184+
185 if (archive_mode) {
186 if (!files_from)
187 recurse = 1;
b952a177 188@@ -723,8 +758,6 @@ int parse_arguments(int *argc, const cha
09add1ae 189 tmpdir = alloc_sanitize_path(tmpdir, curr_dir);
b952a177
WD
190 if (partial_dir)
191 partial_dir = alloc_sanitize_path(partial_dir, curr_dir);
09add1ae
WD
192- if (compare_dest)
193- compare_dest = alloc_sanitize_path(compare_dest, curr_dir);
194 if (backup_dir)
195 backup_dir = alloc_sanitize_path(backup_dir, curr_dir);
196 if (files_from)
b952a177 197@@ -836,8 +869,8 @@ int parse_arguments(int *argc, const cha
09add1ae
WD
198 **/
199 void server_options(char **args,int *argc)
200 {
201+ static char argstr[50+MAX_COMP_DEST*2];
202 int ac = *argc;
203- static char argstr[50];
204 char *arg;
205
206 int i, x;
b952a177 207@@ -1018,13 +1051,16 @@ void server_options(char **args,int *arg
09add1ae
WD
208 args[ac++] = tmpdir;
209 }
210
211- if (compare_dest && am_sender) {
212+ if (compare_dest[0] && am_sender) {
213 /* the server only needs this option if it is not the sender,
214 * and it may be an older version that doesn't know this
215 * option, so don't send it if client is the sender.
216 */
217- args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
218- args[ac++] = compare_dest;
219+ int i;
220+ for (i = 0; i < num_comp_dest; i++) {
221+ args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
222+ args[ac++] = compare_dest[i];
223+ }
224 }
225
226 if (files_from && (!am_sender || remote_filesfrom_file)) {
b952a177
WD
227--- orig/receiver.c 2004-07-23 21:59:07
228+++ receiver.c 2004-07-23 22:05:04
229@@ -39,7 +39,6 @@ extern int cvs_exclude;
09add1ae
WD
230 extern int io_error;
231 extern char *tmpdir;
b952a177 232 extern char *partial_dir;
09add1ae 233-extern char *compare_dest;
09add1ae
WD
234 extern int make_backups;
235 extern int do_progress;
236 extern char *backup_dir;
b952a177 237--- orig/rsync.h 2004-07-27 23:23:54
824abc86 238+++ rsync.h 2004-07-03 17:33:30
09add1ae
WD
239@@ -98,6 +98,8 @@
240
241 #define MAX_ARGS 1000
242
243+#define MAX_COMP_DEST 20
244+
245 #define MPLEX_BASE 7
246
247 #define NO_EXCLUDES 0