Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/archival


Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
3 added
2 deleted
41 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi-busybox/archival/Config.src

    r3232 r3621  
    55
    66menu "Archival Utilities"
    7 
    8 INSERT
    97
    108config FEATURE_SEAMLESS_XZ
     
    3432config FEATURE_SEAMLESS_Z
    3533    bool "tar, rpm, modprobe etc understand .Z data"
    36     default n
     34    default n  # it is ancient
    3735    help
    3836      Make tar, rpm, modprobe etc understand .Z data.
    3937
    40 config AR
    41     bool "ar"
    42     default n  # needs to be improved to be able to replace binutils ar
    43     help
    44       ar is an archival utility program used to create, modify, and
    45       extract contents from archives. An archive is a single file holding
    46       a collection of other files in a structure that makes it possible to
    47       retrieve the original individual files (called archive members).
    48       The original files' contents, mode (permissions), timestamp, owner,
    49       and group are preserved in the archive, and can be restored on
    50       extraction.
    51 
    52       The stored filename is limited to 15 characters. (for more information
    53       see long filename support).
    54       ar has 60 bytes of overheads for every stored file.
    55 
    56       This implementation of ar can extract archives, it cannot create or
    57       modify them.
    58       On an x86 system, the ar applet adds about 1K.
    59 
    60       Unless you have a specific application which requires ar, you should
    61       probably say N here.
    62 
    63 config FEATURE_AR_LONG_FILENAMES
    64     bool "Support for long filenames (not needed for debs)"
    65     default y
    66     depends on AR
    67     help
    68       By default the ar format can only store the first 15 characters
    69       of the filename, this option removes that limitation.
    70       It supports the GNU ar long filename method which moves multiple long
    71       filenames into a the data section of a new ar entry.
    72 
    73 config FEATURE_AR_CREATE
    74     bool "Support archive creation"
    75     default y
    76     depends on AR
    77     help
    78       This enables archive creation (-c and -r) with busybox ar.
    79 
    80 config BUNZIP2
    81     bool "bunzip2"
    82     default y
    83     help
    84       bunzip2 is a compression utility using the Burrows-Wheeler block
    85       sorting text compression algorithm, and Huffman coding. Compression
    86       is generally considerably better than that achieved by more
    87       conventional LZ77/LZ78-based compressors, and approaches the
    88       performance of the PPM family of statistical compressors.
    89 
    90       Unless you have a specific application which requires bunzip2, you
    91       should probably say N here.
    92 
    93 config BZIP2
    94     bool "bzip2"
    95     default y
    96     help
    97       bzip2 is a compression utility using the Burrows-Wheeler block
    98       sorting text compression algorithm, and Huffman coding. Compression
    99       is generally considerably better than that achieved by more
    100       conventional LZ77/LZ78-based compressors, and approaches the
    101       performance of the PPM family of statistical compressors.
    102 
    103       Unless you have a specific application which requires bzip2, you
    104       should probably say N here.
    105 
    106 config CPIO
    107     bool "cpio"
    108     default y
    109     help
    110       cpio is an archival utility program used to create, modify, and
    111       extract contents from archives.
    112       cpio has 110 bytes of overheads for every stored file.
    113 
    114       This implementation of cpio can extract cpio archives created in the
    115       "newc" or "crc" format, it cannot create or modify them.
    116 
    117       Unless you have a specific application which requires cpio, you
    118       should probably say N here.
    119 
    120 config FEATURE_CPIO_O
    121     bool "Support for archive creation"
    122     default y
    123     depends on CPIO
    124     help
    125       This implementation of cpio can create cpio archives in the "newc"
    126       format only.
    127 
    128 config FEATURE_CPIO_P
    129     bool "Support for passthrough mode"
    130     default y
    131     depends on FEATURE_CPIO_O
    132     help
    133       Passthrough mode. Rarely used.
    134 
    135 config DPKG
    136     bool "dpkg"
    137     default n
    138     select FEATURE_SEAMLESS_GZ
    139     help
    140       dpkg is a medium-level tool to install, build, remove and manage
    141       Debian packages.
    142 
    143       This implementation of dpkg has a number of limitations,
    144       you should use the official dpkg if possible.
    145 
    146 config DPKG_DEB
    147     bool "dpkg_deb"
    148     default n
    149     select FEATURE_SEAMLESS_GZ
    150     help
    151       dpkg-deb unpacks and provides information about Debian archives.
    152 
    153       This implementation of dpkg-deb cannot pack archives.
    154 
    155       Unless you have a specific application which requires dpkg-deb,
    156       say N here.
    157 
    158 config FEATURE_DPKG_DEB_EXTRACT_ONLY
    159     bool "Extract only (-x)"
    160     default n
    161     depends on DPKG_DEB
    162     help
    163       This reduces dpkg-deb to the equivalent of
    164       "ar -p <deb> data.tar.gz | tar -zx". However it saves space as none
    165       of the extra dpkg-deb, ar or tar options are needed, they are linked
    166       to internally.
    167 
    168 config GUNZIP
    169     bool "gunzip"
    170     default y
    171     help
    172       gunzip is used to decompress archives created by gzip.
    173       You can use the `-t' option to test the integrity of
    174       an archive, without decompressing it.
    175 
    176 config GZIP
    177     bool "gzip"
    178     default y
    179     help
    180       gzip is used to compress files.
    181       It's probably the most widely used UNIX compression program.
    182 
    183 config FEATURE_GZIP_LONG_OPTIONS
    184     bool "Enable long options"
    185     default y
    186     depends on GZIP && LONG_OPTS
    187     help
    188       Enable use of long options, increases size by about 106 Bytes
    189 
    190 config GZIP_FAST
    191     int "Trade memory for gzip speed (0:small,slow - 2:fast,big)"
    192     default 0
    193     range 0 2
    194     depends on GZIP
    195     help
    196       Enable big memory options for gzip.
    197       0: small buffers, small hash-tables
    198       1: larger buffers, larger hash-tables
    199       2: larger buffers, largest hash-tables
    200       Larger models may give slightly better compression
    201 
    202 config LZOP
    203     bool "lzop"
    204     default y
    205     help
    206       Lzop compression/decompresion.
    207 
    208 config LZOP_COMPR_HIGH
    209     bool "lzop compression levels 7,8,9 (not very useful)"
    210     default n
    211     depends on LZOP
    212     help
    213       High levels (7,8,9) of lzop compression. These levels
    214       are actually slower than gzip at equivalent compression ratios
    215       and take up 3.2K of code.
    216 
    217 config RPM2CPIO
    218     bool "rpm2cpio"
    219     default y
    220     help
    221       Converts a RPM file into a CPIO archive.
    222 
    223 config RPM
    224     bool "rpm"
    225     default y
    226     help
    227       Mini RPM applet - queries and extracts RPM packages.
    228 
    229 config TAR
    230     bool "tar"
    231     default y
    232     help
    233       tar is an archiving program. It's commonly used with gzip to
    234       create compressed archives. It's probably the most widely used
    235       UNIX archive program.
    236 
    237 config FEATURE_TAR_CREATE
    238     bool "Enable archive creation"
    239     default y
    240     depends on TAR
    241     help
    242       If you enable this option you'll be able to create
    243       tar archives using the `-c' option.
    244 
    245 config FEATURE_TAR_AUTODETECT
    246     bool "Autodetect compressed tarballs"
    247     default y
    248     depends on TAR && (FEATURE_SEAMLESS_Z || FEATURE_SEAMLESS_GZ || FEATURE_SEAMLESS_BZ2 || FEATURE_SEAMLESS_LZMA || FEATURE_SEAMLESS_XZ)
    249     help
    250       With this option tar can automatically detect compressed
    251       tarballs. Currently it works only on files (not pipes etc).
    252 
    253 config FEATURE_TAR_FROM
    254     bool "Enable -X (exclude from) and -T (include from) options)"
    255     default y
    256     depends on TAR
    257     help
    258       If you enable this option you'll be able to specify
    259       a list of files to include or exclude from an archive.
    260 
    261 config FEATURE_TAR_OLDGNU_COMPATIBILITY
    262     bool "Support for old tar header format"
    263     default y
    264     depends on TAR || DPKG
    265     help
    266       This option is required to unpack archives created in
    267       the old GNU format; help to kill this old format by
    268       repacking your ancient archives with the new format.
    269 
    270 config FEATURE_TAR_OLDSUN_COMPATIBILITY
    271     bool "Enable untarring of tarballs with checksums produced by buggy Sun tar"
    272     default y
    273     depends on TAR || DPKG
    274     help
    275       This option is required to unpack archives created by some old
    276       version of Sun's tar (it was calculating checksum using signed
    277       arithmetic). It is said to be fixed in newer Sun tar, but "old"
    278       tarballs still exist.
    279 
    280 config FEATURE_TAR_GNU_EXTENSIONS
    281     bool "Support for GNU tar extensions (long filenames)"
    282     default y
    283     depends on TAR || DPKG
    284     help
    285       With this option busybox supports GNU long filenames and
    286       linknames.
    287 
    288 config FEATURE_TAR_LONG_OPTIONS
    289     bool "Enable long options"
    290     default y
    291     depends on TAR && LONG_OPTS
    292     help
    293       Enable use of long options, increases size by about 400 Bytes
    294 
    295 config FEATURE_TAR_TO_COMMAND
    296     bool "Support for writing to an external program"
    297     default y
    298     depends on TAR && FEATURE_TAR_LONG_OPTIONS
    299     help
    300       If you enable this option you'll be able to instruct tar to send
    301       the contents of each extracted file to the standard input of an
    302       external program.
    303 
    304 config FEATURE_TAR_UNAME_GNAME
    305     bool "Enable use of user and group names"
    306     default y
    307     depends on TAR
    308     help
    309       Enables use of user and group names in tar. This affects contents
    310       listings (-t) and preserving permissions when unpacking (-p).
    311       +200 bytes.
    312 
    313 config FEATURE_TAR_NOPRESERVE_TIME
    314     bool "Enable -m (do not preserve time) option"
    315     default y
    316     depends on TAR
    317     help
    318       With this option busybox supports GNU tar -m
    319       (do not preserve time) option.
    320 
    321 config FEATURE_TAR_SELINUX
    322     bool "Support for extracting SELinux labels"
    323     default n
    324     depends on TAR && SELINUX
    325     help
    326       With this option busybox supports restoring SELinux labels
    327       when extracting files from tar archives.
    328 
    329 config UNCOMPRESS
    330     bool "uncompress"
    331     default n
    332     help
    333       uncompress is used to decompress archives created by compress.
    334       Not much used anymore, replaced by gzip/gunzip.
    335 
    336 config UNLZMA
    337     bool "unlzma"
    338     default y
    339     help
    340       unlzma is a compression utility using the Lempel-Ziv-Markov chain
    341       compression algorithm, and range coding. Compression
    342       is generally considerably better than that achieved by the bzip2
    343       compressors.
    344 
    345       The BusyBox unlzma applet is limited to decompression only.
    346       On an x86 system, this applet adds about 4K.
    347 
    348 config FEATURE_LZMA_FAST
    349     bool "Optimize unlzma for speed"
    350     default n
    351     depends on UNLZMA
    352     help
    353       This option reduces decompression time by about 25% at the cost of
    354       a 1K bigger binary.
    355 
    356 config LZMA
    357     bool "Provide lzma alias which supports only unpacking"
    358     default y
    359     depends on UNLZMA
    360     help
    361       Enable this option if you want commands like "lzma -d" to work.
    362       IOW: you'll get lzma applet, but it will always require -d option.
    363 
    364 config UNXZ
    365     bool "unxz"
    366     default y
    367     help
    368       unxz is a unlzma successor.
    369 
    370 config XZ
    371     bool "Provide xz alias which supports only unpacking"
    372     default y
    373     depends on UNXZ
    374     help
    375       Enable this option if you want commands like "xz -d" to work.
    376       IOW: you'll get xz applet, but it will always require -d option.
    377 
    378 config UNZIP
    379     bool "unzip"
    380     default y
    381     help
    382       unzip will list or extract files from a ZIP archive,
    383       commonly found on DOS/WIN systems. The default behavior
    384       (with no options) is to extract the archive into the
    385       current directory. Use the `-d' option to extract to a
    386       directory of your choice.
     38INSERT
    38739
    38840endmenu
  • branches/3.3/mindi-busybox/archival/Kbuild.src

    r2725 r3621  
    55# Licensed under GPLv2, see file LICENSE in this source tree.
    66
    7 libs-y              += libarchive/
     7libs-y += libarchive/
    88
    99lib-y:=
    1010
    1111INSERT
    12 
    13 lib-$(CONFIG_AR)        += ar.o
    14 lib-$(CONFIG_CPIO)      += cpio.o
    15 lib-$(CONFIG_DPKG)      += dpkg.o
    16 lib-$(CONFIG_DPKG_DEB)      += dpkg_deb.o
    17 lib-$(CONFIG_RPM2CPIO)      += rpm2cpio.o
    18 lib-$(CONFIG_RPM)       += rpm.o
    19 lib-$(CONFIG_TAR)       += tar.o
    20 lib-$(CONFIG_UNZIP)     += unzip.o
    21 
    22 lib-$(CONFIG_LZOP)      += lzop.o bbunzip.o
    23 lib-$(CONFIG_GZIP)      += gzip.o bbunzip.o
    24 lib-$(CONFIG_BZIP2)     += bzip2.o bbunzip.o
    25 
    26 lib-$(CONFIG_UNXZ)      += bbunzip.o
    27 lib-$(CONFIG_UNLZMA)        += bbunzip.o
    28 lib-$(CONFIG_BUNZIP2)       += bbunzip.o
    29 lib-$(CONFIG_GUNZIP)        += bbunzip.o
    30 lib-$(CONFIG_UNCOMPRESS)    += bbunzip.o
  • branches/3.3/mindi-busybox/archival/ar.c

    r3232 r3621  
    1717 * http://www.unix-systems.org/single_unix_specification_v2/xcu/ar.html
    1818 */
     19
     20//config:config AR
     21//config:   bool "ar"
     22//config:   default n  # needs to be improved to be able to replace binutils ar
     23//config:   help
     24//config:     ar is an archival utility program used to create, modify, and
     25//config:     extract contents from archives. In practice, it is used exclusively
     26//config:     for object module archives used by compilers.
     27//config:
     28//config:     On an x86 system, the ar applet adds about 1K.
     29//config:
     30//config:     Unless you have a specific application which requires ar, you should
     31//config:     probably say N here: most compilers come with their own ar utility.
     32//config:
     33//config:config FEATURE_AR_LONG_FILENAMES
     34//config:   bool "Support for long filenames (not needed for debs)"
     35//config:   default y
     36//config:   depends on AR
     37//config:   help
     38//config:     By default the ar format can only store the first 15 characters
     39//config:     of the filename, this option removes that limitation.
     40//config:     It supports the GNU ar long filename method which moves multiple long
     41//config:     filenames into a the data section of a new ar entry.
     42//config:
     43//config:config FEATURE_AR_CREATE
     44//config:   bool "Support archive creation"
     45//config:   default y
     46//config:   depends on AR
     47//config:   help
     48//config:     This enables archive creation (-c and -r) with busybox ar.
     49
     50//applet:IF_AR(APPLET(ar, BB_DIR_USR_BIN, BB_SUID_DROP))
     51//kbuild:lib-$(CONFIG_AR) += ar.o
    1952
    2053//usage:#define ar_trivial_usage
  • branches/3.3/mindi-busybox/archival/bbunzip.c

    r3232 r3621  
    88#include "bb_archive.h"
    99
     10/* lzop_main() uses bbunpack(), need this: */
     11//kbuild:lib-$(CONFIG_LZOP) += bbunzip.o
     12
     13/* Note: must be kept in sync with archival/lzop.c */
    1014enum {
    1115    OPT_STDOUT     = 1 << 0,
     
    1317    /* only some decompressors: */
    1418    OPT_VERBOSE    = 1 << 2,
    15     OPT_DECOMPRESS = 1 << 3,
    16     OPT_TEST       = 1 << 4,
     19    OPT_QUIET      = 1 << 3,
     20    OPT_DECOMPRESS = 1 << 4,
     21    OPT_TEST       = 1 << 5,
     22    SEAMLESS_MAGIC = (1 << 31) * SEAMLESS_COMPRESSION,
    1723};
    1824
     
    3440
    3541int FAST_FUNC bbunpack(char **argv,
    36     IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux),
     42    IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_state_t *xstate),
    3743    char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext),
    3844    const char *expected_ext
     
    4046{
    4147    struct stat stat_buf;
    42     IF_DESKTOP(long long) int status;
     48    IF_DESKTOP(long long) int status = 0;
    4349    char *filename, *new_name;
    4450    smallint exitcode = 0;
    45     transformer_aux_data_t aux;
     51    transformer_state_t xstate;
    4652
    4753    do {
     
    5561        /* Open src */
    5662        if (filename) {
    57             if (stat(filename, &stat_buf) != 0) {
    58                 bb_simple_perror_msg(filename);
     63            if (!(option_mask32 & SEAMLESS_MAGIC)) {
     64                if (stat(filename, &stat_buf) != 0) {
     65 err_name:
     66                    bb_simple_perror_msg(filename);
    5967 err:
    60                 exitcode = 1;
    61                 goto free_name;
     68                    exitcode = 1;
     69                    goto free_name;
     70                }
     71                if (open_to_or_warn(STDIN_FILENO, filename, O_RDONLY, 0))
     72                    goto err;
     73            } else {
     74                /* "clever zcat" with FILE */
     75                /* fail_if_not_compressed because zcat refuses uncompressed input */
     76                int fd = open_zipped(filename, /*fail_if_not_compressed:*/ 1);
     77                if (fd < 0)
     78                    goto err_name;
     79                xmove_fd(fd, STDIN_FILENO);
    6280            }
    63             if (open_to_or_warn(STDIN_FILENO, filename, O_RDONLY, 0))
     81        } else
     82        if (option_mask32 & SEAMLESS_MAGIC) {
     83            /* "clever zcat" on stdin */
     84            if (setup_unzip_on_fd(STDIN_FILENO, /*fail_if_not_compressed*/ 1))
    6485                goto err;
    6586        }
     
    6990            if (option_mask32 & OPT_TEST)
    7091                if (open_to_or_warn(STDOUT_FILENO, bb_dev_null, O_WRONLY, 0))
    71                     goto err;
     92                    xfunc_die();
    7293            filename = NULL;
    7394        }
     
    94115
    95116        /* Check that the input is sane */
    96         if (isatty(STDIN_FILENO) && (option_mask32 & OPT_FORCE) == 0) {
     117        if (!(option_mask32 & OPT_FORCE) && isatty(STDIN_FILENO)) {
    97118            bb_error_msg_and_die("compressed data not read from terminal, "
    98119                    "use -f to force it");
    99120        }
    100121
    101         init_transformer_aux_data(&aux);
    102         aux.check_signature = 1;
    103         status = unpacker(&aux);
    104         if (status < 0)
    105             exitcode = 1;
     122        if (!(option_mask32 & SEAMLESS_MAGIC)) {
     123            init_transformer_state(&xstate);
     124            xstate.signature_skipped = 0;
     125            /*xstate.src_fd = STDIN_FILENO; - already is */
     126            xstate.dst_fd = STDOUT_FILENO;
     127            status = unpacker(&xstate);
     128            if (status < 0)
     129                exitcode = 1;
     130        } else {
     131            if (bb_copyfd_eof(STDIN_FILENO, STDOUT_FILENO) < 0)
     132                /* Disk full, tty closed, etc. No point in continuing */
     133                xfunc_die();
     134        }
    106135
    107136        if (!(option_mask32 & OPT_STDOUT))
     
    110139        if (filename) {
    111140            char *del = new_name;
     141
    112142            if (status >= 0) {
     143                unsigned new_name_len;
     144
    113145                /* TODO: restore other things? */
    114                 if (aux.mtime != 0) {
     146                if (xstate.mtime != 0) {
    115147                    struct timeval times[2];
    116148
    117                     times[1].tv_sec = times[0].tv_sec = aux.mtime;
     149                    times[1].tv_sec = times[0].tv_sec = xstate.mtime;
    118150                    times[1].tv_usec = times[0].tv_usec = 0;
    119151                    /* Note: we closed it first.
     
    124156                }
    125157
    126                 /* Delete _compressed_ file */
     158                if (ENABLE_DESKTOP)
     159                    new_name_len = strlen(new_name);
     160                /* Restore source filename (unless tgz -> tar case) */
     161                if (new_name == filename) {
     162                    new_name_len = strlen(filename);
     163                    filename[new_name_len] = '.';
     164                }
     165                /* Extreme bloat for gunzip compat */
     166                /* Some users do want this info... */
     167                if (ENABLE_DESKTOP && (option_mask32 & OPT_VERBOSE)) {
     168                    unsigned percent = status
     169                        ? ((uoff_t)stat_buf.st_size * 100u / (unsigned long long)status)
     170                        : 0;
     171                    fprintf(stderr, "%s: %u%% - replaced with %.*s\n",
     172                        filename,
     173                        100u - percent,
     174                        new_name_len, new_name
     175                    );
     176                }
     177                /* Delete _source_ file */
    127178                del = filename;
    128                 /* restore extension (unless tgz -> tar case) */
    129                 if (new_name == filename)
    130                     filename[strlen(filename)] = '.';
    131179            }
    132180            xunlink(del);
    133 
    134 #if 0 /* Currently buggy - wrong name: "a.gz: 261% - replaced with a.gz" */
    135             /* Extreme bloat for gunzip compat */
    136             if (ENABLE_DESKTOP && (option_mask32 & OPT_VERBOSE) && status >= 0) {
    137                 fprintf(stderr, "%s: %u%% - replaced with %s\n",
    138                     filename, (unsigned)(stat_buf.st_size*100 / (status+1)), new_name);
    139             }
    140 #endif
    141 
    142181 free_name:
    143182            if (new_name != filename)
     
    173212 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    174213 */
    175 
    176214//usage:#define uncompress_trivial_usage
    177215//usage:       "[-cf] [FILE]..."
     
    181219//usage:     "\n    -f  Overwrite"
    182220
     221//config:config UNCOMPRESS
     222//config:   bool "uncompress"
     223//config:   default n  # ancient
     224//config:   help
     225//config:     uncompress is used to decompress archives created by compress.
     226//config:     Not much used anymore, replaced by gzip/gunzip.
     227
     228//applet:IF_UNCOMPRESS(APPLET(uncompress, BB_DIR_BIN, BB_SUID_DROP))
     229//kbuild:lib-$(CONFIG_UNCOMPRESS) += bbunzip.o
    183230#if ENABLE_UNCOMPRESS
    184 static
    185 IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(transformer_aux_data_t *aux)
    186 {
    187     return unpack_Z_stream(aux, STDIN_FILENO, STDOUT_FILENO);
    188 }
    189231int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    190232int uncompress_main(int argc UNUSED_PARAM, char **argv)
     
    193235    argv += optind;
    194236
    195     return bbunpack(argv, unpack_uncompress, make_new_name_generic, "Z");
     237    return bbunpack(argv, unpack_Z_stream, make_new_name_generic, "Z");
    196238}
    197239#endif
     
    221263 * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
    222264 * Ken Turkowski, Dave Mack and Peter Jannesen.
    223  *
    224  * See the license_msg below and the file COPYING for the software license.
    225  * See the file algorithm.doc for the compression algorithms and file formats.
    226265 */
    227 
    228266//usage:#define gunzip_trivial_usage
    229267//usage:       "[-cft] [FILE]..."
     
    242280//usage:
    243281//usage:#define zcat_trivial_usage
    244 //usage:       "FILE"
     282//usage:       "[FILE]..."
    245283//usage:#define zcat_full_usage "\n\n"
    246284//usage:       "Decompress to stdout"
    247285
     286//config:config GUNZIP
     287//config:   bool "gunzip"
     288//config:   default y
     289//config:   help
     290//config:     gunzip is used to decompress archives created by gzip.
     291//config:     You can use the `-t' option to test the integrity of
     292//config:     an archive, without decompressing it.
     293//config:
     294//config:config FEATURE_GUNZIP_LONG_OPTIONS
     295//config:   bool "Enable long options"
     296//config:   default y
     297//config:   depends on GUNZIP && LONG_OPTS
     298//config:   help
     299//config:     Enable use of long options.
     300
     301//applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP))
     302//applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat))
     303//kbuild:lib-$(CONFIG_GZIP) += bbunzip.o
     304//kbuild:lib-$(CONFIG_GUNZIP) += bbunzip.o
    248305#if ENABLE_GUNZIP
    249306static
     
    272329    return filename;
    273330}
    274 static
    275 IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(transformer_aux_data_t *aux)
    276 {
    277     return unpack_gz_stream(aux, STDIN_FILENO, STDOUT_FILENO);
    278 }
     331
     332#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS
     333static const char gunzip_longopts[] ALIGN1 =
     334    "stdout\0"              No_argument       "c"
     335    "to-stdout\0"           No_argument       "c"
     336    "force\0"               No_argument       "f"
     337    "test\0"                No_argument       "t"
     338    "no-name\0"             No_argument       "n"
     339    ;
     340#endif
     341
    279342/*
    280343 * Linux kernel build uses gzip -d -n. We accept and ignore it.
     
    293356int gunzip_main(int argc UNUSED_PARAM, char **argv)
    294357{
    295     getopt32(argv, "cfvdtn");
     358#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS
     359    applet_long_options = gunzip_longopts;
     360#endif
     361    getopt32(argv, "cfvqdtn");
    296362    argv += optind;
    297     /* if called as zcat */
     363
     364    /* If called as zcat...
     365     * Normally, "zcat" is just "gunzip -c".
     366     * But if seamless magic is enabled, then we are much more clever.
     367     */
    298368    if (applet_name[1] == 'c')
    299         option_mask32 |= OPT_STDOUT;
    300 
    301     return bbunpack(argv, unpack_gunzip, make_new_name_gunzip, /*unused:*/ NULL);
     369        option_mask32 |= OPT_STDOUT | SEAMLESS_MAGIC;
     370
     371    return bbunpack(argv, unpack_gz_stream, make_new_name_gunzip, /*unused:*/ NULL);
    302372}
    303373#endif
     
    317387//usage:     "\n    -f  Force"
    318388//usage:#define bzcat_trivial_usage
    319 //usage:       "FILE"
     389//usage:       "[FILE]..."
    320390//usage:#define bzcat_full_usage "\n\n"
    321391//usage:       "Decompress to stdout"
     392
     393//config:config BUNZIP2
     394//config:   bool "bunzip2"
     395//config:   default y
     396//config:   help
     397//config:     bunzip2 is a compression utility using the Burrows-Wheeler block
     398//config:     sorting text compression algorithm, and Huffman coding. Compression
     399//config:     is generally considerably better than that achieved by more
     400//config:     conventional LZ77/LZ78-based compressors, and approaches the
     401//config:     performance of the PPM family of statistical compressors.
     402//config:
     403//config:     Unless you have a specific application which requires bunzip2, you
     404//config:     should probably say N here.
     405
    322406//applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP))
    323407//applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat))
     408//kbuild:lib-$(CONFIG_BZIP2) += bbunzip.o
     409//kbuild:lib-$(CONFIG_BUNZIP2) += bbunzip.o
    324410#if ENABLE_BUNZIP2
    325 static
    326 IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(transformer_aux_data_t *aux)
    327 {
    328     return unpack_bz2_stream(aux, STDIN_FILENO, STDOUT_FILENO);
    329 }
    330411int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    331412int bunzip2_main(int argc UNUSED_PARAM, char **argv)
    332413{
    333     getopt32(argv, "cfvdt");
     414    getopt32(argv, "cfvqdt");
    334415    argv += optind;
    335416    if (applet_name[2] == 'c') /* bzcat */
    336417        option_mask32 |= OPT_STDOUT;
    337418
    338     return bbunpack(argv, unpack_bunzip2, make_new_name_generic, "bz2");
     419    return bbunpack(argv, unpack_bz2_stream, make_new_name_generic, "bz2");
    339420}
    340421#endif
     
    349430 * Licensed under GPLv2, see file LICENSE in this source tree.
    350431 */
    351 
    352432//usage:#define unlzma_trivial_usage
    353433//usage:       "[-cf] [FILE]..."
     
    366446//usage:
    367447//usage:#define lzcat_trivial_usage
    368 //usage:       "FILE"
     448//usage:       "[FILE]..."
    369449//usage:#define lzcat_full_usage "\n\n"
    370450//usage:       "Decompress to stdout"
     
    386466//usage:
    387467//usage:#define xzcat_trivial_usage
    388 //usage:       "FILE"
     468//usage:       "[FILE]..."
    389469//usage:#define xzcat_full_usage "\n\n"
    390470//usage:       "Decompress to stdout"
    391471
     472//config:config UNLZMA
     473//config:   bool "unlzma"
     474//config:   default y
     475//config:   help
     476//config:     unlzma is a compression utility using the Lempel-Ziv-Markov chain
     477//config:     compression algorithm, and range coding. Compression
     478//config:     is generally considerably better than that achieved by the bzip2
     479//config:     compressors.
     480//config:
     481//config:     The BusyBox unlzma applet is limited to decompression only.
     482//config:     On an x86 system, this applet adds about 4K.
     483//config:
     484//config:config FEATURE_LZMA_FAST
     485//config:   bool "Optimize unlzma for speed"
     486//config:   default n
     487//config:   depends on UNLZMA
     488//config:   help
     489//config:     This option reduces decompression time by about 25% at the cost of
     490//config:     a 1K bigger binary.
     491//config:
     492//config:config LZMA
     493//config:   bool "Provide lzma alias which supports only unpacking"
     494//config:   default y
     495//config:   depends on UNLZMA
     496//config:   help
     497//config:     Enable this option if you want commands like "lzma -d" to work.
     498//config:     IOW: you'll get lzma applet, but it will always require -d option.
     499
     500//applet:IF_UNLZMA(APPLET(unlzma, BB_DIR_USR_BIN, BB_SUID_DROP))
     501//applet:IF_UNLZMA(APPLET_ODDNAME(lzcat, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzcat))
     502//applet:IF_LZMA(APPLET_ODDNAME(lzma, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzma))
     503//kbuild:lib-$(CONFIG_UNLZMA) += bbunzip.o
    392504#if ENABLE_UNLZMA
    393 static
    394 IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(transformer_aux_data_t *aux)
    395 {
    396     return unpack_lzma_stream(aux, STDIN_FILENO, STDOUT_FILENO);
    397 }
    398505int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    399506int unlzma_main(int argc UNUSED_PARAM, char **argv)
    400507{
    401     IF_LZMA(int opts =) getopt32(argv, "cfvdt");
     508    IF_LZMA(int opts =) getopt32(argv, "cfvqdt");
    402509# if ENABLE_LZMA
    403510    /* lzma without -d or -t? */
     
    410517
    411518    argv += optind;
    412     return bbunpack(argv, unpack_unlzma, make_new_name_generic, "lzma");
    413 }
    414 #endif
    415 
    416 
     519    return bbunpack(argv, unpack_lzma_stream, make_new_name_generic, "lzma");
     520}
     521#endif
     522
     523
     524//config:config UNXZ
     525//config:   bool "unxz"
     526//config:   default y
     527//config:   help
     528//config:     unxz is a unlzma successor.
     529//config:
     530//config:config XZ
     531//config:   bool "Provide xz alias which supports only unpacking"
     532//config:   default y
     533//config:   depends on UNXZ
     534//config:   help
     535//config:     Enable this option if you want commands like "xz -d" to work.
     536//config:     IOW: you'll get xz applet, but it will always require -d option.
     537
     538//applet:IF_UNXZ(APPLET(unxz, BB_DIR_USR_BIN, BB_SUID_DROP))
     539//applet:IF_UNXZ(APPLET_ODDNAME(xzcat, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xzcat))
     540//applet:IF_XZ(APPLET_ODDNAME(xz, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xz))
     541//kbuild:lib-$(CONFIG_UNXZ) += bbunzip.o
    417542#if ENABLE_UNXZ
    418 static
    419 IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(transformer_aux_data_t *aux)
    420 {
    421     return unpack_xz_stream(aux, STDIN_FILENO, STDOUT_FILENO);
    422 }
    423543int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    424544int unxz_main(int argc UNUSED_PARAM, char **argv)
    425545{
    426     IF_XZ(int opts =) getopt32(argv, "cfvdt");
     546    IF_XZ(int opts =) getopt32(argv, "cfvqdt");
    427547# if ENABLE_XZ
    428548    /* xz without -d or -t? */
     
    435555
    436556    argv += optind;
    437     return bbunpack(argv, unpack_unxz, make_new_name_generic, "xz");
    438 }
    439 #endif
     557    return bbunpack(argv, unpack_xz_stream, make_new_name_generic, "xz");
     558}
     559#endif
  • branches/3.3/mindi-busybox/archival/bzip2.c

    r3232 r3621  
    77 * about bzip2 library code.
    88 */
     9
     10//config:config BZIP2
     11//config:   bool "bzip2"
     12//config:   default y
     13//config:   help
     14//config:     bzip2 is a compression utility using the Burrows-Wheeler block
     15//config:     sorting text compression algorithm, and Huffman coding. Compression
     16//config:     is generally considerably better than that achieved by more
     17//config:     conventional LZ77/LZ78-based compressors, and approaches the
     18//config:     performance of the PPM family of statistical compressors.
     19//config:
     20//config:     Unless you have a specific application which requires bzip2, you
     21//config:     should probably say N here.
     22
     23//applet:IF_BZIP2(APPLET(bzip2, BB_DIR_USR_BIN, BB_SUID_DROP))
     24//kbuild:lib-$(CONFIG_BZIP2) += bzip2.o
    925
    1026//usage:#define bzip2_trivial_usage
     
    112128
    113129static
    114 IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_aux_data_t *aux UNUSED_PARAM)
     130IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_state_t *xstate UNUSED_PARAM)
    115131{
    116132    IF_DESKTOP(long long) int total;
  • branches/3.3/mindi-busybox/archival/cpio.c

    r3232 r3621  
    1010 * Doesn't check CRC's
    1111 * Only supports new ASCII and CRC formats
    12  *
    1312 */
    1413#include "libbb.h"
     14#include "common_bufsiz.h"
    1515#include "bb_archive.h"
    1616
     17//config:config CPIO
     18//config:   bool "cpio"
     19//config:   default y
     20//config:   help
     21//config:     cpio is an archival utility program used to create, modify, and
     22//config:     extract contents from archives.
     23//config:     cpio has 110 bytes of overheads for every stored file.
     24//config:
     25//config:     This implementation of cpio can extract cpio archives created in the
     26//config:     "newc" or "crc" format, it cannot create or modify them.
     27//config:
     28//config:     Unless you have a specific application which requires cpio, you
     29//config:     should probably say N here.
     30//config:
     31//config:config FEATURE_CPIO_O
     32//config:   bool "Support for archive creation"
     33//config:   default y
     34//config:   depends on CPIO
     35//config:   help
     36//config:     This implementation of cpio can create cpio archives in the "newc"
     37//config:     format only.
     38//config:
     39//config:config FEATURE_CPIO_P
     40//config:   bool "Support for passthrough mode"
     41//config:   default y
     42//config:   depends on FEATURE_CPIO_O
     43//config:   help
     44//config:     Passthrough mode. Rarely used.
     45
     46//applet:IF_CPIO(APPLET(cpio, BB_DIR_BIN, BB_SUID_DROP))
     47//kbuild:lib-$(CONFIG_CPIO) += cpio.o
     48
    1749//usage:#define cpio_trivial_usage
    18 //usage:       "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]")
     50//usage:       "[-dmvu] [-F FILE] [-R USER[:GRP]]" IF_FEATURE_CPIO_O(" [-H newc]")
    1951//usage:       " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]")
    2052//usage:       " [EXTR_FILE]..."
     
    3567//usage:     "\n    -p DIR  Copy files to DIR"
    3668//usage:    )
     69//usage:     "\nOptions:"
    3770//usage:     "\n    -d  Make leading directories"
    3871//usage:     "\n    -m  Preserve mtime"
     
    4073//usage:     "\n    -u  Overwrite"
    4174//usage:     "\n    -F FILE Input (-t,-i,-p) or output (-o) file"
     75//usage:     "\n    -R USER[:GRP]   Set owner of created files"
    4276//usage:    IF_FEATURE_CPIO_O(
    4377//usage:     "\n    -H newc Archive format"
     
    99133  -L, --dereference          Dereference symbolic links (copy the files
    100134                             that they point to instead of copying the links)
    101   -R, --owner=[USER][:.][GROUP] Set owner of created files
     135  -R, --owner=[USER][:.][GRP] Set owner of created files
    102136
    103137 Options valid in --extract and --pass-through modes:
     
    119153    OPT_DEREF              = (1 << 7),
    120154    OPT_FILE               = (1 << 8),
    121     OPTBIT_FILE = 8,
     155    OPT_OWNER              = (1 << 9),
     156    OPTBIT_OWNER = 9,
    122157    IF_FEATURE_CPIO_O(OPTBIT_CREATE     ,)
    123158    IF_FEATURE_CPIO_O(OPTBIT_FORMAT     ,)
     
    132167};
    133168
    134 #define OPTION_STR "it0uvdmLF:"
     169#define OPTION_STR "it0uvdmLF:R:"
     170
     171struct globals {
     172    struct bb_uidgid_t owner_ugid;
     173} FIX_ALIASING;
     174#define G (*(struct globals*)bb_common_bufsiz1)
     175void BUG_cpio_globals_too_big(void);
     176#define INIT_G() do { \
     177    setup_common_bufsiz(); \
     178    G.owner_ugid.uid = -1L; \
     179    G.owner_ugid.gid = -1L; \
     180} while (0)
    135181
    136182#if ENABLE_FEATURE_CPIO_O
     
    150196static NOINLINE int cpio_o(void)
    151197{
    152     static const char trailer[] ALIGN1 = "TRAILER!!!";
    153198    struct name_s {
    154199        struct name_s *next;
     
    191236                bb_simple_perror_msg_and_die(name);
    192237            }
     238
     239            if (G.owner_ugid.uid != (uid_t)-1L)
     240                st.st_uid = G.owner_ugid.uid;
     241            if (G.owner_ugid.gid != (gid_t)-1L)
     242                st.st_gid = G.owner_ugid.gid;
    193243
    194244            if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode)))
     
    226276                continue;
    227277            }
    228 
    229278        } else { /* line == NULL: EOF */
    230279 next_link:
     
    245294                /* If no (more) hardlinks to output,
    246295                 * output "trailer" entry */
    247                 name = trailer;
     296                name = cpio_TRAILER;
    248297                /* st.st_size == 0 is a must, but for uniformity
    249298                 * in the output, we zero out everything */
     
    293342
    294343        if (!line) {
    295             if (name != trailer)
     344            if (name != cpio_TRAILER)
    296345                goto next_link;
    297346            /* TODO: GNU cpio pads trailer to 512 bytes, do we want that? */
     
    309358    archive_handle_t *archive_handle;
    310359    char *cpio_filename;
     360    char *cpio_owner;
    311361    IF_FEATURE_CPIO_O(const char *cpio_fmt = "";)
    312362    unsigned opt;
     
    323373#endif
    324374#endif
     375        "owner\0"        Required_argument "R"
    325376        "verbose\0"      No_argument       "v"
    326377        "quiet\0"        No_argument       "\xff"
     
    329380#endif
    330381
     382    INIT_G();
    331383    archive_handle = init_handle();
    332384    /* archive_handle->src_fd = STDIN_FILENO; - done by init_handle */
     
    339391
    340392#if !ENABLE_FEATURE_CPIO_O
    341     opt = getopt32(argv, OPTION_STR, &cpio_filename);
     393    opt = getopt32(argv, OPTION_STR, &cpio_filename, &cpio_owner);
     394#else
     395    opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"),
     396               &cpio_filename, &cpio_owner, &cpio_fmt);
     397#endif
    342398    argv += optind;
     399    if (opt & OPT_OWNER) { /* -R */
     400        parse_chown_usergroup_or_die(&G.owner_ugid, cpio_owner);
     401        archive_handle->cpio__owner = G.owner_ugid;
     402    }
     403#if !ENABLE_FEATURE_CPIO_O
    343404    if (opt & OPT_FILE) { /* -F */
    344405        xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO);
    345406    }
    346407#else
    347     opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt);
    348     argv += optind;
    349408    if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */
    350409        xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO);
  • branches/3.3/mindi-busybox/archival/dpkg.c

    r3232 r3621  
    1515 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1616 */
    17 
    1817/*
    1918 * known difference between busybox dpkg and the official dpkg that i don't
     
    2625 * bugs that need to be fixed
    2726 *  - (unknown, please let me know when you find any)
    28  *
    2927 */
     28
     29//config:config DPKG
     30//config:   bool "dpkg"
     31//config:   default n
     32//config:   select FEATURE_SEAMLESS_GZ
     33//config:   help
     34//config:     dpkg is a medium-level tool to install, build, remove and manage
     35//config:     Debian packages.
     36//config:
     37//config:     This implementation of dpkg has a number of limitations,
     38//config:     you should use the official dpkg if possible.
     39
     40//applet:IF_DPKG(APPLET(dpkg, BB_DIR_USR_BIN, BB_SUID_DROP))
     41//kbuild:lib-$(CONFIG_DPKG) += dpkg.o
    3042
    3143//usage:#define dpkg_trivial_usage
     
    11401152                    if (root_of_alternatives)
    11411153                        bb_error_msg_and_die(
    1142                             "package %s %sdepends on %s, "
    1143                             "which cannot be satisfied",
     1154                            "package %s %sdepends on %s, which %s",
    11441155                            name_hashtable[package_node->name],
    11451156                            package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",
    1146                             name_hashtable[root_of_alternatives->name]);
     1157                            name_hashtable[root_of_alternatives->name],
     1158                            "cannot be satisfied");
    11471159                    bb_error_msg_and_die(
    1148                         "package %s %sdepends on %s, which %s\n",
     1160                        "package %s %sdepends on %s, which %s",
    11491161                        name_hashtable[package_node->name],
    11501162                        package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",
     
    14611473
    14621474    /* We don't care about data.tar.* or debian-binary, just control.tar.* */
     1475    llist_add_to(&(ar_handle->accept), (char*)"control.tar");
    14631476#if ENABLE_FEATURE_SEAMLESS_GZ
    14641477    llist_add_to(&(ar_handle->accept), (char*)"control.tar.gz");
     
    14671480    llist_add_to(&(ar_handle->accept), (char*)"control.tar.bz2");
    14681481#endif
     1482#if ENABLE_FEATURE_SEAMLESS_XZ
     1483    llist_add_to(&(ar_handle->accept), (char*)"control.tar.xz");
     1484#endif
    14691485
    14701486    /* Assign the tar handle as a subarchive of the ar handle */
     
    14811497
    14821498    /* We don't care about control.tar.* or debian-binary, just data.tar.* */
     1499    llist_add_to(&(ar_handle->accept), (char*)"data.tar");
    14831500#if ENABLE_FEATURE_SEAMLESS_GZ
    14841501    llist_add_to(&(ar_handle->accept), (char*)"data.tar.gz");
     
    14861503#if ENABLE_FEATURE_SEAMLESS_BZ2
    14871504    llist_add_to(&(ar_handle->accept), (char*)"data.tar.bz2");
     1505#endif
     1506#if ENABLE_FEATURE_SEAMLESS_LZMA
     1507    llist_add_to(&(ar_handle->accept), (char*)"data.tar.lzma");
     1508#endif
     1509#if ENABLE_FEATURE_SEAMLESS_XZ
     1510    llist_add_to(&(ar_handle->accept), (char*)"data.tar.xz");
    14881511#endif
    14891512
  • branches/3.3/mindi-busybox/archival/dpkg_deb.c

    r3232 r3621  
    66 */
    77
     8//config:config DPKG_DEB
     9//config:   bool "dpkg_deb"
     10//config:   default n
     11//config:   select FEATURE_SEAMLESS_GZ
     12//config:   help
     13//config:     dpkg-deb unpacks and provides information about Debian archives.
     14//config:
     15//config:     This implementation of dpkg-deb cannot pack archives.
     16//config:
     17//config:     Unless you have a specific application which requires dpkg-deb,
     18//config:     say N here.
     19//config:
     20//config:config FEATURE_DPKG_DEB_EXTRACT_ONLY
     21//config:   bool "Extract only (-x)"
     22//config:   default n
     23//config:   depends on DPKG_DEB
     24//config:   help
     25//config:     This reduces dpkg-deb to the equivalent of
     26//config:     "ar -p <deb> data.tar.gz | tar -zx". However it saves space as none
     27//config:     of the extra dpkg-deb, ar or tar options are needed, they are linked
     28//config:     to internally.
     29
     30//applet:IF_DPKG_DEB(APPLET_ODDNAME(dpkg-deb, dpkg_deb, BB_DIR_USR_BIN, BB_SUID_DROP, dpkg_deb))
     31//kbuild:lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o
     32
    833//usage:#define dpkg_deb_trivial_usage
    9 //usage:       "[-cefxX] FILE [argument"
     34//usage:       "[-cefxX] FILE [argument]"
    1035//usage:#define dpkg_deb_full_usage "\n\n"
    1136//usage:       "Perform actions on Debian packages (.debs)\n"
     
    4671    ar_archive->filter = filter_accept_list_reassign;
    4772
     73    llist_add_to(&ar_archive->accept, (char*)"data.tar");
     74    llist_add_to(&control_tar_llist, (char*)"control.tar");
    4875#if ENABLE_FEATURE_SEAMLESS_GZ
    4976    llist_add_to(&ar_archive->accept, (char*)"data.tar.gz");
     
    5784    llist_add_to(&ar_archive->accept, (char*)"data.tar.lzma");
    5885    llist_add_to(&control_tar_llist, (char*)"control.tar.lzma");
     86#endif
     87#if ENABLE_FEATURE_SEAMLESS_XZ
     88    llist_add_to(&ar_archive->accept, (char*)"data.tar.xz");
     89    llist_add_to(&control_tar_llist, (char*)"control.tar.xz");
    5990#endif
    6091
  • branches/3.3/mindi-busybox/archival/gzip.c

    r3232 r3621  
    1616 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1717 */
    18 
    1918/* big objects in bss:
    2019 * 00000020 b bl_count
     
    3231 * 000008f4 b dyn_ltree
    3332 */
    34 
    3533/* TODO: full support for -v for DESKTOP
    3634 * "/usr/bin/gzip -v a bogus aa" should say:
     
    4038*/
    4139
     40//config:config GZIP
     41//config:   bool "gzip"
     42//config:   default y
     43//config:   help
     44//config:     gzip is used to compress files.
     45//config:     It's probably the most widely used UNIX compression program.
     46//config:
     47//config:config FEATURE_GZIP_LONG_OPTIONS
     48//config:   bool "Enable long options"
     49//config:   default y
     50//config:   depends on GZIP && LONG_OPTS
     51//config:   help
     52//config:     Enable use of long options, increases size by about 106 Bytes
     53//config:
     54//config:config GZIP_FAST
     55//config:   int "Trade memory for gzip speed (0:small,slow - 2:fast,big)"
     56//config:   default 0
     57//config:   range 0 2
     58//config:   depends on GZIP
     59//config:   help
     60//config:     Enable big memory options for gzip.
     61//config:     0: small buffers, small hash-tables
     62//config:     1: larger buffers, larger hash-tables
     63//config:     2: larger buffers, largest hash-tables
     64//config:     Larger models may give slightly better compression
     65//config:
     66//config:config FEATURE_GZIP_LEVELS
     67//config:   bool "Enable compression levels"
     68//config:   default n
     69//config:   depends on GZIP
     70//config:   help
     71//config:     Enable support for compression levels 4-9. The default level
     72//config:     is 6. If levels 1-3 are specified, 4 is used.
     73//config:     If this option is not selected, -N options are ignored and -9
     74//config:     is used.
     75
     76//applet:IF_GZIP(APPLET(gzip, BB_DIR_BIN, BB_SUID_DROP))
     77//kbuild:lib-$(CONFIG_GZIP) += gzip.o
     78
    4279//usage:#define gzip_trivial_usage
    43 //usage:       "[-cfd] [FILE]..."
     80//usage:       "[-cf" IF_GUNZIP("d") IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..."
    4481//usage:#define gzip_full_usage "\n\n"
    4582//usage:       "Compress FILEs (or stdin)\n"
     83//usage:    IF_FEATURE_GZIP_LEVELS(
     84//usage:     "\n    -1..9   Compression level"
     85//usage:    )
     86//usage:    IF_GUNZIP(
    4687//usage:     "\n    -d  Decompress"
     88//usage:    )
    4789//usage:     "\n    -c  Write to stdout"
    4890//usage:     "\n    -f  Force"
     
    226268 */
    227269
     270#ifndef ENABLE_FEATURE_GZIP_LEVELS
     271
    228272    max_chain_length = 4096,
    229273/* To speed up deflation, hash chains are never searched beyond this length.
     
    257301 * meaning.
    258302 */
     303#endif /* ENABLE_FEATURE_GZIP_LEVELS */
    259304};
    260305
    261306
    262307struct globals {
     308
     309#ifdef ENABLE_FEATURE_GZIP_LEVELS
     310    unsigned max_chain_length;
     311    unsigned max_lazy_match;
     312    unsigned good_match;
     313    unsigned nice_match;
     314#define max_chain_length (G1.max_chain_length)
     315#define max_lazy_match   (G1.max_lazy_match)
     316#define good_match   (G1.good_match)
     317#define nice_match   (G1.nice_match)
     318#endif
    263319
    264320    lng block_start;
     
    391447do { \
    392448    G1.outbuf[G1.outcnt++] = (c); \
    393     if (G1.outcnt == OUTBUFSIZ) flush_outbuf(); \
     449    if (G1.outcnt == OUTBUFSIZ) \
     450        flush_outbuf(); \
    394451} while (0)
    395452
     
    397454static void put_16bit(ush w)
    398455{
    399     if (G1.outcnt < OUTBUFSIZ - 2) {
    400         G1.outbuf[G1.outcnt++] = w;
    401         G1.outbuf[G1.outcnt++] = w >> 8;
    402     } else {
    403         put_8bit(w);
    404         put_8bit(w >> 8);
    405     }
     456    /* GCC 4.2.1 won't optimize out redundant loads of G1.outcnt
     457     * (probably because of fear of aliasing with G1.outbuf[]
     458     * stores), do it explicitly:
     459     */
     460    unsigned outcnt = G1.outcnt;
     461    uch *dst = &G1.outbuf[outcnt];
     462
     463#if BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN
     464    if (outcnt < OUTBUFSIZ-2) {
     465        /* Common case */
     466        ush *dst16 = (void*) dst;
     467        *dst16 = w; /* unalinged LSB 16-bit store */
     468        G1.outcnt = outcnt + 2;
     469        return;
     470    }
     471    *dst = (uch)w;
     472    w >>= 8;
     473#else
     474    *dst = (uch)w;
     475    w >>= 8;
     476    if (outcnt < OUTBUFSIZ-2) {
     477        /* Common case */
     478        dst[1] = w;
     479        G1.outcnt = outcnt + 2;
     480        return;
     481    }
     482#endif
     483
     484    /* Slowpath: we will need to do flush_outbuf() */
     485    G1.outcnt = ++outcnt;
     486    if (outcnt == OUTBUFSIZ)
     487        flush_outbuf();
     488    put_8bit(w);
    406489}
    407490
     
    12921375        G2.heap[SMALLEST] = node++;
    12931376        pqdownheap(tree, SMALLEST);
    1294 
    12951377    } while (G2.heap_len >= 2);
    12961378
     
    16401722        copy_block(buf, (unsigned) stored_len, 0);  /* without header */
    16411723        G2.compressed_len = stored_len << 3;
    1642 
    16431724    } else if (stored_len + 4 <= opt_lenb && buf != NULL) {
    16441725        /* 4: two words for the lengths */
     
    16541735
    16551736        copy_block(buf, (unsigned) stored_len, 1);  /* with header */
    1656 
    16571737    } else if (static_lenb == opt_lenb) {
    16581738        send_bits((STATIC_TREES << 1) + eof, 3);
     
    19812061 */
    19822062
    1983 static void zip(ulg time_stamp)
     2063static void zip(void)
    19842064{
    19852065    ush deflate_flags = 0;  /* pkzip -es, -en or -ex equivalent */
     
    19922072    /* general flags: 0 */
    19932073    put_32bit(0x00088b1f);
    1994     put_32bit(time_stamp);
     2074    put_32bit(0);       /* Unix timestamp */
    19952075
    19962076    /* Write deflated file to zip file */
     
    20162096/* ======================================================================== */
    20172097static
    2018 IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_aux_data_t *aux UNUSED_PARAM)
    2019 {
    2020     struct stat s;
    2021 
     2098IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM)
     2099{
    20222100    /* Clear input and output buffers */
    20232101    G1.outcnt = 0;
     
    20512129    //G2.bl_desc.max_code    = 0;
    20522130
     2131#if 0
     2132    /* Saving of timestamp is disabled. Why?
     2133     * - it is not Y2038-safe.
     2134     * - some people want deterministic results
     2135     *   (normally they'd use -n, but our -n is a nop).
     2136     * - it's bloat.
     2137     * Per RFC 1952, gzfile.time=0 is "no timestamp".
     2138     * If users will demand this to be reinstated,
     2139     * implement -n "don't save timestamp".
     2140     */
     2141    struct stat s;
    20532142    s.st_ctime = 0;
    20542143    fstat(STDIN_FILENO, &s);
    20552144    zip(s.st_ctime);
     2145#else
     2146    zip();
     2147#endif
    20562148    return 0;
    20572149}
     
    20712163    "fast\0"                No_argument       "1"
    20722164    "best\0"                No_argument       "9"
     2165    "no-name\0"             No_argument       "n"
    20732166    ;
    20742167#endif
     
    20962189{
    20972190    unsigned opt;
     2191#ifdef ENABLE_FEATURE_GZIP_LEVELS
     2192    static const struct {
     2193        uint8_t good;
     2194        uint8_t chain_shift;
     2195        uint8_t lazy2;
     2196        uint8_t nice2;
     2197    } gzip_level_config[6] = {
     2198        {4,   4,   4/2,  16/2}, /* Level 4 */
     2199        {8,   5,  16/2,  32/2}, /* Level 5 */
     2200        {8,   7,  16/2, 128/2}, /* Level 6 */
     2201        {8,   8,  32/2, 128/2}, /* Level 7 */
     2202        {32, 10, 128/2, 258/2}, /* Level 8 */
     2203        {32, 12, 258/2, 258/2}, /* Level 9 */
     2204    };
     2205#endif
     2206
     2207    SET_PTR_TO_GLOBALS((char *)xzalloc(sizeof(struct globals)+sizeof(struct globals2))
     2208            + sizeof(struct globals));
    20982209
    20992210#if ENABLE_FEATURE_GZIP_LONG_OPTIONS
     
    21012212#endif
    21022213    /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */
    2103     opt = getopt32(argv, "cfv" IF_GUNZIP("dt") "q123456789n");
     2214    opt = getopt32(argv, "cfv" IF_GUNZIP("dt") "qn123456789");
    21042215#if ENABLE_GUNZIP /* gunzip_main may not be visible... */
    21052216    if (opt & 0x18) // -d and/or -t
    21062217        return gunzip_main(argc, argv);
    21072218#endif
    2108     option_mask32 &= 0x7; /* ignore -q, -0..9 */
    2109     //if (opt & 0x1) // -c
    2110     //if (opt & 0x2) // -f
    2111     //if (opt & 0x4) // -v
    2112     argv += optind;
    2113 
    2114     SET_PTR_TO_GLOBALS((char *)xzalloc(sizeof(struct globals)+sizeof(struct globals2))
    2115             + sizeof(struct globals));
     2219#ifdef ENABLE_FEATURE_GZIP_LEVELS
     2220    opt >>= ENABLE_GUNZIP ? 7 : 5; /* drop cfv[dt]qn bits */
     2221    if (opt == 0)
     2222        opt = 1 << 6; /* default: 6 */
     2223    opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */
     2224    max_chain_length = 1 << gzip_level_config[opt].chain_shift;
     2225    good_match   = gzip_level_config[opt].good;
     2226    max_lazy_match   = gzip_level_config[opt].lazy2 * 2;
     2227    nice_match   = gzip_level_config[opt].nice2 * 2;
     2228#endif
     2229    option_mask32 &= 0x7; /* retain only -cfv */
    21162230
    21172231    /* Allocate all global buffers (for DYN_ALLOC option) */
     
    21252239    global_crc32_table = crc32_filltable(NULL, 0);
    21262240
     2241    argv += optind;
    21272242    return bbunpack(argv, pack_gzip, append_ext, "gz");
    21282243}
  • branches/3.3/mindi-busybox/archival/libarchive/Kbuild.src

    r3232 r3621  
    55# Licensed under GPLv2 or later, see file LICENSE in this source tree.
    66
    7 lib-y:=
     7lib-y:= common.o
    88
    99COMMON_FILES:= \
     
    3131    unpack_ar_archive.o \
    3232    filter_accept_list_reassign.o \
     33    unsafe_prefix.o \
    3334    get_header_ar.o \
    3435    get_header_tar.o \
     
    3637    get_header_tar_bz2.o \
    3738    get_header_tar_lzma.o \
     39    get_header_tar_xz.o \
    3840
    3941INSERT
    4042
    41 lib-$(CONFIG_AR)                        += get_header_ar.o unpack_ar_archive.o
    42 lib-$(CONFIG_BUNZIP2)                   += decompress_bunzip2.o
    43 lib-$(CONFIG_UNLZMA)                    += decompress_unlzma.o
    44 lib-$(CONFIG_UNXZ)                      += decompress_unxz.o
    45 lib-$(CONFIG_CPIO)                      += get_header_cpio.o
    4643lib-$(CONFIG_DPKG)                      += $(DPKG_FILES)
    4744lib-$(CONFIG_DPKG_DEB)                  += $(DPKG_FILES)
    48 lib-$(CONFIG_GUNZIP)                    += open_transformer.o decompress_gunzip.o
    49 lib-$(CONFIG_RPM2CPIO)                  += decompress_gunzip.o get_header_cpio.o
    50 lib-$(CONFIG_RPM)                       += open_transformer.o decompress_gunzip.o get_header_cpio.o
    51 lib-$(CONFIG_TAR)                       += get_header_tar.o
    52 lib-$(CONFIG_UNCOMPRESS)                += decompress_uncompress.o
    53 lib-$(CONFIG_UNZIP)                     += decompress_gunzip.o
     45
     46lib-$(CONFIG_AR)                        += get_header_ar.o unpack_ar_archive.o
     47lib-$(CONFIG_CPIO)                      += get_header_cpio.o
     48lib-$(CONFIG_TAR)                       += get_header_tar.o unsafe_prefix.o
     49lib-$(CONFIG_FEATURE_TAR_TO_COMMAND)    += data_extract_to_command.o
    5450lib-$(CONFIG_LZOP)                      += lzo1x_1.o lzo1x_1o.o lzo1x_d.o
    5551lib-$(CONFIG_LZOP_COMPR_HIGH)           += lzo1x_9x.o
     52lib-$(CONFIG_BUNZIP2)                   += open_transformer.o decompress_bunzip2.o
     53lib-$(CONFIG_UNLZMA)                    += open_transformer.o decompress_unlzma.o
     54lib-$(CONFIG_UNXZ)                      += open_transformer.o decompress_unxz.o
     55lib-$(CONFIG_GUNZIP)                    += open_transformer.o decompress_gunzip.o
     56lib-$(CONFIG_UNCOMPRESS)                += open_transformer.o decompress_uncompress.o
     57lib-$(CONFIG_UNZIP)                     += open_transformer.o decompress_gunzip.o unsafe_prefix.o
     58lib-$(CONFIG_RPM2CPIO)                  += open_transformer.o decompress_gunzip.o get_header_cpio.o
     59lib-$(CONFIG_RPM)                       += open_transformer.o decompress_gunzip.o get_header_cpio.o
     60
     61lib-$(CONFIG_GZIP)                      += open_transformer.o
     62lib-$(CONFIG_BZIP2)                     += open_transformer.o
     63lib-$(CONFIG_LZOP)                      += open_transformer.o
     64lib-$(CONFIG_MAN)                       += open_transformer.o
     65lib-$(CONFIG_SETFONT)                   += open_transformer.o
     66lib-$(CONFIG_FEATURE_2_4_MODULES)       += open_transformer.o
    5667lib-$(CONFIG_MODINFO)                   += open_transformer.o
    5768lib-$(CONFIG_INSMOD)                    += open_transformer.o
     69lib-$(CONFIG_DEPMOD)                    += open_transformer.o
     70lib-$(CONFIG_RMMOD)                     += open_transformer.o
     71lib-$(CONFIG_LSMOD)                     += open_transformer.o
     72lib-$(CONFIG_MODPROBE)                  += open_transformer.o
     73lib-$(CONFIG_MODPROBE_SMALL)            += open_transformer.o
     74
    5875lib-$(CONFIG_FEATURE_SEAMLESS_Z)        += open_transformer.o decompress_uncompress.o
    5976lib-$(CONFIG_FEATURE_SEAMLESS_GZ)       += open_transformer.o decompress_gunzip.o
     
    6279lib-$(CONFIG_FEATURE_SEAMLESS_XZ)       += open_transformer.o decompress_unxz.o
    6380lib-$(CONFIG_FEATURE_COMPRESS_USAGE)    += open_transformer.o decompress_bunzip2.o
    64 lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += decompress_bunzip2.o
    65 lib-$(CONFIG_FEATURE_TAR_TO_COMMAND)    += data_extract_to_command.o
     81lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += open_transformer.o decompress_bunzip2.o
    6682
    6783ifneq ($(lib-y),)
  • branches/3.3/mindi-busybox/archival/libarchive/bz/compress.c

    r3232 r3621  
    250250void sendMTFValues(EState* s)
    251251{
    252     int32_t v, t, i, j, gs, ge, totc, bt, bc, iter;
     252    int32_t v, t, i, j, gs, ge, bt, bc, iter;
    253253    int32_t nSelectors, alphaSize, minLen, maxLen, selCtr;
    254254    int32_t nGroups;
     
    346346#endif
    347347        nSelectors = 0;
    348         totc = 0;
    349348        gs = 0;
    350349        while (1) {
     
    387386                cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
    388387                cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
    389 
    390388            } else
    391389#endif
     
    412410                }
    413411            }
    414             totc += bc;
    415412            fave[bt]++;
    416413            s->selector[nSelectors] = bt;
     
    502499            if (sizeof(long) <= 4) {
    503500                inUse16 = inUse16*2 +
    504                     ((*(uint32_t*)&(s->inUse[i * 16 + 0])
    505                     | *(uint32_t*)&(s->inUse[i * 16 + 4])
    506                     | *(uint32_t*)&(s->inUse[i * 16 + 8])
    507                     | *(uint32_t*)&(s->inUse[i * 16 + 12])) != 0);
     501                    ((*(bb__aliased_uint32_t*)&(s->inUse[i * 16 + 0])
     502                    | *(bb__aliased_uint32_t*)&(s->inUse[i * 16 + 4])
     503                    | *(bb__aliased_uint32_t*)&(s->inUse[i * 16 + 8])
     504                    | *(bb__aliased_uint32_t*)&(s->inUse[i * 16 + 12])) != 0);
    508505            } else { /* Our CPU can do better */
    509506                inUse16 = inUse16*2 +
    510                     ((*(uint64_t*)&(s->inUse[i * 16 + 0])
    511                     | *(uint64_t*)&(s->inUse[i * 16 + 8])) != 0);
     507                    ((*(bb__aliased_uint64_t*)&(s->inUse[i * 16 + 0])
     508                    | *(bb__aliased_uint64_t*)&(s->inUse[i * 16 + 8])) != 0);
    512509            }
    513510        }
  • branches/3.3/mindi-busybox/archival/libarchive/data_extract_all.c

    r3232 r3621  
    1212    int dst_fd;
    1313    int res;
     14    char *hard_link;
     15#if ENABLE_FEATURE_TAR_LONG_OPTIONS
     16    char *dst_name;
     17#else
     18# define dst_name (file_header->name)
     19#endif
    1420
    1521#if ENABLE_FEATURE_TAR_SELINUX
     
    2430#endif
    2531
     32    /* Hard links are encoded as regular files of size 0
     33     * with a nonempty link field */
     34    hard_link = NULL;
     35    if (S_ISREG(file_header->mode) && file_header->size == 0)
     36        hard_link = file_header->link_target;
     37
     38#if ENABLE_FEATURE_TAR_LONG_OPTIONS
     39    dst_name = file_header->name;
     40    if (archive_handle->tar__strip_components) {
     41        unsigned n = archive_handle->tar__strip_components;
     42        do {
     43            dst_name = strchr(dst_name, '/');
     44            if (!dst_name || dst_name[1] == '\0') {
     45                data_skip(archive_handle);
     46                goto ret;
     47            }
     48            dst_name++;
     49            /*
     50             * Link target is shortened only for hardlinks:
     51             * softlinks restored unchanged.
     52             */
     53            if (hard_link) {
     54// GNU tar 1.26 does not check that we reached end of link name:
     55// if "dir/hardlink" is hardlinked to "file",
     56// tar xvf a.tar --strip-components=1 says:
     57//  tar: hardlink: Cannot hard link to '': No such file or directory
     58// and continues processing. We silently skip such entries.
     59                hard_link = strchr(hard_link, '/');
     60                if (!hard_link || hard_link[1] == '\0') {
     61                    data_skip(archive_handle);
     62                    goto ret;
     63                }
     64                hard_link++;
     65            }
     66        } while (--n != 0);
     67    }
     68#endif
     69
    2670    if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
    27         char *slash = strrchr(file_header->name, '/');
     71        char *slash = strrchr(dst_name, '/');
    2872        if (slash) {
    2973            *slash = '\0';
    30             bb_make_directory(file_header->name, -1, FILEUTILS_RECUR);
     74            bb_make_directory(dst_name, -1, FILEUTILS_RECUR);
    3175            *slash = '/';
    3276        }
     
    3680        /* Remove the entry if it exists */
    3781        if (!S_ISDIR(file_header->mode)) {
    38             /* Is it hardlink?
    39              * We encode hard links as regular files of size 0 with a symlink */
    40             if (S_ISREG(file_header->mode)
    41              && file_header->link_target
    42              && file_header->size == 0
    43             ) {
     82            if (hard_link) {
    4483                /* Ugly special case:
    4584                 * tar cf t.tar hardlink1 hardlink2 hardlink1
     
    4988                 * hardlink1 -> hardlink1 <== !!!
    5089                 */
    51                 if (strcmp(file_header->link_target, file_header->name) == 0)
     90                if (strcmp(hard_link, dst_name) == 0)
    5291                    goto ret;
    5392            }
    5493            /* Proceed with deleting */
    55             if (unlink(file_header->name) == -1
     94            if (unlink(dst_name) == -1
    5695             && errno != ENOENT
    5796            ) {
    5897                bb_perror_msg_and_die("can't remove old file %s",
    59                         file_header->name);
     98                        dst_name);
    6099            }
    61100        }
     
    64103        /* Remove the existing entry if its older than the extracted entry */
    65104        struct stat existing_sb;
    66         if (lstat(file_header->name, &existing_sb) == -1) {
     105        if (lstat(dst_name, &existing_sb) == -1) {
    67106            if (errno != ENOENT) {
    68107                bb_perror_msg_and_die("can't stat old file");
     
    74113            ) {
    75114                bb_error_msg("%s not created: newer or "
    76                     "same age file exists", file_header->name);
     115                    "same age file exists", dst_name);
    77116            }
    78117            data_skip(archive_handle);
    79118            goto ret;
    80119        }
    81         else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) {
     120        else if ((unlink(dst_name) == -1) && (errno != EISDIR)) {
    82121            bb_perror_msg_and_die("can't remove old file %s",
    83                     file_header->name);
    84         }
    85     }
    86 
    87     /* Handle hard links separately
    88      * We encode hard links as regular files of size 0 with a symlink */
    89     if (S_ISREG(file_header->mode)
    90      && file_header->link_target
    91      && file_header->size == 0
    92     ) {
    93         /* hard link */
    94         res = link(file_header->link_target, file_header->name);
    95         if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
     122                    dst_name);
     123        }
     124    }
     125
     126    /* Handle hard links separately */
     127    if (hard_link) {
     128        res = link(hard_link, dst_name);
     129        if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
    96130            bb_perror_msg("can't create %slink "
    97131                    "from %s to %s", "hard",
    98                     file_header->name,
    99                     file_header->link_target);
     132                    dst_name,
     133                    hard_link);
    100134        }
    101135        /* Hardlinks have no separate mode/ownership, skip chown/chmod */
     
    107141    case S_IFREG: {
    108142        /* Regular file */
     143        char *dst_nameN;
    109144        int flags = O_WRONLY | O_CREAT | O_EXCL;
    110145        if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
    111146            flags = O_WRONLY | O_CREAT | O_TRUNC;
    112         dst_fd = xopen3(file_header->name,
     147        dst_nameN = dst_name;
     148#ifdef ARCHIVE_REPLACE_VIA_RENAME
     149        if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME)
     150            /* rpm-style temp file name */
     151            dst_nameN = xasprintf("%s;%x", dst_name, (int)getpid());
     152#endif
     153        dst_fd = xopen3(dst_nameN,
    113154            flags,
    114155            file_header->mode
     
    116157        bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);
    117158        close(dst_fd);
     159#ifdef ARCHIVE_REPLACE_VIA_RENAME
     160        if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) {
     161            xrename(dst_nameN, dst_name);
     162            free(dst_nameN);
     163        }
     164#endif
    118165        break;
    119166    }
    120167    case S_IFDIR:
    121         res = mkdir(file_header->name, file_header->mode);
     168        res = mkdir(dst_name, file_header->mode);
    122169        if ((res == -1)
    123170         && (errno != EISDIR) /* btw, Linux doesn't return this */
     
    125172         && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
    126173        ) {
    127             bb_perror_msg("can't make dir %s", file_header->name);
     174            bb_perror_msg("can't make dir %s", dst_name);
    128175        }
    129176        break;
     
    131178        /* Symlink */
    132179//TODO: what if file_header->link_target == NULL (say, corrupted tarball?)
    133         res = symlink(file_header->link_target, file_header->name);
    134         if ((res == -1)
     180        res = symlink(file_header->link_target, dst_name);
     181        if (res != 0
    135182         && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
    136183        ) {
    137184            bb_perror_msg("can't create %slink "
    138185                "from %s to %s", "sym",
    139                 file_header->name,
     186                dst_name,
    140187                file_header->link_target);
    141188        }
     
    145192    case S_IFCHR:
    146193    case S_IFIFO:
    147         res = mknod(file_header->name, file_header->mode, file_header->device);
     194        res = mknod(dst_name, file_header->mode, file_header->device);
    148195        if ((res == -1)
    149196         && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
    150197        ) {
    151             bb_perror_msg("can't create node %s", file_header->name);
     198            bb_perror_msg("can't create node %s", dst_name);
    152199        }
    153200        break;
     
    174221#endif
    175222            /* GNU tar 1.15.1 uses chown, not lchown */
    176             chown(file_header->name, uid, gid);
     223            chown(dst_name, uid, gid);
    177224        }
    178225        /* uclibc has no lchmod, glibc is even stranger -
     
    180227         * so we use chmod... */
    181228        if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) {
    182             chmod(file_header->name, file_header->mode);
     229            chmod(dst_name, file_header->mode);
    183230        }
    184231        if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) {
     
    187234            t[1].tv_sec = t[0].tv_sec = file_header->mtime;
    188235            t[1].tv_usec = t[0].tv_usec = 0;
    189             utimes(file_header->name, t);
     236            utimes(dst_name, t);
    190237        }
    191238    }
  • branches/3.3/mindi-busybox/archival/libarchive/data_extract_to_command.c

    r3232 r3621  
    104104                "-c",
    105105                archive_handle->tar__to_command,
    106                 NULL);
     106                (char *)0);
    107107            bb_perror_msg_and_die("can't execute '%s'", archive_handle->tar__to_command_shell);
    108108        }
     
    113113        close(p[1]);
    114114
    115         if (safe_waitpid(pid, &status, 0) == -1)
    116             bb_perror_msg_and_die("waitpid");
     115        status = wait_for_exitstatus(pid);
    117116        if (WIFEXITED(status) && WEXITSTATUS(status))
    118117            bb_error_msg_and_die("'%s' returned status %d",
    119118                archive_handle->tar__to_command, WEXITSTATUS(status));
    120119        if (WIFSIGNALED(status))
    121             bb_error_msg_and_die("'%s' terminated on signal %d",
     120            bb_error_msg_and_die("'%s' terminated by signal %d",
    122121                archive_handle->tar__to_command, WTERMSIG(status));
    123122
  • branches/3.3/mindi-busybox/archival/libarchive/decompress_bunzip2.c

    r3232 r3621  
    4343#include "bb_archive.h"
    4444
     45#if 0
     46# define dbg(...) bb_error_msg(__VA_ARGS__)
     47#else
     48# define dbg(...) ((void)0)
     49#endif
     50
    4551/* Constants for Huffman coding */
    4652#define MAX_GROUPS          6
     
    5359/* Status return values */
    5460#define RETVAL_OK                       0
    55 #define RETVAL_LAST_BLOCK               (-1)
    56 #define RETVAL_NOT_BZIP_DATA            (-2)
    57 #define RETVAL_UNEXPECTED_INPUT_EOF     (-3)
    58 #define RETVAL_SHORT_WRITE              (-4)
    59 #define RETVAL_DATA_ERROR               (-5)
    60 #define RETVAL_OUT_OF_MEMORY            (-6)
    61 #define RETVAL_OBSOLETE_INPUT           (-7)
     61#define RETVAL_LAST_BLOCK               (dbg("%d", __LINE__), -1)
     62#define RETVAL_NOT_BZIP_DATA            (dbg("%d", __LINE__), -2)
     63#define RETVAL_UNEXPECTED_INPUT_EOF     (dbg("%d", __LINE__), -3)
     64#define RETVAL_SHORT_WRITE              (dbg("%d", __LINE__), -4)
     65#define RETVAL_DATA_ERROR               (dbg("%d", __LINE__), -5)
     66#define RETVAL_OUT_OF_MEMORY            (dbg("%d", __LINE__), -6)
     67#define RETVAL_OBSOLETE_INPUT           (dbg("%d", __LINE__), -7)
    6268
    6369/* Other housekeeping constants */
     
    441447        if (runPos != 0) {
    442448            uint8_t tmp_byte;
    443             if (dbufCount + runCnt >= dbufSize) return RETVAL_DATA_ERROR;
     449            if (dbufCount + runCnt > dbufSize) {
     450                dbg("dbufCount:%d+runCnt:%d %d > dbufSize:%d RETVAL_DATA_ERROR",
     451                        dbufCount, runCnt, dbufCount + runCnt, dbufSize);
     452                return RETVAL_DATA_ERROR;
     453            }
    444454            tmp_byte = symToByte[mtfSymbol[0]];
    445455            byteCount[tmp_byte] += runCnt;
     
    722732/* Decompress src_fd to dst_fd.  Stops at end of bzip data, not end of file. */
    723733IF_DESKTOP(long long) int FAST_FUNC
    724 unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
     734unpack_bz2_stream(transformer_state_t *xstate)
    725735{
    726736    IF_DESKTOP(long long total_written = 0;)
     
    730740    unsigned len;
    731741
    732     if (check_signature16(aux, src_fd, BZIP2_MAGIC))
     742    if (check_signature16(xstate, BZIP2_MAGIC))
    733743        return -1;
    734744
     
    737747    while (1) { /* "Process one BZ... stream" loop */
    738748
    739         i = start_bunzip(&bd, src_fd, outbuf + 2, len);
     749        i = start_bunzip(&bd, xstate->src_fd, outbuf + 2, len);
    740750
    741751        if (i == 0) {
     
    747757                if (i == 0) /* EOF? */
    748758                    break;
    749                 if (i != full_write(dst_fd, outbuf, i)) {
    750                     bb_error_msg("short write");
     759                if (i != transformer_write(xstate, outbuf, i)) {
    751760                    i = RETVAL_SHORT_WRITE;
    752761                    goto release_mem;
     
    781790        memcpy(outbuf, &bd->inbuf[bd->inbufPos], len);
    782791        if (len < 2) {
    783             if (safe_read(src_fd, outbuf + len, 2 - len) != 2 - len)
     792            if (safe_read(xstate->src_fd, outbuf + len, 2 - len) != 2 - len)
    784793                break;
    785794            len = 2;
     
    809818int main(int argc, char **argv)
    810819{
    811     int i;
    812820    char c;
    813821
  • branches/3.3/mindi-busybox/archival/libarchive/decompress_gunzip.c

    r3233 r3621  
    306306    unsigned j;             /* counter */
    307307    int k;                  /* number of bits in current code */
    308     unsigned *p;            /* pointer into c[], b[], or v[] */
     308    const unsigned *p;      /* pointer into c[], b[], or v[] */
    309309    huft_t *q;              /* points to current table */
    310310    huft_t r;               /* table entry for structure assignment */
    311311    huft_t *u[BMAX];        /* table stack */
    312     unsigned v[N_MAX];      /* values in order of bit length */
     312    unsigned v[N_MAX + 1];  /* values in order of bit length. last v[] is never used */
    313313    int ws[BMAX + 1];       /* bits decoded stack */
    314314    int w;                  /* bits decoded */
     
    325325    /* Generate counts for each bit length */
    326326    memset(c, 0, sizeof(c));
    327     p = (unsigned *) b; /* cast allows us to reuse p for pointing to b */
     327    p = b;
    328328    i = n;
    329329    do {
     
    337337
    338338    /* Find minimum and maximum length, bound *m by those */
    339     for (j = 1; (c[j] == 0) && (j <= BMAX); j++)
     339    for (j = 1; (j <= BMAX) && (c[j] == 0); j++)
    340340        continue;
    341341    k = j; /* minimum code length */
     
    365365    }
    366366
    367     /* Make a table of values in order of bit lengths */
    368     p = (unsigned *) b;
     367    /* Make a table of values in order of bit lengths.
     368     * To detect bad input, unused v[i]'s are set to invalid value UINT_MAX.
     369     * In particular, last v[i] is never filled and must not be accessed.
     370     */
     371    memset(v, 0xff, sizeof(v));
     372    p = b;
    369373    i = 0;
    370374    do {
     
    433437            /* set up table entry in r */
    434438            r.b = (unsigned char) (k - w);
    435             if (p >= v + n) {
     439            if (/*p >= v + n || -- redundant, caught by the second check: */
     440                *p == UINT_MAX /* do we access uninited v[i]? (see memset(v))*/
     441            ) {
    436442                r.e = 99; /* out of values--invalid code */
    437443            } else if (*p < s) {
     
    518524        if (e > 16)
    519525            do {
    520                 if (e == 99)
    521                     abort_unzip(PASS_STATE_ONLY);;
     526                if (e == 99) {
     527                    abort_unzip(PASS_STATE_ONLY);
     528                }
    522529                bb >>= t->b;
    523530                k -= t->b;
     
    555562            if (e > 16)
    556563                do {
    557                     if (e == 99)
     564                    if (e == 99) {
    558565                        abort_unzip(PASS_STATE_ONLY);
     566                    }
    559567                    bb >>= t->b;
    560568                    k -= t->b;
     
    822830        b_dynamic >>= 4;
    823831        k_dynamic -= 4;
    824         if (nl > 286 || nd > 30)
     832        if (nl > 286 || nd > 30) {
    825833            abort_unzip(PASS_STATE_ONLY);   /* bad lengths */
     834        }
    826835
    827836        /* read in bit-length-code lengths */
     
    904913
    905914        i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl);
    906         if (i != 0)
     915        if (i != 0) {
    907916            abort_unzip(PASS_STATE_ONLY);
     917        }
    908918        bd = dbits;
    909919        i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd);
    910         if (i != 0)
     920        if (i != 0) {
    911921            abort_unzip(PASS_STATE_ONLY);
     922        }
    912923
    913924        /* set up data for inflate_codes() */
     
    972983/* Called from unpack_gz_stream() and inflate_unzip() */
    973984static IF_DESKTOP(long long) int
    974 inflate_unzip_internal(STATE_PARAM int in, int out)
     985inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate)
    975986{
    976987    IF_DESKTOP(long long) int n = 0;
     
    981992    gunzip_outbuf_count = 0;
    982993    gunzip_bytes_out = 0;
    983     gunzip_src_fd = in;
     994    gunzip_src_fd = xstate->src_fd;
    984995
    985996    /* (re) initialize state */
     
    9971008    if (setjmp(error_jmp)) {
    9981009        /* Error from deep inside zip machinery */
     1010        bb_error_msg(error_msg);
    9991011        n = -1;
    10001012        goto ret;
     
    10031015    while (1) {
    10041016        int r = inflate_get_next_window(PASS_STATE_ONLY);
    1005         nwrote = full_write(out, gunzip_window, gunzip_outbuf_count);
    1006         if (nwrote != (ssize_t)gunzip_outbuf_count) {
    1007             bb_perror_msg("write");
     1017        nwrote = transformer_write(xstate, gunzip_window, gunzip_outbuf_count);
     1018        if (nwrote == (ssize_t)-1) {
    10081019            n = -1;
    10091020            goto ret;
     
    10351046
    10361047IF_DESKTOP(long long) int FAST_FUNC
    1037 inflate_unzip(transformer_aux_data_t *aux, int in, int out)
     1048inflate_unzip(transformer_state_t *xstate)
    10381049{
    10391050    IF_DESKTOP(long long) int n;
     
    10421053    ALLOC_STATE;
    10431054
    1044     to_read = aux->bytes_in;
     1055    to_read = xstate->bytes_in;
    10451056//  bytebuffer_max = 0x8000;
    10461057    bytebuffer_offset = 4;
    10471058    bytebuffer = xmalloc(bytebuffer_max);
    1048     n = inflate_unzip_internal(PASS_STATE in, out);
     1059    n = inflate_unzip_internal(PASS_STATE xstate);
    10491060    free(bytebuffer);
    10501061
    1051     aux->crc32 = gunzip_crc;
    1052     aux->bytes_out = gunzip_bytes_out;
     1062    xstate->crc32 = gunzip_crc;
     1063    xstate->bytes_out = gunzip_bytes_out;
    10531064    DEALLOC_STATE;
    10541065    return n;
     
    11081119}
    11091120
    1110 static int check_header_gzip(STATE_PARAM transformer_aux_data_t *aux)
     1121static int check_header_gzip(STATE_PARAM transformer_state_t *xstate)
    11111122{
    11121123    union {
     
    11201131        } PACKED formatted;
    11211132    } header;
    1122     struct BUG_header {
    1123         char BUG_header[sizeof(header) == 8 ? 1 : -1];
    1124     };
     1133
     1134    BUILD_BUG_ON(sizeof(header) != 8);
    11251135
    11261136    /*
     
    11701180    }
    11711181
    1172     if (aux)
    1173         aux->mtime = SWAP_LE32(header.formatted.mtime);
     1182    xstate->mtime = SWAP_LE32(header.formatted.mtime);
    11741183
    11751184    /* Read the header checksum */
     
    11831192
    11841193IF_DESKTOP(long long) int FAST_FUNC
    1185 unpack_gz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
     1194unpack_gz_stream(transformer_state_t *xstate)
    11861195{
    11871196    uint32_t v32;
     
    11901199
    11911200#if !ENABLE_FEATURE_SEAMLESS_Z
    1192     if (check_signature16(aux, src_fd, GZIP_MAGIC))
     1201    if (check_signature16(xstate, GZIP_MAGIC))
    11931202        return -1;
    11941203#else
    1195     if (aux && aux->check_signature) {
     1204    if (!xstate->signature_skipped) {
    11961205        uint16_t magic2;
    11971206
    1198         if (full_read(src_fd, &magic2, 2) != 2) {
     1207        if (full_read(xstate->src_fd, &magic2, 2) != 2) {
    11991208 bad_magic:
    12001209            bb_error_msg("invalid magic");
     
    12021211        }
    12031212        if (magic2 == COMPRESS_MAGIC) {
    1204             aux->check_signature = 0;
    1205             return unpack_Z_stream(aux, src_fd, dst_fd);
     1213            xstate->signature_skipped = 2;
     1214            return unpack_Z_stream(xstate);
    12061215        }
    12071216        if (magic2 != GZIP_MAGIC)
     
    12161225//  bytebuffer_max = 0x8000;
    12171226    bytebuffer = xmalloc(bytebuffer_max);
    1218     gunzip_src_fd = src_fd;
     1227    gunzip_src_fd = xstate->src_fd;
    12191228
    12201229 again:
    1221     if (!check_header_gzip(PASS_STATE aux)) {
     1230    if (!check_header_gzip(PASS_STATE xstate)) {
    12221231        bb_error_msg("corrupted data");
    12231232        total = -1;
     
    12251234    }
    12261235
    1227     n = inflate_unzip_internal(PASS_STATE src_fd, dst_fd);
     1236    n = inflate_unzip_internal(PASS_STATE xstate);
    12281237    if (n < 0) {
    12291238        total = -1;
  • branches/3.3/mindi-busybox/archival/libarchive/decompress_uncompress.c

    r3232 r3621  
    7474
    7575IF_DESKTOP(long long) int FAST_FUNC
    76 unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
     76unpack_Z_stream(transformer_state_t *xstate)
    7777{
    7878    IF_DESKTOP(long long total_written = 0;)
     
    103103    int block_mode; /* = BLOCK_MODE; */
    104104
    105     if (check_signature16(aux, src_fd, COMPRESS_MAGIC))
     105    if (check_signature16(xstate, COMPRESS_MAGIC))
    106106        return -1;
    107107
     
    115115    /* xread isn't good here, we have to return - caller may want
    116116     * to do some cleanup (e.g. delete incomplete unpacked file etc) */
    117     if (full_read(src_fd, inbuf, 1) != 1) {
     117    if (full_read(xstate->src_fd, inbuf, 1) != 1) {
    118118        bb_error_msg("short read");
    119119        goto err;
     
    167167
    168168        if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
    169             rsize = safe_read(src_fd, inbuf + insize, IBUFSIZ);
     169            rsize = safe_read(xstate->src_fd, inbuf + insize, IBUFSIZ);
    170170            if (rsize < 0)
    171171                bb_error_msg_and_die(bb_msg_read_error);
     
    275275
    276276                        if (outpos >= OBUFSIZ) {
    277                             xwrite(dst_fd, outbuf, outpos);
     277                            xtransformer_write(xstate, outbuf, outpos);
    278278                            IF_DESKTOP(total_written += outpos;)
    279279                            outpos = 0;
     
    298298            oldcode = incode;
    299299        }
    300 
    301300    } while (rsize > 0);
    302301
    303302    if (outpos > 0) {
    304         xwrite(dst_fd, outbuf, outpos);
     303        xtransformer_write(xstate, outbuf, outpos);
    305304        IF_DESKTOP(total_written += outpos;)
    306305    }
  • branches/3.3/mindi-busybox/archival/libarchive/decompress_unlzma.c

    r3232 r3621  
    4646
    4747
    48 /* Called twice: once at startup (LZMA_FAST only) and once in rc_normalize() */
    49 static size_inline void rc_read(rc_t *rc)
     48/* Called once in rc_do_normalize() */
     49static void rc_read(rc_t *rc)
    5050{
    5151    int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE);
     
    5454    if (buffer_size <= 0)
    5555        bb_error_msg_and_die("unexpected EOF");
     56    rc->buffer_end = RC_BUFFER + buffer_size;
    5657    rc->ptr = RC_BUFFER;
    57     rc->buffer_end = RC_BUFFER + buffer_size;
    5858}
    5959
     
    6666    rc->code = (rc->code << 8) | *rc->ptr++;
    6767}
     68static ALWAYS_INLINE void rc_normalize(rc_t *rc)
     69{
     70    if (rc->range < (1 << RC_TOP_BITS)) {
     71        rc_do_normalize(rc);
     72    }
     73}
    6874
    6975/* Called once */
     
    7985
    8086    for (i = 0; i < 5; i++) {
    81 #if ENABLE_FEATURE_LZMA_FAST
    82         if (rc->ptr >= rc->buffer_end)
    83             rc_read(rc);
    84         rc->code = (rc->code << 8) | *rc->ptr++;
    85 #else
    8687        rc_do_normalize(rc);
    87 #endif
    88     }
    89     rc->range = 0xFFFFFFFF;
     88    }
     89    rc->range = 0xffffffff;
    9090    return rc;
    9191}
     
    9595{
    9696    free(rc);
    97 }
    98 
    99 static ALWAYS_INLINE void rc_normalize(rc_t *rc)
    100 {
    101     if (rc->range < (1 << RC_TOP_BITS)) {
    102         rc_do_normalize(rc);
    103     }
    10497}
    10598
     
    121114
    122115/* Called 4 times in unlzma loop */
    123 static speed_inline int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol)
     116static ALWAYS_INLINE int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol)
    124117{
    125118    int ret = rc_is_bit_1(rc, p);
     
    214207
    215208IF_DESKTOP(long long) int FAST_FUNC
    216 unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst_fd)
     209unpack_lzma_stream(transformer_state_t *xstate)
    217210{
    218211    IF_DESKTOP(long long total_written = 0;)
     
    222215    uint32_t literal_pos_mask;
    223216    uint16_t *p;
    224     int num_bits;
    225     int num_probs;
    226217    rc_t *rc;
    227218    int i;
     
    233224    uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
    234225
    235     if (full_read(src_fd, &header, sizeof(header)) != sizeof(header)
     226    if (full_read(xstate->src_fd, &header, sizeof(header)) != sizeof(header)
    236227     || header.pos >= (9 * 5 * 5)
    237228    ) {
     
    247238    literal_pos_mask = (1 << lp) - 1;
    248239
     240    /* Example values from linux-3.3.4.tar.lzma:
     241     * dict_size: 64M, dst_size: 2^64-1
     242     */
    249243    header.dict_size = SWAP_LE32(header.dict_size);
    250244    header.dst_size = SWAP_LE64(header.dst_size);
     
    255249    buffer = xmalloc(MIN(header.dst_size, header.dict_size));
    256250
    257     num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
    258     p = xmalloc(num_probs * sizeof(*p));
    259     num_probs += LZMA_LITERAL - LZMA_BASE_SIZE;
    260     for (i = 0; i < num_probs; i++)
    261         p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
    262 
    263     rc = rc_init(src_fd); /*, RC_BUFFER_SIZE); */
     251    {
     252        int num_probs;
     253
     254        num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
     255        p = xmalloc(num_probs * sizeof(*p));
     256        num_probs += LZMA_LITERAL - LZMA_BASE_SIZE;
     257        for (i = 0; i < num_probs; i++)
     258            p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
     259    }
     260
     261    rc = rc_init(xstate->src_fd); /*, RC_BUFFER_SIZE); */
    264262
    265263    while (global_pos + buffer_pos < header.dst_size) {
     
    309307                buffer_pos = 0;
    310308                global_pos += header.dict_size;
    311                 if (full_write(dst_fd, buffer, header.dict_size) != (ssize_t)header.dict_size)
     309                if (transformer_write(xstate, buffer, header.dict_size) != (ssize_t)header.dict_size)
    312310                    goto bad;
    313311                IF_DESKTOP(total_written += header.dict_size;)
     
    318316#endif
    319317        } else {
     318            int num_bits;
    320319            int offset;
    321320            uint16_t *prob2;
     
    442441                    buffer_pos = 0;
    443442                    global_pos += header.dict_size;
    444                     if (full_write(dst_fd, buffer, header.dict_size) != (ssize_t)header.dict_size)
     443                    if (transformer_write(xstate, buffer, header.dict_size) != (ssize_t)header.dict_size)
    445444                        goto bad;
    446445                    IF_DESKTOP(total_written += header.dict_size;)
     
    448447                len--;
    449448            } while (len != 0 && buffer_pos < header.dst_size);
     449            /* FIXME: ...........^^^^^
     450             * shouldn't it be "global_pos + buffer_pos < header.dst_size"?
     451             */
    450452        }
    451453    }
     
    454456        IF_NOT_DESKTOP(int total_written = 0; /* success */)
    455457        IF_DESKTOP(total_written += buffer_pos;)
    456         if (full_write(dst_fd, buffer, buffer_pos) != (ssize_t)buffer_pos) {
     458        if (transformer_write(xstate, buffer, buffer_pos) != (ssize_t)buffer_pos) {
    457459 bad:
    458460            total_written = -1; /* failure */
  • branches/3.3/mindi-busybox/archival/libarchive/decompress_unxz.c

    r3232 r3621  
    3939
    4040IF_DESKTOP(long long) int FAST_FUNC
    41 unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
     41unpack_xz_stream(transformer_state_t *xstate)
    4242{
    4343    enum xz_ret xz_result;
     
    5656    iobuf.out_size = BUFSIZ;
    5757
    58     if (!aux || aux->check_signature == 0) {
     58    if (!xstate || xstate->signature_skipped) {
    5959        /* Preload XZ file signature */
    6060        strcpy((char*)membuf, HEADER_MAGIC);
     
    6868    while (1) {
    6969        if (iobuf.in_pos == iobuf.in_size) {
    70             int rd = safe_read(src_fd, membuf, BUFSIZ);
     70            int rd = safe_read(xstate->src_fd, membuf, BUFSIZ);
    7171            if (rd < 0) {
    7272                bb_error_msg(bb_msg_read_error);
     
    105105//              iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, xz_result);
    106106        if (iobuf.out_pos) {
    107             xwrite(dst_fd, iobuf.out, iobuf.out_pos);
     107            xtransformer_write(xstate, iobuf.out, iobuf.out_pos);
    108108            IF_DESKTOP(total += iobuf.out_pos;)
    109109            iobuf.out_pos = 0;
  • branches/3.3/mindi-busybox/archival/libarchive/filter_accept_list_reassign.c

    r3232 r3621  
    2929
    3030        /* Modify the subarchive handler based on the extension */
     31        if (strcmp(name_ptr, "tar") == 0) {
     32            archive_handle->dpkg__action_data_subarchive = get_header_tar;
     33            return EXIT_SUCCESS;
     34        }
    3135        if (ENABLE_FEATURE_SEAMLESS_GZ
    3236         && strcmp(name_ptr, "gz") == 0
     
    4751            return EXIT_SUCCESS;
    4852        }
     53        if (ENABLE_FEATURE_SEAMLESS_XZ
     54         && strcmp(name_ptr, "xz") == 0
     55        ) {
     56            archive_handle->dpkg__action_data_subarchive = get_header_tar_xz;
     57            return EXIT_SUCCESS;
     58        }
    4959    }
    5060    return EXIT_FAILURE;
  • branches/3.3/mindi-busybox/archival/libarchive/get_header_ar.c

    r3232 r3621  
    99#include "ar.h"
    1010
    11 static unsigned read_num(const char *str, int base)
     11/* WARNING: Clobbers str[len], so fields must be read in reverse order! */
     12static unsigned read_num(char *str, int base, int len)
    1213{
     14    int err;
     15
     16    /* ar fields are fixed length text strings (padded with spaces).
     17     * Ensure bb_strtou doesn't read past the field in case the full
     18     * width is used. */
     19    str[len] = 0;
     20
    1321    /* This code works because
    1422     * on misformatted numbers bb_strtou returns all-ones */
    15     int err = bb_strtou(str, NULL, base);
     23    err = bb_strtou(str, NULL, base);
    1624    if (err == -1)
    1725        bb_error_msg_and_die("invalid ar header");
     
    5260        bb_error_msg_and_die("invalid ar header");
    5361
    54     /* FIXME: more thorough routine would be in order here
    55      * (we have something like that in tar)
    56      * but for now we are lax. */
    57     ar.formatted.magic[0] = '\0'; /* else 4G-2 file will have size="4294967294`\n..." */
    58     typed->size = size = read_num(ar.formatted.size, 10);
     62    /*
     63     * Note that the fields MUST be read in reverse order as
     64     * read_num() clobbers the next byte after the field!
     65     * Order is: name, date, uid, gid, mode, size, magic.
     66     */
     67    typed->size = size = read_num(ar.formatted.size, 10,
     68                      sizeof(ar.formatted.size));
    5969
    6070    /* special filenames have '/' as the first character */
     
    8898     * after dealing with long filename pseudo file.
    8999     */
    90     typed->mode = read_num(ar.formatted.mode, 8);
    91     typed->mtime = read_num(ar.formatted.date, 10);
    92     typed->uid = read_num(ar.formatted.uid, 10);
    93     typed->gid = read_num(ar.formatted.gid, 10);
     100    typed->mode = read_num(ar.formatted.mode, 8, sizeof(ar.formatted.mode));
     101    typed->gid = read_num(ar.formatted.gid, 10, sizeof(ar.formatted.gid));
     102    typed->uid = read_num(ar.formatted.uid, 10, sizeof(ar.formatted.uid));
     103    typed->mtime = read_num(ar.formatted.date, 10, sizeof(ar.formatted.date));
    94104
    95105#if ENABLE_FEATURE_AR_LONG_FILENAMES
     
    99109        /* The number after the '/' indicates the offset in the ar data section
    100110         * (saved in ar_long_names) that conatains the real filename */
    101         long_offset = read_num(&ar.formatted.name[1], 10);
     111        long_offset = read_num(&ar.formatted.name[1], 10,
     112                       sizeof(ar.formatted.name) - 1);
    102113        if (long_offset >= ar_long_name_size) {
    103114            bb_error_msg_and_die("can't resolve long filename");
  • branches/3.3/mindi-busybox/archival/libarchive/get_header_cpio.c

    r3232 r3621  
    3838    archive_handle->offset += 110;
    3939
    40     if (strncmp(&cpio_header[0], "07070", 5) != 0
     40    if (!is_prefixed_with(&cpio_header[0], "07070")
    4141     || (cpio_header[5] != '1' && cpio_header[5] != '2')
    4242    ) {
     
    5353        bb_error_msg_and_die("damaged cpio file");
    5454    file_header->mode = mode;
     55    /* "cpio -R USER:GRP" support: */
     56    if (archive_handle->cpio__owner.uid != (uid_t)-1L)
     57        uid = archive_handle->cpio__owner.uid;
     58    if (archive_handle->cpio__owner.gid != (gid_t)-1L)
     59        gid = archive_handle->cpio__owner.gid;
    5560    file_header->uid = uid;
    5661    file_header->gid = gid;
     
    7681    data_align(archive_handle, 4);
    7782
    78     if (strcmp(file_header->name, "TRAILER!!!") == 0) {
     83    if (strcmp(file_header->name, cpio_TRAILER) == 0) {
    7984        /* Always round up. ">> 9" divides by 512 */
    8085        archive_handle->cpio__blocks = (uoff_t)(archive_handle->offset + 511) >> 9;
  • branches/3.3/mindi-busybox/archival/libarchive/get_header_tar.c

    r3232 r3621  
    1717typedef uint32_t aliased_uint32_t FIX_ALIASING;
    1818typedef off_t    aliased_off_t    FIX_ALIASING;
    19 
    20 
    21 const char* FAST_FUNC strip_unsafe_prefix(const char *str)
    22 {
    23     const char *cp = str;
    24     while (1) {
    25         char *cp2;
    26         if (*cp == '/') {
    27             cp++;
    28             continue;
    29         }
    30         if (strncmp(cp, "/../"+1, 3) == 0) {
    31             cp += 3;
    32             continue;
    33         }
    34         cp2 = strstr(cp, "/../");
    35         if (!cp2)
    36             break;
    37         cp = cp2 + 4;
    38     }
    39     if (cp != str) {
    40         static smallint warned = 0;
    41         if (!warned) {
    42             warned = 1;
    43             bb_error_msg("removing leading '%.*s' from member names",
    44                 (int)(cp - str), str);
    45         }
    46     }
    47     return cp;
    48 }
    4919
    5020/* NB: _DESTROYS_ str[len] character! */
     
    9161#define GET_OCTAL(a) getOctal((a), sizeof(a))
    9262
     63#define TAR_EXTD (ENABLE_FEATURE_TAR_GNU_EXTENSIONS || ENABLE_FEATURE_TAR_SELINUX)
     64#if !TAR_EXTD
     65#define process_pax_hdr(archive_handle, sz, global) \
     66    process_pax_hdr(archive_handle, sz)
     67#endif
    9368/* "global" is 0 or 1 */
    9469static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int global)
    9570{
     71#if !TAR_EXTD
     72    unsigned blk_sz = (sz + 511) & (~511);
     73    seek_by_read(archive_handle->src_fd, blk_sz);
     74#else
     75    unsigned blk_sz = (sz + 511) & (~511);
    9676    char *buf, *p;
    97     unsigned blk_sz;
    98 
    99     blk_sz = (sz + 511) & (~511);
     77
    10078    p = buf = xmalloc(blk_sz + 1);
    10179    xread(archive_handle->src_fd, buf, blk_sz);
     
    11694        p += len;
    11795        sz -= len;
    118         if ((int)sz < 0
     96        if (
     97        /** (int)sz < 0 - not good enough for huge malicious VALUE of 2^32-1 */
     98            (int)(sz|len) < 0 /* this works */
    11999         || len == 0
    120100         || errno != EINVAL
     
    133113        value = end + 1;
    134114
    135 #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
    136         if (!global && strncmp(value, "path=", sizeof("path=") - 1) == 0) {
     115# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
     116        if (!global && is_prefixed_with(value, "path=")) {
    137117            value += sizeof("path=") - 1;
    138118            free(archive_handle->tar__longname);
     
    140120            continue;
    141121        }
    142 #endif
    143 
    144 #if ENABLE_FEATURE_TAR_SELINUX
     122# endif
     123
     124# if ENABLE_FEATURE_TAR_SELINUX
    145125        /* Scan for SELinux contexts, via "RHT.security.selinux" keyword.
    146126         * This is what Red Hat's patched version of tar uses.
    147127         */
    148 # define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux"
    149         if (strncmp(value, SELINUX_CONTEXT_KEYWORD"=", sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1) == 0) {
     128#  define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux"
     129        if (is_prefixed_with(value, SELINUX_CONTEXT_KEYWORD"=")) {
    150130            value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1;
    151131            free(archive_handle->tar__sctx[global]);
     
    153133            continue;
    154134        }
    155 #endif
     135# endif
    156136    }
    157137
    158138    free(buf);
     139#endif
    159140}
    160141
     
    199180     * saw zero block directly before this. */
    200181    if (i == 0) {
    201         xfunc_error_retval = 0;
    202  short_read:
    203         bb_error_msg_and_die("short read");
     182        bb_error_msg("short read");
     183        /* this merely signals end of archive, not exit(1): */
     184        return EXIT_FAILURE;
    204185    }
    205186    if (i != 512) {
    206187        IF_FEATURE_TAR_AUTODETECT(goto autodetect;)
    207         goto short_read;
     188        bb_error_msg_and_die("short read");
    208189    }
    209190
     
    222203            while (full_read(archive_handle->src_fd, &tar, 512) == 512)
    223204                continue;
    224             return EXIT_FAILURE;
     205            return EXIT_FAILURE; /* "end of archive" */
    225206        }
    226207        archive_handle->tar__end = 1;
    227         return EXIT_SUCCESS;
     208        return EXIT_SUCCESS; /* "decoded one header" */
    228209    }
    229210    archive_handle->tar__end = 0;
     
    231212    /* Check header has valid magic, "ustar" is for the proper tar,
    232213     * five NULs are for the old tar format  */
    233     if (strncmp(tar.magic, "ustar", 5) != 0
     214    if (!is_prefixed_with(tar.magic, "ustar")
    234215     && (!ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY
    235216         || memcmp(tar.magic, "\0\0\0\0", 5) != 0)
     
    242223        if (lseek(archive_handle->src_fd, -i, SEEK_CUR) != 0)
    243224            goto err;
    244         if (setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_detected:*/ 0) != 0)
     225        if (setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_compressed:*/ 0) != 0)
    245226 err:
    246227            bb_error_msg_and_die("invalid tar magic");
     
    379360        file_header->mode |= S_IFIFO;
    380361        goto size0;
     362    case 'g':   /* pax global header */
     363    case 'x': { /* pax extended header */
     364        if ((uoff_t)file_header->size > 0xfffff) /* paranoia */
     365            goto skip_ext_hdr;
     366        process_pax_hdr(archive_handle, file_header->size, (tar.typeflag == 'g'));
     367        goto again_after_align;
    381368#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
     369/* See http://www.gnu.org/software/tar/manual/html_node/Extensions.html */
    382370    case 'L':
    383371        /* free: paranoia: tar with several consecutive longnames */
     
    399387        /* return get_header_tar(archive_handle); */
    400388        goto again;
    401     case 'D':   /* GNU dump dir */
    402     case 'M':   /* Continuation of multi volume archive */
    403     case 'N':   /* Old GNU for names > 100 characters */
    404     case 'S':   /* Sparse file */
    405     case 'V':   /* Volume header */
    406 #endif
    407     case 'g':   /* pax global header */
    408     case 'x': { /* pax extended header */
    409         if ((uoff_t)file_header->size > 0xfffff) /* paranoia */
    410             goto skip_ext_hdr;
    411         process_pax_hdr(archive_handle, file_header->size, (tar.typeflag == 'g'));
    412         goto again_after_align;
     389/*
     390 *  case 'S':   // Sparse file
     391 * Was seen in the wild. Not supported (yet?).
     392 * See https://www.gnu.org/software/tar/manual/html_section/tar_92.html
     393 * for the format. (An "Old GNU Format" was seen, not PAX formats).
     394 */
     395//  case 'D':   /* GNU dump dir */
     396//  case 'M':   /* Continuation of multi volume archive */
     397//  case 'N':   /* Old GNU for names > 100 characters */
     398//  case 'V':   /* Volume header */
     399#endif
    413400    }
    414401 skip_ext_hdr:
     
    441428    /* Everything up to and including last ".." component is stripped */
    442429    overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name));
     430//TODO: do the same for file_header->link_target?
    443431
    444432    /* Strip trailing '/' in directories */
     
    472460    free(file_header->tar__gname);
    473461#endif
    474     return EXIT_SUCCESS;
     462    return EXIT_SUCCESS; /* "decoded one header" */
    475463}
  • branches/3.3/mindi-busybox/archival/libarchive/get_header_tar_bz2.c

    r3232 r3621  
    1212    archive_handle->seek = seek_by_read;
    1313
    14     open_transformer_with_sig(archive_handle->src_fd, unpack_bz2_stream, "bunzip2");
     14    fork_transformer_with_sig(archive_handle->src_fd, unpack_bz2_stream, "bunzip2");
    1515    archive_handle->offset = 0;
    1616    while (get_header_tar(archive_handle) == EXIT_SUCCESS)
  • branches/3.3/mindi-busybox/archival/libarchive/get_header_tar_gz.c

    r3232 r3621  
    1212    archive_handle->seek = seek_by_read;
    1313
    14     open_transformer_with_sig(archive_handle->src_fd, unpack_gz_stream, "gunzip");
     14    fork_transformer_with_sig(archive_handle->src_fd, unpack_gz_stream, "gunzip");
    1515    archive_handle->offset = 0;
    1616    while (get_header_tar(archive_handle) == EXIT_SUCCESS)
  • branches/3.3/mindi-busybox/archival/libarchive/get_header_tar_lzma.c

    r3232 r3621  
    1515    archive_handle->seek = seek_by_read;
    1616
    17     open_transformer_with_sig(archive_handle->src_fd, unpack_lzma_stream, "unlzma");
     17    fork_transformer_with_sig(archive_handle->src_fd, unpack_lzma_stream, "unlzma");
    1818    archive_handle->offset = 0;
    1919    while (get_header_tar(archive_handle) == EXIT_SUCCESS)
  • branches/3.3/mindi-busybox/archival/libarchive/liblzo.h

    r2725 r3621  
    7777#    define NEED_IP(x) \
    7878            if ((unsigned)(ip_end - ip) < (unsigned)(x))  goto input_overrun
     79#    define TEST_IV(x)          if ((x) > (unsigned)0 - (511)) goto input_overrun
    7980
    8081#    undef TEST_OP              /* don't need both of the tests here */
     
    8283#    define NEED_OP(x) \
    8384            if ((unsigned)(op_end - op) < (unsigned)(x))  goto output_overrun
     85#    define TEST_OV(x)          if ((x) > (unsigned)0 - (511)) goto output_overrun
    8486
    8587#define HAVE_ANY_OP 1
  • branches/3.3/mindi-busybox/archival/libarchive/lzo1x_9x.c

    r3232 r3621  
    7272
    7373    unsigned r1_lit;
    74 
    7574} lzo1x_999_t;
    7675
     
    9594
    9695#if defined(LZO_UNALIGNED_OK_2)
    97 #  define HEAD2(b,p)      (* (uint16_t *) &(b[p]))
     96#  define HEAD2(b,p)      (* (bb__aliased_uint16_t *) &(b[p]))
    9897#else
    9998#  define HEAD2(b,p)      (b[p] ^ ((unsigned)b[p+1]<<8))
     
    466465    }
    467466
    468     s->m_len = 1;
    469467    s->m_len = 1;
    470468#ifdef SWD_BEST_OFF
  • branches/3.3/mindi-busybox/archival/libarchive/lzo1x_d.c

    r3232 r3621  
    9393                NEED_IP(1);
    9494            }
     95            TEST_IV(t);
    9596            t += 15 + *ip++;
    9697        }
     
    225226                        NEED_IP(1);
    226227                    }
     228                    TEST_IV(t);
    227229                    t += 31 + *ip++;
    228230                }
     
    266268                        NEED_IP(1);
    267269                    }
     270                    TEST_IV(t);
    268271                    t += 7 + *ip++;
    269272                }
  • branches/3.3/mindi-busybox/archival/libarchive/open_transformer.c

    r3232 r3621  
    77#include "bb_archive.h"
    88
    9 void FAST_FUNC init_transformer_aux_data(transformer_aux_data_t *aux)
    10 {
    11     memset(aux, 0, sizeof(*aux));
    12 }
    13 
    14 int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigned magic16)
    15 {
    16     if (aux && aux->check_signature) {
     9void FAST_FUNC init_transformer_state(transformer_state_t *xstate)
     10{
     11    memset(xstate, 0, sizeof(*xstate));
     12}
     13
     14int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16)
     15{
     16    if (!xstate->signature_skipped) {
    1717        uint16_t magic2;
    18         if (full_read(src_fd, &magic2, 2) != 2 || magic2 != magic16) {
     18        if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) {
    1919            bb_error_msg("invalid magic");
    20 #if 0 /* possible future extension */
    21             if (aux->check_signature > 1)
    22                 xfunc_die();
    23 #endif
    2420            return -1;
    2521        }
     22        xstate->signature_skipped = 2;
    2623    }
    2724    return 0;
     25}
     26
     27ssize_t FAST_FUNC transformer_write(transformer_state_t *xstate, const void *buf, size_t bufsize)
     28{
     29    ssize_t nwrote;
     30
     31    if (xstate->mem_output_size_max != 0) {
     32        size_t pos = xstate->mem_output_size;
     33        size_t size;
     34
     35        size = (xstate->mem_output_size += bufsize);
     36        if (size > xstate->mem_output_size_max) {
     37            free(xstate->mem_output_buf);
     38            xstate->mem_output_buf = NULL;
     39            bb_perror_msg("buffer %u too small", (unsigned)xstate->mem_output_size_max);
     40            nwrote = -1;
     41            goto ret;
     42        }
     43        xstate->mem_output_buf = xrealloc(xstate->mem_output_buf, size + 1);
     44        memcpy(xstate->mem_output_buf + pos, buf, bufsize);
     45        xstate->mem_output_buf[size] = '\0';
     46        nwrote = bufsize;
     47    } else {
     48        nwrote = full_write(xstate->dst_fd, buf, bufsize);
     49        if (nwrote != (ssize_t)bufsize) {
     50            bb_perror_msg("write");
     51            nwrote = -1;
     52            goto ret;
     53        }
     54    }
     55 ret:
     56    return nwrote;
     57}
     58
     59ssize_t FAST_FUNC xtransformer_write(transformer_state_t *xstate, const void *buf, size_t bufsize)
     60{
     61    ssize_t nwrote = transformer_write(xstate, buf, bufsize);
     62    if (nwrote != (ssize_t)bufsize) {
     63        xfunc_die();
     64    }
     65    return nwrote;
    2866}
    2967
     
    3573        /* block waiting for any child */
    3674        if (wait(&status) < 0)
     75//FIXME: check EINTR?
    3776            return; /* probably there are no children */
    3877        goto check_status;
     
    4281    for (;;) {
    4382        if (wait_any_nohang(&status) < 0)
     83//FIXME: check EINTR?
    4484            /* wait failed?! I'm confused... */
    4585            return;
    4686 check_status:
    47         if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
     87        /*if (WIFEXITED(status) && WEXITSTATUS(status) == 0)*/
     88        /* On Linux, the above can be checked simply as: */
     89        if (status == 0)
    4890            /* this child exited with 0 */
    4991            continue;
    50         /* Cannot happen?
    51         if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???; */
     92        /* Cannot happen:
     93        if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???;
     94         */
    5295        bb_got_signal = 1;
    5396    }
     
    5699/* transformer(), more than meets the eye */
    57100#if BB_MMU
    58 void FAST_FUNC open_transformer(int fd,
    59     int check_signature,
    60     IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd)
     101void FAST_FUNC fork_transformer(int fd,
     102    int signature_skipped,
     103    IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate)
    61104)
    62105#else
    63 void FAST_FUNC open_transformer(int fd, const char *transform_prog)
     106void FAST_FUNC fork_transformer(int fd, const char *transform_prog)
    64107#endif
    65108{
     
    75118#if BB_MMU
    76119        {
    77             transformer_aux_data_t aux;
    78             init_transformer_aux_data(&aux);
    79             aux.check_signature = check_signature;
    80             transformer(&aux, fd, fd_pipe.wr);
     120            IF_DESKTOP(long long) int r;
     121            transformer_state_t xstate;
     122            init_transformer_state(&xstate);
     123            xstate.signature_skipped = signature_skipped;
     124            xstate.src_fd = fd;
     125            xstate.dst_fd = fd_pipe.wr;
     126            r = transformer(&xstate);
    81127            if (ENABLE_FEATURE_CLEAN_UP) {
    82128                close(fd_pipe.wr); /* send EOF */
     
    84130            }
    85131            /* must be _exit! bug was actually seen here */
    86             _exit(EXIT_SUCCESS);
     132            _exit(/*error if:*/ r < 0);
    87133        }
    88134#else
     
    113159 * thus we can't guess the format from filename's extension.
    114160 */
    115 int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_detected)
     161static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed)
    116162{
    117163    union {
     
    120166        uint32_t b32[1];
    121167    } magic;
    122     int offset = -2;
    123     USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);)
    124     USE_FOR_NOMMU(const char *xformer_prog;)
     168    transformer_state_t *xstate;
     169
     170    xstate = xzalloc(sizeof(*xstate));
     171    xstate->src_fd = fd;
     172    xstate->signature_skipped = 2;
    125173
    126174    /* .gz and .bz2 both have 2-byte signature, and their
     
    130178     && magic.b16[0] == GZIP_MAGIC
    131179    ) {
    132         USE_FOR_MMU(xformer = unpack_gz_stream;)
    133         USE_FOR_NOMMU(xformer_prog = "gunzip";)
     180        xstate->xformer = unpack_gz_stream;
     181        USE_FOR_NOMMU(xstate->xformer_prog = "gunzip";)
     182        goto found_magic;
     183    }
     184    if (ENABLE_FEATURE_SEAMLESS_Z
     185     && magic.b16[0] == COMPRESS_MAGIC
     186    ) {
     187        xstate->xformer = unpack_Z_stream;
     188        USE_FOR_NOMMU(xstate->xformer_prog = "uncompress";)
    134189        goto found_magic;
    135190    }
     
    137192     && magic.b16[0] == BZIP2_MAGIC
    138193    ) {
    139         USE_FOR_MMU(xformer = unpack_bz2_stream;)
    140         USE_FOR_NOMMU(xformer_prog = "bunzip2";)
     194        xstate->xformer = unpack_bz2_stream;
     195        USE_FOR_NOMMU(xstate->xformer_prog = "bunzip2";)
    141196        goto found_magic;
    142197    }
     
    144199     && magic.b16[0] == XZ_MAGIC1
    145200    ) {
    146         offset = -6;
     201        xstate->signature_skipped = 6;
    147202        xread(fd, magic.b32, sizeof(magic.b32[0]));
    148203        if (magic.b32[0] == XZ_MAGIC2) {
    149             USE_FOR_MMU(xformer = unpack_xz_stream;)
    150             USE_FOR_NOMMU(xformer_prog = "unxz";)
     204            xstate->xformer = unpack_xz_stream;
     205            USE_FOR_NOMMU(xstate->xformer_prog = "unxz";)
    151206            goto found_magic;
    152207        }
     
    154209
    155210    /* No known magic seen */
    156     if (fail_if_not_detected)
     211    if (fail_if_not_compressed)
    157212        bb_error_msg_and_die("no gzip"
    158213            IF_FEATURE_SEAMLESS_BZ2("/bzip2")
    159214            IF_FEATURE_SEAMLESS_XZ("/xz")
    160215            " magic");
    161     xlseek(fd, offset, SEEK_CUR);
    162     return 1;
     216
     217    /* Some callers expect this function to "consume" fd
     218     * even if data is not compressed. In this case,
     219     * we return a state with trivial transformer.
     220     */
     221//  USE_FOR_MMU(xstate->xformer = copy_stream;)
     222//  USE_FOR_NOMMU(xstate->xformer_prog = "cat";)
    163223
    164224 found_magic:
     225    return xstate;
     226}
     227
     228/* Used by e.g. rpm which gives us a fd without filename,
     229 * thus we can't guess the format from filename's extension.
     230 */
     231int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed)
     232{
     233    transformer_state_t *xstate = setup_transformer_on_fd(fd, fail_if_not_compressed);
     234
     235    if (!xstate || !xstate->xformer) {
     236        free(xstate);
     237        return 1;
     238    }
     239
    165240# if BB_MMU
    166     open_transformer_with_no_sig(fd, xformer);
     241    fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer);
    167242# else
    168     /* NOMMU version of open_transformer execs
     243    /* NOMMU version of fork_transformer execs
    169244     * an external unzipper that wants
    170      * file position at the start of the file */
    171     xlseek(fd, offset, SEEK_CUR);
    172     open_transformer_with_sig(fd, xformer, xformer_prog);
     245     * file position at the start of the file.
     246     */
     247    xlseek(fd, - xstate->signature_skipped, SEEK_CUR);
     248    xstate->signature_skipped = 0;
     249    fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog);
    173250# endif
     251    free(xstate);
    174252    return 0;
    175253}
    176254
    177 int FAST_FUNC open_zipped(const char *fname)
    178 {
    179     char *sfx;
     255static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed)
     256{
     257    transformer_state_t *xstate;
    180258    int fd;
    181259
    182260    fd = open(fname, O_RDONLY);
    183261    if (fd < 0)
    184         return fd;
    185 
    186     sfx = strrchr(fname, '.');
    187     if (sfx) {
    188         sfx++;
    189         if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0)
    190             /* .lzma has no header/signature, just trust it */
    191             open_transformer_with_sig(fd, unpack_lzma_stream, "unlzma");
    192         else
    193         if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0)
    194          || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0)
    195          || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0)
    196         ) {
    197             setup_unzip_on_fd(fd, /*fail_if_not_detected:*/ 1);
    198         }
    199     }
    200 
     262        return NULL;
     263
     264    if (ENABLE_FEATURE_SEAMLESS_LZMA) {
     265        /* .lzma has no header/signature, can only detect it by extension */
     266        char *sfx = strrchr(fname, '.');
     267        if (sfx && strcmp(sfx+1, "lzma") == 0) {
     268            xstate = xzalloc(sizeof(*xstate));
     269            xstate->src_fd = fd;
     270            xstate->xformer = unpack_lzma_stream;
     271            USE_FOR_NOMMU(xstate->xformer_prog = "unlzma";)
     272            return xstate;
     273        }
     274    }
     275
     276    xstate = setup_transformer_on_fd(fd, fail_if_not_compressed);
     277
     278    return xstate;
     279}
     280
     281int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed)
     282{
     283    int fd;
     284    transformer_state_t *xstate;
     285
     286    xstate = open_transformer(fname, fail_if_not_compressed);
     287    if (!xstate)
     288        return -1;
     289
     290    fd = xstate->src_fd;
     291# if BB_MMU
     292    if (xstate->xformer) {
     293        fork_transformer_with_no_sig(fd, xstate->xformer);
     294    } else {
     295        /* the file is not compressed */
     296        xlseek(fd, - xstate->signature_skipped, SEEK_CUR);
     297        xstate->signature_skipped = 0;
     298    }
     299# else
     300    /* NOMMU can't avoid the seek :( */
     301    xlseek(fd, - xstate->signature_skipped, SEEK_CUR);
     302    xstate->signature_skipped = 0;
     303    if (xstate->xformer) {
     304        fork_transformer_with_sig(fd, xstate->xformer, xstate->xformer_prog);
     305    } /* else: the file is not compressed */
     306# endif
     307
     308    free(xstate);
    201309    return fd;
    202310}
    203311
    204 #endif /* SEAMLESS_COMPRESSION */
    205 
    206312void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p)
    207313{
     314# if 1
     315    transformer_state_t *xstate;
     316    char *image;
     317
     318    xstate = open_transformer(fname, /*fail_if_not_compressed:*/ 0);
     319    if (!xstate) /* file open error */
     320        return NULL;
     321
     322    image = NULL;
     323    if (xstate->xformer) {
     324        /* In-memory decompression */
     325        xstate->mem_output_size_max = maxsz_p ? *maxsz_p : (size_t)(INT_MAX - 4095);
     326        xstate->xformer(xstate);
     327        if (xstate->mem_output_buf) {
     328            image = xstate->mem_output_buf;
     329            if (maxsz_p)
     330                *maxsz_p = xstate->mem_output_size;
     331        }
     332    } else {
     333        /* File is not compressed */
     334//FIXME: avoid seek
     335        xlseek(xstate->src_fd, - xstate->signature_skipped, SEEK_CUR);
     336        xstate->signature_skipped = 0;
     337        image = xmalloc_read(xstate->src_fd, maxsz_p);
     338    }
     339
     340    if (!image)
     341        bb_perror_msg("read error from '%s'", fname);
     342    close(xstate->src_fd);
     343    free(xstate);
     344    return image;
     345# else
     346    /* This version forks a subprocess - much more expensive */
    208347    int fd;
    209348    char *image;
    210349
    211     fd = open_zipped(fname);
     350    fd = open_zipped(fname, /*fail_if_not_compressed:*/ 0);
    212351    if (fd < 0)
    213352        return NULL;
     
    217356        bb_perror_msg("read error from '%s'", fname);
    218357    close(fd);
    219 
    220358    return image;
    221 }
     359# endif
     360}
     361
     362#endif /* SEAMLESS_COMPRESSION */
  • branches/3.3/mindi-busybox/archival/libarchive/unpack_ar_archive.c

    r3232 r3621  
    1313
    1414    xread(ar_archive->src_fd, magic, AR_MAGIC_LEN);
    15     if (strncmp(magic, AR_MAGIC, AR_MAGIC_LEN) != 0) {
     15    if (!is_prefixed_with(magic, AR_MAGIC)) {
    1616        bb_error_msg_and_die("invalid ar magic");
    1717    }
  • branches/3.3/mindi-busybox/archival/libarchive/unxz/README

    r2725 r3621  
    88    XZ Embedded was written for use in the Linux kernel, but the code can
    99    be easily used in other environments too, including regular userspace
    10     applications.
     10    applications. See userspace/xzminidec.c for an example program.
    1111
    1212    This README contains information that is useful only when the copy
     
    5656    care than just using 32-bit integer instead of 64-bit).
    5757
    58     If you use GCC, try to use a recent version. For example, on x86,
     58    If you use GCC, try to use a recent version. For example, on x86-32,
    5959    xz_dec_lzma2.c compiled with GCC 3.3.6 is 15-25 % slower than when
    6060    compiled with GCC 4.3.3.
     
    9494
    9595        #define             Instruction set     BCJ filter endianness
    96         XZ_DEC_X86          x86 or x86-64       Little endian only
     96        XZ_DEC_X86          x86-32 or x86-64    Little endian only
    9797        XZ_DEC_POWERPC      PowerPC             Big endian only
    9898        XZ_DEC_IA64         Itanium (IA-64)     Big or little endian
  • branches/3.3/mindi-busybox/archival/libarchive/unxz/xz.h

    r2725 r3621  
    1818#   include <stddef.h>
    1919#   include <stdint.h>
     20#endif
     21
     22#ifdef __cplusplus
     23extern "C" {
    2024#endif
    2125
     
    7175 *                          is still possible in multi-call mode by simply
    7276 *                          calling xz_dec_run() again.
    73  *                          NOTE: This return value is used only if
     77 *                          Note that this return value is used only if
    7478 *                          XZ_DEC_ANY_CHECK was defined at build time,
    7579 *                          which is not used in the kernel. Unsupported
     
    106110 *
    107111 * In single-call mode, XZ_BUF_ERROR is returned only when the output buffer
    108  * is too small, or the compressed input is corrupt in a way that makes the
     112 * is too small or the compressed input is corrupt in a way that makes the
    109113 * decoder produce more output than the caller expected. When it is
    110114 * (relatively) clear that the compressed input is truncated, XZ_DATA_ERROR
     
    208212 * See enum xz_ret for details.
    209213 *
    210  * NOTE: If an error occurs in single-call mode (return value is not
    211  * XZ_STREAM_END), b->in_pos and b->out_pos are not modified, and the
     214 * Note that if an error occurs in single-call mode (return value is not
     215 * XZ_STREAM_END), b->in_pos and b->out_pos are not modified and the
    212216 * contents of the output buffer from b->out[b->out_pos] onward are
    213217 * undefined. This is true even after XZ_BUF_ERROR, because with some filter
     
    269273        const uint8_t *buf, size_t size, uint32_t crc);
    270274#endif
    271 #endif
     275
     276#ifdef __cplusplus
     277}
     278#endif
     279
     280#endif
  • branches/3.3/mindi-busybox/archival/libarchive/unxz/xz_dec_bcj.c

    r2725 r3621  
    7878#ifdef XZ_DEC_X86
    7979/*
    80  * This is macro used to test the most significant byte of a memory address
     80 * This is used to test the most significant byte of a memory address
    8181 * in an x86 instruction.
    8282 */
    83 #define bcj_x86_test_msbyte(b) ((b) == 0x00 || (b) == 0xFF)
     83static inline int bcj_x86_test_msbyte(uint8_t b)
     84{
     85    return b == 0x00 || b == 0xFF;
     86}
    8487
    8588static noinline_for_stack size_t XZ_FUNC bcj_x86(
     
    444447     * in the output buffer. If everything cannot be filtered, copy it
    445448     * to temp and rewind the output buffer position accordingly.
     449     *
     450     * This needs to be always run when temp.size == 0 to handle a special
     451     * case where the output buffer is full and the next filter has no
     452     * more output coming but hasn't returned XZ_STREAM_END yet.
    446453     */
    447     if (s->temp.size < b->out_size - b->out_pos) {
     454    if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) {
    448455        out_start = b->out_pos;
    449456        memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
     
    468475        b->out_pos -= s->temp.size;
    469476        memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
     477
     478        /*
     479         * If there wasn't enough input to the next filter to fill
     480         * the output buffer with unfiltered data, there's no point
     481         * to try decoding more data to temp.
     482         */
     483        if (b->out_pos + s->temp.size < b->out_size)
     484            return XZ_OK;
    470485    }
    471486
    472487    /*
    473      * If we have unfiltered data in temp, try to fill by decoding more
    474      * data from the next filter. Apply the BCJ filter on temp. Then we
    475      * hopefully can fill the actual output buffer by copying filtered
    476      * data from temp. A mix of filtered and unfiltered data may be left
    477      * in temp; it will be taken care on the next call to this function.
     488     * We have unfiltered data in temp. If the output buffer isn't full
     489     * yet, try to fill the temp buffer by decoding more data from the
     490     * next filter. Apply the BCJ filter on temp. Then we hopefully can
     491     * fill the actual output buffer by copying filtered data from temp.
     492     * A mix of filtered and unfiltered data may be left in temp; it will
     493     * be taken care on the next call to this function.
    478494     */
    479     if (s->temp.size > 0) {
     495    if (b->out_pos < b->out_size) {
    480496        /* Make b->out{,_pos,_size} temporarily point to s->temp. */
    481497        s->out = b->out;
  • branches/3.3/mindi-busybox/archival/libarchive/unxz/xz_dec_lzma2.c

    r2725 r3621  
    408408        b->out_pos += copy_size;
    409409        b->in_pos += copy_size;
    410 
    411410    }
    412411}
     
    973972            tmp = b->in[b->in_pos++];
    974973
     974            if (tmp == 0x00)
     975                return XZ_STREAM_END;
     976
    975977            if (tmp >= 0xE0 || tmp == 0x01) {
    976978                s->lzma2.need_props = true;
     
    994996                    s->lzma2.next_sequence
    995997                            = SEQ_PROPERTIES;
    996 
    997998                } else if (s->lzma2.need_props) {
    998999                    return XZ_DATA_ERROR;
    999 
    10001000                } else {
    10011001                    s->lzma2.next_sequence
     
    10051005                }
    10061006            } else {
    1007                 if (tmp == 0x00)
    1008                     return XZ_STREAM_END;
    1009 
    10101007                if (tmp > 0x02)
    10111008                    return XZ_DATA_ERROR;
     
    10821079                rc_reset(&s->rc);
    10831080                s->lzma2.sequence = SEQ_CONTROL;
    1084 
    10851081            } else if (b->out_pos == b->out_size
    10861082                    || (b->in_pos == b->in_size
  • branches/3.3/mindi-busybox/archival/libarchive/unxz/xz_dec_stream.c

    r2725 r3621  
    354354
    355355        s->pos += 8;
    356 
    357356    } while (s->pos < 32);
    358357
     
    754753            b->out_pos = out_start;
    755754        }
    756 
    757755    } else if (ret == XZ_OK && in_start == b->in_pos
    758756            && out_start == b->out_pos) {
  • branches/3.3/mindi-busybox/archival/libarchive/unxz/xz_stream.h

    r2725 r3621  
    2626#define STREAM_HEADER_SIZE 12
    2727
    28 #define HEADER_MAGIC "\3757zXZ\0"
     28#define HEADER_MAGIC "\3757zXZ"
    2929#define HEADER_MAGIC_SIZE 6
    3030
     
    3333
    3434/*
    35  * Variable-length integer can hold a 63-bit unsigned integer, or a special
    36  * value to indicate that the value is unknown.
     35 * Variable-length integer can hold a 63-bit unsigned integer or a special
     36 * value indicating that the value is unknown.
     37 *
     38 * Experimental: vli_type can be defined to uint32_t to save a few bytes
     39 * in code size (no effect on speed). Doing so limits the uncompressed and
     40 * compressed size of the file to less than 256 MiB and may also weaken
     41 * error detection slightly.
    3742 */
    3843typedef uint64_t vli_type;
  • branches/3.3/mindi-busybox/archival/lzop.c

    r3232 r3621  
    2525   "Minimalized" for busybox by Alain Knaff
    2626*/
     27
     28//config:config LZOP
     29//config:   bool "lzop"
     30//config:   default y
     31//config:   help
     32//config:     Lzop compression/decompresion.
     33//config:
     34//config:config LZOP_COMPR_HIGH
     35//config:   bool "lzop compression levels 7,8,9 (not very useful)"
     36//config:   default n
     37//config:   depends on LZOP
     38//config:   help
     39//config:     High levels (7,8,9) of lzop compression. These levels
     40//config:     are actually slower than gzip at equivalent compression ratios
     41//config:     and take up 3.2K of code.
     42
     43//applet:IF_LZOP(APPLET(lzop, BB_DIR_BIN, BB_SUID_DROP))
     44//applet:IF_LZOP(APPLET_ODDNAME(lzopcat, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, lzopcat))
     45//applet:IF_LZOP(APPLET_ODDNAME(unlzop, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, unlzop))
     46//kbuild:lib-$(CONFIG_LZOP) += lzop.o
    2747
    2848//usage:#define lzop_trivial_usage
     
    5272
    5373#include "libbb.h"
     74#include "common_bufsiz.h"
    5475#include "bb_archive.h"
    5576#include "liblzo_interface.h"
     
    424445    chksum_t chksum_out;
    425446} FIX_ALIASING;
    426 #define G (*(struct globals*)&bb_common_bufsiz1)
    427 #define INIT_G() do { } while (0)
     447#define G (*(struct globals*)bb_common_bufsiz1)
     448#define INIT_G() do { setup_common_bufsiz(); } while (0)
    428449//#define G (*ptr_to_globals)
    429450//#define INIT_G() do {
     
    437458//#define LZOP_VERSION_DATE       "Apr 27th 2003"
    438459
    439 #define OPTION_STRING "cfvdt123456789CF"
    440 
     460#define OPTION_STRING "cfvqdt123456789CF"
     461
     462/* Note: must be kept in sync with archival/bbunzip.c */
    441463enum {
    442464    OPT_STDOUT      = (1 << 0),
    443465    OPT_FORCE       = (1 << 1),
    444466    OPT_VERBOSE     = (1 << 2),
    445     OPT_DECOMPRESS  = (1 << 3),
    446     OPT_TEST        = (1 << 4),
    447     OPT_1           = (1 << 5),
    448     OPT_2           = (1 << 6),
    449     OPT_3           = (1 << 7),
    450     OPT_4           = (1 << 8),
    451     OPT_5           = (1 << 9),
    452     OPT_6           = (1 << 10),
    453     OPT_789         = (7 << 11),
    454     OPT_7           = (1 << 11),
    455     OPT_8           = (1 << 12),
    456     OPT_C           = (1 << 14),
    457     OPT_F           = (1 << 15),
     467    OPT_QUIET       = (1 << 3),
     468    OPT_DECOMPRESS  = (1 << 4),
     469    OPT_TEST        = (1 << 5),
     470    OPT_1           = (1 << 6),
     471    OPT_2           = (1 << 7),
     472    OPT_3           = (1 << 8),
     473    OPT_4           = (1 << 9),
     474    OPT_5           = (1 << 10),
     475    OPT_6           = (1 << 11),
     476    OPT_789         = (7 << 12),
     477    OPT_7           = (1 << 13),
     478    OPT_8           = (1 << 14),
     479    OPT_C           = (1 << 15),
     480    OPT_F           = (1 << 16),
    458481};
    459482
     
    619642// compress a file
    620643/**********************************************************************/
    621 static NOINLINE smallint lzo_compress(const header_t *h)
     644static NOINLINE int lzo_compress(const header_t *h)
    622645{
    623646    unsigned block_size = LZO_BLOCK_SIZE;
     
    629652    uint32_t d_crc32 = CRC32_INIT_VALUE;
    630653    int l;
    631     smallint ok = 1;
    632654    uint8_t *wrk_mem = NULL;
    633655
     
    711733    free(b1);
    712734    free(b2);
    713     return ok;
     735    return 1;
    714736}
    715737
     
    732754// decompress a file
    733755/**********************************************************************/
    734 static NOINLINE smallint lzo_decompress(const header_t *h)
     756static NOINLINE int lzo_decompress(const header_t *h)
    735757{
    736758    unsigned block_size = LZO_BLOCK_SIZE;
     
    740762    uint32_t d_adler32 = ADLER32_INIT_VALUE;
    741763    uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE;
    742     smallint ok = 1;
    743764    uint8_t *b1;
    744765    uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size);
     
    844865
    845866    free(b2);
    846     return ok;
     867    return 1;
    847868}
    848869
     
    876897 * The rest is identical.
    877898*/
    878 static const unsigned char lzop_magic[9] = {
     899static const unsigned char lzop_magic[9] ALIGN1 = {
    879900    0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a
    880901};
     
    10291050}
    10301051
    1031 static smallint do_lzo_compress(void)
     1052static int do_lzo_compress(void)
    10321053{
    10331054    header_t header;
     
    10571078// decompress
    10581079/**********************************************************************/
    1059 static smallint do_lzo_decompress(void)
     1080static int do_lzo_decompress(void)
    10601081{
    10611082    header_t header;
     
    10781099}
    10791100
    1080 static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(transformer_aux_data_t *aux UNUSED_PARAM)
     1101static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(transformer_state_t *xstate UNUSED_PARAM)
    10811102{
    10821103    if (option_mask32 & OPT_DECOMPRESS)
     
    10941115        option_mask32 |= (OPT_STDOUT | OPT_DECOMPRESS);
    10951116    /* unlzop? */
    1096     if (applet_name[0] == 'u')
     1117    if (applet_name[4] == 'o')
    10971118        option_mask32 |= OPT_DECOMPRESS;
    10981119
  • branches/3.3/mindi-busybox/archival/rpm.c

    r3232 r3621  
    88 */
    99
     10//config:config RPM
     11//config:   bool "rpm"
     12//config:   default y
     13//config:   help
     14//config:     Mini RPM applet - queries and extracts RPM packages.
     15
     16//applet:IF_RPM(APPLET(rpm, BB_DIR_BIN, BB_SUID_DROP))
     17//kbuild:lib-$(CONFIG_RPM) += rpm.o
     18
    1019//usage:#define rpm_trivial_usage
    1120//usage:       "-i PACKAGE.rpm; rpm -qp[ildc] PACKAGE.rpm"
     
    1524//usage:     "\n    -i  Install package"
    1625//usage:     "\n    -qp Query package"
    17 //usage:     "\n    -i  Show information"
    18 //usage:     "\n    -l  List contents"
    19 //usage:     "\n    -d  List documents"
    20 //usage:     "\n    -c  List config files"
     26//usage:     "\n    -qpi    Show information"
     27//usage:     "\n    -qpl    List contents"
     28//usage:     "\n    -qpd    List documents"
     29//usage:     "\n    -qpc    List config files"
    2130
    2231#include "libbb.h"
     32#include "common_bufsiz.h"
    2333#include "bb_archive.h"
    2434#include "rpm.h"
     
    8090} rpm_index;
    8191
    82 static void *map;
    83 static rpm_index **mytags;
    84 static int tagcount;
    85 
    86 static void extract_cpio(int fd, const char *source_rpm);
    87 static rpm_index **rpm_gettags(int fd, int *num_tags);
    88 static int bsearch_rpmtag(const void *key, const void *item);
    89 static char *rpm_getstr(int tag, int itemindex);
    90 static int rpm_getint(int tag, int itemindex);
    91 static int rpm_getcount(int tag);
    92 static void fileaction_dobackup(char *filename, int fileref);
    93 static void fileaction_setowngrp(char *filename, int fileref);
    94 static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref));
     92struct globals {
     93    void *map;
     94    rpm_index **mytags;
     95    int tagcount;
     96} FIX_ALIASING;
     97#define G (*(struct globals*)bb_common_bufsiz1)
     98#define INIT_G() do { setup_common_bufsiz(); } while (0)
     99
     100static void extract_cpio(int fd, const char *source_rpm)
     101{
     102    archive_handle_t *archive_handle;
     103
     104    if (source_rpm != NULL) {
     105        /* Binary rpm (it was built from some SRPM), install to root */
     106        xchdir("/");
     107    } /* else: SRPM, install to current dir */
     108
     109    /* Initialize */
     110    archive_handle = init_handle();
     111    archive_handle->seek = seek_by_read;
     112    archive_handle->action_data = data_extract_all;
     113#if 0 /* For testing (rpm -i only lists the files in internal cpio): */
     114    archive_handle->action_header = header_list;
     115    archive_handle->action_data = data_skip;
     116#endif
     117    archive_handle->ah_flags = ARCHIVE_RESTORE_DATE | ARCHIVE_CREATE_LEADING_DIRS
     118        /* compat: overwrite existing files.
     119         * try "rpm -i foo.src.rpm" few times in a row -
     120         * standard rpm will not complain.
     121         */
     122        | ARCHIVE_REPLACE_VIA_RENAME;
     123    archive_handle->src_fd = fd;
     124    /*archive_handle->offset = 0; - init_handle() did it */
     125
     126    setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_compressed:*/ 1);
     127    while (get_header_cpio(archive_handle) == EXIT_SUCCESS)
     128        continue;
     129}
     130
     131static rpm_index **rpm_gettags(int fd, int *num_tags)
     132{
     133    /* We should never need more than 200 (shrink via realloc later) */
     134    rpm_index **tags = xzalloc(200 * sizeof(tags[0]));
     135    int pass, tagindex = 0;
     136
     137    xlseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */
     138
     139    /* 1st pass is the signature headers, 2nd is the main stuff */
     140    for (pass = 0; pass < 2; pass++) {
     141        struct rpm_header header;
     142        rpm_index *tmpindex;
     143        int storepos;
     144
     145        xread(fd, &header, sizeof(header));
     146        if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER))
     147            return NULL; /* Invalid magic, or not version 1 */
     148        header.size = ntohl(header.size);
     149        header.entries = ntohl(header.entries);
     150        storepos = xlseek(fd, 0, SEEK_CUR) + header.entries * 16;
     151
     152        while (header.entries--) {
     153            tmpindex = tags[tagindex++] = xmalloc(sizeof(*tmpindex));
     154            xread(fd, tmpindex, sizeof(*tmpindex));
     155            tmpindex->tag = ntohl(tmpindex->tag);
     156            tmpindex->type = ntohl(tmpindex->type);
     157            tmpindex->count = ntohl(tmpindex->count);
     158            tmpindex->offset = storepos + ntohl(tmpindex->offset);
     159            if (pass == 0)
     160                tmpindex->tag -= 743;
     161        }
     162        storepos = xlseek(fd, header.size, SEEK_CUR); /* Seek past store */
     163        /* Skip padding to 8 byte boundary after reading signature headers */
     164        if (pass == 0)
     165            xlseek(fd, (-storepos) & 0x7, SEEK_CUR);
     166    }
     167    /* realloc tags to save space */
     168    tags = xrealloc(tags, tagindex * sizeof(tags[0]));
     169    *num_tags = tagindex;
     170    /* All done, leave the file at the start of the gzipped cpio archive */
     171    return tags;
     172}
     173
     174static int bsearch_rpmtag(const void *key, const void *item)
     175{
     176    int *tag = (int *)key;
     177    rpm_index **tmp = (rpm_index **) item;
     178    return (*tag - tmp[0]->tag);
     179}
     180
     181static int rpm_getcount(int tag)
     182{
     183    rpm_index **found;
     184    found = bsearch(&tag, G.mytags, G.tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
     185    if (!found)
     186        return 0;
     187    return found[0]->count;
     188}
     189
     190static char *rpm_getstr(int tag, int itemindex)
     191{
     192    rpm_index **found;
     193    found = bsearch(&tag, G.mytags, G.tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
     194    if (!found || itemindex >= found[0]->count)
     195        return NULL;
     196    if (found[0]->type == RPM_STRING_TYPE
     197     || found[0]->type == RPM_I18NSTRING_TYPE
     198     || found[0]->type == RPM_STRING_ARRAY_TYPE
     199    ) {
     200        int n;
     201        char *tmpstr = (char *) G.map + found[0]->offset;
     202        for (n = 0; n < itemindex; n++)
     203            tmpstr = tmpstr + strlen(tmpstr) + 1;
     204        return tmpstr;
     205    }
     206    return NULL;
     207}
     208
     209static int rpm_getint(int tag, int itemindex)
     210{
     211    rpm_index **found;
     212    char *tmpint;
     213
     214    /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ...
     215     * it's ok to ignore it because tag won't be used as a pointer */
     216    found = bsearch(&tag, G.mytags, G.tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
     217    if (!found || itemindex >= found[0]->count)
     218        return -1;
     219
     220    tmpint = (char *) G.map + found[0]->offset;
     221    if (found[0]->type == RPM_INT32_TYPE) {
     222        tmpint += itemindex*4;
     223        return ntohl(*(int32_t*)tmpint);
     224    }
     225    if (found[0]->type == RPM_INT16_TYPE) {
     226        tmpint += itemindex*2;
     227        return ntohs(*(int16_t*)tmpint);
     228    }
     229    if (found[0]->type == RPM_INT8_TYPE) {
     230        tmpint += itemindex;
     231        return *(int8_t*)tmpint;
     232    }
     233    return -1;
     234}
     235
     236static void fileaction_dobackup(char *filename, int fileref)
     237{
     238    struct stat oldfile;
     239    int stat_res;
     240    char *newname;
     241    if (rpm_getint(TAG_FILEFLAGS, fileref) & RPMFILE_CONFIG) {
     242        /* Only need to backup config files */
     243        stat_res = lstat(filename, &oldfile);
     244        if (stat_res == 0 && S_ISREG(oldfile.st_mode)) {
     245            /* File already exists  - really should check MD5's etc to see if different */
     246            newname = xasprintf("%s.rpmorig", filename);
     247            copy_file(filename, newname, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS);
     248            remove_file(filename, FILEUTILS_RECUR | FILEUTILS_FORCE);
     249            free(newname);
     250        }
     251    }
     252}
     253
     254static void fileaction_setowngrp(char *filename, int fileref)
     255{
     256    /* real rpm warns: "user foo does not exist - using <you>" */
     257    struct passwd *pw = getpwnam(rpm_getstr(TAG_FILEUSERNAME, fileref));
     258    int uid = pw ? pw->pw_uid : getuid(); /* or euid? */
     259    struct group *gr = getgrnam(rpm_getstr(TAG_FILEGROUPNAME, fileref));
     260    int gid = gr ? gr->gr_gid : getgid();
     261    chown(filename, uid, gid);
     262}
     263
     264static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref))
     265{
     266    int count = 0;
     267    while (rpm_getstr(filetag, count)) {
     268        char* filename = xasprintf("%s%s",
     269            rpm_getstr(TAG_DIRNAMES, rpm_getint(TAG_DIRINDEXES, count)),
     270            rpm_getstr(TAG_BASENAMES, count));
     271        fileaction(filename, count++);
     272        free(filename);
     273    }
     274}
    95275
    96276int rpm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    97277int rpm_main(int argc, char **argv)
    98278{
    99     int opt = 0, func = 0, rpm_fd, offset;
    100     const int pagesize = getpagesize();
     279    int opt, func = 0;
     280    const unsigned pagesize = getpagesize();
    101281
    102282    while ((opt = getopt(argc, argv, "iqpldc")) != -1) {
     
    135315
    136316    while (*argv) {
     317        int rpm_fd;
     318        unsigned mapsize;
    137319        const char *source_rpm;
    138320
    139321        rpm_fd = xopen(*argv++, O_RDONLY);
    140         mytags = rpm_gettags(rpm_fd, &tagcount);
    141         if (!mytags)
     322        G.mytags = rpm_gettags(rpm_fd, &G.tagcount);
     323        if (!G.mytags)
    142324            bb_error_msg_and_die("error reading rpm header");
    143         offset = xlseek(rpm_fd, 0, SEEK_CUR);
    144         /* Mimimum is one page */
    145         map = mmap(0, offset > pagesize ? (offset + offset % pagesize) : pagesize, PROT_READ, MAP_PRIVATE, rpm_fd, 0);
     325        mapsize = xlseek(rpm_fd, 0, SEEK_CUR);
     326        mapsize = (mapsize + pagesize) & -(int)pagesize;
     327        /* Some NOMMU systems prefer MAP_PRIVATE over MAP_SHARED */
     328        G.map = mmap(0, mapsize, PROT_READ, MAP_PRIVATE, rpm_fd, 0);
     329//FIXME: error check?
    146330
    147331        source_rpm = rpm_getstr(TAG_SOURCERPM, 0);
     
    167351                const char *p;
    168352
    169                 p = rpm_getstr(TAG_PREFIXS, 0);
    170                 if (!p) p = "(not relocateable)";
    171                 printf("Name        : %-29sRelocations: %s\n", rpm_getstr(TAG_NAME, 0), p);
    172                 p = rpm_getstr(TAG_VENDOR, 0);
    173                 if (!p) p = "(none)";
    174                 printf("Version     : %-34sVendor: %s\n", rpm_getstr(TAG_VERSION, 0), p);
     353                printf("%-12s: %s\n", "Name"        , rpm_getstr(TAG_NAME, 0));
     354                /* TODO compat: add "Epoch" here */
     355                printf("%-12s: %s\n", "Version"     , rpm_getstr(TAG_VERSION, 0));
     356                printf("%-12s: %s\n", "Release"     , rpm_getstr(TAG_RELEASE, 0));
     357                /* add "Architecture" */
     358                printf("%-12s: %s\n", "Install Date", "(not installed)");
     359                printf("%-12s: %s\n", "Group"       , rpm_getstr(TAG_GROUP, 0));
     360                printf("%-12s: %d\n", "Size"        , rpm_getint(TAG_SIZE, 0));
     361                printf("%-12s: %s\n", "License"     , rpm_getstr(TAG_LICENSE, 0));
     362                /* add "Signature" */
     363                printf("%-12s: %s\n", "Source RPM"  , source_rpm ? source_rpm : "(none)");
    175364                bdate_time = rpm_getint(TAG_BUILDTIME, 0);
    176365                bdate_ptm = localtime(&bdate_time);
    177366                strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate_ptm);
    178                 printf("Release     : %-30sBuild Date: %s\n", rpm_getstr(TAG_RELEASE, 0), bdatestring);
    179                 printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstr(TAG_BUILDHOST, 0));
    180                 printf("Group       : %-30sSource RPM: %s\n", rpm_getstr(TAG_GROUP, 0), source_rpm);
    181                 printf("Size        : %-33dLicense: %s\n", rpm_getint(TAG_SIZE, 0), rpm_getstr(TAG_LICENSE, 0));
    182                 printf("URL         : %s\n", rpm_getstr(TAG_URL, 0));
    183                 printf("Summary     : %s\n", rpm_getstr(TAG_SUMMARY, 0));
     367                printf("%-12s: %s\n", "Build Date"  , bdatestring);
     368                printf("%-12s: %s\n", "Build Host"  , rpm_getstr(TAG_BUILDHOST, 0));
     369                p = rpm_getstr(TAG_PREFIXS, 0);
     370                printf("%-12s: %s\n", "Relocations" , p ? p : "(not relocatable)");
     371                /* add "Packager" */
     372                p = rpm_getstr(TAG_VENDOR, 0);
     373                printf("%-12s: %s\n", "Vendor"      , p ? p : "(none)");
     374                printf("%-12s: %s\n", "URL"         , rpm_getstr(TAG_URL, 0));
     375                printf("%-12s: %s\n", "Summary"     , rpm_getstr(TAG_SUMMARY, 0));
    184376                printf("Description :\n%s\n", rpm_getstr(TAG_DESCRIPTION, 0));
    185377            }
     
    206398            }
    207399        }
    208         free(mytags);
     400        munmap(G.map, mapsize);
     401        free(G.mytags);
     402        close(rpm_fd);
    209403    }
    210404    return 0;
    211405}
    212 
    213 static void extract_cpio(int fd, const char *source_rpm)
    214 {
    215     archive_handle_t *archive_handle;
    216 
    217     if (source_rpm != NULL) {
    218         /* Binary rpm (it was built from some SRPM), install to root */
    219         xchdir("/");
    220     } /* else: SRPM, install to current dir */
    221 
    222     /* Initialize */
    223     archive_handle = init_handle();
    224     archive_handle->seek = seek_by_read;
    225     archive_handle->action_data = data_extract_all;
    226 #if 0 /* For testing (rpm -i only lists the files in internal cpio): */
    227     archive_handle->action_header = header_list;
    228     archive_handle->action_data = data_skip;
    229 #endif
    230     archive_handle->ah_flags = ARCHIVE_RESTORE_DATE | ARCHIVE_CREATE_LEADING_DIRS
    231         /* compat: overwrite existing files.
    232          * try "rpm -i foo.src.rpm" few times in a row -
    233          * standard rpm will not complain.
    234          * (TODO? real rpm creates "file;1234" and then renames it) */
    235         | ARCHIVE_UNLINK_OLD;
    236     archive_handle->src_fd = fd;
    237     /*archive_handle->offset = 0; - init_handle() did it */
    238 
    239     setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_detected:*/ 1);
    240     while (get_header_cpio(archive_handle) == EXIT_SUCCESS)
    241         continue;
    242 }
    243 
    244 static rpm_index **rpm_gettags(int fd, int *num_tags)
    245 {
    246     /* We should never need more than 200 (shrink via realloc later) */
    247     rpm_index **tags = xzalloc(200 * sizeof(tags[0]));
    248     int pass, tagindex = 0;
    249 
    250     xlseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */
    251 
    252     /* 1st pass is the signature headers, 2nd is the main stuff */
    253     for (pass = 0; pass < 2; pass++) {
    254         struct rpm_header header;
    255         rpm_index *tmpindex;
    256         int storepos;
    257 
    258         xread(fd, &header, sizeof(header));
    259         if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER))
    260             return NULL; /* Invalid magic, or not version 1 */
    261         header.size = ntohl(header.size);
    262         header.entries = ntohl(header.entries);
    263         storepos = xlseek(fd, 0, SEEK_CUR) + header.entries * 16;
    264 
    265         while (header.entries--) {
    266             tmpindex = tags[tagindex++] = xmalloc(sizeof(*tmpindex));
    267             xread(fd, tmpindex, sizeof(*tmpindex));
    268             tmpindex->tag = ntohl(tmpindex->tag);
    269             tmpindex->type = ntohl(tmpindex->type);
    270             tmpindex->count = ntohl(tmpindex->count);
    271             tmpindex->offset = storepos + ntohl(tmpindex->offset);
    272             if (pass == 0)
    273                 tmpindex->tag -= 743;
    274         }
    275         storepos = xlseek(fd, header.size, SEEK_CUR); /* Seek past store */
    276         /* Skip padding to 8 byte boundary after reading signature headers */
    277         if (pass == 0)
    278             xlseek(fd, (-storepos) & 0x7, SEEK_CUR);
    279     }
    280     /* realloc tags to save space */
    281     tags = xrealloc(tags, tagindex * sizeof(tags[0]));
    282     *num_tags = tagindex;
    283     /* All done, leave the file at the start of the gzipped cpio archive */
    284     return tags;
    285 }
    286 
    287 static int bsearch_rpmtag(const void *key, const void *item)
    288 {
    289     int *tag = (int *)key;
    290     rpm_index **tmp = (rpm_index **) item;
    291     return (*tag - tmp[0]->tag);
    292 }
    293 
    294 static int rpm_getcount(int tag)
    295 {
    296     rpm_index **found;
    297     found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
    298     if (!found)
    299         return 0;
    300     return found[0]->count;
    301 }
    302 
    303 static char *rpm_getstr(int tag, int itemindex)
    304 {
    305     rpm_index **found;
    306     found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
    307     if (!found || itemindex >= found[0]->count)
    308         return NULL;
    309     if (found[0]->type == RPM_STRING_TYPE
    310      || found[0]->type == RPM_I18NSTRING_TYPE
    311      || found[0]->type == RPM_STRING_ARRAY_TYPE
    312     ) {
    313         int n;
    314         char *tmpstr = (char *) map + found[0]->offset;
    315         for (n = 0; n < itemindex; n++)
    316             tmpstr = tmpstr + strlen(tmpstr) + 1;
    317         return tmpstr;
    318     }
    319     return NULL;
    320 }
    321 
    322 static int rpm_getint(int tag, int itemindex)
    323 {
    324     rpm_index **found;
    325     int *tmpint; /* NB: using int8_t* would be easier to code */
    326 
    327     /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ...
    328      * it's ok to ignore it because tag won't be used as a pointer */
    329     found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
    330     if (!found || itemindex >= found[0]->count)
    331         return -1;
    332 
    333     tmpint = (int *) ((char *) map + found[0]->offset);
    334 
    335     if (found[0]->type == RPM_INT32_TYPE) {
    336         tmpint = (int *) ((char *) tmpint + itemindex*4);
    337         /*return ntohl(*tmpint);*/
    338         /* int can be != int32_t */
    339         return ntohl(*(int32_t*)tmpint);
    340     }
    341     if (found[0]->type == RPM_INT16_TYPE) {
    342         tmpint = (int *) ((char *) tmpint + itemindex*2);
    343         /* ??? read int, and THEN ntohs() it?? */
    344         /*return ntohs(*tmpint);*/
    345         return ntohs(*(int16_t*)tmpint);
    346     }
    347     if (found[0]->type == RPM_INT8_TYPE) {
    348         tmpint = (int *) ((char *) tmpint + itemindex);
    349         /* ??? why we don't read byte here??? */
    350         /*return ntohs(*tmpint);*/
    351         return *(int8_t*)tmpint;
    352     }
    353     return -1;
    354 }
    355 
    356 static void fileaction_dobackup(char *filename, int fileref)
    357 {
    358     struct stat oldfile;
    359     int stat_res;
    360     char *newname;
    361     if (rpm_getint(TAG_FILEFLAGS, fileref) & RPMFILE_CONFIG) {
    362         /* Only need to backup config files */
    363         stat_res = lstat(filename, &oldfile);
    364         if (stat_res == 0 && S_ISREG(oldfile.st_mode)) {
    365             /* File already exists  - really should check MD5's etc to see if different */
    366             newname = xasprintf("%s.rpmorig", filename);
    367             copy_file(filename, newname, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS);
    368             remove_file(filename, FILEUTILS_RECUR | FILEUTILS_FORCE);
    369             free(newname);
    370         }
    371     }
    372 }
    373 
    374 static void fileaction_setowngrp(char *filename, int fileref)
    375 {
    376     /* real rpm warns: "user foo does not exist - using <you>" */
    377     struct passwd *pw = getpwnam(rpm_getstr(TAG_FILEUSERNAME, fileref));
    378     int uid = pw ? pw->pw_uid : getuid(); /* or euid? */
    379     struct group *gr = getgrnam(rpm_getstr(TAG_FILEGROUPNAME, fileref));
    380     int gid = gr ? gr->gr_gid : getgid();
    381     chown(filename, uid, gid);
    382 }
    383 
    384 static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref))
    385 {
    386     int count = 0;
    387     while (rpm_getstr(filetag, count)) {
    388         char* filename = xasprintf("%s%s",
    389             rpm_getstr(TAG_DIRNAMES, rpm_getint(TAG_DIRINDEXES, count)),
    390             rpm_getstr(TAG_BASENAMES, count));
    391         fileaction(filename, count++);
    392         free(filename);
    393     }
    394 }
  • branches/3.3/mindi-busybox/archival/rpm2cpio.c

    r3232 r3621  
    77 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
     9
     10//config:config RPM2CPIO
     11//config:   bool "rpm2cpio"
     12//config:   default y
     13//config:   help
     14//config:     Converts a RPM file into a CPIO archive.
     15
     16//applet:IF_RPM2CPIO(APPLET(rpm2cpio, BB_DIR_USR_BIN, BB_SUID_DROP))
     17//kbuild:lib-$(CONFIG_RPM2CPIO) += rpm2cpio.o
    918
    1019//usage:#define rpm2cpio_trivial_usage
     
    7281
    7382    /* This works, but doesn't report uncompress errors (they happen in child) */
    74     setup_unzip_on_fd(rpm_fd, /*fail_if_not_detected:*/ 1);
     83    setup_unzip_on_fd(rpm_fd, /*fail_if_not_compressed:*/ 1);
    7584    if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0)
    7685        bb_error_msg_and_die("error unpacking");
  • branches/3.3/mindi-busybox/archival/tar.c

    r3232 r3621  
    2323 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    2424 */
    25 
    2625/* TODO: security with -C DESTDIR option can be enhanced.
    2726 * Consider tar file created via:
     
    4342 */
    4443
     44//config:config TAR
     45//config:   bool "tar"
     46//config:   default y
     47//config:   help
     48//config:     tar is an archiving program. It's commonly used with gzip to
     49//config:     create compressed archives. It's probably the most widely used
     50//config:     UNIX archive program.
     51//config:
     52//config:config FEATURE_TAR_CREATE
     53//config:   bool "Enable archive creation"
     54//config:   default y
     55//config:   depends on TAR
     56//config:   help
     57//config:     If you enable this option you'll be able to create
     58//config:     tar archives using the `-c' option.
     59//config:
     60//config:config FEATURE_TAR_AUTODETECT
     61//config:   bool "Autodetect compressed tarballs"
     62//config:   default y
     63//config:   depends on TAR && (FEATURE_SEAMLESS_Z || FEATURE_SEAMLESS_GZ || FEATURE_SEAMLESS_BZ2 || FEATURE_SEAMLESS_LZMA || FEATURE_SEAMLESS_XZ)
     64//config:   help
     65//config:     With this option tar can automatically detect compressed
     66//config:     tarballs. Currently it works only on files (not pipes etc).
     67//config:
     68//config:config FEATURE_TAR_FROM
     69//config:   bool "Enable -X (exclude from) and -T (include from) options)"
     70//config:   default y
     71//config:   depends on TAR
     72//config:   help
     73//config:     If you enable this option you'll be able to specify
     74//config:     a list of files to include or exclude from an archive.
     75//config:
     76//config:config FEATURE_TAR_OLDGNU_COMPATIBILITY
     77//config:   bool "Support for old tar header format"
     78//config:   default y
     79//config:   depends on TAR || DPKG
     80//config:   help
     81//config:     This option is required to unpack archives created in
     82//config:     the old GNU format; help to kill this old format by
     83//config:     repacking your ancient archives with the new format.
     84//config:
     85//config:config FEATURE_TAR_OLDSUN_COMPATIBILITY
     86//config:   bool "Enable untarring of tarballs with checksums produced by buggy Sun tar"
     87//config:   default y
     88//config:   depends on TAR || DPKG
     89//config:   help
     90//config:     This option is required to unpack archives created by some old
     91//config:     version of Sun's tar (it was calculating checksum using signed
     92//config:     arithmetic). It is said to be fixed in newer Sun tar, but "old"
     93//config:     tarballs still exist.
     94//config:
     95//config:config FEATURE_TAR_GNU_EXTENSIONS
     96//config:   bool "Support for GNU tar extensions (long filenames)"
     97//config:   default y
     98//config:   depends on TAR || DPKG
     99//config:   help
     100//config:     With this option busybox supports GNU long filenames and
     101//config:     linknames.
     102//config:
     103//config:config FEATURE_TAR_LONG_OPTIONS
     104//config:   bool "Enable long options"
     105//config:   default y
     106//config:   depends on TAR && LONG_OPTS
     107//config:   help
     108//config:     Enable use of long options, increases size by about 400 Bytes
     109//config:
     110//config:config FEATURE_TAR_TO_COMMAND
     111//config:   bool "Support for writing to an external program"
     112//config:   default y
     113//config:   depends on TAR && FEATURE_TAR_LONG_OPTIONS
     114//config:   help
     115//config:     If you enable this option you'll be able to instruct tar to send
     116//config:     the contents of each extracted file to the standard input of an
     117//config:     external program.
     118//config:
     119//config:config FEATURE_TAR_UNAME_GNAME
     120//config:   bool "Enable use of user and group names"
     121//config:   default y
     122//config:   depends on TAR
     123//config:   help
     124//config:     Enables use of user and group names in tar. This affects contents
     125//config:     listings (-t) and preserving permissions when unpacking (-p).
     126//config:     +200 bytes.
     127//config:
     128//config:config FEATURE_TAR_NOPRESERVE_TIME
     129//config:   bool "Enable -m (do not preserve time) option"
     130//config:   default y
     131//config:   depends on TAR
     132//config:   help
     133//config:     With this option busybox supports GNU tar -m
     134//config:     (do not preserve time) option.
     135//config:
     136//config:config FEATURE_TAR_SELINUX
     137//config:   bool "Support for extracting SELinux labels"
     138//config:   default n
     139//config:   depends on TAR && SELINUX
     140//config:   help
     141//config:     With this option busybox supports restoring SELinux labels
     142//config:     when extracting files from tar archives.
     143
     144//applet:IF_TAR(APPLET(tar, BB_DIR_BIN, BB_SUID_DROP))
     145//kbuild:lib-$(CONFIG_TAR) += tar.o
     146
    45147#include <fnmatch.h>
    46148#include "libbb.h"
     149#include "common_bufsiz.h"
    47150#include "bb_archive.h"
    48151/* FIXME: Stop using this non-standard feature */
     
    51154#endif
    52155
    53 
    54 //#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__)
    55 #define DBG(...) ((void)0)
     156#if 0
     157# define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__)
     158#else
     159# define DBG(...) ((void)0)
     160#endif
     161#define DBG_OPTION_PARSING 0
    56162
    57163
    58164#define block_buf bb_common_bufsiz1
    59 
    60 
    61 #if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2
    62 /* Do not pass gzip flag to writeTarFile() */
    63 #define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \
    64     writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude)
    65 #endif
     165#define INIT_G() do { setup_common_bufsiz(); } while (0)
    66166
    67167
     
    520620}
    521621
    522 #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
    523 # if !(ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2)
    524 #  define vfork_compressor(tar_fd, gzip) vfork_compressor(tar_fd)
    525 # endif
     622#if SEAMLESS_COMPRESSION
    526623/* Don't inline: vfork scares gcc and pessimizes code */
    527 static void NOINLINE vfork_compressor(int tar_fd, int gzip)
     624static void NOINLINE vfork_compressor(int tar_fd, const char *gzip)
    528625{
    529626    pid_t gzipPid;
    530 # if ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2
    531     const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2";
    532 # elif ENABLE_FEATURE_SEAMLESS_GZ
    533     const char *zip_exec = "gzip";
    534 # else /* only ENABLE_FEATURE_SEAMLESS_BZ2 */
    535     const char *zip_exec = "bzip2";
    536 # endif
     627
    537628    // On Linux, vfork never unpauses parent early, although standard
    538629    // allows for that. Do we want to waste bytes checking for it?
     
    547638
    548639    signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */
    549 
    550 # if defined(__GNUC__) && __GNUC__
    551     /* Avoid vfork clobbering */
    552     (void) &zip_exec;
    553 # endif
    554640
    555641    gzipPid = xvfork();
     
    568654        xmove_fd(tar_fd, 1);
    569655        /* exec gzip/bzip2 program/applet */
    570         BB_EXECLP(zip_exec, zip_exec, "-f", NULL);
     656        BB_EXECLP(gzip, gzip, "-f", (char *)0);
    571657        vfork_exec_errno = errno;
    572658        _exit(EXIT_FAILURE);
     
    591677    if (vfork_exec_errno) {
    592678        errno = vfork_exec_errno;
    593         bb_perror_msg_and_die("can't execute '%s'", zip_exec);
     679        bb_perror_msg_and_die("can't execute '%s'", gzip);
    594680    }
    595681}
    596 #endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 */
    597 
    598 
     682#endif /* SEAMLESS_COMPRESSION */
     683
     684
     685#if !SEAMLESS_COMPRESSION
     686/* Do not pass gzip flag to writeTarFile() */
     687#define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \
     688    writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude)
     689#endif
    599690/* gcc 4.2.1 inlines it, making code bigger */
    600691static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
    601692    int recurseFlags, const llist_t *include,
    602     const llist_t *exclude, int gzip)
     693    const llist_t *exclude, const char *gzip)
    603694{
    604695    int errorFlag = FALSE;
     
    613704    xfstat(tbInfo.tarFd, &tbInfo.tarFileStatBuf, "can't stat tar file");
    614705
    615 #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
     706#if SEAMLESS_COMPRESSION
    616707    if (gzip)
    617708        vfork_compressor(tbInfo.tarFd, gzip);
     
    648739        bb_error_msg("error exit delayed from previous errors");
    649740
    650 #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
     741#if SEAMLESS_COMPRESSION
    651742    if (gzip) {
    652743        int status;
     
    660751    return errorFlag;
    661752}
    662 #else
    663 int writeTarFile(int tar_fd, int verboseFlag,
    664     int recurseFlags, const llist_t *include,
    665     const llist_t *exclude, int gzip);
    666 #endif /* FEATURE_TAR_CREATE */
     753#else /* !FEATURE_TAR_CREATE */
     754# define writeTarFile(...) 0
     755#endif
    667756
    668757#if ENABLE_FEATURE_TAR_FROM
     
    680769            if (cp > line)
    681770                *cp = '\0';
    682             llist_add_to(&newlist, line);
     771            llist_add_to_end(&newlist, line);
    683772        }
    684773        fclose(src_stream);
     
    686775    return newlist;
    687776}
    688 #else
    689 # define append_file_list_to_list(x) 0
    690777#endif
    691778
     
    774861    IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,)
    775862#if ENABLE_FEATURE_TAR_LONG_OPTIONS
     863    OPTBIT_STRIP_COMPONENTS,
    776864    OPTBIT_NORECURSION,
    777865    IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND   ,)
     
    798886    OPT_XZ           = IF_FEATURE_SEAMLESS_XZ(  (1 << OPTBIT_XZ          )) + 0, // J
    799887    OPT_COMPRESS     = IF_FEATURE_SEAMLESS_Z(   (1 << OPTBIT_COMPRESS    )) + 0, // Z
    800     OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m
    801     OPT_NORECURSION     = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION    )) + 0, // no-recursion
    802     OPT_2COMMAND        = IF_FEATURE_TAR_TO_COMMAND(  (1 << OPTBIT_2COMMAND       )) + 0, // to-command
    803     OPT_NUMERIC_OWNER   = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER  )) + 0, // numeric-owner
    804     OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions
    805     OPT_OVERWRITE       = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE      )) + 0, // overwrite
     888    OPT_NOPRESERVE_TIME  = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m
     889    OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components
     890    OPT_NORECURSION      = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION    )) + 0, // no-recursion
     891    OPT_2COMMAND         = IF_FEATURE_TAR_TO_COMMAND(  (1 << OPTBIT_2COMMAND       )) + 0, // to-command
     892    OPT_NUMERIC_OWNER    = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER  )) + 0, // numeric-owner
     893    OPT_NOPRESERVE_PERM  = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions
     894    OPT_OVERWRITE        = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE      )) + 0, // overwrite
    806895
    807896    OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS),
     
    847936    "touch\0"               No_argument       "m"
    848937# endif
     938    "strip-components\0"    Required_argument "\xf9"
    849939    "no-recursion\0"    No_argument       "\xfa"
    850940# if ENABLE_FEATURE_TAR_TO_COMMAND
     
    876966    llist_t *excludes = NULL;
    877967#endif
     968    INIT_G();
    878969
    879970    /* Initialise default values */
     
    892983        IF_FEATURE_TAR_FROM("X::T::") // cumulative lists
    893984#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
    894         "\xff::" // cumulative lists for --exclude
     985        "\xff::" // --exclude=PATTERN is a list
    895986#endif
    896987        IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd
    897988        IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive
    898         IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive
     989        IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive
     990#if ENABLE_FEATURE_TAR_LONG_OPTIONS
     991        ":\xf9+" // --strip-components=NUM
     992#endif
     993    ;
    899994#if ENABLE_FEATURE_TAR_LONG_OPTIONS
    900995    applet_long_options = tar_longopts;
    901996#endif
    902997#if ENABLE_DESKTOP
     998    /* Lie to buildroot when it starts asking stupid questions. */
     999    if (argv[1] && strcmp(argv[1], "--version") == 0) {
     1000        // Output of 'tar --version' examples:
     1001        // tar (GNU tar) 1.15.1
     1002        // tar (GNU tar) 1.25
     1003        // bsdtar 2.8.3 - libarchive 2.8.3
     1004        puts("tar (busybox) " BB_VER);
     1005        return 0;
     1006    }
    9031007    if (argv[1] && argv[1][0] != '-') {
    9041008        /* Compat:
     
    9371041        IF_FEATURE_SEAMLESS_Z(   "Z"   )
    9381042        IF_FEATURE_TAR_NOPRESERVE_TIME("m")
     1043        IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components
    9391044        , &base_dir // -C dir
    9401045        , &tar_filename // -f filename
    9411046        IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T
    9421047        IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X
     1048#if ENABLE_FEATURE_TAR_LONG_OPTIONS
     1049        , &tar_handle->tar__strip_components // --strip-components
     1050#endif
    9431051        IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command
    9441052#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
     
    9481056        , &verboseFlag // combined count for -t and -v
    9491057        );
    950     //bb_error_msg("opt:%08x", opt);
     1058#if DBG_OPTION_PARSING
     1059    bb_error_msg("opt: 0x%08x", opt);
     1060# define showopt(o) bb_error_msg("opt & %s(%x): %x", #o, o, opt & o);
     1061    showopt(OPT_TEST            );
     1062    showopt(OPT_EXTRACT         );
     1063    showopt(OPT_BASEDIR         );
     1064    showopt(OPT_TARNAME         );
     1065    showopt(OPT_2STDOUT         );
     1066    showopt(OPT_NOPRESERVE_OWNER);
     1067    showopt(OPT_P               );
     1068    showopt(OPT_VERBOSE         );
     1069    showopt(OPT_KEEP_OLD        );
     1070    showopt(OPT_CREATE          );
     1071    showopt(OPT_DEREFERENCE     );
     1072    showopt(OPT_BZIP2           );
     1073    showopt(OPT_LZMA            );
     1074    showopt(OPT_INCLUDE_FROM    );
     1075    showopt(OPT_EXCLUDE_FROM    );
     1076    showopt(OPT_GZIP            );
     1077    showopt(OPT_XZ              );
     1078    showopt(OPT_COMPRESS        );
     1079    showopt(OPT_NOPRESERVE_TIME );
     1080    showopt(OPT_STRIP_COMPONENTS);
     1081    showopt(OPT_NORECURSION     );
     1082    showopt(OPT_2COMMAND        );
     1083    showopt(OPT_NUMERIC_OWNER   );
     1084    showopt(OPT_NOPRESERVE_PERM );
     1085    showopt(OPT_OVERWRITE       );
     1086    showopt(OPT_ANY_COMPRESS    );
     1087    bb_error_msg("base_dir:'%s'", base_dir);
     1088    bb_error_msg("tar_filename:'%s'", tar_filename);
     1089    bb_error_msg("verboseFlag:%d", verboseFlag);
     1090    bb_error_msg("tar_handle->tar__to_command:'%s'", tar_handle->tar__to_command);
     1091    bb_error_msg("tar_handle->tar__strip_components:%u", tar_handle->tar__strip_components);
     1092    return 0;
     1093# undef showopt
     1094#endif
    9511095    argv += optind;
    9521096
    953     if (verboseFlag) tar_handle->action_header = header_verbose_list;
    954     if (verboseFlag == 1) tar_handle->action_header = header_list;
     1097    if (verboseFlag)
     1098        tar_handle->action_header = header_verbose_list;
     1099    if (verboseFlag == 1)
     1100        tar_handle->action_header = header_list;
    9551101
    9561102    if (opt & OPT_EXTRACT)
     
    10381184             && !(opt & OPT_ANY_COMPRESS)
    10391185            ) {
    1040                 tar_handle->src_fd = open_zipped(tar_filename);
     1186                tar_handle->src_fd = open_zipped(tar_filename, /*fail_if_not_compressed:*/ 0);
    10411187                if (tar_handle->src_fd < 0)
    10421188                    bb_perror_msg_and_die("can't open '%s'", tar_filename);
     
    10501196        xchdir(base_dir);
    10511197
    1052     //if (SEAMLESS_COMPRESSION || OPT_COMPRESS)
     1198    //if (SEAMLESS_COMPRESSION)
    10531199    //  /* We need to know whether child (gzip/bzip/etc) exits abnormally */
    10541200    //  signal(SIGCHLD, check_errors_in_children);
    10551201
     1202#if ENABLE_FEATURE_TAR_CREATE
    10561203    /* Create an archive */
    10571204    if (opt & OPT_CREATE) {
    1058 #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
    1059         int zipMode = 0;
    1060         if (ENABLE_FEATURE_SEAMLESS_GZ && (opt & OPT_GZIP))
    1061             zipMode = 1;
    1062         if (ENABLE_FEATURE_SEAMLESS_BZ2 && (opt & OPT_BZIP2))
    1063             zipMode = 2;
    1064 #endif
     1205# if SEAMLESS_COMPRESSION
     1206        const char *zipMode = NULL;
     1207        if (opt & OPT_COMPRESS)
     1208            zipMode = "compress";
     1209        if (opt & OPT_GZIP)
     1210            zipMode = "gzip";
     1211        if (opt & OPT_BZIP2)
     1212            zipMode = "bzip2";
     1213        if (opt & OPT_LZMA)
     1214            zipMode = "lzma";
     1215        if (opt & OPT_XZ)
     1216            zipMode = "xz";
     1217# endif
    10651218        /* NB: writeTarFile() closes tar_handle->src_fd */
    10661219        return writeTarFile(tar_handle->src_fd, verboseFlag,
     
    10701223                tar_handle->reject, zipMode);
    10711224    }
     1225#endif
    10721226
    10731227    if (opt & OPT_ANY_COMPRESS) {
    1074         USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);)
     1228        USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_state_t *xstate);)
    10751229        USE_FOR_NOMMU(const char *xformer_prog;)
    10761230
     
    10911245            USE_FOR_NOMMU(xformer_prog = "unxz";)
    10921246
    1093         open_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog);
     1247        fork_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog);
    10941248        /* Can't lseek over pipes */
    10951249        tar_handle->seek = seek_by_read;
     
    10971251    }
    10981252
     1253    /* Zero processed headers (== empty file) is not a valid tarball.
     1254     * We (ab)use bb_got_signal as exitcode here,
     1255     * because check_errors_in_children() uses _it_ as error indicator.
     1256     */
     1257    bb_got_signal = EXIT_FAILURE;
     1258
    10991259    while (get_header_tar(tar_handle) == EXIT_SUCCESS)
    1100         continue;
     1260        bb_got_signal = EXIT_SUCCESS; /* saw at least one header, good */
    11011261
    11021262    /* Check that every file that should have been extracted was */
     
    11141274
    11151275    if (SEAMLESS_COMPRESSION || OPT_COMPRESS) {
     1276        /* Set bb_got_signal to 1 if a child died with !0 exitcode */
    11161277        check_errors_in_children(0);
    1117         return bb_got_signal;
    1118     }
    1119     return EXIT_SUCCESS;
     1278    }
     1279
     1280    return bb_got_signal;
    11201281}
  • branches/3.3/mindi-busybox/archival/unzip.c

    r3232 r3621  
    1010 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1111 */
    12 
    1312/* For reference see
    1413 * http://www.pkware.com/company/standards/appnote/
    1514 * http://www.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
    16  */
    17 
    18 /* TODO
     15 *
     16 * TODO
    1917 * Zip64 + other methods
    2018 */
     19
     20//config:config UNZIP
     21//config:   bool "unzip"
     22//config:   default y
     23//config:   help
     24//config:     unzip will list or extract files from a ZIP archive,
     25//config:     commonly found on DOS/WIN systems. The default behavior
     26//config:     (with no options) is to extract the archive into the
     27//config:     current directory. Use the `-d' option to extract to a
     28//config:     directory of your choice.
     29
     30//applet:IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP))
     31//kbuild:lib-$(CONFIG_UNZIP) += unzip.o
    2132
    2233//usage:#define unzip_trivial_usage
     
    3445#include "libbb.h"
    3546#include "bb_archive.h"
     47
     48#if 0
     49# define dbg(...) bb_error_msg(__VA_ARGS__)
     50#else
     51# define dbg(...) ((void)0)
     52#endif
    3653
    3754enum {
     
    164181#if ENABLE_DESKTOP
    165182
    166 #define PEEK_FROM_END 16384
     183/* Seen in the wild:
     184 * Self-extracting PRO2K3XP_32.exe contains 19078464 byte zip archive,
     185 * where CDE was nearly 48 kbytes before EOF.
     186 * (Surprisingly, it also apparently has *another* CDE structure
     187 * closer to the end, with bogus cdf_offset).
     188 * To make extraction work, bumped PEEK_FROM_END from 16k to 64k.
     189 */
     190#define PEEK_FROM_END (64*1024)
     191
     192/* This value means that we failed to find CDF */
     193#define BAD_CDF_OFFSET ((uint32_t)0xffffffff)
    167194
    168195/* NB: does not preserve file position! */
     
    173200    off_t end;
    174201    unsigned char *buf = xzalloc(PEEK_FROM_END);
     202    uint32_t found;
    175203
    176204    end = xlseek(zip_fd, 0, SEEK_END);
     
    178206    if (end < 0)
    179207        end = 0;
    180     xlseek(zip_fd, end, SEEK_SET);
     208    dbg("Looking for cdf_offset starting from 0x%"OFF_FMT"x", end);
     209    xlseek(zip_fd, end, SEEK_SET);
    181210    full_read(zip_fd, buf, PEEK_FROM_END);
    182211
     212    found = BAD_CDF_OFFSET;
    183213    p = buf;
    184214    while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) {
     
    196226        memcpy(cde_header.raw, p + 1, CDE_HEADER_LEN);
    197227        FIX_ENDIANNESS_CDE(cde_header);
    198         free(buf);
    199         return cde_header.formatted.cdf_offset;
    200     }
    201     //free(buf);
    202     bb_error_msg_and_die("can't find file table");
     228        /*
     229         * I've seen .ZIP files with seemingly valid CDEs
     230         * where cdf_offset points past EOF - ??
     231         * This check ignores such CDEs:
     232         */
     233        if (cde_header.formatted.cdf_offset < end + (p - buf)) {
     234            found = cde_header.formatted.cdf_offset;
     235            dbg("Possible cdf_offset:0x%x at 0x%"OFF_FMT"x",
     236                (unsigned)found, end + (p-3 - buf));
     237            dbg("  cdf_offset+cdf_size:0x%x",
     238                (unsigned)(found + SWAP_LE32(cde_header.formatted.cdf_size)));
     239            /*
     240             * We do not "break" here because only the last CDE is valid.
     241             * I've seen a .zip archive which contained a .zip file,
     242             * uncompressed, and taking the first CDE was using
     243             * the CDE inside that file!
     244             */
     245        }
     246    }
     247    free(buf);
     248    dbg("Found cdf_offset:0x%x", (unsigned)found);
     249    return found;
    203250};
    204251
     
    212259        cdf_offset = find_cdf_offset();
    213260
    214     xlseek(zip_fd, cdf_offset + 4, SEEK_SET);
    215     xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN);
    216     FIX_ENDIANNESS_CDF(*cdf_ptr);
    217     cdf_offset += 4 + CDF_HEADER_LEN
    218         + cdf_ptr->formatted.file_name_length
    219         + cdf_ptr->formatted.extra_field_length
    220         + cdf_ptr->formatted.file_comment_length;
    221 
     261    if (cdf_offset != BAD_CDF_OFFSET) {
     262        dbg("Reading CDF at 0x%x", (unsigned)cdf_offset);
     263        xlseek(zip_fd, cdf_offset + 4, SEEK_SET);
     264        xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN);
     265        FIX_ENDIANNESS_CDF(*cdf_ptr);
     266        dbg("  file_name_length:%u extra_field_length:%u file_comment_length:%u",
     267            (unsigned)cdf_ptr->formatted.file_name_length,
     268            (unsigned)cdf_ptr->formatted.extra_field_length,
     269            (unsigned)cdf_ptr->formatted.file_comment_length
     270        );
     271        cdf_offset += 4 + CDF_HEADER_LEN
     272            + cdf_ptr->formatted.file_name_length
     273            + cdf_ptr->formatted.extra_field_length
     274            + cdf_ptr->formatted.file_comment_length;
     275    }
     276
     277    dbg("Returning file position to 0x%"OFF_FMT"x", org);
    222278    xlseek(zip_fd, org, SEEK_SET);
    223279    return cdf_offset;
     
    227283static void unzip_skip(off_t skip)
    228284{
    229     if (lseek(zip_fd, skip, SEEK_CUR) == (off_t)-1)
    230         bb_copyfd_exact_size(zip_fd, -1, skip);
     285    if (skip != 0)
     286        if (lseek(zip_fd, skip, SEEK_CUR) == (off_t)-1)
     287            bb_copyfd_exact_size(zip_fd, -1, skip);
    231288}
    232289
     
    250307    } else {
    251308        /* Method 8 - inflate */
    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)
     309        transformer_state_t xstate;
     310        init_transformer_state(&xstate);
     311        xstate.bytes_in = zip_header->formatted.cmpsize;
     312        xstate.src_fd = zip_fd;
     313        xstate.dst_fd = dst_fd;
     314        if (inflate_unzip(&xstate) < 0)
    256315            bb_error_msg_and_die("inflate error");
    257316        /* Validate decompression - crc */
    258         if (zip_header->formatted.crc32 != (aux.crc32 ^ 0xffffffffL)) {
     317        if (zip_header->formatted.crc32 != (xstate.crc32 ^ 0xffffffffL)) {
    259318            bb_error_msg_and_die("crc error");
    260319        }
    261320        /* Validate decompression - size */
    262         if (zip_header->formatted.ucmpsize != aux.bytes_out) {
     321        if (zip_header->formatted.ucmpsize != xstate.bytes_out) {
    263322            /* Don't die. Who knows, maybe len calculation
    264323             * was botched somewhere. After all, crc matched! */
    265324            bb_error_msg("bad length");
    266325        }
     326    }
     327}
     328
     329static void my_fgets80(char *buf80)
     330{
     331    fflush_all();
     332    if (!fgets(buf80, 80, stdin)) {
     333        bb_perror_msg_and_die("can't read standard input");
    267334    }
    268335}
     
    292359    char *base_dir = NULL;
    293360    int i, opt;
    294     char key_buf[80];
     361    char key_buf[80]; /* must match size used by my_fgets80 */
    295362    struct stat stat_buf;
    296363
     
    421488            overwrite = O_NEVER;
    422489    } else {
    423         static const char extn[][5] = { ".zip", ".ZIP" };
     490        static const char extn[][5] ALIGN1 = { ".zip", ".ZIP" };
    424491        char *ext = src_fn + strlen(src_fn);
    425492        int src_fd;
     
    448515        if (listing) {
    449516            puts(verbose ?
    450                 " Length   Method    Size  Ratio   Date   Time   CRC-32    Name\n"
    451                 "--------  ------  ------- -----   ----   ----   ------    ----"
     517                " Length   Method    Size  Cmpr    Date    Time   CRC-32   Name\n"
     518                "--------  ------  ------- ---- ---------- ----- --------  ----"
    452519                :
    453                 "  Length     Date   Time    Name\n"
    454                 " --------    ----   ----    ----"
     520                "  Length      Date    Time    Name\n"
     521                "---------  ---------- -----   ----"
    455522                );
    456523        }
     
    492559        xread(zip_fd, &magic, 4);
    493560        /* Central directory? It's at the end, so exit */
    494         if (magic == ZIP_CDF_MAGIC)
    495             break;
     561        if (magic == ZIP_CDF_MAGIC) {
     562            dbg("got ZIP_CDF_MAGIC");
     563            break;
     564        }
    496565#if ENABLE_DESKTOP
    497566        /* Data descriptor? It was a streaming file, go on */
    498567        if (magic == ZIP_DD_MAGIC) {
     568            dbg("got ZIP_DD_MAGIC");
    499569            /* skip over duplicate crc32, cmpsize and ucmpsize */
    500570            unzip_skip(3 * 4);
     
    504574        if (magic != ZIP_FILEHEADER_MAGIC)
    505575            bb_error_msg_and_die("invalid zip magic %08X", (int)magic);
     576        dbg("got ZIP_FILEHEADER_MAGIC");
    506577
    507578        /* Read the file header */
     
    521592        }
    522593
    523         {
     594        if (cdf_offset != BAD_CDF_OFFSET) {
    524595            cdf_header_t cdf_header;
    525596            cdf_offset = read_next_cdf(cdf_offset, &cdf_header);
     597            /*
     598             * Note: cdf_offset can become BAD_CDF_OFFSET after the above call.
     599             */
    526600            if (zip_header.formatted.zip_flags & SWAP_LE16(0x0008)) {
    527601                /* 0x0008 - streaming. [u]cmpsize can be reliably gotten
    528                  * only from Central Directory. See unzip_doc.txt */
     602                 * only from Central Directory. See unzip_doc.txt
     603                 */
    529604                zip_header.formatted.crc32    = cdf_header.formatted.crc32;
    530605                zip_header.formatted.cmpsize  = cdf_header.formatted.cmpsize;
     
    532607            }
    533608            if ((cdf_header.formatted.version_made_by >> 8) == 3) {
    534                 /* this archive is created on Unix */
     609                /* This archive is created on Unix */
    535610                dir_mode = file_mode = (cdf_header.formatted.external_file_attributes >> 16);
    536611            }
    537612        }
    538 #endif
     613        if (cdf_offset == BAD_CDF_OFFSET
     614         && (zip_header.formatted.zip_flags & SWAP_LE16(0x0008))
     615        ) {
     616            /* If it's a streaming zip, we _require_ CDF */
     617            bb_error_msg_and_die("can't find file table");
     618        }
     619#endif
     620        dbg("File cmpsize:0x%x extra_len:0x%x ucmpsize:0x%x",
     621            (unsigned)zip_header.formatted.cmpsize,
     622            (unsigned)zip_header.formatted.extra_len,
     623            (unsigned)zip_header.formatted.ucmpsize
     624        );
    539625
    540626        /* Read filename */
     
    545631        /* Skip extra header bytes */
    546632        unzip_skip(zip_header.formatted.extra_len);
     633
     634        /* Guard against "/abspath", "/../" and similar attacks */
     635        overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn));
    547636
    548637        /* Filter zip entries */
     
    551640        ) { /* Skip entry */
    552641            i = 'n';
    553 
    554         } else { /* Extract entry */
    555             if (listing) { /* List entry */
    556                 unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16);
     642        } else {
     643            if (listing) {
     644                /* List entry */
     645                char dtbuf[sizeof("mm-dd-yyyy hh:mm")];
     646                sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u",
     647                    (zip_header.formatted.moddate >> 5) & 0xf,  // mm: 0x01e0
     648                    (zip_header.formatted.moddate)      & 0x1f, // dd: 0x001f
     649                    (zip_header.formatted.moddate >> 9) + 1980, // yy: 0xfe00
     650                    (zip_header.formatted.modtime >> 11),       // hh: 0xf800
     651                    (zip_header.formatted.modtime >> 5) & 0x3f  // mm: 0x07e0
     652                    // seconds/2 are not shown, encoded in ----------- 0x001f
     653                );
    557654                if (!verbose) {
    558                     //      "  Length     Date   Time    Name\n"
    559                     //      " --------    ----   ----    ----"
    560                     printf(       "%9u  %02u-%02u-%02u %02u:%02u   %s\n",
     655                    //      "  Length      Date    Time    Name\n"
     656                    //      "---------  ---------- -----   ----"
     657                    printf(       "%9u  " "%s   "         "%s\n",
    561658                        (unsigned)zip_header.formatted.ucmpsize,
    562                         (dostime & 0x01e00000) >> 21,
    563                         (dostime & 0x001f0000) >> 16,
    564                         (((dostime & 0xfe000000) >> 25) + 1980) % 100,
    565                         (dostime & 0x0000f800) >> 11,
    566                         (dostime & 0x000007e0) >> 5,
     659                        dtbuf,
    567660                        dst_fn);
    568                     total_usize += zip_header.formatted.ucmpsize;
    569661                } else {
    570662                    unsigned long percents = zip_header.formatted.ucmpsize - zip_header.formatted.cmpsize;
     663                    if ((int32_t)percents < 0)
     664                        percents = 0; /* happens if ucmpsize < cmpsize */
    571665                    percents = percents * 100;
    572666                    if (zip_header.formatted.ucmpsize)
    573667                        percents /= zip_header.formatted.ucmpsize;
    574                     //      " Length   Method    Size  Ratio   Date   Time   CRC-32    Name\n"
    575                     //      "--------  ------  ------- -----   ----   ----   ------    ----"
    576                     printf(      "%8u  Defl:N"    "%9u%4u%%  %02u-%02u-%02u %02u:%02u  %08x  %s\n",
     668                    //      " Length   Method    Size  Cmpr    Date    Time   CRC-32   Name\n"
     669                    //      "--------  ------  ------- ---- ---------- ----- --------  ----"
     670                    printf(      "%8u  %s"        "%9u%4u%% " "%s "         "%08x  "  "%s\n",
    577671                        (unsigned)zip_header.formatted.ucmpsize,
     672                        zip_header.formatted.method == 0 ? "Stored" : "Defl:N", /* Defl is method 8 */
     673/* TODO: show other methods?
     674 *  1 - Shrunk
     675 *  2 - Reduced with compression factor 1
     676 *  3 - Reduced with compression factor 2
     677 *  4 - Reduced with compression factor 3
     678 *  5 - Reduced with compression factor 4
     679 *  6 - Imploded
     680 *  7 - Reserved for Tokenizing compression algorithm
     681 *  9 - Deflate64
     682 * 10 - PKWARE Data Compression Library Imploding
     683 * 11 - Reserved by PKWARE
     684 * 12 - BZIP2
     685 */
    578686                        (unsigned)zip_header.formatted.cmpsize,
    579687                        (unsigned)percents,
    580                         (dostime & 0x01e00000) >> 21,
    581                         (dostime & 0x001f0000) >> 16,
    582                         (((dostime & 0xfe000000) >> 25) + 1980) % 100,
    583                         (dostime & 0x0000f800) >> 11,
    584                         (dostime & 0x000007e0) >> 5,
     688                        dtbuf,
    585689                        zip_header.formatted.crc32,
    586690                        dst_fn);
    587                     total_usize += zip_header.formatted.ucmpsize;
    588691                    total_size += zip_header.formatted.cmpsize;
    589692                }
     693                total_usize += zip_header.formatted.ucmpsize;
    590694                i = 'n';
    591             } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */
     695            } else if (dst_fd == STDOUT_FILENO) {
     696                /* Extracting to STDOUT */
    592697                i = -1;
    593             } else if (last_char_is(dst_fn, '/')) { /* Extract directory */
     698            } else if (last_char_is(dst_fn, '/')) {
     699                /* Extract directory */
    594700                if (stat(dst_fn, &stat_buf) == -1) {
    595701                    if (errno != ENOENT) {
     
    605711                } else {
    606712                    if (!S_ISDIR(stat_buf.st_mode)) {
    607                         bb_error_msg_and_die("'%s' exists but is not directory", dst_fn);
     713                        bb_error_msg_and_die("'%s' exists but is not a %s",
     714                            dst_fn, "directory");
    608715                    }
    609716                }
    610717                i = 'n';
    611 
    612             } else {  /* Extract file */
     718            } else {
     719                /* Extract file */
    613720 check_file:
    614                 if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */
     721                if (stat(dst_fn, &stat_buf) == -1) {
     722                    /* File does not exist */
    615723                    if (errno != ENOENT) {
    616724                        bb_perror_msg_and_die("can't stat '%s'", dst_fn);
    617725                    }
    618726                    i = 'y';
    619                 } else { /* File already exists */
     727                } else {
     728                    /* File already exists */
    620729                    if (overwrite == O_NEVER) {
    621730                        i = 'n';
    622                     } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */
     731                    } else if (S_ISREG(stat_buf.st_mode)) {
     732                        /* File is regular file */
    623733                        if (overwrite == O_ALWAYS) {
    624734                            i = 'y';
    625735                        } else {
    626736                            printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn);
    627                             fflush_all();
    628                             if (!fgets(key_buf, sizeof(key_buf), stdin)) {
    629                                 bb_perror_msg_and_die("can't read input");
    630                             }
     737                            my_fgets80(key_buf);
    631738                            i = key_buf[0];
    632739                        }
    633                     } else { /* File is not regular file */
    634                         bb_error_msg_and_die("'%s' exists but is not regular file", dst_fn);
     740                    } else {
     741                        /* File is not regular file */
     742                        bb_error_msg_and_die("'%s' exists but is not a %s",
     743                            dst_fn, "regular file");
    635744                    }
    636745                }
     
    669778            /* Prompt for new name */
    670779            printf("new name: ");
    671             if (!fgets(key_buf, sizeof(key_buf), stdin)) {
    672                 bb_perror_msg_and_die("can't read input");
    673             }
     780            my_fgets80(key_buf);
    674781            free(dst_fn);
    675782            dst_fn = xstrdup(key_buf);
     
    687794    if (listing && quiet <= 1) {
    688795        if (!verbose) {
    689             //      "  Length     Date   Time    Name\n"
    690             //      " --------    ----   ----    ----"
    691             printf( " --------                   -------\n"
    692                 "%9lu"   "                   %u files\n",
    693                 total_usize, total_entries);
     796            //  "  Length      Date    Time    Name\n"
     797            //  "---------  ---------- -----   ----"
     798            printf( " --------%21s"               "-------\n"
     799                     "%9lu%21s"               "%u files\n",
     800                "",
     801                total_usize, "", total_entries);
    694802        } else {
    695803            unsigned long percents = total_usize - total_size;
     804            if ((long)percents < 0)
     805                percents = 0; /* happens if usize < size */
    696806            percents = percents * 100;
    697807            if (total_usize)
    698808                percents /= total_usize;
    699             //      " Length   Method    Size  Ratio   Date   Time   CRC-32    Name\n"
    700             //      "--------  ------  ------- -----   ----   ----   ------    ----"
    701             printf( "--------          -------  ---                            -------\n"
    702                 "%8lu"              "%17lu%4u%%                            %u files\n",
    703                 total_usize, total_size, (unsigned)percents,
     809            //  " Length   Method    Size  Cmpr    Date    Time   CRC-32   Name\n"
     810            //  "--------  ------  ------- ---- ---------- ----- --------  ----"
     811            printf( "--------          ------- ----%28s"                      "----\n"
     812                "%8lu"              "%17lu%4u%%%28s"                      "%u files\n",
     813                "",
     814                total_usize, total_size, (unsigned)percents, "",
    704815                total_entries);
    705816        }
Note: See TracChangeset for help on using the changeset viewer.