-/* -*- c-file-style: "linux" -*-
+/*
+ * Command-line (and received via daemon-socket) option parsing.
*
- * Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
- * Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
+ * Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
+ * Copyright (C) 2000, 2001, 2002 Martin Pool <mbp@samba.org>
+ * 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
* 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"
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;
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");
case OPT_EXCLUDE_FROM:
case OPT_INCLUDE_FROM:
arg = poptGetOptArg(pc);
- if (sanitize_paths)
- arg = sanitize_path(NULL, arg, NULL, 0);
+ if (sanitize_paths) {
+ arg = sanitize_path(NULL, arg, NULL, 0, NULL);
+ die_on_unsafe_path((char*)arg, 0);
+ }
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,
break;
case OPT_LINK_DEST:
-#ifdef HAVE_LINK
+#ifdef SUPPORT_HARD_LINKS
link_dest = 1;
dest_option = "--link-dest";
goto set_dest_dir;
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:
}
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) {
if (sanitize_paths) {
int i;
for (i = *argc; i-- > 0; )
- (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
- if (tmpdir)
- tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
- if (partial_dir)
- partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
- if (backup_dir)
- backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
+ (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0, NULL);
+ if (tmpdir) {
+ tmpdir = sanitize_path(NULL, tmpdir, NULL, 0, NULL);
+ die_on_unsafe_path(tmpdir, 0);
+ }
+ if (backup_dir) {
+ backup_dir = sanitize_path(NULL, backup_dir, NULL, 0, NULL);
+ die_on_unsafe_path(backup_dir, 0);
+ }
}
if (server_filter_list.head && !am_sender) {
struct filter_list_struct *elp = &server_filter_list;
- int i;
if (tmpdir) {
if (!*tmpdir)
goto options_rejected;
if (check_filter(elp, tmpdir, 1) < 0)
goto options_rejected;
}
- if (partial_dir && *partial_dir) {
- clean_fname(partial_dir, 1);
- 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;
}
} 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;