diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-20 20:04:49 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-20 20:04:49 +0200 |
commit | 997ad2c64abbe931dffa3598b015c5de04e515cf (patch) | |
tree | 808dadf75484b464d6b55e06624ff2007f33ed02 | |
parent | bff9bbc73fce9a3886992f413fb18fe78c007cbb (diff) | |
download | busybox-w32-997ad2c64abbe931dffa3598b015c5de04e515cf.tar.gz busybox-w32-997ad2c64abbe931dffa3598b015c5de04e515cf.tar.bz2 busybox-w32-997ad2c64abbe931dffa3598b015c5de04e515cf.zip |
unzip: implement -j, closes 9126
function old new delta
unzip_main 2642 2703 +61
packed_usage 31747 31770 +23
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 84/0) Total: 84 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/unzip.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/archival/unzip.c b/archival/unzip.c index 21ba172b5..d5bca08d4 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -62,6 +62,7 @@ | |||
62 | //usage: "\n -l List contents (with -q for short form)" | 62 | //usage: "\n -l List contents (with -q for short form)" |
63 | //usage: "\n -n Never overwrite files (default: ask)" | 63 | //usage: "\n -n Never overwrite files (default: ask)" |
64 | //usage: "\n -o Overwrite" | 64 | //usage: "\n -o Overwrite" |
65 | //usage: "\n -j Do not restore paths" | ||
65 | //usage: "\n -p Print to stdout" | 66 | //usage: "\n -p Print to stdout" |
66 | //usage: "\n -q Quiet" | 67 | //usage: "\n -q Quiet" |
67 | //usage: "\n -x FILE Exclude FILEs" | 68 | //usage: "\n -x FILE Exclude FILEs" |
@@ -455,13 +456,16 @@ static int get_lstat_mode(const char *dst_fn) | |||
455 | int unzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 456 | int unzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
456 | int unzip_main(int argc, char **argv) | 457 | int unzip_main(int argc, char **argv) |
457 | { | 458 | { |
458 | enum { O_PROMPT, O_NEVER, O_ALWAYS }; | 459 | enum { |
459 | 460 | OPT_l = (1 << 0), | |
461 | OPT_x = (1 << 1), | ||
462 | OPT_j = (1 << 2), | ||
463 | }; | ||
464 | unsigned opts; | ||
460 | smallint quiet = 0; | 465 | smallint quiet = 0; |
461 | IF_NOT_FEATURE_UNZIP_CDF(const) smallint verbose = 0; | 466 | IF_NOT_FEATURE_UNZIP_CDF(const) smallint verbose = 0; |
462 | smallint listing = 0; | 467 | enum { O_PROMPT, O_NEVER, O_ALWAYS }; |
463 | smallint overwrite = O_PROMPT; | 468 | smallint overwrite = O_PROMPT; |
464 | smallint x_opt_seen; | ||
465 | uint32_t cdf_offset; | 469 | uint32_t cdf_offset; |
466 | unsigned long total_usize; | 470 | unsigned long total_usize; |
467 | unsigned long total_size; | 471 | unsigned long total_size; |
@@ -472,7 +476,7 @@ int unzip_main(int argc, char **argv) | |||
472 | llist_t *zaccept = NULL; | 476 | llist_t *zaccept = NULL; |
473 | llist_t *zreject = NULL; | 477 | llist_t *zreject = NULL; |
474 | char *base_dir = NULL; | 478 | char *base_dir = NULL; |
475 | int i, opt; | 479 | int i; |
476 | char key_buf[80]; /* must match size used by my_fgets80 */ | 480 | char key_buf[80]; /* must match size used by my_fgets80 */ |
477 | 481 | ||
478 | /* -q, -l and -v: UnZip 5.52 of 28 February 2005, by Info-ZIP: | 482 | /* -q, -l and -v: UnZip 5.52 of 28 February 2005, by Info-ZIP: |
@@ -516,16 +520,16 @@ int unzip_main(int argc, char **argv) | |||
516 | * 204372 1 file | 520 | * 204372 1 file |
517 | */ | 521 | */ |
518 | 522 | ||
519 | x_opt_seen = 0; | 523 | opts = 0; |
520 | /* '-' makes getopt return 1 for non-options */ | 524 | /* '-' makes getopt return 1 for non-options */ |
521 | while ((opt = getopt(argc, argv, "-d:lnopqxv")) != -1) { | 525 | while ((i = getopt(argc, argv, "-d:lnopqxjv")) != -1) { |
522 | switch (opt) { | 526 | switch (i) { |
523 | case 'd': /* Extract to base directory */ | 527 | case 'd': /* Extract to base directory */ |
524 | base_dir = optarg; | 528 | base_dir = optarg; |
525 | break; | 529 | break; |
526 | 530 | ||
527 | case 'l': /* List */ | 531 | case 'l': /* List */ |
528 | listing = 1; | 532 | opts |= OPT_l; |
529 | break; | 533 | break; |
530 | 534 | ||
531 | case 'n': /* Never overwrite existing files */ | 535 | case 'n': /* Never overwrite existing files */ |
@@ -545,11 +549,15 @@ int unzip_main(int argc, char **argv) | |||
545 | 549 | ||
546 | case 'v': /* Verbose list */ | 550 | case 'v': /* Verbose list */ |
547 | IF_FEATURE_UNZIP_CDF(verbose++;) | 551 | IF_FEATURE_UNZIP_CDF(verbose++;) |
548 | listing = 1; | 552 | opts |= OPT_l; |
549 | break; | 553 | break; |
550 | 554 | ||
551 | case 'x': | 555 | case 'x': |
552 | x_opt_seen = 1; | 556 | opts |= OPT_x; |
557 | break; | ||
558 | |||
559 | case 'j': | ||
560 | opts |= OPT_j; | ||
553 | break; | 561 | break; |
554 | 562 | ||
555 | case 1: | 563 | case 1: |
@@ -558,7 +566,7 @@ int unzip_main(int argc, char **argv) | |||
558 | /* +5: space for ".zip" and NUL */ | 566 | /* +5: space for ".zip" and NUL */ |
559 | src_fn = xmalloc(strlen(optarg) + 5); | 567 | src_fn = xmalloc(strlen(optarg) + 5); |
560 | strcpy(src_fn, optarg); | 568 | strcpy(src_fn, optarg); |
561 | } else if (!x_opt_seen) { | 569 | } else if (!(opts & OPT_x)) { |
562 | /* Include files */ | 570 | /* Include files */ |
563 | llist_add_to(&zaccept, optarg); | 571 | llist_add_to(&zaccept, optarg); |
564 | } else { | 572 | } else { |
@@ -626,7 +634,7 @@ int unzip_main(int argc, char **argv) | |||
626 | if (quiet <= 1) { /* not -qq */ | 634 | if (quiet <= 1) { /* not -qq */ |
627 | if (quiet == 0) | 635 | if (quiet == 0) |
628 | printf("Archive: %s\n", src_fn); | 636 | printf("Archive: %s\n", src_fn); |
629 | if (listing) { | 637 | if (opts & OPT_l) { |
630 | puts(verbose ? | 638 | puts(verbose ? |
631 | " Length Method Size Cmpr Date Time CRC-32 Name\n" | 639 | " Length Method Size Cmpr Date Time CRC-32 Name\n" |
632 | "-------- ------ ------- ---- ---------- ----- -------- ----" | 640 | "-------- ------ ------- ---- ---------- ----- -------- ----" |
@@ -778,13 +786,19 @@ int unzip_main(int argc, char **argv) | |||
778 | free(dst_fn); | 786 | free(dst_fn); |
779 | dst_fn = xzalloc(zip.fmt.filename_len + 1); | 787 | dst_fn = xzalloc(zip.fmt.filename_len + 1); |
780 | xread(zip_fd, dst_fn, zip.fmt.filename_len); | 788 | xread(zip_fd, dst_fn, zip.fmt.filename_len); |
781 | |||
782 | /* Skip extra header bytes */ | 789 | /* Skip extra header bytes */ |
783 | unzip_skip(zip.fmt.extra_len); | 790 | unzip_skip(zip.fmt.extra_len); |
784 | 791 | ||
785 | /* Guard against "/abspath", "/../" and similar attacks */ | 792 | /* Guard against "/abspath", "/../" and similar attacks */ |
786 | overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn)); | 793 | overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn)); |
787 | 794 | ||
795 | if (opts & OPT_j) /* Strip paths? */ | ||
796 | overlapping_strcpy(dst_fn, bb_basename(dst_fn)); | ||
797 | |||
798 | /* Did this strip everything ("DIR/" case)? Then skip */ | ||
799 | if (!dst_fn[0]) | ||
800 | goto skip_cmpsize; | ||
801 | |||
788 | /* Filter zip entries */ | 802 | /* Filter zip entries */ |
789 | if (find_list_entry(zreject, dst_fn) | 803 | if (find_list_entry(zreject, dst_fn) |
790 | || (zaccept && !find_list_entry(zaccept, dst_fn)) | 804 | || (zaccept && !find_list_entry(zaccept, dst_fn)) |
@@ -792,7 +806,7 @@ int unzip_main(int argc, char **argv) | |||
792 | goto skip_cmpsize; | 806 | goto skip_cmpsize; |
793 | } | 807 | } |
794 | 808 | ||
795 | if (listing) { | 809 | if (opts & OPT_l) { |
796 | /* List entry */ | 810 | /* List entry */ |
797 | char dtbuf[sizeof("mm-dd-yyyy hh:mm")]; | 811 | char dtbuf[sizeof("mm-dd-yyyy hh:mm")]; |
798 | sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u", | 812 | sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u", |
@@ -960,7 +974,7 @@ int unzip_main(int argc, char **argv) | |||
960 | total_entries++; | 974 | total_entries++; |
961 | } | 975 | } |
962 | 976 | ||
963 | if (listing && quiet <= 1) { | 977 | if ((opts & OPT_l) && quiet <= 1) { |
964 | if (!verbose) { | 978 | if (!verbose) { |
965 | // " Length Date Time Name\n" | 979 | // " Length Date Time Name\n" |
966 | // "--------- ---------- ----- ----" | 980 | // "--------- ---------- ----- ----" |