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