+++ /dev/null
-This patch allows multiple --compare-dest or --link-dest options to be
-used, making the transfer of some files more optimal. Note that the
-algorithm does NOT search for the best match -- it stops at the first
-match and uses that as the basis file for the transfer, so be sure to
-order your arguments appropriately (the args are searched in the order
-they are suppled).
-
-Before compiling, be sure to run "make proto".
-
---- orig/generator.c 2004-11-11 22:13:09
-+++ generator.c 2004-11-03 22:47:23
-@@ -46,7 +46,7 @@ extern int io_timeout;
- extern int protocol_version;
- extern int always_checksum;
- extern char *partial_dir;
--extern char *compare_dest;
-+extern char *compare_dest[];
- extern int link_dest;
- extern int whole_file;
- extern int local_server;
-@@ -429,11 +429,19 @@ static void recv_generator(char *fname,
- fnamecmp = fname;
- fnamecmp_type = FNAMECMP_FNAME;
-
-- if (statret == -1 && compare_dest != NULL) {
-+ if (statret == -1 && compare_dest[0] != NULL) {
- /* try the file at compare_dest instead */
-- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
-- if (link_stat(fnamecmpbuf, &st, 0) == 0
-- && S_ISREG(st.st_mode)) {
-+ int i = 0;
-+ do {
-+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
-+ compare_dest[i], fname);
-+ if (link_stat(fnamecmpbuf, &st, 0) == 0
-+ && S_ISREG(st.st_mode)) {
-+ statret = 0;
-+ break;
-+ }
-+ } while (compare_dest[++i] != NULL);
-+ if (statret == 0) {
- #if HAVE_LINK
- if (link_dest && !dry_run) {
- if (do_link(fnamecmpbuf, fname) < 0) {
-@@ -444,15 +452,14 @@ static void recv_generator(char *fname,
- safe_fname(fname));
- }
- fnamecmp = fnamecmpbuf;
-- fnamecmp_type = FNAMECMP_CMPDEST;
-+ fnamecmp_type = FNAMECMP_CMPDEST + i;
- }
- } else
- #endif
- {
- fnamecmp = fnamecmpbuf;
-- fnamecmp_type = FNAMECMP_CMPDEST;
-+ fnamecmp_type = FNAMECMP_CMPDEST + i;
- }
-- statret = 0;
- }
- }
-
---- orig/main.c 2004-11-25 16:32:40
-+++ main.c 2004-07-30 07:23:54
-@@ -59,7 +59,7 @@ extern int filesfrom_fd;
- extern pid_t cleanup_child_pid;
- extern char *files_from;
- extern char *remote_filesfrom_file;
--extern char *compare_dest;
-+extern char *compare_dest[];
- extern char *rsync_path;
- extern char *shell_cmd;
- extern char *batch_name;
-@@ -463,7 +463,7 @@ static int do_recv(int f_in,int f_out,st
- int pid;
- int status = 0;
- int error_pipe[2], name_pipe[2];
-- BOOL need_name_pipe = compare_dest && !dry_run;
-+ BOOL need_name_pipe = compare_dest[0] && !dry_run;
-
- /* The receiving side mustn't obey this, or an existing symlink that
- * points to an identical file won't be replaced by the referent. */
---- orig/options.c 2004-11-17 19:41:31
-+++ options.c 2004-11-25 16:38:16
-@@ -116,12 +116,13 @@ int write_batch = 0;
- int read_batch = 0;
- int backup_dir_len = 0;
- int backup_suffix_len;
-+int num_comp_dest = 0;
- unsigned int backup_dir_remainder;
-
- char *backup_suffix = NULL;
- char *tmpdir = NULL;
- char *partial_dir = NULL;
--char *compare_dest = NULL;
-+char *compare_dest[MAX_COMP_DEST+1];
- char *config_file = NULL;
- char *shell_cmd = NULL;
- char *log_format = NULL;
-@@ -142,6 +143,7 @@ char *batch_name = NULL;
-
- static int daemon_opt; /* sets am_daemon after option error-reporting */
- static int modify_window_set;
-+static int saw_compare_dest = 0;
- static char *max_size_arg;
-
- /** Local address to bind. As a character string because it's
-@@ -314,7 +316,7 @@ void usage(enum logcode F)
- }
-
- enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
-- OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
-+ OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_COMPARE_DEST, OPT_LINK_DEST,
- OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
- OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
- OPT_REFUSED_BASE = 9000};
-@@ -374,8 +376,8 @@ static struct poptOption long_options[]
- {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
- {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
- {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
-- {"compare-dest", 0, POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
-- {"link-dest", 0, POPT_ARG_STRING, &compare_dest, OPT_LINK_DEST, 0, 0 },
-+ {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
-+ {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
- /* TODO: Should this take an optional int giving the compression level? */
- {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
- {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
-@@ -712,7 +714,7 @@ int parse_arguments(int *argc, const cha
- case OPT_LINK_DEST:
- #if HAVE_LINK
- link_dest = 1;
-- break;
-+ goto compare_dest;
- #else
- snprintf(err_buf, sizeof err_buf,
- "hard links are not supported on this %s\n",
-@@ -720,6 +722,20 @@ int parse_arguments(int *argc, const cha
- return 0;
- #endif
-
-+ case OPT_COMPARE_DEST:
-+ saw_compare_dest = 1;
-+ compare_dest:
-+ if (num_comp_dest >= MAX_COMP_DEST-1) {
-+ rprintf(FERROR, "ERROR: too many %s args given\n",
-+ link_dest ? "--link-dest" : "--compare-dest");
-+ return 0;
-+ }
-+ arg = poptGetOptArg(pc);
-+ if (sanitize_paths)
-+ arg = sanitize_path(NULL, arg, NULL, 0);
-+ compare_dest[num_comp_dest++] = (char *)arg;
-+ break;
-+
- default:
- /* A large opt value means that set_refuse_options()
- * turned this option off (opt-BASE is its index). */
-@@ -802,6 +818,11 @@ int parse_arguments(int *argc, const cha
- return 0;
- }
-
-+ if (saw_compare_dest && link_dest) {
-+ rprintf(FINFO,
-+ "WARNING: promoting --compare-dest options to --link-dest.\n");
-+ }
-+
- if (archive_mode) {
- if (!files_from)
- recurse = 1;
-@@ -829,8 +850,6 @@ int parse_arguments(int *argc, const cha
- tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
- if (partial_dir)
- partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
-- if (compare_dest)
-- compare_dest = sanitize_path(NULL, compare_dest, NULL, 0);
- if (backup_dir)
- backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
- if (files_from)
-@@ -838,6 +857,7 @@ int parse_arguments(int *argc, const cha
- }
- if (server_exclude_list.head && !am_sender) {
- struct exclude_list_struct *elp = &server_exclude_list;
-+ int i;
- if (tmpdir) {
- clean_fname(tmpdir, 1);
- if (check_exclude(elp, tmpdir, 1) < 0)
-@@ -848,9 +868,9 @@ int parse_arguments(int *argc, const cha
- if (check_exclude(elp, partial_dir, 1) < 0)
- goto options_rejected;
- }
-- if (compare_dest) {
-- clean_fname(compare_dest, 1);
-- if (check_exclude(elp, compare_dest, 1) < 0)
-+ for (i = 0; i < num_comp_dest; i++) {
-+ clean_fname(compare_dest[i], 1);
-+ if (check_exclude(elp, compare_dest[i], 1) < 0)
- goto options_rejected;
- }
- if (backup_dir) {
-@@ -923,7 +943,7 @@ int parse_arguments(int *argc, const cha
- am_server ? "server" : "client");
- return 0;
- #endif
-- if (compare_dest) {
-+ if (saw_compare_dest || link_dest) {
- snprintf(err_buf, sizeof err_buf,
- "--inplace does not yet work with %s\n",
- link_dest ? "--link-dest" : "--compare-dest");
-@@ -990,8 +1010,8 @@ int parse_arguments(int *argc, const cha
- **/
- void server_options(char **args,int *argc)
- {
-+ static char argstr[50+MAX_COMP_DEST*2];
- int ac = *argc;
-- static char argstr[50];
- char *arg;
-
- int i, x;
-@@ -1179,13 +1199,16 @@ void server_options(char **args,int *arg
- args[ac++] = tmpdir;
- }
-
-- if (compare_dest && am_sender) {
-+ if (compare_dest[0] && am_sender) {
- /* the server only needs this option if it is not the sender,
- * and it may be an older version that doesn't know this
- * option, so don't send it if client is the sender.
- */
-- args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
-- args[ac++] = compare_dest;
-+ int i;
-+ for (i = 0; i < num_comp_dest; i++) {
-+ args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
-+ args[ac++] = compare_dest[i];
-+ }
- }
-
- if (files_from && (!am_sender || remote_filesfrom_file)) {
---- orig/receiver.c 2004-11-03 20:30:45
-+++ receiver.c 2004-11-03 22:50:43
-@@ -39,7 +39,7 @@ extern int cvs_exclude;
- extern int io_error;
- extern char *tmpdir;
- extern char *partial_dir;
--extern char *compare_dest;
-+extern char *compare_dest[];
- extern int make_backups;
- extern int do_progress;
- extern char *backup_dir;
-@@ -439,7 +439,8 @@ int recv_files(int f_in, struct file_lis
- partialptr = partial_dir ? partial_dir_fname(fname) : fname;
-
- if (f_in_name >= 0) {
-- switch (read_byte(f_in_name)) {
-+ uchar j;
-+ switch (j = read_byte(f_in_name)) {
- case FNAMECMP_FNAME:
- fnamecmp = fname;
- break;
-@@ -452,7 +453,7 @@ int recv_files(int f_in, struct file_lis
- case FNAMECMP_CMPDEST:
- default:
- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
-- compare_dest, fname);
-+ compare_dest[j], fname);
- fnamecmp = fnamecmpbuf;
- break;
- }
---- orig/rsync.h 2004-11-03 20:30:45
-+++ rsync.h 2004-07-30 07:23:54
-@@ -98,6 +98,8 @@
-
- #define MAX_ARGS 1000
-
-+#define MAX_COMP_DEST 20
-+
- #define MPLEX_BASE 7
-
- #define NO_EXCLUDES 0
---- orig/testsuite/compare-dest.test 2004-07-23 17:16:13
-+++ testsuite/compare-dest.test 2004-11-25 16:56:33
-@@ -11,22 +11,25 @@
-
- set -x
-
--altdir="$tmpdir/alt"
-+alt1dir="$tmpdir/alt1"
-+alt2dir="$tmpdir/alt2"
-
- # Build some files/dirs/links to copy
-
- hands_setup
-
- # Setup the alt and chk dirs
--$RSYNC -av --include=text --include='*/' --exclude='*' "$fromdir/" "$altdir/"
-+$RSYNC -av --include=text --include='*/' --exclude='*' "$fromdir/" "$alt1dir/"
-+$RSYNC -av --include=etc-ltr-list --include='*/' --exclude='*' "$fromdir/" "$alt2dir/"
-
- sleep 1
- touch "$fromdir/dir/text"
-
--$RSYNC -av --exclude=/text "$fromdir/" "$chkdir/"
-+$RSYNC -av --exclude=/text --exclude=etc-ltr-list "$fromdir/" "$chkdir/"
-
- # Let's do it!
--checkit "$RSYNC -avv --no-whole-file --compare-dest=\"$altdir\" \
-+checkit "$RSYNC -avv --no-whole-file \
-+ --compare-dest=\"$alt1dir\" --compare-dest=\"$alt2dir\" \
- \"$fromdir/\" \"$todir/\"" "$chkdir" "$todir"
-
- # The script would have aborted on error, so getting here means we've won.