Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/archival/bbunzip.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  *  Common code for gunzip-like applets
    4  *
    5  *  Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    6  */
    7 
     3 * Common code for gunzip-like applets
     4 *
     5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
     6 */
    87#include "libbb.h"
    9 #include "unarchive.h"
     8#include "archive.h"
    109
    1110enum {
    12     OPT_STDOUT = 0x1,
    13     OPT_FORCE = 0x2,
    14 /* gunzip only: */
    15     OPT_VERBOSE = 0x4,
    16     OPT_DECOMPRESS = 0x8,
    17     OPT_TEST = 0x10,
     11    OPT_STDOUT     = 1 << 0,
     12    OPT_FORCE      = 1 << 1,
     13    /* only some decompressors: */
     14    OPT_VERBOSE    = 1 << 2,
     15    OPT_DECOMPRESS = 1 << 3,
     16    OPT_TEST       = 1 << 4,
    1817};
    1918
     
    2928}
    3029
    31 int bbunpack(char **argv,
    32     char* (*make_new_name)(char *filename),
    33     USE_DESKTOP(long long) int (*unpacker)(void)
     30char* FAST_FUNC append_ext(char *filename, const char *expected_ext)
     31{
     32    return xasprintf("%s.%s", filename, expected_ext);
     33}
     34
     35int FAST_FUNC bbunpack(char **argv,
     36    IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info),
     37    char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext),
     38    const char *expected_ext
    3439)
    3540{
    3641    struct stat stat_buf;
    37     USE_DESKTOP(long long) int status;
     42    IF_DESKTOP(long long) int status;
    3843    char *filename, *new_name;
    3944    smallint exitcode = 0;
     45    unpack_info_t info;
    4046
    4147    do {
     
    5056        if (filename) {
    5157            if (stat(filename, &stat_buf) != 0) {
    52                 bb_perror_msg("%s", filename);
     58                bb_simple_perror_msg(filename);
    5359 err:
    5460                exitcode = 1;
     
    6975        /* Open dst if we are going to unpack to file */
    7076        if (filename) {
    71             new_name = make_new_name(filename);
     77            new_name = make_new_name(filename, expected_ext);
    7278            if (!new_name) {
    7379                bb_error_msg("%s: unknown suffix - ignored", filename);
    7480                goto err;
    7581            }
     82
     83            /* -f: overwrite existing output files */
     84            if (option_mask32 & OPT_FORCE) {
     85                unlink(new_name);
     86            }
     87
    7688            /* O_EXCL: "real" bunzip2 doesn't overwrite files */
    77             /* GNU gunzip goes not bail out, but goes to next file */
     89            /* GNU gunzip does not bail out, but goes to next file */
    7890            if (open_to_or_warn(STDOUT_FILENO, new_name, O_WRONLY | O_CREAT | O_EXCL,
    7991                    stat_buf.st_mode))
     
    8799        }
    88100
    89         status = unpacker();
     101        /* memset(&info, 0, sizeof(info)); */
     102        info.mtime = 0; /* so far it has one member only */
     103        status = unpacker(&info);
    90104        if (status < 0)
    91105            exitcode = 1;
     106        xclose(STDOUT_FILENO); /* with error check! */
    92107
    93108        if (filename) {
    94109            char *del = new_name;
    95110            if (status >= 0) {
    96                 /* TODO: restore user/group/times here? */
     111                /* TODO: restore other things? */
     112                if (info.mtime) {
     113                    struct timeval times[2];
     114
     115                    times[1].tv_sec = times[0].tv_sec = info.mtime;
     116                    times[1].tv_usec = times[0].tv_usec = 0;
     117                    /* Note: we closed it first.
     118                     * On some systems calling utimes
     119                     * then closing resets the mtime
     120                     * back to current time. */
     121                    utimes(new_name, times); /* ignoring errors */
     122                }
     123
    97124                /* Delete _compressed_ file */
    98125                del = filename;
     
    120147}
    121148
    122 #if ENABLE_BUNZIP2 || ENABLE_UNLZMA || ENABLE_UNCOMPRESS
    123 
    124 static
    125 char* make_new_name_generic(char *filename, const char *expected_ext)
     149#if ENABLE_UNCOMPRESS || ENABLE_BUNZIP2 || ENABLE_UNLZMA || ENABLE_UNXZ
     150static
     151char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext)
    126152{
    127153    char *extension = strrchr(filename, '.');
     
    134160    return filename;
    135161}
    136 
    137 #endif
    138 
    139 
    140 /*
    141  *  Modified for busybox by Glenn McGrath <bug1@iinet.net.au>
    142  *  Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
    143  *
    144  *  Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    145  */
    146 
    147 #if ENABLE_BUNZIP2
    148 
    149 static
    150 char* make_new_name_bunzip2(char *filename)
    151 {
    152     return make_new_name_generic(filename, "bz2");
    153 }
    154 
    155 static
    156 USE_DESKTOP(long long) int unpack_bunzip2(void)
    157 {
    158     return unpack_bz2_stream(STDIN_FILENO, STDOUT_FILENO);
    159 }
    160 
    161 int bunzip2_main(int argc, char **argv);
    162 int bunzip2_main(int argc, char **argv)
     162#endif
     163
     164
     165/*
     166 * Uncompress applet for busybox (c) 2002 Glenn McGrath
     167 *
     168 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
     169 */
     170#if ENABLE_UNCOMPRESS
     171static
     172IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(unpack_info_t *info UNUSED_PARAM)
     173{
     174    IF_DESKTOP(long long) int status = -1;
     175
     176    if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) {
     177        bb_error_msg("invalid magic");
     178    } else {
     179        status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO);
     180    }
     181    return status;
     182}
     183int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     184int uncompress_main(int argc UNUSED_PARAM, char **argv)
    163185{
    164186    getopt32(argv, "cf");
    165187    argv += optind;
    166     if (applet_name[2] == 'c')
    167         option_mask32 |= OPT_STDOUT;
    168 
    169     return bbunpack(argv, make_new_name_bunzip2, unpack_bunzip2);
    170 }
    171 
     188
     189    return bbunpack(argv, unpack_uncompress, make_new_name_generic, "Z");
     190}
    172191#endif
    173192
     
    186205 *
    187206 * General cleanup to better adhere to the style guide and make use of standard
    188  * busybox functions by Glenn McGrath <bug1@iinet.net.au>
    189  *
    190  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     207 * busybox functions by Glenn McGrath
     208 *
     209 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    191210 *
    192211 * gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
     
    200219 * See the file algorithm.doc for the compression algorithms and file formats.
    201220 */
    202 
    203221#if ENABLE_GUNZIP
    204 
    205 static
    206 char* make_new_name_gunzip(char *filename)
     222static
     223char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UNUSED_PARAM)
    207224{
    208225    char *extension = strrchr(filename, '.');
     
    213230    extension++;
    214231    if (strcmp(extension, "tgz" + 1) == 0
    215 #if ENABLE_FEATURE_GUNZIP_UNCOMPRESS
    216      || strcmp(extension, "Z") == 0
     232#if ENABLE_FEATURE_SEAMLESS_Z
     233     || (extension[0] == 'Z' && extension[1] == '\0')
    217234#endif
    218235    ) {
     
    228245    return filename;
    229246}
    230 
    231 static
    232 USE_DESKTOP(long long) int unpack_gunzip(void)
    233 {
    234     USE_DESKTOP(long long) int status = -1;
     247static
     248IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(unpack_info_t *info)
     249{
     250    IF_DESKTOP(long long) int status = -1;
    235251
    236252    /* do the decompression, and cleanup */
     
    239255
    240256        magic2 = xread_char(STDIN_FILENO);
    241         if (ENABLE_FEATURE_GUNZIP_UNCOMPRESS && magic2 == 0x9d) {
    242             status = uncompress(STDIN_FILENO, STDOUT_FILENO);
     257        if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == 0x9d) {
     258            status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO);
    243259        } else if (magic2 == 0x8b) {
    244             check_header_gzip_or_die(STDIN_FILENO);
    245             status = unpack_gz_stream(STDIN_FILENO, STDOUT_FILENO);
     260            status = unpack_gz_stream_with_info(STDIN_FILENO, STDOUT_FILENO, info);
    246261        } else {
    247262            goto bad_magic;
     
    257272    return status;
    258273}
    259 
    260 int gunzip_main(int argc, char **argv);
    261 int gunzip_main(int argc, char **argv)
    262 {
    263     getopt32(argv, "cfvdt");
     274/*
     275 * Linux kernel build uses gzip -d -n. We accept and ignore it.
     276 * Man page says:
     277 * -n --no-name
     278 * gzip: do not save the original file name and time stamp.
     279 * (The original name is always saved if the name had to be truncated.)
     280 * gunzip: do not restore the original file name/time even if present
     281 * (remove only the gzip suffix from the compressed file name).
     282 * This option is the default when decompressing.
     283 * -N --name
     284 * gzip: always save the original file name and time stamp (this is the default)
     285 * gunzip: restore the original file name and time stamp if present.
     286 */
     287int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     288int gunzip_main(int argc UNUSED_PARAM, char **argv)
     289{
     290    getopt32(argv, "cfvdtn");
    264291    argv += optind;
    265292    /* if called as zcat */
     
    267294        option_mask32 |= OPT_STDOUT;
    268295
    269     return bbunpack(argv, make_new_name_gunzip, unpack_gunzip);
    270 }
    271 
     296    return bbunpack(argv, unpack_gunzip, make_new_name_gunzip, /*unused:*/ NULL);
     297}
     298#endif
     299
     300
     301/*
     302 * Modified for busybox by Glenn McGrath
     303 * Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
     304 *
     305 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
     306 */
     307//usage:#define bunzip2_trivial_usage
     308//usage:       "[-cf] [FILE]..."
     309//usage:#define bunzip2_full_usage "\n\n"
     310//usage:       "Decompress FILEs (or stdin)\n"
     311//usage:     "\nOptions:"
     312//usage:     "\n    -c  Write to stdout"
     313//usage:     "\n    -f  Force"
     314//usage:#define bzcat_trivial_usage
     315//usage:       "FILE"
     316//usage:#define bzcat_full_usage "\n\n"
     317//usage:       "Decompress to stdout"
     318//applet:IF_BUNZIP2(APPLET(bunzip2, _BB_DIR_USR_BIN, _BB_SUID_DROP))
     319//applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, _BB_DIR_USR_BIN, _BB_SUID_DROP, bzcat))
     320#if ENABLE_BUNZIP2
     321static
     322IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(unpack_info_t *info UNUSED_PARAM)
     323{
     324    return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO);
     325}
     326int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     327int bunzip2_main(int argc UNUSED_PARAM, char **argv)
     328{
     329    getopt32(argv, "cfvdt");
     330    argv += optind;
     331    if (applet_name[2] == 'c') /* bzcat */
     332        option_mask32 |= OPT_STDOUT;
     333
     334    return bbunpack(argv, unpack_bunzip2, make_new_name_generic, "bz2");
     335}
    272336#endif
    273337
     
    279343 * Based on bunzip.c from busybox
    280344 *
    281  * Licensed under GPL v2, see file LICENSE in this tarball for details.
    282  */
    283 
     345 * Licensed under GPLv2, see file LICENSE in this source tree.
     346 */
    284347#if ENABLE_UNLZMA
    285 
    286 static
    287 char* make_new_name_unlzma(char *filename)
    288 {
    289     return make_new_name_generic(filename, "lzma");
    290 }
    291 
    292 static
    293 USE_DESKTOP(long long) int unpack_unlzma(void)
     348static
     349IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(unpack_info_t *info UNUSED_PARAM)
    294350{
    295351    return unpack_lzma_stream(STDIN_FILENO, STDOUT_FILENO);
    296352}
    297 
    298 int unlzma_main(int argc, char **argv);
    299 int unlzma_main(int argc, char **argv)
    300 {
    301     getopt32(argv, "cf");
     353int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     354int unlzma_main(int argc UNUSED_PARAM, char **argv)
     355{
     356    IF_LZMA(int opts =) getopt32(argv, "cfvdt");
     357# if ENABLE_LZMA
     358    /* lzma without -d or -t? */
     359    if (applet_name[2] == 'm' && !(opts & (OPT_DECOMPRESS|OPT_TEST)))
     360        bb_show_usage();
     361# endif
     362    /* lzcat? */
     363    if (applet_name[2] == 'c')
     364        option_mask32 |= OPT_STDOUT;
     365
    302366    argv += optind;
    303     /* lzmacat? */
    304     if (applet_name[4] == 'c')
     367    return bbunpack(argv, unpack_unlzma, make_new_name_generic, "lzma");
     368}
     369#endif
     370
     371
     372#if ENABLE_UNXZ
     373static
     374IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(unpack_info_t *info UNUSED_PARAM)
     375{
     376    struct {
     377        uint32_t v1;
     378        uint16_t v2;
     379    } magic;
     380    xread(STDIN_FILENO, &magic, 6);
     381    if (magic.v1 != XZ_MAGIC1a || magic.v2 != XZ_MAGIC2a) {
     382        bb_error_msg("invalid magic");
     383        return -1;
     384    }
     385    return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO);
     386}
     387int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     388int unxz_main(int argc UNUSED_PARAM, char **argv)
     389{
     390    IF_XZ(int opts =) getopt32(argv, "cfvdt");
     391# if ENABLE_XZ
     392    /* xz without -d or -t? */
     393    if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST)))
     394        bb_show_usage();
     395# endif
     396    /* xzcat? */
     397    if (applet_name[2] == 'c')
    305398        option_mask32 |= OPT_STDOUT;
    306399
    307     return bbunpack(argv, make_new_name_unlzma, unpack_unlzma);
    308 }
    309 
    310 #endif
    311 
    312 
    313 /*
    314  *  Uncompress applet for busybox (c) 2002 Glenn McGrath
    315  *
    316  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    317  */
    318 
    319 #if ENABLE_UNCOMPRESS
    320 
    321 static
    322 char* make_new_name_uncompress(char *filename)
    323 {
    324     return make_new_name_generic(filename, "Z");
    325 }
    326 
    327 static
    328 USE_DESKTOP(long long) int unpack_uncompress(void)
    329 {
    330     USE_DESKTOP(long long) int status = -1;
    331 
    332     if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) {
    333         bb_error_msg("invalid magic");
    334     } else {
    335         status = uncompress(STDIN_FILENO, STDOUT_FILENO);
    336     }
    337     return status;
    338 }
    339 
    340 int uncompress_main(int argc, char **argv);
    341 int uncompress_main(int argc, char **argv)
    342 {
    343     getopt32(argv, "cf");
    344400    argv += optind;
    345 
    346     return bbunpack(argv, make_new_name_uncompress, unpack_uncompress);
    347 }
    348 
    349 #endif
     401    return bbunpack(argv, unpack_unxz, make_new_name_generic, "xz");
     402}
     403#endif
Note: See TracChangeset for help on using the changeset viewer.