#include "rsync.h"
#include "popt.h"
+extern int module_id;
extern int sanitize_paths;
extern int select_timeout;
extern struct filter_list_struct filter_list;
int numeric_ids = 0;
int force_delete = 0;
int io_timeout = 0;
-int read_only = 0;
-int module_id = -1;
int am_server = 0;
int am_sender = 0;
int am_generator = 0;
int blocking_io = -1;
int checksum_seed = 0;
int inplace = 0;
+int delay_updates = 0;
long block_size = 0; /* "long" because popt can't set an int32. */
/** Network address family. **/
-#ifdef INET6
+#if INET6
int default_af_hint = 0; /* Any protocol */
#else
int default_af_hint = AF_INET; /* Must use IPv4 */
char const *ipv6 = "no ";
STRUCT_STAT *dumstat;
-#ifdef HAVE_SOCKETPAIR
+#if HAVE_SOCKETPAIR
got_socketpair = "";
#endif
rprintf(f, "%s version %s protocol version %d\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
rprintf(f,
- "Copyright (C) 1996-2004 by Andrew Tridgell and others\n");
+ "Copyright (C) 1996-2005 by Andrew Tridgell and others\n");
rprintf(f, "<http://rsync.samba.org/>\n");
rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
"%shard links, %ssymlinks, batchfiles, \n",
get_panic_action());
#endif
-#ifdef INT64_IS_OFF_T
- if (sizeof (int64) < 8)
- rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
+#if SIZEOF_INT64 < 8
+ rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
#endif
+ if (sizeof (int64) != SIZEOF_INT64) {
+ rprintf(f,
+ "WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
+ (int) SIZEOF_INT64, (int) sizeof (int64));
+ }
rprintf(f,
"\n"
rprintf(F," sources separated by space as long as they have same top-level\n");
rprintf(F,"\nOptions\n");
rprintf(F," -v, --verbose increase verbosity\n");
- rprintf(F," -q, --quiet decrease verbosity\n");
- rprintf(F," -c, --checksum always checksum\n");
- rprintf(F," -a, --archive archive mode, equivalent to -rlptgoD (no -H)\n");
+ rprintf(F," -q, --quiet suppress non-error messages\n");
+ rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n");
+ rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H)\n");
rprintf(F," -r, --recursive recurse into directories\n");
rprintf(F," -R, --relative use relative path names\n");
rprintf(F," --no-relative turn off --relative\n");
rprintf(F," --no-implied-dirs don't send implied dirs with -R\n");
rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
- rprintf(F," --backup-dir make backups into this directory\n");
- rprintf(F," --suffix=SUFFIX backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
- rprintf(F," -u, --update update only (don't overwrite newer files)\n");
+ rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
+ rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
+ rprintf(F," -u, --update skip files that are newer on the receiver\n");
rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
rprintf(F," -d, --dirs transfer directories without recursing\n");
rprintf(F," -l, --links copy symlinks as symlinks\n");
- rprintf(F," -L, --copy-links copy the referent of all symlinks\n");
- rprintf(F," --copy-unsafe-links copy the referent of \"unsafe\" symlinks\n");
- rprintf(F," --safe-links ignore \"unsafe\" symlinks\n");
+ rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
+ rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n");
+ rprintf(F," --safe-links ignore symlinks that point outside the source tree\n");
rprintf(F," -H, --hard-links preserve hard links\n");
rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
rprintf(F," -p, --perms preserve permissions\n");
rprintf(F," -O, --omit-dir-times omit directories when preserving times\n");
rprintf(F," -S, --sparse handle sparse files efficiently\n");
rprintf(F," -n, --dry-run show what would have been transferred\n");
- rprintf(F," -W, --whole-file copy whole files, no incremental checks\n");
- rprintf(F," --no-whole-file turn off --whole-file\n");
+ rprintf(F," -W, --whole-file copy files whole\n");
+ rprintf(F," --no-whole-file always use incremental rsync 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\n");
+ rprintf(F," -e, --rsh=COMMAND specify the remote shell to use\n");
rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
- rprintf(F," --existing only update files that already exist\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," --del an alias for --delete-during\n");
rprintf(F," --delete delete files that don't exist on the sending side\n");
+ rprintf(F," --delete-before receiver deletes before transfer (default)\n");
rprintf(F," --delete-during receiver deletes during transfer, not before\n");
rprintf(F," --delete-after receiver deletes after transfer, not before\n");
rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
rprintf(F," --max-size=SIZE don't transfer any file larger 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");
rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
- rprintf(F," -I, --ignore-times turn off mod time & file size quick check\n");
- rprintf(F," --size-only ignore mod time for quick check (use size)\n");
- rprintf(F," --modify-window=NUM compare mod times with reduced accuracy\n");
+ rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
+ rprintf(F," --size-only skip files that match in size\n");
+ rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
- rprintf(F," -P equivalent to --partial --progress\n");
rprintf(F," -z, --compress compress file data\n");
- rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
+ rprintf(F," -C, --cvs-exclude auto-ignore files the same way CVS does\n");
rprintf(F," -f, --filter=RULE add a file-filtering RULE\n");
rprintf(F," -F same as --filter=': /.rsync-filter'\n");
rprintf(F," repeated: --filter='- .rsync-filter'\n");
rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
- rprintf(F," --exclude-from=FILE exclude patterns listed in FILE\n");
+ rprintf(F," --exclude-from=FILE read exclude patterns from FILE\n");
rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
- rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n");
- rprintf(F," --files-from=FILE read FILE for list of source-file names\n");
+ rprintf(F," --include-from=FILE read include patterns from FILE\n");
+ rprintf(F," --files-from=FILE read list of source-file names from FILE\n");
rprintf(F," -0, --from0 all *-from file lists are delimited by nulls\n");
rprintf(F," --version print version number\n");
rprintf(F," --port=PORT specify double-colon alternate port number\n");
rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
- rprintf(F," --no-blocking-io turn off --blocking-io\n");
- rprintf(F," --stats give some file transfer stats\n");
+ rprintf(F," --no-blocking-io turn off blocking I/O when it is the default\n");
+ rprintf(F," --stats give some file-transfer stats\n");
rprintf(F," --progress show progress during transfer\n");
- rprintf(F," --log-format=FORMAT log file transfers using specified format\n");
- rprintf(F," --password-file=FILE get password from FILE\n");
+ rprintf(F," -P same as --partial --progress\n");
+ rprintf(F," --log-format=FORMAT log file-transfers using specified format\n");
+ rprintf(F," --password-file=FILE read 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," --write-batch=FILE write a batch to FILE\n");
- rprintf(F," --read-batch=FILE read a batch from FILE\n");
-#ifdef INET6
+ rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
+ rprintf(F," --write-batch=FILE write a batched update to FILE\n");
+ rprintf(F," --read-batch=FILE read a batched update from FILE\n");
+#if INET6
rprintf(F," -4, --ipv4 prefer IPv4\n");
rprintf(F," -6, --ipv6 prefer IPv6\n");
#endif
{"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
{"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
{"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
+ {"delete-before", 0, POPT_ARG_VAL, &delete_before, 2, 0, 0 },
{"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
{"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
{"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
{"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
{"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
{"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
+ {"delay-updates", 0, POPT_ARG_NONE, &delay_updates, 0, 0, 0 },
{"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
{"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
{"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
{"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
{"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
{"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
-#ifdef INET6
+#if INET6
{"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
{"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
#endif
rprintf(F,"\nUsage: 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=KBPS limit I/O bandwidth; KBytes per second\n");
rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
rprintf(F," --no-detach do not detach from the parent\n");
- rprintf(F," --port=PORT specify alternate rsyncd port number\n");
-#ifdef INET6
+ rprintf(F," --port=PORT listen on alternate port number\n");
+ rprintf(F," -v, --verbose increase verbosity\n");
+#if INET6
rprintf(F," -4, --ipv4 prefer IPv4\n");
rprintf(F," -6, --ipv6 prefer IPv6\n");
#endif
{"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
{"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
{"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
-#ifdef INET6
+#if INET6
{"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
{"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
#endif
{"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
{"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
{"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
+ {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
{"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
{0,0,0,0, 0, 0, 0}
};
daemon_usage(FINFO);
exit_cleanup(0);
+ case 'v':
+ verbose++;
+ break;
+
default:
rprintf(FERROR,
"rsync: %s: %s (in daemon mode)\n",
break;
case OPT_MAX_SIZE:
- for (arg = max_size_arg; isdigit(*arg); arg++) {}
+ for (arg = max_size_arg; isdigit(*(uchar*)arg); arg++) {}
if (*arg == '.')
- for (arg++; isdigit(*arg); arg++) {}
+ for (arg++; isdigit(*(uchar*)arg); arg++) {}
switch (*arg) {
case 'k': case 'K':
max_size = atof(max_size_arg) * 1024;
if (relative_paths < 0)
relative_paths = files_from? 1 : 0;
- if (delete_during && delete_after) {
+ if (!!delete_before + delete_during + delete_after > 1) {
snprintf(err_buf, sizeof err_buf,
- "You may not combine --delete-during (--del) and --delete-after.\n");
+ "You may not combine multiple --delete-WHEN options.\n");
return 0;
}
- if (delete_during || delete_after)
+ if (delete_before || delete_during || delete_after)
delete_mode = 1;
else if (delete_mode || delete_excluded)
delete_mode = delete_before = 1;
bwlimit_writemax = 512;
}
+ if (delay_updates && !partial_dir)
+ partial_dir = ".~tmp~";
+
if (inplace) {
#if HAVE_FTRUNCATE
if (partial_dir) {
snprintf(err_buf, sizeof err_buf,
- "--inplace cannot be used with --partial-dir\n");
+ "--inplace cannot be used with --%s\n",
+ delay_updates ? "delay-updates" : "partial-dir");
return 0;
}
keep_partial = 0;
if (copy_links)
argstr[x++] = 'L';
if (xfer_dirs > 1)
- argstr[x++] = 'k';
+ argstr[x++] = 'd';
if (keep_dirlinks && am_sender)
argstr[x++] = 'K';
if (am_sender) {
if (delete_excluded)
args[ac++] = "--delete-excluded";
- else if (delete_before || delete_after)
+ else if (delete_before == 1 || delete_after)
args[ac++] = "--delete";
+ if (delete_before > 1)
+ args[ac++] = "--delete-before";
if (delete_during)
args[ac++] = "--delete-during";
if (delete_after)
if (partial_dir && am_sender) {
args[ac++] = "--partial-dir";
args[ac++] = partial_dir;
+ if (delay_updates)
+ args[ac++] = "--delay-updates";
} else if (keep_partial)
args[ac++] = "--partial";