Reverted one xfer_dirs change from the last commit that should not
[rsync/rsync.git] / options.c
index cb1e89f..b475774 100644 (file)
--- a/options.c
+++ b/options.c
@@ -39,7 +39,6 @@ int make_backups = 0;
 int whole_file = -1;
 
 int append_mode = 0;
-int archive_mode = 0;
 int keep_dirlinks = 0;
 int copy_links = 0;
 int preserve_links = 0;
@@ -82,7 +81,7 @@ int filesfrom_fd = -1;
 char *filesfrom_host = NULL;
 int eol_nulls = 0;
 int recurse = 0;
-int xfer_dirs = 0;
+int xfer_dirs = -1;
 int am_daemon = 0;
 int daemon_over_rsh = 0;
 int do_stats = 0;
@@ -252,25 +251,24 @@ void usage(enum logcode F)
 
   rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
 
-  rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
+  rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... DEST\n");
+  rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
+  rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
+  rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
   rprintf(F,"  or   rsync [OPTION]... [USER@]HOST:SRC [DEST]\n");
-  rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... DEST\n");
   rprintf(F,"  or   rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
-  rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
   rprintf(F,"  or   rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
-  rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
-  rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
-  rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
-  rprintf(F,"  sources separated by space as long as they have same top-level\n");
+  rprintf(F,"The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect\n");
+  rprintf(F,"to an rsync daemon, and require SRC or DEST to start with a module name.\n");
   rprintf(F,"\nOptions\n");
   rprintf(F," -v, --verbose               increase verbosity\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,"     --no-OPTION             turn of an implied OPTION (e.g. --no-D)\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,"     --no-implied-dirs       don't send implied dirs with --relative\n");
   rprintf(F," -b, --backup                make backups (see --suffix & --backup-dir)\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);
@@ -293,7 +291,6 @@ void usage(enum logcode F)
   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 (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," -e, --rsh=COMMAND           specify the remote shell to use\n");
@@ -338,7 +335,6 @@ void usage(enum logcode F)
   rprintf(F,"     --address=ADDRESS       bind address for outgoing socket to daemon\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 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," -P                          same as --partial --progress\n");
@@ -371,16 +367,60 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
 
 static struct poptOption long_options[] = {
   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
+  {"help",            'h', POPT_ARG_NONE,   0, 'h', 0, 0 },
   {"version",          0,  POPT_ARG_NONE,   0, OPT_VERSION, 0, 0},
-  {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
-  {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
-  {"password-file",    0,  POPT_ARG_STRING, &password_file, 0, 0, 0 },
+  {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
+  {"no-verbose",       0,  POPT_ARG_VAL,    &verbose, 0, 0, 0 },
+  {"no-v",             0,  POPT_ARG_VAL,    &verbose, 0, 0, 0 },
+  {"quiet",           'q', POPT_ARG_NONE,   0, 'q', 0, 0 },
+  {"stats",            0,  POPT_ARG_NONE,   &do_stats, 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 },
+  {"no-r",             0,  POPT_ARG_VAL,    &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 },
+  {"perms",           'p', POPT_ARG_VAL,    &preserve_perms, 1, 0, 0 },
+  {"no-perms",         0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
+  {"no-p",             0,  POPT_ARG_VAL,    &preserve_perms, 0, 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, 2, 0, 0 },
+  {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
+  {"owner",           'o', POPT_ARG_VAL,    &preserve_uid, 1, 0, 0 },
+  {"no-owner",         0,  POPT_ARG_VAL,    &preserve_uid, 0, 0, 0 },
+  {"no-o",             0,  POPT_ARG_VAL,    &preserve_uid, 0, 0, 0 },
+  {"group",           'g', POPT_ARG_VAL,    &preserve_gid, 1, 0, 0 },
+  {"no-group",         0,  POPT_ARG_VAL,    &preserve_gid, 0, 0, 0 },
+  {"no-g",             0,  POPT_ARG_VAL,    &preserve_gid, 0, 0, 0 },
+  {"devices",         'D', POPT_ARG_VAL,    &preserve_devices, 1, 0, 0 },
+  {"no-devices",       0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
+  {"no-D",             0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
+  {"links",           'l', POPT_ARG_VAL,    &preserve_links, 1, 0, 0 },
+  {"no-links",         0,  POPT_ARG_VAL,    &preserve_links, 0, 0, 0 },
+  {"no-l",             0,  POPT_ARG_VAL,    &preserve_links, 0, 0, 0 },
+  {"copy-links",      'L', POPT_ARG_NONE,   &copy_links, 0, 0, 0 },
+  {"copy-unsafe-links",0,  POPT_ARG_NONE,   &copy_unsafe_links, 0, 0, 0 },
+  {"safe-links",       0,  POPT_ARG_NONE,   &safe_symlinks, 0, 0, 0 },
+  {"keep-dirlinks",   'K', POPT_ARG_NONE,   &keep_dirlinks, 0, 0, 0 },
+  {"hard-links",      'H', POPT_ARG_NONE,   &preserve_hard_links, 0, 0, 0 },
+  {"relative",        'R', POPT_ARG_VAL,    &relative_paths, 1, 0, 0 },
+  {"no-relative",      0,  POPT_ARG_VAL,    &relative_paths, 0, 0, 0 },
+  {"no-R",             0,  POPT_ARG_VAL,    &relative_paths, 0, 0, 0 },
+  {"no-implied-dirs",  0,  POPT_ARG_VAL,    &implied_dirs, 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 },
-  {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
   {"one-file-system", 'x', POPT_ARG_NONE,   &one_file_system, 0, 0, 0 },
+  {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
   {"existing",         0,  POPT_ARG_NONE,   &only_existing, 0, 0, 0 },
   {"ignore-existing",  0,  POPT_ARG_NONE,   &opt_ignore_existing, 0, 0, 0 },
+  {"max-size",         0,  POPT_ARG_STRING, &max_size_arg,  OPT_MAX_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 },
   {"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_VAL,    &delete_before, 2, 0, 0 },
@@ -389,86 +429,63 @@ static struct poptOption long_options[] = {
   {"delete-excluded",  0,  POPT_ARG_NONE,   &delete_excluded, 0, 0, 0 },
   {"remove-sent-files",0,  POPT_ARG_NONE,   &remove_sent_files, 0, 0, 0 },
   {"force",            0,  POPT_ARG_NONE,   &force_delete, 0, 0, 0 },
-  {"numeric-ids",      0,  POPT_ARG_NONE,   &numeric_ids, 0, 0, 0 },
+  {"ignore-errors",    0,  POPT_ARG_NONE,   &ignore_errors, 0, 0, 0 },
+  {"max-delete",       0,  POPT_ARG_INT,    &max_delete, 0, 0, 0 },
+  {0,                 'F', POPT_ARG_NONE,   0, 'F', 0, 0 },
   {"filter",          'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
   {"exclude",          0,  POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
   {"include",          0,  POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
   {"exclude-from",     0,  POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
   {"include-from",     0,  POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
-  {"safe-links",       0,  POPT_ARG_NONE,   &safe_symlinks, 0, 0, 0 },
-  {"help",            'h', POPT_ARG_NONE,   0, 'h', 0, 0 },
-  {"backup",          'b', POPT_ARG_NONE,   &make_backups, 0, 0, 0 },
-  {"dry-run",         'n', POPT_ARG_NONE,   &dry_run, 0, 0, 0 },
-  {"sparse",          'S', POPT_ARG_NONE,   &sparse_files, 0, 0, 0 },
   {"cvs-exclude",     'C', POPT_ARG_NONE,   &cvs_exclude, 0, 0, 0 },
-  {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
-  {"inplace",          0,  POPT_ARG_NONE,   &inplace, 0, 0, 0 },
-  {"dirs",            'd', POPT_ARG_VAL,    &xfer_dirs, 2, 0, 0 },
-  {"links",           'l', POPT_ARG_NONE,   &preserve_links, 0, 0, 0 },
-  {"copy-links",      'L', POPT_ARG_NONE,   &copy_links, 0, 0, 0 },
-  {"keep-dirlinks",   'K', POPT_ARG_NONE,   &keep_dirlinks, 0, 0, 0 },
-  {"append",           0,  POPT_ARG_VAL,    &append_mode, 1, 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,   &copy_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 },
-  {"devices",         'D', POPT_ARG_NONE,   &preserve_devices, 0, 0, 0 },
-  {"times",           't', POPT_ARG_NONE,   &preserve_times, 0, 0, 0 },
-  {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
+  {"no-W",             0,  POPT_ARG_VAL,    &whole_file, 0, 0, 0 },
   {"checksum",        'c', POPT_ARG_NONE,   &always_checksum, 0, 0, 0 },
-  {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
-  {"quiet",           'q', POPT_ARG_NONE,   0, 'q', 0, 0 },
-  {"archive",         'a', POPT_ARG_NONE,   &archive_mode, 0, 0, 0 },
-  {"server",           0,  POPT_ARG_NONE,   &am_server, 0, 0, 0 },
-  {"sender",           0,  POPT_ARG_NONE,   0, OPT_SENDER, 0, 0 },
-  {"recursive",       'r', POPT_ARG_NONE,   &recurse, 0, 0, 0 },
-  {"list-only",        0,  POPT_ARG_VAL,    &list_only, 2, 0, 0 },
-  {"relative",        'R', POPT_ARG_VAL,    &relative_paths, 1, 0, 0 },
-  {"no-relative",      0,  POPT_ARG_VAL,    &relative_paths, 0, 0, 0 },
-  {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
   {"block-size",      'B', POPT_ARG_LONG,   &block_size, 0, 0, 0 },
-  {"max-delete",       0,  POPT_ARG_INT,    &max_delete, 0, 0, 0 },
-  {"max-size",         0,  POPT_ARG_STRING, &max_size_arg,  OPT_MAX_SIZE, 0, 0 },
-  {"timeout",          0,  POPT_ARG_INT,    &io_timeout, 0, 0, 0 },
-  {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 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 },
-  {"progress",         0,  POPT_ARG_NONE,   &do_progress, 0, 0, 0 },
-  {"partial",          0,  POPT_ARG_NONE,   &keep_partial, 0, 0, 0 },
+  {0,                 'P', POPT_ARG_NONE,   0, 'P', 0, 0 },
+  {"progress",         0,  POPT_ARG_VAL,    &do_progress, 1, 0, 0 },
+  {"no-progress",      0,  POPT_ARG_VAL,    &do_progress, 0, 0, 0 },
+  {"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 },
-  {"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 },
-  {0,                 'F', POPT_ARG_NONE,   0, 'F', 0, 0 },
-  {0,                 'P', POPT_ARG_NONE,   0, 'P', 0, 0 },
-  {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 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",          'b', POPT_ARG_NONE,   &make_backups, 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 },
+  {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
+  {"list-only",        0,  POPT_ARG_VAL,    &list_only, 2, 0, 0 },
   {"read-batch",       0,  POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
   {"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},
-  {"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 },
+  {"numeric-ids",      0,  POPT_ARG_NONE,   &numeric_ids, 0, 0, 0 },
+  {"timeout",          0,  POPT_ARG_INT,    &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 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
-  /* All these options switch us into daemon-mode option-parsing. */
+  {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
+  {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
+  {"password-file",    0,  POPT_ARG_STRING, &password_file, 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 },
+  {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
+  {"checksum-seed",    0,  POPT_ARG_INT,    &checksum_seed, 0, 0, 0 },
+  {"server",           0,  POPT_ARG_NONE,   &am_server, 0, 0, 0 },
+  {"sender",           0,  POPT_ARG_NONE,   0, OPT_SENDER, 0, 0 },
+  /* All the following options switch us into daemon-mode option-parsing. */
   {"config",           0,  POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
   {"daemon",           0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
   {"detach",           0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
@@ -512,7 +529,10 @@ static struct poptOption long_daemon_options[] = {
   {"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 },
+  {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
   {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
+  {"no-verbose",       0,  POPT_ARG_VAL,    &verbose, 0, 0, 0 },
+  {"no-v",             0,  POPT_ARG_VAL,    &verbose, 0, 0, 0 },
   {"help",            'h', POPT_ARG_NONE,   0, 'h', 0, 0 },
   {0,0,0,0, 0, 0, 0}
 };
@@ -730,6 +750,13 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                                        goto daemon_error;
                                }
                        }
+
+                       if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
+                               snprintf(err_buf, sizeof err_buf,
+                                        "the --temp-dir path is WAY too long.\n");
+                               return 0;
+                       }
+
                        if (!daemon_opt) {
                                rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
                            daemon_error:
@@ -737,6 +764,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                                    "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
                                exit_cleanup(RERR_SYNTAX);
                        }
+
                        *argv = poptGetArgs(pc);
                        *argc = count_args(*argv);
                        am_starting_up = 0;
@@ -783,6 +811,23 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                                XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
                        break;
 
+               case 'a':
+                       if (refused_archive_part) {
+                               create_refuse_error(refused_archive_part);
+                               return 0;
+                       }
+                       if (!recurse) /* preserve recurse == 2 */
+                               recurse = 1;
+#ifdef SUPPORT_LINKS
+                       preserve_links = 1;
+#endif
+                       preserve_perms = 1;
+                       preserve_times = 1;
+                       preserve_gid = 1;
+                       preserve_uid = 1;
+                       preserve_devices = 1;
+                       break;
+
                case 'h':
                        usage(FINFO);
                        exit_cleanup(0);
@@ -957,25 +1002,15 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                return 0;
        }
 
-       if (archive_mode) {
-               if (refused_archive_part) {
-                       create_refuse_error(refused_archive_part);
-                       return 0;
-               }
-               if (!files_from)
-                       recurse = 1;
-#ifdef SUPPORT_LINKS
-               preserve_links = 1;
-#endif
-               preserve_perms = 1;
-               preserve_times = 1;
-               preserve_gid = 1;
-               preserve_uid = 1;
-               preserve_devices = 1;
+       if (files_from) {
+               if (recurse == 1) /* preserve recurse == 2 */
+                       recurse = 0;
+               if (xfer_dirs < 0)
+                       xfer_dirs = 1;
        }
 
-       if (recurse || list_only || files_from)
-               xfer_dirs |= 1;
+       if (xfer_dirs < 1)
+               xfer_dirs = recurse || list_only;
 
        if (relative_paths < 0)
                relative_paths = files_from? 1 : 0;
@@ -987,7 +1022,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                        "You may not combine multiple --delete-WHEN options.\n");
                return 0;
        }
-       if (!recurse) {
+       if (!xfer_dirs) {
                delete_before = delete_during = delete_after = 0;
                delete_mode = delete_excluded = 0;
        } else if (delete_before || delete_during || delete_after)
@@ -1134,6 +1169,14 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                        bwlimit_writemax = 512;
        }
 
+       if (sparse_files && inplace) {
+               /* Note: we don't check for this below, because --append is
+                * OK with --sparse (as long as redos are handled right). */
+               snprintf(err_buf, sizeof err_buf,
+                        "--sparse cannot be used with --inplace\n");
+               return 0;
+       }
+
        if (append_mode) {
                if (whole_file > 0) {
                        snprintf(err_buf, sizeof err_buf,