X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/2dbf36ef550d63550188480bb596c88cbeecf54a..fcecb70b1d003589cd9e8766d70a4a0010fc73d4:/options.c diff --git a/options.c b/options.c index 6509d958..e5f88f73 100644 --- a/options.c +++ b/options.c @@ -1,7 +1,9 @@ -/* -*- c-file-style: "linux" -*- +/* + * Command-line (and received via daemon-socket) option parsing. * - * Copyright (C) 1998-2001 by Andrew Tridgell - * Copyright (C) 2000, 2001, 2002 by Martin Pool + * Copyright (C) 1998-2001 Andrew Tridgell + * Copyright (C) 2000, 2001, 2002 Martin Pool + * Copyright (C) 2002, 2003, 2004, 2005, 2006 Wayne Davison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,9 +15,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * 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. */ #include "rsync.h" @@ -58,8 +60,6 @@ int cvs_exclude = 0; int dry_run = 0; int do_xfers = 1; int ignore_times = 0; -int saw_delete_opt = 0; -int saw_delete_excluded_opt = 0; int delete_mode = 0; int delete_during = 0; int delete_before = 0; @@ -311,15 +311,15 @@ void usage(enum logcode F) 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"); rprintf(F," --rsync-path=PROGRAM specify the rsync to run on the remote machine\n"); - rprintf(F," --existing ignore non-existing files on receiving side\n"); - rprintf(F," --ignore-existing ignore files that already exist on receiving side\n"); - rprintf(F," --remove-sent-files sent files/symlinks are removed from sending side\n"); + rprintf(F," --existing skip creating new files on receiver\n"); + rprintf(F," --ignore-existing skip updating files that already exist on receiver\n"); + rprintf(F," --remove-sent-files sender removes successfully sent files (non-dirs)\n"); rprintf(F," --del an alias for --delete-during\n"); - rprintf(F," --delete delete files that don't exist on the sending side\n"); + 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-after receiver deletes after transfer, not before\n"); - rprintf(F," --delete-excluded also delete excluded files on the receiving side\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"); 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"); @@ -437,7 +437,9 @@ static struct poptOption long_options[] = { {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 }, {"copy-dirlinks", 'k', POPT_ARG_NONE, ©_dirlinks, 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 }, + {"hard-links", 'H', POPT_ARG_VAL, &preserve_hard_links, 1, 0, 0 }, + {"no-hard-links", 0, POPT_ARG_VAL, &preserve_hard_links, 0, 0, 0 }, + {"no-H", 0, POPT_ARG_VAL, &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 }, @@ -889,14 +891,17 @@ int parse_arguments(int *argc, const char ***argv, int frommain) case OPT_INCLUDE_FROM: arg = poptGetOptArg(pc); if (sanitize_paths) - arg = sanitize_path(NULL, arg, NULL, 0); + arg = sanitize_path(NULL, arg, NULL, 0, NULL); if (server_filter_list.head) { - char *cp = (char *)arg; + char *cp = strdup(arg); + if (!cp) + out_of_memory("parse_arguments"); if (!*cp) goto options_rejected; clean_fname(cp, 1); if (check_filter(&server_filter_list, cp, 0) < 0) goto options_rejected; + free(cp); } parse_filter_file(&filter_list, arg, opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0, @@ -1020,7 +1025,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain) break; case OPT_LINK_DEST: -#ifdef HAVE_LINK +#ifdef SUPPORT_HARD_LINKS link_dest = 1; dest_option = "--link-dest"; goto set_dest_dir; @@ -1046,10 +1051,9 @@ int parse_arguments(int *argc, const char ***argv, int frommain) MAX_BASIS_DIRS, dest_option); return 0; } - arg = poptGetOptArg(pc); - if (sanitize_paths) - arg = sanitize_path(NULL, arg, NULL, 0); - basis_dir[basis_dir_cnt++] = (char *)arg; + /* We defer sanitizing this arg until we know what + * our destination directory is going to be. */ + basis_dir[basis_dir_cnt++] = (char *)poptGetOptArg(pc); break; case OPT_CHMOD: @@ -1176,11 +1180,10 @@ int parse_arguments(int *argc, const char ***argv, int frommain) } delete_mode = delete_before = 1; } - saw_delete_opt = delete_mode; - saw_delete_excluded_opt = delete_excluded; - if (!xfer_dirs) { - delete_before = delete_during = delete_after = 0; - delete_mode = delete_excluded = 0; + if (!xfer_dirs && delete_mode) { + snprintf(err_buf, sizeof err_buf, + "--delete does not work without -r or -d.\n"); + return 0; } if (delete_mode && refused_delete) { @@ -1205,17 +1208,16 @@ int parse_arguments(int *argc, const char ***argv, int frommain) if (sanitize_paths) { int i; for (i = *argc; i-- > 0; ) - (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0); + (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0, NULL); if (tmpdir) - tmpdir = sanitize_path(NULL, tmpdir, NULL, 0); + tmpdir = sanitize_path(NULL, tmpdir, NULL, 0, NULL); if (partial_dir) - partial_dir = sanitize_path(NULL, partial_dir, NULL, 0); + partial_dir = sanitize_path(NULL, partial_dir, NULL, 0, NULL); if (backup_dir) - backup_dir = sanitize_path(NULL, backup_dir, NULL, 0); + backup_dir = sanitize_path(NULL, backup_dir, NULL, 0, NULL); } if (server_filter_list.head && !am_sender) { struct filter_list_struct *elp = &server_filter_list; - int i; if (tmpdir) { if (!*tmpdir) goto options_rejected; @@ -1228,13 +1230,6 @@ int parse_arguments(int *argc, const char ***argv, int frommain) if (check_filter(elp, partial_dir, 1) < 0) goto options_rejected; } - for (i = 0; i < basis_dir_cnt; i++) { - if (!*basis_dir[i]) - goto options_rejected; - clean_fname(basis_dir[i], 1); - if (check_filter(elp, basis_dir[i], 1) < 0) - goto options_rejected; - } if (backup_dir) { if (!*backup_dir) goto options_rejected; @@ -1415,7 +1410,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain) } } else { if (sanitize_paths) - files_from = sanitize_path(NULL, files_from, NULL, 0); + files_from = sanitize_path(NULL, files_from, NULL, 0, NULL); if (server_filter_list.head) { if (!*files_from) goto options_rejected;