Clarified something in the new --hard-links text.
[rsync/rsync.git] / options.c
index 57c4446..77cbe10 100644 (file)
--- a/options.c
+++ b/options.c
@@ -6,8 +6,9 @@
  * Copyright (C) 2002-2007 Wayne Davison
  *
  * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +16,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ * with this program; if not, visit the http://fsf.org website.
  */
 
 #include "rsync.h"
@@ -25,6 +25,7 @@
 
 extern int module_id;
 extern int sanitize_paths;
+extern int daemon_over_rsh;
 extern struct filter_list_struct filter_list;
 extern struct filter_list_struct server_filter_list;
 
@@ -55,7 +56,6 @@ int preserve_specials = 0;
 int preserve_uid = 0;
 int preserve_gid = 0;
 int preserve_times = 0;
-int omit_dir_times = 0;
 int update_only = 0;
 int cvs_exclude = 0;
 int dry_run = 0;
@@ -85,6 +85,7 @@ int force_delete = 0;
 int io_timeout = 0;
 int allowed_lull = 0;
 int prune_empty_dirs = 0;
+int use_qsort = 0;
 char *files_from = NULL;
 int filesfrom_fd = -1;
 char *filesfrom_host = NULL;
@@ -94,7 +95,6 @@ int recurse = 0;
 int allow_inc_recurse = 1;
 int xfer_dirs = -1;
 int am_daemon = 0;
-int daemon_over_rsh = 0;
 int do_stats = 0;
 int do_progress = 0;
 int keep_partial = 0;
@@ -108,7 +108,7 @@ size_t bwlimit_writemax = 0;
 int ignore_existing = 0;
 int ignore_non_existing = 0;
 int need_messages_from_generator = 0;
-int max_delete = -1;
+int max_delete = INT_MIN;
 OFF_T max_size = 0;
 OFF_T min_size = 0;
 int ignore_errors = 0;
@@ -118,12 +118,18 @@ int checksum_seed = 0;
 int inplace = 0;
 int delay_updates = 0;
 long block_size = 0; /* "long" because popt can't set an int32. */
+char *skip_compress = NULL;
 
 /** Network address family. **/
+int default_af_hint
 #ifdef INET6
-int default_af_hint = 0;       /* Any protocol */
+       = 0;            /* Any protocol */
 #else
-int default_af_hint = AF_INET; /* Must use IPv4 */
+       = AF_INET;      /* Must use IPv4 */
+# ifdef AF_INET6
+#  undef AF_INET6
+# endif
+# define AF_INET6 AF_INET /* make -6 option a no-op */
 #endif
 
 /** Do not go into the background when run as --daemon.  Good
@@ -185,6 +191,7 @@ char *iconv_opt = ICONV_OPTION;
 struct chmod_mode_struct *chmod_modes = NULL;
 
 static int daemon_opt;   /* sets am_daemon after option error-reporting */
+static int omit_dir_times = 0;
 static int F_option_cnt = 0;
 static int modify_window_set;
 static int itemize_changes = 0;
@@ -312,6 +319,7 @@ void usage(enum logcode F)
   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,"     --append                append data onto shorter files\n");
+  rprintf(F,"     --append-verify         like --append, but with old data in file checksum\n");
   rprintf(F," -d, --dirs                  transfer directories without recursing\n");
   rprintf(F," -l, --links                 copy symlinks as symlinks\n");
   rprintf(F," -L, --copy-links            transform symlink into referent file/dir\n");
@@ -327,15 +335,15 @@ void usage(enum logcode F)
   rprintf(F," -A, --acls                  preserve ACLs (implies --perms)\n");
 #endif
 #ifdef SUPPORT_XATTRS
-  rprintf(F," -X, --xattrs                preserve extended attributes (implies --perms)\n");
+  rprintf(F," -X, --xattrs                preserve extended attributes\n");
 #endif
   rprintf(F," -o, --owner                 preserve owner (super-user only)\n");
   rprintf(F," -g, --group                 preserve group\n");
   rprintf(F,"     --devices               preserve device files (super-user only)\n");
   rprintf(F,"     --specials              preserve special files\n");
   rprintf(F," -D                          same as --devices --specials\n");
-  rprintf(F," -t, --times                 preserve times\n");
-  rprintf(F," -O, --omit-dir-times        omit directories when preserving times\n");
+  rprintf(F," -t, --times                 preserve modification times\n");
+  rprintf(F," -O, --omit-dir-times        omit directories 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");
@@ -378,6 +386,7 @@ void usage(enum logcode F)
   rprintf(F,"     --link-dest=DIR         hardlink to files in DIR when unchanged\n");
   rprintf(F," -z, --compress              compress file data during the transfer\n");
   rprintf(F,"     --compress-level=NUM    explicitly set compression level\n");
+  rprintf(F,"     --skip-compress=LIST    skip compressing files with a suffix in LIST\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='dir-merge /.rsync-filter'\n");
@@ -411,10 +420,8 @@ void usage(enum logcode F)
 #ifdef ICONV_OPTION
   rprintf(F,"     --iconv=CONVERT_SPEC    request charset conversion of filesnames\n");
 #endif
-#ifdef INET6
   rprintf(F," -4, --ipv4                  prefer IPv4\n");
   rprintf(F," -6, --ipv6                  prefer IPv6\n");
-#endif
   rprintf(F,"     --version               print version number\n");
   rprintf(F,"(-h) --help                  show this help (-h works with no other options)\n");
 
@@ -428,7 +435,7 @@ 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_HELP,
       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_NO_D, OPT_APPEND,
       OPT_SERVER, OPT_REFUSED_BASE = 9000};
 
 static struct poptOption long_options[] = {
@@ -443,15 +450,17 @@ static struct poptOption long_options[] = {
   {"no-motd",          0,  POPT_ARG_VAL,    &output_motd, 0, 0, 0 },
   {"stats",            0,  POPT_ARG_NONE,   &do_stats, 0, 0, 0 },
   {"human-readable",  'h', POPT_ARG_NONE,   0, 'h', 0, 0},
+  {"no-human-readable",0,  POPT_ARG_VAL,    &human_readable, 0, 0, 0},
+  {"no-h",             0,  POPT_ARG_VAL,    &human_readable, 0, 0, 0},
   {"dry-run",         'n', POPT_ARG_NONE,   &dry_run, 0, 0, 0 },
   {"archive",         'a', POPT_ARG_NONE,   0, 'a', 0, 0 },
   {"recursive",       'r', POPT_ARG_VAL,    &recurse, 2, 0, 0 },
   {"no-recursive",     0,  POPT_ARG_VAL,    &recurse, 0, 0, 0 },
-  {"ir",               0,  POPT_ARG_VAL,    &allow_inc_recurse, 1, 0, 0 },
+  {"no-r",             0,  POPT_ARG_VAL,    &recurse, 0, 0, 0 },
   {"inc-recursive",    0,  POPT_ARG_VAL,    &allow_inc_recurse, 1, 0, 0 },
-  {"no-ir",            0,  POPT_ARG_VAL,    &allow_inc_recurse, 0, 0, 0 },
   {"no-inc-recursive", 0,  POPT_ARG_VAL,    &allow_inc_recurse, 0, 0, 0 },
-  {"no-r",             0,  POPT_ARG_VAL,    &recurse, 0, 0, 0 },
+  {"ir",               0,  POPT_ARG_VAL,    &allow_inc_recurse, 1, 0, 0 },
+  {"no-ir",            0,  POPT_ARG_VAL,    &allow_inc_recurse, 0, 0, 0 },
   {"dirs",            'd', POPT_ARG_VAL,    &xfer_dirs, 2, 0, 0 },
   {"no-dirs",          0,  POPT_ARG_VAL,    &xfer_dirs, 0, 0, 0 },
   {"no-d",             0,  POPT_ARG_VAL,    &xfer_dirs, 0, 0, 0 },
@@ -465,10 +474,12 @@ 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, 1, 0, 0 },
+  {"times",           't', POPT_ARG_VAL,    &preserve_times, 2, 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, 2, 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 },
   {"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 },
@@ -513,7 +524,9 @@ static struct poptOption long_options[] = {
   {"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 },
+  {"append",           0,  POPT_ARG_NONE,   0, OPT_APPEND, 0, 0 },
+  {"append-verify",    0,  POPT_ARG_VAL,    &append_mode, 2, 0, 0 },
+  {"no-append",        0,  POPT_ARG_VAL,    &append_mode, 0, 0, 0 },
   {"del",              0,  POPT_ARG_NONE,   &delete_during, 0, 0, 0 },
   {"delete",           0,  POPT_ARG_NONE,   &delete_mode, 0, 0, 0 },
   {"delete-before",    0,  POPT_ARG_NONE,   &delete_before, 0, 0, 0 },
@@ -536,13 +549,18 @@ static struct poptOption long_options[] = {
   {"whole-file",      'W', POPT_ARG_VAL,    &whole_file, 1, 0, 0 },
   {"no-whole-file",    0,  POPT_ARG_VAL,    &whole_file, 0, 0, 0 },
   {"no-W",             0,  POPT_ARG_VAL,    &whole_file, 0, 0, 0 },
-  {"checksum",        'c', POPT_ARG_NONE,   &always_checksum, 0, 0, 0 },
+  {"checksum",        'c', POPT_ARG_VAL,    &always_checksum, 1, 0, 0 },
+  {"no-checksum",      0,  POPT_ARG_VAL,    &always_checksum, 0, 0, 0 },
+  {"no-c",             0,  POPT_ARG_VAL,    &always_checksum, 0, 0, 0 },
   {"block-size",      'B', POPT_ARG_LONG,   &block_size, 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 },
   {"compress",        'z', POPT_ARG_NONE,   0, 'z', 0, 0 },
+  {"no-compress",      0,  POPT_ARG_VAL,    &do_compression, 0, 0, 0 },
+  {"skip-compress",    0,  POPT_ARG_STRING, &skip_compress, 0, 0, 0 },
+  {"no-z",             0,  POPT_ARG_VAL,    &do_compression, 0, 0, 0 },
   {"compress-level",   0,  POPT_ARG_INT,    &def_compress_level, 'z', 0, 0 },
   {0,                 'P', POPT_ARG_NONE,   0, 'P', 0, 0 },
   {"progress",         0,  POPT_ARG_VAL,    &do_progress, 1, 0, 0 },
@@ -550,15 +568,20 @@ static struct poptOption long_options[] = {
   {"partial",          0,  POPT_ARG_VAL,    &keep_partial, 1, 0, 0 },
   {"no-partial",       0,  POPT_ARG_VAL,    &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 },
+  {"delay-updates",    0,  POPT_ARG_VAL,    &delay_updates, 1, 0, 0 },
+  {"no-delay-updates", 0,  POPT_ARG_VAL,    &delay_updates, 0, 0, 0 },
   {"prune-empty-dirs",'m', POPT_ARG_NONE,   &prune_empty_dirs, 0, 0, 0 },
   {"log-file",         0,  POPT_ARG_STRING, &logfile_name, 0, 0, 0 },
   {"log-file-format",  0,  POPT_ARG_STRING, &logfile_format, 0, 0, 0 },
   {"out-format",       0,  POPT_ARG_STRING, &stdout_format, 0, 0, 0 },
   {"log-format",       0,  POPT_ARG_STRING, &stdout_format, 0, 0, 0 }, /* DEPRECATED */
   {"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 },
-  {"backup",          'b', POPT_ARG_NONE,   &make_backups, 0, 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 },
   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
   {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
   {"list-only",        0,  POPT_ARG_VAL,    &list_only, 2, 0, 0 },
@@ -566,20 +589,22 @@ static struct poptOption long_options[] = {
   {"write-batch",      0,  POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
   {"only-write-batch", 0,  POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 },
   {"files-from",       0,  POPT_ARG_STRING, &files_from, 0, 0, 0 },
-  {"from0",           '0', POPT_ARG_NONE,   &eol_nulls, 0, 0, 0},
-  {"numeric-ids",      0,  POPT_ARG_NONE,   &numeric_ids, 0, 0, 0 },
+  {"from0",           '0', POPT_ARG_VAL,    &eol_nulls, 1, 0, 0},
+  {"no-from0",         0,  POPT_ARG_VAL,    &eol_nulls, 0, 0, 0},
+  {"numeric-ids",      0,  POPT_ARG_VAL,    &numeric_ids, 1, 0, 0 },
+  {"no-numeric-ids",   0,  POPT_ARG_VAL,    &numeric_ids, 0, 0, 0 },
   {"timeout",          0,  POPT_ARG_INT,    &io_timeout, 0, 0, 0 },
+  {"no-timeout",       0,  POPT_ARG_VAL,    &io_timeout, 0, 0, 0 },
   {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
   {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
   {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
 #ifdef ICONV_OPTION
   {"iconv",            0,  POPT_ARG_STRING, &iconv_opt, 0, 0, 0 },
 #endif
-#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
   {"8-bit-output",    '8', POPT_ARG_NONE,   &allow_8bit_chars, 0, 0, 0 },
+  {"qsort",            0,  POPT_ARG_NONE,   &use_qsort, 0, 0, 0 },
   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
   {"sockopts",         0,  POPT_ARG_STRING, &sockopts, 0, 0, 0 },
@@ -613,10 +638,8 @@ static void daemon_usage(enum logcode F)
   rprintf(F,"     --log-file-format=FMT   override the \"log format\" setting\n");
   rprintf(F,"     --sockopts=OPTIONS      specify custom TCP options\n");
   rprintf(F," -v, --verbose               increase verbosity\n");
-#ifdef INET6
   rprintf(F," -4, --ipv4                  prefer IPv4\n");
   rprintf(F," -6, --ipv6                  prefer IPv6\n");
-#endif
   rprintf(F,"     --help                  show this help screen\n");
 
   rprintf(F,"\n");
@@ -630,14 +653,12 @@ static struct poptOption long_daemon_options[] = {
   {"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
   {"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
   {"detach",           0,  POPT_ARG_VAL,    &no_detach, 0, 0, 0 },
+  {"no-detach",        0,  POPT_ARG_VAL,    &no_detach, 1, 0, 0 },
   {"log-file",         0,  POPT_ARG_STRING, &logfile_name, 0, 0, 0 },
   {"log-file-format",  0,  POPT_ARG_STRING, &logfile_format, 0, 0, 0 },
-  {"no-detach",        0,  POPT_ARG_VAL,    &no_detach, 1, 0, 0 },
   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
   {"sockopts",         0,  POPT_ARG_STRING, &sockopts, 0, 0, 0 },
   {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
@@ -996,7 +1017,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                        preserve_links = 1;
 #endif
                        preserve_perms = 1;
-                       preserve_times = 1;
+                       preserve_times = 2;
                        preserve_gid = 1;
                        preserve_uid = 1;
                        preserve_devices = 1;
@@ -1105,6 +1126,13 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                        }
                        break;
 
+               case OPT_APPEND:
+                       if (am_server)
+                               append_mode++;
+                       else
+                               append_mode = 1;
+                       break;
+
                case OPT_LINK_DEST:
 #ifdef SUPPORT_HARD_LINKS
                        link_dest = 1;
@@ -1170,8 +1198,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
 
                case 'X':
 #ifdef SUPPORT_XATTRS
-                       preserve_xattrs = 1;
-                       preserve_perms = 1;
+                       preserve_xattrs++;
                        break;
 #else
                        snprintf(err_buf,sizeof(err_buf),
@@ -1272,6 +1299,11 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                return 0;
        }
 
+       if (max_delete < 0 && max_delete != INT_MIN) {
+               /* Negative numbers are treated as "no deletions". */
+               max_delete = 0;
+       }
+
        if (compare_dest + copy_dest + link_dest > 1) {
                snprintf(err_buf, sizeof err_buf,
                        "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
@@ -1397,8 +1429,15 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                        "P *%s", backup_suffix);
                parse_rule(&filter_list, backup_dir_buf, 0, 0);
        }
-       if (make_backups && !backup_dir)
-               omit_dir_times = 1;
+
+       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;
+       }
 
        if (stdout_format) {
                if (am_server && log_format_has(stdout_format, 'I'))
@@ -1593,7 +1632,7 @@ void server_options(char **args,int *argc)
        /* This should always remain first on the server's command-line. */
        args[ac++] = "--server";
 
-       if (daemon_over_rsh) {
+       if (daemon_over_rsh > 0) {
                args[ac++] = "--daemon";
                *argc = ac;
                /* if we're passing --daemon, we're done */
@@ -1624,7 +1663,7 @@ void server_options(char **args,int *argc)
                        argstr[x++] = 'K';
                if (prune_empty_dirs)
                        argstr[x++] = 'm';
-               if (omit_dir_times == 2)
+               if (omit_dir_times)
                        argstr[x++] = 'O';
        } else {
                if (copy_links)
@@ -1661,8 +1700,11 @@ void server_options(char **args,int *argc)
                argstr[x++] = 'A';
 #endif
 #ifdef SUPPORT_XATTRS
-       if (preserve_xattrs)
+       if (preserve_xattrs) {
                argstr[x++] = 'X';
+               if (preserve_xattrs > 1)
+                       argstr[x++] = 'X';
+       }
 #endif
        if (recurse)
                argstr[x++] = 'r';
@@ -1758,22 +1800,6 @@ void server_options(char **args,int *argc)
                args[ac++] = arg;
        }
 
-       if (max_delete >= 0 && am_sender) {
-               if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
-                       goto oom;
-               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;
-       }
-
        if (io_timeout) {
                if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
                        goto oom;
@@ -1800,6 +1826,20 @@ void server_options(char **args,int *argc)
        }
 
        if (am_sender) {
+               if (max_delete > 0) {
+                       if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
+                               goto oom;
+                       args[ac++] = arg;
+               } else if (max_delete == 0)
+                       args[ac++] = "--max_delete=-1";
+               if (min_size) {
+                       args[ac++] = "--min-size";
+                       args[ac++] = min_size_arg;
+               }
+               if (max_size) {
+                       args[ac++] = "--max-size";
+                       args[ac++] = max_size_arg;
+               }
                if (delete_before)
                        args[ac++] = "--delete-before";
                else if (delete_during == 2)
@@ -1820,6 +1860,12 @@ void server_options(char **args,int *argc)
                        args[ac++] = "--super";
                if (size_only)
                        args[ac++] = "--size-only";
+       } else {
+               if (skip_compress) {
+                       if (asprintf(&arg, "--skip-compress=%s", skip_compress) < 0)
+                               goto oom;
+                       args[ac++] = arg;
+               }
        }
 
        if (modify_window_set) {
@@ -1856,6 +1902,9 @@ void server_options(char **args,int *argc)
        if (numeric_ids)
                args[ac++] = "--numeric-ids";
 
+       if (!allow_inc_recurse)
+               args[ac++] = "--no-ir";
+
        if (am_sender) {
                if (ignore_existing)
                        args[ac++] = "--ignore-existing";
@@ -1882,9 +1931,11 @@ void server_options(char **args,int *argc)
                }
        }
 
-       if (append_mode)
+       if (append_mode) {
+               if (append_mode > 1)
+                       args[ac++] = "--append";
                args[ac++] = "--append";
-       else if (inplace)
+       else if (inplace)
                args[ac++] = "--inplace";
 
        if (files_from && (!am_sender || filesfrom_host)) {
@@ -1947,7 +1998,7 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
                        if (p[1] == ':')
                                *port_ptr = atoi(p+2);
                } else {
-                       if ((p = strchr(s, ':')) != NULL) {
+                       if ((p = strchr(s, ':')) != NULL && p < s + hostlen) {
                                hostlen = p - s;
                                *port_ptr = atoi(p+1);
                        }