From 73cb6738b33846130c21f2903b2200fa3f1903ab Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Mon, 24 Mar 2008 09:33:07 -0700 Subject: [PATCH] Improved --dirs/--no-dirs/--list-only option handling: - Moved setting of list_only and xfer_dirs from main.c to options.c. - Fixed the ability of the user to force --no-dirs. - Added the --old-dirs/--old-d option to make it easier to interact in list-only mode with an older rsync. - Suggest the use of --old-d instead of "-r --exclude='/*/*'". --- NEWS | 4 ++++ io.c | 3 +-- main.c | 11 ----------- options.c | 24 +++++++++++++++++------- rsync.yo | 10 +++++++--- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/NEWS b/NEWS index 14d65035..32e6ccde 100644 --- a/NEWS +++ b/NEWS @@ -78,6 +78,10 @@ Changes since 3.0.0: ENHANCEMENTS: + - Added the --old-dirs (--old-d) option to make it easier for a user to + ask for file-listings with older rsync versions (this is easier than + having to type "-r --exclude='/*/*'" manually). + - When getting an error while asking an older rsync daemon for a file listing, rsync will try to notice if the error is a rejection of the --dirs (-d) option and let the user know how to work around the issue. diff --git a/io.c b/io.c index d29643d8..60062f90 100644 --- a/io.c +++ b/io.c @@ -352,8 +352,7 @@ static void check_for_d_option_error(const char *msg) if (saw_d) { rprintf(FWARNING, - "*** Try adding \"-r --exclude='/*/*'\" " - "if remote rsync is <= 2.6.3 ***\n"); + "*** Try using \"--old-d\" if remote rsync is <= 2.6.3 ***\n"); } } diff --git a/main.c b/main.c index 5985f808..ad4fb0af 100644 --- a/main.c +++ b/main.c @@ -1038,11 +1038,6 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) io_start_multiplex_out(); } - if (argc == 0) { - list_only |= 1; - xfer_dirs |= 1; - } - send_filter_list(read_batch ? -1 : f_out); if (filesfrom_fd >= 0) { @@ -1153,8 +1148,6 @@ static int start_client(int argc, char *argv[]) static char *dotarg[1] = { "." }; p = dotarg[0]; remote_argv = dotarg; - list_only |= 1; - xfer_dirs |= 1; } remote_argc = 1; @@ -1226,10 +1219,6 @@ static int start_client(int argc, char *argv[]) } remote_argv[i] = arg; } - if (argc == 0) { - list_only |= 1; - xfer_dirs |= 1; - } } if (daemon_over_rsh < 0) diff --git a/options.c b/options.c index f2d23f62..9074e06e 100644 --- a/options.c +++ b/options.c @@ -475,6 +475,8 @@ static struct poptOption long_options[] = { {"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 }, + {"old-dirs", 0, POPT_ARG_VAL, &xfer_dirs, 4, 0, 0 }, + {"old-d", 0, POPT_ARG_VAL, &xfer_dirs, 4, 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 }, @@ -1295,6 +1297,9 @@ int parse_arguments(int *argc_p, const char ***argv_p) if (protect_args == 1 && am_server) return 1; + *argv_p = argv = poptGetArgs(pc); + *argc_p = argc = count_args(argv); + #ifndef SUPPORT_LINKS if (preserve_links && !am_sender) { snprintf(err_buf, sizeof err_buf, @@ -1382,8 +1387,16 @@ int parse_arguments(int *argc_p, const char ***argv_p) xfer_dirs = 1; } - if (xfer_dirs < 1) - xfer_dirs = recurse || list_only; + if (argc < 2 && !read_batch) + list_only |= 1; + + if (xfer_dirs >= 4) { + parse_rule(&filter_list, "- /*/*", 0, 0); + recurse = xfer_dirs = 1; + } else if (recurse) + xfer_dirs = 1; + else if (xfer_dirs < 0) + xfer_dirs = list_only ? 1 : 0; if (relative_paths < 0) relative_paths = files_from? 1 : 0; @@ -1432,9 +1445,6 @@ int parse_arguments(int *argc_p, const char ***argv_p) need_messages_from_generator = 1; } - *argv_p = argv = poptGetArgs(pc); - *argc_p = argc = count_args(argv); - if (sanitize_paths) { int i; for (i = argc; i-- > 0; ) @@ -1727,8 +1737,8 @@ void server_options(char **args, int *argc_p) argstr[x++] = 'n'; if (preserve_links) argstr[x++] = 'l'; - if ((list_only && !recurse) || xfer_dirs > 1 - || (xfer_dirs && !recurse && delete_mode && am_sender)) + if ((xfer_dirs >= 2 && xfer_dirs < 4) + || (xfer_dirs && !recurse && (list_only || (delete_mode && am_sender)))) argstr[x++] = 'd'; if (am_sender) { if (keep_dirlinks) diff --git a/rsync.yo b/rsync.yo index 6bbf400c..ffb99837 100644 --- a/rsync.yo +++ b/rsync.yo @@ -751,11 +751,15 @@ bf(--recursive) option, rsync will skip all directories it encounters (and output a message to that effect for each one). If you specify both bf(--dirs) and bf(--recursive), bf(--recursive) takes precedence. -This option is implied by the bf(--list-only) option (including an implied +The bf(--dirs) option is implied by the bf(--files-from) option +or the bf(--list-only) option (including an implied bf(--list-only) usage) if bf(--recursive) wasn't specified (so that directories are seen in the listing). Specify bf(--no-dirs) (or bf(--no-d)) -if you want to override this. This option is also implied by -bf(--files-from). +if you want to turn this off. + +There is also a backward-compatibility helper option, bf(--old-dirs) (or +bf(--old-d)) that tells rsync to use a hack of "-r --exclude='/*/*'" to get +an older rsync to list a single directory without recursing. dit(bf(-l, --links)) When symlinks are encountered, recreate the symlink on the destination. -- 2.34.1