X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/5275029d11b980f7a5c6582c78412ae864dd2ec8..9439c0cb5a4b020b9bfcfe0351e33c17b9c53b54:/options.c diff --git a/options.c b/options.c index 4bf20c0b..f3d10838 100644 --- a/options.c +++ b/options.c @@ -47,6 +47,7 @@ int copy_links = 0; int preserve_links = 0; int preserve_hard_links = 0; int preserve_acls = 0; +int preserve_xattrs = 0; int preserve_perms = 0; int preserve_executability = 0; int preserve_devices = 0; @@ -71,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; @@ -197,50 +198,55 @@ 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 "; char const *acls = "no "; + char const *xattrs = "no "; char const *links = "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_XATTRS + xattrs = ""; +#endif #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, "\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\n", - have_inplace, acls); + rprintf(f, " %sappend, %sACLs, %sxattrs\n", + have_inplace, acls, xattrs); #ifdef MAINTAINER_MODE rprintf(f, "Panic Action: \"%s\"\n", get_panic_action()); @@ -286,7 +292,7 @@ void usage(enum logcode F) rprintf(F," -q, --quiet suppress non-error messages\n"); rprintf(F," --no-motd suppress daemon-mode MOTD (see manpage caveat)\n"); rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n"); - rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H, -A)\n"); + rprintf(F," -a, --archive archive mode; equals -rlptgoD (no -H,-A,-X)\n"); rprintf(F," --no-OPTION turn off an implied OPTION (e.g. --no-D)\n"); rprintf(F," -r, --recursive recurse into directories\n"); rprintf(F," -R, --relative use relative path names\n"); @@ -310,6 +316,9 @@ void usage(enum logcode F) rprintf(F," --chmod=CHMOD affect file and/or directory permissions\n"); #ifdef SUPPORT_ACLS rprintf(F," -A, --acls preserve ACLs (implies --perms)\n"); +#endif +#ifdef SUPPORT_XATTRS + rprintf(F," -X, --xattrs preserve extended attributes (implies --perms)\n"); #endif rprintf(F," -o, --owner preserve owner (super-user only)\n"); rprintf(F," -g, --group preserve group\n"); @@ -319,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"); @@ -438,6 +450,9 @@ static struct poptOption long_options[] = { {"acls", 'A', POPT_ARG_NONE, 0, 'A', 0, 0 }, {"no-acls", 0, POPT_ARG_VAL, &preserve_acls, 0, 0, 0 }, {"no-A", 0, POPT_ARG_VAL, &preserve_acls, 0, 0, 0 }, + {"xattrs", 'X', POPT_ARG_NONE, 0, 'X', 0, 0 }, + {"no-xattrs", 0, POPT_ARG_VAL, &preserve_xattrs, 0, 0, 0 }, + {"no-X", 0, POPT_ARG_VAL, &preserve_xattrs, 0, 0, 0 }, {"times", 't', POPT_ARG_VAL, &preserve_times, 1, 0, 0 }, {"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 }, {"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 }, @@ -445,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 }, @@ -1126,6 +1142,17 @@ int parse_arguments(int *argc, const char ***argv, int frommain) return 0; #endif + case 'X': +#ifdef SUPPORT_XATTRS + preserve_xattrs = 1; + preserve_perms = 1; + break; +#else + snprintf(err_buf,sizeof(err_buf), + "extended attributes are not supported on this %s\n", + am_server ? "server" : "client"); + return 0; +#endif default: /* A large opt value means that set_refuse_options() @@ -1166,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"); @@ -1589,6 +1624,10 @@ void server_options(char **args,int *argc) #ifdef SUPPORT_ACLS if (preserve_acls) argstr[x++] = 'A'; +#endif +#ifdef SUPPORT_XATTRS + if (preserve_xattrs) + argstr[x++] = 'X'; #endif if (recurse) argstr[x++] = 'r'; @@ -1618,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;