X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/b6e22a47d3ed994c63876fe57ffd1cdccbb750ac..1db954e9bca018594c9626c92999847d0d1170c5:/options.c diff --git a/options.c b/options.c index 669b15f9..a5b862fd 100644 --- a/options.c +++ b/options.c @@ -94,11 +94,12 @@ int daemon_bwlimit = 0; int bwlimit = 0; int fuzzy_basis = 0; size_t bwlimit_writemax = 0; -int only_existing = 0; -int opt_ignore_existing = 0; +int ignore_existing = 0; +int ignore_non_existing = 0; int need_messages_from_generator = 0; int max_delete = 0; OFF_T max_size = 0; +OFF_T min_size = 0; int ignore_errors = 0; int modify_window = 0; int blocking_io = -1; @@ -167,7 +168,7 @@ static int itemize_changes = 0; static int refused_delete, refused_archive_part; static int refused_partial, refused_progress, refused_delete_before; static int refused_inplace; -static char *max_size_arg; +static char *max_size_arg, *min_size_arg; static char partialdir_for_delayupdate[] = ".~tmp~"; /** Local address to bind. As a character string because it's @@ -251,16 +252,15 @@ void usage(enum logcode F) rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n"); - rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n"); + rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... DEST\n"); + rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n"); + rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n"); + rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n"); rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC [DEST]\n"); - rprintf(F," or rsync [OPTION]... SRC [SRC]... DEST\n"); rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n"); - rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n"); rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n"); - rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n"); - rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n"); - rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n"); - rprintf(F," sources separated by space as long as they have same top-level\n"); + rprintf(F,"The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect\n"); + rprintf(F,"to an rsync daemon, and require SRC or DEST to start with a module name.\n"); rprintf(F,"\nOptions\n"); rprintf(F," -v, --verbose increase verbosity\n"); rprintf(F," -q, --quiet suppress non-error messages\n"); @@ -309,6 +309,7 @@ void usage(enum logcode F) rprintf(F," --force force deletion of directories even if not empty\n"); rprintf(F," --max-delete=NUM don't delete more than NUM files\n"); rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n"); + rprintf(F," --min-size=SIZE don't transfer any file smaller than SIZE\n"); rprintf(F," --partial keep partially transferred files\n"); rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n"); rprintf(F," --delay-updates put all updated files into place at transfer's end\n"); @@ -362,7 +363,7 @@ void usage(enum logcode F) 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_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, + OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE, OPT_REFUSED_BASE = 9000}; @@ -416,9 +417,11 @@ static struct poptOption long_options[] = { {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 }, {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 }, {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 }, - {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 }, - {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 }, - {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 }, + {"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 }, + {"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 }, + {"ignore-non-existing",0,POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 }, + {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 }, + {"min-size", 0, POPT_ARG_STRING, &min_size_arg, OPT_MIN_SIZE, 0, 0 }, {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 }, {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 }, {"append", 0, POPT_ARG_VAL, &append_mode, 1, 0, 0 }, @@ -648,31 +651,58 @@ static int count_args(const char **argv) } -static OFF_T parse_size_arg(const char *size_arg) +static OFF_T parse_size_arg(char **size_arg, char def_suf) { - const char *arg; - OFF_T size; + int mult, make_compatible = 0; + const char *arg, *p; + OFF_T size = 0; - for (arg = size_arg; isdigit(*(uchar*)arg); arg++) {} + for (arg = *size_arg; isdigit(*(uchar*)arg); arg++) {} if (*arg == '.') for (arg++; isdigit(*(uchar*)arg); arg++) {} - switch (*arg) { + if (*arg && (arg[1] == 't' || arg[1] == 'T')) + mult = 1000, make_compatible = 1; + else + mult = 1024; + if ((p = strstr(arg, "+1")) != NULL + || (p = strstr(arg, "-1")) != NULL) { + if (p[2] != '\0') + return -1; + size = atoi(p); + make_compatible = 1; + } + switch (*arg && arg != p ? *arg : def_suf) { + case 'b': case 'B': + size += atof(*size_arg); + break; case 'k': case 'K': - size = atof(size_arg) * 1024; + size += atof(*size_arg) * mult; break; case 'm': case 'M': - size = atof(size_arg) * 1024*1024; + size += atof(*size_arg) * mult*mult; break; case 'g': case 'G': - size = atof(size_arg) * 1024*1024*1024; - break; - case '\0': - size = atof(size_arg); + size += atof(*size_arg) * mult*mult*mult; break; default: - size = 0; + size = -1; break; } + if (size > 0 && make_compatible) { + /* We convert this manually because we may need %lld precision, + * and that's not a portable sprintf() escape. */ + char buf[128], *s = buf + sizeof buf; + OFF_T num = size; + *--s = '\0'; + while (num) { + if (s == buf) /* impossible... */ + out_of_memory("parse_size_arg@buf"); + *--s = (num % 10) + '0'; + num /= 10; + } + if (!(*size_arg = strdup(s))) + out_of_memory("parse_size_arg"); + } return size; } @@ -887,7 +917,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain) break; case OPT_MAX_SIZE: - if ((max_size = parse_size_arg(max_size_arg)) <= 0) { + if ((max_size = parse_size_arg(&max_size_arg, 'b')) <= 0) { snprintf(err_buf, sizeof err_buf, "--max-size value is invalid: %s\n", max_size_arg); @@ -895,6 +925,15 @@ int parse_arguments(int *argc, const char ***argv, int frommain) } break; + case OPT_MIN_SIZE: + if ((min_size = parse_size_arg(&min_size_arg, 'b')) <= 0) { + snprintf(err_buf, sizeof err_buf, + "--min-size value is invalid: %s\n", + min_size_arg); + return 0; + } + break; + case OPT_LINK_DEST: #ifdef HAVE_LINK link_dest = 1; @@ -1023,7 +1062,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain) "You may not combine multiple --delete-WHEN options.\n"); return 0; } - if (!recurse) { + if (!xfer_dirs) { delete_before = delete_during = delete_after = 0; delete_mode = delete_excluded = 0; } else if (delete_before || delete_during || delete_after) @@ -1415,6 +1454,11 @@ void server_options(char **args,int *argc) args[ac++] = arg; } + if (min_size && am_sender) { + args[ac++] = "--min-size"; + args[ac++] = min_size_arg; + } + if (max_size && am_sender) { args[ac++] = "--max-size"; args[ac++] = max_size_arg; @@ -1499,12 +1543,13 @@ void server_options(char **args,int *argc) if (numeric_ids) args[ac++] = "--numeric-ids"; - if (only_existing && am_sender) - args[ac++] = "--existing"; - - if (opt_ignore_existing && am_sender) + if (ignore_existing && am_sender) args[ac++] = "--ignore-existing"; + /* Backward compatibility: send --existing, not --ignore-non-existing. */ + if (ignore_non_existing && am_sender) + args[ac++] = "--existing"; + if (append_mode) args[ac++] = "--append"; else if (inplace)