aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-21 19:35:33 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-21 19:38:39 +0200
commit0ec52d438a41be92d2d8e8651242b4d9faf23a6c (patch)
treec80be8cec69e3852a151e5d3329d1d63d2f7d672 /coreutils
parent1de709fda2e75aeef160b3b13a43865e7a622f06 (diff)
downloadbusybox-w32-0ec52d438a41be92d2d8e8651242b4d9faf23a6c.tar.gz
busybox-w32-0ec52d438a41be92d2d8e8651242b4d9faf23a6c.tar.bz2
busybox-w32-0ec52d438a41be92d2d8e8651242b4d9faf23a6c.zip
cp: implement -t DIR
function old new delta packed_usage 33713 33734 +21 .rodata 103670 103672 +2 cp_main 506 500 -6 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 23/-6) Total: 17 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/cp.c130
1 files changed, 71 insertions, 59 deletions
diff --git a/coreutils/cp.c b/coreutils/cp.c
index ac00e09bf..8b9e03c95 100644
--- a/coreutils/cp.c
+++ b/coreutils/cp.c
@@ -37,8 +37,55 @@
37 37
38/* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */ 38/* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */
39 39
40// Options of cp from GNU coreutils 6.10:
41// -a, --archive
42// -f, --force
43// -i, --interactive
44// -l, --link
45// -L, --dereference
46// -P, --no-dereference
47// -R, -r, --recursive
48// -s, --symbolic-link
49// -v, --verbose
50// -H follow command-line symbolic links in SOURCE
51// -d same as --no-dereference --preserve=links
52// -p same as --preserve=mode,ownership,timestamps
53// -c same as --preserve=context
54// -u, --update
55// copy only when the SOURCE file is newer than the destination
56// file or when the destination file is missing
57// --remove-destination
58// remove each existing destination file before attempting to open
59// --parents
60// use full source file name under DIRECTORY
61// -T, --no-target-directory
62// treat DEST as a normal file
63// NOT SUPPORTED IN BBOX:
64// --backup[=CONTROL]
65// make a backup of each existing destination file
66// -b like --backup but does not accept an argument
67// --copy-contents
68// copy contents of special files when recursive
69// --preserve[=ATTR_LIST]
70// preserve attributes (default: mode,ownership,timestamps),
71// if possible additional attributes: security context,links,all
72// --no-preserve=ATTR_LIST
73// --sparse=WHEN
74// control creation of sparse files
75// --strip-trailing-slashes
76// remove any trailing slashes from each SOURCE argument
77// -S, --suffix=SUFFIX
78// override the usual backup suffix
79// -t, --target-directory=DIRECTORY
80// copy all SOURCE arguments into DIRECTORY
81// -x, --one-file-system
82// stay on this file system
83// -Z, --context=CONTEXT
84// (SELinux) set SELinux security context of copy to CONTEXT
85
40//usage:#define cp_trivial_usage 86//usage:#define cp_trivial_usage
41//usage: "[-arPLHpfilsTu] SOURCE... DEST" 87//usage: "[-arPLHpfilsTu] SOURCE DEST\n"
88//usage: "or: cp [-arPLHpfilsu] SOURCE... { -t DIRECTORY | DIRECTORY }"
42//usage:#define cp_full_usage "\n\n" 89//usage:#define cp_full_usage "\n\n"
43//usage: "Copy SOURCEs to DEST\n" 90//usage: "Copy SOURCEs to DEST\n"
44//usage: "\n -a Same as -dpR" 91//usage: "\n -a Same as -dpR"
@@ -53,7 +100,8 @@
53//usage: "\n -f Overwrite" 100//usage: "\n -f Overwrite"
54//usage: "\n -i Prompt before overwrite" 101//usage: "\n -i Prompt before overwrite"
55//usage: "\n -l,-s Create (sym)links" 102//usage: "\n -l,-s Create (sym)links"
56//usage: "\n -T Treat DEST as a normal file" 103//usage: "\n -T Refuse to copy if DEST is a directory"
104//usage: "\n -t DIR Copy all SOURCEs into DIR"
57//usage: "\n -u Copy only newer files" 105//usage: "\n -u Copy only newer files"
58 106
59#include "libbb.h" 107#include "libbb.h"
@@ -73,14 +121,12 @@ int cp_main(int argc, char **argv)
73 int flags; 121 int flags;
74 int status; 122 int status;
75 enum { 123 enum {
76 FILEUTILS_CP_OPTNUM = sizeof(FILEUTILS_CP_OPTSTR)-1,
77#if ENABLE_FEATURE_CP_LONG_OPTIONS 124#if ENABLE_FEATURE_CP_LONG_OPTIONS
78 /*OPT_rmdest = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTNUM */ 125 /*OPT_rmdest = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTNUM */
79 OPT_parents = 1 << (FILEUTILS_CP_OPTNUM+1), 126 OPT_parents = 1 << (FILEUTILS_CP_OPTNUM+1),
80 OPT_reflink = 1 << (FILEUTILS_CP_OPTNUM+2), 127 OPT_reflink = 1 << (FILEUTILS_CP_OPTNUM+2),
81#endif 128#endif
82 }; 129 };
83
84#if ENABLE_FEATURE_CP_LONG_OPTIONS 130#if ENABLE_FEATURE_CP_LONG_OPTIONS
85# if ENABLE_FEATURE_CP_REFLINK 131# if ENABLE_FEATURE_CP_REFLINK
86 char *reflink = NULL; 132 char *reflink = NULL;
@@ -94,7 +140,8 @@ int cp_main(int argc, char **argv)
94 // -r and -R are the same 140 // -r and -R are the same
95 // -R (and therefore -r) turns on -d (coreutils does this) 141 // -R (and therefore -r) turns on -d (coreutils does this)
96 // -a = -pdR 142 // -a = -pdR
97 "-2:l--s:s--l:Pd:rRd:Rd:apdR", 143 /* At least one argument. (Usually two+, but -t DIR can have only one) */
144 "-1:l--s:s--l:Pd:rRd:Rd:apdR",
98 "archive\0" No_argument "a" 145 "archive\0" No_argument "a"
99 "force\0" No_argument "f" 146 "force\0" No_argument "f"
100 "interactive\0" No_argument "i" 147 "interactive\0" No_argument "i"
@@ -110,6 +157,9 @@ int cp_main(int argc, char **argv)
110 "parents\0" No_argument "\xfe" 157 "parents\0" No_argument "\xfe"
111# if ENABLE_FEATURE_CP_REFLINK 158# if ENABLE_FEATURE_CP_REFLINK
112 "reflink\0" Optional_argument "\xfd" 159 "reflink\0" Optional_argument "\xfd"
160# endif
161 , &last
162# if ENABLE_FEATURE_CP_REFLINK
113 , &reflink 163 , &reflink
114# endif 164# endif
115 ); 165 );
@@ -128,55 +178,10 @@ int cp_main(int argc, char **argv)
128 flags = getopt32(argv, "^" 178 flags = getopt32(argv, "^"
129 FILEUTILS_CP_OPTSTR 179 FILEUTILS_CP_OPTSTR
130 "\0" 180 "\0"
131 "-2:l--s:s--l:Pd:rRd:Rd:apdR" 181 "-1:l--s:s--l:Pd:rRd:Rd:apdR"
182 , &last
132 ); 183 );
133#endif 184#endif
134 /* Options of cp from GNU coreutils 6.10:
135 * -a, --archive
136 * -f, --force
137 * -i, --interactive
138 * -l, --link
139 * -L, --dereference
140 * -P, --no-dereference
141 * -R, -r, --recursive
142 * -s, --symbolic-link
143 * -v, --verbose
144 * -H follow command-line symbolic links in SOURCE
145 * -d same as --no-dereference --preserve=links
146 * -p same as --preserve=mode,ownership,timestamps
147 * -c same as --preserve=context
148 * -u, --update
149 * copy only when the SOURCE file is newer than the destination
150 * file or when the destination file is missing
151 * --remove-destination
152 * remove each existing destination file before attempting to open
153 * --parents
154 * use full source file name under DIRECTORY
155 * -T, --no-target-directory
156 * treat DEST as a normal file
157 * NOT SUPPORTED IN BBOX:
158 * --backup[=CONTROL]
159 * make a backup of each existing destination file
160 * -b like --backup but does not accept an argument
161 * --copy-contents
162 * copy contents of special files when recursive
163 * --preserve[=ATTR_LIST]
164 * preserve attributes (default: mode,ownership,timestamps),
165 * if possible additional attributes: security context,links,all
166 * --no-preserve=ATTR_LIST
167 * --sparse=WHEN
168 * control creation of sparse files
169 * --strip-trailing-slashes
170 * remove any trailing slashes from each SOURCE argument
171 * -S, --suffix=SUFFIX
172 * override the usual backup suffix
173 * -t, --target-directory=DIRECTORY
174 * copy all SOURCE arguments into DIRECTORY
175 * -x, --one-file-system
176 * stay on this file system
177 * -Z, --context=CONTEXT
178 * (SELinux) set SELinux security context of copy to CONTEXT
179 */
180 argc -= optind; 185 argc -= optind;
181 argv += optind; 186 argv += optind;
182 /* Reverse this bit. If there is -d, bit is not set: */ 187 /* Reverse this bit. If there is -d, bit is not set: */
@@ -195,15 +200,22 @@ int cp_main(int argc, char **argv)
195#endif 200#endif
196 201
197 status = EXIT_SUCCESS; 202 status = EXIT_SUCCESS;
198 last = argv[argc - 1]; 203 if (!(flags & FILEUTILS_TARGET_DIR)) {
199 /* If there are only two arguments and... */ 204 last = argv[argc - 1];
200 if (argc == 2) { 205 if (argc < 2)
206 bb_show_usage();
207 if (argc != 2) {
208 if (flags & FILEUTILS_NO_TARGET_DIR)
209 bb_show_usage();
210 /* "cp A B C... DIR" - target must be dir */
211 } else /* argc == 2 */ {
212 /* "cp A B" - only case where target can be not a dir */
201 s_flags = cp_mv_stat2(*argv, &source_stat, 213 s_flags = cp_mv_stat2(*argv, &source_stat,
202 (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); 214 (flags & FILEUTILS_DEREFERENCE) ? stat : lstat);
203 if (s_flags < 0) 215 if (s_flags < 0) /* error other than ENOENT */
204 return EXIT_FAILURE; 216 return EXIT_FAILURE;
205 d_flags = cp_mv_stat(last, &dest_stat); 217 d_flags = cp_mv_stat(last, &dest_stat);
206 if (d_flags < 0) 218 if (d_flags < 0) /* error other than ENOENT */
207 return EXIT_FAILURE; 219 return EXIT_FAILURE;
208 220
209 if (flags & FILEUTILS_NO_TARGET_DIR) { /* -T */ 221 if (flags & FILEUTILS_NO_TARGET_DIR) { /* -T */
@@ -235,9 +247,9 @@ int cp_main(int argc, char **argv)
235 dest = last; 247 dest = last;
236 goto DO_COPY; /* NB: argc==2 -> *++argv==last */ 248 goto DO_COPY; /* NB: argc==2 -> *++argv==last */
237 } 249 }
238 } else if (flags & FILEUTILS_NO_TARGET_DIR) { 250 }
239 bb_simple_error_msg_and_die("too many arguments");
240 } 251 }
252 /* else: last is DIR from "t -DIR" */
241 253
242 while (1) { 254 while (1) {
243#if ENABLE_FEATURE_CP_LONG_OPTIONS 255#if ENABLE_FEATURE_CP_LONG_OPTIONS