int sparse_files = 0;
int do_compression = 0;
int def_compress_level = Z_DEFAULT_COMPRESSION;
-int am_root = 0;
+int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */
int am_server = 0;
int am_sender = 0;
int am_generator = 0;
#define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
char *batch_name = NULL;
+#ifdef ICONV_OPTION
+int need_unsorted_flist = 0;
+char *iconv_opt = ICONV_OPTION;
+#endif
+
struct chmod_mode_struct *chmod_modes = NULL;
static int daemon_opt; /* sets am_daemon after option error-reporting */
static void print_rsync_version(enum logcode f)
{
+ char *subprotocol = "";
char const *got_socketpair = "no ";
char const *have_inplace = "no ";
char const *hardlinks = "no ";
char const *acls = "no ";
char const *xattrs = "no ";
char const *links = "no ";
+ char const *iconv = "no ";
char const *ipv6 = "no ";
STRUCT_STAT *dumstat;
+#if SUBPROTOCOL_VERSION != 0
+ asprintf(&subprotocol, ".PR%d", SUBPROTOCOL_VERSION);
+#endif
#ifdef HAVE_SOCKETPAIR
got_socketpair = "";
#endif
-
#ifdef HAVE_FTRUNCATE
have_inplace = "";
#endif
-
#ifdef SUPPORT_HARD_LINKS
hardlinks = "";
#endif
-
#ifdef SUPPORT_ACLS
acls = "";
#endif
#ifdef SUPPORT_LINKS
links = "";
#endif
-
#ifdef INET6
ipv6 = "";
#endif
+#ifdef ICONV_OPTION
+ iconv = "";
+#endif
- rprintf(f, "%s version %s protocol version %d\n",
- RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
+ 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, "<http://rsync.samba.org/>\n");
- rprintf(f, "Capabilities: %d-bit files, %d-bit system inums, %d-bit internal inums,\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",
(int)(sizeof (OFF_T) * 8),
(int)(sizeof dumstat->st_ino * 8), /* Don't check ino_t! */
+ (int)(sizeof (time_t) * 8),
(int)(sizeof (int64) * 8));
rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
got_socketpair, hardlinks, links, ipv6, have_inplace);
- rprintf(f, " %sappend, %sACLs, %sxattrs\n",
- have_inplace, acls, xattrs);
+ rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv\n",
+ have_inplace, acls, xattrs, iconv);
#ifdef MAINTAINER_MODE
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
rprintf(F," -t, --times preserve times\n");
rprintf(F," -O, --omit-dir-times omit directories when preserving times\n");
rprintf(F," --super receiver attempts super-user activities\n");
+#ifdef SUPPORT_XATTRS
+ rprintf(F," --fake-super store/recover privileged attrs using xattrs\n");
+#endif
rprintf(F," -S, --sparse handle sparse files efficiently\n");
rprintf(F," -n, --dry-run show what would have been transferred\n");
rprintf(F," -W, --whole-file copy files whole (without rsync algorithm)\n");
rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
rprintf(F," --protocol=NUM force an older protocol version to be used\n");
+#ifdef ICONV_OPTION
+ rprintf(F," --iconv=CONVERT_SPEC request charset conversion of filesnames\n");
+#endif
#ifdef INET6
rprintf(F," -4, --ipv4 prefer IPv4\n");
rprintf(F," -6, --ipv6 prefer IPv6\n");
{"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
{"super", 0, POPT_ARG_VAL, &am_root, 2, 0, 0 },
{"no-super", 0, POPT_ARG_VAL, &am_root, 0, 0, 0 },
+ {"fake-super", 0, POPT_ARG_VAL, &am_root, -1, 0, 0 },
{"owner", 'o', POPT_ARG_VAL, &preserve_uid, 1, 0, 0 },
{"no-owner", 0, POPT_ARG_VAL, &preserve_uid, 0, 0, 0 },
{"no-o", 0, POPT_ARG_VAL, &preserve_uid, 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 },
+#ifdef ICONV_OPTION
+ {"iconv", 0, POPT_ARG_STRING, &iconv_opt, 0, 0, 0 },
+#endif
#ifdef INET6
{"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
{"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
if (am_daemon)
set_refuse_options("log-file*");
+#ifdef ICONV_OPTION
+ if (!am_daemon && (arg = getenv("RSYNC_ICONV")) != NULL && *arg)
+ iconv_opt = strdup(arg);
+#endif
+
/* TODO: Call poptReadDefaultConfig; handle errors. */
/* The context leaks in case of an error, but if there's a
long_options, 0);
am_server = 1;
}
+#ifdef ICONV_OPTION
+ iconv_opt = NULL;
+#endif
break;
case OPT_SENDER:
sizeof err_buf);
return 0;
}
+#ifdef ICONV_OPTION
+ iconv_opt = NULL;
+#endif
poptFreeContext(pc);
pc = poptGetContext(RSYNC_NAME, *argc, *argv,
long_daemon_options, 0);
exit_cleanup(0);
}
+#ifdef ICONV_OPTION
+ if (iconv_opt) {
+ if (!am_server && strcmp(iconv_opt, "-") == 0)
+ iconv_opt = NULL;
+ else
+ need_unsorted_flist = 1;
+ }
+#endif
+
#ifndef SUPPORT_LINKS
if (preserve_links && !am_sender) {
snprintf(err_buf, sizeof err_buf,
}
#endif
+#ifndef SUPPORT_XATTRS
+ if (am_root < 0) {
+ snprintf(err_buf, sizeof err_buf,
+ "--fake-super requires an rsync with extended attributes enabled\n");
+ return 0;
+ }
+#endif
+
if (write_batch && read_batch) {
snprintf(err_buf, sizeof err_buf,
"--write-batch and --read-batch can not be used together\n");
if (list_only == 1 && !recurse)
argstr[x++] = 'r';
+#if SUBPROTOCOL_VERSION != 0
+ /* If we're speaking a pre-release version of a protocol, we tell
+ * the server about this by (ab)using the -e option. */
+ if (protocol_version == PROTOCOL_VERSION) {
+ x += snprintf(argstr+x, sizeof argstr - x,
+ "e%d.%d", PROTOCOL_VERSION, SUBPROTOCOL_VERSION);
+ }
+#endif
+
argstr[x] = '\0';
if (x != 1)
args[ac++] = "--log-format=X";
}
+#ifdef ICONV_OPTION
+ if (iconv_opt) {
+ char *set = strchr(iconv_opt, ',');
+ if (set)
+ set++;
+ else
+ set = iconv_opt;
+ if (asprintf(&arg, "--iconv=%s", set) < 0)
+ goto oom;
+ args[ac++] = arg;
+ }
+#endif
+
if (block_size) {
if (asprintf(&arg, "-B%lu", block_size) < 0)
goto oom;
if (numeric_ids)
args[ac++] = "--numeric-ids";
- if (ignore_existing && am_sender)
- args[ac++] = "--ignore-existing";
+ if (am_sender) {
+ if (ignore_existing)
+ args[ac++] = "--ignore-existing";
- /* Backward compatibility: send --existing, not --ignore-non-existing. */
- if (ignore_non_existing && am_sender)
- args[ac++] = "--existing";
+ /* Backward compatibility: send --existing, not --ignore-non-existing. */
+ if (ignore_non_existing)
+ args[ac++] = "--existing";
+
+ if (tmpdir) {
+ args[ac++] = "--temp-dir";
+ args[ac++] = tmpdir;
+ }
+
+ if (basis_dir[0]) {
+ /* the server only needs this option if it is not the sender,
+ * and it may be an older version that doesn't know this
+ * option, so don't send it if client is the sender.
+ */
+ int i;
+ for (i = 0; i < basis_dir_cnt; i++) {
+ args[ac++] = dest_option;
+ args[ac++] = basis_dir[i];
+ }
+ }
+ }
if (append_mode)
args[ac++] = "--append";
else if (inplace)
args[ac++] = "--inplace";
- if (tmpdir && am_sender) {
- args[ac++] = "--temp-dir";
- args[ac++] = tmpdir;
- }
-
- if (basis_dir[0] && am_sender) {
- /* the server only needs this option if it is not the sender,
- * and it may be an older version that doesn't know this
- * option, so don't send it if client is the sender.
- */
- int i;
- for (i = 0; i < basis_dir_cnt; i++) {
- args[ac++] = dest_option;
- args[ac++] = basis_dir[i];
- }
- }
-
if (files_from && (!am_sender || filesfrom_host)) {
if (filesfrom_host) {
args[ac++] = "--files-from";