diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-20 22:17:13 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-20 22:17:13 +0000 |
commit | 83518d18a34a3ddfcaac1739930d8469f5bc2442 (patch) | |
tree | 2af665365a69f2689288cc13bb65efbb59e7d520 /archival | |
parent | 0b28103cc774eb1ee62362cf61d52c32d44ec2cf (diff) | |
download | busybox-w32-83518d18a34a3ddfcaac1739930d8469f5bc2442.tar.gz busybox-w32-83518d18a34a3ddfcaac1739930d8469f5bc2442.tar.bz2 busybox-w32-83518d18a34a3ddfcaac1739930d8469f5bc2442.zip |
Compatibility fixes:
grep: support -z
find: support --mindepth
together +45 bytes
cpio: support -p (configurable, +230 bytes)
libbb: tweaks for cpio
Diffstat (limited to 'archival')
-rw-r--r-- | archival/Config.in | 7 | ||||
-rw-r--r-- | archival/cpio.c | 81 |
2 files changed, 72 insertions, 16 deletions
diff --git a/archival/Config.in b/archival/Config.in index 0b5cf3750..64b44c218 100644 --- a/archival/Config.in +++ b/archival/Config.in | |||
@@ -110,6 +110,13 @@ config FEATURE_CPIO_O | |||
110 | This implementation of cpio can create cpio archives in the "newc" | 110 | This implementation of cpio can create cpio archives in the "newc" |
111 | format only. | 111 | format only. |
112 | 112 | ||
113 | config FEATURE_CPIO_P | ||
114 | bool "Support for passthrough mode" | ||
115 | default n | ||
116 | depends on FEATURE_CPIO_O | ||
117 | help | ||
118 | Passthrough mode. Rarely used. | ||
119 | |||
113 | config DPKG | 120 | config DPKG |
114 | bool "dpkg" | 121 | bool "dpkg" |
115 | default n | 122 | default n |
diff --git a/archival/cpio.c b/archival/cpio.c index 1c30d89a8..929d544ff 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -259,8 +259,9 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
259 | CPIO_OPT_FILE = (1 << 4), | 259 | CPIO_OPT_FILE = (1 << 4), |
260 | CPIO_OPT_CREATE_LEADING_DIR = (1 << 5), | 260 | CPIO_OPT_CREATE_LEADING_DIR = (1 << 5), |
261 | CPIO_OPT_PRESERVE_MTIME = (1 << 6), | 261 | CPIO_OPT_PRESERVE_MTIME = (1 << 6), |
262 | CPIO_OPT_CREATE = (1 << 7), | 262 | CPIO_OPT_CREATE = (1 << 7) * ENABLE_FEATURE_CPIO_O, |
263 | CPIO_OPT_FORMAT = (1 << 8), | 263 | CPIO_OPT_FORMAT = (1 << 8) * ENABLE_FEATURE_CPIO_O, |
264 | CPIO_OPT_PASSTHROUGH = (1 << 9) * ENABLE_FEATURE_CPIO_P, | ||
264 | }; | 265 | }; |
265 | 266 | ||
266 | #if ENABLE_GETOPT_LONG | 267 | #if ENABLE_GETOPT_LONG |
@@ -270,21 +271,66 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
270 | #if ENABLE_FEATURE_CPIO_O | 271 | #if ENABLE_FEATURE_CPIO_O |
271 | "create\0" No_argument "o" | 272 | "create\0" No_argument "o" |
272 | "format\0" Required_argument "H" | 273 | "format\0" Required_argument "H" |
274 | #if ENABLE_FEATURE_CPIO_P | ||
275 | "pass-through\0" No_argument "p" | ||
276 | #endif | ||
273 | #endif | 277 | #endif |
274 | ; | 278 | ; |
275 | #endif | 279 | #endif |
276 | 280 | ||
277 | /* Initialize */ | 281 | /* As of now we do not enforce this: */ |
278 | archive_handle = init_handle(); | 282 | /* -i,-t,-o,-p are mutually exclusive */ |
279 | archive_handle->src_fd = STDIN_FILENO; | 283 | /* -u,-d,-m make sense only with -i or -p */ |
280 | archive_handle->seek = seek_by_read; | 284 | /* -F makes sense only with -o */ |
281 | archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER; | 285 | #if !ENABLE_FEATURE_CPIO_O |
282 | 286 | opt = getopt32(argv, "ituvF:dm", &cpio_filename); | |
283 | #if ENABLE_FEATURE_CPIO_O | 287 | #else |
284 | opt = getopt32(argv, "ituvF:dmoH:", &cpio_filename, &cpio_fmt); | 288 | opt = getopt32(argv, "ituvF:dmoH:" USE_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); |
289 | if (opt & CPIO_OPT_PASSTHROUGH) { | ||
290 | pid_t pid; | ||
291 | struct fd_pair pp; | ||
285 | 292 | ||
293 | if (argv[optind] == NULL) | ||
294 | bb_show_usage(); | ||
295 | if (opt & CPIO_OPT_CREATE_LEADING_DIR) | ||
296 | mkdir(argv[optind], 0777); | ||
297 | /* Crude existence check: | ||
298 | * close(xopen(argv[optind], O_RDONLY | O_DIRECTORY)); | ||
299 | * We can also xopen, fstat, IS_DIR, later fchdir. | ||
300 | * This would check for existence earlier and cleaner. | ||
301 | * As it stands now, if we fail xchdir later, | ||
302 | * child dies on EPIPE, unless it caught | ||
303 | * a diffrerent problem earlier. | ||
304 | * This is good enough for now. | ||
305 | */ | ||
306 | #if !BB_MMU | ||
307 | pp.rd = 3; | ||
308 | pp.wr = 4; | ||
309 | if (!re_execed) { | ||
310 | close(3); | ||
311 | close(4); | ||
312 | xpiped_pair(pp); | ||
313 | } | ||
314 | #else | ||
315 | xpiped_pair(pp); | ||
316 | #endif | ||
317 | pid = fork_or_rexec(argv); | ||
318 | if (pid == 0) { /* child */ | ||
319 | close(pp.rd); | ||
320 | xmove_fd(pp.wr, STDOUT_FILENO); | ||
321 | goto dump; | ||
322 | } | ||
323 | /* parent */ | ||
324 | xchdir(argv[optind++]); | ||
325 | close(pp.wr); | ||
326 | xmove_fd(pp.rd, STDIN_FILENO); | ||
327 | opt &= ~CPIO_OPT_PASSTHROUGH; | ||
328 | opt |= CPIO_OPT_EXTRACT; | ||
329 | goto skip; | ||
330 | } | ||
331 | /* -o */ | ||
286 | if (opt & CPIO_OPT_CREATE) { | 332 | if (opt & CPIO_OPT_CREATE) { |
287 | if (*cpio_fmt != 'n') | 333 | if (*cpio_fmt != 'n') /* we _require_ "-H newc" */ |
288 | bb_show_usage(); | 334 | bb_show_usage(); |
289 | if (opt & CPIO_OPT_FILE) { | 335 | if (opt & CPIO_OPT_FILE) { |
290 | fclose(stdout); | 336 | fclose(stdout); |
@@ -292,13 +338,18 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
292 | /* Paranoia: I don't trust libc that much */ | 338 | /* Paranoia: I don't trust libc that much */ |
293 | xdup2(fileno(stdout), STDOUT_FILENO); | 339 | xdup2(fileno(stdout), STDOUT_FILENO); |
294 | } | 340 | } |
341 | dump: | ||
295 | return cpio_o(); | 342 | return cpio_o(); |
296 | } | 343 | } |
297 | #else | 344 | skip: |
298 | opt = getopt32(argv, "ituvF:dm", &cpio_filename); | ||
299 | #endif | 345 | #endif |
300 | argv += optind; | 346 | argv += optind; |
301 | 347 | ||
348 | archive_handle = init_handle(); | ||
349 | archive_handle->src_fd = STDIN_FILENO; | ||
350 | archive_handle->seek = seek_by_read; | ||
351 | archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER; | ||
352 | |||
302 | /* One of either extract or test options must be given */ | 353 | /* One of either extract or test options must be given */ |
303 | if ((opt & (CPIO_OPT_TEST | CPIO_OPT_EXTRACT)) == 0) { | 354 | if ((opt & (CPIO_OPT_TEST | CPIO_OPT_EXTRACT)) == 0) { |
304 | bb_show_usage(); | 355 | bb_show_usage(); |
@@ -306,9 +357,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
306 | 357 | ||
307 | if (opt & CPIO_OPT_TEST) { | 358 | if (opt & CPIO_OPT_TEST) { |
308 | /* if both extract and test options are given, ignore extract option */ | 359 | /* if both extract and test options are given, ignore extract option */ |
309 | if (opt & CPIO_OPT_EXTRACT) { | 360 | opt &= ~CPIO_OPT_EXTRACT; |
310 | opt &= ~CPIO_OPT_EXTRACT; | ||
311 | } | ||
312 | archive_handle->action_header = header_list; | 361 | archive_handle->action_header = header_list; |
313 | } | 362 | } |
314 | if (opt & CPIO_OPT_EXTRACT) { | 363 | if (opt & CPIO_OPT_EXTRACT) { |