*
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2000, 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2002-2009 Wayne Davison
+ * Copyright (C) 2002-2011 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int filesfrom_fd = -1;
char *filesfrom_host = NULL;
int eol_nulls = 0;
-int protect_args = 0;
+int protect_args = -1;
int human_readable = 1;
int recurse = 0;
int allow_inc_recurse = 1;
DEBUG_WORD(DEL, W_REC, "Debug delete actions (levels 1-3)"),
DEBUG_WORD(DELTASUM, W_SND|W_REC, "Debug delta-transfer checksumming (levels 1-4)"),
DEBUG_WORD(DUP, W_REC, "Debug weeding of duplicate names"),
- DEBUG_WORD(EXIT, W_CLI|W_SRV, "Debug exit events (levels 1-2)"),
+ DEBUG_WORD(EXIT, W_CLI|W_SRV, "Debug exit events (levels 1-3)"),
DEBUG_WORD(FILTER, W_SND|W_REC, "Debug filter actions (levels 1-2)"),
DEBUG_WORD(FLIST, W_SND|W_REC, "Debug file-list operations (levels 1-4)"),
DEBUG_WORD(FUZZY, W_REC, "Debug fuzzy scoring (levels 1-2)"),
DEBUG_WORD(GENR, W_REC, "Debug generator functions"),
DEBUG_WORD(HASH, W_SND|W_REC, "Debug hashtable code"),
- DEBUG_WORD(HLINK, W_SND|W_REC, "Debug hard-link actions"),
+ DEBUG_WORD(HLINK, W_SND|W_REC, "Debug hard-link actions (levels 1-3)"),
DEBUG_WORD(ICONV, W_CLI|W_SRV, "Debug iconv character conversions (levels 1-2)"),
DEBUG_WORD(IO, W_CLI|W_SRV, "Debug I/O routines (levels 1-4)"),
DEBUG_WORD(OWN, W_REC, "Debug ownership changes in users & groups (levels 1-2)"),
static int do_progress = 0;
static int daemon_opt; /* sets am_daemon after option error-reporting */
static int omit_dir_times = 0;
+static int omit_link_times = 0;
static int F_option_cnt = 0;
static int modify_window_set;
static int itemize_changes = 0;
static int refused_delete_during;
static int refused_inplace, refused_no_iconv;
static BOOL usermap_via_chown, groupmap_via_chown;
-static char *max_size_arg, *min_size_arg;
+static char *bwlimit_arg, *max_size_arg, *min_size_arg;
static char tmp_partialdir[] = ".~tmp~";
/** Local address to bind. As a character string because it's
rprintf(f, "%s version %s protocol version %d%s\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
- rprintf(f, "Copyright (C) 1996-2009 by Andrew Tridgell, Wayne Davison, and others.\n");
+ rprintf(f, "Copyright (C) 1996-2011 by Andrew Tridgell, Wayne Davison, and others.\n");
rprintf(f, "Web site: http://rsync.samba.org/\n");
rprintf(f, "Capabilities:\n");
rprintf(f, " %d-bit files, %d-bit inums, %d-bit timestamps, %d-bit long ints,\n",
rprintf(F," -D same as --devices --specials\n");
rprintf(F," -t, --times preserve modification times\n");
rprintf(F," -O, --omit-dir-times omit directories from --times\n");
+ rprintf(F," -J, --omit-link-times omit symlinks from --times\n");
rprintf(F," --super receiver attempts super-user activities\n");
#ifdef SUPPORT_XATTRS
rprintf(F," --fake-super store/recover privileged attrs using xattrs\n");
rprintf(F," --log-file-format=FMT log updates using the specified FMT\n");
rprintf(F," --password-file=FILE read daemon-access password from FILE\n");
rprintf(F," --list-only list the files instead of copying them\n");
- rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
+ rprintf(F," --bwlimit=RATE limit socket I/O bandwidth\n");
rprintf(F," --write-batch=FILE write a batched update to FILE\n");
rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
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_ICONV, OPT_INFO, OPT_DEBUG,
- OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN,
+ OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT,
OPT_SERVER, OPT_REFUSED_BASE = 9000};
static struct poptOption long_options[] = {
{"xattrs", 'X', POPT_ARG_NONE, 0, 'X', 0, 0 },
{"no-xattrs", 0, POPT_ARG_VAL, &preserve_xattrs, 0, 0, 0 },
{"no-X", 0, POPT_ARG_VAL, &preserve_xattrs, 0, 0, 0 },
- {"times", 't', POPT_ARG_VAL, &preserve_times, 2, 0, 0 },
+ {"times", 't', POPT_ARG_VAL, &preserve_times, 1, 0, 0 },
{"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
{"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
{"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 },
{"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
{"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
+ {"omit-link-times", 'J', POPT_ARG_VAL, &omit_link_times, 1, 0, 0 },
+ {"no-omit-link-times",0, POPT_ARG_VAL, &omit_link_times, 0, 0, 0 },
+ {"no-J", 0, POPT_ARG_VAL, &omit_link_times, 0, 0, 0 },
{"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
{"super", 0, POPT_ARG_VAL, &am_root, 2, 0, 0 },
{"no-super", 0, POPT_ARG_VAL, &am_root, 0, 0, 0 },
{"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
{"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
{"one-file-system", 'x', POPT_ARG_NONE, 0, 'x', 0, 0 },
- {"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
- {"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
+ {"no-one-file-system",0, POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
+ {"no-x", 0, POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
{"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
{"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
{"ignore-non-existing",0,POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
{"itemize-changes", 'i', POPT_ARG_NONE, 0, 'i', 0, 0 },
{"no-itemize-changes",0, POPT_ARG_VAL, &itemize_changes, 0, 0, 0 },
{"no-i", 0, POPT_ARG_VAL, &itemize_changes, 0, 0, 0 },
- {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
+ {"bwlimit", 0, POPT_ARG_STRING, &bwlimit_arg, OPT_BWLIMIT, 0, 0 },
{"no-bwlimit", 0, POPT_ARG_VAL, &bwlimit, 0, 0, 0 },
{"backup", 'b', POPT_ARG_VAL, &make_backups, 1, 0, 0 },
{"no-backup", 0, POPT_ARG_VAL, &make_backups, 0, 0, 0 },
rprintf(F,"\n");
rprintf(F,"Usage: rsync --daemon [OPTION]...\n");
rprintf(F," --address=ADDRESS bind to the specified address\n");
- rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
+ rprintf(F," --bwlimit=RATE limit socket I/O bandwidth\n");
rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
rprintf(F," -M, --dparam=OVERRIDE override global daemon config parameter\n");
rprintf(F," --no-detach do not detach from the parent\n");
size += atoi(arg), make_compatible = 1, arg += 2;
if (*arg)
return -1;
- if (size > 0 && make_compatible) {
+ if (size > 0 && make_compatible && def_suf == 'b') {
/* 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 - 1;
}
#ifdef ICONV_OPTION
- if (!am_daemon && !protect_args && (arg = getenv("RSYNC_ICONV")) != NULL && *arg)
+ if (!am_daemon && protect_args <= 0 && (arg = getenv("RSYNC_ICONV")) != NULL && *arg)
iconv_opt = strdup(arg);
#endif
#ifdef ICONV_OPTION
iconv_opt = NULL;
#endif
+ protect_args = 0;
poptFreeContext(pc);
pc = poptGetContext(RSYNC_NAME, argc, argv,
long_daemon_options, 0);
preserve_links = 1;
#endif
preserve_perms = 1;
- preserve_times = 2;
+ preserve_times = 1;
preserve_gid = 1;
preserve_uid = 1;
preserve_devices = 1;
}
break;
+ case OPT_BWLIMIT:
+ {
+ OFF_T limit = parse_size_arg(&bwlimit_arg, 'K');
+ if (limit < 0) {
+ snprintf(err_buf, sizeof err_buf,
+ "--bwlimit value is invalid: %s\n", bwlimit_arg);
+ return 0;
+ }
+ bwlimit = (limit + 512) / 1024;
+ if (limit && !bwlimit) {
+ snprintf(err_buf, sizeof err_buf,
+ "--bwlimit value is too small: %s\n", bwlimit_arg);
+ return 0;
+ }
+ }
+ break;
+
case OPT_APPEND:
if (am_server)
append_mode++;
}
}
+ if (protect_args < 0) {
+ if (am_server)
+ protect_args = 0;
+ else if ((arg = getenv("RSYNC_PROTECT_ARGS")) != NULL && *arg)
+ protect_args = atoi(arg) ? 1 : 0;
+ else {
+#ifdef RSYNC_USE_PROTECTED_ARGS
+ protect_args = 1;
+#else
+ protect_args = 0;
+#endif
+ }
+ }
+
if (human_readable > 1 && argc == 2 && !am_server) {
/* Allow the old meaning of 'h' (--help) on its own. */
usage(FINFO);
return 0;
}
if (backup_dir) {
+ size_t len;
while (*backup_dir == '.' && backup_dir[1] == '/')
backup_dir += 2;
if (*backup_dir == '.' && backup_dir[1] == '\0')
backup_dir++;
- backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
- backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
- if (backup_dir_remainder < 128) {
+ len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
+ if (len > sizeof backup_dir_buf - 128) {
snprintf(err_buf, sizeof err_buf,
"the --backup-dir path is WAY too long.\n");
return 0;
}
+ backup_dir_len = (int)len;
if (!backup_dir_len) {
backup_dir_len = -1;
backup_dir = NULL;
backup_dir_buf[backup_dir_len++] = '/';
backup_dir_buf[backup_dir_len] = '\0';
}
+ backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
}
if (backup_dir) {
/* No need for a suffix or a protect rule. */
parse_filter_str(&filter_list, backup_dir_buf, rule_template(0), 0);
}
+ if (preserve_times) {
+ preserve_times = PRESERVE_FILE_TIMES;
+ if (!omit_dir_times)
+ preserve_times |= PRESERVE_DIR_TIMES;
+#ifdef CAN_SET_SYMLINK_TIMES
+ if (!omit_link_times)
+ preserve_times |= PRESERVE_LINK_TIMES;
+#endif
+ }
+
if (make_backups && !backup_dir) {
omit_dir_times = 0; /* Implied, so avoid -O to sender. */
- if (preserve_times > 1)
- preserve_times = 1;
- } else if (omit_dir_times) {
- if (preserve_times > 1)
- preserve_times = 1;
+ preserve_times &= ~PRESERVE_DIR_TIMES;
}
if (stdout_format) {
argstr[x++] = 'm';
if (omit_dir_times)
argstr[x++] = 'O';
+ if (omit_link_times)
+ argstr[x++] = 'J';
} else {
if (copy_links)
argstr[x++] = 'L';