int size_only = 0;
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;
/** Network address family. **/
-#if INET6
+#ifdef INET6
int default_af_hint = 0; /* Any protocol */
#else
int default_af_hint = AF_INET; /* Must use IPv4 */
int verbose = 0;
int quiet = 0;
+int itemize_changes = 0;
+int log_before_transfer = 0;
int always_checksum = 0;
int list_only = 0;
static int F_option_cnt = 0;
static int modify_window_set;
static int refused_verbose, refused_delete, refused_archive_part;
-static int refused_partial, refused_progress;
+static int refused_partial, refused_progress, refused_delete_before;
static char *dest_option = NULL;
static char *max_size_arg;
static char partialdir_for_delayupdate[] = ".~tmp~";
char const *ipv6 = "no ";
STRUCT_STAT *dumstat;
-#if HAVE_SOCKETPAIR
+#ifdef HAVE_SOCKETPAIR
got_socketpair = "";
#endif
-#if HAVE_FTRUNCATE
+#ifdef HAVE_FTRUNCATE
have_inplace = "";
#endif
-#if SUPPORT_HARD_LINKS
+#ifdef SUPPORT_HARD_LINKS
hardlinks = "";
#endif
-#if SUPPORT_LINKS
+#ifdef SUPPORT_LINKS
links = "";
#endif
-#if INET6
+#ifdef INET6
ipv6 = "";
#endif
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 files whole\n");
+ rprintf(F," -W, --whole-file copy files whole (without rsync algorithm)\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," --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," -y, --fuzzy find similar file for basis if no dest file\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," --stats give some file-transfer stats\n");
rprintf(F," --progress show progress during transfer\n");
rprintf(F," -P same as --partial --progress\n");
+ rprintf(F," -i, --itemize-changes output a change-summary for all updates\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 batched update to FILE\n");
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
-#if INET6
+#ifdef INET6
rprintf(F," -4, --ipv4 prefer IPv4\n");
rprintf(F," -6, --ipv6 prefer IPv6\n");
#endif
{"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
{"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
{"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
- {"copy-unsafe-links", 0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 },
+ {"copy-unsafe-links",0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 },
{"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
{"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
{"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
{"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
{"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
{"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
+ {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
/* TODO: Should this take an optional int giving the compression level? */
{"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
{"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
{0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
{"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
{"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
+ {"itemize-changes", 'i', POPT_ARG_NONE, &itemize_changes, 0, 0, 0 },
{"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
{"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
{"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 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 },
-#if INET6
+#ifdef 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," --no-detach do not detach from the parent\n");
rprintf(F," --port=PORT listen on alternate port number\n");
rprintf(F," -v, --verbose increase verbosity\n");
-#if INET6
+#ifdef 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 },
-#if INET6
+#ifdef 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
case '\0':
if (wildmatch("delete", op->longName))
refused_delete = op->val;
+ else if (wildmatch("delete-before", op->longName))
+ refused_delete_before = op->val;
else if (wildmatch("partial", op->longName))
refused_partial = op->val;
else if (wildmatch("progress", op->longName))
break;
case OPT_LINK_DEST:
-#if HAVE_LINK
+#ifdef HAVE_LINK
link_dest = 1;
dest_option = "--link-dest";
goto set_dest_dir;
if (am_sender < 0)
am_sender = 0;
-#if !SUPPORT_LINKS
+#ifndef SUPPORT_LINKS
if (preserve_links && !am_sender) {
snprintf(err_buf, sizeof err_buf,
"symlinks are not supported on this %s\n",
}
#endif
-#if !SUPPORT_HARD_LINKS
+#ifndef SUPPORT_HARD_LINKS
if (preserve_hard_links) {
snprintf(err_buf, sizeof err_buf,
"hard links are not supported on this %s\n",
}
if (!files_from)
recurse = -1; /* infinite recursion */
-#if SUPPORT_LINKS
+#ifdef SUPPORT_LINKS
preserve_links = 1;
#endif
preserve_perms = 1;
delete_mode = delete_excluded = 0;
} else if (delete_before || delete_during || delete_after)
delete_mode = 1;
- else if (delete_mode || delete_excluded)
+ else if (delete_mode || delete_excluded) {
+ if (refused_delete_before) {
+ create_refuse_error(refused_delete_before);
+ return 0;
+ }
delete_mode = delete_before = 1;
+ }
if (delete_mode && refused_delete) {
create_refuse_error(refused_delete);
return 0;
}
- if (do_progress && !verbose) {
- if (refused_verbose) {
- create_refuse_error(refused_verbose);
- return 0;
- }
+ if (log_format) {
+ if (strstr(log_format, "%i") != NULL)
+ itemize_changes = 1;
+ if (strstr(log_format, "%b") == NULL
+ && strstr(log_format, "%c") == NULL)
+ log_before_transfer = !am_server;
+ } else if (itemize_changes) {
+ log_format = "%i %n%L";
+ log_before_transfer = !am_server;
+ }
+
+ if ((do_progress || dry_run) && !verbose && !log_before_transfer
+ && !refused_verbose)
verbose = 1;
+
+ if (verbose && !log_format) {
+ log_format = "%n%L";
+ log_before_transfer = !am_server;
}
if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
partial_dir = partialdir_for_delayupdate;
if (inplace) {
-#if HAVE_FTRUNCATE
+#ifdef HAVE_FTRUNCATE
if (partial_dir) {
snprintf(err_buf, sizeof err_buf,
"--inplace cannot be used with --%s\n",
if (!implied_dirs && !am_sender)
args[ac++] = "--no-implied-dirs";
+ if (fuzzy_basis && am_sender)
+ args[ac++] = "--fuzzy";
+
*argc = ac;
return;