Adding the --fake-super option.
[rsync/rsync.git] / options.c
index 4a9b28f..f3d1083 100644 (file)
--- a/options.c
+++ b/options.c
@@ -72,7 +72,7 @@ int protocol_version = PROTOCOL_VERSION;
 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;
@@ -198,7 +198,7 @@ char *bind_address;
 
 static void print_rsync_version(enum logcode f)
 {
-       char buf[32];
+       char *subprotocol = "";
        char const *got_socketpair = "no ";
        char const *have_inplace = "no ";
        char const *hardlinks = "no ";
@@ -208,18 +208,18 @@ static void print_rsync_version(enum logcode f)
        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
@@ -229,17 +229,12 @@ static void print_rsync_version(enum logcode f)
 #ifdef SUPPORT_LINKS
        links = "";
 #endif
-
 #ifdef INET6
        ipv6 = "";
 #endif
 
-       if (SUBPROTOCOL_VERSION)
-               snprintf(buf, sizeof buf, ".PR%d", SUBPROTOCOL_VERSION);
-       else
-               *buf = '\0';
        rprintf(f, "%s  version %s  protocol version %d%s\n",
-               RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, buf);
+               RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
        rprintf(f, "Copyright (C) 1996-2007 by Andrew Tridgell, Wayne Davison, and others.\n");
        rprintf(f, "Web site: http://rsync.samba.org/\n");
        rprintf(f, "Capabilities:\n");
@@ -333,6 +328,9 @@ void usage(enum logcode F)
   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");
@@ -462,6 +460,7 @@ static struct poptOption long_options[] = {
   {"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 },
@@ -1194,6 +1193,14 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
        }
 #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");
@@ -1650,12 +1657,14 @@ void server_options(char **args,int *argc)
 
        argstr[x] = '\0';
 
+#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 (SUBPROTOCOL_VERSION && protocol_version == PROTOCOL_VERSION) {
+       if (protocol_version == PROTOCOL_VERSION) {
                x += snprintf(argstr+x, sizeof argstr - x,
                              "e%d.%d", PROTOCOL_VERSION, SUBPROTOCOL_VERSION);
        }
+#endif
 
        if (x != 1)
                args[ac++] = argstr;