Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/archival/unzip.c


Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (10 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/archival/unzip.c

    r2725 r3232  
    2020 */
    2121
     22//usage:#define unzip_trivial_usage
     23//usage:       "[-lnopq] FILE[.zip] [FILE]... [-x FILE...] [-d DIR]"
     24//usage:#define unzip_full_usage "\n\n"
     25//usage:       "Extract FILEs from ZIP archive\n"
     26//usage:     "\n    -l  List contents (with -q for short form)"
     27//usage:     "\n    -n  Never overwrite files (default: ask)"
     28//usage:     "\n    -o  Overwrite"
     29//usage:     "\n    -p  Print to stdout"
     30//usage:     "\n    -q  Quiet"
     31//usage:     "\n    -x FILE Exclude FILEs"
     32//usage:     "\n    -d DIR  Extract into DIR"
     33
    2234#include "libbb.h"
    23 #include "archive.h"
     35#include "bb_archive.h"
    2436
    2537enum {
     
    224236    char *name = xstrdup(fn);
    225237    if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) {
    226         bb_error_msg_and_die("exiting"); /* bb_make_directory is noisy */
     238        xfunc_die(); /* bb_make_directory is noisy */
    227239    }
    228240    free(name);
     
    238250    } else {
    239251        /* Method 8 - inflate */
    240         inflate_unzip_result res;
    241         if (inflate_unzip(&res, zip_header->formatted.cmpsize, zip_fd, dst_fd) < 0)
     252        transformer_aux_data_t aux;
     253        init_transformer_aux_data(&aux);
     254        aux.bytes_in = zip_header->formatted.cmpsize;
     255        if (inflate_unzip(&aux, zip_fd, dst_fd) < 0)
    242256            bb_error_msg_and_die("inflate error");
    243257        /* Validate decompression - crc */
    244         if (zip_header->formatted.crc32 != (res.crc ^ 0xffffffffL)) {
     258        if (zip_header->formatted.crc32 != (aux.crc32 ^ 0xffffffffL)) {
    245259            bb_error_msg_and_die("crc error");
    246260        }
    247261        /* Validate decompression - size */
    248         if (zip_header->formatted.ucmpsize != res.bytes_out) {
     262        if (zip_header->formatted.ucmpsize != aux.bytes_out) {
    249263            /* Don't die. Who knows, maybe len calculation
    250264             * was botched somewhere. After all, crc matched! */
     
    264278    smallint listing = 0;
    265279    smallint overwrite = O_PROMPT;
     280    smallint x_opt_seen;
    266281#if ENABLE_DESKTOP
    267282    uint32_t cdf_offset;
     
    277292    char *base_dir = NULL;
    278293    int i, opt;
    279     int opt_range = 0;
    280294    char key_buf[80];
    281295    struct stat stat_buf;
     
    322336 */
    323337
     338    x_opt_seen = 0;
    324339    /* '-' makes getopt return 1 for non-options */
    325340    while ((opt = getopt(argc, argv, "-d:lnopqxv")) != -1) {
    326         switch (opt_range) {
    327         case 0: /* Options */
    328             switch (opt) {
    329             case 'l': /* List */
    330                 listing = 1;
    331                 break;
    332 
    333             case 'n': /* Never overwrite existing files */
    334                 overwrite = O_NEVER;
    335                 break;
    336 
    337             case 'o': /* Always overwrite existing files */
    338                 overwrite = O_ALWAYS;
    339                 break;
    340 
    341             case 'p': /* Extract files to stdout and fall through to set verbosity */
    342                 dst_fd = STDOUT_FILENO;
    343 
    344             case 'q': /* Be quiet */
    345                 quiet++;
    346                 break;
    347 
    348             case 'v': /* Verbose list */
    349                 IF_DESKTOP(verbose++;)
    350                 listing = 1;
    351                 break;
    352 
    353             case 1: /* The zip file */
     341        switch (opt) {
     342        case 'd':  /* Extract to base directory */
     343            base_dir = optarg;
     344            break;
     345
     346        case 'l': /* List */
     347            listing = 1;
     348            break;
     349
     350        case 'n': /* Never overwrite existing files */
     351            overwrite = O_NEVER;
     352            break;
     353
     354        case 'o': /* Always overwrite existing files */
     355            overwrite = O_ALWAYS;
     356            break;
     357
     358        case 'p': /* Extract files to stdout and fall through to set verbosity */
     359            dst_fd = STDOUT_FILENO;
     360
     361        case 'q': /* Be quiet */
     362            quiet++;
     363            break;
     364
     365        case 'v': /* Verbose list */
     366            IF_DESKTOP(verbose++;)
     367            listing = 1;
     368            break;
     369
     370        case 'x':
     371            x_opt_seen = 1;
     372            break;
     373
     374        case 1:
     375            if (!src_fn) {
     376                /* The zip file */
    354377                /* +5: space for ".zip" and NUL */
    355378                src_fn = xmalloc(strlen(optarg) + 5);
    356379                strcpy(src_fn, optarg);
    357                 opt_range++;
    358                 break;
    359 
    360             default:
    361                 bb_show_usage();
     380            } else if (!x_opt_seen) {
     381                /* Include files */
     382                llist_add_to(&zaccept, optarg);
     383            } else {
     384                /* Exclude files */
     385                llist_add_to(&zreject, optarg);
    362386            }
    363387            break;
    364 
    365         case 1: /* Include files */
    366             if (opt == 1) {
    367                 llist_add_to(&zaccept, optarg);
    368                 break;
    369             }
    370             if (opt == 'd') {
    371                 base_dir = optarg;
    372                 opt_range += 2;
    373                 break;
    374             }
    375             if (opt == 'x') {
    376                 opt_range++;
    377                 break;
    378             }
    379             bb_show_usage();
    380 
    381         case 2 : /* Exclude files */
    382             if (opt == 1) {
    383                 llist_add_to(&zreject, optarg);
    384                 break;
    385             }
    386             if (opt == 'd') { /* Extract to base directory */
    387                 base_dir = optarg;
    388                 opt_range++;
    389                 break;
    390             }
    391             /* fall through */
    392388
    393389        default:
     
    396392    }
    397393
    398     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) {
    399413        bb_show_usage();
    400414    }
     
    407421            overwrite = O_NEVER;
    408422    } else {
    409         static const char extn[][5] = {"", ".zip", ".ZIP"};
    410         int orig_src_fn_len = strlen(src_fn);
    411         int src_fd = -1;
    412 
    413         for (i = 0; (i < 3) && (src_fd == -1); i++) {
    414             strcpy(src_fn + orig_src_fn_len, extn[i]);
     423        static const char extn[][5] = { ".zip", ".ZIP" };
     424        char *ext = src_fn + strlen(src_fn);
     425        int src_fd;
     426
     427        i = 0;
     428        for (;;) {
    415429            src_fd = open(src_fn, O_RDONLY);
    416         }
    417         if (src_fd == -1) {
    418             src_fn[orig_src_fn_len] = '\0';
    419             bb_error_msg_and_die("can't open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn);
     430            if (src_fd >= 0)
     431                break;
     432            if (++i > 2) {
     433                *ext = '\0';
     434                bb_error_msg_and_die("can't open %s[.zip]", src_fn);
     435            }
     436            strcpy(ext, extn[i - 1]);
    420437        }
    421438        xmove_fd(src_fd, zip_fd);
     
    583600                    }
    584601                    unzip_create_leading_dirs(dst_fn);
    585                     if (bb_make_directory(dst_fn, dir_mode, 0)) {
    586                         bb_error_msg_and_die("exiting");
     602                    if (bb_make_directory(dst_fn, dir_mode, FILEUTILS_IGNORE_CHMOD_ERR)) {
     603                        xfunc_die();
    587604                    }
    588605                } else {
     
    608625                        } else {
    609626                            printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn);
     627                            fflush_all();
    610628                            if (!fgets(key_buf, sizeof(key_buf), stdin)) {
    611629                                bb_perror_msg_and_die("can't read input");
Note: See TracChangeset for help on using the changeset viewer.