X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/4d51f0db79f11734a92db2d876aeb7b0f6546735..5a3e9ff6081cb83873881df9a7bcfc19f9af5e58:/options.c diff --git a/options.c b/options.c index 05df91e4..304704b0 100644 --- a/options.c +++ b/options.c @@ -106,7 +106,7 @@ size_t bwlimit_writemax = 0; int ignore_existing = 0; int ignore_non_existing = 0; int need_messages_from_generator = 0; -int max_delete = 0; +int max_delete = -1; OFF_T max_size = 0; OFF_T min_size = 0; int ignore_errors = 0; @@ -116,7 +116,7 @@ int checksum_seed = 0; int inplace = 0; int delay_updates = 0; long block_size = 0; /* "long" because popt can't set an int32. */ - +int flist_extra_cnt = 0; /* count of file-list extras that everyone gets */ /** Network address family. **/ #ifdef INET6 @@ -164,6 +164,7 @@ char *dest_option = NULL; int verbose = 0; int quiet = 0; +int output_motd = 1; int log_before_transfer = 0; int stdout_format_has_i = 0; int stdout_format_has_o_or_i = 0; @@ -226,19 +227,15 @@ static void print_rsync_version(enum logcode f) RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION); rprintf(f, "Copyright (C) 1996-2006 by Andrew Tridgell, Wayne Davison, and others.\n"); rprintf(f, "\n"); - rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, " - "%shard links, %ssymlinks, batchfiles,\n", - (int) (sizeof (OFF_T) * 8), - got_socketpair, hardlinks, links); - - /* Note that this field may not have type ino_t. It depends - * on the complicated interaction between largefile feature - * macros. */ - rprintf(f, " %sinplace, %sIPv6, " - "%d-bit system inums, %d-bit internal inums\n", - have_inplace, ipv6, - (int) (sizeof dumstat->st_ino * 8), - (int) (sizeof (int64) * 8)); + rprintf(f, "Capabilities: %d-bit files, %d-bit system inums, %d-bit internal inums,\n", + (int)(sizeof (OFF_T) * 8), + (int)(sizeof dumstat->st_ino * 8), /* Don't check ino_t! */ + (int)(sizeof (int64) * 8)); + rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n", + got_socketpair, hardlinks, links, ipv6, have_inplace); + rprintf(f, " %sappend\n", + have_inplace); + #ifdef MAINTAINER_MODE rprintf(f, "Panic Action: \"%s\"\n", get_panic_action()); #endif @@ -281,6 +278,7 @@ void usage(enum logcode F) rprintf(F,"Options\n"); rprintf(F," -v, --verbose increase verbosity\n"); rprintf(F," -q, --quiet suppress non-error messages\n"); + rprintf(F," --no-motd suppress daemon-mode MOTD (see manpage caveat)\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 off an implied OPTION (e.g. --no-D)\n"); @@ -326,6 +324,7 @@ void usage(enum logcode F) rprintf(F," --delete delete extraneous files from destination dirs\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-delay find deletions during, delete after\n"); rprintf(F," --delete-after receiver deletes after transfer, not before\n"); rprintf(F," --delete-excluded also delete excluded files from destination dirs\n"); rprintf(F," --ignore-errors delete even if there are I/O errors\n"); @@ -407,6 +406,8 @@ static struct poptOption long_options[] = { {"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 }, + {"motd", 0, POPT_ARG_VAL, &output_motd, 1, 0, 0 }, + {"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}, {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 }, @@ -472,7 +473,8 @@ static struct poptOption long_options[] = { {"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 }, - {"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 }, + {"delete-during", 0, POPT_ARG_VAL, &delete_during, 1, 0, 0 }, + {"delete-delay", 0, POPT_ARG_VAL, &delete_during, 2, 0, 0 }, {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 }, {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 }, {"remove-sent-files",0, POPT_ARG_VAL, &remove_source_files, 2, 0, 0 }, /* deprecated */ @@ -613,8 +615,9 @@ static char err_buf[200]; void option_error(void) { if (!err_buf[0]) { - strcpy(err_buf, "Error parsing options: " - "option may be supported on client but not on server?\n"); + strlcpy(err_buf, "Error parsing options: option may " + "be supported on client but not on server?\n", + sizeof err_buf); } rprintf(FERROR, RSYNC_NAME ": %s", err_buf); @@ -710,9 +713,9 @@ static OFF_T parse_size_arg(char **size_arg, char def_suf) const char *arg; OFF_T size = 1; - for (arg = *size_arg; isdigit(*(uchar*)arg); arg++) {} + for (arg = *size_arg; isDigit(arg); arg++) {} if (*arg == '.') - for (arg++; isdigit(*(uchar*)arg); arg++) {} + for (arg++; isDigit(arg); arg++) {} switch (*arg && *arg != '+' && *arg != '-' ? *arg++ : def_suf) { case 'b': case 'B': reps = 0; @@ -751,7 +754,7 @@ static OFF_T parse_size_arg(char **size_arg, char def_suf) OFF_T num = size; *s = '\0'; while (num) { - *--s = (num % 10) + '0'; + *--s = (char)(num % 10) + '0'; num /= 10; } if (!(*size_arg = strdup(s))) @@ -832,7 +835,9 @@ int parse_arguments(int *argc, const char ***argv, int frommain) case OPT_DAEMON: if (am_daemon) { - strcpy(err_buf, "Attempt to hack rsync thwarted!\n"); + strlcpy(err_buf, + "Attempt to hack rsync thwarted!\n", + sizeof err_buf); return 0; } poptFreeContext(pc); @@ -1178,7 +1183,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain) if (!relative_paths) implied_dirs = 0; - if (!!delete_before + delete_during + delete_after > 1) { + if (!!delete_before + !!delete_during + delete_after > 1) { snprintf(err_buf, sizeof err_buf, "You may not combine multiple --delete-WHEN options.\n"); return 0; @@ -1214,6 +1219,11 @@ int parse_arguments(int *argc, const char ***argv, int frommain) need_messages_from_generator = 1; } + if (preserve_uid) + preserve_uid = ++flist_extra_cnt; + if (preserve_gid) + preserve_gid = ++flist_extra_cnt; + *argv = poptGetArgs(pc); *argc = count_args(*argv); @@ -1239,12 +1249,8 @@ int parse_arguments(int *argc, const char ***argv, int frommain) if (!*backup_dir) goto options_rejected; clean_fname(backup_dir, 1); - if (check_filter(elp, backup_dir, 1) < 0) { - options_rejected: - snprintf(err_buf, sizeof err_buf, - "Your options have been rejected by the server.\n"); - return 0; - } + if (check_filter(elp, backup_dir, 1) < 0) + goto options_rejected; } } @@ -1391,7 +1397,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain) clean_fname(partial_dir, 1); if (!*partial_dir || strcmp(partial_dir, ".") == 0) partial_dir = NULL; - else if (*partial_dir != '/') { + else if (*partial_dir != '/' && !am_server) { parse_rule(&filter_list, partial_dir, MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0); } @@ -1450,6 +1456,11 @@ int parse_arguments(int *argc, const char ***argv, int frommain) am_starting_up = 0; return 1; + + options_rejected: + snprintf(err_buf, sizeof err_buf, + "Your options have been rejected by the server.\n"); + return 0; } @@ -1607,7 +1618,7 @@ void server_options(char **args,int *argc) args[ac++] = arg; } - if (max_delete && am_sender) { + if (max_delete >= 0 && am_sender) { if (asprintf(&arg, "--max-delete=%d", max_delete) < 0) goto oom; args[ac++] = arg; @@ -1655,9 +1666,11 @@ void server_options(char **args,int *argc) args[ac++] = "--delete"; if (delete_before > 1) args[ac++] = "--delete-before"; - if (delete_during) + else if (delete_during == 2) + args[ac++] = "--delete-delay"; + else if (delete_during) args[ac++] = "--delete-during"; - if (delete_after) + else if (delete_after) args[ac++] = "--delete-after"; if (force_delete) args[ac++] = "--force";