X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/ba22c9e219ccd45fea318e7759a7fe4a7c3703dc..0b52f94da727c4881b58c1cd6f2cf2a824e02b30:/options.c diff --git a/options.c b/options.c index a3ea1c6a..d12d28a7 100644 --- a/options.c +++ b/options.c @@ -27,6 +27,7 @@ extern int module_id; extern int sanitize_paths; extern int daemon_over_rsh; +extern unsigned int module_dirlen; extern struct filter_list_struct filter_list; extern struct filter_list_struct server_filter_list; @@ -201,7 +202,7 @@ static int itemize_changes = 0; static int refused_delete, refused_archive_part, refused_compress; static int refused_partial, refused_progress, refused_delete_before; static int refused_delete_during; -static int refused_inplace; +static int refused_inplace, refused_no_iconv; static char *max_size_arg, *min_size_arg; static char tmp_partialdir[] = ".~tmp~"; @@ -353,7 +354,7 @@ void usage(enum logcode F) #endif rprintf(F," -S, --sparse handle sparse files efficiently\n"); rprintf(F," -n, --dry-run perform a trial run with no changes made\n"); - rprintf(F," -W, --whole-file copy files whole (without rsync algorithm)\n"); + rprintf(F," -W, --whole-file copy files whole (without delta-xfer algorithm)\n"); rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n"); rprintf(F," -B, --block-size=SIZE force a fixed checksum block-size\n"); rprintf(F," -e, --rsh=COMMAND specify the remote shell to use\n"); @@ -440,7 +441,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST, OPT_HELP, OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD, OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE, - OPT_NO_D, OPT_APPEND, + OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_SERVER, OPT_REFUSED_BASE = 9000}; static struct poptOption long_options[] = { @@ -611,6 +612,7 @@ static struct poptOption long_options[] = { {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 }, #ifdef ICONV_OPTION {"iconv", 0, POPT_ARG_STRING, &iconv_opt, 0, 0, 0 }, + {"no-iconv", 0, POPT_ARG_NONE, 0, OPT_NO_ICONV, 0, 0 }, #endif {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 }, {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 }, @@ -757,6 +759,8 @@ static void set_refuse_options(char *bp) refused_progress = op->val; else if (wildmatch("inplace", op->longName)) refused_inplace = op->val; + else if (wildmatch("no-iconv", op->longName)) + refused_no_iconv = op->val; break; } if (!is_wild) @@ -877,8 +881,11 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) if (ref && *ref) set_refuse_options(ref); - if (am_daemon) + if (am_daemon) { set_refuse_options("log-file*"); + if (!*lp_charset(module_id)) + set_refuse_options("iconv"); + } #ifdef ICONV_OPTION if (!am_daemon && !protect_args && (arg = getenv("RSYNC_ICONV")) != NULL && *arg) @@ -1007,13 +1014,14 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) arg = sanitize_path(NULL, arg, NULL, 0); if (server_filter_list.head) { int rej; - char *cp = strdup(arg); + char *dir, *cp = strdup(arg); if (!cp) out_of_memory("parse_arguments"); if (!*cp) goto options_rejected; - clean_fname(cp, CFN_COLLAPSE_DOT_DOT_DIRS); - rej = check_filter(&server_filter_list, cp, 0) < 0; + dir = cp + (*cp == '/' ? module_dirlen : 0); + clean_fname(dir, CFN_COLLAPSE_DOT_DOT_DIRS); + rej = check_filter(&server_filter_list, dir, 0) < 0; free(cp); if (rej) goto options_rejected; @@ -1125,6 +1133,10 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) read_batch = 1; break; + case OPT_NO_ICONV: + iconv_opt = NULL; + break; + case OPT_MAX_SIZE: if ((max_size = parse_size_arg(&max_size_arg, 'b')) <= 0) { snprintf(err_buf, sizeof err_buf, @@ -1252,6 +1264,10 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) else need_unsorted_flist = 1; } + if (refused_no_iconv && !iconv_opt) { + create_refuse_error(refused_no_iconv); + return 0; + } #endif if (protect_args == 1) { @@ -1304,7 +1320,8 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) batch_name = NULL; } else if (dry_run) write_batch = 0; - } + } else if (write_batch < 0 && dry_run) + write_batch = 0; if (read_batch && files_from) { snprintf(err_buf, sizeof err_buf, "--read-batch cannot be used with --files-from\n"); @@ -1406,17 +1423,21 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) if (server_filter_list.head && !am_sender) { struct filter_list_struct *elp = &server_filter_list; if (tmpdir) { + char *dir; if (!*tmpdir) goto options_rejected; - clean_fname(tmpdir, CFN_COLLAPSE_DOT_DOT_DIRS); - if (check_filter(elp, tmpdir, 1) < 0) + dir = tmpdir + (*tmpdir == '/' ? module_dirlen : 0); + clean_fname(dir, CFN_COLLAPSE_DOT_DOT_DIRS); + if (check_filter(elp, dir, 1) < 0) goto options_rejected; } if (backup_dir) { + char *dir; if (!*backup_dir) goto options_rejected; - clean_fname(backup_dir, CFN_COLLAPSE_DOT_DOT_DIRS); - if (check_filter(elp, backup_dir, 1) < 0) + dir = backup_dir + (*backup_dir == '/' ? module_dirlen : 0); + clean_fname(dir, CFN_COLLAPSE_DOT_DOT_DIRS); + if (check_filter(elp, dir, 1) < 0) goto options_rejected; } } @@ -1607,10 +1628,12 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) if (sanitize_paths) files_from = sanitize_path(NULL, files_from, NULL, 0); if (server_filter_list.head) { + char *dir; if (!*files_from) goto options_rejected; - clean_fname(files_from, CFN_COLLAPSE_DOT_DOT_DIRS); - if (check_filter(&server_filter_list, files_from, 0) < 0) + dir = files_from + (*files_from == '/' ? module_dirlen : 0); + clean_fname(dir, CFN_COLLAPSE_DOT_DOT_DIRS); + if (check_filter(&server_filter_list, dir, 0) < 0) goto options_rejected; } filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);