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