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;
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
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");
rprintf(F," --rsync-path=PROGRAM specify the rsync to run on the remote machine\n");
- rprintf(F," --existing only update files that already exist on receiver\n");
rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
+ rprintf(F," --ignore-non-existing ignore files that don't exist on receiving side\n");
rprintf(F," --remove-sent-files sent files/symlinks are removed from sending side\n");
rprintf(F," --del an alias for --delete-during\n");
rprintf(F," --delete delete files that don't exist on the sending side\n");
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");
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};
{"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 },
+ {"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 },
}
-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;
}
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);
}
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;
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;