Adding the --fake-super option.
[rsync/rsync.git] / options.c
index c1423b6..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,6 +198,7 @@ char *bind_address;
 
 static void print_rsync_version(enum logcode f)
 {
+       char *subprotocol = "";
        char const *got_socketpair = "no ";
        char const *have_inplace = "no ";
        char const *hardlinks = "no ";
@@ -207,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
@@ -228,18 +229,19 @@ static void print_rsync_version(enum logcode f)
 #ifdef SUPPORT_LINKS
        links = "";
 #endif
-
 #ifdef INET6
        ipv6 = "";
 #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);
@@ -326,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");
@@ -455,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 },
@@ -1187,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");
@@ -1643,6 +1657,15 @@ 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 (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;