diff options
Diffstat (limited to 'archival')
-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/decompress_gunzip.c | 5 | ||||
-rw-r--r-- | archival/libarchive/get_header_cpio.c | 7 |
6 files changed, 55 insertions, 16 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 a202069c4..30f66d1f7 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,8 +388,17 @@ 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 | #if ENABLE_PLATFORM_MINGW32 | 404 | #if ENABLE_PLATFORM_MINGW32 |
@@ -379,8 +407,6 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
379 | #endif | 407 | #endif |
380 | } | 408 | } |
381 | #else | 409 | #else |
382 | opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); | ||
383 | argv += optind; | ||
384 | if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */ | 410 | if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */ |
385 | xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); | 411 | xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); |
386 | } | 412 | } |
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/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index dced609e5..b6ae7f738 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -1121,9 +1121,8 @@ static int check_header_gzip(STATE_PARAM transformer_state_t *xstate) | |||
1121 | uint8_t os_flags_UNUSED; | 1121 | uint8_t os_flags_UNUSED; |
1122 | } PACKED formatted; | 1122 | } PACKED formatted; |
1123 | } header; | 1123 | } header; |
1124 | struct BUG_header { | 1124 | |
1125 | char BUG_header[sizeof(header) == 8 ? 1 : -1]; | 1125 | BUILD_BUG_ON(sizeof(header) != 8); |
1126 | }; | ||
1127 | 1126 | ||
1128 | /* | 1127 | /* |
1129 | * Rewind bytebuffer. We use the beginning because the header has 8 | 1128 | * Rewind bytebuffer. We use the beginning because the header has 8 |
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; |