diff options
author | Jim Meyering <jim@meyering.net> | 2001-10-13 19:57:08 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2001-10-13 19:57:08 +0000 |
commit | ed759a47cb551d861d161973a9a22aae24afc8db (patch) | |
tree | 189d60f6f1f1c88c71ee602e04beb6fe77edc6da /src | |
parent | a5f6a3dc40a2b8cb1ff9bf4671fc1205be68c89e (diff) | |
download | coreutils-ed759a47cb551d861d161973a9a22aae24afc8db.tar.xz |
(enum) [NO_DEREFERENCE_OPTION]: New member.
(enum) [NO_PRESERVE_ATTRIBUTES_OPTION]: New member.
(enum) [PRESERVE_ATTRIBUTES_OPTION]: New member.
(long_opts): Separate -d and --no-dereference options.
Add `no-preserve'.
Separate -p and --preserve options.
The long-named --preserve now accepts optional arguments; -p doesn't.
(usage): Describe additions and changes.
(cp_option_init): Initialize new member, preserve_links, to 0.
(decode_preserve_arg): New function.
(main) [case 'a']: Set preserve_links to 1.
[case 'd']: Set preserve_links to 1.
Add `case' for long-named --no-dereference.
Handle long-named --no-preserve and --preserve.
Diffstat (limited to 'src')
-rw-r--r-- | src/cp.c | 119 |
1 files changed, 113 insertions, 6 deletions
@@ -70,7 +70,10 @@ struct dir_attr non-character as a pseudo short option, starting with CHAR_MAX + 1. */ enum { - PARENTS_OPTION = CHAR_MAX + 1, + NO_DEREFERENCE_OPTION = CHAR_MAX + 1, + NO_PRESERVE_ATTRIBUTES_OPTION, + PARENTS_OPTION, + PRESERVE_ATTRIBUTES_OPTION, REPLY_OPTION, SPARSE_OPTION, STRIP_TRAILING_SLASHES_OPTION, @@ -125,17 +128,18 @@ static struct option const long_opts[] = {"backup", optional_argument, NULL, 'b'}, {"dereference", no_argument, NULL, 'L'}, {"force", no_argument, NULL, 'f'}, - {"sparse", required_argument, NULL, SPARSE_OPTION}, {"interactive", no_argument, NULL, 'i'}, {"link", no_argument, NULL, 'l'}, - {"no-dereference", no_argument, NULL, 'd'}, + {"no-dereference", no_argument, NULL, NO_DEREFERENCE_OPTION}, + {"no-preserve", required_argument, NULL, NO_PRESERVE_ATTRIBUTES_OPTION}, {"one-file-system", no_argument, NULL, 'x'}, {"parents", no_argument, NULL, PARENTS_OPTION}, {"path", no_argument, NULL, PARENTS_OPTION}, /* Deprecated. */ - {"preserve", no_argument, NULL, 'p'}, + {"preserve", optional_argument, NULL, PRESERVE_ATTRIBUTES_OPTION}, {"recursive", no_argument, NULL, 'R'}, {"remove-destination", no_argument, NULL, UNLINK_DEST_BEFORE_OPENING}, {"reply", required_argument, NULL, REPLY_OPTION}, + {"sparse", required_argument, NULL, SPARSE_OPTION}, {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION}, {"suffix", required_argument, NULL, 'S'}, {"symbolic-link", no_argument, NULL, 's'}, @@ -168,7 +172,8 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ -a, --archive same as -dpR\n\ --backup[=CONTROL] make a backup of each existing destination file\n\ -b like --backup but does not accept an argument\n\ - -d, --no-dereference never follow symbolic links\n\ + -d same as --no-dereference --preserve=link\n\ + --no-dereference never follow symbolic links\n\ -f, --force if an existing destination file cannot be\n\ opened, remove it and try again\n\ -i, --interactive prompt before overwrite\n\ @@ -177,7 +182,11 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ printf (_("\ -l, --link link files instead of copying\n\ -L, --dereference always follow symbolic links\n\ - -p, --preserve preserve file attributes if possible\n\ + -p same as --preserve=mode,ownership,timestamps\n\ + --preserve[=ATTR_LIST] preserve the specified attributes (default:\n\ + mode,ownership,timestamps), if possible\n\ + additional attributes: links, all\n\ + --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents append source path to DIRECTORY\n\ -P same as `--parents' for now; soon to change to\n\ `--no-dereference' to conform to POSIX\n\ @@ -697,6 +706,7 @@ cp_option_init (struct cp_options *x) x->one_file_system = 0; x->preserve_ownership = 0; + x->preserve_links = 0; x->preserve_mode = 0; x->preserve_timestamps = 0; @@ -720,6 +730,81 @@ cp_option_init (struct cp_options *x) x->verbose = 0; } +/* Given a string, ARG, containing a comma-separated list of arguments + to the --preserve option, set the appropriate fields of X to ON_OFF. */ +static void +decode_preserve_arg (char const *arg, struct cp_options *x, int on_off) +{ + enum File_attribute + { + PRESERVE_MODE, + PRESERVE_TIMESTAMPS, + PRESERVE_OWNERSHIP, + PRESERVE_LINK, + PRESERVE_ALL + }; + static enum File_attribute const preserve_vals[] = + { + PRESERVE_MODE, PRESERVE_TIMESTAMPS, + PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_ALL + }; + + /* Valid arguments to the `--reply' option. */ + static char const* const preserve_args[] = + { + "mode", "timestamps", + "ownership", "links", "all", 0 + }; + + char *arg_writable = xstrdup (arg); + char *s = arg_writable; + do + { + /* find next comma */ + char *comma = strchr (s, ','); + enum File_attribute val; + + /* put a NUL in its place */ + if (comma) + *comma = 0; + + /* process S. */ + val = XARGMATCH ("--preserve", s, preserve_args, preserve_vals); + switch (val) + { + case PRESERVE_MODE: + x->preserve_mode = on_off; + break; + + case PRESERVE_TIMESTAMPS: + x->preserve_timestamps = on_off; + break; + + case PRESERVE_OWNERSHIP: + x->preserve_ownership = on_off; + break; + + case PRESERVE_LINK: + x->preserve_links = on_off; + break; + + case PRESERVE_ALL: + x->preserve_mode = on_off; + x->preserve_timestamps = on_off; + x->preserve_ownership = on_off; + x->preserve_links = on_off; + break; + + default: + abort (); + } + s = comma; + } + while (s); + + free (arg_writable); +} + int main (int argc, char **argv) { @@ -759,6 +844,7 @@ main (int argc, char **argv) case 'a': /* Like -dpR. */ x.dereference = DEREF_NEVER; + x.preserve_links = 1; x.preserve_ownership = 1; x.preserve_mode = 1; x.preserve_timestamps = 1; @@ -781,6 +867,7 @@ main (int argc, char **argv) break; case 'd': + x.preserve_links = 1; x.dereference = DEREF_NEVER; break; @@ -804,6 +891,26 @@ main (int argc, char **argv) x.dereference = DEREF_ALWAYS; break; + case NO_DEREFERENCE_OPTION: + x.dereference = DEREF_NEVER; + break; + + case NO_PRESERVE_ATTRIBUTES_OPTION: + decode_preserve_arg (optarg, &x, 0); + break; + + case PRESERVE_ATTRIBUTES_OPTION: + if (optarg == NULL) + { + /* Fall through to the case for `p' below. */ + } + else + { + decode_preserve_arg (optarg, &x, 1); + x.require_preserve = 1; + break; + } + case 'p': x.preserve_ownership = 1; x.preserve_mode = 1; |