diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2012-06-15 16:43:26 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2012-06-15 16:43:26 +0200 |
commit | c5b01016e622f01dfa9c8c542c0968fe37d4a5f2 (patch) | |
tree | e45679f07399c053c71f0d3a9b08ef74ce38239b | |
parent | 604499e5a93d8055a761e968b12d6a0907bc3d0a (diff) | |
download | busybox-w32-c5b01016e622f01dfa9c8c542c0968fe37d4a5f2.tar.gz busybox-w32-c5b01016e622f01dfa9c8c542c0968fe37d4a5f2.tar.bz2 busybox-w32-c5b01016e622f01dfa9c8c542c0968fe37d4a5f2.zip |
unzip: make options parsing more robust on getopt w/o gnu extensions
Also, code shrank:
function old new delta
static.extn 15 10 -5
packed_usage 29231 29217 -14
unzip_main 2388 2291 -97
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-116) Total: -116 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/unzip.c | 137 |
1 files changed, 70 insertions, 67 deletions
diff --git a/archival/unzip.c b/archival/unzip.c index c1b945a44..380674701 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -20,11 +20,11 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | //usage:#define unzip_trivial_usage | 22 | //usage:#define unzip_trivial_usage |
23 | //usage: "[-opts[modifiers]] FILE[.zip] [LIST] [-x XLIST] [-d DIR]" | 23 | //usage: "[-lnopq] FILE[.zip] [LIST] [-x XLIST] [-d DIR]" |
24 | //usage:#define unzip_full_usage "\n\n" | 24 | //usage:#define unzip_full_usage "\n\n" |
25 | //usage: "Extract files from ZIP archives\n" | 25 | //usage: "Extract files from ZIP archives\n" |
26 | //usage: "\n -l List archive contents (with -q for short form)" | 26 | //usage: "\n -l List archive contents (with -q for short form)" |
27 | //usage: "\n -n Never overwrite files (default)" | 27 | //usage: "\n -n Never overwrite files (default: ask)" |
28 | //usage: "\n -o Overwrite" | 28 | //usage: "\n -o Overwrite" |
29 | //usage: "\n -p Send output to stdout" | 29 | //usage: "\n -p Send output to stdout" |
30 | //usage: "\n -q Quiet" | 30 | //usage: "\n -q Quiet" |
@@ -277,6 +277,7 @@ int unzip_main(int argc, char **argv) | |||
277 | IF_NOT_DESKTOP(const) smallint verbose = 0; | 277 | IF_NOT_DESKTOP(const) smallint verbose = 0; |
278 | smallint listing = 0; | 278 | smallint listing = 0; |
279 | smallint overwrite = O_PROMPT; | 279 | smallint overwrite = O_PROMPT; |
280 | smallint x_opt_seen; | ||
280 | #if ENABLE_DESKTOP | 281 | #if ENABLE_DESKTOP |
281 | uint32_t cdf_offset; | 282 | uint32_t cdf_offset; |
282 | #endif | 283 | #endif |
@@ -290,7 +291,6 @@ int unzip_main(int argc, char **argv) | |||
290 | llist_t *zreject = NULL; | 291 | llist_t *zreject = NULL; |
291 | char *base_dir = NULL; | 292 | char *base_dir = NULL; |
292 | int i, opt; | 293 | int i, opt; |
293 | int opt_range = 0; | ||
294 | char key_buf[80]; | 294 | char key_buf[80]; |
295 | struct stat stat_buf; | 295 | struct stat stat_buf; |
296 | 296 | ||
@@ -335,81 +335,81 @@ int unzip_main(int argc, char **argv) | |||
335 | * 204372 1 file | 335 | * 204372 1 file |
336 | */ | 336 | */ |
337 | 337 | ||
338 | x_opt_seen = 0; | ||
338 | /* '-' makes getopt return 1 for non-options */ | 339 | /* '-' makes getopt return 1 for non-options */ |
339 | while ((opt = getopt(argc, argv, "-d:lnopqxv")) != -1) { | 340 | while ((opt = getopt(argc, argv, "-d:lnopqxv")) != -1) { |
340 | switch (opt_range) { | 341 | switch (opt) { |
341 | case 0: /* Options */ | 342 | case 'd': /* Extract to base directory */ |
342 | switch (opt) { | 343 | base_dir = optarg; |
343 | case 'l': /* List */ | 344 | break; |
344 | listing = 1; | ||
345 | break; | ||
346 | 345 | ||
347 | case 'n': /* Never overwrite existing files */ | 346 | case 'l': /* List */ |
348 | overwrite = O_NEVER; | 347 | listing = 1; |
349 | break; | 348 | break; |
350 | 349 | ||
351 | case 'o': /* Always overwrite existing files */ | 350 | case 'n': /* Never overwrite existing files */ |
352 | overwrite = O_ALWAYS; | 351 | overwrite = O_NEVER; |
353 | break; | 352 | break; |
354 | 353 | ||
355 | case 'p': /* Extract files to stdout and fall through to set verbosity */ | 354 | case 'o': /* Always overwrite existing files */ |
356 | dst_fd = STDOUT_FILENO; | 355 | overwrite = O_ALWAYS; |
356 | break; | ||
357 | 357 | ||
358 | case 'q': /* Be quiet */ | 358 | case 'p': /* Extract files to stdout and fall through to set verbosity */ |
359 | quiet++; | 359 | dst_fd = STDOUT_FILENO; |
360 | break; | ||
361 | 360 | ||
362 | case 'v': /* Verbose list */ | 361 | case 'q': /* Be quiet */ |
363 | IF_DESKTOP(verbose++;) | 362 | quiet++; |
364 | listing = 1; | 363 | break; |
365 | break; | ||
366 | 364 | ||
367 | case 1: /* The zip file */ | 365 | case 'v': /* Verbose list */ |
368 | /* +5: space for ".zip" and NUL */ | 366 | IF_DESKTOP(verbose++;) |
369 | src_fn = xmalloc(strlen(optarg) + 5); | 367 | listing = 1; |
370 | strcpy(src_fn, optarg); | 368 | break; |
371 | opt_range++; | ||
372 | break; | ||
373 | 369 | ||
374 | default: | 370 | case 'x': |
375 | bb_show_usage(); | 371 | x_opt_seen = 1; |
376 | } | ||
377 | break; | 372 | break; |
378 | 373 | ||
379 | case 1: /* Include files */ | 374 | case 1: |
380 | if (opt == 1) { | 375 | if (!src_fn) { |
376 | /* The zip file */ | ||
377 | /* +5: space for ".zip" and NUL */ | ||
378 | src_fn = xmalloc(strlen(optarg) + 5); | ||
379 | strcpy(src_fn, optarg); | ||
380 | } else if (!x_opt_seen) { | ||
381 | /* Include files */ | ||
381 | llist_add_to(&zaccept, optarg); | 382 | llist_add_to(&zaccept, optarg); |
382 | break; | 383 | } else { |
383 | } | 384 | /* Exclude files */ |
384 | if (opt == 'd') { | ||
385 | base_dir = optarg; | ||
386 | opt_range += 2; | ||
387 | break; | ||
388 | } | ||
389 | if (opt == 'x') { | ||
390 | opt_range++; | ||
391 | break; | ||
392 | } | ||
393 | bb_show_usage(); | ||
394 | |||
395 | case 2 : /* Exclude files */ | ||
396 | if (opt == 1) { | ||
397 | llist_add_to(&zreject, optarg); | 385 | llist_add_to(&zreject, optarg); |
398 | break; | ||
399 | } | 386 | } |
400 | if (opt == 'd') { /* Extract to base directory */ | 387 | break; |
401 | base_dir = optarg; | ||
402 | opt_range++; | ||
403 | break; | ||
404 | } | ||
405 | /* fall through */ | ||
406 | 388 | ||
407 | default: | 389 | default: |
408 | bb_show_usage(); | 390 | bb_show_usage(); |
409 | } | 391 | } |
410 | } | 392 | } |
411 | 393 | ||
412 | if (src_fn == NULL) { | 394 | #ifndef __GLIBC__ |
395 | /* | ||
396 | * This code is needed for non-GNU getopt | ||
397 | * which doesn't understand "-" in option string. | ||
398 | * The -x option won't work properly in this case: | ||
399 | * "unzip a.zip q -x w e" will be interpreted as | ||
400 | * "unzip a.zip q w e -x" = "unzip a.zip q w e" | ||
401 | */ | ||
402 | argv += optind; | ||
403 | if (argv[0]) { | ||
404 | /* +5: space for ".zip" and NUL */ | ||
405 | src_fn = xmalloc(strlen(argv[0]) + 5); | ||
406 | strcpy(src_fn, argv[0]); | ||
407 | while (*++argv) | ||
408 | llist_add_to(&zaccept, *argv); | ||
409 | } | ||
410 | #endif | ||
411 | |||
412 | if (!src_fn) { | ||
413 | bb_show_usage(); | 413 | bb_show_usage(); |
414 | } | 414 | } |
415 | 415 | ||
@@ -420,17 +420,20 @@ int unzip_main(int argc, char **argv) | |||
420 | if (overwrite == O_PROMPT) | 420 | if (overwrite == O_PROMPT) |
421 | overwrite = O_NEVER; | 421 | overwrite = O_NEVER; |
422 | } else { | 422 | } else { |
423 | static const char extn[][5] = {"", ".zip", ".ZIP"}; | 423 | static const char extn[][5] = { ".zip", ".ZIP" }; |
424 | int orig_src_fn_len = strlen(src_fn); | 424 | char *ext = src_fn + strlen(src_fn); |
425 | int src_fd = -1; | 425 | int src_fd; |
426 | 426 | ||
427 | for (i = 0; (i < 3) && (src_fd == -1); i++) { | 427 | i = 0; |
428 | strcpy(src_fn + orig_src_fn_len, extn[i]); | 428 | for (;;) { |
429 | src_fd = open(src_fn, O_RDONLY); | 429 | src_fd = open(src_fn, O_RDONLY); |
430 | } | 430 | if (src_fd >= 0) |
431 | if (src_fd == -1) { | 431 | break; |
432 | src_fn[orig_src_fn_len] = '\0'; | 432 | if (++i > 2) { |
433 | bb_error_msg_and_die("can't open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); | 433 | *ext = '\0'; |
434 | bb_error_msg_and_die("can't open %s[.zip]", src_fn); | ||
435 | } | ||
436 | strcpy(ext, extn[i - 1]); | ||
434 | } | 437 | } |
435 | xmove_fd(src_fd, zip_fd); | 438 | xmove_fd(src_fd, zip_fd); |
436 | } | 439 | } |