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 | ||
