summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compat.c5
-rw-r--r--generator.c24
-rw-r--r--hlink.c4
-rw-r--r--main.c5
-rw-r--r--options.c62
-rw-r--r--rsync.h4
6 files changed, 57 insertions, 47 deletions
diff --git a/compat.c b/compat.c
index 91b2771d..19d054bf 100644
--- a/compat.c
+++ b/compat.c
@@ -51,7 +51,6 @@ extern int do_compression;
extern int do_compression_level;
extern char *shell_cmd;
extern char *partial_dir;
-extern char *dest_option;
extern char *files_from;
extern char *filesfrom_host;
extern const char *checksum_choice;
@@ -566,7 +565,7 @@ void setup_protocol(int f_out,int f_in)
rprintf(FERROR,
"%s with --inplace requires protocol 29 or higher"
" (negotiated %d).\n",
- dest_option, protocol_version);
+ alt_dest_name(0), protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
@@ -574,7 +573,7 @@ void setup_protocol(int f_out,int f_in)
rprintf(FERROR,
"Using more than one %s option requires protocol"
" 29 or higher (negotiated %d).\n",
- dest_option, protocol_version);
+ alt_dest_name(0), protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
diff --git a/generator.c b/generator.c
index b0755a30..39f8310d 100644
--- a/generator.c
+++ b/generator.c
@@ -78,9 +78,7 @@ extern int fuzzy_basis;
extern int always_checksum;
extern int flist_csum_len;
extern char *partial_dir;
-extern int compare_dest;
-extern int copy_dest;
-extern int link_dest;
+extern int alt_dest_type;
extern int whole_file;
extern int list_only;
extern int read_batch;
@@ -916,15 +914,15 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
goto got_nothing_for_ya;
}
- if (match_level == 3 && !copy_dest) {
+ if (match_level == 3 && alt_dest_type != COPY_DEST) {
if (find_exact_for_existing) {
- if (link_dest && real_st.st_dev == sxp->st.st_dev && real_st.st_ino == sxp->st.st_ino)
+ if (alt_dest_type == LINK_DEST && real_st.st_dev == sxp->st.st_dev && real_st.st_ino == sxp->st.st_ino)
return -1;
if (do_unlink(fname) < 0 && errno != ENOENT)
goto got_nothing_for_ya;
}
#ifdef SUPPORT_HARD_LINKS
- if (link_dest) {
+ if (alt_dest_type == LINK_DEST) {
if (!hard_link_one(file, fname, cmpbuf, 1))
goto try_a_copy;
if (atimes_ndx)
@@ -1094,7 +1092,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
if (match_level == 3) {
#ifdef SUPPORT_HARD_LINKS
- if (link_dest
+ if (alt_dest_type == LINK_DEST
#ifndef CAN_HARDLINK_SYMLINK
&& !S_ISLNK(file->mode)
#endif
@@ -1115,7 +1113,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
match_level = 2;
if (itemizing && stdout_format_has_i
&& (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) {
- int chg = compare_dest && type != TYPE_DIR ? 0
+ int chg = alt_dest_type == COMPARE_DEST && type != TYPE_DIR ? 0
: ITEM_LOCAL_CHANGE + (match_level == 3 ? ITEM_XNAME_FOLLOWS : 0);
char *lp = match_level == 3 ? "" : NULL;
itemize(cmpbuf, file, ndx, 0, sxp, chg + ITEM_MATCHED, 0, lp);
@@ -1550,11 +1548,11 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
itemizing, code);
if (j == -2) {
#ifndef CAN_HARDLINK_SYMLINK
- if (link_dest) {
+ if (alt_dest_type == LINK_DEST) {
/* Resort to --copy-dest behavior. */
} else
#endif
- if (!copy_dest)
+ if (alt_dest_type != COPY_DEST)
goto cleanup;
itemizing = 0;
code = FNONE;
@@ -1626,11 +1624,11 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
itemizing, code);
if (j == -2) {
#ifndef CAN_HARDLINK_SPECIAL
- if (link_dest) {
+ if (alt_dest_type == LINK_DEST) {
/* Resort to --copy-dest behavior. */
} else
#endif
- if (!copy_dest)
+ if (alt_dest_type != COPY_DEST)
goto cleanup;
itemizing = 0;
code = FNONE;
@@ -1705,7 +1703,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
stat_errno = ENOENT;
}
- if (basis_dir[0] != NULL && (statret != 0 || !copy_dest)) {
+ if (basis_dir[0] != NULL && (statret != 0 || alt_dest_type != COPY_DEST)) {
int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &sx,
statret == 0, itemizing, code);
if (j == -2) {
diff --git a/hlink.c b/hlink.c
index 91f043f4..419e8290 100644
--- a/hlink.c
+++ b/hlink.c
@@ -29,7 +29,7 @@ extern int list_only;
extern int am_sender;
extern int inc_recurse;
extern int do_xfers;
-extern int link_dest;
+extern int alt_dest_type;
extern int preserve_acls;
extern int preserve_xattrs;
extern int protocol_version;
@@ -396,7 +396,7 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
if (link_stat(cmpbuf, &alt_sx.st, 0) < 0)
continue;
- if (link_dest) {
+ if (alt_dest_type == LINK_DEST) {
if (prev_st.st_dev != alt_sx.st.st_dev
|| prev_st.st_ino != alt_sx.st.st_ino)
continue;
diff --git a/main.c b/main.c
index 90ab43db..5ccfabe3 100644
--- a/main.c
+++ b/main.c
@@ -86,7 +86,6 @@ extern char *stdout_format;
extern char *logfile_format;
extern char *filesfrom_host;
extern char *partial_dir;
-extern char *dest_option;
extern char *rsync_path;
extern char *shell_cmd;
extern char *password_file;
@@ -834,9 +833,9 @@ static void check_alt_basis_dirs(void)
basis_dir[j] = bdir = new;
}
if (do_stat(bdir, &st) < 0)
- rprintf(FWARNING, "%s arg does not exist: %s\n", dest_option, bdir);
+ rprintf(FWARNING, "%s arg does not exist: %s\n", alt_dest_name(0), bdir);
else if (!S_ISDIR(st.st_mode))
- rprintf(FWARNING, "%s arg is not a dir: %s\n", dest_option, bdir);
+ rprintf(FWARNING, "%s arg is not a dir: %s\n", alt_dest_name(0), bdir);
}
}
diff --git a/options.c b/options.c
index b6088405..d865a8e1 100644
--- a/options.c
+++ b/options.c
@@ -177,11 +177,8 @@ char *sockopts = NULL;
char *usermap = NULL;
char *groupmap = NULL;
int rsync_port = 0;
-int compare_dest = 0;
-int copy_dest = 0;
-int link_dest = 0;
+int alt_dest_type = 0;
int basis_dir_cnt = 0;
-char *dest_option = NULL;
static int remote_option_alloc = 0;
int remote_option_cnt = 0;
@@ -1146,6 +1143,9 @@ static void set_refuse_options(void)
parse_one_refuse_match(0, "log-file*", list_end);
}
+#ifndef SUPPORT_HARD_LINKS
+ parse_one_refuse_match(0, "link-dest", list_end);
+#endif
#ifndef ICONV_OPTION
parse_one_refuse_match(0, "iconv", list_end);
#endif
@@ -1297,6 +1297,23 @@ static void popt_unalias(poptContext con, const char *opt)
poptAddAlias(con, unalias, 0);
}
+char *alt_dest_name(int type)
+{
+ if (!type)
+ type = alt_dest_type;
+
+ switch (type) {
+ case COMPARE_DEST:
+ return "--compare-dest";
+ case COPY_DEST:
+ return "--copy-dest";
+ case LINK_DEST:
+ return "--link-dest";
+ default:
+ assert(0);
+ }
+}
+
/**
* Process command line arguments. Called on both local and remote.
*
@@ -1310,7 +1327,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
static poptContext pc;
const char *arg, **argv = *argv_p;
int argc = *argc_p;
- int opt;
+ int opt, want_dest_type;
int orig_protect_args = protect_args;
if (argc == 0) {
@@ -1668,30 +1685,29 @@ int parse_arguments(int *argc_p, const char ***argv_p)
break;
case OPT_LINK_DEST:
-#ifdef SUPPORT_HARD_LINKS
- link_dest = 1;
- dest_option = "--link-dest";
+ want_dest_type = LINK_DEST;
goto set_dest_dir;
-#else
- snprintf(err_buf, sizeof err_buf,
- "hard links are not supported on this %s\n",
- am_server ? "server" : "client");
- return 0;
-#endif
case OPT_COPY_DEST:
- copy_dest = 1;
- dest_option = "--copy-dest";
+ want_dest_type = COPY_DEST;
goto set_dest_dir;
case OPT_COMPARE_DEST:
- compare_dest = 1;
- dest_option = "--compare-dest";
+ want_dest_type = COMPARE_DEST;
+
set_dest_dir:
+ if (alt_dest_type && alt_dest_type != want_dest_type) {
+ snprintf(err_buf, sizeof err_buf,
+ "ERROR: the %s option conflicts with the %s option\n",
+ alt_dest_name(want_dest_type), alt_dest_name(0));
+ return 0;
+ }
+ alt_dest_type = want_dest_type;
+
if (basis_dir_cnt >= MAX_BASIS_DIRS) {
snprintf(err_buf, sizeof err_buf,
"ERROR: at most %d %s args may be specified\n",
- MAX_BASIS_DIRS, dest_option);
+ MAX_BASIS_DIRS, alt_dest_name(0));
return 0;
}
/* We defer sanitizing this arg until we know what
@@ -2039,12 +2055,6 @@ int parse_arguments(int *argc_p, const char ***argv_p)
max_delete = 0;
}
- if (compare_dest + copy_dest + link_dest > 1) {
- snprintf(err_buf, sizeof err_buf,
- "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
- return 0;
- }
-
if (files_from) {
if (recurse == 1) /* preserve recurse == 2 */
recurse = 0;
@@ -2787,7 +2797,7 @@ void server_options(char **args, int *argc_p)
* option, so don't send it if client is the sender.
*/
for (i = 0; i < basis_dir_cnt; i++) {
- args[ac++] = dest_option;
+ args[ac++] = alt_dest_name(0);
args[ac++] = basis_dir[i];
}
}
diff --git a/rsync.h b/rsync.h
index e5394a8e..8af83ecf 100644
--- a/rsync.h
+++ b/rsync.h
@@ -161,6 +161,10 @@
#define MAX_BASIS_DIRS 20
#define MAX_SERVER_ARGS (MAX_BASIS_DIRS*2 + 100)
+#define COMPARE_DEST 1
+#define COPY_DEST 2
+#define LINK_DEST 3
+
#define MPLEX_BASE 7
#define NO_FILTERS 0