#include "zlib/zlib.h"
extern int module_id;
+extern int local_server;
extern int sanitize_paths;
extern int daemon_over_rsh;
extern unsigned int module_dirlen;
extern struct filter_list_struct filter_list;
-extern struct filter_list_struct server_filter_list;
+extern struct filter_list_struct daemon_filter_list;
int make_backups = 0;
int blocking_io = -1;
int checksum_seed = 0;
int inplace = 0;
+int tweak_attrs = 2; /* 2 = always, 1 = if not hlinked, 0 = never */
int delay_updates = 0;
long block_size = 0; /* "long" because popt can't set an int32. */
char *skip_compress = NULL;
rprintf(f, "%s version %s protocol version %d%s\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
- rprintf(f, "Copyright (C) 1996-2007 by Andrew Tridgell, Wayne Davison, and others.\n");
+ rprintf(f, "Copyright (C) 1996-2008 by Andrew Tridgell, Wayne Davison, and others.\n");
rprintf(f, "Web site: http://rsync.samba.org/\n");
rprintf(f, "Capabilities:\n");
rprintf(f, " %d-bit files, %d-bit inums, %d-bit timestamps, %d-bit long ints,\n",
rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
rprintf(F," --append append data onto shorter files\n");
rprintf(F," --append-verify like --append, but with old data in file checksum\n");
+ rprintf(F," --no-tweak recreate dest files instead of tweaking attrs\n");
+ rprintf(F," --no-tweak-hlinked ... if they have multiple hard links\n");
rprintf(F," -d, --dirs transfer directories without recursing\n");
rprintf(F," -l, --links copy symlinks as symlinks\n");
rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
{"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 },
{"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
{"min-size", 0, POPT_ARG_STRING, &min_size_arg, OPT_MIN_SIZE, 0, 0 },
- {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
- {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
+ {"sparse", 'S', POPT_ARG_VAL, &sparse_files, 1, 0, 0 },
+ {"no-sparse", 0, POPT_ARG_VAL, &sparse_files, 0, 0, 0 },
+ {"no-S", 0, POPT_ARG_VAL, &sparse_files, 0, 0, 0 },
+ {"inplace", 0, POPT_ARG_VAL, &inplace, 1, 0, 0 },
+ {"no-inplace", 0, POPT_ARG_VAL, &inplace, 0, 0, 0 },
{"append", 0, POPT_ARG_NONE, 0, OPT_APPEND, 0, 0 },
{"append-verify", 0, POPT_ARG_VAL, &append_mode, 2, 0, 0 },
{"no-append", 0, POPT_ARG_VAL, &append_mode, 0, 0, 0 },
+ {"no-tweak", 0, POPT_ARG_VAL, &tweak_attrs, 0, 0, 0 },
+ {"no-tweak-hlinked", 0, POPT_ARG_VAL, &tweak_attrs, 1, 0, 0 },
+ {"tweak", 0, POPT_ARG_VAL, &tweak_attrs, 2, 0, 0 },
{"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_NONE, &delete_before, 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 */
{"remove-source-files",0,POPT_ARG_VAL, &remove_source_files, 1, 0, 0 },
- {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
- {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
+ {"force", 0, POPT_ARG_VAL, &force_delete, 1, 0, 0 },
+ {"no-force", 0, POPT_ARG_VAL, &force_delete, 0, 0, 0 },
+ {"ignore-errors", 0, POPT_ARG_VAL, &ignore_errors, 1, 0, 0 },
+ {"no-ignore-errors", 0, POPT_ARG_VAL, &ignore_errors, 0, 0, 0 },
{"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
{0, 'F', POPT_ARG_NONE, 0, 'F', 0, 0 },
{"filter", 'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
{"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
{"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
{"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
- {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
+ {"fuzzy", 'y', POPT_ARG_VAL, &fuzzy_basis, 1, 0, 0 },
+ {"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
+ {"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
{"compress", 'z', POPT_ARG_NONE, 0, 'z', 0, 0 },
{"no-compress", 0, POPT_ARG_VAL, &do_compression, 0, 0, 0 },
- {"skip-compress", 0, POPT_ARG_STRING, &skip_compress, 0, 0, 0 },
{"no-z", 0, POPT_ARG_VAL, &do_compression, 0, 0, 0 },
+ {"skip-compress", 0, POPT_ARG_STRING, &skip_compress, 0, 0, 0 },
{"compress-level", 0, POPT_ARG_INT, &def_compress_level, 'z', 0, 0 },
{0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
{"progress", 0, POPT_ARG_VAL, &do_progress, 1, 0, 0 },
{"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
{"delay-updates", 0, POPT_ARG_VAL, &delay_updates, 1, 0, 0 },
{"no-delay-updates", 0, POPT_ARG_VAL, &delay_updates, 0, 0, 0 },
- {"prune-empty-dirs",'m', POPT_ARG_NONE, &prune_empty_dirs, 0, 0, 0 },
+ {"prune-empty-dirs",'m', POPT_ARG_VAL, &prune_empty_dirs, 1, 0, 0 },
+ {"no-prune-empty-dirs",0,POPT_ARG_VAL, &prune_empty_dirs, 0, 0, 0 },
+ {"no-m", 0, POPT_ARG_VAL, &prune_empty_dirs, 0, 0, 0 },
{"log-file", 0, POPT_ARG_STRING, &logfile_name, 0, 0, 0 },
{"log-file-format", 0, POPT_ARG_STRING, &logfile_format, 0, 0, 0 },
{"out-format", 0, POPT_ARG_STRING, &stdout_format, 0, 0, 0 },
{"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 },
{"no-timeout", 0, POPT_ARG_VAL, &io_timeout, 0, 0, 0 },
{"contimeout", 0, POPT_ARG_INT, &connect_timeout, 0, 0, 0 },
+ {"no-contimeout", 0, POPT_ARG_VAL, &connect_timeout, 0, 0, 0 },
{"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
{"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
#endif
{"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
{"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
- {"8-bit-output", '8', POPT_ARG_NONE, &allow_8bit_chars, 0, 0, 0 },
+ {"8-bit-output", '8', POPT_ARG_VAL, &allow_8bit_chars, 1, 0, 0 },
+ {"no-8-bit-output", 0, POPT_ARG_VAL, &allow_8bit_chars, 0, 0, 0 },
+ {"no-8", 0, POPT_ARG_VAL, &allow_8bit_chars, 0, 0, 0 },
{"qsort", 0, POPT_ARG_NONE, &use_qsort, 0, 0, 0 },
{"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
{"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
*
* @retval 0 on error, with err_buf containing an explanation
**/
-int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+int parse_arguments(int *argc_p, const char ***argv_p)
{
static poptContext pc;
char *ref = lp_refuse_options(module_id);
set_refuse_options(ref);
if (am_daemon) {
set_refuse_options("log-file*");
+#ifdef ICONV_OPTION
if (!*lp_charset(module_id))
set_refuse_options("iconv");
+#endif
}
#ifdef ICONV_OPTION
arg = poptGetOptArg(pc);
if (sanitize_paths)
arg = sanitize_path(NULL, arg, NULL, 0);
- if (server_filter_list.head) {
+ if (daemon_filter_list.head) {
int rej;
char *dir, *cp = strdup(arg);
if (!cp)
goto options_rejected;
dir = cp + (*cp == '/' ? module_dirlen : 0);
clean_fname(dir, CFN_COLLAPSE_DOT_DOT_DIRS);
- rej = check_filter(&server_filter_list, dir, 0) < 0;
+ rej = check_filter(&daemon_filter_list, dir, 0) < 0;
free(cp);
if (rej)
goto options_rejected;
break;
case 'q':
- if (frommain)
- quiet++;
+ quiet++;
break;
case 'x':
}
#endif
- if (protect_args == 1) {
- if (!frommain)
- protect_args = 0;
- else if (am_server)
- return 1;
- }
+ if (protect_args == 1 && am_server)
+ return 1;
#ifndef SUPPORT_LINKS
if (preserve_links && !am_sender) {
}
#endif
-#ifndef SUPPORT_XATTRS
+#ifdef SUPPORT_XATTRS
+ if (am_root < 0 && preserve_xattrs > 1) {
+ snprintf(err_buf, sizeof err_buf,
+ "--fake-super conflicts with -XX\n");
+ return 0;
+ }
+#else
if (am_root < 0) {
snprintf(err_buf, sizeof err_buf,
"--fake-super requires an rsync with extended attributes enabled\n");
if (backup_dir)
backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
}
- if (server_filter_list.head && !am_sender) {
- struct filter_list_struct *elp = &server_filter_list;
+ if (daemon_filter_list.head && !am_sender) {
+ struct filter_list_struct *elp = &daemon_filter_list;
if (tmpdir) {
char *dir;
if (!*tmpdir)
partial_dir = tmp_partialdir;
if (inplace) {
+ char *inplace_opt = append_mode ? "append" : "inplace";
#ifdef HAVE_FTRUNCATE
+ if (tweak_attrs == 0) {
+ snprintf(err_buf, sizeof err_buf,
+ "--no-tweak controverts --%s. Remove --%s.\n",
+ inplace_opt, inplace_opt);
+ return 0;
+ }
+ if (tweak_attrs == 1) {
+ snprintf(err_buf, sizeof err_buf,
+ "The combination of --no-tweak-hlinked and --%s is not implemented.\n",
+ inplace_opt);
+ return 0;
+ }
if (partial_dir) {
snprintf(err_buf, sizeof err_buf,
"--%s cannot be used with --%s\n",
- append_mode ? "append" : "inplace",
+ inplace_opt,
delay_updates ? "delay-updates" : "partial-dir");
return 0;
}
#else
snprintf(err_buf, sizeof err_buf,
"--%s is not supported on this %s\n",
- append_mode ? "append" : "inplace",
+ inplace_opt,
am_server ? "server" : "client");
return 0;
#endif
} else {
if (sanitize_paths)
files_from = sanitize_path(NULL, files_from, NULL, 0);
- if (server_filter_list.head) {
+ if (daemon_filter_list.head) {
char *dir;
if (!*files_from)
goto options_rejected;
dir = files_from + (*files_from == '/' ? module_dirlen : 0);
clean_fname(dir, CFN_COLLAPSE_DOT_DOT_DIRS);
- if (check_filter(&server_filter_list, dir, 0) < 0)
+ if (check_filter(&daemon_filter_list, dir, 0) < 0)
goto options_rejected;
}
filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
}
#endif
- if (protect_args) /* initial args break here */
+ if (protect_args && !local_server) /* unprotected args stop here */
args[ac++] = NULL;
if (list_only > 1)
args[ac++] = "--super";
if (size_only)
args[ac++] = "--size-only";
+ if (tweak_attrs != 2)
+ args[ac++] = (tweak_attrs == 1) ? "--no-tweak-hlinked" : "--no-tweak";
} else {
if (skip_compress) {
if (asprintf(&arg, "--skip-compress=%s", skip_compress) < 0)