diff options
author | Aaro Koskinen <aaro.koskinen@iki.fi> | 2015-10-16 17:24:46 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-10-16 17:24:46 +0200 |
commit | 2735bc00e35c5fd8eec6d656f4d8a17ee2630c2a (patch) | |
tree | a04c7e75f1363e431431c24dc36549a5ff7e9595 | |
parent | 93dd9fd90ae284e7878767fe14bcb17e3edd9cf8 (diff) | |
download | busybox-w32-2735bc00e35c5fd8eec6d656f4d8a17ee2630c2a.tar.gz busybox-w32-2735bc00e35c5fd8eec6d656f4d8a17ee2630c2a.tar.bz2 busybox-w32-2735bc00e35c5fd8eec6d656f4d8a17ee2630c2a.zip |
cpio: implement -R/--owner
Implement -R/--owner to force ownership of files.
function old new delta
cpio_main 532 586 +54
get_header_cpio 909 939 +30
print 36 65 +29
cpio_o 804 832 +28
cpio_TRAILER - 11 +11
packed_usage 30667 30662 -5
static.trailer 11 - -11
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 4/1 up/down: 152/-16) Total: 136 bytes
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/Kbuild.src | 2 | ||||
-rw-r--r-- | archival/cpio.c | 46 | ||||
-rw-r--r-- | archival/libarchive/Kbuild.src | 2 | ||||
-rw-r--r-- | archival/libarchive/common.c | 9 | ||||
-rw-r--r-- | archival/libarchive/get_header_cpio.c | 7 | ||||
-rw-r--r-- | coreutils/chown.c | 4 | ||||
-rw-r--r-- | include/bb_archive.h | 3 |
7 files changed, 58 insertions, 15 deletions
diff --git a/archival/Kbuild.src b/archival/Kbuild.src index a6fd2eac0..b3a7d538f 100644 --- a/archival/Kbuild.src +++ b/archival/Kbuild.src | |||
@@ -4,7 +4,7 @@ | |||
4 | # | 4 | # |
5 | # Licensed under GPLv2, see file LICENSE in this source tree. | 5 | # Licensed under GPLv2, see file LICENSE in this source tree. |
6 | 6 | ||
7 | libs-y += libarchive/ | 7 | libs-y += libarchive/ |
8 | 8 | ||
9 | lib-y:= | 9 | lib-y:= |
10 | 10 | ||
diff --git a/archival/cpio.c b/archival/cpio.c index cdc16c14e..82b3fe5ed 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -46,7 +46,7 @@ | |||
46 | //kbuild:lib-$(CONFIG_CPIO) += cpio.o | 46 | //kbuild:lib-$(CONFIG_CPIO) += cpio.o |
47 | 47 | ||
48 | //usage:#define cpio_trivial_usage | 48 | //usage:#define cpio_trivial_usage |
49 | //usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]") | 49 | //usage: "[-dmvu] [-F FILE] [-R USER[:GRP]]" IF_FEATURE_CPIO_O(" [-H newc]") |
50 | //usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]") | 50 | //usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]") |
51 | //usage: " [EXTR_FILE]..." | 51 | //usage: " [EXTR_FILE]..." |
52 | //usage:#define cpio_full_usage "\n\n" | 52 | //usage:#define cpio_full_usage "\n\n" |
@@ -71,6 +71,7 @@ | |||
71 | //usage: "\n -v Verbose" | 71 | //usage: "\n -v Verbose" |
72 | //usage: "\n -u Overwrite" | 72 | //usage: "\n -u Overwrite" |
73 | //usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file" | 73 | //usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file" |
74 | //usage: "\n -R USER[:GRP] Set owner of created files" | ||
74 | //usage: IF_FEATURE_CPIO_O( | 75 | //usage: IF_FEATURE_CPIO_O( |
75 | //usage: "\n -H newc Archive format" | 76 | //usage: "\n -H newc Archive format" |
76 | //usage: ) | 77 | //usage: ) |
@@ -130,7 +131,7 @@ | |||
130 | -I FILE File to use instead of standard input | 131 | -I FILE File to use instead of standard input |
131 | -L, --dereference Dereference symbolic links (copy the files | 132 | -L, --dereference Dereference symbolic links (copy the files |
132 | that they point to instead of copying the links) | 133 | that they point to instead of copying the links) |
133 | -R, --owner=[USER][:.][GROUP] Set owner of created files | 134 | -R, --owner=[USER][:.][GRP] Set owner of created files |
134 | 135 | ||
135 | Options valid in --extract and --pass-through modes: | 136 | Options valid in --extract and --pass-through modes: |
136 | -d, --make-directories Create leading directories where needed | 137 | -d, --make-directories Create leading directories where needed |
@@ -150,7 +151,8 @@ enum { | |||
150 | OPT_PRESERVE_MTIME = (1 << 6), | 151 | OPT_PRESERVE_MTIME = (1 << 6), |
151 | OPT_DEREF = (1 << 7), | 152 | OPT_DEREF = (1 << 7), |
152 | OPT_FILE = (1 << 8), | 153 | OPT_FILE = (1 << 8), |
153 | OPTBIT_FILE = 8, | 154 | OPT_OWNER = (1 << 9), |
155 | OPTBIT_OWNER = 9, | ||
154 | IF_FEATURE_CPIO_O(OPTBIT_CREATE ,) | 156 | IF_FEATURE_CPIO_O(OPTBIT_CREATE ,) |
155 | IF_FEATURE_CPIO_O(OPTBIT_FORMAT ,) | 157 | IF_FEATURE_CPIO_O(OPTBIT_FORMAT ,) |
156 | IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,) | 158 | IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,) |
@@ -163,7 +165,17 @@ enum { | |||
163 | OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0, | 165 | OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0, |
164 | }; | 166 | }; |
165 | 167 | ||
166 | #define OPTION_STR "it0uvdmLF:" | 168 | #define OPTION_STR "it0uvdmLF:R:" |
169 | |||
170 | struct globals { | ||
171 | struct bb_uidgid_t owner_ugid; | ||
172 | } FIX_ALIASING; | ||
173 | #define G (*(struct globals*)&bb_common_bufsiz1) | ||
174 | void BUG_cpio_globals_too_big(void); | ||
175 | #define INIT_G() do { \ | ||
176 | G.owner_ugid.uid = -1L; \ | ||
177 | G.owner_ugid.gid = -1L; \ | ||
178 | } while (0) | ||
167 | 179 | ||
168 | #if ENABLE_FEATURE_CPIO_O | 180 | #if ENABLE_FEATURE_CPIO_O |
169 | static off_t cpio_pad4(off_t size) | 181 | static off_t cpio_pad4(off_t size) |
@@ -181,7 +193,6 @@ static off_t cpio_pad4(off_t size) | |||
181 | * It's ok to exit instead of return. */ | 193 | * It's ok to exit instead of return. */ |
182 | static NOINLINE int cpio_o(void) | 194 | static NOINLINE int cpio_o(void) |
183 | { | 195 | { |
184 | static const char trailer[] ALIGN1 = "TRAILER!!!"; | ||
185 | struct name_s { | 196 | struct name_s { |
186 | struct name_s *next; | 197 | struct name_s *next; |
187 | char name[1]; | 198 | char name[1]; |
@@ -223,6 +234,11 @@ static NOINLINE int cpio_o(void) | |||
223 | bb_simple_perror_msg_and_die(name); | 234 | bb_simple_perror_msg_and_die(name); |
224 | } | 235 | } |
225 | 236 | ||
237 | if (G.owner_ugid.uid != (uid_t)-1L) | ||
238 | st.st_uid = G.owner_ugid.uid; | ||
239 | if (G.owner_ugid.gid != (gid_t)-1L) | ||
240 | st.st_gid = G.owner_ugid.gid; | ||
241 | |||
226 | if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode))) | 242 | if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode))) |
227 | st.st_size = 0; /* paranoia */ | 243 | st.st_size = 0; /* paranoia */ |
228 | 244 | ||
@@ -275,7 +291,7 @@ static NOINLINE int cpio_o(void) | |||
275 | } else { | 291 | } else { |
276 | /* If no (more) hardlinks to output, | 292 | /* If no (more) hardlinks to output, |
277 | * output "trailer" entry */ | 293 | * output "trailer" entry */ |
278 | name = trailer; | 294 | name = cpio_TRAILER; |
279 | /* st.st_size == 0 is a must, but for uniformity | 295 | /* st.st_size == 0 is a must, but for uniformity |
280 | * in the output, we zero out everything */ | 296 | * in the output, we zero out everything */ |
281 | memset(&st, 0, sizeof(st)); | 297 | memset(&st, 0, sizeof(st)); |
@@ -323,7 +339,7 @@ static NOINLINE int cpio_o(void) | |||
323 | } | 339 | } |
324 | 340 | ||
325 | if (!line) { | 341 | if (!line) { |
326 | if (name != trailer) | 342 | if (name != cpio_TRAILER) |
327 | goto next_link; | 343 | goto next_link; |
328 | /* TODO: GNU cpio pads trailer to 512 bytes, do we want that? */ | 344 | /* TODO: GNU cpio pads trailer to 512 bytes, do we want that? */ |
329 | return EXIT_SUCCESS; | 345 | return EXIT_SUCCESS; |
@@ -339,6 +355,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
339 | { | 355 | { |
340 | archive_handle_t *archive_handle; | 356 | archive_handle_t *archive_handle; |
341 | char *cpio_filename; | 357 | char *cpio_filename; |
358 | char *cpio_owner; | ||
342 | IF_FEATURE_CPIO_O(const char *cpio_fmt = "";) | 359 | IF_FEATURE_CPIO_O(const char *cpio_fmt = "";) |
343 | unsigned opt; | 360 | unsigned opt; |
344 | 361 | ||
@@ -353,12 +370,14 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
353 | "pass-through\0" No_argument "p" | 370 | "pass-through\0" No_argument "p" |
354 | #endif | 371 | #endif |
355 | #endif | 372 | #endif |
373 | "owner\0" Required_argument "R" | ||
356 | "verbose\0" No_argument "v" | 374 | "verbose\0" No_argument "v" |
357 | "quiet\0" No_argument "\xff" | 375 | "quiet\0" No_argument "\xff" |
358 | "to-stdout\0" No_argument "\xfe" | 376 | "to-stdout\0" No_argument "\xfe" |
359 | ; | 377 | ; |
360 | #endif | 378 | #endif |
361 | 379 | ||
380 | INIT_G(); | ||
362 | archive_handle = init_handle(); | 381 | archive_handle = init_handle(); |
363 | /* archive_handle->src_fd = STDIN_FILENO; - done by init_handle */ | 382 | /* archive_handle->src_fd = STDIN_FILENO; - done by init_handle */ |
364 | archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER; | 383 | archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER; |
@@ -369,14 +388,21 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
369 | /* -L makes sense only with -o or -p */ | 388 | /* -L makes sense only with -o or -p */ |
370 | 389 | ||
371 | #if !ENABLE_FEATURE_CPIO_O | 390 | #if !ENABLE_FEATURE_CPIO_O |
372 | opt = getopt32(argv, OPTION_STR, &cpio_filename); | 391 | opt = getopt32(argv, OPTION_STR, &cpio_filename, &cpio_owner); |
392 | #else | ||
393 | opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), | ||
394 | &cpio_filename, &cpio_owner, &cpio_fmt); | ||
395 | #endif | ||
373 | argv += optind; | 396 | argv += optind; |
397 | if (opt & OPT_OWNER) { /* -R */ | ||
398 | parse_chown_usergroup_or_die(&G.owner_ugid, cpio_owner); | ||
399 | archive_handle->cpio__owner = G.owner_ugid; | ||
400 | } | ||
401 | #if !ENABLE_FEATURE_CPIO_O | ||
374 | if (opt & OPT_FILE) { /* -F */ | 402 | if (opt & OPT_FILE) { /* -F */ |
375 | xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); | 403 | xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); |
376 | } | 404 | } |
377 | #else | 405 | #else |
378 | opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); | ||
379 | argv += optind; | ||
380 | if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */ | 406 | if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */ |
381 | xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); | 407 | xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); |
382 | } | 408 | } |
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index b7faaf77f..b159a786a 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src | |||
@@ -4,7 +4,7 @@ | |||
4 | # | 4 | # |
5 | # Licensed under GPLv2 or later, see file LICENSE in this source tree. | 5 | # Licensed under GPLv2 or later, see file LICENSE in this source tree. |
6 | 6 | ||
7 | lib-y:= | 7 | lib-y:= common.o |
8 | 8 | ||
9 | COMMON_FILES:= \ | 9 | COMMON_FILES:= \ |
10 | \ | 10 | \ |
diff --git a/archival/libarchive/common.c b/archival/libarchive/common.c new file mode 100644 index 000000000..dd69d2222 --- /dev/null +++ b/archival/libarchive/common.c | |||
@@ -0,0 +1,9 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
4 | */ | ||
5 | |||
6 | #include "libbb.h" | ||
7 | #include "bb_archive.h" | ||
8 | |||
9 | const char cpio_TRAILER[] = "TRAILER!!!"; | ||
diff --git a/archival/libarchive/get_header_cpio.c b/archival/libarchive/get_header_cpio.c index 7861d1f6f..badd4a841 100644 --- a/archival/libarchive/get_header_cpio.c +++ b/archival/libarchive/get_header_cpio.c | |||
@@ -52,6 +52,11 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) | |||
52 | &major, &minor, &namesize) != 10) | 52 | &major, &minor, &namesize) != 10) |
53 | bb_error_msg_and_die("damaged cpio file"); | 53 | bb_error_msg_and_die("damaged cpio file"); |
54 | file_header->mode = mode; | 54 | file_header->mode = mode; |
55 | /* "cpio -R USER:GRP" support: */ | ||
56 | if (archive_handle->cpio__owner.uid != (uid_t)-1L) | ||
57 | uid = archive_handle->cpio__owner.uid; | ||
58 | if (archive_handle->cpio__owner.gid != (gid_t)-1L) | ||
59 | gid = archive_handle->cpio__owner.gid; | ||
55 | file_header->uid = uid; | 60 | file_header->uid = uid; |
56 | file_header->gid = gid; | 61 | file_header->gid = gid; |
57 | file_header->mtime = mtime; | 62 | file_header->mtime = mtime; |
@@ -75,7 +80,7 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) | |||
75 | /* Update offset amount and skip padding before file contents */ | 80 | /* Update offset amount and skip padding before file contents */ |
76 | data_align(archive_handle, 4); | 81 | data_align(archive_handle, 4); |
77 | 82 | ||
78 | if (strcmp(file_header->name, "TRAILER!!!") == 0) { | 83 | if (strcmp(file_header->name, cpio_TRAILER) == 0) { |
79 | /* Always round up. ">> 9" divides by 512 */ | 84 | /* Always round up. ">> 9" divides by 512 */ |
80 | archive_handle->cpio__blocks = (uoff_t)(archive_handle->offset + 511) >> 9; | 85 | archive_handle->cpio__blocks = (uoff_t)(archive_handle->offset + 511) >> 9; |
81 | goto create_hardlinks; | 86 | goto create_hardlinks; |
diff --git a/coreutils/chown.c b/coreutils/chown.c index 679c0d832..eaa1ee2a3 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c | |||
@@ -11,9 +11,9 @@ | |||
11 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */ | 11 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */ |
12 | 12 | ||
13 | //usage:#define chown_trivial_usage | 13 | //usage:#define chown_trivial_usage |
14 | //usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... OWNER[<.|:>[GROUP]] FILE..." | 14 | //usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... USER[:[GRP]] FILE..." |
15 | //usage:#define chown_full_usage "\n\n" | 15 | //usage:#define chown_full_usage "\n\n" |
16 | //usage: "Change the owner and/or group of each FILE to OWNER and/or GROUP\n" | 16 | //usage: "Change the owner and/or group of each FILE to USER and/or GRP\n" |
17 | //usage: "\n -R Recurse" | 17 | //usage: "\n -R Recurse" |
18 | //usage: "\n -h Affect symlinks instead of symlink targets" | 18 | //usage: "\n -h Affect symlinks instead of symlink targets" |
19 | //usage: IF_DESKTOP( | 19 | //usage: IF_DESKTOP( |
diff --git a/include/bb_archive.h b/include/bb_archive.h index 5d9e24c17..2329d025d 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h | |||
@@ -95,6 +95,7 @@ typedef struct archive_handle_t { | |||
95 | #endif | 95 | #endif |
96 | #if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM | 96 | #if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM |
97 | uoff_t cpio__blocks; | 97 | uoff_t cpio__blocks; |
98 | struct bb_uidgid_t cpio__owner; | ||
98 | struct hardlinks_t *cpio__hardlinks_to_create; | 99 | struct hardlinks_t *cpio__hardlinks_to_create; |
99 | struct hardlinks_t *cpio__created_hardlinks; | 100 | struct hardlinks_t *cpio__created_hardlinks; |
100 | #endif | 101 | #endif |
@@ -159,6 +160,8 @@ struct BUG_tar_header { | |||
159 | }; | 160 | }; |
160 | 161 | ||
161 | 162 | ||
163 | extern const char cpio_TRAILER[]; | ||
164 | |||
162 | 165 | ||
163 | archive_handle_t *init_handle(void) FAST_FUNC; | 166 | archive_handle_t *init_handle(void) FAST_FUNC; |
164 | 167 | ||