X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/794f38099a79cb1150b72a93c86782f7f07aa361..refs/heads/hacks/missing-args-b3.0.x:/options.c diff --git a/options.c b/options.c index e699ff2c..f5dbecea 100644 --- a/options.c +++ b/options.c @@ -82,6 +82,7 @@ int am_generator = 0; int am_starting_up = 1; int relative_paths = -1; int implied_dirs = 1; +int missing_args = 0; /* 0 = FERROR_XFER, 1 = ignore, 2 = delete */ int numeric_ids = 0; int allow_8bit_chars = 0; int force_delete = 0; @@ -375,6 +376,8 @@ void usage(enum logcode F) rprintf(F," --delete-delay find deletions during, delete after\n"); rprintf(F," --delete-after receiver deletes after transfer, not during\n"); rprintf(F," --delete-excluded also delete excluded files from destination dirs\n"); + rprintf(F," --ignore-missing-args ignore missing source args without error\n"); + rprintf(F," --delete-missing-args delete missing source args from destination\n"); rprintf(F," --ignore-errors delete even if there are I/O errors\n"); rprintf(F," --force force deletion of directories even if not empty\n"); rprintf(F," --max-delete=NUM don't delete more than NUM files\n"); @@ -555,6 +558,8 @@ static struct poptOption long_options[] = { {"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 }, + {"delete-missing-args",0,POPT_BIT_SET, &missing_args, 2, 0, 0 }, + {"ignore-missing-args",0,POPT_BIT_SET, &missing_args, 1, 0, 0 }, {"remove-sent-files",0, POPT_ARG_VAL, &remove_source_files, 2, 0, 0 }, /* deprecated */ {"remove-source-files",0,POPT_ARG_VAL, &remove_source_files, 1, 0, 0 }, {"force", 0, POPT_ARG_VAL, &force_delete, 1, 0, 0 }, @@ -1357,6 +1362,12 @@ int parse_arguments(int *argc_p, const char ***argv_p) "--read-batch cannot be used with --files-from\n"); return 0; } + if (read_batch && remove_source_files) { + snprintf(err_buf, sizeof err_buf, + "--read-batch cannot be used with --remove-%s-files\n", + remove_source_files == 1 ? "source" : "sent"); + return 0; + } if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) { snprintf(err_buf, sizeof err_buf, "the batch-file name must be %d characters or less.\n", @@ -1430,7 +1441,9 @@ int parse_arguments(int *argc_p, const char ***argv_p) return 0; } - if (delete_mode && refused_delete) { + if (missing_args == 3) /* simplify if both options were specified */ + missing_args = 2; + if (refused_delete && (delete_mode || missing_args == 2)) { create_refuse_error(refused_delete); return 0; } @@ -1969,6 +1982,13 @@ void server_options(char **args, int *argc_p) } } + /* --delete-missing-args needs the cooperation of both sides, but + * the sender can handle --ignore-missing-args by itself. */ + if (missing_args == 2) + args[ac++] = "--delete-missing-args"; + else if (missing_args == 1 && !am_sender) + args[ac++] = "--ignore-missing-args"; + if (modify_window_set) { if (asprintf(&arg, "--modify-window=%d", modify_window) < 0) goto oom; @@ -2083,17 +2103,18 @@ void server_options(char **args, int *argc_p) * (required for parsing) [ and ] chars elided from the returned string. */ static char *parse_hostspec(char *str, char **path_start_ptr, int *port_ptr) { - char *s = str; - char *host_start = str; + char *s, *host_start = str; int hostlen = 0, userlen = 0; char *ret; - for ( ; ; s++) { + for (s = str; ; s++) { if (!*s) { /* It is only OK if we run out of string with rsync:// */ - if (port_ptr) - break; - return NULL; + if (!port_ptr) + return NULL; + if (!hostlen) + hostlen = s - host_start; + break; } if (*s == ':' || *s == '/') { if (!hostlen) @@ -2104,7 +2125,7 @@ static char *parse_hostspec(char *str, char **path_start_ptr, int *port_ptr) } else if (port_ptr) { *port_ptr = atoi(s); while (isDigit(s)) s++; - if (*s++ != '/') + if (*s && *s++ != '/') return NULL; } break;