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