Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/archival


Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (16 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

Location:
branches/2.2.5/mindi-busybox/archival
Files:
4 added
10 deleted
39 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/archival/Config.in

    r821 r1765  
    66menu "Archival Utilities"
    77
    8 config CONFIG_AR
     8config AR
    99    bool "ar"
    1010    default n
     
    2929      probably say N here.
    3030
    31 config CONFIG_FEATURE_AR_LONG_FILENAMES
     31config FEATURE_AR_LONG_FILENAMES
    3232    bool "Enable support for long filenames (not need for debs)"
    3333    default n
    34     depends on CONFIG_AR
     34    depends on AR
    3535    help
    3636      By default the ar format can only store the first 15 characters of the
     
    3939      filenames into a the data section of a new ar entry.
    4040
    41 config CONFIG_BUNZIP2
     41config BUNZIP2
    4242    bool "bunzip2"
    4343    default n
     
    5555      should probably say N here.
    5656
    57 config CONFIG_CPIO
     57config CPIO
    5858    bool "cpio"
    5959    default n
     
    6969      probably say N here.
    7070
    71 config CONFIG_DPKG
     71config DPKG
    7272    bool "dpkg"
    7373    default n
     
    7878      official dpkg if possible.
    7979
    80 config CONFIG_DPKG_DEB
     80config DPKG_DEB
    8181    bool "dpkg_deb"
    8282    default n
     
    8989      probably say N here.
    9090
    91 config CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY
     91config FEATURE_DPKG_DEB_EXTRACT_ONLY
    9292    bool "extract only (-x)"
    9393    default n
    94     depends on CONFIG_DPKG_DEB
     94    depends on DPKG_DEB
    9595    help
    9696      This reduces dpkg-deb to the equivalent of "ar -p <deb> data.tar.gz | tar -zx".
     
    9898      needed, they are linked to internally.
    9999
    100 config CONFIG_GUNZIP
     100config GUNZIP
    101101    bool "gunzip"
    102102    default n
     
    106106      an archive, without decompressing it.
    107107
    108 config CONFIG_FEATURE_GUNZIP_UNCOMPRESS
     108config FEATURE_GUNZIP_UNCOMPRESS
    109109    bool "Uncompress support"
    110110    default n
    111     depends on CONFIG_GUNZIP
     111    depends on GUNZIP
    112112    help
    113113      Enable if you want gunzip to have the ability to decompress
     
    115115      used anymore).
    116116
    117 config CONFIG_GZIP
     117config GZIP
    118118    bool "gzip"
    119119    default n
     
    122122      It's probably the most widely used UNIX compression program.
    123123
    124 config CONFIG_RPM2CPIO
     124config RPM2CPIO
    125125    bool "rpm2cpio"
    126126    default n
     
    128128      Converts an RPM file into a CPIO archive.
    129129
    130 config CONFIG_RPM
     130config RPM
    131131    bool "rpm"
    132132    default n
    133133    help
    134       Mini RPM applet - queries and extracts
    135 
    136 config CONFIG_TAR
     134      Mini RPM applet - queries and extracts RPM packages.
     135
     136config FEATURE_RPM_BZ2
     137    bool "Enable handling of rpms with bzip2-compressed data inside"
     138    default n
     139    depends on RPM
     140    help
     141      Enable handling of rpms with bzip2-compressed data inside.
     142
     143config TAR
    137144    bool "tar"
    138145    default n
     
    142149      UNIX archive program.
    143150
    144 config CONFIG_FEATURE_TAR_CREATE
     151config FEATURE_TAR_CREATE
    145152    bool "Enable archive creation"
    146153    default y
    147     depends on CONFIG_TAR
     154    depends on TAR
    148155    help
    149156      If you enable this option you'll be able to create
    150157      tar archives using the `-c' option.
    151158
    152 config CONFIG_FEATURE_TAR_BZIP2
     159config FEATURE_TAR_BZIP2
    153160    bool "Enable -j option to handle .tar.bz2 files"
    154161    default n
    155     depends on CONFIG_TAR
     162    depends on TAR
    156163    help
    157164      If you enable this option you'll be able to extract
    158165      archives compressed with bzip2.
    159166
    160 config CONFIG_FEATURE_TAR_LZMA
     167config FEATURE_TAR_LZMA
    161168    bool "Enable -a option to handle .tar.lzma files"
    162169    default n
    163     depends on CONFIG_TAR
     170    depends on TAR
    164171    help
    165172      If you enable this option you'll be able to extract
    166173      archives compressed with lzma.
    167174
    168 config CONFIG_FEATURE_TAR_FROM
     175config FEATURE_TAR_FROM
    169176    bool "Enable -X (exclude from) and -T (include from) options)"
    170177    default n
    171     depends on CONFIG_TAR
     178    depends on TAR
    172179    help
    173180      If you enable this option you'll be able to specify
    174181      a list of files to include or exclude from an archive.
    175182
    176 config CONFIG_FEATURE_TAR_GZIP
     183config FEATURE_TAR_GZIP
    177184    bool "Enable -z option"
    178185    default y
    179     depends on CONFIG_TAR
     186    depends on TAR
    180187    help
    181188      If you enable this option tar will be able to call gzip,
    182189      when creating or extracting tar gziped archives.
    183190
    184 config CONFIG_FEATURE_TAR_COMPRESS
     191config FEATURE_TAR_COMPRESS
    185192    bool "Enable -Z option"
    186193    default n
    187     depends on CONFIG_TAR
     194    depends on TAR
    188195    help
    189196      If you enable this option tar will be able to call uncompress,
    190197      when extracting .tar.Z archives.
    191198
    192 config CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY
     199config FEATURE_TAR_OLDGNU_COMPATIBILITY
    193200    bool "Enable support for old tar header format"
    194201    default N
    195     depends on CONFIG_TAR
     202    depends on TAR
    196203    help
    197204      This option is required to unpack archives created in
     
    199206      repacking your ancient archives with the new format.
    200207
    201 config CONFIG_FEATURE_TAR_GNU_EXTENSIONS
     208config FEATURE_TAR_OLDSUN_COMPATIBILITY
     209    bool "Enable untarring of tarballs with checksums produced by buggy Sun tar"
     210    default N
     211    depends on TAR
     212    help
     213      This option is required to unpack archives created by some old
     214      version of Sun's tar (it was calculating checksum using signed arithmetic).
     215      It is said to be fixed in newer Sun tar, but "old" tarballs still exist.
     216
     217config FEATURE_TAR_GNU_EXTENSIONS
    202218    bool "Enable support for some GNU tar extensions"
    203219    default y
    204     depends on CONFIG_TAR
     220    depends on TAR
    205221    help
    206222      With this option busybox supports GNU long filenames and
    207223      linknames.
    208224
    209 config CONFIG_FEATURE_TAR_LONG_OPTIONS
     225config FEATURE_TAR_LONG_OPTIONS
    210226    bool "Enable long options"
    211227    default n
    212     depends on CONFIG_TAR && CONFIG_GETOPT_LONG
     228    depends on TAR && GETOPT_LONG
    213229    help
    214230        Enable use of long options, increases size by about 400 Bytes
    215231
    216 config CONFIG_UNCOMPRESS
     232config UNCOMPRESS
    217233    bool "uncompress"
    218234    default n
     
    221237      Not much used anymore, replaced by gzip/gunzip.
    222238
    223 config CONFIG_UNLZMA
     239config UNLZMA
    224240    bool "unlzma"
    225241    default n
     
    236252      should probably say N here.
    237253
    238 config CONFIG_FEATURE_LZMA_FAST
     254config FEATURE_LZMA_FAST
    239255    bool "Optimze unlzma for speed"
    240256    default n
    241     depends on CONFIG_UNLZMA
     257    depends on UNLZMA
    242258    help
    243259      This option reduces decompression time by about 33% at the cost of
    244260      a 2K bigger binary.
    245261
    246 config CONFIG_UNZIP
     262config UNZIP
    247263    bool "unzip"
    248264    default n
     
    255271
    256272comment "Common options for cpio and tar"
    257     depends on CONFIG_CPIO || CONFIG_TAR
    258 
    259 config CONFIG_FEATURE_UNARCHIVE_TAPE
     273    depends on CPIO || TAR
     274
     275config FEATURE_UNARCHIVE_TAPE
    260276    bool "Enable tape drive support"
    261277    default n
    262     depends on CONFIG_CPIO || CONFIG_TAR
     278    depends on CPIO || TAR
    263279    help
    264280      I don't think this is needed anymore.
    265281
    266282comment "Common options for dpkg and dpkg_deb"
    267     depends on CONFIG_DPKG || CONFIG_DPKG_DEB
    268 
    269 config CONFIG_FEATURE_DEB_TAR_GZ
     283    depends on DPKG || DPKG_DEB
     284
     285config FEATURE_DEB_TAR_GZ
    270286    bool "gzip debian packages (normal)"
    271     default y if CONFIG_DPKG || CONFIG_DPKG_DEB
    272     depends on CONFIG_DPKG || CONFIG_DPKG_DEB
     287    default y if DPKG || DPKG_DEB
     288    depends on DPKG || DPKG_DEB
    273289    help
    274290      This is the default compression method inside the debian ar file.
     
    276292      If you want compatibility with standard .deb's you should say yes here.
    277293
    278 config CONFIG_FEATURE_DEB_TAR_BZ2
     294config FEATURE_DEB_TAR_BZ2
    279295    bool "bzip2 debian packages"
    280296    default n
    281     depends on CONFIG_DPKG || CONFIG_DPKG_DEB
     297    depends on DPKG || DPKG_DEB
    282298    help
    283299      This allows dpkg and dpkg-deb to extract deb's that are compressed internally
     
    287303      use an internal control.tar.bz2 or data.tar.bz2.
    288304
    289 config CONFIG_FEATURE_DEB_TAR_LZMA
     305config FEATURE_DEB_TAR_LZMA
    290306    bool "lzma debian packages"
    291307    default n
    292     depends on CONFIG_DPKG || CONFIG_DPKG_DEB
     308    depends on DPKG || DPKG_DEB
    293309    help
    294310      This allows dpkg and dpkg-deb to extract deb's that are compressed
    295           internally with lzma instead of gzip.
     311      internally with lzma instead of gzip.
    296312
    297313      You only want this if you are creating your own custom debian
    298           packages that use an internal control.tar.lzma or data.tar.lzma.
     314      packages that use an internal control.tar.lzma or data.tar.lzma.
    299315
    300316endmenu
  • branches/2.2.5/mindi-busybox/archival/ar.c

    r821 r1765  
    88 * Based in part on BusyBox tar, Debian dpkg-deb and GNU ar.
    99 *
    10  * This program is free software; you can redistribute it and/or modify
    11  * it under the terms of the GNU General Public License as published by
    12  * the Free Software Foundation; either version 2 of the License, or
    13  * (at your option) any later version.
    14  *
    15  * This program is distributed in the hope that it will be useful,
    16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    18  * General Public License for more details.
    19  *
    20  * You should have received a copy of the GNU General Public License
    21  * along with this program; if not, write to the Free Software
    22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    2311 *
    2412 * There is no single standard to adhere to so ar may not portable
     
    2715 */
    2816
    29 #include <fcntl.h>
    30 #include <stdio.h>
    31 #include <stdlib.h>
    32 #include <string.h>
    33 #include <time.h>
    34 #include <utime.h>
    35 #include <unistd.h>
    36 
     17#include "libbb.h"
    3718#include "unarchive.h"
    38 #include "busybox.h"
    3919
    4020static void header_verbose_list_ar(const file_header_t *file_header)
     
    4727    memmove(&mtime[17], &mtime[20], 4);
    4828    mtime[21] = '\0';
    49     printf("%s %d/%d%7d %s %s\n", &mode[1], file_header->uid, file_header->gid, (int) file_header->size, &mtime[4], file_header->name);
     29    printf("%s %d/%d%7d %s %s\n", &mode[1], file_header->uid, file_header->gid,
     30            (int) file_header->size, &mtime[4], file_header->name);
    5031}
    5132
     
    5839#define AR_OPT_INSERT       0x40
    5940
     41int ar_main(int argc, char **argv);
    6042int ar_main(int argc, char **argv)
    6143{
     44    static const char msg_unsupported_err[] ALIGN1 =
     45        "archive %s is not supported";
     46
    6247    archive_handle_t *archive_handle;
    63     unsigned long opt;
    64     static const char msg_unsupported_err[] =
    65             "Archive %s not supported.  Install binutils 'ar'.";
     48    unsigned opt;
    6649    char magic[8];
    6750
     
    6952
    7053    /* Prepend '-' to the first argument if required */
    71     bb_opt_complementally = "--:p:t:x:-1:?:p--tx:t--px:x--pt";
    72     opt = bb_getopt_ulflags(argc, argv, "ptxovcr");
     54    opt_complementary = "--:p:t:x:-1:p--tx:t--px:x--pt";
     55    opt = getopt32(argv, "ptxovcr");
    7356
    7457    if (opt & AR_CTX_PRINT) {
     
    9477    }
    9578
    96     archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY);
     79    archive_handle->src_fd = xopen(argv[optind++], O_RDONLY);
    9780
    9881    while (optind < argc) {
     
    10184    }
    10285
    103     archive_xread_all(archive_handle, magic, 7);
     86    xread(archive_handle->src_fd, magic, 7);
    10487    if (strncmp(magic, "!<arch>", 7) != 0) {
    105         bb_error_msg_and_die("Invalid ar magic");
     88        bb_error_msg_and_die("invalid ar magic");
    10689    }
    10790    archive_handle->offset += 7;
    10891
    109     while (get_header_ar(archive_handle) == EXIT_SUCCESS);
     92    while (get_header_ar(archive_handle) == EXIT_SUCCESS)
     93        continue;
    11094
    11195    return EXIT_SUCCESS;
  • branches/2.2.5/mindi-busybox/archival/cpio.c

    r821 r1765  
    55 * Copyright (C) 2001 by Glenn McGrath
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    208 *
    219 * Limitations:
     
    2412 *
    2513 */
    26 #include <fcntl.h>
    27 #include <stdlib.h>
    28 #include <string.h>
    29 #include <unistd.h>
     14#include "libbb.h"
    3015#include "unarchive.h"
    31 #include "busybox.h"
    3216
    33 #define CPIO_OPT_EXTRACT            0x01
    34 #define CPIO_OPT_TEST               0x02
    35 #define CPIO_OPT_UNCONDITIONAL      0x04
    36 #define CPIO_OPT_VERBOSE            0x08
    37 #define CPIO_OPT_FILE               0x10
    38 #define CPIO_OPT_CREATE_LEADING_DIR 0x20
    39 #define CPIO_OPT_PRESERVE_MTIME     0x40
     17#define CPIO_OPT_EXTRACT                0x01
     18#define CPIO_OPT_TEST                   0x02
     19#define CPIO_OPT_UNCONDITIONAL          0x04
     20#define CPIO_OPT_VERBOSE                0x08
     21#define CPIO_OPT_FILE                   0x10
     22#define CPIO_OPT_CREATE_LEADING_DIR     0x20
     23#define CPIO_OPT_PRESERVE_MTIME         0x40
    4024
     25int cpio_main(int argc, char **argv);
    4126int cpio_main(int argc, char **argv)
    4227{
    4328    archive_handle_t *archive_handle;
    4429    char *cpio_filename = NULL;
    45     unsigned long opt;
     30    unsigned opt;
    4631
    4732    /* Initialise */
    4833    archive_handle = init_handle();
    4934    archive_handle->src_fd = STDIN_FILENO;
    50     archive_handle->seek = seek_by_char;
     35    archive_handle->seek = seek_by_read;
    5136    archive_handle->flags = ARCHIVE_EXTRACT_NEWER | ARCHIVE_PRESERVE_DATE;
    5237
    53     opt = bb_getopt_ulflags(argc, argv, "ituvF:dm", &cpio_filename);
     38    opt = getopt32(argv, "ituvF:dm", &cpio_filename);
    5439
    5540    /* One of either extract or test options must be given */
     
    8065    }
    8166    if (cpio_filename) { /* CPIO_OPT_FILE */
    82         archive_handle->src_fd = bb_xopen(cpio_filename, O_RDONLY);
     67        archive_handle->src_fd = xopen(cpio_filename, O_RDONLY);
    8368        archive_handle->seek = seek_by_jump;
    8469    }
     
    9580    while (get_header_cpio(archive_handle) == EXIT_SUCCESS);
    9681
    97     return(EXIT_SUCCESS);
     82    return EXIT_SUCCESS;
    9883}
  • branches/2.2.5/mindi-busybox/archival/dpkg.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  Mini dpkg implementation for busybox.
    3  *  This is not meant as a replacement for dpkg
     3 *  mini dpkg implementation for busybox.
     4 *  this is not meant as a replacement for dpkg
    45 *
    5  *  Written By Glenn McGrath with the help of others
    6  *  Copyright (C) 2001 by Glenn McGrath
     6 *  written by glenn mcgrath with the help of others
     7 *  copyright (c) 2001 by glenn mcgrath
    78 *
    8  *  Started life as a busybox implementation of udpkg
     9 *  started life as a busybox implementation of udpkg
    910 *
    10  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     11 * licensed under gplv2 or later, see file license in this tarball for details.
    1112 */
    1213
    1314/*
    14  * Known difference between busybox dpkg and the official dpkg that i don't
     15 * known difference between busybox dpkg and the official dpkg that i don't
    1516 * consider important, its worth keeping a note of differences anyway, just to
    1617 * make it easier to maintain.
    17  *  - The first value for the Confflile: field isnt placed on a new line.
    18  *  - When installing a package the Status: field is placed at the end of the
    19  *      section, rather than just after the Package: field.
     18 *  - the first value for the confflile: field isnt placed on a new line.
     19 *  - when installing a package the status: field is placed at the end of the
     20 *      section, rather than just after the package: field.
    2021 *
    21  * Bugs that need to be fixed
     22 * bugs that need to be fixed
    2223 *  - (unknown, please let me know when you find any)
    2324 *
    2425 */
    2526
    26 #include <fcntl.h>
    27 #include <getopt.h>
    28 #include <stdlib.h>
    29 #include <string.h>
    30 #include <unistd.h>
     27#include "libbb.h"
    3128#include "unarchive.h"
    32 #include "busybox.h"
    33 
    34 /* NOTE: If you vary HASH_PRIME sizes be aware,
    35  * 1) Tweaking these will have a big effect on how much memory this program uses.
    36  * 2) For computational efficiency these hash tables should be at least 20%
     29
     30/* note: if you vary hash_prime sizes be aware,
     31 * 1) tweaking these will have a big effect on how much memory this program uses.
     32 * 2) for computational efficiency these hash tables should be at least 20%
    3733 *    larger than the maximum number of elements stored in it.
    38  * 3) All _HASH_PRIME's must be a prime number or chaos is assured, if your looking
     34 * 3) all _hash_prime's must be a prime number or chaos is assured, if your looking
    3935 *    for a prime, try http://www.utm.edu/research/primes/lists/small/10000.txt
    40  * 4) If you go bigger than 15 bits you may get into trouble (untested) as its
    41  *    sometimes cast to an unsigned int, if you go to 16 bit you will overlap
     36 * 4) if you go bigger than 15 bits you may get into trouble (untested) as its
     37 *    sometimes cast to an unsigned, if you go to 16 bit you will overlap
    4238 *    int's and chaos is assured, 16381 is the max prime for 14 bit field
    4339 */
     
    4743 * as there a lot of duplicate version numbers */
    4844#define NAME_HASH_PRIME 16381
    49 static char *name_hashtable[NAME_HASH_PRIME + 1];
    5045
    5146/* PACKAGE_HASH_PRIME, Maximum number of unique packages,
     
    5954#define PACKAGE_HASH_PRIME 10007
    6055typedef struct edge_s {
    61     unsigned int operator:3;
    62     unsigned int type:4;
    63     unsigned int name:14;
    64     unsigned int version:14;
     56    unsigned operator:4; /* was:3 */
     57    unsigned type:4;
     58    unsigned name:16; /* was:14 */
     59    unsigned version:16; /* was:14 */
    6560} edge_t;
    6661
    6762typedef struct common_node_s {
    68     unsigned int name:14;
    69     unsigned int version:14;
    70     unsigned int num_of_edges:14;
     63    unsigned name:16; /* was:14 */
     64    unsigned version:16; /* was:14 */
     65    unsigned num_of_edges:16; /* was:14 */
    7166    edge_t **edge;
    7267} common_node_t;
    73 static common_node_t *package_hashtable[PACKAGE_HASH_PRIME + 1];
    7468
    7569/* Currently it doesnt store packages that have state-status of not-installed
     
    7872#define STATUS_HASH_PRIME 8191
    7973typedef struct status_node_s {
    80     unsigned int package:14;    /* has to fit PACKAGE_HASH_PRIME */
    81     unsigned int status:14;     /* has to fit STATUS_HASH_PRIME */
     74    unsigned package:16; /* was:14 */       /* has to fit PACKAGE_HASH_PRIME */
     75    unsigned status:16; /* was:14 */        /* has to fit STATUS_HASH_PRIME */
    8276} status_node_t;
    83 static status_node_t *status_hashtable[STATUS_HASH_PRIME + 1];
     77
     78/* Were statically declared here, but such a big bss is nommu-unfriendly */
     79static char **name_hashtable;             /* [NAME_HASH_PRIME + 1] */
     80static common_node_t **package_hashtable; /* [PACKAGE_HASH_PRIME + 1] */
     81static status_node_t **status_hashtable;  /* [STATUS_HASH_PRIME + 1] */
    8482
    8583/* Even numbers are for 'extras', like ored dependencies or null */
     
    107105};
    108106
    109 enum dpkg_opt_e {
    110     dpkg_opt_purge = 1,
    111     dpkg_opt_remove = 2,
    112     dpkg_opt_unpack = 4,
    113     dpkg_opt_configure = 8,
    114     dpkg_opt_install = 16,
    115     dpkg_opt_package_name = 32,
    116     dpkg_opt_filename = 64,
    117     dpkg_opt_list_installed = 128,
    118     dpkg_opt_force_ignore_depends = 256
    119 };
    120 
    121107typedef struct deb_file_s {
    122108    char *control_file;
    123109    char *filename;
    124     unsigned int package:14;
     110    unsigned package:16; /* was:14 */
    125111} deb_file_t;
    126112
    127113
    128 static void make_hash(const char *key, unsigned int *start, unsigned int *decrement, const int hash_prime)
    129 {
    130     unsigned long int hash_num = key[0];
     114static void make_hash(const char *key, unsigned *start, unsigned *decrement, const int hash_prime)
     115{
     116    unsigned long hash_num = key[0];
    131117    int len = strlen(key);
    132118    int i;
     
    134120    /* Maybe i should have uses a "proper" hashing algorithm here instead
    135121     * of making one up myself, seems to be working ok though. */
    136     for(i = 1; i < len; i++) {
     122    for (i = 1; i < len; i++) {
    137123        /* shifts the ascii based value and adds it to previous value
    138124         * shift amount is mod 24 because long int is 32 bit and data
     
    141127        hash_num += ((key[i] + key[i-1]) << ((key[i] * i) % 24));
    142128    }
    143     *start = (unsigned int) hash_num % hash_prime;
    144     *decrement = (unsigned int) 1 + (hash_num % (hash_prime - 1));
     129    *start = (unsigned) hash_num % hash_prime;
     130    *decrement = (unsigned) 1 + (hash_num % (hash_prime - 1));
    145131}
    146132
     
    148134static int search_name_hashtable(const char *key)
    149135{
    150     unsigned int probe_address = 0;
    151     unsigned int probe_decrement = 0;
    152 //  char *temp;
     136    unsigned probe_address = 0;
     137    unsigned probe_decrement = 0;
    153138
    154139    make_hash(key, &probe_address, &probe_decrement, NAME_HASH_PRIME);
    155     while(name_hashtable[probe_address] != NULL) {
     140    while (name_hashtable[probe_address] != NULL) {
    156141        if (strcmp(name_hashtable[probe_address], key) == 0) {
    157             return(probe_address);
    158         } else {
    159             probe_address -= probe_decrement;
    160             if ((int)probe_address < 0) {
    161                 probe_address += NAME_HASH_PRIME;
    162             }
    163         }
    164     }
    165     name_hashtable[probe_address] = bb_xstrdup(key);
    166     return(probe_address);
     142            return probe_address;
     143        }
     144        probe_address -= probe_decrement;
     145        if ((int)probe_address < 0) {
     146            probe_address += NAME_HASH_PRIME;
     147        }
     148    }
     149    name_hashtable[probe_address] = xstrdup(key);
     150    return probe_address;
    167151}
    168152
     
    170154 * TODO make it consistent with search_name_hashtable
    171155 */
    172 static unsigned int search_status_hashtable(const char *key)
    173 {
    174     unsigned int probe_address = 0;
    175     unsigned int probe_decrement = 0;
     156static unsigned search_status_hashtable(const char *key)
     157{
     158    unsigned probe_address = 0;
     159    unsigned probe_decrement = 0;
    176160
    177161    make_hash(key, &probe_address, &probe_decrement, STATUS_HASH_PRIME);
    178     while(status_hashtable[probe_address] != NULL) {
     162    while (status_hashtable[probe_address] != NULL) {
    179163        if (strcmp(key, name_hashtable[package_hashtable[status_hashtable[probe_address]->package]->name]) == 0) {
    180164            break;
    181         } else {
    182             probe_address -= probe_decrement;
    183             if ((int)probe_address < 0) {
    184                 probe_address += STATUS_HASH_PRIME;
    185             }
    186         }
    187     }
    188     return(probe_address);
     165        }
     166        probe_address -= probe_decrement;
     167        if ((int)probe_address < 0) {
     168            probe_address += STATUS_HASH_PRIME;
     169        }
     170    }
     171    return probe_address;
    189172}
    190173
     
    201184    int ver_num1;
    202185    int ver_num2;
    203     int ret;
    204186
    205187    if (version1 == NULL) {
    206         version1 = bb_xstrdup("");
     188        version1 = xstrdup("");
    207189    }
    208190    if (version2 == NULL) {
    209         version2 = bb_xstrdup("");
     191        version2 = xstrdup("");
    210192    }
    211193    upstream_len1 = strlen(version1);
     
    215197        /* Compare non-digit section */
    216198        tmp_int = strcspn(&version1[len1], "0123456789");
    217         name1_char = bb_xstrndup(&version1[len1], tmp_int);
     199        name1_char = xstrndup(&version1[len1], tmp_int);
    218200        len1 += tmp_int;
    219201        tmp_int = strcspn(&version2[len2], "0123456789");
    220         name2_char = bb_xstrndup(&version2[len2], tmp_int);
     202        name2_char = xstrndup(&version2[len2], tmp_int);
    221203        len2 += tmp_int;
    222204        tmp_int = strcmp(name1_char, name2_char);
     
    224206        free(name2_char);
    225207        if (tmp_int != 0) {
    226             ret = tmp_int;
    227             goto cleanup_version_compare_part;
     208            return tmp_int;
    228209        }
    229210
    230211        /* Compare digits */
    231212        tmp_int = strspn(&version1[len1], "0123456789");
    232         name1_char = bb_xstrndup(&version1[len1], tmp_int);
     213        name1_char = xstrndup(&version1[len1], tmp_int);
    233214        len1 += tmp_int;
    234215        tmp_int = strspn(&version2[len2], "0123456789");
    235         name2_char = bb_xstrndup(&version2[len2], tmp_int);
     216        name2_char = xstrndup(&version2[len2], tmp_int);
    236217        len2 += tmp_int;
    237218        ver_num1 = atoi(name1_char);
     
    240221        free(name2_char);
    241222        if (ver_num1 < ver_num2) {
    242             ret = -1;
    243             goto cleanup_version_compare_part;
    244         }
    245         else if (ver_num1 > ver_num2) {
    246             ret = 1;
    247             goto cleanup_version_compare_part;
    248         }
    249     }
    250     ret = 0;
    251 cleanup_version_compare_part:
    252     return(ret);
     223            return -1;
     224        }
     225        if (ver_num1 > ver_num2) {
     226            return 1;
     227        }
     228    }
     229    return 0;
    253230}
    254231
     
    257234 * if ver1 > ver2 return 1,
    258235 */
    259 static int version_compare(const unsigned int ver1, const unsigned int ver2)
     236static int version_compare(const unsigned ver1, const unsigned ver2)
    260237{
    261238    char *ch_ver1 = name_hashtable[ver1];
     
    285262    }
    286263    if (epoch1 < epoch2) {
    287         return(-1);
     264        return -1;
    288265    }
    289266    else if (epoch1 > epoch2) {
    290         return(1);
     267        return 1;
    291268    }
    292269
    293270    /* Compare upstream version */
    294     upstream_ver1 = bb_xstrdup(ver1_ptr);
    295     upstream_ver2 = bb_xstrdup(ver2_ptr);
     271    upstream_ver1 = xstrdup(ver1_ptr);
     272    upstream_ver2 = xstrdup(ver2_ptr);
    296273
    297274    /* Chop off debian version, and store for later use */
     
    307284    }
    308285    result = version_compare_part(upstream_ver1, upstream_ver2);
     286    if (!result)
     287        /* Compare debian versions */
     288        result = version_compare_part(deb_ver1, deb_ver2);
    309289
    310290    free(upstream_ver1);
    311291    free(upstream_ver2);
    312 
    313     if (result != 0) {
    314         return(result);
    315     }
    316 
    317     /* Compare debian versions */
    318     return(version_compare_part(deb_ver1, deb_ver2));
    319 }
    320 
    321 static int test_version(const unsigned int version1, const unsigned int version2, const unsigned int operator)
     292    return result;
     293}
     294
     295static int test_version(const unsigned version1, const unsigned version2, const unsigned operator)
    322296{
    323297    const int version_result = version_compare(version1, version2);
    324     switch(operator) {
    325         case (VER_ANY):
    326             return(TRUE);
    327         case (VER_EQUAL):
    328             if (version_result == 0) {
    329                 return(TRUE);
    330             }
    331             break;
    332         case (VER_LESS):
    333             if (version_result < 0) {
    334                 return(TRUE);
    335             }
    336             break;
    337         case (VER_LESS_EQUAL):
    338             if (version_result <= 0) {
    339                 return(TRUE);
    340             }
    341             break;
    342         case (VER_MORE):
    343             if (version_result > 0) {
    344                 return(TRUE);
    345             }
    346             break;
    347         case (VER_MORE_EQUAL):
    348             if (version_result >= 0) {
    349                 return(TRUE);
    350             }
    351             break;
    352     }
    353     return(FALSE);
    354 }
    355 
    356 
    357 static int search_package_hashtable(const unsigned int name, const unsigned int version, const unsigned int operator)
    358 {
    359     unsigned int probe_address = 0;
    360     unsigned int probe_decrement = 0;
     298    switch (operator) {
     299    case VER_ANY:
     300        return TRUE;
     301    case VER_EQUAL:
     302        return (version_result == 0);
     303    case VER_LESS:
     304        return (version_result < 0);
     305    case VER_LESS_EQUAL:
     306        return (version_result <= 0);
     307    case VER_MORE:
     308        return (version_result > 0);
     309    case VER_MORE_EQUAL:
     310        return (version_result >= 0);
     311    }
     312    return FALSE;
     313}
     314
     315
     316static int search_package_hashtable(const unsigned name, const unsigned version, const unsigned operator)
     317{
     318    unsigned probe_address = 0;
     319    unsigned probe_decrement = 0;
    361320
    362321    make_hash(name_hashtable[name], &probe_address, &probe_decrement, PACKAGE_HASH_PRIME);
    363     while(package_hashtable[probe_address] != NULL) {
     322    while (package_hashtable[probe_address] != NULL) {
    364323        if (package_hashtable[probe_address]->name == name) {
    365324            if (operator == VER_ANY) {
    366                 return(probe_address);
     325                return probe_address;
    367326            }
    368327            if (test_version(package_hashtable[probe_address]->version, version, operator)) {
    369                 return(probe_address);
     328                return probe_address;
    370329            }
    371330        }
     
    375334        }
    376335    }
    377     return(probe_address);
     336    return probe_address;
    378337}
    379338
     
    394353 * it simple for now until it proves to be a problem.
    395354 */
    396 static int search_for_provides(int needle, int start_at) {
     355static int search_for_provides(int needle, int start_at)
     356{
    397357    int i, j;
    398358    common_node_t *p;
    399359    for (i = start_at + 1; i < PACKAGE_HASH_PRIME; i++) {
    400360        p = package_hashtable[i];
    401         if ( p == NULL ) continue;
    402         for(j = 0; j < p->num_of_edges; j++)
    403             if ( p->edge[j]->type == EDGE_PROVIDES && p->edge[j]->name == needle )
     361        if (p == NULL)
     362            continue;
     363        for (j = 0; j < p->num_of_edges; j++)
     364            if (p->edge[j]->type == EDGE_PROVIDES && p->edge[j]->name == needle)
    404365                return i;
    405366    }
     
    427388 * this alternative.
    428389 */
    429 static void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned int edge_type)
    430 {
    431     char *line = bb_xstrdup(whole_line);
     390static void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned edge_type)
     391{
     392    char *line = xstrdup(whole_line);
    432393    char *line2;
    433394    char *line_ptr1 = NULL;
     
    444405        /* skip leading spaces */
    445406        field += strspn(field, " ");
    446         line2 = bb_xstrdup(field);
     407        line2 = xstrdup(field);
    447408        field2 = strtok_r(line2, "|", &line_ptr2);
    448         if ( (edge_type == EDGE_DEPENDS || edge_type == EDGE_PRE_DEPENDS) &&
    449              (strcmp(field, field2) != 0)) {
    450             or_edge = (edge_t *)xmalloc(sizeof(edge_t));
     409        or_edge = NULL;
     410        if ((edge_type == EDGE_DEPENDS || edge_type == EDGE_PRE_DEPENDS)
     411         && (strcmp(field, field2) != 0)
     412        ) {
     413            or_edge = xmalloc(sizeof(edge_t));
    451414            or_edge->type = edge_type + 1;
    452         } else {
    453             or_edge = NULL;
    454         }
    455 
    456         if ( or_edge ) {
    457415            or_edge->name = search_name_hashtable(field);
    458             or_edge->version = 0; // tracks the number of altenatives
    459 
     416            or_edge->version = 0; // tracks the number of alternatives
    460417            add_edge_to_node(parent_node, or_edge);
    461418        }
    462419
    463420        do {
    464             edge = (edge_t *) xmalloc(sizeof(edge_t));
     421            edge = xmalloc(sizeof(edge_t));
    465422            edge->type = edge_type;
    466423
     
    476433            } else {
    477434                /* Skip leading ' ' or '(' */
    478                 version += strspn(field2, " ");
    479                 version += strspn(version, "(");
     435                version += strspn(version, " (");
    480436                /* Calculate length of any operator characters */
    481437                offset_ch = strspn(version, "<=>");
     
    497453                        edge->operator = VER_MORE_EQUAL;
    498454                    } else {
    499                         bb_error_msg_and_die("Illegal operator\n");
     455                        bb_error_msg_and_die("illegal operator");
    500456                    }
    501457                }
     
    514470            edge->name = search_name_hashtable(field2);
    515471
    516             if ( or_edge )
     472            if (or_edge)
    517473                or_edge->version++;
    518474
    519475            add_edge_to_node(parent_node, edge);
    520         } while ((field2 = strtok_r(NULL, "|", &line_ptr2)) != NULL);
     476            field2 = strtok_r(NULL, "|", &line_ptr2);
     477        } while (field2 != NULL);
     478
    521479        free(line2);
    522     } while ((field = strtok_r(NULL, ",", &line_ptr1)) != NULL);
     480        field = strtok_r(NULL, ",", &line_ptr1);
     481    } while (field != NULL);
     482
    523483    free(line);
    524 
    525     return;
    526484}
    527485
    528486static void free_package(common_node_t *node)
    529487{
    530     unsigned short i;
     488    unsigned i;
    531489    if (node) {
    532490        for (i = 0; i < node->num_of_edges; i++) {
     
    538496}
    539497
    540 static unsigned int fill_package_struct(char *control_buffer)
    541 {
    542     static const char *const field_names[] = { "Package", "Version",
    543         "Pre-Depends", "Depends","Replaces", "Provides",
    544         "Conflicts", "Suggests", "Recommends", "Enhances", 0
    545     };
    546 
    547     common_node_t *new_node = (common_node_t *) xzalloc(sizeof(common_node_t));
     498/*
     499 * Gets the next package field from package_buffer, seperated into the field name
     500 * and field value, it returns the int offset to the first character of the next field
     501 */
     502static int read_package_field(const char *package_buffer, char **field_name, char **field_value)
     503{
     504    int offset_name_start = 0;
     505    int offset_name_end = 0;
     506    int offset_value_start = 0;
     507    int offset_value_end = 0;
     508    int offset = 0;
     509    int next_offset;
     510    int name_length;
     511    int value_length;
     512    int exit_flag = FALSE;
     513
     514    if (package_buffer == NULL) {
     515        *field_name = NULL;
     516        *field_value = NULL;
     517        return -1;
     518    }
     519    while (1) {
     520        next_offset = offset + 1;
     521        switch (package_buffer[offset]) {
     522            case '\0':
     523                exit_flag = TRUE;
     524                break;
     525            case ':':
     526                if (offset_name_end == 0) {
     527                    offset_name_end = offset;
     528                    offset_value_start = next_offset;
     529                }
     530                /* TODO: Name might still have trailing spaces if ':' isnt
     531                 * immediately after name */
     532                break;
     533            case '\n':
     534                /* TODO: The char next_offset may be out of bounds */
     535                if (package_buffer[next_offset] != ' ') {
     536                    exit_flag = TRUE;
     537                    break;
     538                }
     539            case '\t':
     540            case ' ':
     541                /* increment the value start point if its a just filler */
     542                if (offset_name_start == offset) {
     543                    offset_name_start++;
     544                }
     545                if (offset_value_start == offset) {
     546                    offset_value_start++;
     547                }
     548                break;
     549        }
     550        if (exit_flag) {
     551            /* Check that the names are valid */
     552            offset_value_end = offset;
     553            name_length = offset_name_end - offset_name_start;
     554            value_length = offset_value_end - offset_value_start;
     555            if (name_length == 0) {
     556                break;
     557            }
     558            if ((name_length > 0) && (value_length > 0)) {
     559                break;
     560            }
     561
     562            /* If not valid, start fresh with next field */
     563            exit_flag = FALSE;
     564            offset_name_start = offset + 1;
     565            offset_name_end = 0;
     566            offset_value_start = offset + 1;
     567            offset_value_end = offset + 1;
     568            offset++;
     569        }
     570        offset++;
     571    }
     572    *field_name = NULL;
     573    if (name_length) {
     574        *field_name = xstrndup(&package_buffer[offset_name_start], name_length);
     575    }
     576    *field_value = NULL;
     577    if (value_length > 0) {
     578        *field_value = xstrndup(&package_buffer[offset_value_start], value_length);
     579    }
     580    return next_offset;
     581}
     582
     583static unsigned fill_package_struct(char *control_buffer)
     584{
     585    static const char field_names[] ALIGN1 =
     586        "Package\0""Version\0"
     587        "Pre-Depends\0""Depends\0""Replaces\0""Provides\0"
     588        "Conflicts\0""Suggests\0""Recommends\0""Enhances\0";
     589
     590    common_node_t *new_node = xzalloc(sizeof(common_node_t));
    548591    char *field_name;
    549592    char *field_value;
     
    554597    new_node->version = search_name_hashtable("unknown");
    555598    while (field_start < buffer_length) {
    556         unsigned short field_num;
     599        unsigned field_num;
    557600
    558601        field_start += read_package_field(&control_buffer[field_start],
     
    560603
    561604        if (field_name == NULL) {
    562             goto fill_package_struct_cleanup; /* Oh no, the dreaded goto statement ! */
    563         }
    564 
    565         field_num = compare_string_array(field_names, field_name);
    566         switch(field_num) {
    567             case 0: /* Package */
    568                 new_node->name = search_name_hashtable(field_value);
    569                 break;
    570             case 1: /* Version */
    571                 new_node->version = search_name_hashtable(field_value);
    572                 break;
    573             case 2: /* Pre-Depends */
    574                 add_split_dependencies(new_node, field_value, EDGE_PRE_DEPENDS);
    575                 break;
    576             case 3: /* Depends */
    577                 add_split_dependencies(new_node, field_value, EDGE_DEPENDS);
    578                 break;
    579             case 4: /* Replaces */
    580                 add_split_dependencies(new_node, field_value, EDGE_REPLACES);
    581                 break;
    582             case 5: /* Provides */
    583                 add_split_dependencies(new_node, field_value, EDGE_PROVIDES);
    584                 break;
    585             case 6: /* Conflicts */
    586                 add_split_dependencies(new_node, field_value, EDGE_CONFLICTS);
    587                 break;
    588             case 7: /* Suggests */
    589                 add_split_dependencies(new_node, field_value, EDGE_SUGGESTS);
    590                 break;
    591             case 8: /* Recommends */
    592                 add_split_dependencies(new_node, field_value, EDGE_RECOMMENDS);
    593                 break;
    594             case 9: /* Enhances */
    595                 add_split_dependencies(new_node, field_value, EDGE_ENHANCES);
    596                 break;
    597         }
    598 fill_package_struct_cleanup:
     605            goto fill_package_struct_cleanup; /* Oh no, the dreaded goto statement! */
     606        }
     607
     608        field_num = index_in_strings(field_names, field_name);
     609        switch (field_num) {
     610        case 0: /* Package */
     611            new_node->name = search_name_hashtable(field_value);
     612            break;
     613        case 1: /* Version */
     614            new_node->version = search_name_hashtable(field_value);
     615            break;
     616        case 2: /* Pre-Depends */
     617            add_split_dependencies(new_node, field_value, EDGE_PRE_DEPENDS);
     618            break;
     619        case 3: /* Depends */
     620            add_split_dependencies(new_node, field_value, EDGE_DEPENDS);
     621            break;
     622        case 4: /* Replaces */
     623            add_split_dependencies(new_node, field_value, EDGE_REPLACES);
     624            break;
     625        case 5: /* Provides */
     626            add_split_dependencies(new_node, field_value, EDGE_PROVIDES);
     627            break;
     628        case 6: /* Conflicts */
     629            add_split_dependencies(new_node, field_value, EDGE_CONFLICTS);
     630            break;
     631        case 7: /* Suggests */
     632            add_split_dependencies(new_node, field_value, EDGE_SUGGESTS);
     633            break;
     634        case 8: /* Recommends */
     635            add_split_dependencies(new_node, field_value, EDGE_RECOMMENDS);
     636            break;
     637        case 9: /* Enhances */
     638            add_split_dependencies(new_node, field_value, EDGE_ENHANCES);
     639            break;
     640        }
     641 fill_package_struct_cleanup:
    599642        free(field_name);
    600643        free(field_value);
     
    603646    if (new_node->version == search_name_hashtable("unknown")) {
    604647        free_package(new_node);
    605         return(-1);
     648        return -1;
    606649    }
    607650    num = search_package_hashtable(new_node->name, new_node->version, VER_EQUAL);
    608     if (package_hashtable[num] == NULL) {
    609         package_hashtable[num] = new_node;
    610     } else {
    611         free_package(new_node);
    612     }
    613     return(num);
     651    free_package(package_hashtable[num]);
     652    package_hashtable[num] = new_node;
     653    return num;
    614654}
    615655
    616656/* if num = 1, it returns the want status, 2 returns flag, 3 returns status */
    617 static unsigned int get_status(const unsigned int status_node, const int num)
     657static unsigned get_status(const unsigned status_node, const int num)
    618658{
    619659    char *status_string = name_hashtable[status_hashtable[status_node]->status];
    620660    char *state_sub_string;
    621     unsigned int state_sub_num;
     661    unsigned state_sub_num;
    622662    int len;
    623663    int i;
     
    630670        status_string += strspn(status_string, " ");
    631671    }
    632     len = strcspn(status_string, " \n\0");
    633     state_sub_string = bb_xstrndup(status_string, len);
     672    len = strcspn(status_string, " \n");
     673    state_sub_string = xstrndup(status_string, len);
    634674    state_sub_num = search_name_hashtable(state_sub_string);
    635675    free(state_sub_string);
    636     return(state_sub_num);
    637 }
    638 
    639 static void set_status(const unsigned int status_node_num, const char *new_value, const int position)
    640 {
    641     const unsigned int new_value_len = strlen(new_value);
    642     const unsigned int new_value_num = search_name_hashtable(new_value);
    643     unsigned int want = get_status(status_node_num, 1);
    644     unsigned int flag = get_status(status_node_num, 2);
    645     unsigned int status = get_status(status_node_num, 3);
     676    return state_sub_num;
     677}
     678
     679static void set_status(const unsigned status_node_num, const char *new_value, const int position)
     680{
     681    const unsigned new_value_len = strlen(new_value);
     682    const unsigned new_value_num = search_name_hashtable(new_value);
     683    unsigned want = get_status(status_node_num, 1);
     684    unsigned flag = get_status(status_node_num, 2);
     685    unsigned status = get_status(status_node_num, 3);
    646686    int want_len = strlen(name_hashtable[want]);
    647687    int flag_len = strlen(name_hashtable[flag]);
     
    650690
    651691    switch (position) {
    652         case (1):
     692        case 1:
    653693            want = new_value_num;
    654694            want_len = new_value_len;
    655695            break;
    656         case (2):
     696        case 2:
    657697            flag = new_value_num;
    658698            flag_len = new_value_len;
    659699            break;
    660         case (3):
     700        case 3:
    661701            status = new_value_num;
    662702            status_len = new_value_len;
     
    666706    }
    667707
    668     new_status = bb_xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]);
     708    new_status = xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]);
    669709    status_hashtable[status_node_num]->status = search_name_hashtable(new_status);
    670710    free(new_status);
    671     return;
    672 }
    673 
    674 static const char *describe_status(int status_num) {
    675     int status_want, status_state ;
    676     if ( status_hashtable[status_num] == NULL || status_hashtable[status_num]->status == 0 )
    677         return "is not installed or flagged to be installed\n";
     711}
     712
     713static const char *describe_status(int status_num)
     714{
     715    int status_want, status_state;
     716    if (status_hashtable[status_num] == NULL || status_hashtable[status_num]->status == 0)
     717        return "is not installed or flagged to be installed";
    678718
    679719    status_want = get_status(status_num, 1);
    680720    status_state = get_status(status_num, 3);
    681721
    682     if ( status_state == search_name_hashtable("installed") ) {
    683         if ( status_want == search_name_hashtable("install") )
     722    if (status_state == search_name_hashtable("installed")) {
     723        if (status_want == search_name_hashtable("install"))
    684724            return "is installed";
    685         if ( status_want == search_name_hashtable("deinstall") )
     725        if (status_want == search_name_hashtable("deinstall"))
    686726            return "is marked to be removed";
    687         if ( status_want == search_name_hashtable("purge") )
     727        if (status_want == search_name_hashtable("purge"))
    688728            return "is marked to be purged";
    689729    }
    690     if ( status_want ==  search_name_hashtable("unknown") )
     730    if (status_want == search_name_hashtable("unknown"))
    691731        return "is in an indeterminate state";
    692     if ( status_want == search_name_hashtable("install") )
     732    if (status_want == search_name_hashtable("install"))
    693733        return "is marked to be installed";
    694734
     
    703743    char *status_line;
    704744    status_node_t *status_node = NULL;
    705     unsigned int status_num;
    706 
    707     status_file = bb_xfopen(filename, "r");
    708     while ((control_buffer = fgets_str(status_file, "\n\n")) != NULL) {
    709         const unsigned int package_num = fill_package_struct(control_buffer);
     745    unsigned status_num;
     746
     747    status_file = xfopen(filename, "r");
     748    while ((control_buffer = xmalloc_fgets_str(status_file, "\n\n")) != NULL) {
     749        const unsigned package_num = fill_package_struct(control_buffer);
    710750        if (package_num != -1) {
    711751            status_node = xmalloc(sizeof(status_node_t));
     
    715755                status_line += 7;
    716756                status_line += strspn(status_line, " \n\t");
    717                 status_line = bb_xstrndup(status_line, strcspn(status_line, "\n\0"));
     757                status_line = xstrndup(status_line, strcspn(status_line, "\n"));
    718758                status_node->status = search_name_hashtable(status_line);
    719759                free(status_line);
     
    726766    }
    727767    fclose(status_file);
    728     return;
    729768}
    730769
     
    743782        }
    744783    }
    745     return;
    746784}
    747785
     
    749787static void write_status_file(deb_file_t **deb_file)
    750788{
    751     FILE *old_status_file = bb_xfopen("/var/lib/dpkg/status", "r");
    752     FILE *new_status_file = bb_xfopen("/var/lib/dpkg/status.udeb", "w");
     789    FILE *old_status_file = xfopen("/var/lib/dpkg/status", "r");
     790    FILE *new_status_file = xfopen("/var/lib/dpkg/status.udeb", "w");
    753791    char *package_name;
    754792    char *status_from_file;
     
    761799
    762800    /* Update previously known packages */
    763     while ((control_buffer = fgets_str(old_status_file, "\n\n")) != NULL) {
    764         if ((tmp_string = strstr(control_buffer, "Package:")) == NULL) {
     801    while ((control_buffer = xmalloc_fgets_str(old_status_file, "\n\n")) != NULL) {
     802        tmp_string = strstr(control_buffer, "Package:");
     803        if (tmp_string == NULL) {
    765804            continue;
    766805        }
     
    768807        tmp_string += 8;
    769808        tmp_string += strspn(tmp_string, " \n\t");
    770         package_name = bb_xstrndup(tmp_string, strcspn(tmp_string, "\n\0"));
     809        package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n"));
    771810        write_flag = FALSE;
    772811        tmp_string = strstr(control_buffer, "Status:");
     
    775814            tmp_string += 7;
    776815            tmp_string += strspn(tmp_string, " \n\t");
    777             status_from_file = bb_xstrndup(tmp_string, strcspn(tmp_string, "\n"));
     816            status_from_file = xstrndup(tmp_string, strcspn(tmp_string, "\n"));
    778817        } else {
    779818            status_from_file = NULL;
     
    787826                /* New status isnt exactly the same as old status */
    788827                const int state_status = get_status(status_num, 3);
    789                 if ((strcmp("installed", name_hashtable[state_status]) == 0) ||
    790                     (strcmp("unpacked", name_hashtable[state_status]) == 0)) {
     828                if ((strcmp("installed", name_hashtable[state_status]) == 0)
     829                 || (strcmp("unpacked", name_hashtable[state_status]) == 0)
     830                ) {
    791831                    /* We need to add the control file from the package */
    792832                    i = 0;
    793                     while(deb_file[i] != NULL) {
     833                    while (deb_file[i] != NULL) {
    794834                        if (strcmp(package_name, name_hashtable[package_hashtable[deb_file[i]->package]->name]) == 0) {
    795835                            /* Write a status file entry with a modified status */
     
    797837                            write_buffer_no_status(new_status_file, deb_file[i]->control_file);
    798838                            set_status(status_num, "ok", 2);
    799                             fprintf(new_status_file, "Status: %s\n\n", name_hashtable[status_hashtable[status_num]->status]);
     839                            fprintf(new_status_file, "Status: %s\n\n",
     840                                    name_hashtable[status_hashtable[status_num]->status]);
    800841                            write_flag = TRUE;
    801842                            break;
     
    805846                    /* This is temperary, debugging only */
    806847                    if (deb_file[i] == NULL) {
    807                         bb_error_msg_and_die("ALERT: Couldnt find a control file, your status file may be broken, status may be incorrect for %s", package_name);
     848                        bb_error_msg_and_die("ALERT: cannot find a control file, "
     849                            "your status file may be broken, status may be "
     850                            "incorrect for %s", package_name);
    808851                    }
    809852                }
     
    850893        }
    851894        /* If the package from the status file wasnt handle above, do it now*/
    852         if (! write_flag) {
     895        if (!write_flag) {
    853896            fprintf(new_status_file, "%s\n\n", control_buffer);
    854897        }
     
    860903
    861904    /* Write any new packages */
    862     for(i = 0; deb_file[i] != NULL; i++) {
     905    for (i = 0; deb_file[i] != NULL; i++) {
    863906        status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[i]->package]->name]);
    864907        if (strcmp("reinstreq", name_hashtable[get_status(status_num, 2)]) == 0) {
     
    878921        /* Its ok if renaming the status file fails because status
    879922         * file doesnt exist, maybe we are starting from scratch */
    880         bb_error_msg("No status file found, creating new one");
     923        bb_error_msg("no status file found, creating new one");
    881924    }
    882925
    883926    if (rename("/var/lib/dpkg/status.udeb", "/var/lib/dpkg/status") == -1) {
    884         bb_error_msg_and_die("DANGER: Couldnt create status file, you need to manually repair your status file");
     927        bb_error_msg_and_die("DANGER: cannot create status file, "
     928            "you need to manually repair your status file");
    885929    }
    886930}
     
    900944     * provides which cannot satisfy any dependency by itself.
    901945     */
    902     if ( status_hashtable[status_num] == NULL )
     946    if (status_hashtable[status_num] == NULL)
    903947        return 0;
    904948
     
    927971     * installed package for conflicts*/
    928972    while (deb_file[i] != NULL) {
    929         const unsigned int package_num = deb_file[i]->package;
     973        const unsigned package_num = deb_file[i]->package;
    930974        conflicts = xrealloc(conflicts, sizeof(int) * (conflicts_num + 1));
    931975        conflicts[conflicts_num] = package_num;
     
    940984                if (package_hashtable[conflicts_package_num] == NULL) {
    941985                    /* create a new package */
    942                     common_node_t *new_node = (common_node_t *) xzalloc(sizeof(common_node_t));
     986                    common_node_t *new_node = xzalloc(sizeof(common_node_t));
    943987                    new_node->name = package_hashtable[package_num]->edge[j]->name;
    944988                    new_node->version = package_hashtable[package_num]->edge[j]->version;
     
    9691013
    9701014            if (package_edge->type == EDGE_CONFLICTS) {
    971                 const unsigned int package_num =
     1015                const unsigned package_num =
    9721016                    search_package_hashtable(package_edge->name,
    9731017                                 package_edge->version,
     
    9841028
    9851029                if (result) {
    986                     bb_error_msg_and_die("Package %s conflicts with %s",
     1030                    bb_error_msg_and_die("package %s conflicts with %s",
    9871031                        name_hashtable[package_node->name],
    9881032                        name_hashtable[package_edge->name]);
     
    10051049         * no dependencies to check.
    10061050         */
    1007         if ( package_node == NULL ) continue;
     1051        if (package_node == NULL) continue;
    10081052
    10091053        status_num = search_status_hashtable(name_hashtable[package_node->name]);
     
    10131057         * case there are no dependencies to check.
    10141058         */
    1015         if ( status_hashtable[status_num] == NULL ) continue;
     1059        if (status_hashtable[status_num] == NULL) continue;
    10161060
    10171061        /* If we don't want this package installed then we may
     
    10211065            continue;
    10221066        }
    1023 
    1024 #if 0
    1025         /* This might be needed so we don't complain about
    1026          * things which are broken but unrelated to the
    1027          * packages that are currently being installed
    1028          */
    1029         if (state_status == search_name_hashtable("installed"))
    1030             continue;
    1031 #endif
    10321067
    10331068        /* This code is tested only for EDGE_DEPENDS, since I
     
    10371072        for (j = 0; j < package_node->num_of_edges; j++) {
    10381073            const edge_t *package_edge = package_node->edge[j];
    1039             unsigned int package_num;
    1040 
    1041             if ( package_edge->type == EDGE_OR_PRE_DEPENDS ||
    1042                  package_edge->type == EDGE_OR_DEPENDS ) {  /* start an EDGE_OR_ list */
     1074            unsigned package_num;
     1075
     1076            if (package_edge->type == EDGE_OR_PRE_DEPENDS
     1077             || package_edge->type == EDGE_OR_DEPENDS
     1078            ) { /* start an EDGE_OR_ list */
    10431079                number_of_alternatives = package_edge->version;
    10441080                root_of_alternatives = package_edge;
    10451081                continue;
    1046             } else if ( number_of_alternatives == 0 ) { /* not in the middle of an EDGE_OR_ list */
     1082            }
     1083            if (number_of_alternatives == 0) {  /* not in the middle of an EDGE_OR_ list */
    10471084                number_of_alternatives = 1;
    10481085                root_of_alternatives = NULL;
     
    10521089
    10531090            if (package_edge->type == EDGE_PRE_DEPENDS ||
    1054                 package_edge->type == EDGE_DEPENDS ) {
     1091                package_edge->type == EDGE_DEPENDS) {
    10551092                int result=1;
    10561093                status_num = 0;
     
    10621099                 * EDGE_PRE_DEPENDS == OR_PRE_DEPENDS -1
    10631100                 */
    1064                 if ( root_of_alternatives && package_edge->type != root_of_alternatives->type - 1)
    1065                     bb_error_msg_and_die("Fatal error. Package dependencies corrupt: %d != %d - 1 \n",
     1101                if (root_of_alternatives && package_edge->type != root_of_alternatives->type - 1)
     1102                    bb_error_msg_and_die("fatal error, package dependencies corrupt: %d != %d - 1",
    10661103                                 package_edge->type, root_of_alternatives->type);
    10671104
     
    10721109                    int provider = -1;
    10731110
    1074                     while ( (provider = search_for_provides(package_edge->name, provider) ) > -1 ) {
    1075                         if ( package_hashtable[provider] == NULL ) {
    1076                             printf("Have a provider but no package information for it\n");
     1111                    while ((provider = search_for_provides(package_edge->name, provider)) > -1) {
     1112                        if (package_hashtable[provider] == NULL) {
     1113                            puts("Have a provider but no package information for it");
    10771114                            continue;
    10781115                        }
    10791116                        result = !package_satisfies_dependency(provider, package_edge->type);
    10801117
    1081                         if ( result == 0 )
     1118                        if (result == 0)
    10821119                            break;
    10831120                    }
     
    10871124                number_of_alternatives--;
    10881125                if (result && number_of_alternatives == 0) {
    1089                     if ( root_of_alternatives )
     1126                    if (root_of_alternatives)
    10901127                        bb_error_msg_and_die(
    1091                             "Package %s %sdepends on %s, "
     1128                            "package %s %sdepends on %s, "
    10921129                            "which cannot be satisfied",
    10931130                            name_hashtable[package_node->name],
    10941131                            package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",
    10951132                            name_hashtable[root_of_alternatives->name]);
    1096                     else
    1097                         bb_error_msg_and_die(
    1098                             "Package %s %sdepends on %s, which %s\n",
    1099                             name_hashtable[package_node->name],
    1100                             package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",
    1101                             name_hashtable[package_edge->name],
    1102                             describe_status(status_num));
    1103                 } else if ( result == 0 && number_of_alternatives ) {
     1133                    bb_error_msg_and_die(
     1134                        "package %s %sdepends on %s, which %s\n",
     1135                        name_hashtable[package_node->name],
     1136                        package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",
     1137                        name_hashtable[package_edge->name],
     1138                        describe_status(status_num));
     1139                }
     1140                if (result == 0 && number_of_alternatives) {
    11041141                    /* we've found a package which
    11051142                     * satisfies the dependency,
     
    11141151    }
    11151152    free(conflicts);
    1116     return(TRUE);
     1153    return TRUE;
    11171154}
    11181155
     
    11271164    list_stream = fopen(filename, "r");
    11281165    if (list_stream == NULL) {
    1129         return(NULL);
    1130     }
    1131 
    1132     while ((line = bb_get_chomped_line_from_file(list_stream)) != NULL) {
     1166        return NULL;
     1167    }
     1168
     1169    while ((line = xmalloc_getline(list_stream)) != NULL) {
    11331170        file_list = xrealloc(file_list, sizeof(char *) * (count + 2));
    11341171        file_list[count] = line;
     
    11381175
    11391176    if (count == 0) {
    1140         return(NULL);
    1141     } else {
    1142         file_list[count] = NULL;
    1143         return(file_list);
    1144     }
     1177        return NULL;
     1178    }
     1179    file_list[count] = NULL;
     1180    return file_list;
    11451181}
    11461182
     
    11491185{
    11501186    struct stat path_stat;
    1151     int match_flag;
    1152     int remove_flag = FALSE;
    1153     int i,j;
     1187    int remove_flag = 1; /* not removed anything yet */
     1188    int i, j;
    11541189
    11551190    if (remove_names == NULL) {
    1156         return(FALSE);
     1191        return 0;
    11571192    }
    11581193    for (i = 0; remove_names[i] != NULL; i++) {
    1159         match_flag = FALSE;
    11601194        if (exclude_names != NULL) {
    1161             for (j = 0; exclude_names[j] != 0; j++) {
     1195            for (j = 0; exclude_names[j] != NULL; j++) {
    11621196                if (strcmp(remove_names[i], exclude_names[j]) == 0) {
    1163                     match_flag = TRUE;
    1164                     break;
     1197                    goto skip;
    11651198                }
    11661199            }
    11671200        }
    1168         if (!match_flag) {
    1169             if (lstat(remove_names[i], &path_stat) < 0) {
    1170                 continue;
    1171             }
    1172             if (S_ISDIR(path_stat.st_mode)) {
    1173                 if (rmdir(remove_names[i]) != -1) {
    1174                     remove_flag = TRUE;
    1175                 }
    1176             } else {
    1177                 if (unlink(remove_names[i]) != -1) {
    1178                     remove_flag = TRUE;
    1179                 }
    1180             }
    1181         }
    1182     }
    1183     return(remove_flag);
     1201        /* TODO: why we are checking lstat? we can just try rm/rmdir */
     1202        if (lstat(remove_names[i], &path_stat) < 0) {
     1203            continue;
     1204        }
     1205        if (S_ISDIR(path_stat.st_mode)) {
     1206            remove_flag &= rmdir(remove_names[i]); /* 0 if no error */
     1207        } else {
     1208            remove_flag &= unlink(remove_names[i]); /* 0 if no error */
     1209        }
     1210 skip:
     1211        continue;
     1212    }
     1213    return (remove_flag == 0);
    11841214}
    11851215
     
    11901220    int result;
    11911221
    1192     script_path = bb_xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type);
     1222    script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type);
    11931223
    11941224    /* If the file doesnt exist is isnt a fatal */
    11951225    result = lstat(script_path, &path_stat) < 0 ? EXIT_SUCCESS : system(script_path);
    11961226    free(script_path);
    1197     return(result);
    1198 }
    1199 
    1200 static const char *all_control_files[] = {"preinst", "postinst", "prerm", "postrm",
    1201     "list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL };
     1227    return result;
     1228}
     1229
     1230static const char *const all_control_files[] = {
     1231    "preinst", "postinst", "prerm", "postrm",
     1232    "list", "md5sums", "shlibs", "conffiles",
     1233    "config", "templates", NULL
     1234};
    12021235
    12031236static char **all_control_list(const char *package_name)
    12041237{
    1205     unsigned short i = 0;
     1238    unsigned i = 0;
    12061239    char **remove_files;
    12071240
     
    12091242    remove_files = xzalloc(sizeof(all_control_files));
    12101243    while (all_control_files[i]) {
    1211         remove_files[i] = bb_xasprintf("/var/lib/dpkg/info/%s.%s", package_name, all_control_files[i]);
     1244        remove_files[i] = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, all_control_files[i]);
    12121245        i++;
    12131246    }
    12141247
    1215     return(remove_files);
     1248    return remove_files;
    12161249}
    12171250
    12181251static void free_array(char **array)
    12191252{
    1220 
    12211253    if (array) {
    1222         unsigned short i = 0;
     1254        unsigned i = 0;
    12231255        while (array[i]) {
    12241256            free(array[i]);
     
    12371269    int i;
    12381270
    1239     printf("    Name           Version\n");
    1240     printf("+++-==============-==============\n");
     1271    puts("    Name           Version");
     1272    puts("+++-==============-==============");
    12411273
    12421274    /* go through status hash, dereference package hash and finally strings */
    1243     for (i=0; i<STATUS_HASH_PRIME+1; i++) {
    1244 
    1245             if (status_hashtable[i]) {
    1246                 const char *stat_str;  /* status string */
     1275    for (i = 0; i < STATUS_HASH_PRIME+1; i++) {
     1276        if (status_hashtable[i]) {
     1277            const char *stat_str;  /* status string */
    12471278            const char *name_str;  /* package name */
    12481279            const char *vers_str;  /* version */
     
    12591290
    12601291            /* get abbreviation for status field 2 */
    1261             for (j=0, spccnt=0; stat_str[j] && spccnt<2; j++) {
    1262                     if (stat_str[j] == ' ') spccnt++;
     1292            for (j = 0, spccnt = 0; stat_str[j] && spccnt < 2; j++) {
     1293                if (stat_str[j] == ' ') spccnt++;
    12631294            }
    12641295            s2 = stat_str[j];
     
    12671298            printf("%c%c  %-14s %s\n", s1, s2, name_str, vers_str);
    12681299        }
    1269     }
    1270 }
    1271 
    1272 static void remove_package(const unsigned int package_num, int noisy)
     1300    }
     1301}
     1302
     1303static void remove_package(const unsigned package_num, int noisy)
    12731304{
    12741305    const char *package_name = name_hashtable[package_hashtable[package_num]->name];
    12751306    const char *package_version = name_hashtable[package_hashtable[package_num]->version];
    1276     const unsigned int status_num = search_status_hashtable(package_name);
     1307    const unsigned status_num = search_status_hashtable(package_name);
    12771308    const int package_name_length = strlen(package_name);
    12781309    char **remove_files;
     
    12801311    char list_name[package_name_length + 25];
    12811312    char conffile_name[package_name_length + 30];
    1282     int return_value;
    1283 
    1284     if ( noisy )
    1285         printf("Removing %s (%s) ...\n", package_name, package_version);
     1313
     1314    if (noisy)
     1315        printf("Removing %s (%s)...\n", package_name, package_version);
    12861316
    12871317    /* run prerm script */
    1288     return_value = run_package_script(package_name, "prerm");
    1289     if (return_value == -1) {
     1318    if (run_package_script(package_name, "prerm") != 0) {
    12901319        bb_error_msg_and_die("script failed, prerm failure");
    12911320    }
     
    12981327    exclude_files = create_list(conffile_name);
    12991328
    1300     /* Some directories cant be removed straight away, so do multiple passes */
    1301     while (remove_file_array(remove_files, exclude_files));
     1329    /* Some directories can't be removed straight away, so do multiple passes */
     1330    while (remove_file_array(remove_files, exclude_files)) /*repeat */;
    13021331    free_array(exclude_files);
    13031332    free_array(remove_files);
     
    13051334    /* Create a list of files in /var/lib/dpkg/info/<package>.* to keep  */
    13061335    exclude_files = xzalloc(sizeof(char*) * 3);
    1307     exclude_files[0] = bb_xstrdup(conffile_name);
    1308     exclude_files[1] = bb_xasprintf("/var/lib/dpkg/info/%s.postrm", package_name);
     1336    exclude_files[0] = xstrdup(conffile_name);
     1337    exclude_files[1] = xasprintf("/var/lib/dpkg/info/%s.postrm", package_name);
    13091338
    13101339    /* Create a list of all /var/lib/dpkg/info/<package> files */
     
    13221351}
    13231352
    1324 static void purge_package(const unsigned int package_num)
     1353static void purge_package(const unsigned package_num)
    13251354{
    13261355    const char *package_name = name_hashtable[package_hashtable[package_num]->name];
    13271356    const char *package_version = name_hashtable[package_hashtable[package_num]->version];
    1328     const unsigned int status_num = search_status_hashtable(package_name);
     1357    const unsigned status_num = search_status_hashtable(package_name);
    13291358    char **remove_files;
    13301359    char **exclude_files;
    13311360    char list_name[strlen(package_name) + 25];
    13321361
    1333     printf("Purging %s (%s) ...\n", package_name, package_version);
     1362    printf("Purging %s (%s)...\n", package_name, package_version);
    13341363
    13351364    /* run prerm script */
     
    13451374
    13461375    /* Some directories cant be removed straight away, so do multiple passes */
    1347     while (remove_file_array(remove_files, exclude_files));
     1376    while (remove_file_array(remove_files, exclude_files)) /* repeat */;
    13481377    free_array(remove_files);
    13491378
     
    13551384
    13561385    /* run postrm script */
    1357     if (run_package_script(package_name, "postrm") == -1) {
    1358         bb_error_msg_and_die("postrm fialure.. set status to what?");
     1386    if (run_package_script(package_name, "postrm") != 0) {
     1387        bb_error_msg_and_die("postrm failure.. set status to what?");
    13591388    }
    13601389
     
    13701399    ar_handle = init_handle();
    13711400    ar_handle->filter = filter_accept_list_reassign;
    1372     ar_handle->src_fd = bb_xopen(filename, O_RDONLY);
    1373 
    1374     return(ar_handle);
     1401    ar_handle->src_fd = xopen(filename, O_RDONLY);
     1402
     1403    return ar_handle;
    13751404}
    13761405
     
    13841413
    13851414    /* We don't care about data.tar.* or debian-binary, just control.tar.* */
    1386 #ifdef CONFIG_FEATURE_DEB_TAR_GZ
    1387     llist_add_to(&(ar_handle->accept), "control.tar.gz");
     1415#if ENABLE_FEATURE_DEB_TAR_GZ
     1416    llist_add_to(&(ar_handle->accept), (char*)"control.tar.gz");
    13881417#endif
    1389 #ifdef CONFIG_FEATURE_DEB_TAR_BZ2
    1390     llist_add_to(&(ar_handle->accept), "control.tar.bz2");
     1418#if ENABLE_FEATURE_DEB_TAR_BZ2
     1419    llist_add_to(&(ar_handle->accept), (char*)"control.tar.bz2");
    13911420#endif
    13921421
    13931422    /* Assign the tar handle as a subarchive of the ar handle */
    13941423    ar_handle->sub_archive = tar_handle;
    1395 
    1396     return;
    13971424}
    13981425
     
    14061433
    14071434    /* We don't care about control.tar.* or debian-binary, just data.tar.* */
    1408 #ifdef CONFIG_FEATURE_DEB_TAR_GZ
    1409     llist_add_to(&(ar_handle->accept), "data.tar.gz");
     1435#if ENABLE_FEATURE_DEB_TAR_GZ
     1436    llist_add_to(&(ar_handle->accept), (char*)"data.tar.gz");
    14101437#endif
    1411 #ifdef CONFIG_FEATURE_DEB_TAR_BZ2
    1412     llist_add_to(&(ar_handle->accept), "data.tar.bz2");
     1438#if ENABLE_FEATURE_DEB_TAR_BZ2
     1439    llist_add_to(&(ar_handle->accept), (char*)"data.tar.bz2");
    14131440#endif
    14141441
    14151442    /* Assign the tar handle as a subarchive of the ar handle */
    14161443    ar_handle->sub_archive = tar_handle;
    1417 
    1418     return;
    14191444}
    14201445
     
    14281453    close(ar_handle->src_fd);
    14291454
    1430     return(ar_handle->sub_archive->buffer);
     1455    return ar_handle->sub_archive->buffer;
    14311456}
    14321457
     
    14371462    name_ptr += strspn(name_ptr, "./");
    14381463    if (name_ptr[0] != '\0') {
    1439         archive_handle->file_header->name = bb_xasprintf("%s%s", archive_handle->buffer, name_ptr);
     1464        archive_handle->file_header->name = xasprintf("%s%s", archive_handle->buffer, name_ptr);
    14401465        data_extract_all(archive_handle);
    14411466    }
    1442     return;
    14431467}
    14441468
     
    14461470{
    14471471    const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];
    1448     const unsigned int status_num = search_status_hashtable(package_name);
    1449     const unsigned int status_package_num = status_hashtable[status_num]->package;
     1472    const unsigned status_num = search_status_hashtable(package_name);
     1473    const unsigned status_package_num = status_hashtable[status_num]->package;
    14501474    char *info_prefix;
     1475    char *list_filename;
    14511476    archive_handle_t *archive_handle;
    14521477    FILE *out_stream;
     
    14571482    if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) {
    14581483        /* Package is already installed, remove old version first */
    1459         printf("Preparing to replace %s %s (using %s) ...\n", package_name,
     1484        printf("Preparing to replace %s %s (using %s)...\n", package_name,
    14601485            name_hashtable[package_hashtable[status_package_num]->version],
    14611486            deb_file->filename);
    14621487        remove_package(status_package_num, 0);
    14631488    } else {
    1464         printf("Unpacking %s (from %s) ...\n", package_name, deb_file->filename);
     1489        printf("Unpacking %s (from %s)...\n", package_name, deb_file->filename);
    14651490    }
    14661491
    14671492    /* Extract control.tar.gz to /var/lib/dpkg/info/<package>.filename */
    1468     info_prefix = bb_xasprintf("/var/lib/dpkg/info/%s.", package_name);
     1493    info_prefix = xasprintf("/var/lib/dpkg/info/%s.", package_name);
    14691494    archive_handle = init_archive_deb_ar(deb_file->filename);
    14701495    init_archive_deb_control(archive_handle);
    14711496
    1472     while(all_control_files[i]) {
    1473         char *c = bb_xasprintf("./%s", all_control_files[i]);
     1497    while (all_control_files[i]) {
     1498        char *c = xasprintf("./%s", all_control_files[i]);
    14741499        llist_add_to(&accept_list, c);
    14751500        i++;
     
    14851510    if (run_package_script(package_name, "preinst") != 0) {
    14861511        /* when preinst returns exit code != 0 then quit installation process */
    1487         bb_error_msg_and_die("subprocess pre-installation script returned error.");
     1512        bb_error_msg_and_die("subprocess pre-installation script returned error");
    14881513    }
    14891514
     
    14921517    init_archive_deb_data(archive_handle);
    14931518    archive_handle->sub_archive->action_data = data_extract_all_prefix;
    1494     archive_handle->sub_archive->buffer = "/";
     1519    archive_handle->sub_archive->buffer = (char*)"/"; /* huh? */
    14951520    archive_handle->sub_archive->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL;
    14961521    unpack_ar_archive(archive_handle);
    14971522
    14981523    /* Create the list file */
    1499     strcat(info_prefix, "list");
    1500     out_stream = bb_xfopen(info_prefix, "w");
     1524    list_filename = xasprintf("/var/lib/dpkg/info/%s.list", package_name);
     1525    out_stream = xfopen(list_filename, "w");
    15011526    while (archive_handle->sub_archive->passed) {
    15021527        /* the leading . has been stripped by data_extract_all_prefix already */
     
    15121537
    15131538    free(info_prefix);
     1539    free(list_filename);
    15141540}
    15151541
     
    15201546    const int status_num = search_status_hashtable(package_name);
    15211547
    1522     printf("Setting up %s (%s) ...\n", package_name, package_version);
     1548    printf("Setting up %s (%s)...\n", package_name, package_version);
    15231549
    15241550    /* Run the postinst script */
    15251551    if (run_package_script(package_name, "postinst") != 0) {
    15261552        /* TODO: handle failure gracefully */
    1527         bb_error_msg_and_die("postrm failure.. set status to what?");
     1553        bb_error_msg_and_die("postinst failure.. set status to what?");
    15281554    }
    15291555    /* Change status to reflect success */
     
    15321558}
    15331559
     1560int dpkg_main(int argc, char **argv);
    15341561int dpkg_main(int argc, char **argv)
    15351562{
    15361563    deb_file_t **deb_file = NULL;
    15371564    status_node_t *status_node;
     1565    char *str_f;
    15381566    int opt;
    15391567    int package_num;
    1540     int dpkg_opt = 0;
    15411568    int deb_count = 0;
    15421569    int state_status;
    15431570    int status_num;
    15441571    int i;
    1545 
    1546     while ((opt = getopt(argc, argv, "CF:ilPru")) != -1) {
    1547         switch (opt) {
    1548             case 'C': // equivalent to --configure in official dpkg
    1549                 dpkg_opt |= dpkg_opt_configure;
    1550                 dpkg_opt |= dpkg_opt_package_name;
    1551                 break;
    1552             case 'F': // equivalent to --force in official dpkg
    1553                 if (strcmp(optarg, "depends") == 0) {
    1554                     dpkg_opt |= dpkg_opt_force_ignore_depends;
    1555                 }
    1556                 break;
    1557             case 'i':
    1558                 dpkg_opt |= dpkg_opt_install;
    1559                 dpkg_opt |= dpkg_opt_filename;
    1560                 break;
    1561             case 'l':
    1562                 dpkg_opt |= dpkg_opt_list_installed;
    1563                 break;
    1564             case 'P':
    1565                 dpkg_opt |= dpkg_opt_purge;
    1566                 dpkg_opt |= dpkg_opt_package_name;
    1567                 break;
    1568             case 'r':
    1569                 dpkg_opt |= dpkg_opt_remove;
    1570                 dpkg_opt |= dpkg_opt_package_name;
    1571                 break;
    1572             case 'u':   /* Equivalent to --unpack in official dpkg */
    1573                 dpkg_opt |= dpkg_opt_unpack;
    1574                 dpkg_opt |= dpkg_opt_filename;
    1575                 break;
    1576             default:
    1577                 bb_show_usage();
    1578         }
    1579     }
    1580     /* check for non-otion argument if expected  */
    1581     if ((dpkg_opt == 0) || ((argc == optind) && !(dpkg_opt && dpkg_opt_list_installed))) {
     1572    enum {
     1573        OPT_configure = 0x1,
     1574        OPT_force_ignore_depends = 0x2,
     1575        OPT_install = 0x4,
     1576        OPT_list_installed = 0x8,
     1577        OPT_purge = 0x10,
     1578        OPT_remove = 0x20,
     1579        OPT_unpack = 0x40,
     1580    };
     1581
     1582    opt = getopt32(argv, "CF:ilPru", &str_f);
     1583    //if (opt & OPT_configure) ... // -C
     1584    if (opt & OPT_force_ignore_depends) { // -F (--force in official dpkg)
     1585        if (strcmp(str_f, "depends"))
     1586            opt &= ~OPT_force_ignore_depends;
     1587    }
     1588    //if (opt & OPT_install) ... // -i
     1589    //if (opt & OPT_list_installed) ... // -l
     1590    //if (opt & OPT_purge) ... // -P
     1591    //if (opt & OPT_remove) ... // -r
     1592    //if (opt & OPT_unpack) ... // -u (--unpack in official dpkg)
     1593    argc -= optind;
     1594    argv += optind;
     1595    /* check for non-option argument if expected  */
     1596    if (!opt || (!argc && !(opt && OPT_list_installed)))
    15821597        bb_show_usage();
    1583     }
     1598
     1599    name_hashtable = xzalloc(sizeof(name_hashtable[0]) * (NAME_HASH_PRIME + 1));
     1600    package_hashtable = xzalloc(sizeof(package_hashtable[0]) * (PACKAGE_HASH_PRIME + 1));
     1601    status_hashtable = xzalloc(sizeof(status_hashtable[0]) * (STATUS_HASH_PRIME + 1));
    15841602
    15851603/*  puts("(Reading database ... xxxxx files and directories installed.)"); */
     
    15871605
    15881606    /* if the list action was given print the installed packages and exit */
    1589     if (dpkg_opt & dpkg_opt_list_installed) {
     1607    if (opt & OPT_list_installed) {
    15901608        list_packages();
    1591         return(EXIT_SUCCESS);
     1609        return EXIT_SUCCESS;
    15921610    }
    15931611
    15941612    /* Read arguments and store relevant info in structs */
    1595     while (optind < argc) {
     1613    while (*argv) {
    15961614        /* deb_count = nb_elem - 1 and we need nb_elem + 1 to allocate terminal node [NULL pointer] */
    1597         deb_file = xrealloc(deb_file, sizeof(deb_file_t *) * (deb_count + 2));
    1598         deb_file[deb_count] = (deb_file_t *) xzalloc(sizeof(deb_file_t));
    1599         if (dpkg_opt & dpkg_opt_filename) {
     1615        deb_file = xrealloc(deb_file, sizeof(deb_file[0]) * (deb_count + 2));
     1616        deb_file[deb_count] = xzalloc(sizeof(deb_file[0][0]));
     1617        if (opt & (OPT_install | OPT_unpack)) {
     1618            /* -i/-u: require filename */
    16001619            archive_handle_t *archive_handle;
    16011620            llist_t *control_list = NULL;
    16021621
    16031622            /* Extract the control file */
    1604             llist_add_to(&control_list, "./control");
    1605             archive_handle = init_archive_deb_ar(argv[optind]);
     1623            llist_add_to(&control_list, (char*)"./control");
     1624            archive_handle = init_archive_deb_ar(argv[0]);
    16061625            init_archive_deb_control(archive_handle);
    16071626            deb_file[deb_count]->control_file = deb_extract_control_file_to_buffer(archive_handle, control_list);
    16081627            if (deb_file[deb_count]->control_file == NULL) {
    1609                 bb_error_msg_and_die("Couldnt extract control file");
    1610             }
    1611             deb_file[deb_count]->filename = bb_xstrdup(argv[optind]);
     1628                bb_error_msg_and_die("cannot extract control file");
     1629            }
     1630            deb_file[deb_count]->filename = xstrdup(argv[0]);
    16121631            package_num = fill_package_struct(deb_file[deb_count]->control_file);
    16131632
    16141633            if (package_num == -1) {
    1615                 bb_error_msg("Invalid control file in %s", argv[optind]);
    1616                 optind++;
     1634                bb_error_msg("invalid control file in %s", argv[0]);
     1635                argv++;
    16171636                continue;
    16181637            }
    1619             deb_file[deb_count]->package = (unsigned int) package_num;
     1638            deb_file[deb_count]->package = (unsigned) package_num;
    16201639
    16211640            /* Add the package to the status hashtable */
    1622             if ((dpkg_opt & dpkg_opt_unpack) || (dpkg_opt & dpkg_opt_install)) {
     1641            if (opt & (OPT_unpack | OPT_install)) {
    16231642                /* Try and find a currently installed version of this package */
    16241643                status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]);
    16251644                /* If no previous entry was found initialise a new entry */
    1626                 if ((status_hashtable[status_num] == NULL) ||
    1627                     (status_hashtable[status_num]->status == 0)) {
    1628                     status_node = (status_node_t *) xmalloc(sizeof(status_node_t));
     1645                if (status_hashtable[status_num] == NULL
     1646                 || status_hashtable[status_num]->status == 0
     1647                ) {
     1648                    status_node = xmalloc(sizeof(status_node_t));
    16291649                    status_node->package = deb_file[deb_count]->package;
    16301650                    /* reinstreq isnt changed to "ok" until the package control info
     
    16371657                }
    16381658            }
    1639         }
    1640         else if (dpkg_opt & dpkg_opt_package_name) {
     1659        } else if (opt & (OPT_configure | OPT_purge | OPT_remove)) {
     1660            /* -C/-p/-r: require package name */
    16411661            deb_file[deb_count]->package = search_package_hashtable(
    1642                 search_name_hashtable(argv[optind]),
    1643                 search_name_hashtable("ANY"), VER_ANY);
     1662                    search_name_hashtable(argv[0]),
     1663                    search_name_hashtable("ANY"), VER_ANY);
    16441664            if (package_hashtable[deb_file[deb_count]->package] == NULL) {
    1645                 bb_error_msg_and_die("Package %s is uninstalled or unknown\n", argv[optind]);
     1665                bb_error_msg_and_die("package %s is uninstalled or unknown", argv[0]);
    16461666            }
    16471667            package_num = deb_file[deb_count]->package;
     
    16501670
    16511671            /* check package status is "installed" */
    1652             if (dpkg_opt & dpkg_opt_remove) {
    1653                 if ((strcmp(name_hashtable[state_status], "not-installed") == 0) ||
    1654                     (strcmp(name_hashtable[state_status], "config-files") == 0)) {
    1655                     bb_error_msg_and_die("%s is already removed.", name_hashtable[package_hashtable[package_num]->name]);
     1672            if (opt & OPT_remove) {
     1673                if (strcmp(name_hashtable[state_status], "not-installed") == 0
     1674                 || strcmp(name_hashtable[state_status], "config-files") == 0
     1675                ) {
     1676                    bb_error_msg_and_die("%s is already removed", name_hashtable[package_hashtable[package_num]->name]);
    16561677                }
    16571678                set_status(status_num, "deinstall", 1);
    1658             }
    1659             else if (dpkg_opt & dpkg_opt_purge) {
     1679            } else if (opt & OPT_purge) {
    16601680                /* if package status is "conf-files" then its ok */
    16611681                if (strcmp(name_hashtable[state_status], "not-installed") == 0) {
    1662                     bb_error_msg_and_die("%s is already purged.", name_hashtable[package_hashtable[package_num]->name]);
     1682                    bb_error_msg_and_die("%s is already purged", name_hashtable[package_hashtable[package_num]->name]);
    16631683                }
    16641684                set_status(status_num, "purge", 1);
     
    16661686        }
    16671687        deb_count++;
    1668         optind++;
    1669     }
     1688        argv++;
     1689    }
     1690    if (!deb_count)
     1691        bb_error_msg_and_die("no package files specified");
    16701692    deb_file[deb_count] = NULL;
    16711693
    16721694    /* Check that the deb file arguments are installable */
    1673     if ((dpkg_opt & dpkg_opt_force_ignore_depends) != dpkg_opt_force_ignore_depends) {
     1695    if (!(opt & OPT_force_ignore_depends)) {
    16741696        if (!check_deps(deb_file, 0, deb_count)) {
    1675             bb_error_msg_and_die("Dependency check failed");
     1697            bb_error_msg_and_die("dependency check failed");
    16761698        }
    16771699    }
     
    16801702    for (i = 0; i < deb_count; i++) {
    16811703        /* Remove or purge packages */
    1682         if (dpkg_opt & dpkg_opt_remove) {
     1704        if (opt & OPT_remove) {
    16831705            remove_package(deb_file[i]->package, 1);
    16841706        }
    1685         else if (dpkg_opt & dpkg_opt_purge) {
     1707        else if (opt & OPT_purge) {
    16861708            purge_package(deb_file[i]->package);
    16871709        }
    1688         else if (dpkg_opt & dpkg_opt_unpack) {
     1710        else if (opt & OPT_unpack) {
    16891711            unpack_package(deb_file[i]);
    16901712        }
    1691         else if (dpkg_opt & dpkg_opt_install) {
     1713        else if (opt & OPT_install) {
    16921714            unpack_package(deb_file[i]);
    16931715            /* package is configured in second pass below */
    16941716        }
    1695         else if (dpkg_opt & dpkg_opt_configure) {
     1717        else if (opt & OPT_configure) {
    16961718            configure_package(deb_file[i]);
    16971719        }
    16981720    }
    16991721    /* configure installed packages */
    1700     if (dpkg_opt & dpkg_opt_install) {
     1722    if (opt & OPT_install) {
    17011723        for (i = 0; i < deb_count; i++)
    17021724            configure_package(deb_file[i]);
     
    17051727    write_status_file(deb_file);
    17061728
    1707     for (i = 0; i < deb_count; i++) {
    1708         free(deb_file[i]->control_file);
    1709         free(deb_file[i]->filename);
    1710         free(deb_file[i]);
    1711     }
    1712 
    1713     free(deb_file);
    1714 
    1715     for (i = 0; i < NAME_HASH_PRIME; i++) {
    1716         free(name_hashtable[i]);
    1717     }
    1718 
    1719     for (i = 0; i < PACKAGE_HASH_PRIME; i++) {
    1720         if (package_hashtable[i] != NULL) {
     1729    if (ENABLE_FEATURE_CLEAN_UP) {
     1730        for (i = 0; i < deb_count; i++) {
     1731            free(deb_file[i]->control_file);
     1732            free(deb_file[i]->filename);
     1733            free(deb_file[i]);
     1734        }
     1735
     1736        free(deb_file);
     1737
     1738        for (i = 0; i < NAME_HASH_PRIME; i++) {
     1739            free(name_hashtable[i]);
     1740        }
     1741
     1742        for (i = 0; i < PACKAGE_HASH_PRIME; i++) {
    17211743            free_package(package_hashtable[i]);
    17221744        }
    1723     }
    1724 
    1725     for (i = 0; i < STATUS_HASH_PRIME; i++) {
    1726         free(status_hashtable[i]);
    1727     }
    1728 
    1729     return(EXIT_SUCCESS);
    1730 }
    1731 
     1745
     1746        for (i = 0; i < STATUS_HASH_PRIME; i++) {
     1747            free(status_hashtable[i]);
     1748        }
     1749
     1750        free(status_hashtable);
     1751        free(package_hashtable);
     1752        free(name_hashtable);
     1753    }
     1754
     1755    return EXIT_SUCCESS;
     1756}
  • branches/2.2.5/mindi-busybox/archival/dpkg_deb.c

    r821 r1765  
    55 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    66 */
    7 #include <fcntl.h>
    8 #include <stdlib.h>
    9 #include <string.h>
    10 #include <unistd.h>
    11 
     7#include "libbb.h"
    128#include "unarchive.h"
    13 #include "busybox.h"
    149
    1510#define DPKG_DEB_OPT_CONTENTS   1
     
    1914#define DPKG_DEB_OPT_EXTRACT_VERBOSE    16
    2015
     16int dpkg_deb_main(int argc, char **argv);
    2117int dpkg_deb_main(int argc, char **argv)
    2218{
     
    2420    archive_handle_t *tar_archive;
    2521    llist_t *control_tar_llist = NULL;
    26     unsigned long opt;
    27     char *extract_dir = NULL;
     22    unsigned opt;
     23    const char *extract_dir = NULL;
    2824    short argcount = 1;
    2925
     
    3632    ar_archive->filter = filter_accept_list_reassign;
    3733
    38 #ifdef CONFIG_FEATURE_DEB_TAR_GZ
    39     llist_add_to(&(ar_archive->accept), "data.tar.gz");
    40     llist_add_to(&control_tar_llist, "control.tar.gz");
     34#if ENABLE_FEATURE_DEB_TAR_GZ
     35    llist_add_to(&(ar_archive->accept), (char*)"data.tar.gz");
     36    llist_add_to(&control_tar_llist, (char*)"control.tar.gz");
    4137#endif
    4238
    43 #ifdef CONFIG_FEATURE_DEB_TAR_BZ2
    44     llist_add_to(&(ar_archive->accept), "data.tar.bz2");
    45     llist_add_to(&control_tar_llist, "control.tar.bz2");
     39#if ENABLE_FEATURE_DEB_TAR_BZ2
     40    llist_add_to(&(ar_archive->accept), (char*)"data.tar.bz2");
     41    llist_add_to(&control_tar_llist, (char*)"control.tar.bz2");
    4642#endif
    4743
    48     bb_opt_complementally = "?c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX";
    49     opt = bb_getopt_ulflags(argc, argv, "cefXx");
     44    opt_complementary = "?c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX";
     45    opt = getopt32(argv, "cefXx");
    5046
    5147    if (opt & DPKG_DEB_OPT_CONTENTS) {
     
    6662         * specific field to print */
    6763        ar_archive->accept = control_tar_llist;
    68         llist_add_to(&(tar_archive->accept), "./control");
     64        llist_add_to(&(tar_archive->accept), (char*)"./control");
    6965        tar_archive->filter = filter_accept_list;
    7066        tar_archive->action_data = data_extract_to_stdout;
     
    8278    }
    8379
    84     tar_archive->src_fd = ar_archive->src_fd = bb_xopen(argv[optind++], O_RDONLY);
     80    tar_archive->src_fd = ar_archive->src_fd = xopen(argv[optind++], O_RDONLY);
    8581
    8682    /* Workout where to extract the files */
     
    9187    if (extract_dir) {
    9288        mkdir(extract_dir, 0777); /* bb_make_directory(extract_dir, 0777, 0) */
    93         bb_xchdir(extract_dir);
     89        xchdir(extract_dir);
    9490    }
    9591    unpack_ar_archive(ar_archive);
    9692
    9793    /* Cleanup */
    98     close (ar_archive->src_fd);
     94    close(ar_archive->src_fd);
    9995
    100     return(EXIT_SUCCESS);
     96    return EXIT_SUCCESS;
    10197}
  • branches/2.2.5/mindi-busybox/archival/gzip.c

    r821 r1765  
    66 *
    77 * Originally adjusted for busybox by Charles P. Wright <cpw@unix.asb.com>
    8  *      "this is a stripped down version of gzip I put into busybox, it does
    9  *      only standard in to standard out with -9 compression.  It also requires
    10  *      the zcat module for some important functions."
     8 * "this is a stripped down version of gzip I put into busybox, it does
     9 * only standard in to standard out with -9 compression.  It also requires
     10 * the zcat module for some important functions."
    1111 *
    1212 * Adjusted further by Erik Andersen <andersen@codepoet.org> to support
     
    1717 */
    1818
     19/* big objects in bss:
     20 * 00000020 b bl_count
     21 * 00000074 b base_length
     22 * 00000078 b base_dist
     23 * 00000078 b static_dtree
     24 * 0000009c b bl_tree
     25 * 000000f4 b dyn_dtree
     26 * 00000100 b length_code
     27 * 00000200 b dist_code
     28 * 0000023d b depth
     29 * 00000400 b flag_buf
     30 * 0000047a b heap
     31 * 00000480 b static_ltree
     32 * 000008f4 b dyn_ltree
     33 */
     34
     35/* TODO: full support for -v for DESKTOP
     36 * "/usr/bin/gzip -v a bogus aa" should say:
     37a:       85.1% -- replaced with a.gz
     38gzip: bogus: No such file or directory
     39aa:      85.1% -- replaced with aa.gz
     40*/
     41
     42#include "libbb.h"
     43
     44
     45/* ===========================================================================
     46 */
     47//#define DEBUG 1
     48/* Diagnostic functions */
     49#ifdef DEBUG
     50#  define Assert(cond,msg) { if (!(cond)) bb_error_msg(msg); }
     51#  define Trace(x) fprintf x
     52#  define Tracev(x) {if (verbose) fprintf x; }
     53#  define Tracevv(x) {if (verbose > 1) fprintf x; }
     54#  define Tracec(c,x) {if (verbose && (c)) fprintf x; }
     55#  define Tracecv(c,x) {if (verbose > 1 && (c)) fprintf x; }
     56#else
     57#  define Assert(cond,msg)
     58#  define Trace(x)
     59#  define Tracev(x)
     60#  define Tracevv(x)
     61#  define Tracec(c,x)
     62#  define Tracecv(c,x)
     63#endif
     64
     65
     66/* ===========================================================================
     67 */
    1968#define SMALL_MEM
    20 
    21 #include <stdlib.h>
    22 #include <stdio.h>
    23 #include <string.h>
    24 #include <unistd.h>
    25 #include <errno.h>
    26 #include <sys/types.h>
    27 #include <signal.h>
    28 #include <utime.h>
    29 #include <ctype.h>
    30 #include <sys/types.h>
    31 #include <unistd.h>
    32 #include <dirent.h>
    33 #include <fcntl.h>
    34 #include <time.h>
    35 #include "busybox.h"
    36 
    37 typedef unsigned char uch;
    38 typedef unsigned short ush;
    39 typedef unsigned long ulg;
    40 
    41 /* Return codes from gzip */
    42 #define OK      0
    43 #define ERROR   1
    44 #define WARNING 2
    45 
    46 /* Compression methods (see algorithm.doc) */
    47 /* Only STORED and DEFLATED are supported by this BusyBox module */
    48 #define STORED      0
    49 /* methods 4 to 7 reserved */
    50 #define DEFLATED    8
    51 
    52 /* To save memory for 16 bit systems, some arrays are overlaid between
    53  * the various modules:
    54  * deflate:  prev+head   window      d_buf  l_buf  outbuf
    55  * unlzw:    tab_prefix  tab_suffix  stack  inbuf  outbuf
    56  * For compression, input is done in window[]. For decompression, output
    57  * is done in window except for unlzw.
    58  */
    5969
    6070#ifndef INBUFSIZ
     
    6575#  endif
    6676#endif
    67 #define INBUF_EXTRA  64 /* required by unlzw() */
    6877
    6978#ifndef OUTBUFSIZ
     
    7483#  endif
    7584#endif
    76 #define OUTBUF_EXTRA 2048   /* required by unlzw() */
    7785
    7886#ifndef DIST_BUFSIZE
     
    8391#  endif
    8492#endif
    85 
    86 #  define DECLARE(type, array, size)  static type * array
    87 #  define ALLOC(type, array, size) { \
    88       array = (type*)xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type)); \
    89    }
    90 #  define FREE(array) {free(array), array=NULL;}
    91 
    92 #define tab_suffix window
    93 #define tab_prefix prev /* hash link (see deflate.c) */
    94 #define head (prev+WSIZE)   /* hash head (see deflate.c) */
    95 
    96 static long bytes_in;   /* number of input bytes */
    97 
    98 #define isize bytes_in
    99 /* for compatibility with old zip sources (to be cleaned) */
    100 
    101 typedef int file_t;     /* Do not use stdio */
    102 
    103 #define NO_FILE  (-1)   /* in memory compression */
    104 
    105 
    106 #define PACK_MAGIC     "\037\036"   /* Magic header for packed files */
    107 #define GZIP_MAGIC     "\037\213"   /* Magic header for gzip files, 1F 8B */
    108 #define OLD_GZIP_MAGIC "\037\236"   /* Magic header for gzip 0.5 = freeze 1.x */
    109 #define LZH_MAGIC      "\037\240"   /* Magic header for SCO LZH Compress files */
    110 #define PKZIP_MAGIC    "\120\113\003\004"   /* Magic header for pkzip files */
    11193
    11294/* gzip flag byte */
     
    124106
    125107#ifndef WSIZE
    126 #  define WSIZE 0x8000  /* window size--must be a power of two, and */
    127 #endif                          /*  at least 32K for zip's deflate method */
     108#  define WSIZE 0x8000  /* window size--must be a power of two, and */
     109#endif                  /*  at least 32K for zip's deflate method */
    128110
    129111#define MIN_MATCH  3
     
    141123 */
    142124
    143 /* put_byte is used for the compressed output */
    144 #define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\
    145    flush_outbuf();}
    146 
    147 
    148 /* Output a 32 bit value to the bit stream, lsb first */
    149 #if 0
    150 #define put_long(n) { \
    151     put_short((n) & 0xffff); \
    152     put_short(((ulg)(n)) >> 16); \
    153 }
     125#ifndef MAX_PATH_LEN
     126#  define MAX_PATH_LEN   1024   /* max pathname length */
    154127#endif
    155128
    156129#define seekable()    0 /* force sequential output */
    157130#define translate_eol 0 /* no option -a yet */
    158 
    159 /* Diagnostic functions */
    160 #ifdef DEBUG
    161 #  define Assert(cond,msg) {if(!(cond)) bb_error_msg(msg);}
    162 #  define Trace(x) fprintf x
    163 #  define Tracev(x) {if (verbose) fprintf x ;}
    164 #  define Tracevv(x) {if (verbose>1) fprintf x ;}
    165 #  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
    166 #  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
    167 #else
    168 #  define Assert(cond,msg)
    169 #  define Trace(x)
    170 #  define Tracev(x)
    171 #  define Tracevv(x)
    172 #  define Tracec(c,x)
    173 #  define Tracecv(c,x)
    174 #endif
    175 
    176 #define WARN(msg) {if (!quiet) fprintf msg ; \
    177            if (exit_code == OK) exit_code = WARNING;}
    178 
    179 #ifndef MAX_PATH_LEN
    180 #  define MAX_PATH_LEN   1024   /* max pathname length */
    181 #endif
    182 
    183 
    184     /* from zip.c: */
    185 static int zip(int in, int out);
    186 static int file_read(char *buf, unsigned size);
    187 
    188         /* from deflate.c */
    189 static void lm_init(ush * flags);
    190 static ulg deflate(void);
    191 
    192         /* from trees.c */
    193 static void ct_init(ush * attr, int *methodp);
    194 static int ct_tally(int dist, int lc);
    195 static ulg flush_block(char *buf, ulg stored_len, int eof);
    196 
    197         /* from bits.c */
    198 static void bi_init(file_t zipfile);
    199 static void send_bits(int value, int length);
    200 static unsigned bi_reverse(unsigned value, int length);
    201 static void bi_windup(void);
    202 static void copy_block(char *buf, unsigned len, int header);
    203 static int (*read_buf) (char *buf, unsigned size);
    204 
    205     /* from util.c: */
    206 static void flush_outbuf(void);
    207 
    208 /* lzw.h -- define the lzw functions.
    209  * Copyright (C) 1992-1993 Jean-loup Gailly.
    210  * This is free software; you can redistribute it and/or modify it under the
    211  * terms of the GNU General Public License, see the file COPYING.
    212  */
    213131
    214132#ifndef BITS
     
    227145 */
    228146
    229 /* tailor.h -- target dependent definitions
    230  * Copyright (C) 1992-1993 Jean-loup Gailly.
    231  * This is free software; you can redistribute it and/or modify it under the
    232  * terms of the GNU General Public License, see the file COPYING.
    233  */
    234 
    235 /* The target dependent definitions should be defined here only.
    236  * The target dependent functions should be defined in tailor.c.
    237  */
    238 
    239 
    240     /* Common defaults */
    241 
    242 #ifndef OS_CODE
    243 #  define OS_CODE  0x03 /* assume Unix */
    244 #endif
    245 
    246 #ifndef PATH_SEP
    247 #  define PATH_SEP '/'
    248 #endif
    249 
    250 #ifndef OPTIONS_VAR
    251 #  define OPTIONS_VAR "GZIP"
    252 #endif
    253 
    254 #ifndef Z_SUFFIX
    255 #  define Z_SUFFIX ".gz"
    256 #endif
    257 
    258147#ifdef MAX_EXT_CHARS
    259148#  define MAX_SUFFIX  MAX_EXT_CHARS
     
    262151#endif
    263152
    264         /* global buffers */
    265 
    266 DECLARE(uch, inbuf, INBUFSIZ + INBUF_EXTRA);
    267 DECLARE(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA);
    268 DECLARE(ush, d_buf, DIST_BUFSIZE);
    269 DECLARE(uch, window, 2L * WSIZE);
    270 DECLARE(ush, tab_prefix, 1L << BITS);
    271 
    272 static int foreground;  /* set if program run in foreground */
    273 static int method = DEFLATED;   /* compression method */
    274 static int exit_code = OK;  /* program exit code */
    275 static int part_nb;     /* number of parts in .gz file */
    276 static long time_stamp; /* original time stamp (modification time) */
    277 static long ifile_size; /* input file size, -1 for devices (debug only) */
    278 static char z_suffix[MAX_SUFFIX + 1];   /* default suffix (can be set with --suffix) */
    279 static int z_len;       /* strlen(z_suffix) */
    280 
    281 static int ifd;         /* input file descriptor */
    282 static int ofd;         /* output file descriptor */
    283 static unsigned insize; /* valid bytes in inbuf */
    284 static unsigned outcnt; /* bytes in output buffer */
    285 
    286 static uint32_t *crc_32_tab;
    287 
    288 /* Output a 16 bit value, lsb first */
    289 static void put_short(ush w)
    290 {
    291     if (outcnt < OUTBUFSIZ - 2) {
    292         outbuf[outcnt++] = (uch) ((w) & 0xff);
    293         outbuf[outcnt++] = (uch) ((ush) (w) >> 8);
    294     } else {
    295         put_byte((uch) ((w) & 0xff));
    296         put_byte((uch) ((ush) (w) >> 8));
    297     }
    298 }
    299 
    300 /* ========================================================================
    301  * Signal and error handler.
    302  */
    303 static void abort_gzip(int ATTRIBUTE_UNUSED ignored)
    304 {
    305     exit(ERROR);
    306 }
    307 
    308 /* ===========================================================================
    309  * Clear input and output buffers
    310  */
    311 static void clear_bufs(void)
    312 {
    313     outcnt = 0;
    314     insize = 0;
    315     bytes_in = 0L;
    316 }
    317 
    318 /* ===========================================================================
    319  * Does the same as write(), but also handles partial pipe writes and checks
    320  * for error return.
    321  */
    322 static void write_buf(int fd, void *buf, unsigned cnt)
    323 {
    324     unsigned n;
    325 
    326     while ((n = write(fd, buf, cnt)) != cnt) {
    327         if (n == (unsigned) (-1)) bb_error_msg_and_die(bb_msg_write_error);
    328         cnt -= n;
    329         buf = (void *) ((char *) buf + n);
    330     }
    331 }
    332 
    333 /* ===========================================================================
    334  * Run a set of bytes through the crc shift register.  If s is a NULL
    335  * pointer, then initialize the crc shift register contents instead.
    336  * Return the current crc in either case.
    337  */
    338 static uint32_t updcrc(uch * s, unsigned n)
    339 {
    340     static uint32_t crc = ~0;   /* shift register contents */
    341     uint32_t c;     /* temporary variable */
    342 
    343     if (s == NULL) {
    344         c = ~0;
    345     } else {
    346         c = crc;
    347         if (n)
    348             do {
    349                 c = crc_32_tab[((int) c ^ (*s++)) & 0xff] ^ (c >> 8);
    350             } while (--n);
    351     }
    352     crc = c;
    353     return ~c;
    354 }
    355 
    356 /* bits.c -- output variable-length bit strings
    357  * Copyright (C) 1992-1993 Jean-loup Gailly
    358  * This is free software; you can redistribute it and/or modify it under the
    359  * terms of the GNU General Public License, see the file COPYING.
    360  */
    361 
    362 
    363 /*
    364  *  PURPOSE
    365  *
    366  *      Output variable-length bit strings. Compression can be done
    367  *      to a file or to memory. (The latter is not supported in this version.)
    368  *
    369  *  DISCUSSION
    370  *
    371  *      The PKZIP "deflate" file format interprets compressed file data
    372  *      as a sequence of bits.  Multi-bit strings in the file may cross
    373  *      byte boundaries without restriction.
    374  *
    375  *      The first bit of each byte is the low-order bit.
    376  *
    377  *      The routines in this file allow a variable-length bit value to
    378  *      be output right-to-left (useful for literal values). For
    379  *      left-to-right output (useful for code strings from the tree routines),
    380  *      the bits must have been reversed first with bi_reverse().
    381  *
    382  *      For in-memory compression, the compressed bit stream goes directly
    383  *      into the requested output buffer. The input data is read in blocks
    384  *      by the mem_read() function. The buffer is limited to 64K on 16 bit
    385  *      machines.
    386  *
    387  *  INTERFACE
    388  *
    389  *      void bi_init (FILE *zipfile)
    390  *          Initialize the bit string routines.
    391  *
    392  *      void send_bits (int value, int length)
    393  *          Write out a bit string, taking the source bits right to
    394  *          left.
    395  *
    396  *      int bi_reverse (int value, int length)
    397  *          Reverse the bits of a bit string, taking the source bits left to
    398  *          right and emitting them right to left.
    399  *
    400  *      void bi_windup (void)
    401  *          Write out any remaining bits in an incomplete byte.
    402  *
    403  *      void copy_block(char *buf, unsigned len, int header)
    404  *          Copy a stored block to the zip file, storing first the length and
    405  *          its one's complement if requested.
    406  *
    407  */
    408 
    409 /* ===========================================================================
    410  * Local data used by the "bit string" routines.
    411  */
    412 
    413 static file_t zfile;    /* output gzip file */
    414 
    415 static unsigned short bi_buf;
    416 
    417 /* Output buffer. bits are inserted starting at the bottom (least significant
    418  * bits).
    419  */
    420 
    421 #define Buf_size (8 * 2*sizeof(char))
    422 /* Number of bits used within bi_buf. (bi_buf might be implemented on
    423  * more than 16 bits on some systems.)
    424  */
    425 
    426 static int bi_valid;
    427 
    428 /* Current input function. Set to mem_read for in-memory compression */
    429 
    430 #ifdef DEBUG
    431 ulg bits_sent;          /* bit length of the compressed data */
    432 #endif
    433 
    434 /* ===========================================================================
    435  * Initialize the bit string routines.
    436  */
    437 static void bi_init(file_t zipfile)
    438 {
    439     zfile = zipfile;
    440     bi_buf = 0;
    441     bi_valid = 0;
    442 #ifdef DEBUG
    443     bits_sent = 0L;
    444 #endif
    445 
    446     /* Set the defaults for file compression. They are set by memcompress
    447      * for in-memory compression.
    448      */
    449     if (zfile != NO_FILE) {
    450         read_buf = file_read;
    451     }
    452 }
    453 
    454 /* ===========================================================================
    455  * Send a value on a given number of bits.
    456  * IN assertion: length <= 16 and value fits in length bits.
    457  */
    458 static void send_bits(int value, int length)
    459 {
    460 #ifdef DEBUG
    461     Tracev((stderr, " l %2d v %4x ", length, value));
    462     Assert(length > 0 && length <= 15, "invalid length");
    463     bits_sent += (ulg) length;
    464 #endif
    465     /* If not enough room in bi_buf, use (valid) bits from bi_buf and
    466      * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
    467      * unused bits in value.
    468      */
    469     if (bi_valid > (int) Buf_size - length) {
    470         bi_buf |= (value << bi_valid);
    471         put_short(bi_buf);
    472         bi_buf = (ush) value >> (Buf_size - bi_valid);
    473         bi_valid += length - Buf_size;
    474     } else {
    475         bi_buf |= value << bi_valid;
    476         bi_valid += length;
    477     }
    478 }
    479 
    480 /* ===========================================================================
    481  * Reverse the first len bits of a code, using straightforward code (a faster
    482  * method would use a table)
    483  * IN assertion: 1 <= len <= 15
    484  */
    485 static unsigned bi_reverse(unsigned code, int len)
    486 {
    487     register unsigned res = 0;
    488 
    489     do {
    490         res |= code & 1;
    491         code >>= 1, res <<= 1;
    492     } while (--len > 0);
    493     return res >> 1;
    494 }
    495 
    496 /* ===========================================================================
    497  * Write out any remaining bits in an incomplete byte.
    498  */
    499 static void bi_windup(void)
    500 {
    501     if (bi_valid > 8) {
    502         put_short(bi_buf);
    503     } else if (bi_valid > 0) {
    504         put_byte(bi_buf);
    505     }
    506     bi_buf = 0;
    507     bi_valid = 0;
    508 #ifdef DEBUG
    509     bits_sent = (bits_sent + 7) & ~7;
    510 #endif
    511 }
    512 
    513 /* ===========================================================================
    514  * Copy a stored block to the zip file, storing first the length and its
    515  * one's complement if requested.
    516  */
    517 static void copy_block(char *buf, unsigned len, int header)
    518 {
    519     bi_windup();        /* align on byte boundary */
    520 
    521     if (header) {
    522         put_short((ush) len);
    523         put_short((ush) ~ len);
    524 #ifdef DEBUG
    525         bits_sent += 2 * 16;
    526 #endif
    527     }
    528 #ifdef DEBUG
    529     bits_sent += (ulg) len << 3;
    530 #endif
    531     while (len--) {
    532         put_byte(*buf++);
    533     }
    534 }
    535 
    536 /* deflate.c -- compress data using the deflation algorithm
    537  * Copyright (C) 1992-1993 Jean-loup Gailly
    538  * This is free software; you can redistribute it and/or modify it under the
    539  * terms of the GNU General Public License, see the file COPYING.
    540  */
    541 
    542 /*
    543  *  PURPOSE
    544  *
    545  *      Identify new text as repetitions of old text within a fixed-
    546  *      length sliding window trailing behind the new text.
    547  *
    548  *  DISCUSSION
    549  *
    550  *      The "deflation" process depends on being able to identify portions
    551  *      of the input text which are identical to earlier input (within a
    552  *      sliding window trailing behind the input currently being processed).
    553  *
    554  *      The most straightforward technique turns out to be the fastest for
    555  *      most input files: try all possible matches and select the longest.
    556  *      The key feature of this algorithm is that insertions into the string
    557  *      dictionary are very simple and thus fast, and deletions are avoided
    558  *      completely. Insertions are performed at each input character, whereas
    559  *      string matches are performed only when the previous match ends. So it
    560  *      is preferable to spend more time in matches to allow very fast string
    561  *      insertions and avoid deletions. The matching algorithm for small
    562  *      strings is inspired from that of Rabin & Karp. A brute force approach
    563  *      is used to find longer strings when a small match has been found.
    564  *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
    565  *      (by Leonid Broukhis).
    566  *         A previous version of this file used a more sophisticated algorithm
    567  *      (by Fiala and Greene) which is guaranteed to run in linear amortized
    568  *      time, but has a larger average cost, uses more memory and is patented.
    569  *      However the F&G algorithm may be faster for some highly redundant
    570  *      files if the parameter max_chain_length (described below) is too large.
    571  *
    572  *  ACKNOWLEDGMENTS
    573  *
    574  *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
    575  *      I found it in 'freeze' written by Leonid Broukhis.
    576  *      Thanks to many info-zippers for bug reports and testing.
    577  *
    578  *  REFERENCES
    579  *
    580  *      APPNOTE.TXT documentation file in PKZIP 1.93a distribution.
    581  *
    582  *      A description of the Rabin and Karp algorithm is given in the book
    583  *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
    584  *
    585  *      Fiala,E.R., and Greene,D.H.
    586  *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
    587  *
    588  *  INTERFACE
    589  *
    590  *      void lm_init (int pack_level, ush *flags)
    591  *          Initialize the "longest match" routines for a new file
    592  *
    593  *      ulg deflate (void)
    594  *          Processes a new input file and return its compressed length. Sets
    595  *          the compressed length, crc, deflate flags and internal file
    596  *          attributes.
    597  */
    598 
    599 
    600 /* ===========================================================================
    601  * Configuration parameters
    602  */
    603 
    604 /* Compile with MEDIUM_MEM to reduce the memory requirements or
     153
     154/* ===========================================================================
     155 * Compile with MEDIUM_MEM to reduce the memory requirements or
    605156 * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the
    606157 * entire input file can be held in memory (not possible on 16 bit systems).
     
    621172#endif
    622173
    623 /* To save space (see unlzw.c), we overlay prev+head with tab_prefix and
    624  * window with tab_suffix. Check that we can do this:
    625  */
    626 #if (WSIZE<<1) > (1<<BITS)
    627 #  error cannot overlay window with tab_suffix and prev with tab_prefix0
    628 #endif
    629 #if HASH_BITS > BITS-1
    630 #  error cannot overlay head with tab_prefix1
    631 #endif
    632174#define HASH_SIZE (unsigned)(1<<HASH_BITS)
    633175#define HASH_MASK (HASH_SIZE-1)
    634176#define WMASK     (WSIZE-1)
    635177/* HASH_SIZE and WSIZE must be powers of two */
    636 #define NIL 0
    637 /* Tail of hash chains */
    638 #define FAST 4
    639 #define SLOW 2
    640 /* speed options for the general purpose bit flag */
    641178#ifndef TOO_FAR
    642179#  define TOO_FAR 4096
    643180#endif
    644181/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
    645 /* ===========================================================================
    646  * Local data used by the "longest match" routines.
    647  */
     182
     183
     184/* ===========================================================================
     185 * These types are not really 'char', 'short' and 'long'
     186 */
     187typedef uint8_t uch;
     188typedef uint16_t ush;
     189typedef uint32_t ulg;
     190typedef int32_t lng;
     191
    648192typedef ush Pos;
    649193typedef unsigned IPos;
    650 
    651194/* A Pos is an index in the character window. We use short instead of int to
    652195 * save space in the various tables. IPos is used only for parameter passing.
    653196 */
    654197
    655 /* DECLARE(uch, window, 2L*WSIZE); */
     198enum {
     199    WINDOW_SIZE = 2 * WSIZE,
     200/* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
     201 * input file length plus MIN_LOOKAHEAD.
     202 */
     203
     204    max_chain_length = 4096,
     205/* To speed up deflation, hash chains are never searched beyond this length.
     206 * A higher limit improves compression ratio but degrades the speed.
     207 */
     208
     209    max_lazy_match = 258,
     210/* Attempt to find a better match only when the current match is strictly
     211 * smaller than this value. This mechanism is used only for compression
     212 * levels >= 4.
     213 */
     214
     215    max_insert_length = max_lazy_match,
     216/* Insert new strings in the hash table only if the match length
     217 * is not greater than this length. This saves time but degrades compression.
     218 * max_insert_length is used only for compression levels <= 3.
     219 */
     220
     221    good_match = 32,
     222/* Use a faster search when the previous match is longer than this */
     223
     224/* Values for max_lazy_match, good_match and max_chain_length, depending on
     225 * the desired pack level (0..9). The values given below have been tuned to
     226 * exclude worst case performance for pathological files. Better values may be
     227 * found for specific files.
     228 */
     229
     230    nice_match = 258,   /* Stop searching when current match exceeds this */
     231/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
     232 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
     233 * meaning.
     234 */
     235};
     236
     237
     238struct globals {
     239
     240    lng block_start;
     241
     242/* window position at the beginning of the current output block. Gets
     243 * negative when the window is moved backwards.
     244 */
     245    unsigned ins_h; /* hash index of string to be inserted */
     246
     247#define H_SHIFT  ((HASH_BITS+MIN_MATCH-1) / MIN_MATCH)
     248/* Number of bits by which ins_h and del_h must be shifted at each
     249 * input step. It must be such that after MIN_MATCH steps, the oldest
     250 * byte no longer takes part in the hash key, that is:
     251 * H_SHIFT * MIN_MATCH >= HASH_BITS
     252 */
     253
     254    unsigned prev_length;
     255
     256/* Length of the best match at previous step. Matches not greater than this
     257 * are discarded. This is used in the lazy match evaluation.
     258 */
     259
     260    unsigned strstart;  /* start of string to insert */
     261    unsigned match_start;   /* start of matching string */
     262    unsigned lookahead; /* number of valid bytes ahead in window */
     263
     264/* ===========================================================================
     265 */
     266#define DECLARE(type, array, size) \
     267    type * array
     268#define ALLOC(type, array, size) \
     269    array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type));
     270#define FREE(array) \
     271    do { free(array); array = NULL; } while (0)
     272
     273    /* global buffers */
     274
     275    /* buffer for literals or lengths */
     276    /* DECLARE(uch, l_buf, LIT_BUFSIZE); */
     277    DECLARE(uch, l_buf, INBUFSIZ);
     278
     279    DECLARE(ush, d_buf, DIST_BUFSIZE);
     280    DECLARE(uch, outbuf, OUTBUFSIZ);
     281
    656282/* Sliding window. Input bytes are read into the second half of the window,
    657283 * and move to the first half later to keep a dictionary of at least WSIZE
     
    663289 * be less efficient).
    664290 */
    665 
    666 /* DECLARE(Pos, prev, WSIZE); */
     291    DECLARE(uch, window, 2L * WSIZE);
     292
    667293/* Link to older string with same hash index. To limit the size of this
    668294 * array to 64K, this link is maintained only for the last 32K strings.
    669295 * An index in this array is thus a window index modulo 32K.
    670296 */
    671 
    672 /* DECLARE(Pos, head, 1<<HASH_BITS); */
    673 /* Heads of the hash chains or NIL. */
    674 
    675 static const ulg window_size = (ulg) 2 * WSIZE;
    676 
    677 /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
    678  * input file length plus MIN_LOOKAHEAD.
    679  */
    680 
    681 static long block_start;
    682 
    683 /* window position at the beginning of the current output block. Gets
    684  * negative when the window is moved backwards.
    685  */
    686 
    687 static unsigned ins_h;  /* hash index of string to be inserted */
    688 
    689 #define H_SHIFT  ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH)
    690 /* Number of bits by which ins_h and del_h must be shifted at each
    691  * input step. It must be such that after MIN_MATCH steps, the oldest
    692  * byte no longer takes part in the hash key, that is:
    693  *   H_SHIFT * MIN_MATCH >= HASH_BITS
    694  */
    695 
    696 static unsigned int prev_length;
    697 
    698 /* Length of the best match at previous step. Matches not greater than this
    699  * are discarded. This is used in the lazy match evaluation.
    700  */
    701 
    702 static unsigned strstart;   /* start of string to insert */
    703 static unsigned match_start;    /* start of matching string */
    704 static int eofile;      /* flag set at end of input file */
    705 static unsigned lookahead;  /* number of valid bytes ahead in window */
    706 
    707 enum {
    708     max_chain_length = 4096,
    709 
    710 /* To speed up deflation, hash chains are never searched beyond this length.
    711  * A higher limit improves compression ratio but degrades the speed.
    712  */
    713 
    714     max_lazy_match = 258,
    715 
    716 /* Attempt to find a better match only when the current match is strictly
    717  * smaller than this value. This mechanism is used only for compression
    718  * levels >= 4.
    719  */
    720     max_insert_length = max_lazy_match,
    721 /* Insert new strings in the hash table only if the match length
    722  * is not greater than this length. This saves time but degrades compression.
    723  * max_insert_length is used only for compression levels <= 3.
    724  */
    725 
    726     good_match = 32,
    727 
    728 /* Use a faster search when the previous match is longer than this */
    729 
    730 
    731 /* Values for max_lazy_match, good_match and max_chain_length, depending on
    732  * the desired pack level (0..9). The values given below have been tuned to
    733  * exclude worst case performance for pathological files. Better values may be
    734  * found for specific files.
    735  */
    736 
    737     nice_match = 258    /* Stop searching when current match exceeds this */
    738 
    739 /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
    740  * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
    741  * meaning.
    742  */
     297    /* DECLARE(Pos, prev, WSIZE); */
     298    DECLARE(ush, prev, 1L << BITS);
     299
     300/* Heads of the hash chains or 0. */
     301    /* DECLARE(Pos, head, 1<<HASH_BITS); */
     302#define head (G1.prev + WSIZE) /* hash head (see deflate.c) */
     303
     304/* number of input bytes */
     305    ulg isize;      /* only 32 bits stored in .gz file */
     306
     307/* bbox always use stdin/stdout */
     308#define ifd STDIN_FILENO    /* input file descriptor */
     309#define ofd STDOUT_FILENO   /* output file descriptor */
     310
     311#ifdef DEBUG
     312    unsigned insize;    /* valid bytes in l_buf */
     313#endif
     314    unsigned outcnt;    /* bytes in output buffer */
     315
     316    smallint eofile;    /* flag set at end of input file */
     317
     318/* ===========================================================================
     319 * Local data used by the "bit string" routines.
     320 */
     321
     322    unsigned short bi_buf;
     323
     324/* Output buffer. bits are inserted starting at the bottom (least significant
     325 * bits).
     326 */
     327
     328#undef BUF_SIZE
     329#define BUF_SIZE (8 * sizeof(G1.bi_buf))
     330/* Number of bits used within bi_buf. (bi_buf might be implemented on
     331 * more than 16 bits on some systems.)
     332 */
     333
     334    int bi_valid;
     335
     336/* Current input function. Set to mem_read for in-memory compression */
     337
     338#ifdef DEBUG
     339    ulg bits_sent;          /* bit length of the compressed data */
     340#endif
     341
     342    uint32_t *crc_32_tab;
     343    uint32_t crc;   /* shift register contents */
    743344};
    744345
    745 #define EQUAL 0
    746 /* result of memcmp for equal strings */
    747 
    748 /* ===========================================================================
    749  *  Prototypes for local functions.
    750  */
    751 static void fill_window(void);
    752 
    753 static int longest_match(IPos cur_match);
    754 
     346#define G1 (*(ptr_to_globals - 1))
     347
     348
     349/* ===========================================================================
     350 * Write the output buffer outbuf[0..outcnt-1] and update bytes_out.
     351 * (used for the compressed data only)
     352 */
     353static void flush_outbuf(void)
     354{
     355    if (G1.outcnt == 0)
     356        return;
     357
     358    xwrite(ofd, (char *) G1.outbuf, G1.outcnt);
     359    G1.outcnt = 0;
     360}
     361
     362
     363/* ===========================================================================
     364 */
     365/* put_8bit is used for the compressed output */
     366#define put_8bit(c) \
     367do { \
     368    G1.outbuf[G1.outcnt++] = (c); \
     369    if (G1.outcnt == OUTBUFSIZ) flush_outbuf(); \
     370} while (0)
     371
     372/* Output a 16 bit value, lsb first */
     373static void put_16bit(ush w)
     374{
     375    if (G1.outcnt < OUTBUFSIZ - 2) {
     376        G1.outbuf[G1.outcnt++] = w;
     377        G1.outbuf[G1.outcnt++] = w >> 8;
     378    } else {
     379        put_8bit(w);
     380        put_8bit(w >> 8);
     381    }
     382}
     383
     384static void put_32bit(ulg n)
     385{
     386    put_16bit(n);
     387    put_16bit(n >> 16);
     388}
     389
     390/* ===========================================================================
     391 * Clear input and output buffers
     392 */
     393static void clear_bufs(void)
     394{
     395    G1.outcnt = 0;
    755396#ifdef DEBUG
    756 static void check_match(IPos start, IPos match, int length);
    757 #endif
    758 
    759 /* ===========================================================================
    760  * Update a hash value with the given input byte
    761  * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
    762  *    input characters, so that a running hash key can be computed from the
    763  *    previous key instead of complete recalculation each time.
    764  */
    765 #define UPDATE_HASH(h,c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
    766 
    767 /* ===========================================================================
    768  * Insert string s in the dictionary and set match_head to the previous head
    769  * of the hash chain (the most recent string with same hash key). Return
    770  * the previous length of the hash chain.
    771  * IN  assertion: all calls to to INSERT_STRING are made with consecutive
    772  *    input characters and the first MIN_MATCH bytes of s are valid
    773  *    (except for the last MIN_MATCH-1 bytes of the input file).
    774  */
    775 #define INSERT_STRING(s, match_head) \
    776    (UPDATE_HASH(ins_h, window[(s) + MIN_MATCH-1]), \
    777     prev[(s) & WMASK] = match_head = head[ins_h], \
    778     head[ins_h] = (s))
    779 
    780 /* ===========================================================================
    781  * Initialize the "longest match" routines for a new file
    782  */
    783 static void lm_init(ush * flags)
    784 {
    785     register unsigned j;
    786 
    787     /* Initialize the hash table. */
    788     memset(head, 0, HASH_SIZE * sizeof(*head));
    789     /* prev will be initialized on the fly */
    790 
    791     *flags |= SLOW;
    792     /* ??? reduce max_chain_length for binary files */
    793 
    794     strstart = 0;
    795     block_start = 0L;
    796 
    797     lookahead = read_buf((char *) window,
    798                          sizeof(int) <= 2 ? (unsigned) WSIZE : 2 * WSIZE);
    799 
    800     if (lookahead == 0 || lookahead == (unsigned) EOF) {
    801         eofile = 1, lookahead = 0;
    802         return;
    803     }
    804     eofile = 0;
    805     /* Make sure that we always have enough lookahead. This is important
    806      * if input comes from a device such as a tty.
    807      */
    808     while (lookahead < MIN_LOOKAHEAD && !eofile)
    809         fill_window();
    810 
    811     ins_h = 0;
    812     for (j = 0; j < MIN_MATCH - 1; j++)
    813         UPDATE_HASH(ins_h, window[j]);
    814     /* If lookahead < MIN_MATCH, ins_h is garbage, but this is
    815      * not important since only literal bytes will be emitted.
    816      */
    817 }
     397    G1.insize = 0;
     398#endif
     399    G1.isize = 0;
     400}
     401
     402
     403/* ===========================================================================
     404 * Run a set of bytes through the crc shift register.  If s is a NULL
     405 * pointer, then initialize the crc shift register contents instead.
     406 * Return the current crc in either case.
     407 */
     408static uint32_t updcrc(uch * s, unsigned n)
     409{
     410    uint32_t c = G1.crc;
     411    while (n) {
     412        c = G1.crc_32_tab[(uch)(c ^ *s++)] ^ (c >> 8);
     413        n--;
     414    }
     415    G1.crc = c;
     416    return c;
     417}
     418
     419
     420/* ===========================================================================
     421 * Read a new buffer from the current input file, perform end-of-line
     422 * translation, and update the crc and input file size.
     423 * IN assertion: size >= 2 (for end-of-line translation)
     424 */
     425static unsigned file_read(void *buf, unsigned size)
     426{
     427    unsigned len;
     428
     429    Assert(G1.insize == 0, "l_buf not empty");
     430
     431    len = safe_read(ifd, buf, size);
     432    if (len == (unsigned)(-1) || len == 0)
     433        return len;
     434
     435    updcrc(buf, len);
     436    G1.isize += len;
     437    return len;
     438}
     439
     440
     441/* ===========================================================================
     442 * Send a value on a given number of bits.
     443 * IN assertion: length <= 16 and value fits in length bits.
     444 */
     445static void send_bits(int value, int length)
     446{
     447#ifdef DEBUG
     448    Tracev((stderr, " l %2d v %4x ", length, value));
     449    Assert(length > 0 && length <= 15, "invalid length");
     450    G1.bits_sent += length;
     451#endif
     452    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
     453     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
     454     * unused bits in value.
     455     */
     456    if (G1.bi_valid > (int) BUF_SIZE - length) {
     457        G1.bi_buf |= (value << G1.bi_valid);
     458        put_16bit(G1.bi_buf);
     459        G1.bi_buf = (ush) value >> (BUF_SIZE - G1.bi_valid);
     460        G1.bi_valid += length - BUF_SIZE;
     461    } else {
     462        G1.bi_buf |= value << G1.bi_valid;
     463        G1.bi_valid += length;
     464    }
     465}
     466
     467
     468/* ===========================================================================
     469 * Reverse the first len bits of a code, using straightforward code (a faster
     470 * method would use a table)
     471 * IN assertion: 1 <= len <= 15
     472 */
     473static unsigned bi_reverse(unsigned code, int len)
     474{
     475    unsigned res = 0;
     476
     477    while (1) {
     478        res |= code & 1;
     479        if (--len <= 0) return res;
     480        code >>= 1;
     481        res <<= 1;
     482    }
     483}
     484
     485
     486/* ===========================================================================
     487 * Write out any remaining bits in an incomplete byte.
     488 */
     489static void bi_windup(void)
     490{
     491    if (G1.bi_valid > 8) {
     492        put_16bit(G1.bi_buf);
     493    } else if (G1.bi_valid > 0) {
     494        put_8bit(G1.bi_buf);
     495    }
     496    G1.bi_buf = 0;
     497    G1.bi_valid = 0;
     498#ifdef DEBUG
     499    G1.bits_sent = (G1.bits_sent + 7) & ~7;
     500#endif
     501}
     502
     503
     504/* ===========================================================================
     505 * Copy a stored block to the zip file, storing first the length and its
     506 * one's complement if requested.
     507 */
     508static void copy_block(char *buf, unsigned len, int header)
     509{
     510    bi_windup();        /* align on byte boundary */
     511
     512    if (header) {
     513        put_16bit(len);
     514        put_16bit(~len);
     515#ifdef DEBUG
     516        G1.bits_sent += 2 * 16;
     517#endif
     518    }
     519#ifdef DEBUG
     520    G1.bits_sent += (ulg) len << 3;
     521#endif
     522    while (len--) {
     523        put_8bit(*buf++);
     524    }
     525}
     526
     527
     528/* ===========================================================================
     529 * Fill the window when the lookahead becomes insufficient.
     530 * Updates strstart and lookahead, and sets eofile if end of input file.
     531 * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
     532 * OUT assertions: at least one byte has been read, or eofile is set;
     533 *    file reads are performed for at least two bytes (required for the
     534 *    translate_eol option).
     535 */
     536static void fill_window(void)
     537{
     538    unsigned n, m;
     539    unsigned more = WINDOW_SIZE - G1.lookahead - G1.strstart;
     540    /* Amount of free space at the end of the window. */
     541
     542    /* If the window is almost full and there is insufficient lookahead,
     543     * move the upper half to the lower one to make room in the upper half.
     544     */
     545    if (more == (unsigned) -1) {
     546        /* Very unlikely, but possible on 16 bit machine if strstart == 0
     547         * and lookahead == 1 (input done one byte at time)
     548         */
     549        more--;
     550    } else if (G1.strstart >= WSIZE + MAX_DIST) {
     551        /* By the IN assertion, the window is not empty so we can't confuse
     552         * more == 0 with more == 64K on a 16 bit machine.
     553         */
     554        Assert(WINDOW_SIZE == 2 * WSIZE, "no sliding with BIG_MEM");
     555
     556        memcpy(G1.window, G1.window + WSIZE, WSIZE);
     557        G1.match_start -= WSIZE;
     558        G1.strstart -= WSIZE;   /* we now have strstart >= MAX_DIST: */
     559
     560        G1.block_start -= WSIZE;
     561
     562        for (n = 0; n < HASH_SIZE; n++) {
     563            m = head[n];
     564            head[n] = (Pos) (m >= WSIZE ? m - WSIZE : 0);
     565        }
     566        for (n = 0; n < WSIZE; n++) {
     567            m = G1.prev[n];
     568            G1.prev[n] = (Pos) (m >= WSIZE ? m - WSIZE : 0);
     569            /* If n is not on any hash chain, prev[n] is garbage but
     570             * its value will never be used.
     571             */
     572        }
     573        more += WSIZE;
     574    }
     575    /* At this point, more >= 2 */
     576    if (!G1.eofile) {
     577        n = file_read(G1.window + G1.strstart + G1.lookahead, more);
     578        if (n == 0 || n == (unsigned) -1) {
     579            G1.eofile = 1;
     580        } else {
     581            G1.lookahead += n;
     582        }
     583    }
     584}
     585
    818586
    819587/* ===========================================================================
     
    833601{
    834602    unsigned chain_length = max_chain_length;   /* max hash chain length */
    835     register uch *scan = window + strstart; /* current string */
    836     register uch *match;    /* matched string */
    837     register int len;   /* length of current match */
    838     int best_len = prev_length; /* best match length so far */
    839     IPos limit =
    840         strstart > (IPos) MAX_DIST ? strstart - (IPos) MAX_DIST : NIL;
     603    uch *scan = G1.window + G1.strstart;    /* current string */
     604    uch *match; /* matched string */
     605    int len;    /* length of current match */
     606    int best_len = G1.prev_length;  /* best match length so far */
     607    IPos limit = G1.strstart > (IPos) MAX_DIST ? G1.strstart - (IPos) MAX_DIST : 0;
    841608    /* Stop when cur_match becomes <= limit. To simplify the code,
    842609     * we prevent matches with the string of window index 0.
     
    849616#  error Code too clever
    850617#endif
    851     register uch *strend = window + strstart + MAX_MATCH;
    852     register uch scan_end1 = scan[best_len - 1];
    853     register uch scan_end = scan[best_len];
     618    uch *strend = G1.window + G1.strstart + MAX_MATCH;
     619    uch scan_end1 = scan[best_len - 1];
     620    uch scan_end = scan[best_len];
    854621
    855622    /* Do not waste too much time if we already have a good match: */
    856     if (prev_length >= good_match) {
     623    if (G1.prev_length >= good_match) {
    857624        chain_length >>= 2;
    858625    }
    859     Assert(strstart <= window_size - MIN_LOOKAHEAD, "insufficient lookahead");
     626    Assert(G1.strstart <= WINDOW_SIZE - MIN_LOOKAHEAD, "insufficient lookahead");
    860627
    861628    do {
    862         Assert(cur_match < strstart, "no future");
    863         match = window + cur_match;
     629        Assert(cur_match < G1.strstart, "no future");
     630        match = G1.window + cur_match;
    864631
    865632        /* Skip to next match if the match length cannot increase
     
    892659
    893660        if (len > best_len) {
    894             match_start = cur_match;
     661            G1.match_start = cur_match;
    895662            best_len = len;
    896663            if (len >= nice_match)
     
    899666            scan_end = scan[best_len];
    900667        }
    901     } while ((cur_match = prev[cur_match & WMASK]) > limit
     668    } while ((cur_match = G1.prev[cur_match & WMASK]) > limit
    902669             && --chain_length != 0);
    903670
     
    905672}
    906673
     674
    907675#ifdef DEBUG
    908676/* ===========================================================================
     
    912680{
    913681    /* check that the match is indeed a match */
    914     if (memcmp((char *) window + match,
    915                (char *) window + start, length) != EQUAL) {
     682    if (memcmp(G1.window + match, G1.window + start, length) != 0) {
    916683        bb_error_msg(" start %d, match %d, length %d", start, match, length);
    917684        bb_error_msg("invalid match");
     
    920687        bb_error_msg("\\[%d,%d]", start - match, length);
    921688        do {
    922             putc(window[start++], stderr);
     689            putc(G1.window[start++], stderr);
    923690        } while (--length != 0);
    924691    }
    925692}
    926693#else
    927 #  define check_match(start, match, length)
    928 #endif
    929 
    930 /* ===========================================================================
    931  * Fill the window when the lookahead becomes insufficient.
    932  * Updates strstart and lookahead, and sets eofile if end of input file.
    933  * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
    934  * OUT assertions: at least one byte has been read, or eofile is set;
    935  *    file reads are performed for at least two bytes (required for the
    936  *    translate_eol option).
    937  */
    938 static void fill_window(void)
    939 {
    940     register unsigned n, m;
    941     unsigned more =
    942         (unsigned) (window_size - (ulg) lookahead - (ulg) strstart);
    943     /* Amount of free space at the end of the window. */
    944 
    945     /* If the window is almost full and there is insufficient lookahead,
    946      * move the upper half to the lower one to make room in the upper half.
    947      */
    948     if (more == (unsigned) EOF) {
    949         /* Very unlikely, but possible on 16 bit machine if strstart == 0
    950          * and lookahead == 1 (input done one byte at time)
    951          */
    952         more--;
    953     } else if (strstart >= WSIZE + MAX_DIST) {
    954         /* By the IN assertion, the window is not empty so we can't confuse
    955          * more == 0 with more == 64K on a 16 bit machine.
    956          */
    957         Assert(window_size == (ulg) 2 * WSIZE, "no sliding with BIG_MEM");
    958 
    959         memcpy((char *) window, (char *) window + WSIZE, (unsigned) WSIZE);
    960         match_start -= WSIZE;
    961         strstart -= WSIZE;  /* we now have strstart >= MAX_DIST: */
    962 
    963         block_start -= (long) WSIZE;
    964 
    965         for (n = 0; n < HASH_SIZE; n++) {
    966             m = head[n];
    967             head[n] = (Pos) (m >= WSIZE ? m - WSIZE : NIL);
    968         }
    969         for (n = 0; n < WSIZE; n++) {
    970             m = prev[n];
    971             prev[n] = (Pos) (m >= WSIZE ? m - WSIZE : NIL);
    972             /* If n is not on any hash chain, prev[n] is garbage but
    973              * its value will never be used.
    974              */
    975         }
    976         more += WSIZE;
    977     }
    978     /* At this point, more >= 2 */
    979     if (!eofile) {
    980         n = read_buf((char *) window + strstart + lookahead, more);
    981         if (n == 0 || n == (unsigned) EOF) {
    982             eofile = 1;
    983         } else {
    984             lookahead += n;
    985         }
    986     }
    987 }
    988 
    989 /* ===========================================================================
    990  * Flush the current block, with given end-of-file flag.
    991  * IN assertion: strstart is set to the end of the current match.
    992  */
    993 #define FLUSH_BLOCK(eof) \
    994    flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : \
    995         (char*)NULL, (long)strstart - block_start, (eof))
    996 
    997 /* ===========================================================================
    998  * Same as above, but achieves better compression. We use a lazy
    999  * evaluation for matches: a match is finally adopted only if there is
    1000  * no better match at the next window position.
    1001  */
    1002 static ulg deflate(void)
    1003 {
    1004     IPos hash_head;     /* head of hash chain */
    1005     IPos prev_match;    /* previous match */
    1006     int flush;          /* set if current block must be flushed */
    1007     int match_available = 0;    /* set if previous match exists */
    1008     register unsigned match_length = MIN_MATCH - 1; /* length of best match */
    1009 
    1010     /* Process the input block. */
    1011     while (lookahead != 0) {
    1012         /* Insert the string window[strstart .. strstart+2] in the
    1013          * dictionary, and set hash_head to the head of the hash chain:
    1014          */
    1015         INSERT_STRING(strstart, hash_head);
    1016 
    1017         /* Find the longest match, discarding those <= prev_length.
    1018          */
    1019         prev_length = match_length, prev_match = match_start;
    1020         match_length = MIN_MATCH - 1;
    1021 
    1022         if (hash_head != NIL && prev_length < max_lazy_match &&
    1023             strstart - hash_head <= MAX_DIST) {
    1024             /* To simplify the code, we prevent matches with the string
    1025              * of window index 0 (in particular we have to avoid a match
    1026              * of the string with itself at the start of the input file).
    1027              */
    1028             match_length = longest_match(hash_head);
    1029             /* longest_match() sets match_start */
    1030             if (match_length > lookahead)
    1031                 match_length = lookahead;
    1032 
    1033             /* Ignore a length 3 match if it is too distant: */
    1034             if (match_length == MIN_MATCH && strstart - match_start > TOO_FAR) {
    1035                 /* If prev_match is also MIN_MATCH, match_start is garbage
    1036                  * but we will ignore the current match anyway.
    1037                  */
    1038                 match_length--;
    1039             }
    1040         }
    1041         /* If there was a match at the previous step and the current
    1042          * match is not better, output the previous match:
    1043          */
    1044         if (prev_length >= MIN_MATCH && match_length <= prev_length) {
    1045 
    1046             check_match(strstart - 1, prev_match, prev_length);
    1047 
    1048             flush =
    1049                 ct_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
    1050 
    1051             /* Insert in hash table all strings up to the end of the match.
    1052              * strstart-1 and strstart are already inserted.
    1053              */
    1054             lookahead -= prev_length - 1;
    1055             prev_length -= 2;
    1056             do {
    1057                 strstart++;
    1058                 INSERT_STRING(strstart, hash_head);
    1059                 /* strstart never exceeds WSIZE-MAX_MATCH, so there are
    1060                  * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
    1061                  * these bytes are garbage, but it does not matter since the
    1062                  * next lookahead bytes will always be emitted as literals.
    1063                  */
    1064             } while (--prev_length != 0);
    1065             match_available = 0;
    1066             match_length = MIN_MATCH - 1;
    1067             strstart++;
    1068             if (flush)
    1069                 FLUSH_BLOCK(0), block_start = strstart;
    1070 
    1071         } else if (match_available) {
    1072             /* If there was no match at the previous position, output a
    1073              * single literal. If there was a match but the current match
    1074              * is longer, truncate the previous match to a single literal.
    1075              */
    1076             Tracevv((stderr, "%c", window[strstart - 1]));
    1077             if (ct_tally(0, window[strstart - 1])) {
    1078                 FLUSH_BLOCK(0), block_start = strstart;
    1079             }
    1080             strstart++;
    1081             lookahead--;
    1082         } else {
    1083             /* There is no previous match to compare with, wait for
    1084              * the next step to decide.
    1085              */
    1086             match_available = 1;
    1087             strstart++;
    1088             lookahead--;
    1089         }
    1090         Assert(strstart <= isize && lookahead <= isize, "a bit too far");
    1091 
    1092         /* Make sure that we always have enough lookahead, except
    1093          * at the end of the input file. We need MAX_MATCH bytes
    1094          * for the next match, plus MIN_MATCH bytes to insert the
    1095          * string following the next match.
    1096          */
    1097         while (lookahead < MIN_LOOKAHEAD && !eofile)
    1098             fill_window();
    1099     }
    1100     if (match_available)
    1101         ct_tally(0, window[strstart - 1]);
    1102 
    1103     return FLUSH_BLOCK(1);  /* eof */
    1104 }
    1105 
    1106 /* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
    1107  * Copyright (C) 1992-1993 Jean-loup Gailly
    1108  * The unzip code was written and put in the public domain by Mark Adler.
    1109  * Portions of the lzw code are derived from the public domain 'compress'
    1110  * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
    1111  * Ken Turkowski, Dave Mack and Peter Jannesen.
    1112  *
    1113  * See the license_msg below and the file COPYING for the software license.
    1114  * See the file algorithm.doc for the compression algorithms and file formats.
    1115  */
    1116 
    1117 /* Compress files with zip algorithm and 'compress' interface.
    1118  * See usage() and help() functions below for all options.
    1119  * Outputs:
    1120  *        file.gz:   compressed file with same mode, owner, and utimes
    1121  *     or stdout with -c option or if stdin used as input.
    1122  * If the output file name had to be truncated, the original name is kept
    1123  * in the compressed file.
    1124  */
    1125 
    1126         /* configuration */
    1127 
    1128 typedef struct dirent dir_type;
    1129 
    1130 /* ======================================================================== */
    1131 int gzip_main(int argc, char **argv)
    1132 {
    1133     int result;
    1134     int inFileNum;
    1135     int outFileNum;
    1136     struct stat statBuf;
    1137     char *delFileName;
    1138     int tostdout = 0;
    1139     int force = 0;
    1140     int opt;
    1141 
    1142     while ((opt = getopt(argc, argv, "cf123456789dq")) != -1) {
    1143         switch (opt) {
    1144         case 'c':
    1145             tostdout = 1;
    1146             break;
    1147         case 'f':
    1148             force = 1;
    1149             break;
    1150             /* Ignore 1-9 (compression level) options */
    1151         case '1':
    1152         case '2':
    1153         case '3':
    1154         case '4':
    1155         case '5':
    1156         case '6':
    1157         case '7':
    1158         case '8':
    1159         case '9':
    1160             break;
    1161         case 'q':
    1162             break;
    1163 #ifdef CONFIG_GUNZIP
    1164         case 'd':
    1165             optind = 1;
    1166             return gunzip_main(argc, argv);
    1167 #endif
    1168         default:
    1169             bb_show_usage();
    1170         }
    1171     }
    1172 
    1173     foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
    1174     if (foreground) {
    1175         (void) signal(SIGINT, abort_gzip);
    1176     }
    1177 #ifdef SIGTERM
    1178     if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
    1179         (void) signal(SIGTERM, abort_gzip);
    1180     }
    1181 #endif
    1182 #ifdef SIGHUP
    1183     if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
    1184         (void) signal(SIGHUP, abort_gzip);
    1185     }
    1186 #endif
    1187 
    1188     strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix) - 1);
    1189     z_len = strlen(z_suffix);
    1190 
    1191     /* Allocate all global buffers (for DYN_ALLOC option) */
    1192     ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA);
    1193     ALLOC(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA);
    1194     ALLOC(ush, d_buf, DIST_BUFSIZE);
    1195     ALLOC(uch, window, 2L * WSIZE);
    1196     ALLOC(ush, tab_prefix, 1L << BITS);
    1197 
    1198     /* Initialise the CRC32 table */
    1199     crc_32_tab = bb_crc32_filltable(0);
    1200    
    1201     clear_bufs();
    1202     part_nb = 0;
    1203 
    1204     if (optind == argc) {
    1205         time_stamp = 0;
    1206         ifile_size = -1L;
    1207         zip(STDIN_FILENO, STDOUT_FILENO);
    1208     } else {
    1209         int i;
    1210 
    1211         for (i = optind; i < argc; i++) {
    1212             char *path = NULL;
    1213 
    1214             clear_bufs();
    1215             if (strcmp(argv[i], "-") == 0) {
    1216                 time_stamp = 0;
    1217                 ifile_size = -1L;
    1218                 inFileNum = STDIN_FILENO;
    1219                 outFileNum = STDOUT_FILENO;
    1220             } else {
    1221                 inFileNum = bb_xopen3(argv[i], O_RDONLY, 0);
    1222                 if (fstat(inFileNum, &statBuf) < 0)
    1223                     bb_perror_msg_and_die("%s", argv[i]);
    1224                 time_stamp = statBuf.st_ctime;
    1225                 ifile_size = statBuf.st_size;
    1226 
    1227                 if (!tostdout) {
    1228                     path = xmalloc(strlen(argv[i]) + 4);
    1229                     strcpy(path, argv[i]);
    1230                     strcat(path, ".gz");
    1231 
    1232                     /* Open output file */
    1233 #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) && defined O_NOFOLLOW
    1234                     outFileNum =
    1235                         open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW);
    1236 #else
    1237                     outFileNum = open(path, O_RDWR | O_CREAT | O_EXCL);
    1238 #endif
    1239                     if (outFileNum < 0) {
    1240                         bb_perror_msg("%s", path);
    1241                         free(path);
    1242                         continue;
    1243                     }
    1244 
    1245                     /* Set permissions on the file */
    1246                     fchmod(outFileNum, statBuf.st_mode);
    1247                 } else
    1248                     outFileNum = STDOUT_FILENO;
    1249             }
    1250 
    1251             if (path == NULL && isatty(outFileNum) && force == 0) {
    1252                 bb_error_msg
    1253                     ("compressed data not written to a terminal. Use -f to force compression.");
    1254                 free(path);
    1255                 continue;
    1256             }
    1257 
    1258             result = zip(inFileNum, outFileNum);
    1259 
    1260             if (path != NULL) {
    1261                 close(inFileNum);
    1262                 close(outFileNum);
    1263 
    1264                 /* Delete the original file */
    1265                 if (result == OK)
    1266                     delFileName = argv[i];
    1267                 else
    1268                     delFileName = path;
    1269 
    1270                 if (unlink(delFileName) < 0)
    1271                     bb_perror_msg("%s", delFileName);
    1272             }
    1273 
    1274             free(path);
    1275         }
    1276     }
    1277 
    1278     return (exit_code);
    1279 }
     694#  define check_match(start, match, length) ((void)0)
     695#endif
     696
    1280697
    1281698/* trees.c -- output deflated data using Huffman coding
     
    1285702 */
    1286703
    1287 /*
    1288  *  PURPOSE
    1289  *
     704/*  PURPOSE
    1290705 *      Encode various sets of source values using variable-length
    1291706 *      binary code trees.
    1292707 *
    1293708 *  DISCUSSION
    1294  *
    1295709 *      The PKZIP "deflation" process uses several Huffman trees. The more
    1296710 *      common source values are represented by shorter bit sequences.
     
    1304718 *
    1305719 *  REFERENCES
    1306  *
    1307720 *      Lynch, Thomas J.
    1308721 *          Data Compression:  Techniques and Applications, pp. 53-55.
     
    1318731 *
    1319732 *  INTERFACE
     733 *      void ct_init()
     734 *          Allocate the match buffer, initialize the various tables [and save
     735 *          the location of the internal file attribute (ascii/binary) and
     736 *          method (DEFLATE/STORE) -- deleted in bbox]
    1320737 *
    1321  *      void ct_init (ush *attr, int *methodp)
    1322  *          Allocate the match buffer, initialize the various tables and save
    1323  *          the location of the internal file attribute (ascii/binary) and
    1324  *          method (DEFLATE/STORE)
    1325  *
    1326  *      void ct_tally (int dist, int lc);
     738 *      void ct_tally(int dist, int lc);
    1327739 *          Save the match info and tally the frequency counts.
    1328740 *
    1329  *      long flush_block (char *buf, ulg stored_len, int eof)
     741 *      ulg flush_block(char *buf, ulg stored_len, int eof)
    1330742 *          Determine the best encoding for the current block: dynamic trees,
    1331743 *          static trees or store, and output the encoded block to the zip
    1332744 *          file. Returns the total compressed length for the file so far.
    1333  *
    1334  */
    1335 
    1336 /* ===========================================================================
    1337  * Constants
    1338745 */
    1339746
     
    1362769/* number of codes used to transfer the bit lengths */
    1363770
    1364 typedef uch extra_bits_t;
    1365 
    1366771/* extra bits for each length code */
    1367 static const extra_bits_t extra_lbits[LENGTH_CODES]
    1368     = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
     772static const uint8_t extra_lbits[LENGTH_CODES] ALIGN1 = {
     773    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
    1369774    4, 4, 5, 5, 5, 5, 0
    1370775};
    1371776
    1372777/* extra bits for each distance code */
    1373 static const extra_bits_t extra_dbits[D_CODES]
    1374     = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
     778static const uint8_t extra_dbits[D_CODES] ALIGN1 = {
     779    0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
    1375780    10, 10, 11, 11, 12, 12, 13, 13
    1376781};
    1377782
    1378783/* extra bits for each bit length code */
    1379 static const extra_bits_t extra_blbits[BL_CODES]
    1380 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 };
     784static const uint8_t extra_blbits[BL_CODES] ALIGN1 = {
     785    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 };
     786
     787/* number of codes at each bit length for an optimal tree */
     788static const uint8_t bl_order[BL_CODES] ALIGN1 = {
     789    16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
    1381790
    1382791#define STORED_BLOCK 0
     
    1419828 * if we rely on DIST_BUFSIZE == LIT_BUFSIZE.
    1420829 */
    1421 #if LIT_BUFSIZE > INBUFSIZ
    1422 #error cannot overlay l_buf and inbuf
    1423 #endif
    1424830#define REP_3_6      16
    1425831/* repeat previous bit length 3-6 times (2 bits of repeat count) */
     
    1430836
    1431837/* ===========================================================================
    1432  * Local data
    1433  */
    1434 
     838*/
    1435839/* Data structure describing a single value and its code string. */
    1436840typedef struct ct_data {
     
    1450854#define Len  dl.len
    1451855
    1452 #define HEAP_SIZE (2*L_CODES+1)
     856#define HEAP_SIZE (2*L_CODES + 1)
    1453857/* maximum heap size */
    1454 
    1455 static ct_data dyn_ltree[HEAP_SIZE];    /* literal and length tree */
    1456 static ct_data dyn_dtree[2 * D_CODES + 1];  /* distance tree */
    1457 
    1458 static ct_data static_ltree[L_CODES + 2];
    1459 
    1460 /* The static literal tree. Since the bit lengths are imposed, there is no
    1461  * need for the L_CODES extra codes used during heap construction. However
    1462  * The codes 286 and 287 are needed to build a canonical tree (see ct_init
    1463  * below).
    1464  */
    1465 
    1466 static ct_data static_dtree[D_CODES];
    1467 
    1468 /* The static distance tree. (Actually a trivial tree since all codes use
    1469  * 5 bits.)
    1470  */
    1471 
    1472 static ct_data bl_tree[2 * BL_CODES + 1];
    1473 
    1474 /* Huffman tree for the bit lengths */
    1475858
    1476859typedef struct tree_desc {
    1477860    ct_data *dyn_tree;  /* the dynamic tree */
    1478861    ct_data *static_tree;   /* corresponding static tree or NULL */
    1479     const extra_bits_t *extra_bits; /* extra bits for each code or NULL */
     862    const uint8_t *extra_bits;  /* extra bits for each code or NULL */
    1480863    int extra_base;     /* base index for extra_bits */
    1481864    int elems;          /* max number of elements in the tree */
     
    1484867} tree_desc;
    1485868
    1486 static tree_desc l_desc =
    1487     { dyn_ltree, static_ltree, extra_lbits, LITERALS + 1, L_CODES,
    1488     MAX_BITS, 0
    1489 };
    1490 
    1491 static tree_desc d_desc =
    1492     { dyn_dtree, static_dtree, extra_dbits, 0, D_CODES, MAX_BITS, 0 };
    1493 
    1494 static tree_desc bl_desc =
    1495     { bl_tree, (ct_data *) 0, extra_blbits, 0, BL_CODES, MAX_BL_BITS,
    1496     0
    1497 };
    1498 
    1499 
    1500 static ush bl_count[MAX_BITS + 1];
    1501 
    1502 /* number of codes at each bit length for an optimal tree */
    1503 
    1504 static const uch bl_order[BL_CODES]
    1505 = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
     869struct globals2 {
     870
     871    ush heap[HEAP_SIZE];     /* heap used to build the Huffman trees */
     872    int heap_len;            /* number of elements in the heap */
     873    int heap_max;            /* element of largest frequency */
     874
     875/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
     876 * The same heap array is used to build all trees.
     877 */
     878
     879    ct_data dyn_ltree[HEAP_SIZE];   /* literal and length tree */
     880    ct_data dyn_dtree[2 * D_CODES + 1]; /* distance tree */
     881
     882    ct_data static_ltree[L_CODES + 2];
     883
     884/* The static literal tree. Since the bit lengths are imposed, there is no
     885 * need for the L_CODES extra codes used during heap construction. However
     886 * The codes 286 and 287 are needed to build a canonical tree (see ct_init
     887 * below).
     888 */
     889
     890    ct_data static_dtree[D_CODES];
     891
     892/* The static distance tree. (Actually a trivial tree since all codes use
     893 * 5 bits.)
     894 */
     895
     896    ct_data bl_tree[2 * BL_CODES + 1];
     897
     898/* Huffman tree for the bit lengths */
     899
     900    tree_desc l_desc;
     901    tree_desc d_desc;
     902    tree_desc bl_desc;
     903
     904    ush bl_count[MAX_BITS + 1];
    1506905
    1507906/* The lengths of the bit length codes are sent in order of decreasing
     
    1509908 */
    1510909
    1511 static int heap[2 * L_CODES + 1];   /* heap used to build the Huffman trees */
    1512 static int heap_len;    /* number of elements in the heap */
    1513 static int heap_max;    /* element of largest frequency */
    1514 
    1515 /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
    1516  * The same heap array is used to build all trees.
    1517  */
    1518 
    1519 static uch depth[2 * L_CODES + 1];
     910    uch depth[2 * L_CODES + 1];
    1520911
    1521912/* Depth of each subtree used as tie breaker for trees of equal frequency */
    1522913
    1523 static uch length_code[MAX_MATCH - MIN_MATCH + 1];
     914    uch length_code[MAX_MATCH - MIN_MATCH + 1];
    1524915
    1525916/* length code for each normalized match length (0 == MIN_MATCH) */
    1526917
    1527 static uch dist_code[512];
     918    uch dist_code[512];
    1528919
    1529920/* distance codes. The first 256 values correspond to the distances
     
    1532923 */
    1533924
    1534 static int base_length[LENGTH_CODES];
     925    int base_length[LENGTH_CODES];
    1535926
    1536927/* First normalized length for each code (0 = MIN_MATCH) */
    1537928
    1538 static int base_dist[D_CODES];
     929    int base_dist[D_CODES];
    1539930
    1540931/* First normalized distance for each code (0 = distance of 1) */
    1541932
    1542 #define l_buf inbuf
    1543 /* DECLARE(uch, l_buf, LIT_BUFSIZE);  buffer for literals or lengths */
    1544 
    1545 /* DECLARE(ush, d_buf, DIST_BUFSIZE); buffer for distances */
    1546 
    1547 static uch flag_buf[(LIT_BUFSIZE / 8)];
     933    uch flag_buf[LIT_BUFSIZE / 8];
    1548934
    1549935/* flag_buf is a bit array distinguishing literals from lengths in
     
    1551937 */
    1552938
    1553 static unsigned last_lit;   /* running index in l_buf */
    1554 static unsigned last_dist;  /* running index in d_buf */
    1555 static unsigned last_flags; /* running index in flag_buf */
    1556 static uch flags;       /* current flags not yet saved in flag_buf */
    1557 static uch flag_bit;    /* current bit used in flags */
     939    unsigned last_lit;       /* running index in l_buf */
     940    unsigned last_dist;      /* running index in d_buf */
     941    unsigned last_flags;     /* running index in flag_buf */
     942    uch flags;               /* current flags not yet saved in flag_buf */
     943    uch flag_bit;            /* current bit used in flags */
    1558944
    1559945/* bits are filled in flags starting at bit 0 (least significant).
     
    1562948 */
    1563949
    1564 static ulg opt_len;     /* bit length of current block with optimal trees */
    1565 static ulg static_len;  /* bit length of current block with static trees */
    1566 
    1567 static ulg compressed_len;  /* total bit length of compressed file */
    1568 
    1569 
    1570 static ush *file_type;  /* pointer to UNKNOWN, BINARY or ASCII */
    1571 static int *file_method;    /* pointer to DEFLATE or STORE */
    1572 
    1573 /* ===========================================================================
    1574  * Local (static) routines in this file.
    1575  */
    1576 
    1577 static void init_block(void);
    1578 static void pqdownheap(ct_data * tree, int k);
    1579 static void gen_bitlen(tree_desc * desc);
     950    ulg opt_len;             /* bit length of current block with optimal trees */
     951    ulg static_len;          /* bit length of current block with static trees */
     952
     953    ulg compressed_len;      /* total bit length of compressed file */
     954};
     955
     956#define G2ptr ((struct globals2*)(ptr_to_globals))
     957#define G2 (*G2ptr)
     958
     959
     960/* ===========================================================================
     961 */
    1580962static void gen_codes(ct_data * tree, int max_code);
    1581963static void build_tree(tree_desc * desc);
     
    1585967static void send_all_trees(int lcodes, int dcodes, int blcodes);
    1586968static void compress_block(ct_data * ltree, ct_data * dtree);
    1587 static void set_file_type(void);
    1588969
    1589970
    1590971#ifndef DEBUG
    1591 #  define send_code(c, tree) send_bits(tree[c].Code, tree[c].Len)
    1592    /* Send a code of the given tree. c and tree must not have side effects */
    1593 
    1594 #else                           /* DEBUG */
    1595 #  define send_code(c, tree) \
    1596      { if (verbose>1) bb_error_msg("\ncd %3d ",(c)); \
    1597        send_bits(tree[c].Code, tree[c].Len); }
    1598 #endif
    1599 
    1600 #define d_code(dist) \
    1601    ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)])
     972/* Send a code of the given tree. c and tree must not have side effects */
     973#  define SEND_CODE(c, tree) send_bits(tree[c].Code, tree[c].Len)
     974#else
     975#  define SEND_CODE(c, tree) \
     976{ \
     977    if (verbose > 1) bb_error_msg("\ncd %3d ",(c)); \
     978    send_bits(tree[c].Code, tree[c].Len); \
     979}
     980#endif
     981
     982#define D_CODE(dist) \
     983    ((dist) < 256 ? G2.dist_code[dist] : G2.dist_code[256 + ((dist)>>7)])
    1602984/* Mapping from a distance to a distance code. dist is the distance - 1 and
    1603985 * must not have side effects. dist_code[256] and dist_code[257] are never
    1604986 * used.
    1605  */
    1606 
    1607 /* the arguments must not have side effects */
    1608 
    1609 /* ===========================================================================
    1610  * Allocate the match buffer, initialize the various tables and save the
    1611  * location of the internal file attribute (ascii/binary) and method
    1612  * (DEFLATE/STORE).
    1613  */
    1614 static void ct_init(ush * attr, int *methodp)
    1615 {
    1616     int n;              /* iterates over tree elements */
    1617     int bits;           /* bit counter */
    1618     int length;         /* length value */
    1619     int code;           /* code value */
    1620     int dist;           /* distance index */
    1621 
    1622     file_type = attr;
    1623     file_method = methodp;
    1624     compressed_len = 0L;
    1625 
    1626     if (static_dtree[0].Len != 0)
    1627         return;         /* ct_init already called */
    1628 
    1629     /* Initialize the mapping length (0..255) -> length code (0..28) */
    1630     length = 0;
    1631     for (code = 0; code < LENGTH_CODES - 1; code++) {
    1632         base_length[code] = length;
    1633         for (n = 0; n < (1 << extra_lbits[code]); n++) {
    1634             length_code[length++] = (uch) code;
    1635         }
    1636     }
    1637     Assert(length == 256, "ct_init: length != 256");
    1638     /* Note that the length 255 (match length 258) can be represented
    1639      * in two different ways: code 284 + 5 bits or code 285, so we
    1640      * overwrite length_code[255] to use the best encoding:
    1641      */
    1642     length_code[length - 1] = (uch) code;
    1643 
    1644     /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
    1645     dist = 0;
    1646     for (code = 0; code < 16; code++) {
    1647         base_dist[code] = dist;
    1648         for (n = 0; n < (1 << extra_dbits[code]); n++) {
    1649             dist_code[dist++] = (uch) code;
    1650         }
    1651     }
    1652     Assert(dist == 256, "ct_init: dist != 256");
    1653     dist >>= 7;         /* from now on, all distances are divided by 128 */
    1654     for (; code < D_CODES; code++) {
    1655         base_dist[code] = dist << 7;
    1656         for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
    1657             dist_code[256 + dist++] = (uch) code;
    1658         }
    1659     }
    1660     Assert(dist == 256, "ct_init: 256+dist != 512");
    1661 
    1662     /* Construct the codes of the static literal tree */
    1663     for (bits = 0; bits <= MAX_BITS; bits++)
    1664         bl_count[bits] = 0;
    1665     n = 0;
    1666     while (n <= 143)
    1667         static_ltree[n++].Len = 8, bl_count[8]++;
    1668     while (n <= 255)
    1669         static_ltree[n++].Len = 9, bl_count[9]++;
    1670     while (n <= 279)
    1671         static_ltree[n++].Len = 7, bl_count[7]++;
    1672     while (n <= 287)
    1673         static_ltree[n++].Len = 8, bl_count[8]++;
    1674     /* Codes 286 and 287 do not exist, but we must include them in the
    1675      * tree construction to get a canonical Huffman tree (longest code
    1676      * all ones)
    1677      */
    1678     gen_codes((ct_data *) static_ltree, L_CODES + 1);
    1679 
    1680     /* The static distance tree is trivial: */
    1681     for (n = 0; n < D_CODES; n++) {
    1682         static_dtree[n].Len = 5;
    1683         static_dtree[n].Code = bi_reverse(n, 5);
    1684     }
    1685 
    1686     /* Initialize the first block of the first file: */
    1687     init_block();
    1688 }
     987 * The arguments must not have side effects.
     988 */
     989
    1689990
    1690991/* ===========================================================================
     
    1693994static void init_block(void)
    1694995{
    1695     int n;              /* iterates over tree elements */
     996    int n; /* iterates over tree elements */
    1696997
    1697998    /* Initialize the trees. */
    1698999    for (n = 0; n < L_CODES; n++)
    1699         dyn_ltree[n].Freq = 0;
     1000        G2.dyn_ltree[n].Freq = 0;
    17001001    for (n = 0; n < D_CODES; n++)
    1701         dyn_dtree[n].Freq = 0;
     1002        G2.dyn_dtree[n].Freq = 0;
    17021003    for (n = 0; n < BL_CODES; n++)
    1703         bl_tree[n].Freq = 0;
    1704 
    1705     dyn_ltree[END_BLOCK].Freq = 1;
    1706     opt_len = static_len = 0L;
    1707     last_lit = last_dist = last_flags = 0;
    1708     flags = 0;
    1709     flag_bit = 1;
    1710 }
    1711 
    1712 #define SMALLEST 1
    1713 /* Index within the heap array of least frequent node in the Huffman tree */
    1714 
    1715 
    1716 /* ===========================================================================
    1717  * Remove the smallest element from the heap and recreate the heap with
    1718  * one less element. Updates heap and heap_len.
    1719  */
    1720 #define pqremove(tree, top) \
    1721 {\
    1722     top = heap[SMALLEST]; \
    1723     heap[SMALLEST] = heap[heap_len--]; \
    1724     pqdownheap(tree, SMALLEST); \
    1725 }
    1726 
    1727 /* ===========================================================================
    1728  * Compares to subtrees, using the tree depth as tie breaker when
    1729  * the subtrees have equal frequency. This minimizes the worst case length.
    1730  */
    1731 #define smaller(tree, n, m) \
    1732    (tree[n].Freq < tree[m].Freq || \
    1733    (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
     1004        G2.bl_tree[n].Freq = 0;
     1005
     1006    G2.dyn_ltree[END_BLOCK].Freq = 1;
     1007    G2.opt_len = G2.static_len = 0;
     1008    G2.last_lit = G2.last_dist = G2.last_flags = 0;
     1009    G2.flags = 0;
     1010    G2.flag_bit = 1;
     1011}
     1012
    17341013
    17351014/* ===========================================================================
     
    17391018 * two sons).
    17401019 */
     1020
     1021/* Compares to subtrees, using the tree depth as tie breaker when
     1022 * the subtrees have equal frequency. This minimizes the worst case length. */
     1023#define SMALLER(tree, n, m) \
     1024    (tree[n].Freq < tree[m].Freq \
     1025    || (tree[n].Freq == tree[m].Freq && G2.depth[n] <= G2.depth[m]))
     1026
    17411027static void pqdownheap(ct_data * tree, int k)
    17421028{
    1743     int v = heap[k];
     1029    int v = G2.heap[k];
    17441030    int j = k << 1;     /* left son of k */
    17451031
    1746     while (j <= heap_len) {
     1032    while (j <= G2.heap_len) {
    17471033        /* Set j to the smallest of the two sons: */
    1748         if (j < heap_len && smaller(tree, heap[j + 1], heap[j]))
     1034        if (j < G2.heap_len && SMALLER(tree, G2.heap[j + 1], G2.heap[j]))
    17491035            j++;
    17501036
    17511037        /* Exit if v is smaller than both sons */
    1752         if (smaller(tree, v, heap[j]))
     1038        if (SMALLER(tree, v, G2.heap[j]))
    17531039            break;
    17541040
    17551041        /* Exchange v with the smallest son */
    1756         heap[k] = heap[j];
     1042        G2.heap[k] = G2.heap[j];
    17571043        k = j;
    17581044
     
    17601046        j <<= 1;
    17611047    }
    1762     heap[k] = v;
    1763 }
     1048    G2.heap[k] = v;
     1049}
     1050
    17641051
    17651052/* ===========================================================================
     
    17761063{
    17771064    ct_data *tree = desc->dyn_tree;
    1778     const extra_bits_t *extra = desc->extra_bits;
     1065    const uint8_t *extra = desc->extra_bits;
    17791066    int base = desc->extra_base;
    17801067    int max_code = desc->max_code;
     
    17891076
    17901077    for (bits = 0; bits <= MAX_BITS; bits++)
    1791         bl_count[bits] = 0;
     1078        G2.bl_count[bits] = 0;
    17921079
    17931080    /* In a first pass, compute the optimal bit lengths (which may
    17941081     * overflow in the case of the bit length tree).
    17951082     */
    1796     tree[heap[heap_max]].Len = 0;   /* root of the heap */
    1797 
    1798     for (h = heap_max + 1; h < HEAP_SIZE; h++) {
    1799         n = heap[h];
     1083    tree[G2.heap[G2.heap_max]].Len = 0; /* root of the heap */
     1084
     1085    for (h = G2.heap_max + 1; h < HEAP_SIZE; h++) {
     1086        n = G2.heap[h];
    18001087        bits = tree[tree[n].Dad].Len + 1;
    1801         if (bits > max_length)
    1802             bits = max_length, overflow++;
     1088        if (bits > max_length) {
     1089            bits = max_length;
     1090            overflow++;
     1091        }
    18031092        tree[n].Len = (ush) bits;
    18041093        /* We overwrite tree[n].Dad which is no longer needed */
     
    18071096            continue;   /* not a leaf node */
    18081097
    1809         bl_count[bits]++;
     1098        G2.bl_count[bits]++;
    18101099        xbits = 0;
    18111100        if (n >= base)
    18121101            xbits = extra[n - base];
    18131102        f = tree[n].Freq;
    1814         opt_len += (ulg) f *(bits + xbits);
     1103        G2.opt_len += (ulg) f *(bits + xbits);
    18151104
    18161105        if (stree)
    1817             static_len += (ulg) f *(stree[n].Len + xbits);
     1106            G2.static_len += (ulg) f * (stree[n].Len + xbits);
    18181107    }
    18191108    if (overflow == 0)
     
    18261115    do {
    18271116        bits = max_length - 1;
    1828         while (bl_count[bits] == 0)
     1117        while (G2.bl_count[bits] == 0)
    18291118            bits--;
    1830         bl_count[bits]--;   /* move one leaf down the tree */
    1831         bl_count[bits + 1] += 2;    /* move one overflow item as its brother */
    1832         bl_count[max_length]--;
     1119        G2.bl_count[bits]--;    /* move one leaf down the tree */
     1120        G2.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
     1121        G2.bl_count[max_length]--;
    18331122        /* The brother of the overflow item also moves one step up,
    18341123         * but this does not affect bl_count[max_length]
     
    18431132     */
    18441133    for (bits = max_length; bits != 0; bits--) {
    1845         n = bl_count[bits];
     1134        n = G2.bl_count[bits];
    18461135        while (n != 0) {
    1847             m = heap[--h];
     1136            m = G2.heap[--h];
    18481137            if (m > max_code)
    18491138                continue;
    18501139            if (tree[m].Len != (unsigned) bits) {
    1851                 Trace((stderr, "code %d bits %d->%d\n", m, tree[m].Len,
    1852                        bits));
    1853                 opt_len +=
    1854                     ((long) bits - (long) tree[m].Len) * (long) tree[m].Freq;
    1855                 tree[m].Len = (ush) bits;
     1140                Trace((stderr, "code %d bits %d->%d\n", m, tree[m].Len, bits));
     1141                G2.opt_len += ((int32_t) bits - tree[m].Len) * tree[m].Freq;
     1142                tree[m].Len = bits;
    18561143            }
    18571144            n--;
     
    18591146    }
    18601147}
     1148
    18611149
    18621150/* ===========================================================================
     
    18791167     */
    18801168    for (bits = 1; bits <= MAX_BITS; bits++) {
    1881         next_code[bits] = code = (code + bl_count[bits - 1]) << 1;
     1169        next_code[bits] = code = (code + G2.bl_count[bits - 1]) << 1;
    18821170    }
    18831171    /* Check that the bit counts in bl_count are consistent. The last code
    18841172     * must be all ones.
    18851173     */
    1886     Assert(code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
     1174    Assert(code + G2.bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
    18871175           "inconsistent bit counts");
    18881176    Tracev((stderr, "\ngen_codes: max_code %d ", max_code));
     
    18961184        tree[n].Code = bi_reverse(next_code[len]++, len);
    18971185
    1898         Tracec(tree != static_ltree,
     1186        Tracec(tree != G2.static_ltree,
    18991187               (stderr, "\nn %3d %c l %2d c %4x (%x) ", n,
    19001188                (isgraph(n) ? n : ' '), len, tree[n].Code,
     
    19021190    }
    19031191}
     1192
    19041193
    19051194/* ===========================================================================
     
    19111200 *     also updated if stree is not null. The field max_code is set.
    19121201 */
     1202
     1203/* Remove the smallest element from the heap and recreate the heap with
     1204 * one less element. Updates heap and heap_len. */
     1205
     1206#define SMALLEST 1
     1207/* Index within the heap array of least frequent node in the Huffman tree */
     1208
     1209#define PQREMOVE(tree, top) \
     1210do { \
     1211    top = G2.heap[SMALLEST]; \
     1212    G2.heap[SMALLEST] = G2.heap[G2.heap_len--]; \
     1213    pqdownheap(tree, SMALLEST); \
     1214} while (0)
     1215
    19131216static void build_tree(tree_desc * desc)
    19141217{
     
    19241227     * heap[0] is not used.
    19251228     */
    1926     heap_len = 0, heap_max = HEAP_SIZE;
     1229    G2.heap_len = 0;
     1230    G2.heap_max = HEAP_SIZE;
    19271231
    19281232    for (n = 0; n < elems; n++) {
    19291233        if (tree[n].Freq != 0) {
    1930             heap[++heap_len] = max_code = n;
    1931             depth[n] = 0;
     1234            G2.heap[++G2.heap_len] = max_code = n;
     1235            G2.depth[n] = 0;
    19321236        } else {
    19331237            tree[n].Len = 0;
     
    19401244     * two codes of non zero frequency.
    19411245     */
    1942     while (heap_len < 2) {
    1943         int new = heap[++heap_len] = (max_code < 2 ? ++max_code : 0);
     1246    while (G2.heap_len < 2) {
     1247        int new = G2.heap[++G2.heap_len] = (max_code < 2 ? ++max_code : 0);
    19441248
    19451249        tree[new].Freq = 1;
    1946         depth[new] = 0;
    1947         opt_len--;
     1250        G2.depth[new] = 0;
     1251        G2.opt_len--;
    19481252        if (stree)
    1949             static_len -= stree[new].Len;
     1253            G2.static_len -= stree[new].Len;
    19501254        /* new is 0 or 1 so it does not have extra bits */
    19511255    }
     
    19551259     * establish sub-heaps of increasing lengths:
    19561260     */
    1957     for (n = heap_len / 2; n >= 1; n--)
     1261    for (n = G2.heap_len / 2; n >= 1; n--)
    19581262        pqdownheap(tree, n);
    19591263
     
    19621266     */
    19631267    do {
    1964         pqremove(tree, n);  /* n = node of least frequency */
    1965         m = heap[SMALLEST]; /* m = node of next least frequency */
    1966 
    1967         heap[--heap_max] = n;   /* keep the nodes sorted by frequency */
    1968         heap[--heap_max] = m;
     1268        PQREMOVE(tree, n);  /* n = node of least frequency */
     1269        m = G2.heap[SMALLEST];  /* m = node of next least frequency */
     1270
     1271        G2.heap[--G2.heap_max] = n; /* keep the nodes sorted by frequency */
     1272        G2.heap[--G2.heap_max] = m;
    19691273
    19701274        /* Create a new node father of n and m */
    19711275        tree[node].Freq = tree[n].Freq + tree[m].Freq;
    1972         depth[node] = (uch) (MAX(depth[n], depth[m]) + 1);
     1276        G2.depth[node] = MAX(G2.depth[n], G2.depth[m]) + 1;
    19731277        tree[n].Dad = tree[m].Dad = (ush) node;
    19741278#ifdef DUMP_BL_TREE
    1975         if (tree == bl_tree) {
     1279        if (tree == G2.bl_tree) {
    19761280            bb_error_msg("\nnode %d(%d), sons %d(%d) %d(%d)",
    19771281                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
     
    19791283#endif
    19801284        /* and insert the new node in the heap */
    1981         heap[SMALLEST] = node++;
     1285        G2.heap[SMALLEST] = node++;
    19821286        pqdownheap(tree, SMALLEST);
    19831287
    1984     } while (heap_len >= 2);
    1985 
    1986     heap[--heap_max] = heap[SMALLEST];
     1288    } while (G2.heap_len >= 2);
     1289
     1290    G2.heap[--G2.heap_max] = G2.heap[SMALLEST];
    19871291
    19881292    /* At this point, the fields freq and dad are set. We can now
     
    19941298    gen_codes((ct_data *) tree, max_code);
    19951299}
     1300
    19961301
    19971302/* ===========================================================================
     
    20111316    int min_count = 4;  /* min repeat count */
    20121317
    2013     if (nextlen == 0)
    2014         max_count = 138, min_count = 3;
    2015     tree[max_code + 1].Len = (ush) 0xffff;  /* guard */
     1318    if (nextlen == 0) {
     1319        max_count = 138;
     1320        min_count = 3;
     1321    }
     1322    tree[max_code + 1].Len = 0xffff; /* guard */
    20161323
    20171324    for (n = 0; n <= max_code; n++) {
    20181325        curlen = nextlen;
    20191326        nextlen = tree[n + 1].Len;
    2020         if (++count < max_count && curlen == nextlen) {
     1327        if (++count < max_count && curlen == nextlen)
    20211328            continue;
    2022         } else if (count < min_count) {
    2023             bl_tree[curlen].Freq += count;
     1329
     1330        if (count < min_count) {
     1331            G2.bl_tree[curlen].Freq += count;
    20241332        } else if (curlen != 0) {
    20251333            if (curlen != prevlen)
    2026                 bl_tree[curlen].Freq++;
    2027             bl_tree[REP_3_6].Freq++;
     1334                G2.bl_tree[curlen].Freq++;
     1335            G2.bl_tree[REP_3_6].Freq++;
    20281336        } else if (count <= 10) {
    2029             bl_tree[REPZ_3_10].Freq++;
     1337            G2.bl_tree[REPZ_3_10].Freq++;
    20301338        } else {
    2031             bl_tree[REPZ_11_138].Freq++;
     1339            G2.bl_tree[REPZ_11_138].Freq++;
    20321340        }
    20331341        count = 0;
    20341342        prevlen = curlen;
     1343
     1344        max_count = 7;
     1345        min_count = 4;
    20351346        if (nextlen == 0) {
    2036             max_count = 138, min_count = 3;
     1347            max_count = 138;
     1348            min_count = 3;
    20371349        } else if (curlen == nextlen) {
    2038             max_count = 6, min_count = 3;
    2039         } else {
    2040             max_count = 7, min_count = 4;
     1350            max_count = 6;
     1351            min_count = 3;
    20411352        }
    20421353    }
    20431354}
     1355
    20441356
    20451357/* ===========================================================================
     
    20681380        } else if (count < min_count) {
    20691381            do {
    2070                 send_code(curlen, bl_tree);
    2071             } while (--count != 0);
    2072 
     1382                SEND_CODE(curlen, G2.bl_tree);
     1383            } while (--count);
    20731384        } else if (curlen != 0) {
    20741385            if (curlen != prevlen) {
    2075                 send_code(curlen, bl_tree);
     1386                SEND_CODE(curlen, G2.bl_tree);
    20761387                count--;
    20771388            }
    20781389            Assert(count >= 3 && count <= 6, " 3_6?");
    2079             send_code(REP_3_6, bl_tree);
     1390            SEND_CODE(REP_3_6, G2.bl_tree);
    20801391            send_bits(count - 3, 2);
    2081 
    20821392        } else if (count <= 10) {
    2083             send_code(REPZ_3_10, bl_tree);
     1393            SEND_CODE(REPZ_3_10, G2.bl_tree);
    20841394            send_bits(count - 3, 3);
    2085 
    20861395        } else {
    2087             send_code(REPZ_11_138, bl_tree);
     1396            SEND_CODE(REPZ_11_138, G2.bl_tree);
    20881397            send_bits(count - 11, 7);
    20891398        }
     
    20911400        prevlen = curlen;
    20921401        if (nextlen == 0) {
    2093             max_count = 138, min_count = 3;
     1402            max_count = 138;
     1403            min_count = 3;
    20941404        } else if (curlen == nextlen) {
    2095             max_count = 6, min_count = 3;
     1405            max_count = 6;
     1406            min_count = 3;
    20961407        } else {
    2097             max_count = 7, min_count = 4;
     1408            max_count = 7;
     1409            min_count = 4;
    20981410        }
    20991411    }
    21001412}
     1413
    21011414
    21021415/* ===========================================================================
     
    21091422
    21101423    /* Determine the bit length frequencies for literal and distance trees */
    2111     scan_tree((ct_data *) dyn_ltree, l_desc.max_code);
    2112     scan_tree((ct_data *) dyn_dtree, d_desc.max_code);
     1424    scan_tree(G2.dyn_ltree, G2.l_desc.max_code);
     1425    scan_tree(G2.dyn_dtree, G2.d_desc.max_code);
    21131426
    21141427    /* Build the bit length tree: */
    2115     build_tree((tree_desc *) (&bl_desc));
     1428    build_tree(&G2.bl_desc);
    21161429    /* opt_len now includes the length of the tree representations, except
    21171430     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
     
    21231436     */
    21241437    for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
    2125         if (bl_tree[bl_order[max_blindex]].Len != 0)
     1438        if (G2.bl_tree[bl_order[max_blindex]].Len != 0)
    21261439            break;
    21271440    }
    21281441    /* Update opt_len to include the bit length tree and counts */
    2129     opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
    2130     Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", opt_len, static_len));
     1442    G2.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
     1443    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", G2.opt_len, G2.static_len));
    21311444
    21321445    return max_blindex;
    21331446}
     1447
    21341448
    21351449/* ===========================================================================
     
    21511465    for (rank = 0; rank < blcodes; rank++) {
    21521466        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
    2153         send_bits(bl_tree[bl_order[rank]].Len, 3);
    2154     }
    2155     Tracev((stderr, "\nbl tree: sent %ld", bits_sent));
    2156 
    2157     send_tree((ct_data *) dyn_ltree, lcodes - 1);   /* send the literal tree */
    2158     Tracev((stderr, "\nlit tree: sent %ld", bits_sent));
    2159 
    2160     send_tree((ct_data *) dyn_dtree, dcodes - 1);   /* send the distance tree */
    2161     Tracev((stderr, "\ndist tree: sent %ld", bits_sent));
    2162 }
     1467        send_bits(G2.bl_tree[bl_order[rank]].Len, 3);
     1468    }
     1469    Tracev((stderr, "\nbl tree: sent %ld", G1.bits_sent));
     1470
     1471    send_tree((ct_data *) G2.dyn_ltree, lcodes - 1);    /* send the literal tree */
     1472    Tracev((stderr, "\nlit tree: sent %ld", G1.bits_sent));
     1473
     1474    send_tree((ct_data *) G2.dyn_dtree, dcodes - 1);    /* send the distance tree */
     1475    Tracev((stderr, "\ndist tree: sent %ld", G1.bits_sent));
     1476}
     1477
     1478
     1479/* ===========================================================================
     1480 * Save the match info and tally the frequency counts. Return true if
     1481 * the current block must be flushed.
     1482 */
     1483static int ct_tally(int dist, int lc)
     1484{
     1485    G1.l_buf[G2.last_lit++] = lc;
     1486    if (dist == 0) {
     1487        /* lc is the unmatched char */
     1488        G2.dyn_ltree[lc].Freq++;
     1489    } else {
     1490        /* Here, lc is the match length - MIN_MATCH */
     1491        dist--;         /* dist = match distance - 1 */
     1492        Assert((ush) dist < (ush) MAX_DIST
     1493         && (ush) lc <= (ush) (MAX_MATCH - MIN_MATCH)
     1494         && (ush) D_CODE(dist) < (ush) D_CODES, "ct_tally: bad match"
     1495        );
     1496
     1497        G2.dyn_ltree[G2.length_code[lc] + LITERALS + 1].Freq++;
     1498        G2.dyn_dtree[D_CODE(dist)].Freq++;
     1499
     1500        G1.d_buf[G2.last_dist++] = dist;
     1501        G2.flags |= G2.flag_bit;
     1502    }
     1503    G2.flag_bit <<= 1;
     1504
     1505    /* Output the flags if they fill a byte: */
     1506    if ((G2.last_lit & 7) == 0) {
     1507        G2.flag_buf[G2.last_flags++] = G2.flags;
     1508        G2.flags = 0;
     1509        G2.flag_bit = 1;
     1510    }
     1511    /* Try to guess if it is profitable to stop the current block here */
     1512    if ((G2.last_lit & 0xfff) == 0) {
     1513        /* Compute an upper bound for the compressed length */
     1514        ulg out_length = G2.last_lit * 8L;
     1515        ulg in_length = (ulg) G1.strstart - G1.block_start;
     1516        int dcode;
     1517
     1518        for (dcode = 0; dcode < D_CODES; dcode++) {
     1519            out_length += G2.dyn_dtree[dcode].Freq * (5L + extra_dbits[dcode]);
     1520        }
     1521        out_length >>= 3;
     1522        Trace((stderr,
     1523               "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
     1524               G2.last_lit, G2.last_dist, in_length, out_length,
     1525               100L - out_length * 100L / in_length));
     1526        if (G2.last_dist < G2.last_lit / 2 && out_length < in_length / 2)
     1527            return 1;
     1528    }
     1529    return (G2.last_lit == LIT_BUFSIZE - 1 || G2.last_dist == DIST_BUFSIZE);
     1530    /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K
     1531     * on 16 bit machines and because stored blocks are restricted to
     1532     * 64K-1 bytes.
     1533     */
     1534}
     1535
     1536/* ===========================================================================
     1537 * Send the block data compressed using the given Huffman trees
     1538 */
     1539static void compress_block(ct_data * ltree, ct_data * dtree)
     1540{
     1541    unsigned dist;          /* distance of matched string */
     1542    int lc;                 /* match length or unmatched char (if dist == 0) */
     1543    unsigned lx = 0;        /* running index in l_buf */
     1544    unsigned dx = 0;        /* running index in d_buf */
     1545    unsigned fx = 0;        /* running index in flag_buf */
     1546    uch flag = 0;           /* current flags */
     1547    unsigned code;          /* the code to send */
     1548    int extra;              /* number of extra bits to send */
     1549
     1550    if (G2.last_lit != 0) do {
     1551        if ((lx & 7) == 0)
     1552            flag = G2.flag_buf[fx++];
     1553        lc = G1.l_buf[lx++];
     1554        if ((flag & 1) == 0) {
     1555            SEND_CODE(lc, ltree);   /* send a literal byte */
     1556            Tracecv(isgraph(lc), (stderr, " '%c' ", lc));
     1557        } else {
     1558            /* Here, lc is the match length - MIN_MATCH */
     1559            code = G2.length_code[lc];
     1560            SEND_CODE(code + LITERALS + 1, ltree);  /* send the length code */
     1561            extra = extra_lbits[code];
     1562            if (extra != 0) {
     1563                lc -= G2.base_length[code];
     1564                send_bits(lc, extra);   /* send the extra length bits */
     1565            }
     1566            dist = G1.d_buf[dx++];
     1567            /* Here, dist is the match distance - 1 */
     1568            code = D_CODE(dist);
     1569            Assert(code < D_CODES, "bad d_code");
     1570
     1571            SEND_CODE(code, dtree); /* send the distance code */
     1572            extra = extra_dbits[code];
     1573            if (extra != 0) {
     1574                dist -= G2.base_dist[code];
     1575                send_bits(dist, extra); /* send the extra distance bits */
     1576            }
     1577        }           /* literal or match pair ? */
     1578        flag >>= 1;
     1579    } while (lx < G2.last_lit);
     1580
     1581    SEND_CODE(END_BLOCK, ltree);
     1582}
     1583
    21631584
    21641585/* ===========================================================================
     
    21691590static ulg flush_block(char *buf, ulg stored_len, int eof)
    21701591{
    2171     ulg opt_lenb, static_lenb;  /* opt_len and static_len in bytes */
    2172     int max_blindex;    /* index of last bit length code of non zero freq */
    2173 
    2174     flag_buf[last_flags] = flags;   /* Save the flags for the last 8 items */
    2175 
    2176     /* Check if the file is ascii or binary */
    2177     if (*file_type == (ush) UNKNOWN)
    2178         set_file_type();
     1592    ulg opt_lenb, static_lenb;      /* opt_len and static_len in bytes */
     1593    int max_blindex;                /* index of last bit length code of non zero freq */
     1594
     1595    G2.flag_buf[G2.last_flags] = G2.flags;   /* Save the flags for the last 8 items */
    21791596
    21801597    /* Construct the literal and distance trees */
    2181     build_tree((tree_desc *) (&l_desc));
    2182     Tracev((stderr, "\nlit data: dyn %ld, stat %ld", opt_len, static_len));
    2183 
    2184     build_tree((tree_desc *) (&d_desc));
    2185     Tracev((stderr, "\ndist data: dyn %ld, stat %ld", opt_len, static_len));
     1598    build_tree(&G2.l_desc);
     1599    Tracev((stderr, "\nlit data: dyn %ld, stat %ld", G2.opt_len, G2.static_len));
     1600
     1601    build_tree(&G2.d_desc);
     1602    Tracev((stderr, "\ndist data: dyn %ld, stat %ld", G2.opt_len, G2.static_len));
    21861603    /* At this point, opt_len and static_len are the total bit lengths of
    21871604     * the compressed block data, excluding the tree representations.
     
    21941611
    21951612    /* Determine the best encoding. Compute first the block length in bytes */
    2196     opt_lenb = (opt_len + 3 + 7) >> 3;
    2197     static_lenb = (static_len + 3 + 7) >> 3;
     1613    opt_lenb = (G2.opt_len + 3 + 7) >> 3;
     1614    static_lenb = (G2.static_len + 3 + 7) >> 3;
    21981615
    21991616    Trace((stderr,
    22001617           "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
    2201            opt_lenb, opt_len, static_lenb, static_len, stored_len,
    2202            last_lit, last_dist));
     1618           opt_lenb, G2.opt_len, static_lenb, G2.static_len, stored_len,
     1619           G2.last_lit, G2.last_dist));
    22031620
    22041621    if (static_lenb <= opt_lenb)
     
    22091626     * the whole file is transformed into a stored file:
    22101627     */
    2211     if (stored_len <= opt_lenb && eof && compressed_len == 0L && seekable()) {
     1628    if (stored_len <= opt_lenb && eof && G2.compressed_len == 0L && seekable()) {
    22121629        /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
    2213         if (buf == (char *) 0)
     1630        if (buf == NULL)
    22141631            bb_error_msg("block vanished");
    22151632
    22161633        copy_block(buf, (unsigned) stored_len, 0);  /* without header */
    2217         compressed_len = stored_len << 3;
    2218         *file_method = STORED;
    2219 
    2220     } else if (stored_len + 4 <= opt_lenb && buf != (char *) 0) {
     1634        G2.compressed_len = stored_len << 3;
     1635
     1636    } else if (stored_len + 4 <= opt_lenb && buf != NULL) {
    22211637        /* 4: two words for the lengths */
    22221638        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
     
    22271643         */
    22281644        send_bits((STORED_BLOCK << 1) + eof, 3);    /* send block type */
    2229         compressed_len = (compressed_len + 3 + 7) & ~7L;
    2230         compressed_len += (stored_len + 4) << 3;
     1645        G2.compressed_len = (G2.compressed_len + 3 + 7) & ~7L;
     1646        G2.compressed_len += (stored_len + 4) << 3;
    22311647
    22321648        copy_block(buf, (unsigned) stored_len, 1);  /* with header */
     
    22341650    } else if (static_lenb == opt_lenb) {
    22351651        send_bits((STATIC_TREES << 1) + eof, 3);
    2236         compress_block((ct_data *) static_ltree, (ct_data *) static_dtree);
    2237         compressed_len += 3 + static_len;
     1652        compress_block((ct_data *) G2.static_ltree, (ct_data *) G2.static_dtree);
     1653        G2.compressed_len += 3 + G2.static_len;
    22381654    } else {
    22391655        send_bits((DYN_TREES << 1) + eof, 3);
    2240         send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1,
     1656        send_all_trees(G2.l_desc.max_code + 1, G2.d_desc.max_code + 1,
    22411657                       max_blindex + 1);
    2242         compress_block((ct_data *) dyn_ltree, (ct_data *) dyn_dtree);
    2243         compressed_len += 3 + opt_len;
    2244     }
    2245     Assert(compressed_len == bits_sent, "bad compressed size");
     1658        compress_block((ct_data *) G2.dyn_ltree, (ct_data *) G2.dyn_dtree);
     1659        G2.compressed_len += 3 + G2.opt_len;
     1660    }
     1661    Assert(G2.compressed_len == G1.bits_sent, "bad compressed size");
    22461662    init_block();
    22471663
    22481664    if (eof) {
    22491665        bi_windup();
    2250         compressed_len += 7;    /* align on byte boundary */
    2251     }
    2252     Tracev((stderr, "\ncomprlen %lu(%lu) ", compressed_len >> 3,
    2253             compressed_len - 7 * eof));
    2254 
    2255     return compressed_len >> 3;
    2256 }
    2257 
    2258 /* ===========================================================================
    2259  * Save the match info and tally the frequency counts. Return true if
    2260  * the current block must be flushed.
    2261  */
    2262 static int ct_tally(int dist, int lc)
    2263 {
    2264     l_buf[last_lit++] = (uch) lc;
    2265     if (dist == 0) {
    2266         /* lc is the unmatched char */
    2267         dyn_ltree[lc].Freq++;
    2268     } else {
    2269         /* Here, lc is the match length - MIN_MATCH */
    2270         dist--;         /* dist = match distance - 1 */
    2271         Assert((ush) dist < (ush) MAX_DIST &&
    2272                (ush) lc <= (ush) (MAX_MATCH - MIN_MATCH) &&
    2273                (ush) d_code(dist) < (ush) D_CODES, "ct_tally: bad match");
    2274 
    2275         dyn_ltree[length_code[lc] + LITERALS + 1].Freq++;
    2276         dyn_dtree[d_code(dist)].Freq++;
    2277 
    2278         d_buf[last_dist++] = (ush) dist;
    2279         flags |= flag_bit;
    2280     }
    2281     flag_bit <<= 1;
    2282 
    2283     /* Output the flags if they fill a byte: */
    2284     if ((last_lit & 7) == 0) {
    2285         flag_buf[last_flags++] = flags;
    2286         flags = 0, flag_bit = 1;
    2287     }
    2288     /* Try to guess if it is profitable to stop the current block here */
    2289     if ((last_lit & 0xfff) == 0) {
    2290         /* Compute an upper bound for the compressed length */
    2291         ulg out_length = (ulg) last_lit * 8L;
    2292         ulg in_length = (ulg) strstart - block_start;
    2293         int dcode;
    2294 
    2295         for (dcode = 0; dcode < D_CODES; dcode++) {
    2296             out_length +=
    2297                 (ulg) dyn_dtree[dcode].Freq * (5L + extra_dbits[dcode]);
     1666        G2.compressed_len += 7; /* align on byte boundary */
     1667    }
     1668    Tracev((stderr, "\ncomprlen %lu(%lu) ", G2.compressed_len >> 3,
     1669            G2.compressed_len - 7 * eof));
     1670
     1671    return G2.compressed_len >> 3;
     1672}
     1673
     1674
     1675/* ===========================================================================
     1676 * Update a hash value with the given input byte
     1677 * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
     1678 *    input characters, so that a running hash key can be computed from the
     1679 *    previous key instead of complete recalculation each time.
     1680 */
     1681#define UPDATE_HASH(h, c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
     1682
     1683
     1684/* ===========================================================================
     1685 * Same as above, but achieves better compression. We use a lazy
     1686 * evaluation for matches: a match is finally adopted only if there is
     1687 * no better match at the next window position.
     1688 *
     1689 * Processes a new input file and return its compressed length. Sets
     1690 * the compressed length, crc, deflate flags and internal file
     1691 * attributes.
     1692 */
     1693
     1694/* Flush the current block, with given end-of-file flag.
     1695 * IN assertion: strstart is set to the end of the current match. */
     1696#define FLUSH_BLOCK(eof) \
     1697    flush_block( \
     1698        G1.block_start >= 0L \
     1699            ? (char*)&G1.window[(unsigned)G1.block_start] \
     1700            : (char*)NULL, \
     1701        (ulg)G1.strstart - G1.block_start, \
     1702        (eof) \
     1703    )
     1704
     1705/* Insert string s in the dictionary and set match_head to the previous head
     1706 * of the hash chain (the most recent string with same hash key). Return
     1707 * the previous length of the hash chain.
     1708 * IN  assertion: all calls to to INSERT_STRING are made with consecutive
     1709 *    input characters and the first MIN_MATCH bytes of s are valid
     1710 *    (except for the last MIN_MATCH-1 bytes of the input file). */
     1711#define INSERT_STRING(s, match_head) \
     1712do { \
     1713    UPDATE_HASH(G1.ins_h, G1.window[(s) + MIN_MATCH-1]); \
     1714    G1.prev[(s) & WMASK] = match_head = head[G1.ins_h]; \
     1715    head[G1.ins_h] = (s); \
     1716} while (0)
     1717
     1718static ulg deflate(void)
     1719{
     1720    IPos hash_head;     /* head of hash chain */
     1721    IPos prev_match;    /* previous match */
     1722    int flush;          /* set if current block must be flushed */
     1723    int match_available = 0;    /* set if previous match exists */
     1724    unsigned match_length = MIN_MATCH - 1;  /* length of best match */
     1725
     1726    /* Process the input block. */
     1727    while (G1.lookahead != 0) {
     1728        /* Insert the string window[strstart .. strstart+2] in the
     1729         * dictionary, and set hash_head to the head of the hash chain:
     1730         */
     1731        INSERT_STRING(G1.strstart, hash_head);
     1732
     1733        /* Find the longest match, discarding those <= prev_length.
     1734         */
     1735        G1.prev_length = match_length;
     1736        prev_match = G1.match_start;
     1737        match_length = MIN_MATCH - 1;
     1738
     1739        if (hash_head != 0 && G1.prev_length < max_lazy_match
     1740         && G1.strstart - hash_head <= MAX_DIST
     1741        ) {
     1742            /* To simplify the code, we prevent matches with the string
     1743             * of window index 0 (in particular we have to avoid a match
     1744             * of the string with itself at the start of the input file).
     1745             */
     1746            match_length = longest_match(hash_head);
     1747            /* longest_match() sets match_start */
     1748            if (match_length > G1.lookahead)
     1749                match_length = G1.lookahead;
     1750
     1751            /* Ignore a length 3 match if it is too distant: */
     1752            if (match_length == MIN_MATCH && G1.strstart - G1.match_start > TOO_FAR) {
     1753                /* If prev_match is also MIN_MATCH, G1.match_start is garbage
     1754                 * but we will ignore the current match anyway.
     1755                 */
     1756                match_length--;
     1757            }
    22981758        }
    2299         out_length >>= 3;
    2300         Trace((stderr,
    2301                "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
    2302                last_lit, last_dist, in_length, out_length,
    2303                100L - out_length * 100L / in_length));
    2304         if (last_dist < last_lit / 2 && out_length < in_length / 2)
    2305             return 1;
    2306     }
    2307     return (last_lit == LIT_BUFSIZE - 1 || last_dist == DIST_BUFSIZE);
    2308     /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K
    2309      * on 16 bit machines and because stored blocks are restricted to
    2310      * 64K-1 bytes.
    2311      */
    2312 }
    2313 
    2314 /* ===========================================================================
    2315  * Send the block data compressed using the given Huffman trees
    2316  */
    2317 static void compress_block(ct_data * ltree, ct_data * dtree)
    2318 {
    2319     unsigned dist;      /* distance of matched string */
    2320     int lc;             /* match length or unmatched char (if dist == 0) */
    2321     unsigned lx = 0;    /* running index in l_buf */
    2322     unsigned dx = 0;    /* running index in d_buf */
    2323     unsigned fx = 0;    /* running index in flag_buf */
    2324     uch flag = 0;       /* current flags */
    2325     unsigned code;      /* the code to send */
    2326     int extra;          /* number of extra bits to send */
    2327 
    2328     if (last_lit != 0)
    2329         do {
    2330             if ((lx & 7) == 0)
    2331                 flag = flag_buf[fx++];
    2332             lc = l_buf[lx++];
    2333             if ((flag & 1) == 0) {
    2334                 send_code(lc, ltree);   /* send a literal byte */
    2335                 Tracecv(isgraph(lc), (stderr, " '%c' ", lc));
    2336             } else {
    2337                 /* Here, lc is the match length - MIN_MATCH */
    2338                 code = length_code[lc];
    2339                 send_code(code + LITERALS + 1, ltree);  /* send the length code */
    2340                 extra = extra_lbits[code];
    2341                 if (extra != 0) {
    2342                     lc -= base_length[code];
    2343                     send_bits(lc, extra);   /* send the extra length bits */
    2344                 }
    2345                 dist = d_buf[dx++];
    2346                 /* Here, dist is the match distance - 1 */
    2347                 code = d_code(dist);
    2348                 Assert(code < D_CODES, "bad d_code");
    2349 
    2350                 send_code(code, dtree); /* send the distance code */
    2351                 extra = extra_dbits[code];
    2352                 if (extra != 0) {
    2353                     dist -= base_dist[code];
    2354                     send_bits(dist, extra); /* send the extra distance bits */
    2355                 }
    2356             }           /* literal or match pair ? */
    2357             flag >>= 1;
    2358         } while (lx < last_lit);
    2359 
    2360     send_code(END_BLOCK, ltree);
    2361 }
    2362 
    2363 /* ===========================================================================
    2364  * Set the file type to ASCII or BINARY, using a crude approximation:
    2365  * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
    2366  * IN assertion: the fields freq of dyn_ltree are set and the total of all
    2367  * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
    2368  */
    2369 static void set_file_type(void)
    2370 {
    2371     int n = 0;
    2372     unsigned ascii_freq = 0;
    2373     unsigned bin_freq = 0;
    2374 
    2375     while (n < 7)
    2376         bin_freq += dyn_ltree[n++].Freq;
    2377     while (n < 128)
    2378         ascii_freq += dyn_ltree[n++].Freq;
    2379     while (n < LITERALS)
    2380         bin_freq += dyn_ltree[n++].Freq;
    2381     *file_type = bin_freq > (ascii_freq >> 2) ? BINARY : ASCII;
    2382     if (*file_type == BINARY && translate_eol) {
    2383         bb_error_msg("-l used on binary file");
    2384     }
    2385 }
    2386 
    2387 /* zip.c -- compress files to the gzip or pkzip format
    2388  * Copyright (C) 1992-1993 Jean-loup Gailly
    2389  * This is free software; you can redistribute it and/or modify it under the
    2390  * terms of the GNU General Public License, see the file COPYING.
    2391  */
    2392 
    2393 
    2394 static uint32_t crc;            /* crc on uncompressed file data */
    2395 static long header_bytes;   /* number of bytes in gzip header */
    2396 
    2397 static void put_long(ulg n)
    2398 {
    2399     put_short((n) & 0xffff);
    2400     put_short(((ulg) (n)) >> 16);
    2401 }
    2402 
    2403 /* put_header_byte is used for the compressed output
    2404  * - for the initial 4 bytes that can't overflow the buffer.
    2405  */
    2406 #define put_header_byte(c) {outbuf[outcnt++]=(uch)(c);}
     1759        /* If there was a match at the previous step and the current
     1760         * match is not better, output the previous match:
     1761         */
     1762        if (G1.prev_length >= MIN_MATCH && match_length <= G1.prev_length) {
     1763            check_match(G1.strstart - 1, prev_match, G1.prev_length);
     1764            flush = ct_tally(G1.strstart - 1 - prev_match, G1.prev_length - MIN_MATCH);
     1765
     1766            /* Insert in hash table all strings up to the end of the match.
     1767             * strstart-1 and strstart are already inserted.
     1768             */
     1769            G1.lookahead -= G1.prev_length - 1;
     1770            G1.prev_length -= 2;
     1771            do {
     1772                G1.strstart++;
     1773                INSERT_STRING(G1.strstart, hash_head);
     1774                /* strstart never exceeds WSIZE-MAX_MATCH, so there are
     1775                 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
     1776                 * these bytes are garbage, but it does not matter since the
     1777                 * next lookahead bytes will always be emitted as literals.
     1778                 */
     1779            } while (--G1.prev_length != 0);
     1780            match_available = 0;
     1781            match_length = MIN_MATCH - 1;
     1782            G1.strstart++;
     1783            if (flush) {
     1784                FLUSH_BLOCK(0);
     1785                G1.block_start = G1.strstart;
     1786            }
     1787        } else if (match_available) {
     1788            /* If there was no match at the previous position, output a
     1789             * single literal. If there was a match but the current match
     1790             * is longer, truncate the previous match to a single literal.
     1791             */
     1792            Tracevv((stderr, "%c", G1.window[G1.strstart - 1]));
     1793            if (ct_tally(0, G1.window[G1.strstart - 1])) {
     1794                FLUSH_BLOCK(0);
     1795                G1.block_start = G1.strstart;
     1796            }
     1797            G1.strstart++;
     1798            G1.lookahead--;
     1799        } else {
     1800            /* There is no previous match to compare with, wait for
     1801             * the next step to decide.
     1802             */
     1803            match_available = 1;
     1804            G1.strstart++;
     1805            G1.lookahead--;
     1806        }
     1807        Assert(G1.strstart <= G1.isize && lookahead <= G1.isize, "a bit too far");
     1808
     1809        /* Make sure that we always have enough lookahead, except
     1810         * at the end of the input file. We need MAX_MATCH bytes
     1811         * for the next match, plus MIN_MATCH bytes to insert the
     1812         * string following the next match.
     1813         */
     1814        while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile)
     1815            fill_window();
     1816    }
     1817    if (match_available)
     1818        ct_tally(0, G1.window[G1.strstart - 1]);
     1819
     1820    return FLUSH_BLOCK(1);  /* eof */
     1821}
     1822
     1823
     1824/* ===========================================================================
     1825 * Initialize the bit string routines.
     1826 */
     1827static void bi_init(void)
     1828{
     1829    G1.bi_buf = 0;
     1830    G1.bi_valid = 0;
     1831#ifdef DEBUG
     1832    G1.bits_sent = 0L;
     1833#endif
     1834}
     1835
     1836
     1837/* ===========================================================================
     1838 * Initialize the "longest match" routines for a new file
     1839 */
     1840static void lm_init(ush * flagsp)
     1841{
     1842    unsigned j;
     1843
     1844    /* Initialize the hash table. */
     1845    memset(head, 0, HASH_SIZE * sizeof(*head));
     1846    /* prev will be initialized on the fly */
     1847
     1848    /* speed options for the general purpose bit flag */
     1849    *flagsp |= 2;   /* FAST 4, SLOW 2 */
     1850    /* ??? reduce max_chain_length for binary files */
     1851
     1852    G1.strstart = 0;
     1853    G1.block_start = 0L;
     1854
     1855    G1.lookahead = file_read(G1.window,
     1856            sizeof(int) <= 2 ? (unsigned) WSIZE : 2 * WSIZE);
     1857
     1858    if (G1.lookahead == 0 || G1.lookahead == (unsigned) -1) {
     1859        G1.eofile = 1;
     1860        G1.lookahead = 0;
     1861        return;
     1862    }
     1863    G1.eofile = 0;
     1864    /* Make sure that we always have enough lookahead. This is important
     1865     * if input comes from a device such as a tty.
     1866     */
     1867    while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile)
     1868        fill_window();
     1869
     1870    G1.ins_h = 0;
     1871    for (j = 0; j < MIN_MATCH - 1; j++)
     1872        UPDATE_HASH(G1.ins_h, G1.window[j]);
     1873    /* If lookahead < MIN_MATCH, ins_h is garbage, but this is
     1874     * not important since only literal bytes will be emitted.
     1875     */
     1876}
     1877
     1878
     1879/* ===========================================================================
     1880 * Allocate the match buffer, initialize the various tables and save the
     1881 * location of the internal file attribute (ascii/binary) and method
     1882 * (DEFLATE/STORE).
     1883 * One callsite in zip()
     1884 */
     1885static void ct_init(void)
     1886{
     1887    int n;              /* iterates over tree elements */
     1888    int length;         /* length value */
     1889    int code;           /* code value */
     1890    int dist;           /* distance index */
     1891
     1892    G2.compressed_len = 0L;
     1893
     1894#ifdef NOT_NEEDED
     1895    if (G2.static_dtree[0].Len != 0)
     1896        return;         /* ct_init already called */
     1897#endif
     1898
     1899    /* Initialize the mapping length (0..255) -> length code (0..28) */
     1900    length = 0;
     1901    for (code = 0; code < LENGTH_CODES - 1; code++) {
     1902        G2.base_length[code] = length;
     1903        for (n = 0; n < (1 << extra_lbits[code]); n++) {
     1904            G2.length_code[length++] = code;
     1905        }
     1906    }
     1907    Assert(length == 256, "ct_init: length != 256");
     1908    /* Note that the length 255 (match length 258) can be represented
     1909     * in two different ways: code 284 + 5 bits or code 285, so we
     1910     * overwrite length_code[255] to use the best encoding:
     1911     */
     1912    G2.length_code[length - 1] = code;
     1913
     1914    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
     1915    dist = 0;
     1916    for (code = 0; code < 16; code++) {
     1917        G2.base_dist[code] = dist;
     1918        for (n = 0; n < (1 << extra_dbits[code]); n++) {
     1919            G2.dist_code[dist++] = code;
     1920        }
     1921    }
     1922    Assert(dist == 256, "ct_init: dist != 256");
     1923    dist >>= 7;         /* from now on, all distances are divided by 128 */
     1924    for (; code < D_CODES; code++) {
     1925        G2.base_dist[code] = dist << 7;
     1926        for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
     1927            G2.dist_code[256 + dist++] = code;
     1928        }
     1929    }
     1930    Assert(dist == 256, "ct_init: 256+dist != 512");
     1931
     1932    /* Construct the codes of the static literal tree */
     1933    /* already zeroed - it's in bss
     1934    for (n = 0; n <= MAX_BITS; n++)
     1935        G2.bl_count[n] = 0; */
     1936
     1937    n = 0;
     1938    while (n <= 143) {
     1939        G2.static_ltree[n++].Len = 8;
     1940        G2.bl_count[8]++;
     1941    }
     1942    while (n <= 255) {
     1943        G2.static_ltree[n++].Len = 9;
     1944        G2.bl_count[9]++;
     1945    }
     1946    while (n <= 279) {
     1947        G2.static_ltree[n++].Len = 7;
     1948        G2.bl_count[7]++;
     1949    }
     1950    while (n <= 287) {
     1951        G2.static_ltree[n++].Len = 8;
     1952        G2.bl_count[8]++;
     1953    }
     1954    /* Codes 286 and 287 do not exist, but we must include them in the
     1955     * tree construction to get a canonical Huffman tree (longest code
     1956     * all ones)
     1957     */
     1958    gen_codes((ct_data *) G2.static_ltree, L_CODES + 1);
     1959
     1960    /* The static distance tree is trivial: */
     1961    for (n = 0; n < D_CODES; n++) {
     1962        G2.static_dtree[n].Len = 5;
     1963        G2.static_dtree[n].Code = bi_reverse(n, 5);
     1964    }
     1965
     1966    /* Initialize the first block of the first file: */
     1967    init_block();
     1968}
     1969
    24071970
    24081971/* ===========================================================================
    24091972 * Deflate in to out.
    24101973 * IN assertions: the input and output buffers are cleared.
    2411  *   The variables time_stamp and save_orig_name are initialized.
    2412  */
    2413 static int zip(int in, int out)
    2414 {
    2415     uch my_flags = 0;   /* general purpose bit flags */
    2416     ush attr = 0;       /* ascii/binary flag */
    2417     ush deflate_flags = 0;  /* pkzip -es, -en or -ex equivalent */
    2418 
    2419     ifd = in;
    2420     ofd = out;
    2421     outcnt = 0;
     1974 */
     1975
     1976static void zip(ulg time_stamp)
     1977{
     1978    ush deflate_flags = 0;  /* pkzip -es, -en or -ex equivalent */
     1979
     1980    G1.outcnt = 0;
    24221981
    24231982    /* Write the header to the gzip file. See algorithm.doc for the format */
    2424 
    2425 
    2426     method = DEFLATED;
    2427     put_header_byte(GZIP_MAGIC[0]); /* magic header */
    2428     put_header_byte(GZIP_MAGIC[1]);
    2429     put_header_byte(DEFLATED);  /* compression method */
    2430 
    2431     put_header_byte(my_flags);  /* general flags */
    2432     put_long(time_stamp);
     1983    /* magic header for gzip files: 1F 8B */
     1984    /* compression method: 8 (DEFLATED) */
     1985    /* general flags: 0 */
     1986    put_32bit(0x00088b1f);
     1987    put_32bit(time_stamp);
    24331988
    24341989    /* Write deflated file to zip file */
    2435     crc = updcrc(0, 0);
    2436 
    2437     bi_init(out);
    2438     ct_init(&attr, &method);
     1990    G1.crc = ~0;
     1991
     1992    bi_init();
     1993    ct_init();
    24391994    lm_init(&deflate_flags);
    24401995
    2441     put_byte((uch) deflate_flags);  /* extra flags */
    2442     put_byte(OS_CODE);  /* OS identifier */
    2443 
    2444     header_bytes = (long) outcnt;
    2445 
    2446     (void) deflate();
     1996    put_8bit(deflate_flags);    /* extra flags */
     1997    put_8bit(3);    /* OS identifier = 3 (Unix) */
     1998
     1999    deflate();
    24472000
    24482001    /* Write the crc and uncompressed size */
    2449     put_long(crc);
    2450     put_long(isize);
    2451     header_bytes += 2 * sizeof(long);
     2002    put_32bit(~G1.crc);
     2003    put_32bit(G1.isize);
    24522004
    24532005    flush_outbuf();
    2454     return OK;
    2455 }
    2456 
    2457 
    2458 /* ===========================================================================
    2459  * Read a new buffer from the current input file, perform end-of-line
    2460  * translation, and update the crc and input file size.
    2461  * IN assertion: size >= 2 (for end-of-line translation)
    2462  */
    2463 static int file_read(char *buf, unsigned size)
    2464 {
    2465     unsigned len;
    2466 
    2467     Assert(insize == 0, "inbuf not empty");
    2468 
    2469     len = read(ifd, buf, size);
    2470     if (len == (unsigned) (-1) || len == 0)
    2471         return (int) len;
    2472 
    2473     crc = updcrc((uch *) buf, len);
    2474     isize += (ulg) len;
    2475     return (int) len;
    2476 }
    2477 
    2478 /* ===========================================================================
    2479  * Write the output buffer outbuf[0..outcnt-1] and update bytes_out.
    2480  * (used for the compressed data only)
    2481  */
    2482 static void flush_outbuf(void)
    2483 {
    2484     if (outcnt == 0)
    2485         return;
    2486 
    2487     write_buf(ofd, (char *) outbuf, outcnt);
    2488     outcnt = 0;
    2489 }
     2006}
     2007
     2008
     2009/* ======================================================================== */
     2010static
     2011char* make_new_name_gzip(char *filename)
     2012{
     2013    return xasprintf("%s.gz", filename);
     2014}
     2015
     2016static
     2017USE_DESKTOP(long long) int pack_gzip(void)
     2018{
     2019    struct stat s;
     2020
     2021    clear_bufs();
     2022    s.st_ctime = 0;
     2023    fstat(STDIN_FILENO, &s);
     2024    zip(s.st_ctime);
     2025    return 0;
     2026}
     2027
     2028int gzip_main(int argc, char **argv);
     2029int gzip_main(int argc, char **argv)
     2030{
     2031    unsigned opt;
     2032
     2033    /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */
     2034    opt = getopt32(argv, "cfv" USE_GUNZIP("d") "q123456789" );
     2035    option_mask32 &= 0x7; /* Clear -d, ignore -q, -0..9 */
     2036    //if (opt & 0x1) // -c
     2037    //if (opt & 0x2) // -f
     2038    //if (opt & 0x4) // -v
     2039#if ENABLE_GUNZIP /* gunzip_main may not be visible... */
     2040    if (opt & 0x8) { // -d
     2041        return gunzip_main(argc, argv);
     2042    }
     2043#endif
     2044    argv += optind;
     2045
     2046    PTR_TO_GLOBALS = xzalloc(sizeof(struct globals) + sizeof(struct globals2))
     2047            + sizeof(struct globals);
     2048    G2.l_desc.dyn_tree    = G2.dyn_ltree;
     2049    G2.l_desc.static_tree = G2.static_ltree;
     2050    G2.l_desc.extra_bits  = extra_lbits;
     2051    G2.l_desc.extra_base  = LITERALS + 1;
     2052    G2.l_desc.elems       = L_CODES;
     2053    G2.l_desc.max_length  = MAX_BITS;
     2054    //G2.l_desc.max_code    = 0;
     2055
     2056    G2.d_desc.dyn_tree    = G2.dyn_dtree;
     2057    G2.d_desc.static_tree = G2.static_dtree;
     2058    G2.d_desc.extra_bits  = extra_dbits;
     2059    //G2.d_desc.extra_base  = 0;
     2060    G2.d_desc.elems       = D_CODES;
     2061    G2.d_desc.max_length  = MAX_BITS;
     2062    //G2.d_desc.max_code    = 0;
     2063
     2064    G2.bl_desc.dyn_tree    = G2.bl_tree;
     2065    //G2.bl_desc.static_tree = NULL;
     2066    G2.bl_desc.extra_bits  = extra_blbits,
     2067    //G2.bl_desc.extra_base  = 0;
     2068    G2.bl_desc.elems       = BL_CODES;
     2069    G2.bl_desc.max_length  = MAX_BL_BITS;
     2070    //G2.bl_desc.max_code    = 0;
     2071
     2072    /* Allocate all global buffers (for DYN_ALLOC option) */
     2073    ALLOC(uch, G1.l_buf, INBUFSIZ);
     2074    ALLOC(uch, G1.outbuf, OUTBUFSIZ);
     2075    ALLOC(ush, G1.d_buf, DIST_BUFSIZE);
     2076    ALLOC(uch, G1.window, 2L * WSIZE);
     2077    ALLOC(ush, G1.prev, 1L << BITS);
     2078
     2079    /* Initialise the CRC32 table */
     2080    G1.crc_32_tab = crc32_filltable(NULL, 0);
     2081
     2082    return bbunpack(argv, make_new_name_gzip, pack_gzip);
     2083}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/archive_xread_all_eof.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  This program is free software; you can redistribute it and/or modify
    3  *  it under the terms of the GNU General Public License as published by
    4  *  the Free Software Foundation; either version 2 of the License, or
    5  *  (at your option) any later version.
    6  *
    7  *  This program is distributed in the hope that it will be useful,
    8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  *  GNU Library General Public License for more details.
    11  *
    12  *  You should have received a copy of the GNU General Public License
    13  *  along with this program; if not, write to the Free Software
    14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    154 */
    165
    17 #include <stdio.h>
    18 #include <stdlib.h>
    19 #include <string.h>
     6#include "libbb.h"
    207#include "unarchive.h"
    21 #include "libbb.h"
    228
    23 ssize_t archive_xread_all_eof(archive_handle_t *archive_handle, unsigned char *buf, size_t count)
     9ssize_t archive_xread_all_eof(archive_handle_t *archive_handle,
     10            unsigned char *buf, size_t count)
    2411{
    2512    ssize_t size;
    2613
    27     size = bb_full_read(archive_handle->src_fd, buf, count);
    28     if ((size != 0) && (size != count)) {
    29         bb_perror_msg_and_die("Short read, read %ld of %ld", (long)size, (long)count);
     14    size = full_read(archive_handle->src_fd, buf, count);
     15    if (size != 0 && size != count) {
     16        bb_error_msg_and_die("short read: %u of %u",
     17                (unsigned)size, (unsigned)count);
    3018    }
    31     return(size);
     19    return size;
    3220}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/check_header_gzip.c

    r821 r1765  
    1 #include <stdlib.h>
    2 #include <unistd.h>
     1/* vi: set sw=4 ts=4: */
     2/*
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     4 */
     5
    36#include "libbb.h"
    4 #include "unarchive.h" /* for external decl of check_header_gzip */
     7#include "unarchive.h" /* for external decl of check_header_gzip_or_die */
    58
    6 void check_header_gzip(int src_fd)
     9void check_header_gzip_or_die(int src_fd)
    710{
    811    union {
     
    1417            unsigned char xtra_flags;
    1518            unsigned char os_flags;
    16         } formated;
     19        } formatted;
    1720    } header;
    1821
    19     bb_xread_all(src_fd, header.raw, 8);
     22    xread(src_fd, header.raw, 8);
    2023
    2124    /* Check the compression method */
    22     if (header.formated.method != 8) {
    23         bb_error_msg_and_die("Unknown compression method %d",
    24                           header.formated.method);
     25    if (header.formatted.method != 8) {
     26        bb_error_msg_and_die("unknown compression method %d",
     27                          header.formatted.method);
    2528    }
    2629
    27     if (header.formated.flags & 0x04) {
     30    if (header.formatted.flags & 0x04) {
    2831        /* bit 2 set: extra field present */
    29         unsigned char extra_short;
     32        unsigned extra_short;
    3033
    31         extra_short = bb_xread_char(src_fd) + (bb_xread_char(src_fd) << 8);
     34        extra_short = xread_char(src_fd) + (xread_char(src_fd) << 8);
    3235        while (extra_short > 0) {
    3336            /* Ignore extra field */
    34             bb_xread_char(src_fd);
     37            xread_char(src_fd);
    3538            extra_short--;
    3639        }
     
    3841
    3942    /* Discard original name if any */
    40     if (header.formated.flags & 0x08) {
     43    if (header.formatted.flags & 0x08) {
    4144        /* bit 3 set: original file name present */
    42         while(bb_xread_char(src_fd) != 0);
     45        while (xread_char(src_fd) != 0);
    4346    }
    4447
    4548    /* Discard file comment if any */
    46     if (header.formated.flags & 0x10) {
     49    if (header.formatted.flags & 0x10) {
    4750        /* bit 4 set: file comment present */
    48         while(bb_xread_char(src_fd) != 0);
     51        while (xread_char(src_fd) != 0);
    4952    }
    5053
    5154    /* Read the header checksum */
    52     if (header.formated.flags & 0x02) {
    53         bb_xread_char(src_fd);
    54         bb_xread_char(src_fd);
     55    if (header.formatted.flags & 0x02) {
     56        xread_char(src_fd);
     57        xread_char(src_fd);
    5558    }
    56 
    57     return;
    5859}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/data_align.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  This program is free software; you can redistribute it and/or modify
    3  *  it under the terms of the GNU General Public License as published by
    4  *  the Free Software Foundation; either version 2 of the License, or
    5  *  (at your option) any later version.
    6  *
    7  *  This program is distributed in the hope that it will be useful,
    8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  *  GNU General Public License for more details.
    11  *
    12  *  You should have received a copy of the GNU General Public License
    13  *  along with this program; if not, write to the Free Software
    14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    154 */
    165
    17 #include <sys/types.h>
    18 
    19 #include <errno.h>
    20 #include <unistd.h>
     6//#include <sys/types.h>
    217
    228#include "libbb.h"
     
    2915    archive_handle->seek(archive_handle, skip_amount);
    3016    archive_handle->offset += skip_amount;
    31 
    32     return;
    3317}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/data_extract_all.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  This program is free software; you can redistribute it and/or modify
    3  *  it under the terms of the GNU General Public License as published by
    4  *  the Free Software Foundation; either version 2 of the License, or
    5  *  (at your option) any later version.
    6  *
    7  *  This program is distributed in the hope that it will be useful,
    8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  *  GNU General Public License for more details.
    11  *
    12  *  You should have received a copy of the GNU General Public License
    13  *  along with this program; if not, write to the Free Software
    14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    154 */
    16 
    17 #include <sys/types.h>
    18 
    19 #include <errno.h>
    20 #include <fcntl.h>
    21 #include <stdlib.h>
    22 #include <string.h>
    23 #include <utime.h>
    24 #include <unistd.h>
    25 #include <stdlib.h>
    265
    276#include "libbb.h"
     
    3514
    3615    if (archive_handle->flags & ARCHIVE_CREATE_LEADING_DIRS) {
    37         char *name = bb_xstrdup(file_header->name);
    38         bb_make_directory (dirname(name), -1, FILEUTILS_RECUR);
     16        char *name = xstrdup(file_header->name);
     17        bb_make_directory(dirname(name), -1, FILEUTILS_RECUR);
    3918        free(name);
    4019    }
     
    4322    if (archive_handle->flags & ARCHIVE_EXTRACT_UNCONDITIONAL) {
    4423        /* Remove the existing entry if it exists */
    45         if (((file_header->mode & S_IFMT) != S_IFDIR) && (unlink(file_header->name) == -1) && (errno != ENOENT)) {
    46             bb_perror_msg_and_die("Couldnt remove old file");
     24        if (((file_header->mode & S_IFMT) != S_IFDIR)
     25         && (unlink(file_header->name) == -1)
     26         && (errno != ENOENT)
     27        ) {
     28            bb_perror_msg_and_die("cannot remove old file %s",
     29                    file_header->name);
    4730        }
    4831    }
     
    5235        if (lstat(file_header->name, &statbuf) == -1) {
    5336            if (errno != ENOENT) {
    54                 bb_perror_msg_and_die("Couldnt stat old file");
     37                bb_perror_msg_and_die("cannot stat old file");
    5538            }
    5639        }
    5740        else if (statbuf.st_mtime <= file_header->mtime) {
    5841            if (!(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) {
    59                 bb_error_msg("%s not created: newer or same age file exists", file_header->name);
     42                bb_error_msg("%s not created: newer or "
     43                    "same age file exists", file_header->name);
    6044            }
    6145            data_skip(archive_handle);
     
    6347        }
    6448        else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) {
    65             bb_perror_msg_and_die("Couldnt remove old file %s", file_header->name);
     49            bb_perror_msg_and_die("cannot remove old file %s",
     50                    file_header->name);
    6651        }
    6752    }
     
    6954    /* Handle hard links separately
    7055     * We identified hard links as regular files of size 0 with a symlink */
    71     if (S_ISREG(file_header->mode) && (file_header->link_name) && (file_header->size == 0)) {
     56    if (S_ISREG(file_header->mode) && (file_header->link_target)
     57     && (file_header->size == 0)
     58    ) {
    7259        /* hard link */
    73         res = link(file_header->link_name, file_header->name);
     60        res = link(file_header->link_target, file_header->name);
    7461        if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) {
    75             bb_perror_msg("Couldnt create hard link");
     62            bb_perror_msg("cannot create %slink "
     63                    "from %s to %s", "hard",
     64                    file_header->name,
     65                    file_header->link_target);
    7666        }
    7767    } else {
    7868        /* Create the filesystem entry */
    79         switch(file_header->mode & S_IFMT) {
    80             case S_IFREG: {
    81                 /* Regular file */
    82                 dst_fd = bb_xopen(file_header->name, O_WRONLY | O_CREAT | O_EXCL);
    83                 bb_copyfd_size(archive_handle->src_fd, dst_fd, file_header->size);
    84                 close(dst_fd);
    85                 break;
    86                 }
    87             case S_IFDIR:
    88                 res = mkdir(file_header->name, file_header->mode);
    89                 if ((errno != EISDIR) && (res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) {
    90                     bb_perror_msg("extract_archive: %s", file_header->name);
    91                 }
    92                 break;
    93             case S_IFLNK:
    94                 /* Symlink */
    95                 res = symlink(file_header->link_name, file_header->name);
    96                 if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) {
    97                     bb_perror_msg("Cannot create symlink from %s to '%s'", file_header->name, file_header->link_name);
    98                 }
    99                 break;
    100             case S_IFSOCK:
    101             case S_IFBLK:
    102             case S_IFCHR:
    103             case S_IFIFO:
    104                 res = mknod(file_header->name, file_header->mode, file_header->device);
    105                 if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) {
    106                     bb_perror_msg("Cannot create node %s", file_header->name);
    107                 }
    108                 break;
    109             default:
    110                 bb_error_msg_and_die("Unrecognised file type");
     69        switch (file_header->mode & S_IFMT) {
     70        case S_IFREG: {
     71            /* Regular file */
     72            dst_fd = xopen3(file_header->name, O_WRONLY | O_CREAT | O_EXCL,
     73                            file_header->mode);
     74            bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);
     75            close(dst_fd);
     76            break;
     77        }
     78        case S_IFDIR:
     79            res = mkdir(file_header->name, file_header->mode);
     80            if ((res == -1) && (errno != EISDIR)
     81             && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)
     82            ) {
     83                bb_perror_msg("cannot make dir %s", file_header->name);
     84            }
     85            break;
     86        case S_IFLNK:
     87            /* Symlink */
     88            res = symlink(file_header->link_target, file_header->name);
     89            if ((res == -1)
     90             && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)
     91            ) {
     92                bb_perror_msg("cannot create %slink "
     93                    "from %s to %s", "sym",
     94                    file_header->name,
     95                    file_header->link_target);
     96            }
     97            break;
     98        case S_IFSOCK:
     99        case S_IFBLK:
     100        case S_IFCHR:
     101        case S_IFIFO:
     102            res = mknod(file_header->name, file_header->mode, file_header->device);
     103            if ((res == -1)
     104             && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)
     105            ) {
     106                bb_perror_msg("cannot create node %s", file_header->name);
     107            }
     108            break;
     109        default:
     110            bb_error_msg_and_die("unrecognized file type");
    111111        }
    112112    }
     
    115115        lchown(file_header->name, file_header->uid, file_header->gid);
    116116    }
    117     if (!(archive_handle->flags & ARCHIVE_NOPRESERVE_PERM) &&
    118          (file_header->mode & S_IFMT) != S_IFLNK)
    119     {
    120         chmod(file_header->name, file_header->mode);
    121     }
    122 
    123     if (archive_handle->flags & ARCHIVE_PRESERVE_DATE) {
    124         struct utimbuf t;
    125         t.actime = t.modtime = file_header->mtime;
    126         utime(file_header->name, &t);
     117    if ((file_header->mode & S_IFMT) != S_IFLNK) {
     118        /* uclibc has no lchmod, glibc is even stranger -
     119         * it has lchmod which seems to do nothing!
     120         * so we use chmod... */
     121        if (!(archive_handle->flags & ARCHIVE_NOPRESERVE_PERM)) {
     122            chmod(file_header->name, file_header->mode);
     123        }
     124        /* same for utime */
     125        if (archive_handle->flags & ARCHIVE_PRESERVE_DATE) {
     126            struct utimbuf t;
     127            t.actime = t.modtime = file_header->mtime;
     128            utime(file_header->name, &t);
     129        }
    127130    }
    128131}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/data_extract_to_buffer.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * Copyright 2002 Glenn McGrath
     
    1011void data_extract_to_buffer(archive_handle_t *archive_handle)
    1112{
    12     const unsigned int size = archive_handle->file_header->size;
     13    unsigned int size = archive_handle->file_header->size;
    1314
    1415    archive_handle->buffer = xzalloc(size + 1);
    15 
    16     archive_xread_all(archive_handle, archive_handle->buffer, size);
     16    xread(archive_handle->src_fd, archive_handle->buffer, size);
    1717}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/data_extract_to_stdout.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  This program is free software; you can redistribute it and/or modify
    3  *  it under the terms of the GNU General Public License as published by
    4  *  the Free Software Foundation; either version 2 of the License, or
    5  *  (at your option) any later version.
    6  *
    7  *  This program is distributed in the hope that it will be useful,
    8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  *  GNU General Public License for more details.
    11  *
    12  *  You should have received a copy of the GNU General Public License
    13  *  along with this program; if not, write to the Free Software
    14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    154 */
    165
     6#include "libbb.h"
    177#include "unarchive.h"
    18 #include <unistd.h>
    198
    209void data_extract_to_stdout(archive_handle_t *archive_handle)
    2110{
    22     bb_copyfd_size(archive_handle->src_fd, STDOUT_FILENO, archive_handle->file_header->size);
     11    bb_copyfd_exact_size(archive_handle->src_fd,
     12            STDOUT_FILENO,
     13            archive_handle->file_header->size);
    2314}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/data_skip.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  This program is free software; you can redistribute it and/or modify
    3  *  it under the terms of the GNU General Public License as published by
    4  *  the Free Software Foundation; either version 2 of the License, or
    5  *  (at your option) any later version.
    6  *
    7  *  This program is distributed in the hope that it will be useful,
    8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  *  GNU General Public License for more details.
    11  *
    12  *  You should have received a copy of the GNU General Public License
    13  *  along with this program; if not, write to the Free Software
    14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    154 */
    165
    17 #include <sys/types.h>
    18 #include <errno.h>
    19 #include <unistd.h>
    20 #include <stdlib.h>
     6#include "libbb.h"
    217#include "unarchive.h"
    22 #include "libbb.h"
    238
    249void data_skip(archive_handle_t *archive_handle)
  • branches/2.2.5/mindi-busybox/archival/libunarchive/decompress_bunzip2.c

    r821 r1765  
    2929 */
    3030
    31 #include <setjmp.h>
    32 #include <stdio.h>
    33 #include <stdlib.h>
    34 #include <string.h>
    35 #include <unistd.h>
    36 #include <limits.h>
    37 
    3831#include "libbb.h"
    39 
    4032#include "unarchive.h"
    4133
    4234/* Constants for Huffman coding */
    43 #define MAX_GROUPS          6
    44 #define GROUP_SIZE          50      /* 64 would have been more efficient */
    45 #define MAX_HUFCODE_BITS    20      /* Longest Huffman code allowed */
    46 #define MAX_SYMBOLS         258     /* 256 literals + RUNA + RUNB */
    47 #define SYMBOL_RUNA         0
    48 #define SYMBOL_RUNB         1
     35#define MAX_GROUPS          6
     36#define GROUP_SIZE          50      /* 64 would have been more efficient */
     37#define MAX_HUFCODE_BITS    20      /* Longest Huffman code allowed */
     38#define MAX_SYMBOLS         258     /* 256 literals + RUNA + RUNB */
     39#define SYMBOL_RUNA         0
     40#define SYMBOL_RUNB         1
    4941
    5042/* Status return values */
    51 #define RETVAL_OK                       0
    52 #define RETVAL_LAST_BLOCK               (-1)
    53 #define RETVAL_NOT_BZIP_DATA            (-2)
    54 #define RETVAL_UNEXPECTED_INPUT_EOF     (-3)
    55 #define RETVAL_UNEXPECTED_OUTPUT_EOF    (-4)
    56 #define RETVAL_DATA_ERROR               (-5)
    57 #define RETVAL_OUT_OF_MEMORY            (-6)
    58 #define RETVAL_OBSOLETE_INPUT           (-7)
     43#define RETVAL_OK                       0
     44#define RETVAL_LAST_BLOCK               (-1)
     45#define RETVAL_NOT_BZIP_DATA            (-2)
     46#define RETVAL_UNEXPECTED_INPUT_EOF     (-3)
     47#define RETVAL_UNEXPECTED_OUTPUT_EOF    (-4)
     48#define RETVAL_DATA_ERROR               (-5)
     49#define RETVAL_OUT_OF_MEMORY            (-6)
     50#define RETVAL_OBSOLETE_INPUT           (-7)
    5951
    6052/* Other housekeeping constants */
    61 #define IOBUF_SIZE          4096
     53#define IOBUF_SIZE          4096
    6254
    6355/* This is what we know about each Huffman coding group */
    6456struct group_data {
    6557    /* We have an extra slot at the end of limit[] for a sentinal value. */
    66     int limit[MAX_HUFCODE_BITS+1],base[MAX_HUFCODE_BITS],permute[MAX_SYMBOLS];
     58    int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS];
    6759    int minLen, maxLen;
    6860};
     
    7163   memory that persists between calls to bunzip */
    7264
    73 typedef struct {
     65struct bunzip_data {
    7466    /* State for interrupting output loop */
    75 
    76     int writeCopies,writePos,writeRunCountdown,writeCount,writeCurrent;
     67    int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
    7768
    7869    /* I/O tracking data (file handles, buffers, positions, etc.) */
    79 
    80     int in_fd,out_fd,inbufCount,inbufPos /*,outbufPos*/;
     70    int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/;
    8171    unsigned char *inbuf /*,*outbuf*/;
    82     unsigned int inbufBitCount, inbufBits;
     72    unsigned inbufBitCount, inbufBits;
    8373
    8474    /* The CRC values stored in the block header and calculated from the data */
    85 
    8675    uint32_t headerCRC, totalCRC, writeCRC;
    87     uint32_t *crc32Table;
     76
    8877    /* Intermediate buffer and its size (in bytes) */
    89 
    90     unsigned int *dbuf, dbufSize;
    91 
    92     /* These things are a bit too big to go on the stack */
    93 
     78    unsigned *dbuf, dbufSize;
     79
     80    /* For I/O error handling */
     81    jmp_buf jmpbuf;
     82
     83    /* Big things go last (register-relative addressing can be larger for big offsets */
     84    uint32_t crc32Table[256];
    9485    unsigned char selectors[32768];         /* nSelectors=15 bits */
    9586    struct group_data groups[MAX_GROUPS];   /* Huffman coding tables */
    96 
    97     /* For I/O error handling */
    98 
    99     jmp_buf jmpbuf;
    100 } bunzip_data;
     87};
     88/* typedef struct bunzip_data bunzip_data; -- done in .h file */
     89
    10190
    10291/* Return the next nnn bits of input.  All reads from the compressed input
    10392   are done through this function.  All reads are big endian */
    10493
    105 static unsigned int get_bits(bunzip_data *bd, char bits_wanted)
     94static unsigned get_bits(bunzip_data *bd, char bits_wanted)
    10695{
    107     unsigned int bits=0;
     96    unsigned bits = 0;
    10897
    10998    /* If we need to get more data from the byte buffer, do so.  (Loop getting
    11099       one byte at a time to enforce endianness and avoid unaligned access.) */
    111100
    112     while (bd->inbufBitCount<bits_wanted) {
     101    while (bd->inbufBitCount < bits_wanted) {
    113102
    114103        /* If we need to read more data from file into byte buffer, do so */
    115104
    116         if(bd->inbufPos==bd->inbufCount) {
    117             if((bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE)) <= 0)
    118                 longjmp(bd->jmpbuf,RETVAL_UNEXPECTED_INPUT_EOF);
    119             bd->inbufPos=0;
     105        if (bd->inbufPos == bd->inbufCount) {
     106            /* if "no input fd" case: in_fd == -1, read fails, we jump */
     107            bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE);
     108            if (bd->inbufCount <= 0)
     109                longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF);
     110            bd->inbufPos = 0;
    120111        }
    121112
    122113        /* Avoid 32-bit overflow (dump bit buffer to top of output) */
    123114
    124         if(bd->inbufBitCount>=24) {
    125             bits=bd->inbufBits&((1<<bd->inbufBitCount)-1);
    126             bits_wanted-=bd->inbufBitCount;
    127             bits<<=bits_wanted;
    128             bd->inbufBitCount=0;
     115        if (bd->inbufBitCount >= 24) {
     116            bits = bd->inbufBits & ((1 << bd->inbufBitCount) - 1);
     117            bits_wanted -= bd->inbufBitCount;
     118            bits <<= bits_wanted;
     119            bd->inbufBitCount = 0;
    129120        }
    130121
    131122        /* Grab next 8 bits of input from buffer. */
    132123
    133         bd->inbufBits=(bd->inbufBits<<8)|bd->inbuf[bd->inbufPos++];
    134         bd->inbufBitCount+=8;
     124        bd->inbufBits = (bd->inbufBits<<8) | bd->inbuf[bd->inbufPos++];
     125        bd->inbufBitCount += 8;
    135126    }
    136127
    137128    /* Calculate result */
    138129
    139     bd->inbufBitCount-=bits_wanted;
    140     bits|=(bd->inbufBits>>bd->inbufBitCount)&((1<<bits_wanted)-1);
     130    bd->inbufBitCount -= bits_wanted;
     131    bits |= (bd->inbufBits >> bd->inbufBitCount) & ((1 << bits_wanted) - 1);
    141132
    142133    return bits;
     
    148139{
    149140    struct group_data *hufGroup;
    150     int dbufCount,nextSym,dbufSize,groupCount,*base,*limit,selector,
    151         i,j,k,t,runPos,symCount,symTotal,nSelectors,byteCount[256];
     141    int dbufCount, nextSym, dbufSize, groupCount, *base, *limit, selector,
     142        i, j, k, t, runPos, symCount, symTotal, nSelectors, byteCount[256];
    152143    unsigned char uc, symToByte[256], mtfSymbol[256], *selectors;
    153     unsigned int *dbuf,origPtr;
    154 
    155     dbuf=bd->dbuf;
    156     dbufSize=bd->dbufSize;
    157     selectors=bd->selectors;
     144    unsigned *dbuf, origPtr;
     145
     146    dbuf = bd->dbuf;
     147    dbufSize = bd->dbufSize;
     148    selectors = bd->selectors;
    158149
    159150    /* Reset longjmp I/O error handling */
    160151
    161     i=setjmp(bd->jmpbuf);
    162     if(i) return i;
     152    i = setjmp(bd->jmpbuf);
     153    if (i) return i;
    163154
    164155    /* Read in header signature and CRC, then validate signature.
    165156       (last block signature means CRC is for whole file, return now) */
    166157
    167     i = get_bits(bd,24);
    168     j = get_bits(bd,24);
    169     bd->headerCRC=get_bits(bd,32);
     158    i = get_bits(bd, 24);
     159    j = get_bits(bd, 24);
     160    bd->headerCRC = get_bits(bd, 32);
    170161    if ((i == 0x177245) && (j == 0x385090)) return RETVAL_LAST_BLOCK;
    171162    if ((i != 0x314159) || (j != 0x265359)) return RETVAL_NOT_BZIP_DATA;
     
    175166       it didn't actually work. */
    176167
    177     if(get_bits(bd,1)) return RETVAL_OBSOLETE_INPUT;
    178     if((origPtr=get_bits(bd,24)) > dbufSize) return RETVAL_DATA_ERROR;
     168    if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT;
     169    origPtr = get_bits(bd, 24);
     170    if (origPtr > dbufSize) return RETVAL_DATA_ERROR;
    179171
    180172    /* mapping table: if some byte values are never used (encoding things
     
    184176       back to the corresponding bytes. */
    185177
    186     t=get_bits(bd, 16);
    187     symTotal=0;
    188     for (i=0;i<16;i++) {
    189         if(t&(1<<(15-i))) {
    190             k=get_bits(bd,16);
    191             for(j=0;j<16;j++)
    192                 if(k&(1<<(15-j))) symToByte[symTotal++]=(16*i)+j;
     178    t = get_bits(bd, 16);
     179    symTotal = 0;
     180    for (i = 0; i < 16; i++) {
     181        if (t & (1 << (15-i))) {
     182            k = get_bits(bd, 16);
     183            for (j = 0; j < 16; j++)
     184                if (k & (1 << (15-j)))
     185                    symToByte[symTotal++] = (16*i) + j;
    193186        }
    194187    }
     
    196189    /* How many different Huffman coding groups does this block use? */
    197190
    198     groupCount=get_bits(bd,3);
    199     if (groupCount<2 || groupCount>MAX_GROUPS) return RETVAL_DATA_ERROR;
     191    groupCount = get_bits(bd, 3);
     192    if (groupCount < 2 || groupCount > MAX_GROUPS)
     193        return RETVAL_DATA_ERROR;
    200194
    201195    /* nSelectors: Every GROUP_SIZE many symbols we select a new Huffman coding
     
    204198       start of the list.) */
    205199
    206     if(!(nSelectors=get_bits(bd, 15))) return RETVAL_DATA_ERROR;
    207     for(i=0; i<groupCount; i++) mtfSymbol[i] = i;
    208     for(i=0; i<nSelectors; i++) {
     200    nSelectors = get_bits(bd, 15);
     201    if (!nSelectors) return RETVAL_DATA_ERROR;
     202    for (i = 0; i < groupCount; i++) mtfSymbol[i] = i;
     203    for (i = 0; i < nSelectors; i++) {
    209204
    210205        /* Get next value */
    211206
    212         for(j=0;get_bits(bd,1);j++) if (j>=groupCount) return RETVAL_DATA_ERROR;
     207        for (j = 0; get_bits(bd, 1); j++)
     208            if (j>=groupCount) return RETVAL_DATA_ERROR;
    213209
    214210        /* Decode MTF to get the next selector */
    215211
    216212        uc = mtfSymbol[j];
    217         for(;j;j--) mtfSymbol[j] = mtfSymbol[j-1];
    218         mtfSymbol[0]=selectors[i]=uc;
     213        for (;j;j--) mtfSymbol[j] = mtfSymbol[j-1];
     214        mtfSymbol[0] = selectors[i] = uc;
    219215    }
    220216
     
    222218       literal symbols, plus two run symbols (RUNA, RUNB) */
    223219
    224     symCount=symTotal+2;
    225     for (j=0; j<groupCount; j++) {
    226         unsigned char length[MAX_SYMBOLS],temp[MAX_HUFCODE_BITS+1];
    227         int minLen, maxLen, pp;
     220    symCount = symTotal + 2;
     221    for (j = 0; j < groupCount; j++) {
     222        unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1];
     223        int minLen, maxLen, pp;
    228224
    229225        /* Read Huffman code lengths for each symbol.  They're stored in
     
    234230           length 0 becomes negative, so an unsigned inequality catches it.) */
    235231
    236         t=get_bits(bd, 5)-1;
     232        t = get_bits(bd, 5) - 1;
    237233        for (i = 0; i < symCount; i++) {
    238             for(;;) {
    239                 if (((unsigned)t) > (MAX_HUFCODE_BITS-1))
     234            for (;;) {
     235                if ((unsigned)t > (MAX_HUFCODE_BITS-1))
    240236                    return RETVAL_DATA_ERROR;
    241237
     
    244240                   bits and unget the second if the first was 0. */
    245241
    246                 k = get_bits(bd,2);
     242                k = get_bits(bd, 2);
    247243                if (k < 2) {
    248244                    bd->inbufBitCount++;
     
    252248                /* Add one if second bit 1, else subtract 1.  Avoids if/else */
    253249
    254                 t+=(((k+1)&2)-1);
     250                t += (((k+1) & 2) - 1);
    255251            }
    256252
    257253            /* Correct for the initial -1, to get the final symbol length */
    258254
    259             length[i]=t+1;
     255            length[i] = t + 1;
    260256        }
    261257
    262258        /* Find largest and smallest lengths in this group */
    263259
    264         minLen=maxLen=length[0];
    265         for(i = 1; i < symCount; i++) {
    266             if(length[i] > maxLen) maxLen = length[i];
    267             else if(length[i] < minLen) minLen = length[i];
     260        minLen = maxLen = length[0];
     261        for (i = 1; i < symCount; i++) {
     262            if (length[i] > maxLen) maxLen = length[i];
     263            else if (length[i] < minLen) minLen = length[i];
    268264        }
    269265
     
    279275         */
    280276
    281         hufGroup=bd->groups+j;
     277        hufGroup = bd->groups + j;
    282278        hufGroup->minLen = minLen;
    283279        hufGroup->maxLen = maxLen;
     
    287283           entry.  We do this again when using them (during symbol decoding).*/
    288284
    289         base=hufGroup->base-1;
    290         limit=hufGroup->limit-1;
     285        base = hufGroup->base - 1;
     286        limit = hufGroup->limit - 1;
    291287
    292288        /* Calculate permute[].  Concurently, initialize temp[] and limit[]. */
    293289
    294         pp=0;
    295         for(i=minLen;i<=maxLen;i++) {
    296             temp[i]=limit[i]=0;
    297             for(t=0;t<symCount;t++)
    298                 if(length[t]==i) hufGroup->permute[pp++] = t;
     290        pp = 0;
     291        for (i = minLen; i <= maxLen; i++) {
     292            temp[i] = limit[i] = 0;
     293            for (t = 0; t < symCount; t++)
     294                if (length[t] == i)
     295                    hufGroup->permute[pp++] = t;
    299296        }
    300297
    301298        /* Count symbols coded for at each bit length */
    302299
    303         for (i=0;i<symCount;i++) temp[length[i]]++;
     300        for (i = 0; i < symCount; i++) temp[length[i]]++;
    304301
    305302        /* Calculate limit[] (the largest symbol-coding value at each bit
     
    308305         * limit minus the cumulative count of symbols coded for already). */
    309306
    310         pp=t=0;
    311         for (i=minLen; i<maxLen; i++) {
    312             pp+=temp[i];
     307        pp = t = 0;
     308        for (i = minLen; i < maxLen; i++) {
     309            pp += temp[i];
    313310
    314311            /* We read the largest possible symbol size and then unget bits
     
    319316               don't affect the value>limit[length] comparison. */
    320317
    321             limit[i]= (pp << (maxLen - i)) - 1;
    322             pp<<=1;
    323             base[i+1]=pp-(t+=temp[i]);
     318            limit[i] = (pp << (maxLen - i)) - 1;
     319            pp <<= 1;
     320            t += temp[i];
     321            base[i+1] = pp - t;
    324322        }
    325323        limit[maxLen+1] = INT_MAX; /* Sentinal value for reading next sym. */
    326         limit[maxLen]=pp+temp[maxLen]-1;
    327         base[minLen]=0;
     324        limit[maxLen] = pp + temp[maxLen] - 1;
     325        base[minLen] = 0;
    328326    }
    329327
     
    334332    /* Initialize symbol occurrence counters and symbol Move To Front table */
    335333
    336     for(i=0;i<256;i++) {
     334    for (i = 0; i < 256; i++) {
    337335        byteCount[i] = 0;
    338         mtfSymbol[i]=(unsigned char)i;
     336        mtfSymbol[i] = (unsigned char)i;
    339337    }
    340338
    341339    /* Loop through compressed symbols. */
    342340
    343     runPos=dbufCount=selector=0;
    344     for(;;) {
     341    runPos = dbufCount = selector = 0;
     342    for (;;) {
    345343
    346344        /* fetch next Huffman coding group from list. */
    347345
    348         symCount=GROUP_SIZE-1;
    349         if(selector>=nSelectors) return RETVAL_DATA_ERROR;
    350         hufGroup=bd->groups+selectors[selector++];
    351         base=hufGroup->base-1;
    352         limit=hufGroup->limit-1;
    353 continue_this_group:
     346        symCount = GROUP_SIZE - 1;
     347        if (selector >= nSelectors) return RETVAL_DATA_ERROR;
     348        hufGroup = bd->groups + selectors[selector++];
     349        base = hufGroup->base - 1;
     350        limit = hufGroup->limit - 1;
     351 continue_this_group:
    354352
    355353        /* Read next Huffman-coded symbol. */
     
    362360           inline (falling back to a call to get_bits if the buffer runs
    363361           dry).  The following (up to got_huff_bits:) is equivalent to
    364            j=get_bits(bd,hufGroup->maxLen);
     362           j = get_bits(bd, hufGroup->maxLen);
    365363         */
    366364
    367         while (bd->inbufBitCount<hufGroup->maxLen) {
    368             if(bd->inbufPos==bd->inbufCount) {
    369                 j = get_bits(bd,hufGroup->maxLen);
     365        while (bd->inbufBitCount < hufGroup->maxLen) {
     366            if (bd->inbufPos == bd->inbufCount) {
     367                j = get_bits(bd, hufGroup->maxLen);
    370368                goto got_huff_bits;
    371369            }
    372             bd->inbufBits=(bd->inbufBits<<8)|bd->inbuf[bd->inbufPos++];
    373             bd->inbufBitCount+=8;
     370            bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++];
     371            bd->inbufBitCount += 8;
    374372        };
    375         bd->inbufBitCount-=hufGroup->maxLen;
    376         j = (bd->inbufBits>>bd->inbufBitCount)&((1<<hufGroup->maxLen)-1);
    377 
    378 got_huff_bits:
     373        bd->inbufBitCount -= hufGroup->maxLen;
     374        j = (bd->inbufBits >> bd->inbufBitCount) & ((1 << hufGroup->maxLen) - 1);
     375
     376 got_huff_bits:
    379377
    380378        /* Figure how how many bits are in next symbol and unget extras */
    381379
    382         i=hufGroup->minLen;
    383         while(j>limit[i]) ++i;
     380        i = hufGroup->minLen;
     381        while (j > limit[i]) ++i;
    384382        bd->inbufBitCount += (hufGroup->maxLen - i);
    385383
    386384        /* Huffman decode value to get nextSym (with bounds checking) */
    387385
    388         if ((i > hufGroup->maxLen)
    389             || (((unsigned)(j=(j>>(hufGroup->maxLen-i))-base[i]))
    390                 >= MAX_SYMBOLS))
     386        if (i > hufGroup->maxLen)
     387            return RETVAL_DATA_ERROR;
     388        j = (j >> (hufGroup->maxLen - i)) - base[i];
     389        if ((unsigned)j >= MAX_SYMBOLS)
    391390            return RETVAL_DATA_ERROR;
    392391        nextSym = hufGroup->permute[j];
     
    397396           how many times to repeat the last literal. */
    398397
    399         if (((unsigned)nextSym) <= SYMBOL_RUNB) { /* RUNA or RUNB */
     398        if ((unsigned)nextSym <= SYMBOL_RUNB) { /* RUNA or RUNB */
    400399
    401400            /* If this is the start of a new run, zero out counter */
    402401
    403             if(!runPos) {
     402            if (!runPos) {
    404403                runPos = 1;
    405404                t = 0;
     
    415414
    416415            t += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */
    417             if(runPos < dbufSize) runPos <<= 1;
     416            if (runPos < dbufSize) runPos <<= 1;
    418417            goto end_of_huffman_loop;
    419418        }
     
    424423           literal used is the one at the head of the mtfSymbol array.) */
    425424
    426         if(runPos) {
    427             runPos=0;
    428             if(dbufCount+t>=dbufSize) return RETVAL_DATA_ERROR;
     425        if (runPos) {
     426            runPos = 0;
     427            if (dbufCount + t >= dbufSize) return RETVAL_DATA_ERROR;
    429428
    430429            uc = symToByte[mtfSymbol[0]];
    431430            byteCount[uc] += t;
    432             while(t--) dbuf[dbufCount++]=uc;
     431            while (t--) dbuf[dbufCount++] = uc;
    433432        }
    434433
    435434        /* Is this the terminating symbol? */
    436435
    437         if(nextSym>symTotal) break;
     436        if (nextSym > symTotal) break;
    438437
    439438        /* At this point, nextSym indicates a new literal character.  Subtract
     
    445444           2 non-literal nextSym values equals -1.) */
    446445
    447         if(dbufCount>=dbufSize) return RETVAL_DATA_ERROR;
     446        if (dbufCount >= dbufSize) return RETVAL_DATA_ERROR;
    448447        i = nextSym - 1;
    449448        uc = mtfSymbol[i];
     
    458457        } while (--i);
    459458        mtfSymbol[0] = uc;
    460         uc=symToByte[uc];
     459        uc = symToByte[uc];
    461460
    462461        /* We have our literal byte.  Save it into dbuf. */
    463462
    464463        byteCount[uc]++;
    465         dbuf[dbufCount++] = (unsigned int)uc;
     464        dbuf[dbufCount++] = (unsigned)uc;
    466465
    467466        /* Skip group initialization if we're not done with this group.  Done
    468467         * this way to avoid compiler warning. */
    469468
    470 end_of_huffman_loop:
    471         if(symCount--) goto continue_this_group;
     469 end_of_huffman_loop:
     470        if (symCount--) goto continue_this_group;
    472471    }
    473472
    474473    /* At this point, we've read all the Huffman-coded symbols (and repeated
    475        runs) for this block from the input stream, and decoded them into the
     474       runs) for this block from the input stream, and decoded them into the
    476475       intermediate buffer.  There are dbufCount many decoded bytes in dbuf[].
    477476       Now undo the Burrows-Wheeler transform on dbuf.
     
    481480    /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
    482481
    483     j=0;
    484     for(i=0;i<256;i++) {
    485         k=j+byteCount[i];
     482    j = 0;
     483    for (i = 0; i < 256; i++) {
     484        k = j + byteCount[i];
    486485        byteCount[i] = j;
    487         j=k;
     486        j = k;
    488487    }
    489488
    490489    /* Figure out what order dbuf would be in if we sorted it. */
    491490
    492     for (i=0;i<dbufCount;i++) {
    493         uc=(unsigned char)(dbuf[i] & 0xff);
     491    for (i = 0; i < dbufCount; i++) {
     492        uc = (unsigned char)(dbuf[i] & 0xff);
    494493        dbuf[byteCount[uc]] |= (i << 8);
    495494        byteCount[uc]++;
     
    500499       it doesn't qualify as a run (hence writeRunCountdown=5). */
    501500
    502     if(dbufCount) {
    503         if(origPtr>=dbufCount) return RETVAL_DATA_ERROR;
    504         bd->writePos=dbuf[origPtr];
    505         bd->writeCurrent=(unsigned char)(bd->writePos&0xff);
    506         bd->writePos>>=8;
    507         bd->writeRunCountdown=5;
    508     }
    509     bd->writeCount=dbufCount;
     501    if (dbufCount) {
     502        if (origPtr >= dbufCount) return RETVAL_DATA_ERROR;
     503        bd->writePos = dbuf[origPtr];
     504        bd->writeCurrent = (unsigned char)(bd->writePos & 0xff);
     505        bd->writePos >>= 8;
     506        bd->writeRunCountdown = 5;
     507    }
     508    bd->writeCount = dbufCount;
    510509
    511510    return RETVAL_OK;
     
    519518*/
    520519
    521 static int read_bunzip(bunzip_data *bd, char *outbuf, int len)
     520int read_bunzip(bunzip_data *bd, char *outbuf, int len)
    522521{
    523     const unsigned int *dbuf;
    524     int pos,current,previous,gotcount;
     522    const unsigned *dbuf;
     523    int pos, current, previous, gotcount;
    525524
    526525    /* If last read was short due to end of file, return last block now */
    527     if(bd->writeCount<0) return bd->writeCount;
     526    if (bd->writeCount < 0) return bd->writeCount;
    528527
    529528    gotcount = 0;
    530     dbuf=bd->dbuf;
    531     pos=bd->writePos;
    532     current=bd->writeCurrent;
     529    dbuf = bd->dbuf;
     530    pos = bd->writePos;
     531    current = bd->writeCurrent;
    533532
    534533    /* We will always have pending decoded data to write into the output
     
    544543        /* Loop outputting bytes */
    545544
    546         for(;;) {
     545        for (;;) {
    547546
    548547            /* If the output buffer is full, snapshot state and return */
    549548
    550             if(gotcount >= len) {
    551                 bd->writePos=pos;
    552                 bd->writeCurrent=current;
     549            if (gotcount >= len) {
     550                bd->writePos  =pos;
     551                bd->writeCurrent = current;
    553552                bd->writeCopies++;
    554553                return len;
     
    558557
    559558            outbuf[gotcount++] = current;
    560             bd->writeCRC=(((bd->writeCRC)<<8)
    561                           ^bd->crc32Table[((bd->writeCRC)>>24)^current]);
     559            bd->writeCRC = (bd->writeCRC << 8)
     560                          ^ bd->crc32Table[(bd->writeCRC >> 24) ^ current];
    562561
    563562            /* Loop now if we're outputting multiple copies of this byte */
     
    567566                continue;
    568567            }
    569 decode_next_byte:
     568 decode_next_byte:
    570569            if (!bd->writeCount--) break;
    571570            /* Follow sequence vector to undo Burrows-Wheeler transform */
    572             previous=current;
    573             pos=dbuf[pos];
    574             current=pos&0xff;
    575             pos>>=8;
     571            previous = current;
     572            pos = dbuf[pos];
     573            current = pos & 0xff;
     574            pos >>= 8;
    576575
    577576            /* After 3 consecutive copies of the same byte, the 4th is a repeat
     
    579578             * of counting up because testing for non-zero is faster */
    580579
    581             if(--bd->writeRunCountdown) {
    582                 if(current!=previous) bd->writeRunCountdown=4;
     580            if (--bd->writeRunCountdown) {
     581                if (current != previous)
     582                    bd->writeRunCountdown = 4;
    583583            } else {
    584584
    585585                /* We have a repeated run, this byte indicates the count */
    586586
    587                 bd->writeCopies=current;
    588                 current=previous;
    589                 bd->writeRunCountdown=5;
     587                bd->writeCopies = current;
     588                current = previous;
     589                bd->writeRunCountdown = 5;
    590590
    591591                /* Sometimes there are just 3 bytes (run length 0) */
    592592
    593                 if(!bd->writeCopies) goto decode_next_byte;
     593                if (!bd->writeCopies) goto decode_next_byte;
    594594
    595595                /* Subtract the 1 copy we'd output anyway to get extras */
     
    601601        /* Decompression of this block completed successfully */
    602602
    603         bd->writeCRC=~bd->writeCRC;
    604         bd->totalCRC=((bd->totalCRC<<1) | (bd->totalCRC>>31)) ^ bd->writeCRC;
     603        bd->writeCRC = ~bd->writeCRC;
     604        bd->totalCRC = ((bd->totalCRC << 1) | (bd->totalCRC >> 31)) ^ bd->writeCRC;
    605605
    606606        /* If this block had a CRC error, force file level CRC error. */
    607607
    608         if(bd->writeCRC!=bd->headerCRC) {
    609             bd->totalCRC=bd->headerCRC+1;
     608        if (bd->writeCRC != bd->headerCRC) {
     609            bd->totalCRC = bd->headerCRC+1;
    610610            return RETVAL_LAST_BLOCK;
    611611        }
     
    615615    /* (previous is just a convenient unused temp variable here) */
    616616
    617     previous=get_next_block(bd);
    618     if(previous) {
    619         bd->writeCount=previous;
    620         return (previous!=RETVAL_LAST_BLOCK) ? previous : gotcount;
    621     }
    622     bd->writeCRC=~0;
    623     pos=bd->writePos;
    624     current=bd->writeCurrent;
     617    previous = get_next_block(bd);
     618    if (previous) {
     619        bd->writeCount = previous;
     620        return (previous != RETVAL_LAST_BLOCK) ? previous : gotcount;
     621    }
     622    bd->writeCRC = ~0;
     623    pos = bd->writePos;
     624    current = bd->writeCurrent;
    625625    goto decode_next_byte;
    626626}
     627
    627628
    628629/* Allocate the structure, read file header.  If in_fd==-1, inbuf must contain
     
    630631   ignored, and data is read from file handle into temporary buffer. */
    631632
    632 static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf,
     633/* Because bunzip2 is used for help text unpacking, and because bb_show_usage()
     634   should work for NOFORK applets too, we must be extremely careful to not leak
     635   any allocations! */
     636
     637int start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *inbuf,
    633638                        int len)
    634639{
    635640    bunzip_data *bd;
    636     unsigned int i;
    637     const unsigned int BZh0=(((unsigned int)'B')<<24)+(((unsigned int)'Z')<<16)
    638                             +(((unsigned int)'h')<<8)+(unsigned int)'0';
     641    unsigned i;
     642    enum {
     643        BZh0 = ('B' << 24) + ('Z' << 16) + ('h' << 8) + '0'
     644    };
    639645
    640646    /* Figure out how much data to allocate */
    641647
    642     i=sizeof(bunzip_data);
    643     if(in_fd!=-1) i+=IOBUF_SIZE;
     648    i = sizeof(bunzip_data);
     649    if (in_fd != -1) i += IOBUF_SIZE;
    644650
    645651    /* Allocate bunzip_data.  Most fields initialize to zero. */
    646652
    647     bd=*bdp=xzalloc(i);
     653    bd = *bdp = xzalloc(i);
    648654
    649655    /* Setup input buffer */
    650656
    651     if(-1==(bd->in_fd=in_fd)) {
    652         bd->inbuf=inbuf;
    653         bd->inbufCount=len;
    654     } else bd->inbuf=(unsigned char *)(bd+1);
     657    bd->in_fd = in_fd;
     658    if (-1 == in_fd) {
     659        /* in this case, bd->inbuf is read-only */
     660        bd->inbuf = (void*)inbuf; /* cast away const-ness */
     661        bd->inbufCount = len;
     662    } else
     663        bd->inbuf = (unsigned char *)(bd + 1);
    655664
    656665    /* Init the CRC32 table (big endian) */
    657666
    658     bd->crc32Table = bb_crc32_filltable(1);
     667    crc32_filltable(bd->crc32Table, 1);
    659668
    660669    /* Setup for I/O error handling via longjmp */
    661670
    662     i=setjmp(bd->jmpbuf);
    663     if(i) return i;
     671    i = setjmp(bd->jmpbuf);
     672    if (i) return i;
    664673
    665674    /* Ensure that file starts with "BZh['1'-'9']." */
    666675
    667     i = get_bits(bd,32);
    668     if (((unsigned int)(i-BZh0-1)) >= 9) return RETVAL_NOT_BZIP_DATA;
     676    i = get_bits(bd, 32);
     677    if ((unsigned)(i - BZh0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA;
    669678
    670679    /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
    671680       uncompressed data.  Allocate intermediate buffer for block. */
    672681
    673     bd->dbufSize=100000*(i-BZh0);
    674 
    675     bd->dbuf=xmalloc(bd->dbufSize * sizeof(int));
     682    bd->dbufSize = 100000 * (i - BZh0);
     683
     684    /* Cannot use xmalloc - may leak bd in NOFORK case! */
     685    bd->dbuf = malloc_or_warn(bd->dbufSize * sizeof(int));
     686    if (!bd->dbuf) {
     687        free(bd);
     688        xfunc_die();
     689    }
    676690    return RETVAL_OK;
    677691}
    678692
    679 /* Example usage: decompress src_fd to dst_fd.  (Stops at end of bzip data,
    680    not end of file.) */
    681 
    682 int uncompressStream(int src_fd, int dst_fd)
     693void dealloc_bunzip(bunzip_data *bd)
    683694{
     695    free(bd->dbuf);
     696    free(bd);
     697}
     698
     699
     700/* Decompress src_fd to dst_fd.  Stops at end of bzip data, not end of file. */
     701
     702USE_DESKTOP(long long) int
     703unpack_bz2_stream(int src_fd, int dst_fd)
     704{
     705    USE_DESKTOP(long long total_written = 0;)
    684706    char *outbuf;
    685707    bunzip_data *bd;
    686708    int i;
    687709
    688     outbuf=xmalloc(IOBUF_SIZE);
    689     if(!(i=start_bunzip(&bd,src_fd,0,0))) {
    690         for(;;) {
    691             if((i=read_bunzip(bd,outbuf,IOBUF_SIZE)) <= 0) break;
    692             if(i!=write(dst_fd,outbuf,i)) {
    693                 i=RETVAL_UNEXPECTED_OUTPUT_EOF;
     710    outbuf = xmalloc(IOBUF_SIZE);
     711    i = start_bunzip(&bd, src_fd, NULL, 0);
     712    if (!i) {
     713        for (;;) {
     714            i = read_bunzip(bd, outbuf, IOBUF_SIZE);
     715            if (i <= 0) break;
     716            if (i != safe_write(dst_fd, outbuf, i)) {
     717                i = RETVAL_UNEXPECTED_OUTPUT_EOF;
    694718                break;
    695719            }
     720            USE_DESKTOP(total_written += i;)
    696721        }
    697722    }
     
    699724    /* Check CRC and release memory */
    700725
    701     if(i==RETVAL_LAST_BLOCK) {
    702         if (bd->headerCRC!=bd->totalCRC) {
    703             bb_error_msg("Data integrity error when decompressing.");
     726    if (i == RETVAL_LAST_BLOCK) {
     727        if (bd->headerCRC != bd->totalCRC) {
     728            bb_error_msg("data integrity error when decompressing");
    704729        } else {
    705             i=RETVAL_OK;
    706         }
    707     } else if (i==RETVAL_UNEXPECTED_OUTPUT_EOF) {
    708         bb_error_msg("Compressed file ends unexpectedly");
     730            i = RETVAL_OK;
     731        }
     732    } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) {
     733        bb_error_msg("compressed file ends unexpectedly");
    709734    } else {
    710         bb_error_msg("Decompression failed");
    711     }
    712     free(bd->dbuf);
    713     free(bd);
     735        bb_error_msg("decompression failed");
     736    }
     737    dealloc_bunzip(bd);
    714738    free(outbuf);
    715739
    716     return i;
     740    return i ? i : USE_DESKTOP(total_written) + 0;
    717741}
    718742
    719743#ifdef TESTING
    720744
    721 static char * const bunzip_errors[]={NULL,"Bad file checksum","Not bzip data",
    722         "Unexpected input EOF","Unexpected output EOF","Data error",
    723          "Out of memory","Obsolete (pre 0.9.5) bzip format not supported."};
     745static char *const bunzip_errors[] = {
     746    NULL, "Bad file checksum", "Not bzip data",
     747    "Unexpected input EOF", "Unexpected output EOF", "Data error",
     748    "Out of memory", "Obsolete (pre 0.9.5) bzip format not supported"
     749};
    724750
    725751/* Dumb little test thing, decompress stdin to stdout */
    726 int main(int argc, char *argv[])
     752int main(int argc, char **argv)
    727753{
    728     int i=uncompressStream(0,1);
     754    int i = unpack_bz2_stream(0, 1);
    729755    char c;
    730756
    731     if(i) fprintf(stderr,"%s\n", bunzip_errors[-i]);
    732     else if(read(0,&c,1)) fprintf(stderr,"Trailing garbage ignored\n");
     757    if (i < 0)
     758        fprintf(stderr,"%s\n", bunzip_errors[-i]);
     759    else if (read(0, &c, 1))
     760        fprintf(stderr,"Trailing garbage ignored\n");
    733761    return -i;
    734762}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/decompress_uncompress.c

    r902 r1765  
     1/* vi: set sw=4 ts=4: */
    12#include "libbb.h"
    23
     
    67 * (see disclaimer below)
    78 */
    8 
    99
    1010/* (N)compress42.c - File compression ala IEEE Computer, Mar 1992.
     
    2626 *
    2727 */
    28 #include <stdio.h>
    29 #include <string.h>
    30 #include <unistd.h>
    3128
    3229/* Default input buffer size */
     
    3734
    3835/* Defines for third byte of header */
    39 #define MAGIC_1     (char_type)'\037'   /* First byte of compressed file               */
    40 #define MAGIC_2     (char_type)'\235'   /* Second byte of compressed file              */
    41 #define BIT_MASK    0x1f    /* Mask for 'number of compresssion bits'       */
    42                             /* Masks 0x20 and 0x40 are free.                */
    43                             /* I think 0x20 should mean that there is       */
    44                             /* a fourth header byte (for expansion).        */
    45 #define BLOCK_MODE  0x80    /* Block compresssion if table is full and      */
    46             /* compression rate is dropping flush tables    */
    47             /* the next two codes should not be changed lightly, as they must not   */
    48             /* lie within the contiguous general code space.                        */
    49 #define FIRST   257     /* first free entry                             */
    50 #define CLEAR   256     /* table clear output code                      */
    51 
    52 #define INIT_BITS 9     /* initial number of bits/code */
     36#define BIT_MASK        0x1f    /* Mask for 'number of compresssion bits'       */
     37                                /* Masks 0x20 and 0x40 are free.                */
     38                                /* I think 0x20 should mean that there is       */
     39                                /* a fourth header byte (for expansion).        */
     40#define BLOCK_MODE      0x80    /* Block compression if table is full and       */
     41                                /* compression rate is dropping flush tables    */
     42                                /* the next two codes should not be changed lightly, as they must not   */
     43                                /* lie within the contiguous general code space.                        */
     44#define FIRST   257     /* first free entry */
     45#define CLEAR   256     /* table clear output code */
     46
     47#define INIT_BITS 9     /* initial number of bits/code */
    5348
    5449
    5550/* machine variants which require cc -Dmachine:  pdp11, z8000, DOS */
    56 #define FAST
    57 
    58 #define HBITS       17  /* 50% occupancy */
    59 #define HSIZE      (1<<HBITS)
    60 #define HMASK      (HSIZE-1)
    61 #define HPRIME       9941
    62 #define BITS           16
    63 #undef  MAXSEG_64K
    64 #define MAXCODE(n)  (1L << (n))
    65 
    66 /* Block compress mode -C compatible with 2.0 */
    67 static int block_mode = BLOCK_MODE;
    68 
    69 /* user settable max # bits/code */
    70 static int maxbits = BITS;
    71 
    72 #define htabof(i)               htab[i]
    73 #define codetabof(i)            codetab[i]
    74 #define tab_prefixof(i)         codetabof(i)
    75 #define tab_suffixof(i)         ((unsigned char *)(htab))[i]
    76 #define de_stack                ((unsigned char *)&(htab[HSIZE-1]))
    77 #define clear_htab()            memset(htab, -1, HSIZE)
    78 #define clear_tab_prefixof()    memset(codetab, 0, 256);
    79 
     51#define HBITS      17   /* 50% occupancy */
     52#define HSIZE      (1<<HBITS)
     53#define HMASK      (HSIZE-1)    /* unused */
     54#define HPRIME     9941         /* unused */
     55#define BITS       16
     56#define BITS_STR   "16"
     57#undef  MAXSEG_64K              /* unused */
     58#define MAXCODE(n) (1L << (n))
     59
     60#define htabof(i)               htab[i]
     61#define codetabof(i)            codetab[i]
     62#define tab_prefixof(i)         codetabof(i)
     63#define tab_suffixof(i)         ((unsigned char *)(htab))[i]
     64#define de_stack                ((unsigned char *)&(htab[HSIZE-1]))
     65#define clear_tab_prefixof()    memset(codetab, 0, 256)
    8066
    8167/*
    8268 * Decompress stdin to stdout.  This routine adapts to the codes in the
    8369 * file building the "string" table on-the-fly; requiring no table to
    84  * be stored in the compressed file.  The tables used herein are shared
    85  * with those of the compress() routine.  See the definitions above.
     70 * be stored in the compressed file.
    8671 */
    8772
    88 int uncompress(int fd_in, int fd_out)
     73USE_DESKTOP(long long) int
     74uncompress(int fd_in, int fd_out)
    8975{
     76    USE_DESKTOP(long long total_written = 0;)
     77    USE_DESKTOP(long long) int retval = -1;
    9078    unsigned char *stackp;
    91     long int code;
     79    long code;
    9280    int finchar;
    93     long int oldcode;
    94     long int incode;
     81    long oldcode;
     82    long incode;
    9583    int inbits;
    9684    int posbits;
     
    9886    int insize;
    9987    int bitmask;
    100     long int free_ent;
    101     long int maxcode;
    102     long int maxmaxcode;
     88    long free_ent;
     89    long maxcode;
     90    long maxmaxcode;
    10391    int n_bits;
    10492    int rsize = 0;
    105     RESERVE_CONFIG_UBUFFER(inbuf, IBUFSIZ + 64);
    106     RESERVE_CONFIG_UBUFFER(outbuf, OBUFSIZ + 2048);
    107     unsigned char htab[HSIZE];
    108     unsigned short codetab[HSIZE];
    109     memset(inbuf, 0, IBUFSIZ + 64);
    110     memset(outbuf, 0, OBUFSIZ + 2048);
     93    unsigned char *inbuf; /* were eating insane amounts of stack - */
     94    unsigned char *outbuf; /* bad for some embedded targets */
     95    unsigned char *htab;
     96    unsigned short *codetab;
     97
     98    /* Hmm, these were statics - why?! */
     99    /* user settable max # bits/code */
     100    int maxbits; /* = BITS; */
     101    /* block compress mode -C compatible with 2.0 */
     102    int block_mode; /* = BLOCK_MODE; */
     103
     104    inbuf = xzalloc(IBUFSIZ + 64);
     105    outbuf = xzalloc(OBUFSIZ + 2048);
     106    htab = xzalloc(HSIZE);  /* wsn't zeroed out before, maybe can xmalloc? */
     107    codetab = xzalloc(HSIZE * sizeof(codetab[0]));
    111108
    112109    insize = 0;
    113110
    114     inbuf[0] = bb_xread_char(fd_in);
     111    /* xread isn't good here, we have to return - caller may want
     112     * to do some cleanup (e.g. delete incomplete unpacked file etc) */
     113    if (full_read(fd_in, inbuf, 1) != 1) {
     114        bb_error_msg("short read");
     115        goto err;
     116    }
    115117
    116118    maxbits = inbuf[0] & BIT_MASK;
     
    119121
    120122    if (maxbits > BITS) {
    121         bb_error_msg("compressed with %d bits, can only handle %d bits", maxbits,
    122                   BITS);
    123         return -1;
     123        bb_error_msg("compressed with %d bits, can only handle "
     124                BITS_STR" bits", maxbits);
     125        goto err;
    124126    }
    125127
    126     maxcode = MAXCODE(n_bits = INIT_BITS) - 1;
    127     bitmask = (1 << n_bits) - 1;
     128    n_bits = INIT_BITS;
     129    maxcode = MAXCODE(INIT_BITS) - 1;
     130    bitmask = (1 << INIT_BITS) - 1;
    128131    oldcode = -1;
    129132    finchar = 0;
     
    134137
    135138    /* As above, initialize the first 256 entries in the table. */
    136     clear_tab_prefixof();
     139    /*clear_tab_prefixof(); - done by xzalloc */
    137140
    138141    for (code = 255; code >= 0; --code) {
     
    141144
    142145    do {
    143       resetbuf:;
     146 resetbuf:
    144147        {
    145148            int i;
     
    147150            int o;
    148151
    149             e = insize - (o = (posbits >> 3));
     152            o = posbits >> 3;
     153            e = insize - o;
    150154
    151155            for (i = 0; i < e; ++i)
     
    158162        if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
    159163            rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ);
     164//error check??
    160165            insize += rsize;
    161166        }
     
    182187                unsigned char *p = &inbuf[posbits >> 3];
    183188
    184                 code =
    185                     ((((long) (p[0])) | ((long) (p[1]) << 8) |
    186                       ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask;
     189                code = ((((long) (p[0])) | ((long) (p[1]) << 8) |
     190                         ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask;
    187191            }
    188192            posbits += n_bits;
     
    190194
    191195            if (oldcode == -1) {
    192                 outbuf[outpos++] = (unsigned char) (finchar =
    193                                                 (int) (oldcode = code));
     196                oldcode = code;
     197                finchar = (int) oldcode;
     198                outbuf[outpos++] = (unsigned char) finchar;
    194199                continue;
    195200            }
     
    202207                     ((n_bits << 3) -
    203208                      (posbits - 1 + (n_bits << 3)) % (n_bits << 3)));
    204                 maxcode = MAXCODE(n_bits = INIT_BITS) - 1;
    205                 bitmask = (1 << n_bits) - 1;
     209                n_bits = INIT_BITS;
     210                maxcode = MAXCODE(INIT_BITS) - 1;
     211                bitmask = (1 << INIT_BITS) - 1;
    206212                goto resetbuf;
    207213            }
     
    223229                         (posbits & 07));
    224230                    bb_error_msg("uncompress: corrupt input");
    225                     return -1;
     231                    goto err;
    226232                }
    227233
     
    231237
    232238            /* Generate output characters in reverse order */
    233             while ((long int) code >= (long int) 256) {
     239            while ((long) code >= (long) 256) {
    234240                *--stackp = tab_suffixof(code);
    235241                code = tab_prefixof(code);
    236242            }
    237243
    238             *--stackp = (unsigned char) (finchar = tab_suffixof(code));
     244            finchar = tab_suffixof(code);
     245            *--stackp = (unsigned char) finchar;
    239246
    240247            /* And put them out in forward order */
     
    242249                int i;
    243250
    244                 if (outpos + (i = (de_stack - stackp)) >= OBUFSIZ) {
     251                i = de_stack - stackp;
     252                if (outpos + i >= OBUFSIZ) {
    245253                    do {
    246254                        if (i > OBUFSIZ - outpos) {
     
    254262
    255263                        if (outpos >= OBUFSIZ) {
    256                             write(fd_out, outbuf, outpos);
     264                            full_write(fd_out, outbuf, outpos);
     265//error check??
     266                            USE_DESKTOP(total_written += outpos;)
    257267                            outpos = 0;
    258268                        }
    259269                        stackp += i;
    260                     } while ((i = (de_stack - stackp)) > 0);
     270                        i = de_stack - stackp;
     271                    } while (i > 0);
    261272                } else {
    262273                    memcpy(outbuf + outpos, stackp, i);
     
    266277
    267278            /* Generate the new entry. */
    268             if ((code = free_ent) < maxmaxcode) {
     279            code = free_ent;
     280            if (code < maxmaxcode) {
    269281                tab_prefixof(code) = (unsigned short) oldcode;
    270282                tab_suffixof(code) = (unsigned char) finchar;
     
    279291
    280292    if (outpos > 0) {
    281         write(fd_out, outbuf, outpos);
     293        full_write(fd_out, outbuf, outpos);
     294//error check??
     295        USE_DESKTOP(total_written += outpos;)
    282296    }
    283297
    284     RELEASE_CONFIG_BUFFER(inbuf);
    285     RELEASE_CONFIG_BUFFER(outbuf);
    286     return 0;
     298    retval = USE_DESKTOP(total_written) + 0;
     299 err:
     300    free(inbuf);
     301    free(outbuf);
     302    free(htab);
     303    free(codetab);
     304    return retval;
    287305}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/decompress_unlzma.c

    r821 r1765  
    1 /* vi:set ts=4: */
     1/* vi: set sw=4 ts=4: */
    22/*
    33 * Small lzma deflate implementation.
     
    1313#include "unarchive.h"
    1414
    15 #ifdef CONFIG_FEATURE_LZMA_FAST
    16 #  define speed_inline ATTRIBUTE_ALWAYS_INLINE
     15#if ENABLE_FEATURE_LZMA_FAST
     16#  define speed_inline ALWAYS_INLINE
    1717#else
    1818#  define speed_inline
     
    2323    int fd;
    2424    uint8_t *ptr;
    25     uint8_t *buffer;
     25
     26/* Was keeping rc on stack in unlzma and separately allocating buffer,
     27 * but with "buffer 'attached to' allocated rc" code is smaller: */
     28    /* uint8_t *buffer; */
     29#define RC_BUFFER ((uint8_t*)(rc+1))
     30
    2631    uint8_t *buffer_end;
    27     int buffer_size;
     32
     33/* Had provisions for variable buffer, but we don't need it here */
     34    /* int buffer_size; */
     35#define RC_BUFFER_SIZE 0x10000
     36
    2837    uint32_t code;
    2938    uint32_t range;
     
    3140} rc_t;
    3241
    33 
    3442#define RC_TOP_BITS 24
    3543#define RC_MOVE_BITS 5
     
    4048static void rc_read(rc_t * rc)
    4149{
    42     rc->buffer_size = read(rc->fd, rc->buffer, rc->buffer_size);
    43     if (rc->buffer_size <= 0)
     50    int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE);
     51    if (buffer_size <= 0)
    4452        bb_error_msg_and_die("unexpected EOF");
    45     rc->ptr = rc->buffer;
    46     rc->buffer_end = rc->buffer + rc->buffer_size;
     53    rc->ptr = RC_BUFFER;
     54    rc->buffer_end = RC_BUFFER + buffer_size;
    4755}
    4856
    4957/* Called once */
    50 static void rc_init(rc_t * rc, int fd, int buffer_size)
     58static rc_t* rc_init(int fd) /*, int buffer_size) */
    5159{
    5260    int i;
     61    rc_t* rc;
     62
     63    rc = xmalloc(sizeof(rc_t) + RC_BUFFER_SIZE);
    5364
    5465    rc->fd = fd;
    55     rc->buffer = xmalloc(buffer_size);
    56     rc->buffer_size = buffer_size;
    57     rc->buffer_end = rc->buffer + rc->buffer_size;
     66    /* rc->buffer_size = buffer_size; */
     67    rc->buffer_end = RC_BUFFER + RC_BUFFER_SIZE;
    5868    rc->ptr = rc->buffer_end;
    5969
     
    6575        rc->code = (rc->code << 8) | *rc->ptr++;
    6676    }
    67 }
    68 
    69 /* Called once. TODO: bb_maybe_free() */
    70 static ATTRIBUTE_ALWAYS_INLINE void rc_free(rc_t * rc)
     77    return rc;
     78}
     79
     80/* Called once  */
     81static ALWAYS_INLINE void rc_free(rc_t * rc)
    7182{
    7283    if (ENABLE_FEATURE_CLEAN_UP)
    73         free(rc->buffer);
     84        free(rc);
    7485}
    7586
     
    8293    rc->code = (rc->code << 8) | *rc->ptr++;
    8394}
    84 static ATTRIBUTE_ALWAYS_INLINE void rc_normalize(rc_t * rc)
     95static ALWAYS_INLINE void rc_normalize(rc_t * rc)
    8596{
    8697    if (rc->range < (1 << RC_TOP_BITS)) {
     
    89100}
    90101
    91 /* Called 9 times */
     102/* rc_is_bit_0 is called 9 times */
    92103/* Why rc_is_bit_0_helper exists?
    93  * Because we want to always expose (rc->code < rc->bound) to optimizer
     104 * Because we want to always expose (rc->code < rc->bound) to optimizer.
     105 * Thus rc_is_bit_0 is always inlined, and rc_is_bit_0_helper is inlined
     106 * only if we compile for speed.
    94107 */
    95108static speed_inline uint32_t rc_is_bit_0_helper(rc_t * rc, uint16_t * p)
     
    99112    return rc->bound;
    100113}
    101 static ATTRIBUTE_ALWAYS_INLINE int rc_is_bit_0(rc_t * rc, uint16_t * p)
     114static ALWAYS_INLINE int rc_is_bit_0(rc_t * rc, uint16_t * p)
    102115{
    103116    uint32_t t = rc_is_bit_0_helper(rc, p);
     
    133146
    134147/* Called once */
    135 static ATTRIBUTE_ALWAYS_INLINE int rc_direct_bit(rc_t * rc)
     148static ALWAYS_INLINE int rc_direct_bit(rc_t * rc)
    136149{
    137150    rc_normalize(rc);
     
    164177
    165178
    166 #define LZMA_BASE_SIZE 1846
    167 #define LZMA_LIT_SIZE 768
    168 
    169 #define LZMA_NUM_POS_BITS_MAX 4
    170 
    171 #define LZMA_LEN_NUM_LOW_BITS 3
    172 #define LZMA_LEN_NUM_MID_BITS 3
    173 #define LZMA_LEN_NUM_HIGH_BITS 8
    174 
    175 #define LZMA_LEN_CHOICE 0
    176 #define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1)
    177 #define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1)
    178 #define LZMA_LEN_MID (LZMA_LEN_LOW \
    179               + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS)))
    180 #define LZMA_LEN_HIGH (LZMA_LEN_MID \
    181                +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS)))
    182 #define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS))
    183 
    184 #define LZMA_NUM_STATES 12
    185 #define LZMA_NUM_LIT_STATES 7
    186 
    187 #define LZMA_START_POS_MODEL_INDEX 4
    188 #define LZMA_END_POS_MODEL_INDEX 14
    189 #define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1))
    190 
    191 #define LZMA_NUM_POS_SLOT_BITS 6
    192 #define LZMA_NUM_LEN_TO_POS_STATES 4
    193 
    194 #define LZMA_NUM_ALIGN_BITS 4
    195 
    196 #define LZMA_MATCH_MIN_LEN 2
    197 
    198 #define LZMA_IS_MATCH 0
    199 #define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES <<LZMA_NUM_POS_BITS_MAX))
    200 #define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES)
    201 #define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES)
    202 #define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES)
    203 #define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES)
    204 #define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \
    205                + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
    206 #define LZMA_SPEC_POS (LZMA_POS_SLOT \
    207                +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS))
    208 #define LZMA_ALIGN (LZMA_SPEC_POS \
    209             + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX)
    210 #define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS))
    211 #define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS)
    212 #define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS)
    213 
    214 
    215 int unlzma(int src_fd, int dst_fd)
    216 {
     179/* #defines will force compiler to compute/optimize each one with each usage.
     180 * Have heart and use enum instead. */
     181enum {
     182    LZMA_BASE_SIZE = 1846,
     183    LZMA_LIT_SIZE  = 768,
     184
     185    LZMA_NUM_POS_BITS_MAX = 4,
     186
     187    LZMA_LEN_NUM_LOW_BITS  = 3,
     188    LZMA_LEN_NUM_MID_BITS  = 3,
     189    LZMA_LEN_NUM_HIGH_BITS = 8,
     190
     191    LZMA_LEN_CHOICE     = 0,
     192    LZMA_LEN_CHOICE_2   = (LZMA_LEN_CHOICE + 1),
     193    LZMA_LEN_LOW        = (LZMA_LEN_CHOICE_2 + 1),
     194    LZMA_LEN_MID        = (LZMA_LEN_LOW \
     195                          + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))),
     196    LZMA_LEN_HIGH       = (LZMA_LEN_MID \
     197                          + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))),
     198    LZMA_NUM_LEN_PROBS  = (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)),
     199
     200    LZMA_NUM_STATES     = 12,
     201    LZMA_NUM_LIT_STATES = 7,
     202
     203    LZMA_START_POS_MODEL_INDEX = 4,
     204    LZMA_END_POS_MODEL_INDEX   = 14,
     205    LZMA_NUM_FULL_DISTANCES    = (1 << (LZMA_END_POS_MODEL_INDEX >> 1)),
     206
     207    LZMA_NUM_POS_SLOT_BITS = 6,
     208    LZMA_NUM_LEN_TO_POS_STATES = 4,
     209
     210    LZMA_NUM_ALIGN_BITS = 4,
     211
     212    LZMA_MATCH_MIN_LEN  = 2,
     213
     214    LZMA_IS_MATCH       = 0,
     215    LZMA_IS_REP         = (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)),
     216    LZMA_IS_REP_G0      = (LZMA_IS_REP + LZMA_NUM_STATES),
     217    LZMA_IS_REP_G1      = (LZMA_IS_REP_G0 + LZMA_NUM_STATES),
     218    LZMA_IS_REP_G2      = (LZMA_IS_REP_G1 + LZMA_NUM_STATES),
     219    LZMA_IS_REP_0_LONG  = (LZMA_IS_REP_G2 + LZMA_NUM_STATES),
     220    LZMA_POS_SLOT       = (LZMA_IS_REP_0_LONG \
     221                          + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)),
     222    LZMA_SPEC_POS       = (LZMA_POS_SLOT \
     223                          + (LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)),
     224    LZMA_ALIGN          = (LZMA_SPEC_POS \
     225                          + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX),
     226    LZMA_LEN_CODER      = (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)),
     227    LZMA_REP_LEN_CODER  = (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS),
     228    LZMA_LITERAL        = (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS),
     229};
     230
     231
     232USE_DESKTOP(long long) int
     233unpack_lzma_stream(int src_fd, int dst_fd)
     234{
     235    USE_DESKTOP(long long total_written = 0;)
    217236    lzma_header_t header;
    218237    int lc, pb, lp;
     
    225244    int num_bits;
    226245    int num_probs;
    227     rc_t rc;
     246    rc_t *rc;
    228247    int i, mi;
    229248    uint8_t *buffer;
     
    234253    uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
    235254
    236     if (read(src_fd, &header, sizeof(header)) != sizeof(header))
    237         bb_error_msg_and_die("can't read header");
     255    xread(src_fd, &header, sizeof(header));
    238256
    239257    if (header.pos >= (9 * 5 * 5))
     
    260278        p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
    261279
    262     rc_init(&rc, src_fd, 0x10000);
     280    rc = rc_init(src_fd); /*, RC_BUFFER_SIZE); */
    263281
    264282    while (global_pos + buffer_pos < header.dst_size) {
     
    267285        prob =
    268286            p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state;
    269         if (rc_is_bit_0(&rc, prob)) {
     287        if (rc_is_bit_0(rc, prob)) {
    270288            mi = 1;
    271             rc_update_bit_0(&rc, prob);
     289            rc_update_bit_0(rc, prob);
    272290            prob = (p + LZMA_LITERAL + (LZMA_LIT_SIZE
    273291                    * ((((buffer_pos + global_pos) & literal_pos_mask) << lc)
     
    287305                    bit = match_byte & 0x100;
    288306                    prob_lit = prob + 0x100 + bit + mi;
    289                     if (rc_get_bit(&rc, prob_lit, &mi)) {
     307                    if (rc_get_bit(rc, prob_lit, &mi)) {
    290308                        if (!bit)
    291309                            break;
     
    298316            while (mi < 0x100) {
    299317                prob_lit = prob + mi;
    300                 rc_get_bit(&rc, prob_lit, &mi);
     318                rc_get_bit(rc, prob_lit, &mi);
    301319            }
    302320            previous_byte = (uint8_t) mi;
     
    306324                buffer_pos = 0;
    307325                global_pos += header.dict_size;
    308                 write(dst_fd, buffer, header.dict_size);
     326                if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size)
     327                    goto bad;
     328                USE_DESKTOP(total_written += header.dict_size;)
    309329            }
    310330            if (state < 4)
     
    318338            uint16_t *prob_len;
    319339
    320             rc_update_bit_1(&rc, prob);
     340            rc_update_bit_1(rc, prob);
    321341            prob = p + LZMA_IS_REP + state;
    322             if (rc_is_bit_0(&rc, prob)) {
    323                 rc_update_bit_0(&rc, prob);
     342            if (rc_is_bit_0(rc, prob)) {
     343                rc_update_bit_0(rc, prob);
    324344                rep3 = rep2;
    325345                rep2 = rep1;
     
    328348                prob = p + LZMA_LEN_CODER;
    329349            } else {
    330                 rc_update_bit_1(&rc, prob);
     350                rc_update_bit_1(rc, prob);
    331351                prob = p + LZMA_IS_REP_G0 + state;
    332                 if (rc_is_bit_0(&rc, prob)) {
    333                     rc_update_bit_0(&rc, prob);
     352                if (rc_is_bit_0(rc, prob)) {
     353                    rc_update_bit_0(rc, prob);
    334354                    prob = (p + LZMA_IS_REP_0_LONG
    335355                            + (state << LZMA_NUM_POS_BITS_MAX) + pos_state);
    336                     if (rc_is_bit_0(&rc, prob)) {
    337                         rc_update_bit_0(&rc, prob);
     356                    if (rc_is_bit_0(rc, prob)) {
     357                        rc_update_bit_0(rc, prob);
    338358
    339359                        state = state < LZMA_NUM_LIT_STATES ? 9 : 11;
     
    346366                            buffer_pos = 0;
    347367                            global_pos += header.dict_size;
    348                             write(dst_fd, buffer, header.dict_size);
     368                            if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size)
     369                                goto bad;
     370                            USE_DESKTOP(total_written += header.dict_size;)
    349371                        }
    350372                        continue;
    351373                    } else {
    352                         rc_update_bit_1(&rc, prob);
     374                        rc_update_bit_1(rc, prob);
    353375                    }
    354376                } else {
    355377                    uint32_t distance;
    356378
    357                     rc_update_bit_1(&rc, prob);
     379                    rc_update_bit_1(rc, prob);
    358380                    prob = p + LZMA_IS_REP_G1 + state;
    359                     if (rc_is_bit_0(&rc, prob)) {
    360                         rc_update_bit_0(&rc, prob);
     381                    if (rc_is_bit_0(rc, prob)) {
     382                        rc_update_bit_0(rc, prob);
    361383                        distance = rep1;
    362384                    } else {
    363                         rc_update_bit_1(&rc, prob);
     385                        rc_update_bit_1(rc, prob);
    364386                        prob = p + LZMA_IS_REP_G2 + state;
    365                         if (rc_is_bit_0(&rc, prob)) {
    366                             rc_update_bit_0(&rc, prob);
     387                        if (rc_is_bit_0(rc, prob)) {
     388                            rc_update_bit_0(rc, prob);
    367389                            distance = rep2;
    368390                        } else {
    369                             rc_update_bit_1(&rc, prob);
     391                            rc_update_bit_1(rc, prob);
    370392                            distance = rep3;
    371393                            rep3 = rep2;
     
    381403
    382404            prob_len = prob + LZMA_LEN_CHOICE;
    383             if (rc_is_bit_0(&rc, prob_len)) {
    384                 rc_update_bit_0(&rc, prob_len);
     405            if (rc_is_bit_0(rc, prob_len)) {
     406                rc_update_bit_0(rc, prob_len);
    385407                prob_len = (prob + LZMA_LEN_LOW
    386408                            + (pos_state << LZMA_LEN_NUM_LOW_BITS));
     
    388410                num_bits = LZMA_LEN_NUM_LOW_BITS;
    389411            } else {
    390                 rc_update_bit_1(&rc, prob_len);
     412                rc_update_bit_1(rc, prob_len);
    391413                prob_len = prob + LZMA_LEN_CHOICE_2;
    392                 if (rc_is_bit_0(&rc, prob_len)) {
    393                     rc_update_bit_0(&rc, prob_len);
     414                if (rc_is_bit_0(rc, prob_len)) {
     415                    rc_update_bit_0(rc, prob_len);
    394416                    prob_len = (prob + LZMA_LEN_MID
    395417                                + (pos_state << LZMA_LEN_NUM_MID_BITS));
     
    397419                    num_bits = LZMA_LEN_NUM_MID_BITS;
    398420                } else {
    399                     rc_update_bit_1(&rc, prob_len);
     421                    rc_update_bit_1(rc, prob_len);
    400422                    prob_len = prob + LZMA_LEN_HIGH;
    401423                    offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
     
    404426                }
    405427            }
    406             rc_bit_tree_decode(&rc, prob_len, num_bits, &len);
     428            rc_bit_tree_decode(rc, prob_len, num_bits, &len);
    407429            len += offset;
    408430
     
    417439                      LZMA_NUM_LEN_TO_POS_STATES - 1)
    418440                     << LZMA_NUM_POS_SLOT_BITS);
    419                 rc_bit_tree_decode(&rc, prob, LZMA_NUM_POS_SLOT_BITS,
     441                rc_bit_tree_decode(rc, prob, LZMA_NUM_POS_SLOT_BITS,
    420442                                   &pos_slot);
    421443                if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
     
    428450                        num_bits -= LZMA_NUM_ALIGN_BITS;
    429451                        while (num_bits--)
    430                             rep0 = (rep0 << 1) | rc_direct_bit(&rc);
     452                            rep0 = (rep0 << 1) | rc_direct_bit(rc);
    431453                        prob = p + LZMA_ALIGN;
    432454                        rep0 <<= LZMA_NUM_ALIGN_BITS;
     
    436458                    mi = 1;
    437459                    while (num_bits--) {
    438                         if (rc_get_bit(&rc, prob + mi, &mi))
     460                        if (rc_get_bit(rc, prob + mi, &mi))
    439461                            rep0 |= i;
    440462                        i <<= 1;
     
    457479                    buffer_pos = 0;
    458480                    global_pos += header.dict_size;
    459                     write(dst_fd, buffer, header.dict_size);
     481                    if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size)
     482                        goto bad;
     483                    USE_DESKTOP(total_written += header.dict_size;)
    460484                }
    461485                len--;
     
    464488    }
    465489
    466     write(dst_fd, buffer, buffer_pos);
    467     rc_free(&rc);
    468     return 0;
    469 }
    470 
    471 /* vi:set ts=4: */
     490
     491    if (full_write(dst_fd, buffer, buffer_pos) != buffer_pos) {
     492 bad:
     493        rc_free(rc);
     494        return -1;
     495    }
     496    rc_free(rc);
     497    USE_DESKTOP(total_written += buffer_pos;)
     498    return USE_DESKTOP(total_written) + 0;
     499}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/decompress_unzip.c

    r821 r1765  
    3030 *
    3131 * See the file algorithm.doc for the compression algorithms and file formats.
    32  * 
     32 *
    3333 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    3434 */
    3535
    3636#include "libbb.h"
    37 #include <sys/wait.h>
    38 #include <signal.h>
    3937#include "unarchive.h"
    4038
     
    4846} huft_t;
    4947
    50 static int gunzip_src_fd;
    51 unsigned int gunzip_bytes_out;  /* number of output bytes */
    52 static unsigned int gunzip_outbuf_count;    /* bytes in output buffer */
    53 
    54 /* gunzip_window size--must be a power of two, and
    55  *  at least 32K for zip's deflate method */
    56 enum { gunzip_wsize = 0x8000 };
    57 static unsigned char *gunzip_window;
    58 
    59 static uint32_t *gunzip_crc_table;
    60 uint32_t gunzip_crc;
    61 
    62 /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
    63 #define BMAX 16 /* maximum bit length of any code (16 for explode) */
    64 #define N_MAX 288   /* maximum number of codes in any set */
    65 
    66 /* bitbuffer */
    67 static unsigned int gunzip_bb;  /* bit buffer */
    68 static unsigned char gunzip_bk; /* bits in bit buffer */
    69 
    70 /* These control the size of the bytebuffer */
    71 static unsigned int bytebuffer_max = 0x8000;
    72 static unsigned char *bytebuffer = NULL;
    73 static unsigned int bytebuffer_offset = 0;
    74 static unsigned int bytebuffer_size = 0;
    75 
    76 static const unsigned short mask_bits[] = {
     48enum {
     49    /* gunzip_window size--must be a power of two, and
     50     *  at least 32K for zip's deflate method */
     51    GUNZIP_WSIZE = 0x8000,
     52    /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
     53    BMAX = 16,  /* maximum bit length of any code (16 for explode) */
     54    N_MAX = 288,    /* maximum number of codes in any set */
     55};
     56
     57
     58/* This is somewhat complex-looking arrangement, but it allows
     59 * to place decompressor state either in bss or in
     60 * malloc'ed space simply by changing #defines below.
     61 * Sizes on i386:
     62 * text    data     bss     dec     hex
     63 * 5256       0     108    5364    14f4 - bss
     64 * 4915       0       0    4915    1333 - malloc
     65 */
     66#define STATE_IN_BSS 0
     67#define STATE_IN_MALLOC 1
     68
     69
     70typedef struct state_t {
     71    off_t gunzip_bytes_out; /* number of output bytes */
     72    uint32_t gunzip_crc;
     73
     74    int gunzip_src_fd;
     75    unsigned gunzip_outbuf_count; /* bytes in output buffer */
     76
     77    unsigned char *gunzip_window;
     78
     79    uint32_t *gunzip_crc_table;
     80
     81    /* bitbuffer */
     82    unsigned gunzip_bb; /* bit buffer */
     83    unsigned char gunzip_bk; /* bits in bit buffer */
     84
     85    /* These control the size of the STATE()bytebuffer */
     86    unsigned bytebuffer_max;
     87    unsigned char *bytebuffer;
     88    unsigned bytebuffer_offset;
     89    unsigned bytebuffer_size;
     90
     91    /* private data of inflate_codes() */
     92    unsigned inflate_codes_ml; /* masks for bl and bd bits */
     93    unsigned inflate_codes_md; /* masks for bl and bd bits */
     94    unsigned inflate_codes_bb; /* bit buffer */
     95    unsigned inflate_codes_k; /* number of bits in bit buffer */
     96    unsigned inflate_codes_w; /* current gunzip_window position */
     97    huft_t *inflate_codes_tl;
     98    huft_t *inflate_codes_td;
     99    unsigned inflate_codes_bl;
     100    unsigned inflate_codes_bd;
     101    unsigned inflate_codes_nn; /* length and index for copy */
     102    unsigned inflate_codes_dd;
     103    smallint resume_copy;
     104
     105    /* private data of inflate_get_next_window() */
     106    smallint method; /* Method == -1 for stored, -2 for codes */
     107    smallint need_another_block;
     108    smallint end_reached;
     109
     110    /* private data of inflate_stored() */
     111    unsigned inflate_stored_n;
     112    unsigned inflate_stored_b;
     113    unsigned inflate_stored_k;
     114    unsigned inflate_stored_w;
     115} state_t;
     116#define gunzip_bytes_out    (S()gunzip_bytes_out   )
     117#define gunzip_crc          (S()gunzip_crc         )
     118#define gunzip_src_fd       (S()gunzip_src_fd      )
     119#define gunzip_outbuf_count (S()gunzip_outbuf_count)
     120#define gunzip_window       (S()gunzip_window      )
     121#define gunzip_crc_table    (S()gunzip_crc_table   )
     122#define gunzip_bb           (S()gunzip_bb          )
     123#define gunzip_bk           (S()gunzip_bk          )
     124#define bytebuffer_max      (S()bytebuffer_max     )
     125#define bytebuffer          (S()bytebuffer         )
     126#define bytebuffer_offset   (S()bytebuffer_offset  )
     127#define bytebuffer_size     (S()bytebuffer_size    )
     128#define inflate_codes_ml    (S()inflate_codes_ml   )
     129#define inflate_codes_md    (S()inflate_codes_md   )
     130#define inflate_codes_bb    (S()inflate_codes_bb   )
     131#define inflate_codes_k     (S()inflate_codes_k    )
     132#define inflate_codes_w     (S()inflate_codes_w    )
     133#define inflate_codes_tl    (S()inflate_codes_tl   )
     134#define inflate_codes_td    (S()inflate_codes_td   )
     135#define inflate_codes_bl    (S()inflate_codes_bl   )
     136#define inflate_codes_bd    (S()inflate_codes_bd   )
     137#define inflate_codes_nn    (S()inflate_codes_nn   )
     138#define inflate_codes_dd    (S()inflate_codes_dd   )
     139#define resume_copy         (S()resume_copy        )
     140#define method              (S()method             )
     141#define need_another_block  (S()need_another_block )
     142#define end_reached         (S()end_reached        )
     143#define inflate_stored_n    (S()inflate_stored_n   )
     144#define inflate_stored_b    (S()inflate_stored_b   )
     145#define inflate_stored_k    (S()inflate_stored_k   )
     146#define inflate_stored_w    (S()inflate_stored_w   )
     147#define INIT_STATE ({ bytebuffer_size = 0; method = -1; need_another_block = 1; })
     148
     149
     150/* This is generic part */
     151#if STATE_IN_BSS /* Use global data segment */
     152#define DECLARE_STATE /*nothing*/
     153#define ALLOC_STATE (init_state())
     154#define DEALLOC_STATE ((void)0)
     155#define S() state.
     156#define PASS_STATE /*nothing*/
     157#define PASS_STATE_ONLY /*nothing*/
     158#define STATE_PARAM /*nothing*/
     159#define STATE_PARAM_ONLY void
     160static state_t state;
     161static void init_state(void)
     162{
     163    INIT_STATE;
     164}
     165#endif
     166
     167#if STATE_IN_MALLOC /* Use malloc space */
     168#define DECLARE_STATE state_t *state
     169#define ALLOC_STATE (state = alloc_state())
     170#define DEALLOC_STATE free(state)
     171#define S() state->
     172#define PASS_STATE state,
     173#define PASS_STATE_ONLY state
     174#define STATE_PARAM state_t *state,
     175#define STATE_PARAM_ONLY state_t *state
     176static state_t* alloc_state(void)
     177{
     178    state_t* state = xzalloc(sizeof(*state));
     179    INIT_STATE;
     180    return state;
     181}
     182#endif
     183
     184
     185static const unsigned short mask_bits[] ALIGN2 = {
    77186    0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
    78187    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
     
    80189
    81190/* Copy lengths for literal codes 257..285 */
    82 static const unsigned short cplens[] = {
     191static const unsigned short cplens[] ALIGN2 = {
    83192    3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
    84193    67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
     
    87196/* note: see note #13 above about the 258 in this list. */
    88197/* Extra bits for literal codes 257..285 */
    89 static const unsigned char cplext[] = {
     198static const unsigned char cplext[] ALIGN1 = {
    90199    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5,
    91200    5, 5, 5, 0, 99, 99
    92 };                      /* 99==invalid */
     201}; /* 99 == invalid */
    93202
    94203/* Copy offsets for distance codes 0..29 */
    95 static const unsigned short cpdist[] = {
     204static const unsigned short cpdist[] ALIGN2 = {
    96205    1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
    97206    769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
     
    99208
    100209/* Extra bits for distance codes */
    101 static const unsigned char cpdext[] = {
     210static const unsigned char cpdext[] ALIGN1 = {
    102211    0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
    103212    11, 11, 12, 12, 13, 13
     
    106215/* Tables for deflate from PKZIP's appnote.txt. */
    107216/* Order of the bit length code lengths */
    108 static const unsigned char border[] = {
     217static const unsigned char border[] ALIGN1 = {
    109218    16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
    110219};
    111220
    112 static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned int required)
     221static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current, const unsigned required)
    113222{
    114223    while (*current < required) {
     
    117226             * to the front of the bytebuffer, leave 4 bytes free at end of tail
    118227             * so we can easily top up buffer in check_trailer_gzip() */
    119             if (!(bytebuffer_size = bb_xread(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8))) {
     228            bytebuffer_size = safe_read(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8);
     229            if (1 > bytebuffer_size)
     230//shouldn't we propagate error?
    120231                bb_error_msg_and_die("unexpected end of file");
    121             }
    122232            bytebuffer_size += 4;
    123233            bytebuffer_offset = 4;
    124234        }
    125         bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current;
     235        bitbuffer |= ((unsigned) bytebuffer[bytebuffer_offset]) << *current;
    126236        bytebuffer_offset++;
    127237        *current += 8;
    128238    }
    129     return(bitbuffer);
     239    return bitbuffer;
    130240}
    131241
     
    136246 * t: table to free
    137247 */
    138 static int huft_free(huft_t * t)
    139 {
    140     huft_t *p;
     248static void huft_free(huft_t * p)
     249{
    141250    huft_t *q;
    142251
    143252    /* Go through linked list, freeing from the malloced (t[-1]) address. */
    144     p = t;
    145     while (p != (huft_t *) NULL) {
     253    while (p) {
    146254        q = (--p)->v.t;
    147         free((char *) p);
     255        free(p);
    148256        p = q;
    149257    }
    150     return 0;
    151258}
    152259
     
    165272 * m:   maximum lookup bits, returns actual
    166273 */
    167 static
    168 int huft_build(unsigned int *b, const unsigned int n,
    169                const unsigned int s, const unsigned short *d,
    170                const unsigned char *e, huft_t ** t, unsigned int *m)
     274static int huft_build(unsigned *b, const unsigned n,
     275               const unsigned s, const unsigned short *d,
     276               const unsigned char *e, huft_t ** t, unsigned *m)
    171277{
    172278    unsigned a;             /* counter for codes of length k */
     
    195301
    196302    /* Generate counts for each bit length */
    197     memset((void *)c, 0, sizeof(c));
     303    memset(c, 0, sizeof(c));
    198304    p = b;
    199305    i = n;
     
    203309    } while (--i);
    204310    if (c[0] == n) { /* null input--all zero length codes */
    205         *t = (huft_t *) NULL;
     311        *t = NULL;
    206312        *m = 0;
    207313        return 2;
     
    217323    /* Adjust last length count to fill out codes, if needed */
    218324    for (y = 1 << j; j < i; j++, y <<= 1) {
    219         if ((y -= c[j]) < 0) {
     325        y -= c[j];
     326        if (y < 0) {
    220327            return 2; /* bad input: more codes than bits */
    221328        }
    222329    }
    223     if ((y -= c[i]) < 0) {
     330    y -= c[i];
     331    if (y < 0) {
    224332        return 2;
    225333    }
     
    231339    xp = x + 2;
    232340    while (--i) { /* note that i == g from above */
    233         *xp++ = (j += *p++);
     341        j += *p++;
     342        *xp++ = j;
    234343    }
    235344
     
    238347    i = 0;
    239348    do {
    240         if ((j = *p++) != 0) {
     349        j = *p++;
     350        if (j != 0) {
    241351            v[x[j]++] = i;
    242352        }
     
    248358    htl = -1;               /* no tables yet--level -1 */
    249359    w = ws[0] = 0;          /* bits decoded */
    250     u[0] = (huft_t *) NULL; /* just to keep compilers happy */
    251     q = (huft_t *) NULL;    /* ditto */
     360    u[0] = NULL;    /* just to keep compilers happy */
     361    q = NULL;   /* ditto */
    252362    z = 0;                  /* ditto */
    253363
     
    262372
    263373                /* compute minimum size table less than or equal to *m bits */
    264                 z = (z = g - w) > *m ? *m : z; /* upper limit on table size */
    265                 if ((f = 1 << (j = k - w)) > a + 1) { /* try a k-w bit table */
     374                z = g - w;
     375                z = z > *m ? *m : z; /* upper limit on table size */
     376                j = k - w;
     377                f = 1 << j;
     378                if (f > a + 1) { /* try a k-w bit table */
    266379                    /* too few codes for k-w bit table */
    267380                    f -= a + 1; /* deduct codes from patterns left */
    268381                    xp = c + k;
    269382                    while (++j < z) { /* try smaller tables up to z bits */
    270                         if ((f <<= 1) <= *++xp) {
     383                        f <<= 1;
     384                        if (f <= *++xp) {
    271385                            break; /* enough codes to use up j bits */
    272386                        }
     
    279393
    280394                /* allocate and link in new table */
    281                 q = (huft_t *) xzalloc((z + 1) * sizeof(huft_t));
     395                q = xzalloc((z + 1) * sizeof(huft_t));
    282396                *t = q + 1; /* link to list for huft_free() */
    283397                t = &(q->v.t);
     
    333447}
    334448
     449
    335450/*
    336451 * inflate (decompress) the codes in a deflated (compressed) block.
     
    340455 * bl, bd: number of bits decoded by tl[] and td[]
    341456 */
    342 static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned int my_bl, const unsigned int my_bd, int setup)
    343 {
    344     static unsigned int e;  /* table entry flag/number of extra bits */
    345     static unsigned int n, d;   /* length and index for copy */
    346     static unsigned int w;  /* current gunzip_window position */
    347     static huft_t *t;           /* pointer to table entry */
    348     static unsigned int ml, md; /* masks for bl and bd bits */
    349     static unsigned int b;  /* bit buffer */
    350     static unsigned int k;          /* number of bits in bit buffer */
    351     static huft_t *tl, *td;
    352     static unsigned int bl, bd;
    353     static int resumeCopy = 0;
    354 
    355     if (setup) { // 1st time we are called, copy in variables
    356         tl = my_tl;
    357         td = my_td;
    358         bl = my_bl;
    359         bd = my_bd;
    360         /* make local copies of globals */
    361         b = gunzip_bb;              /* initialize bit buffer */
    362         k = gunzip_bk;
    363         w = gunzip_outbuf_count;            /* initialize gunzip_window position */
    364 
    365         /* inflate the coded data */
    366         ml = mask_bits[bl]; /* precompute masks for speed */
    367         md = mask_bits[bd];
    368         return 0; // Don't actually do anything the first time
    369     }
    370 
    371     if (resumeCopy) goto do_copy;
     457/* called once from inflate_block */
     458
     459/* map formerly local static variables to globals */
     460#define ml inflate_codes_ml
     461#define md inflate_codes_md
     462#define bb inflate_codes_bb
     463#define k  inflate_codes_k
     464#define w  inflate_codes_w
     465#define tl inflate_codes_tl
     466#define td inflate_codes_td
     467#define bl inflate_codes_bl
     468#define bd inflate_codes_bd
     469#define nn inflate_codes_nn
     470#define dd inflate_codes_dd
     471static void inflate_codes_setup(STATE_PARAM huft_t * my_tl, huft_t * my_td, const unsigned my_bl, const unsigned my_bd)
     472{
     473    tl = my_tl;
     474    td = my_td;
     475    bl = my_bl;
     476    bd = my_bd;
     477    /* make local copies of globals */
     478    bb = gunzip_bb;         /* initialize bit buffer */
     479    k = gunzip_bk;
     480    w = gunzip_outbuf_count;    /* initialize gunzip_window position */
     481    /* inflate the coded data */
     482    ml = mask_bits[bl];     /* precompute masks for speed */
     483    md = mask_bits[bd];
     484}
     485/* called once from inflate_get_next_window */
     486static int inflate_codes(STATE_PARAM_ONLY)
     487{
     488    unsigned e; /* table entry flag/number of extra bits */
     489    huft_t *t;  /* pointer to table entry */
     490
     491    if (resume_copy) goto do_copy;
    372492
    373493    while (1) {         /* do until end of block */
    374         b = fill_bitbuffer(b, &k, bl);
    375         if ((e = (t = tl + ((unsigned) b & ml))->e) > 16)
     494        bb = fill_bitbuffer(PASS_STATE bb, &k, bl);
     495        t = tl + ((unsigned) bb & ml);
     496        e = t->e;
     497        if (e > 16)
    376498            do {
    377499                if (e == 99) {
     500//shouldn't we propagate error?
    378501                    bb_error_msg_and_die("inflate_codes error 1");
    379502                }
    380                 b >>= t->b;
     503                bb >>= t->b;
    381504                k -= t->b;
    382505                e -= 16;
    383                 b = fill_bitbuffer(b, &k, e);
    384             } while ((e =
    385                       (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
    386         b >>= t->b;
     506                bb = fill_bitbuffer(PASS_STATE bb, &k, e);
     507                t = t->v.t + ((unsigned) bb & mask_bits[e]);
     508                e = t->e;
     509            } while (e > 16);
     510        bb >>= t->b;
    387511        k -= t->b;
    388512        if (e == 16) {  /* then it's a literal */
    389513            gunzip_window[w++] = (unsigned char) t->v.n;
    390             if (w == gunzip_wsize) {
    391                 gunzip_outbuf_count = (w);
     514            if (w == GUNZIP_WSIZE) {
     515                gunzip_outbuf_count = w;
    392516                //flush_gunzip_window();
    393517                w = 0;
     
    395519            }
    396520        } else {        /* it's an EOB or a length */
    397 
    398521            /* exit if end of block */
    399522            if (e == 15) {
     
    402525
    403526            /* get length of block to copy */
    404             b = fill_bitbuffer(b, &k, e);
    405             n = t->v.n + ((unsigned) b & mask_bits[e]);
    406             b >>= e;
     527            bb = fill_bitbuffer(PASS_STATE bb, &k, e);
     528            nn = t->v.n + ((unsigned) bb & mask_bits[e]);
     529            bb >>= e;
    407530            k -= e;
    408531
    409532            /* decode distance of block to copy */
    410             b = fill_bitbuffer(b, &k, bd);
    411             if ((e = (t = td + ((unsigned) b & md))->e) > 16)
     533            bb = fill_bitbuffer(PASS_STATE bb, &k, bd);
     534            t = td + ((unsigned) bb & md);
     535            e = t->e;
     536            if (e > 16)
    412537                do {
    413538                    if (e == 99)
     539//shouldn't we propagate error?
    414540                        bb_error_msg_and_die("inflate_codes error 2");
    415                     b >>= t->b;
     541                    bb >>= t->b;
    416542                    k -= t->b;
    417543                    e -= 16;
    418                     b = fill_bitbuffer(b, &k, e);
    419                 } while ((e =
    420                           (t =
    421                            t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
    422             b >>= t->b;
     544                    bb = fill_bitbuffer(PASS_STATE bb, &k, e);
     545                    t = t->v.t + ((unsigned) bb & mask_bits[e]);
     546                    e = t->e;
     547                } while (e > 16);
     548            bb >>= t->b;
    423549            k -= t->b;
    424             b = fill_bitbuffer(b, &k, e);
    425             d = w - t->v.n - ((unsigned) b & mask_bits[e]);
    426             b >>= e;
     550            bb = fill_bitbuffer(PASS_STATE bb, &k, e);
     551            dd = w - t->v.n - ((unsigned) bb & mask_bits[e]);
     552            bb >>= e;
    427553            k -= e;
    428554
    429555            /* do the copy */
    430 do_copy:        do {
    431                 n -= (e =
    432                       (e =
    433                        gunzip_wsize - ((d &= gunzip_wsize - 1) > w ? d : w)) > n ? n : e);
    434                /* copy to new buffer to prevent possible overwrite */
    435                 if (w - d >= e) {   /* (this test assumes unsigned comparison) */
    436                     memcpy(gunzip_window + w, gunzip_window + d, e);
     556 do_copy:
     557            do {
     558                /* Was: nn -= (e = (e = GUNZIP_WSIZE - ((dd &= GUNZIP_WSIZE - 1) > w ? dd : w)) > nn ? nn : e); */
     559                /* Who wrote THAT?? rewritten as: */
     560                dd &= GUNZIP_WSIZE - 1;
     561                e = GUNZIP_WSIZE - (dd > w ? dd : w);
     562                if (e > nn) e = nn;
     563                nn -= e;
     564
     565                /* copy to new buffer to prevent possible overwrite */
     566                if (w - dd >= e) {  /* (this test assumes unsigned comparison) */
     567                    memcpy(gunzip_window + w, gunzip_window + dd, e);
    437568                    w += e;
    438                     d += e;
     569                    dd += e;
    439570                } else {
    440                    /* do it slow to avoid memcpy() overlap */
    441                    /* !NOMEMCPY */
     571                    /* do it slow to avoid memcpy() overlap */
     572                    /* !NOMEMCPY */
    442573                    do {
    443                         gunzip_window[w++] = gunzip_window[d++];
     574                        gunzip_window[w++] = gunzip_window[dd++];
    444575                    } while (--e);
    445576                }
    446                 if (w == gunzip_wsize) {
    447                     gunzip_outbuf_count = (w);
    448                     if (n) resumeCopy = 1;
    449                     else resumeCopy = 0;
     577                if (w == GUNZIP_WSIZE) {
     578                    gunzip_outbuf_count = w;
     579                    resume_copy = (nn != 0);
    450580                    //flush_gunzip_window();
    451581                    w = 0;
    452582                    return 1;
    453583                }
    454             } while (n);
    455             resumeCopy = 0;
     584            } while (nn);
     585            resume_copy = 0;
    456586        }
    457587    }
    458588
    459589    /* restore the globals from the locals */
    460     gunzip_outbuf_count = w;            /* restore global gunzip_window pointer */
    461     gunzip_bb = b            /* restore global bit buffer */
     590    gunzip_outbuf_count = w;    /* restore global gunzip_window pointer */
     591    gunzip_bb = bb;         /* restore global bit buffer */
    462592    gunzip_bk = k;
    463593
     
    470600    return 0;
    471601}
    472 
    473 static int inflate_stored(int my_n, int my_b_stored, int my_k_stored, int setup)
    474 {
    475     static unsigned int n, b_stored, k_stored, w;
    476     if (setup) {
    477         n = my_n;
    478         b_stored = my_b_stored;
    479         k_stored = my_k_stored;
    480         w = gunzip_outbuf_count;        /* initialize gunzip_window position */
    481         return 0; // Don't do anything first time
    482     }
    483 
     602#undef ml
     603#undef md
     604#undef bb
     605#undef k
     606#undef w
     607#undef tl
     608#undef td
     609#undef bl
     610#undef bd
     611#undef nn
     612#undef dd
     613
     614
     615/* called once from inflate_block */
     616static void inflate_stored_setup(STATE_PARAM int my_n, int my_b, int my_k)
     617{
     618    inflate_stored_n = my_n;
     619    inflate_stored_b = my_b;
     620    inflate_stored_k = my_k;
     621    /* initialize gunzip_window position */
     622    inflate_stored_w = gunzip_outbuf_count;
     623}
     624/* called once from inflate_get_next_window */
     625static int inflate_stored(STATE_PARAM_ONLY)
     626{
    484627    /* read and output the compressed data */
    485     while (n--) {
    486         b_stored = fill_bitbuffer(b_stored, &k_stored, 8);
    487         gunzip_window[w++] = (unsigned char) b_stored;
    488         if (w == gunzip_wsize) {
    489             gunzip_outbuf_count = (w);
     628    while (inflate_stored_n--) {
     629        inflate_stored_b = fill_bitbuffer(PASS_STATE inflate_stored_b, &inflate_stored_k, 8);
     630        gunzip_window[inflate_stored_w++] = (unsigned char) inflate_stored_b;
     631        if (inflate_stored_w == GUNZIP_WSIZE) {
     632            gunzip_outbuf_count = inflate_stored_w;
    490633            //flush_gunzip_window();
    491             w = 0;
    492             b_stored >>= 8;
    493             k_stored -= 8;
     634            inflate_stored_w = 0;
     635            inflate_stored_b >>= 8;
     636            inflate_stored_k -= 8;
    494637            return 1; // We have a block
    495638        }
    496         b_stored >>= 8;
    497         k_stored -= 8;
     639        inflate_stored_b >>= 8;
     640        inflate_stored_k -= 8;
    498641    }
    499642
    500643    /* restore the globals from the locals */
    501     gunzip_outbuf_count = w;        /* restore global gunzip_window pointer */
    502     gunzip_bb = b_stored;   /* restore global bit buffer */
    503     gunzip_bk = k_stored;
     644    gunzip_outbuf_count = inflate_stored_w;     /* restore global gunzip_window pointer */
     645    gunzip_bb = inflate_stored_b;   /* restore global bit buffer */
     646    gunzip_bk = inflate_stored_k;
    504647    return 0; // Finished
    505648}
     649
    506650
    507651/*
     
    511655 * GLOBAL VARIABLES: bb, kk,
    512656 */
    513  // Return values: -1 = inflate_stored, -2 = inflate_codes
    514 static int inflate_block(int *e)
     657/* Return values: -1 = inflate_stored, -2 = inflate_codes */
     658/* One callsite in inflate_get_next_window */
     659static int inflate_block(STATE_PARAM smallint *e)
    515660{
    516661    unsigned t;         /* block type */
    517     register unsigned int b;    /* bit buffer */
    518     unsigned int k; /* number of bits in bit buffer */
     662    unsigned b; /* bit buffer */
     663    unsigned k; /* number of bits in bit buffer */
    519664
    520665    /* make local bit buffer */
     
    524669
    525670    /* read in last block bit */
    526     b = fill_bitbuffer(b, &k, 1);
    527     *e = (int) b & 1;
     671    b = fill_bitbuffer(PASS_STATE b, &k, 1);
     672    *e = b & 1;
    528673    b >>= 1;
    529674    k -= 1;
    530675
    531676    /* read in block type */
    532     b = fill_bitbuffer(b, &k, 2);
     677    b = fill_bitbuffer(PASS_STATE b, &k, 2);
    533678    t = (unsigned) b & 3;
    534679    b >>= 2;
     
    543688    case 0:         /* Inflate stored */
    544689    {
    545         unsigned int n; /* number of bytes in block */
    546         unsigned int b_stored;  /* bit buffer */
    547         unsigned int k_stored;  /* number of bits in bit buffer */
     690        unsigned n; /* number of bytes in block */
     691        unsigned b_stored;  /* bit buffer */
     692        unsigned k_stored;  /* number of bits in bit buffer */
    548693
    549694        /* make local copies of globals */
     
    557702
    558703        /* get the length and its complement */
    559         b_stored = fill_bitbuffer(b_stored, &k_stored, 16);
     704        b_stored = fill_bitbuffer(PASS_STATE b_stored, &k_stored, 16);
    560705        n = ((unsigned) b_stored & 0xffff);
    561706        b_stored >>= 16;
    562707        k_stored -= 16;
    563708
    564         b_stored = fill_bitbuffer(b_stored, &k_stored, 16);
     709        b_stored = fill_bitbuffer(PASS_STATE b_stored, &k_stored, 16);
    565710        if (n != (unsigned) ((~b_stored) & 0xffff)) {
    566711            return 1;   /* error in compressed data */
     
    569714        k_stored -= 16;
    570715
    571         inflate_stored(n, b_stored, k_stored, 1); // Setup inflate_stored
     716        inflate_stored_setup(PASS_STATE n, b_stored, k_stored); // Setup inflate_stored
     717
    572718        return -1;
    573719    }
    574     case 1:         /* Inflate fixed
    575                            * decompress an inflated type 1 (fixed Huffman codes) block.  We should
    576                            * either replace this with a custom decoder, or at least precompute the
    577                            * Huffman tables.
    578                         */
     720    case 1:
     721    /* Inflate fixed
     722     * decompress an inflated type 1 (fixed Huffman codes) block.  We should
     723     * either replace this with a custom decoder, or at least precompute the
     724     * Huffman tables. */
    579725    {
    580726        int i;          /* temporary variable */
    581727        huft_t *tl;     /* literal/length code table */
    582728        huft_t *td;     /* distance code table */
    583         unsigned int bl;            /* lookup bits for tl */
    584         unsigned int bd;            /* lookup bits for td */
    585         unsigned int l[288];    /* length list for huft_build */
     729        unsigned bl;            /* lookup bits for tl */
     730        unsigned bd;            /* lookup bits for td */
     731        unsigned l[288];    /* length list for huft_build */
    586732
    587733        /* set up literal table */
     
    599745        }
    600746        bl = 7;
    601         if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) {
     747        i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl);
     748        if (i != 0) {
    602749            return i;
    603750        }
     
    608755        }
    609756        bd = 5;
    610         if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) {
     757        i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd);
     758        if (i > 1) {
    611759            huft_free(tl);
    612760            return i;
     
    614762
    615763        /* decompress until an end-of-block code */
    616         inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes
     764        inflate_codes_setup(PASS_STATE tl, td, bl, bd); // Setup inflate_codes
    617765
    618766        /* huft_free code moved into inflate_codes */
     
    627775        huft_t *tl;     /* literal/length code table */
    628776        huft_t *td;     /* distance code table */
    629         unsigned int i;         /* temporary variables */
    630         unsigned int j;
    631         unsigned int l;     /* last length */
    632         unsigned int m;     /* mask for bit lengths table */
    633         unsigned int n;     /* number of lengths to get */
    634         unsigned int bl;            /* lookup bits for tl */
    635         unsigned int bd;            /* lookup bits for td */
    636         unsigned int nb;    /* number of bit length codes */
    637         unsigned int nl;    /* number of literal/length codes */
    638         unsigned int nd;    /* number of distance codes */
    639 
    640         unsigned int ll[286 + 30];  /* literal/length and distance code lengths */
    641         unsigned int b_dynamic; /* bit buffer */
    642         unsigned int k_dynamic; /* number of bits in bit buffer */
     777        unsigned i;         /* temporary variables */
     778        unsigned j;
     779        unsigned l;     /* last length */
     780        unsigned m;     /* mask for bit lengths table */
     781        unsigned n;     /* number of lengths to get */
     782        unsigned bl;            /* lookup bits for tl */
     783        unsigned bd;            /* lookup bits for td */
     784        unsigned nb;    /* number of bit length codes */
     785        unsigned nl;    /* number of literal/length codes */
     786        unsigned nd;    /* number of distance codes */
     787
     788        unsigned ll[286 + 30];  /* literal/length and distance code lengths */
     789        unsigned b_dynamic; /* bit buffer */
     790        unsigned k_dynamic; /* number of bits in bit buffer */
    643791
    644792        /* make local bit buffer */
     
    647795
    648796        /* read in table lengths */
    649         b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 5);
    650         nl = 257 + ((unsigned int) b_dynamic & 0x1f);   /* number of literal/length codes */
     797        b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5);
     798        nl = 257 + ((unsigned) b_dynamic & 0x1f);   /* number of literal/length codes */
    651799
    652800        b_dynamic >>= 5;
    653801        k_dynamic -= 5;
    654         b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 5);
    655         nd = 1 + ((unsigned int) b_dynamic & 0x1f); /* number of distance codes */
     802        b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5);
     803        nd = 1 + ((unsigned) b_dynamic & 0x1f); /* number of distance codes */
    656804
    657805        b_dynamic >>= 5;
    658806        k_dynamic -= 5;
    659         b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 4);
    660         nb = 4 + ((unsigned int) b_dynamic & 0xf);  /* number of bit length codes */
     807        b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 4);
     808        nb = 4 + ((unsigned) b_dynamic & 0xf);  /* number of bit length codes */
    661809
    662810        b_dynamic >>= 4;
     
    668816        /* read in bit-length-code lengths */
    669817        for (j = 0; j < nb; j++) {
    670             b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 3);
    671             ll[border[j]] = (unsigned int) b_dynamic & 7;
     818            b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3);
     819            ll[border[j]] = (unsigned) b_dynamic & 7;
    672820            b_dynamic >>= 3;
    673821            k_dynamic -= 3;
     
    691839        m = mask_bits[bl];
    692840        i = l = 0;
    693         while ((unsigned int) i < n) {
    694             b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, (unsigned int)bl);
    695             j = (td = tl + ((unsigned int) b_dynamic & m))->b;
     841        while ((unsigned) i < n) {
     842            b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, (unsigned)bl);
     843            j = (td = tl + ((unsigned) b_dynamic & m))->b;
    696844            b_dynamic >>= j;
    697845            k_dynamic -= j;
     
    700848                ll[i++] = l = j;    /* save last length in l */
    701849            } else if (j == 16) {   /* repeat last length 3 to 6 times */
    702                 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 2);
    703                 j = 3 + ((unsigned int) b_dynamic & 3);
     850                b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 2);
     851                j = 3 + ((unsigned) b_dynamic & 3);
    704852                b_dynamic >>= 2;
    705853                k_dynamic -= 2;
    706                 if ((unsigned int) i + j > n) {
     854                if ((unsigned) i + j > n) {
    707855                    return 1;
    708856                }
     
    711859                }
    712860            } else if (j == 17) {   /* 3 to 10 zero length codes */
    713                 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 3);
    714                 j = 3 + ((unsigned int) b_dynamic & 7);
     861                b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3);
     862                j = 3 + ((unsigned) b_dynamic & 7);
    715863                b_dynamic >>= 3;
    716864                k_dynamic -= 3;
    717                 if ((unsigned int) i + j > n) {
     865                if ((unsigned) i + j > n) {
    718866                    return 1;
    719867                }
     
    723871                l = 0;
    724872            } else {    /* j == 18: 11 to 138 zero length codes */
    725                 b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 7);
    726                 j = 11 + ((unsigned int) b_dynamic & 0x7f);
     873                b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 7);
     874                j = 11 + ((unsigned) b_dynamic & 0x7f);
    727875                b_dynamic >>= 7;
    728876                k_dynamic -= 7;
    729                 if ((unsigned int) i + j > n) {
     877                if ((unsigned) i + j > n) {
    730878                    return 1;
    731879                }
     
    747895        bl = lbits;
    748896
    749         if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) {
     897        i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl);
     898        if (i != 0) {
    750899            if (i == 1) {
    751                 bb_error_msg_and_die("Incomplete literal tree");
    752                 huft_free(tl);
     900//shouldn't we propagate error?
     901                bb_error_msg_and_die("incomplete literal tree");
     902                /* huft_free(tl); */
    753903            }
    754904            return i;   /* incomplete code set */
     
    756906
    757907        bd = dbits;
    758         if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) {
     908        i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd);
     909        if (i != 0) {
    759910            if (i == 1) {
     911//shouldn't we propagate error?
    760912                bb_error_msg_and_die("incomplete distance tree");
    761                 huft_free(td);
     913                /* huft_free(td); */
    762914            }
    763915            huft_free(tl);
     
    766918
    767919        /* decompress until an end-of-block code */
    768         inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes
     920        inflate_codes_setup(PASS_STATE tl, td, bl, bd); // Setup inflate_codes
    769921
    770922        /* huft_free code moved into inflate_codes */
     
    774926    default:
    775927        /* bad block type */
    776         bb_error_msg_and_die("bad block type %d\n", t);
    777     }
    778 }
    779 
    780 static void calculate_gunzip_crc(void)
     928//shouldn't we propagate error?
     929        bb_error_msg_and_die("bad block type %d", t);
     930    }
     931}
     932
     933/* Two callsites, both in inflate_get_next_window */
     934static void calculate_gunzip_crc(STATE_PARAM_ONLY)
    781935{
    782936    int n;
     
    787941}
    788942
    789 static int inflate_get_next_window(void)
    790 {
    791     static int method = -1; // Method == -1 for stored, -2 for codes
    792     static int e = 0;
    793     static int needAnotherBlock = 1;
    794 
     943/* One callsite in inflate_unzip_internal */
     944static int inflate_get_next_window(STATE_PARAM_ONLY)
     945{
    795946    gunzip_outbuf_count = 0;
    796947
    797     while(1) {
     948    while (1) {
    798949        int ret;
    799950
    800         if (needAnotherBlock) {
    801             if(e) {
    802                 calculate_gunzip_crc();
    803                 e = 0;
    804                 needAnotherBlock = 1;
    805                 return 0;
    806             } // Last block
    807             method = inflate_block(&e);
    808             needAnotherBlock = 0;
     951        if (need_another_block) {
     952            if (end_reached) {
     953                calculate_gunzip_crc(PASS_STATE_ONLY);
     954                end_reached = 0;
     955                need_another_block = 1;
     956                return 0; /* Last block */
     957            }
     958            method = inflate_block(PASS_STATE &end_reached);
     959            need_another_block = 0;
    809960        }
    810961
    811962        switch (method) {
    812             case -1:    ret = inflate_stored(0,0,0,0);
    813                     break;
    814             case -2:    ret = inflate_codes(0,0,0,0,0);
    815                     break;
    816             default:    bb_error_msg_and_die("inflate error %d", method);
     963        case -1:
     964            ret = inflate_stored(PASS_STATE_ONLY);
     965            break;
     966        case -2:
     967            ret = inflate_codes(PASS_STATE_ONLY);
     968            break;
     969        default:
     970//shouldn't we propagate error?
     971            bb_error_msg_and_die("inflate error %d", method);
    817972        }
    818973
    819974        if (ret == 1) {
    820             calculate_gunzip_crc();
     975            calculate_gunzip_crc(PASS_STATE_ONLY);
    821976            return 1; // More data left
    822         } else needAnotherBlock = 1; // End of that block
     977        }
     978        need_another_block = 1; // End of that block
    823979    }
    824980    /* Doesnt get here */
    825981}
    826982
    827 /* Initialise bytebuffer, be careful not to overfill the buffer */
    828 void inflate_init(unsigned int bufsize)
    829 {
    830     /* Set the bytebuffer size, default is same as gunzip_wsize */
    831     bytebuffer_max = bufsize + 8;
    832     bytebuffer_offset = 4;
    833     bytebuffer_size = 0;
    834 }
    835 
    836 void inflate_cleanup(void)
    837 {
    838     free(bytebuffer);
    839 }
    840 
    841 int inflate_unzip(int in, int out)
    842 {
     983
     984/* Called from unpack_gz_stream() and inflate_unzip() */
     985/* NB: bytebuffer is allocated here but freeing it is left to the caller! */
     986static USE_DESKTOP(long long) int
     987inflate_unzip_internal(STATE_PARAM int in, int out)
     988{
     989    USE_DESKTOP(long long) int n = 0;
    843990    ssize_t nwrote;
    844     typedef void (*sig_type) (int);
    845991
    846992    /* Allocate all global buffers (for DYN_ALLOC option) */
    847     gunzip_window = xmalloc(gunzip_wsize);
     993    gunzip_window = xmalloc(GUNZIP_WSIZE);
    848994    gunzip_outbuf_count = 0;
    849995    gunzip_bytes_out = 0;
     
    8551001
    8561002    /* Create the crc table */
    857     gunzip_crc_table = bb_crc32_filltable(0);
     1003    gunzip_crc_table = crc32_filltable(NULL, 0);
    8581004    gunzip_crc = ~0;
    859    
     1005
    8601006    /* Allocate space for buffer */
    8611007    bytebuffer = xmalloc(bytebuffer_max);
    8621008
    863     while(1) {
    864         int ret = inflate_get_next_window();
    865         nwrote = bb_full_write(out, gunzip_window, gunzip_outbuf_count);
    866         if (nwrote == -1) {
     1009    while (1) {
     1010        int r = inflate_get_next_window(PASS_STATE_ONLY);
     1011        nwrote = full_write(out, gunzip_window, gunzip_outbuf_count);
     1012        if (nwrote != gunzip_outbuf_count) {
    8671013            bb_perror_msg("write");
    868             return -1;
    869         }
    870         if (ret == 0) break;
    871     }
    872 
    873     /* Cleanup */
    874     free(gunzip_window);
    875     free(gunzip_crc_table);
     1014            n = -1;
     1015            goto ret;
     1016        }
     1017        USE_DESKTOP(n += nwrote;)
     1018        if (r == 0) break;
     1019    }
    8761020
    8771021    /* Store unused bytes in a global buffer so calling applets can access it */
     
    8841028        gunzip_bk -= 8;
    8851029    }
    886     return 0;
    887 }
    888 
    889 int inflate_gunzip(int in, int out)
     1030 ret:
     1031    /* Cleanup */
     1032    free(gunzip_window);
     1033    free(gunzip_crc_table);
     1034    return n;
     1035}
     1036
     1037
     1038USE_DESKTOP(long long) int
     1039inflate_unzip(inflate_unzip_result *res, unsigned bufsize, int in, int out)
     1040{
     1041    USE_DESKTOP(long long) int n;
     1042    DECLARE_STATE;
     1043
     1044    ALLOC_STATE;
     1045
     1046    bytebuffer_max = bufsize + 8;
     1047    bytebuffer_offset = 4;
     1048    n = inflate_unzip_internal(PASS_STATE in, out);
     1049
     1050    res->crc = gunzip_crc;
     1051    res->bytes_out = gunzip_bytes_out;
     1052    free(bytebuffer);
     1053    DEALLOC_STATE;
     1054    return n;
     1055}
     1056
     1057
     1058USE_DESKTOP(long long) int
     1059unpack_gz_stream(int in, int out)
    8901060{
    8911061    uint32_t stored_crc = 0;
    892     unsigned int count;
    893 
    894     inflate_unzip(in, out);
     1062    unsigned count;
     1063    USE_DESKTOP(long long) int n;
     1064    DECLARE_STATE;
     1065
     1066    ALLOC_STATE;
     1067
     1068    bytebuffer_max = 0x8000;
     1069    n = inflate_unzip_internal(PASS_STATE in, out);
     1070
     1071    if (n < 0) goto ret;
    8951072
    8961073    /* top up the input buffer with the rest of the trailer */
    8971074    count = bytebuffer_size - bytebuffer_offset;
    8981075    if (count < 8) {
    899         bb_xread_all(in, &bytebuffer[bytebuffer_size], 8 - count);
     1076        xread(in, &bytebuffer[bytebuffer_size], 8 - count);
     1077//shouldn't we propagate error?
    9001078        bytebuffer_size += 8 - count;
    9011079    }
     
    9081086    if (stored_crc != (~gunzip_crc)) {
    9091087        bb_error_msg("crc error");
    910         return -1;
     1088        n = -1;
     1089        goto ret;
    9111090    }
    9121091
     
    9141093    if (gunzip_bytes_out !=
    9151094        (bytebuffer[bytebuffer_offset] | (bytebuffer[bytebuffer_offset+1] << 8) |
    916         (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))) {
    917         bb_error_msg("Incorrect length");
    918         return -1;
    919     }
    920 
    921     return 0;
    922 }
     1095        (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))
     1096    ) {
     1097        bb_error_msg("incorrect length");
     1098        n = -1;
     1099    }
     1100 ret:
     1101    free(bytebuffer);
     1102    DEALLOC_STATE;
     1103    return n;
     1104}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/filter_accept_all.c

    r821 r1765  
    66 */
    77
    8 #include <stdlib.h>
     8#include "libbb.h"
    99#include "unarchive.h"
    1010
     
    1212char filter_accept_all(archive_handle_t *archive_handle)
    1313{
    14     if (archive_handle->file_header->name) {
    15         return(EXIT_SUCCESS);
    16     } else {
    17         return(EXIT_FAILURE);
    18     }
     14    if (archive_handle->file_header->name)
     15        return EXIT_SUCCESS;
     16    return EXIT_FAILURE;
    1917}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/filter_accept_list.c

    r821 r1765  
    66 */
    77
    8 #include <stdlib.h>
     8#include "libbb.h"
    99#include "unarchive.h"
    1010
     
    1414char filter_accept_list(archive_handle_t *archive_handle)
    1515{
    16     if (find_list_entry(archive_handle->accept, archive_handle->file_header->name)) {
    17         return(EXIT_SUCCESS);
    18     } else {
    19         return(EXIT_FAILURE);
    20     }
     16    if (find_list_entry(archive_handle->accept, archive_handle->file_header->name))
     17        return EXIT_SUCCESS;
     18    return EXIT_FAILURE;
    2119}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/filter_accept_list_reassign.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 *  Copyright (C) 2002 by Glenn McGrath
    34 *
    4  *  This program is free software; you can redistribute it and/or modify
    5  *  it under the terms of the GNU General Public License as published by
    6  *  the Free Software Foundation; either version 2 of the License, or
    7  *  (at your option) any later version.
    8  *
    9  *  This program is distributed in the hope that it will be useful,
    10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  *  GNU General Public License for more details.
    13  *
    14  *  You should have received a copy of the GNU General Public License
    15  *  along with this program; if not, write to the Free Software
    16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    176 */
    18 
    19 #include <stdlib.h>
    20 #include <string.h>
    21 #include <unistd.h>
    227
    238#include "libbb.h"
     
    2510
    2611/*
    27  *  Reassign the subarchive metadata parser based on the filename extension
    28  *  e.g. if its a .tar.gz modify archive_handle->sub_archive to process a .tar.gz
    29  *       or if its a .tar.bz2 make archive_handle->sub_archive handle that
     12 * Reassign the subarchive metadata parser based on the filename extension
     13 * e.g. if its a .tar.gz modify archive_handle->sub_archive to process a .tar.gz
     14 * or if its a .tar.bz2 make archive_handle->sub_archive handle that
    3015 */
    3116char filter_accept_list_reassign(archive_handle_t *archive_handle)
     
    3924
    4025        /* Modify the subarchive handler based on the extension */
    41 #ifdef CONFIG_FEATURE_DEB_TAR_GZ
     26#if ENABLE_FEATURE_DEB_TAR_GZ
    4227        if (strcmp(name_ptr, ".gz") == 0) {
    4328            archive_handle->action_data_subarchive = get_header_tar_gz;
    44             return(EXIT_SUCCESS);
     29            return EXIT_SUCCESS;
    4530        }
    4631#endif
    47 #ifdef CONFIG_FEATURE_DEB_TAR_BZ2
     32#if ENABLE_FEATURE_DEB_TAR_BZ2
    4833        if (strcmp(name_ptr, ".bz2") == 0) {
    4934            archive_handle->action_data_subarchive = get_header_tar_bz2;
    50             return(EXIT_SUCCESS);
     35            return EXIT_SUCCESS;
    5136        }
    5237#endif
    5338        if (ENABLE_FEATURE_DEB_TAR_LZMA && !strcmp(name_ptr, ".lzma")) {
    5439            archive_handle->action_data_subarchive = get_header_tar_lzma;
    55             return(EXIT_SUCCESS);
     40            return EXIT_SUCCESS;
    5641        }
    5742    }
    58     return(EXIT_FAILURE);
     43    return EXIT_FAILURE;
    5944}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/filter_accept_reject_list.c

    r821 r1765  
    66 */
    77
    8 #include <stdlib.h>
     8#include "libbb.h"
    99#include "unarchive.h"
    1010
     
    1515{
    1616    const char *key = archive_handle->file_header->name;
    17     const llist_t *reject_entry = find_list_entry(archive_handle->reject, key);
     17    const llist_t *reject_entry = find_list_entry2(archive_handle->reject, key);
    1818    const llist_t *accept_entry;
    1919
    2020    /* If the key is in a reject list fail */
    2121    if (reject_entry) {
    22         return(EXIT_FAILURE);
     22        return EXIT_FAILURE;
    2323    }
    24     accept_entry = find_list_entry(archive_handle->accept, key);
     24    accept_entry = find_list_entry2(archive_handle->accept, key);
    2525
    2626    /* Fail if an accept list was specified and the key wasnt in there */
    2727    if ((accept_entry == NULL) && archive_handle->accept) {
    28         return(EXIT_FAILURE);
     28        return EXIT_FAILURE;
    2929    }
    3030
    3131    /* Accepted */
    32     return(EXIT_SUCCESS);
     32    return EXIT_SUCCESS;
    3333}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/find_list_entry.c

    r902 r1765  
    77
    88#include <fnmatch.h>
    9 #include <stdlib.h>
     9#include "libbb.h"
    1010#include "unarchive.h"
    1111
    12 /* Find a string in a list */
     12/* Find a string in a shell pattern list */
    1313const llist_t *find_list_entry(const llist_t *list, const char *filename)
    1414{
    1515    while (list) {
    16         if (fnmatch(list->data, filename, FNM_LEADING_DIR) == 0) {
    17             return (list);
     16        if (fnmatch(list->data, filename, 0) == 0) {
     17            return list;
    1818        }
    1919        list = list->link;
    2020    }
    21     return(NULL);
     21    return NULL;
    2222}
     23
     24/* Same, but compares only path components present in pattern
     25 * (extra trailing path components in filename are assumed to match)
     26 */
     27const llist_t *find_list_entry2(const llist_t *list, const char *filename)
     28{
     29    char buf[PATH_MAX];
     30    int pattern_slash_cnt;
     31    const char *c;
     32    char *d;
     33
     34    while (list) {
     35        c = list->data;
     36        pattern_slash_cnt = 0;
     37        while (*c)
     38            if (*c++ == '/') pattern_slash_cnt++;
     39        c = filename;
     40        d = buf;
     41        /* paranoia is better that buffer overflows */
     42        while (*c && d != buf + sizeof(buf)-1) {
     43            if (*c == '/' && --pattern_slash_cnt < 0)
     44                break;
     45            *d++ = *c++;
     46        }
     47        *d = '\0';
     48        if (fnmatch(list->data, buf, 0) == 0) {
     49            return list;
     50        }
     51        list = list->link;
     52    }
     53    return NULL;
     54}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_ar.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/* Copyright 2001 Glenn McGrath.
    23 *
     
    45 */
    56
    6 #include <stdio.h>
    7 #include <stdlib.h>
    8 #include <string.h>
    9 #include <unistd.h>
     7#include "libbb.h"
    108#include "unarchive.h"
    11 #include "libbb.h"
    129
    1310char get_header_ar(archive_handle_t *archive_handle)
    1411{
     12    int err;
    1513    file_header_t *typed = archive_handle->file_header;
    1614    union {
     
    2422            char size[10];
    2523            char magic[2];
    26         } formated;
     24        } formatted;
    2725    } ar;
    28 #ifdef CONFIG_FEATURE_AR_LONG_FILENAMES
     26#if ENABLE_FEATURE_AR_LONG_FILENAMES
    2927    static char *ar_long_names;
    30     static unsigned int ar_long_name_size;
     28    static unsigned ar_long_name_size;
    3129#endif
    3230
    33     /* dont use bb_xread as we want to handle the error ourself */
     31    /* dont use xread as we want to handle the error ourself */
    3432    if (read(archive_handle->src_fd, ar.raw, 60) != 60) {
    3533        /* End Of File */
    36         return(EXIT_FAILURE);
     34        return EXIT_FAILURE;
    3735    }
    3836
     
    4341        /* fix up the header, we started reading 1 byte too early */
    4442        memmove(ar.raw, &ar.raw[1], 59);
    45         ar.raw[59] = bb_xread_char(archive_handle->src_fd);
     43        ar.raw[59] = xread_char(archive_handle->src_fd);
    4644        archive_handle->offset++;
    4745    }
     
    4947
    5048    /* align the headers based on the header magic */
    51     if ((ar.formated.magic[0] != '`') || (ar.formated.magic[1] != '\n')) {
    52         bb_error_msg_and_die("Invalid ar header");
    53     }
     49    if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n')
     50        bb_error_msg_and_die("invalid ar header");
    5451
    55     typed->mode = strtol(ar.formated.mode, NULL, 8);
    56     typed->mtime = atoi(ar.formated.date);
    57     typed->uid = atoi(ar.formated.uid);
    58     typed->gid = atoi(ar.formated.gid);
    59     typed->size = atoi(ar.formated.size);
     52    /* FIXME: more thorough routine would be in order here */
     53    /* (we have something like that in tar) */
     54    /* but for now we are lax. This code works because */
     55    /* on misformatted numbers bb_strtou returns all-ones */
     56    typed->mode = err = bb_strtou(ar.formatted.mode, NULL, 8);
     57    if (err == -1) bb_error_msg_and_die("invalid ar header");
     58    typed->mtime = err = bb_strtou(ar.formatted.date, NULL, 10);
     59    if (err == -1) bb_error_msg_and_die("invalid ar header");
     60    typed->uid = err = bb_strtou(ar.formatted.uid, NULL, 10);
     61    if (err == -1) bb_error_msg_and_die("invalid ar header");
     62    typed->gid = err = bb_strtou(ar.formatted.gid, NULL, 10);
     63    if (err == -1) bb_error_msg_and_die("invalid ar header");
     64    typed->size = err = bb_strtou(ar.formatted.size, NULL, 10);
     65    if (err == -1) bb_error_msg_and_die("invalid ar header");
    6066
    6167    /* long filenames have '/' as the first character */
    62     if (ar.formated.name[0] == '/') {
    63 #ifdef CONFIG_FEATURE_AR_LONG_FILENAMES
    64         if (ar.formated.name[1] == '/') {
     68    if (ar.formatted.name[0] == '/') {
     69#if ENABLE_FEATURE_AR_LONG_FILENAMES
     70        unsigned long_offset;
     71
     72        if (ar.formatted.name[1] == '/') {
    6573            /* If the second char is a '/' then this entries data section
    6674             * stores long filename for multiple entries, they are stored
     
    6876            ar_long_name_size = typed->size;
    6977            ar_long_names = xmalloc(ar_long_name_size);
    70             bb_xread_all(archive_handle->src_fd, ar_long_names, ar_long_name_size);
     78            xread(archive_handle->src_fd, ar_long_names, ar_long_name_size);
    7179            archive_handle->offset += ar_long_name_size;
    7280            /* This ar entries data section only contained filenames for other records
    7381             * they are stored in the static ar_long_names for future reference */
    74             return (get_header_ar(archive_handle)); /* Return next header */
    75         } else if (ar.formated.name[1] == ' ') {
     82            return get_header_ar(archive_handle); /* Return next header */
     83        }
     84
     85        if (ar.formatted.name[1] == ' ') {
    7686            /* This is the index of symbols in the file for compilers */
    7787            data_skip(archive_handle);
    7888            archive_handle->offset += typed->size;
    79             return (get_header_ar(archive_handle)); /* Return next header */
    80         } else {
    81             /* The number after the '/' indicates the offset in the ar data section
    82             (saved in variable long_name) that conatains the real filename */
    83             const unsigned int long_offset = atoi(&ar.formated.name[1]);
    84             if (long_offset >= ar_long_name_size) {
    85                 bb_error_msg_and_die("Cant resolve long filename");
    86             }
    87             typed->name = bb_xstrdup(ar_long_names + long_offset);
     89            return get_header_ar(archive_handle); /* Return next header */
    8890        }
     91
     92        /* The number after the '/' indicates the offset in the ar data section
     93         * (saved in variable long_name) that conatains the real filename */
     94        long_offset = atoi(&ar.formatted.name[1]);
     95        if (long_offset >= ar_long_name_size) {
     96            bb_error_msg_and_die("can't resolve long filename");
     97        }
     98        typed->name = xstrdup(ar_long_names + long_offset);
    8999#else
    90100        bb_error_msg_and_die("long filenames not supported");
     
    92102    } else {
    93103        /* short filenames */
    94            typed->name = bb_xstrndup(ar.formated.name, 16);
     104        typed->name = xstrndup(ar.formatted.name, 16);
    95105    }
    96106
     
    100110        archive_handle->action_header(typed);
    101111        if (archive_handle->sub_archive) {
    102             while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS);
     112            while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS)
     113                /* repeat */;
    103114        } else {
    104115            archive_handle->action_data(archive_handle);
     
    112123    lseek(archive_handle->src_fd, archive_handle->offset, SEEK_SET);
    113124
    114     return(EXIT_SUCCESS);
     125    return EXIT_SUCCESS;
    115126}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_cpio.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/* Copyright 2002 Laurence Anderson
    23 *
     
    45 */
    56
    6 #include <stdio.h>
    7 #include <stdlib.h>
    8 #include <string.h>
    9 #include <unistd.h>
    10 #include <sys/sysmacros.h>     /* major() and minor() */
     7#include "libbb.h"
    118#include "unarchive.h"
    12 #include "libbb.h"
    139
    1410typedef struct hardlinks_s {
    15     file_header_t *entry;
     11    char *name;
    1612    int inode;
    1713    struct hardlinks_s *next;
     
    2117{
    2218    static hardlinks_t *saved_hardlinks = NULL;
    23     static unsigned short pending_hardlinks = 0;
     19    static unsigned pending_hardlinks = 0;
     20    static int inode;
     21
    2422    file_header_t *file_header = archive_handle->file_header;
    2523    char cpio_header[110];
    2624    int namesize;
    2725    char dummy[16];
    28     int major, minor, nlink, inode;
     26    int major, minor, nlink;
    2927
    3028    if (pending_hardlinks) { /* Deal with any pending hardlinks */
    31         hardlinks_t *tmp;
    32         hardlinks_t *oldtmp;
     29        hardlinks_t *tmp, *oldtmp;
    3330
    3431        tmp = saved_hardlinks;
    3532        oldtmp = NULL;
    3633
     34        file_header->link_target = file_header->name;
     35        file_header->size = 0;
     36
    3737        while (tmp) {
    38             bb_error_msg_and_die("need to fix this\n");
    39             if (tmp->entry->link_name) { /* Found a hardlink ready to be extracted */
    40                 file_header = tmp->entry;
    41                 if (oldtmp) {
    42                     oldtmp->next = tmp->next; /* Remove item from linked list */
    43                 } else {
    44                     saved_hardlinks = tmp->next;
    45                 }
    46                 free(tmp);
     38            if (tmp->inode != inode) {
     39                tmp = tmp->next;
    4740                continue;
    4841            }
     42
     43            file_header->name = tmp->name;
     44
     45            if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) {
     46                archive_handle->action_data(archive_handle);
     47                archive_handle->action_header(archive_handle->file_header);
     48            }
     49
     50            pending_hardlinks--;
     51
    4952            oldtmp = tmp;
    5053            tmp = tmp->next;
     54            free(oldtmp->name);
     55            free(oldtmp);
     56            if (oldtmp == saved_hardlinks)
     57                saved_hardlinks = tmp;
    5158        }
    52         pending_hardlinks = 0; /* No more pending hardlinks, read next file entry */
     59
     60        file_header->name = file_header->link_target;
     61
     62        if (pending_hardlinks > 1) {
     63            bb_error_msg("error resolving hardlink: archive made by GNU cpio 2.0-2.2?");
     64        }
     65
     66        /* No more pending hardlinks, read next file entry */
     67        pending_hardlinks = 0;
    5368    }
    5469
     
    5772
    5873    if (archive_xread_all_eof(archive_handle, (unsigned char*)cpio_header, 110) == 0) {
    59         return(EXIT_FAILURE);
     74        return EXIT_FAILURE;
    6075    }
    6176    archive_handle->offset += 110;
    6277
    63     if ((strncmp(&cpio_header[0], "07070", 5) != 0) || ((cpio_header[5] != '1') && (cpio_header[5] != '2'))) {
    64         bb_error_msg_and_die("Unsupported cpio format, use newc or crc");
     78    if (strncmp(&cpio_header[0], "07070", 5) != 0
     79     || (cpio_header[5] != '1' && cpio_header[5] != '2')
     80    ) {
     81        bb_error_msg_and_die("unsupported cpio format, use newc or crc");
    6582    }
    6683
    6784    {
    68         unsigned long tmpsize;
    69         sscanf(cpio_header, "%6c%8x%8x%8x%8x%8x%8lx%8lx%16c%8x%8x%8x%8c",
     85        unsigned long tmpsize;
     86        sscanf(cpio_header, "%6c%8x%8x%8x%8x%8x%8lx%8lx%16c%8x%8x%8x%8c",
    7087            dummy, &inode, (unsigned int*)&file_header->mode,
    7188            (unsigned int*)&file_header->uid, (unsigned int*)&file_header->gid,
    7289            &nlink, &file_header->mtime, &tmpsize,
    7390            dummy, &major, &minor, &namesize, dummy);
    74         file_header->size = tmpsize;
     91        file_header->size = tmpsize;
    7592    }
    7693
    77     file_header->name = (char *) xzalloc(namesize + 1);
    78     archive_xread_all(archive_handle, file_header->name, namesize); /* Read in filename */
     94    free(file_header->name);
     95    file_header->name = xzalloc(namesize + 1);
     96    /* Read in filename */
     97    xread(archive_handle->src_fd, file_header->name, namesize);
    7998    archive_handle->offset += namesize;
    8099
     
    83102
    84103    if (strcmp(file_header->name, "TRAILER!!!") == 0) {
    85         printf("%d blocks\n", (int) (archive_handle->offset % 512 ? (archive_handle->offset / 512) + 1 : archive_handle->offset / 512)); /* Always round up */
     104        /* Always round up */
     105        printf("%d blocks\n", (int) (archive_handle->offset % 512 ?
     106                                     archive_handle->offset / 512 + 1 :
     107                                     archive_handle->offset / 512
     108                                    ));
    86109        if (saved_hardlinks) { /* Bummer - we still have unresolved hardlinks */
    87110            hardlinks_t *tmp = saved_hardlinks;
    88111            hardlinks_t *oldtmp = NULL;
    89112            while (tmp) {
    90                 bb_error_msg("%s not created: cannot resolve hardlink", tmp->entry->name);
     113                bb_error_msg("%s not created: cannot resolve hardlink", tmp->name);
    91114                oldtmp = tmp;
    92115                tmp = tmp->next;
    93                 free (oldtmp->entry->name);
    94                 free (oldtmp->entry);
    95                 free (oldtmp);
     116                free(oldtmp->name);
     117                free(oldtmp);
    96118            }
    97119            saved_hardlinks = NULL;
    98120            pending_hardlinks = 0;
    99121        }
    100         return(EXIT_FAILURE);
     122        return EXIT_FAILURE;
    101123    }
    102124
    103125    if (S_ISLNK(file_header->mode)) {
    104         file_header->link_name = (char *) xzalloc(file_header->size + 1);
    105         archive_xread_all(archive_handle, file_header->link_name, file_header->size);
     126        file_header->link_target = xzalloc(file_header->size + 1);
     127        xread(archive_handle->src_fd, file_header->link_target, file_header->size);
    106128        archive_handle->offset += file_header->size;
    107129        file_header->size = 0; /* Stop possible seeks in future */
    108130    } else {
    109         file_header->link_name = NULL;
     131        file_header->link_target = NULL;
    110132    }
    111133    if (nlink > 1 && !S_ISDIR(file_header->mode)) {
     
    114136            new->next = saved_hardlinks;
    115137            new->inode = inode;
    116             new->entry = file_header;
     138            /* name current allocated, freed later */
     139            new->name = file_header->name;
     140            file_header->name = NULL;
    117141            saved_hardlinks = new;
    118             return(EXIT_SUCCESS); // Skip this one
    119         } else { /* Found the file with data in */
    120             hardlinks_t *tmp = saved_hardlinks;
    121             pending_hardlinks = 1;
    122             while (tmp) {
    123                 if (tmp->inode == inode) {
    124                     tmp->entry->link_name = bb_xstrdup(file_header->name);
    125                     nlink--;
    126                 }
    127                 tmp = tmp->next;
    128             }
    129             if (nlink > 1) {
    130                 bb_error_msg("error resolving hardlink: did you create the archive with GNU cpio 2.0-2.2?");
    131             }
     142            return EXIT_SUCCESS; /* Skip this one */
    132143        }
     144        /* Found the file with data in */
     145        pending_hardlinks = nlink;
    133146    }
    134147    file_header->device = makedev(major, minor);
     
    143156    archive_handle->offset += file_header->size;
    144157
    145     free(file_header->link_name);
     158    free(file_header->link_target);
    146159
    147     return (EXIT_SUCCESS);
     160    return EXIT_SUCCESS;
    148161}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_tar.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    23 *
     
    1112 */
    1213
    13 #include <stdio.h>
    14 #include <stdlib.h>
    15 #include <string.h>
    16 #include <sys/sysmacros.h>  /* For makedev */
     14#include "libbb.h"
    1715#include "unarchive.h"
    18 #include "libbb.h"
    19 
    20 #ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS
    21 static char *longname = NULL;
    22 static char *linkname = NULL;
    23 #endif
    24 
     16
     17#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
     18static char *longname;
     19static char *linkname;
     20#else
     21enum {
     22    longname = 0,
     23    linkname = 0,
     24};
     25#endif
     26
     27/* NB: _DESTROYS_ str[len] character! */
     28static unsigned long long getOctal(char *str, int len)
     29{
     30    unsigned long long v;
     31    /* Actually, tar header allows leading spaces also.
     32     * Oh well, we will be liberal and skip this...
     33     * The only downside probably is that we allow "-123" too :)
     34    if (*str < '0' || *str > '7')
     35        bb_error_msg_and_die("corrupted octal value in tar header");
     36    */
     37    str[len] = '\0';
     38    v = strtoull(str, &str, 8);
     39    if (*str && (!ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY || *str != ' '))
     40        bb_error_msg_and_die("corrupted octal value in tar header");
     41    return v;
     42}
     43#define GET_OCTAL(a) getOctal((a), sizeof(a))
     44
     45void BUG_tar_header_size(void);
    2546char get_header_tar(archive_handle_t *archive_handle)
    2647{
     48    static smallint end;
     49
    2750    file_header_t *file_header = archive_handle->file_header;
    28     union {
     51    struct {
    2952        /* ustar header, Posix 1003.1 */
    30         unsigned char raw[512];
    31         struct {
    32             char name[100]; /*   0-99 */
    33             char mode[8];   /* 100-107 */
    34             char uid[8];    /* 108-115 */
    35             char gid[8];    /* 116-123 */
    36             char size[12];  /* 124-135 */
    37             char mtime[12]; /* 136-147 */
    38             char chksum[8]; /* 148-155 */
    39             char typeflag;  /* 156-156 */
    40             char linkname[100]; /* 157-256 */
    41             char magic[6];  /* 257-262 */
    42             char version[2];    /* 263-264 */
    43             char uname[32]; /* 265-296 */
    44             char gname[32]; /* 297-328 */
    45             char devmajor[8];   /* 329-336 */
    46             char devminor[8];   /* 337-344 */
    47             char prefix[155];   /* 345-499 */
    48             char padding[12];   /* 500-512 */
    49         } formated;
     53        char name[100];     /*   0-99 */
     54        char mode[8];       /* 100-107 */
     55        char uid[8];        /* 108-115 */
     56        char gid[8];        /* 116-123 */
     57        char size[12];      /* 124-135 */
     58        char mtime[12];     /* 136-147 */
     59        char chksum[8];     /* 148-155 */
     60        char typeflag;      /* 156-156 */
     61        char linkname[100]; /* 157-256 */
     62        char magic[6];      /* 257-262 */
     63        char version[2];    /* 263-264 */
     64        char uname[32];     /* 265-296 */
     65        char gname[32];     /* 297-328 */
     66        char devmajor[8];   /* 329-336 */
     67        char devminor[8];   /* 337-344 */
     68        char prefix[155];   /* 345-499 */
     69        char padding[12];   /* 500-512 */
    5070    } tar;
    51     long sum = 0;
    52     long i;
    53     static int end = 0;
    54 
     71    char *cp;
     72    int i, sum_u, sum;
     73#if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY
     74    int sum_s;
     75#endif
     76    int parse_names;
     77
     78    if (sizeof(tar) != 512)
     79        BUG_tar_header_size();
     80
     81#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
     82 again:
     83#endif
    5584    /* Align header */
    5685    data_align(archive_handle, 512);
    5786
    58     if (bb_full_read(archive_handle->src_fd, tar.raw, 512) != 512) {
    59         /* Assume end of file */
    60         bb_error_msg_and_die("Short header");
    61         //return(EXIT_FAILURE);
    62     }
     87 again_after_align:
     88
     89    xread(archive_handle->src_fd, &tar, 512);
    6390    archive_handle->offset += 512;
    6491
    6592    /* If there is no filename its an empty header */
    66     if (tar.formated.name[0] == 0) {
     93    if (tar.name[0] == 0) {
    6794        if (end) {
    6895            /* This is the second consecutive empty header! End of archive!
    6996             * Read until the end to empty the pipe from gz or bz2
    7097             */
    71             while (bb_full_read(archive_handle->src_fd, tar.raw, 512) == 512);
    72             return(EXIT_FAILURE);
     98            while (full_read(archive_handle->src_fd, &tar, 512) == 512)
     99                /* repeat */;
     100            return EXIT_FAILURE;
    73101        }
    74102        end = 1;
    75         return(EXIT_SUCCESS);
     103        return EXIT_SUCCESS;
    76104    }
    77105    end = 0;
     
    80108     * 0's are for the old tar format
    81109     */
    82     if (strncmp(tar.formated.magic, "ustar", 5) != 0) {
    83 #ifdef CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY
    84         if (strncmp(tar.formated.magic, "\0\0\0\0\0", 5) != 0)
    85 #endif
    86             bb_error_msg_and_die("Invalid tar magic");
    87     }
    88     /* Do checksum on headers */
    89     for (i =  0; i < 148 ; i++) {
    90         sum += tar.raw[i];
    91     }
    92     sum += ' ' * 8;
    93     for (i =  156; i < 512 ; i++) {
    94         sum += tar.raw[i];
    95     }
    96     if (sum != strtol(tar.formated.chksum, NULL, 8)) {
    97         bb_error_msg("Invalid tar header checksum");
    98         return(EXIT_FAILURE);
    99     }
    100 
    101 #ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS
     110    if (strncmp(tar.magic, "ustar", 5) != 0) {
     111#if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY
     112        if (memcmp(tar.magic, "\0\0\0\0", 5) != 0)
     113#endif
     114            bb_error_msg_and_die("invalid tar magic");
     115    }
     116
     117    /* Do checksum on headers.
     118     * POSIX says that checksum is done on unsigned bytes, but
     119     * Sun and HP-UX gets it wrong... more details in
     120     * GNU tar source. */
     121#if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY
     122    sum_s = ' ' * sizeof(tar.chksum);
     123#endif
     124    sum_u = ' ' * sizeof(tar.chksum);
     125    for (i = 0; i < 148; i++) {
     126        sum_u += ((unsigned char*)&tar)[i];
     127#if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY
     128        sum_s += ((signed char*)&tar)[i];
     129#endif
     130    }
     131    for (i = 156; i < 512; i++) {
     132        sum_u += ((unsigned char*)&tar)[i];
     133#if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY
     134        sum_s += ((signed char*)&tar)[i];
     135#endif
     136    }
     137#if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY
     138    sum = strtoul(tar.chksum, &cp, 8);
     139    if ((*cp && *cp != ' ')
     140     || (sum_u != sum USE_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum))
     141    ) {
     142        bb_error_msg_and_die("invalid tar header checksum");
     143    }
     144#else
     145    /* This field does not need special treatment (getOctal) */
     146    sum = xstrtoul(tar.chksum, 8);
     147    if (sum_u != sum USE_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) {
     148        bb_error_msg_and_die("invalid tar header checksum");
     149    }
     150#endif
     151
     152    /* 0 is reserved for high perf file, treat as normal file */
     153    if (!tar.typeflag) tar.typeflag = '0';
     154    parse_names = (tar.typeflag >= '0' && tar.typeflag <= '7');
     155
     156    /* getOctal trashes subsequent field, therefore we call it
     157     * on fields in reverse order */
     158    if (tar.devmajor[0]) {
     159        unsigned minor = GET_OCTAL(tar.devminor);
     160        unsigned major = GET_OCTAL(tar.devmajor);
     161        file_header->device = makedev(major, minor);
     162    }
     163    file_header->link_target = NULL;
     164    if (!linkname && parse_names && tar.linkname[0]) {
     165        /* we trash magic[0] here, it's ok */
     166        tar.linkname[sizeof(tar.linkname)] = '\0';
     167        file_header->link_target = xstrdup(tar.linkname);
     168        /* FIXME: what if we have non-link object with link_target? */
     169        /* Will link_target be free()ed? */
     170    }
     171    file_header->mtime = GET_OCTAL(tar.mtime);
     172    file_header->size = GET_OCTAL(tar.size);
     173    file_header->gid = GET_OCTAL(tar.gid);
     174    file_header->uid = GET_OCTAL(tar.uid);
     175    /* Set bits 0-11 of the files mode */
     176    file_header->mode = 07777 & GET_OCTAL(tar.mode);
     177
     178    file_header->name = NULL;
     179    if (!longname && parse_names) {
     180        /* we trash mode[0] here, it's ok */
     181        tar.name[sizeof(tar.name)] = '\0';
     182        if (tar.prefix[0]) {
     183            /* and padding[0] */
     184            tar.prefix[sizeof(tar.prefix)] = '\0';
     185            file_header->name = concat_path_file(tar.prefix, tar.name);
     186        } else
     187            file_header->name = xstrdup(tar.name);
     188    }
     189
     190    /* Set bits 12-15 of the files mode */
     191    /* (typeflag was not trashed because chksum does not use getOctal) */
     192    switch (tar.typeflag) {
     193    /* busybox identifies hard links as being regular files with 0 size and a link name */
     194    case '1':
     195        file_header->mode |= S_IFREG;
     196        break;
     197    case '7':
     198    /* case 0: */
     199    case '0':
     200#if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY
     201        if (last_char_is(file_header->name, '/')) {
     202            file_header->mode |= S_IFDIR;
     203        } else
     204#endif
     205        file_header->mode |= S_IFREG;
     206        break;
     207    case '2':
     208        file_header->mode |= S_IFLNK;
     209        break;
     210    case '3':
     211        file_header->mode |= S_IFCHR;
     212        break;
     213    case '4':
     214        file_header->mode |= S_IFBLK;
     215        break;
     216    case '5':
     217        file_header->mode |= S_IFDIR;
     218        break;
     219    case '6':
     220        file_header->mode |= S_IFIFO;
     221        break;
     222#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
     223    case 'L':
     224        /* free: paranoia: tar with several consecutive longnames */
     225        free(longname);
     226        /* For paranoia reasons we allocate extra NUL char */
     227        longname = xzalloc(file_header->size + 1);
     228        /* We read ASCIZ string, including NUL */
     229        xread(archive_handle->src_fd, longname, file_header->size);
     230        archive_handle->offset += file_header->size;
     231        /* return get_header_tar(archive_handle); */
     232        /* gcc 4.1.1 didn't optimize it into jump */
     233        /* so we will do it ourself, this also saves stack */
     234        goto again;
     235    case 'K':
     236        free(linkname);
     237        linkname = xzalloc(file_header->size + 1);
     238        xread(archive_handle->src_fd, linkname, file_header->size);
     239        archive_handle->offset += file_header->size;
     240        /* return get_header_tar(archive_handle); */
     241        goto again;
     242    case 'D':   /* GNU dump dir */
     243    case 'M':   /* Continuation of multi volume archive */
     244    case 'N':   /* Old GNU for names > 100 characters */
     245    case 'S':   /* Sparse file */
     246    case 'V':   /* Volume header */
     247#endif
     248    case 'g':   /* pax global header */
     249    case 'x': { /* pax extended header */
     250        off_t sz;
     251        bb_error_msg("warning: skipping header '%c'", tar.typeflag);
     252        sz = (file_header->size + 511) & ~(off_t)511;
     253        archive_handle->offset += sz;
     254        sz >>= 9; /* sz /= 512 but w/o contortions for signed div */
     255        while (sz--)
     256            xread(archive_handle->src_fd, &tar, 512);
     257        /* return get_header_tar(archive_handle); */
     258        goto again_after_align;
     259    }
     260    default:
     261        bb_error_msg_and_die("unknown typeflag: 0x%x", tar.typeflag);
     262    }
     263
     264#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
    102265    if (longname) {
    103266        file_header->name = longname;
    104267        longname = NULL;
    105268    }
    106     else if (linkname) {
    107         file_header->name = linkname;
     269    if (linkname) {
     270        file_header->link_target = linkname;
    108271        linkname = NULL;
    109     } else
    110 #endif
    111     {
    112         file_header->name = bb_xstrndup(tar.formated.name,100);
    113 
    114         if (tar.formated.prefix[0]) {
    115             char *temp = file_header->name;
    116             file_header->name = concat_path_file(tar.formated.prefix, temp);
    117             free(temp);
    118         }
    119     }
    120 
    121     file_header->uid = strtol(tar.formated.uid, NULL, 8);
    122     file_header->gid = strtol(tar.formated.gid, NULL, 8);
    123     file_header->size = strtol(tar.formated.size, NULL, 8);
    124     file_header->mtime = strtol(tar.formated.mtime, NULL, 8);
    125     file_header->link_name = (tar.formated.linkname[0] != '\0') ?
    126         bb_xstrdup(tar.formated.linkname) : NULL;
    127     file_header->device = makedev(strtol(tar.formated.devmajor, NULL, 8),
    128         strtol(tar.formated.devminor, NULL, 8));
    129 
    130     /* Set bits 0-11 of the files mode */
    131     file_header->mode = 07777 & strtol(tar.formated.mode, NULL, 8);
    132 
    133     /* Set bits 12-15 of the files mode */
    134     switch (tar.formated.typeflag) {
    135     /* busybox identifies hard links as being regular files with 0 size and a link name */
    136     case '1':
    137         file_header->mode |= S_IFREG;
    138         break;
    139     case '7':
    140         /* Reserved for high performance files, treat as normal file */
    141     case 0:
    142     case '0':
    143 #ifdef CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY
    144         if (last_char_is(file_header->name, '/')) {
    145             file_header->mode |= S_IFDIR;
    146         } else
    147 #endif
    148             file_header->mode |= S_IFREG;
    149         break;
    150     case '2':
    151         file_header->mode |= S_IFLNK;
    152         break;
    153     case '3':
    154         file_header->mode |= S_IFCHR;
    155         break;
    156     case '4':
    157         file_header->mode |= S_IFBLK;
    158         break;
    159     case '5':
    160         file_header->mode |= S_IFDIR;
    161         break;
    162     case '6':
    163         file_header->mode |= S_IFIFO;
    164         break;
    165 #ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS
    166     case 'L': {
    167             longname = xzalloc(file_header->size + 1);
    168             archive_xread_all(archive_handle, longname, file_header->size);
    169             archive_handle->offset += file_header->size;
    170 
    171             return(get_header_tar(archive_handle));
    172         }
    173     case 'K': {
    174             linkname = xzalloc(file_header->size + 1);
    175             archive_xread_all(archive_handle, linkname, file_header->size);
    176             archive_handle->offset += file_header->size;
    177 
    178             file_header->name = linkname;
    179             return(get_header_tar(archive_handle));
    180         }
    181     case 'D':   /* GNU dump dir */
    182     case 'M':   /* Continuation of multi volume archive*/
    183     case 'N':   /* Old GNU for names > 100 characters */
    184     case 'S':   /* Sparse file */
    185     case 'V':   /* Volume header */
    186 #endif
    187     case 'g':   /* pax global header */
    188     case 'x':   /* pax extended header */
    189         bb_error_msg("Ignoring extension type %c", tar.formated.typeflag);
    190         break;
    191     default:
    192         bb_error_msg("Unknown typeflag: 0x%x", tar.formated.typeflag);
    193     }
    194     {   /* Strip trailing '/' in directories */
    195         /* Must be done after mode is set as '/' is used to check if its a directory */
    196         char *tmp = last_char_is(file_header->name, '/');
    197         if (tmp) {
    198             *tmp = '\0';
    199         }
    200     }
     272    }
     273#endif
     274    if (!strncmp(file_header->name, "/../"+1, 3)
     275     || strstr(file_header->name, "/../")
     276    ) {
     277        bb_error_msg_and_die("name with '..' encountered: '%s'",
     278                file_header->name);
     279    }
     280
     281    /* Strip trailing '/' in directories */
     282    /* Must be done after mode is set as '/' is used to check if it's a directory */
     283    cp = last_char_is(file_header->name, '/');
    201284
    202285    if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) {
    203286        archive_handle->action_header(archive_handle->file_header);
     287        /* Note that we kill the '/' only after action_header() */
     288        /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */
     289        if (cp) *cp = '\0';
    204290        archive_handle->flags |= ARCHIVE_EXTRACT_QUIET;
    205291        archive_handle->action_data(archive_handle);
     
    207293    } else {
    208294        data_skip(archive_handle);
     295        free(file_header->name);
    209296    }
    210297    archive_handle->offset += file_header->size;
    211298
    212     free(file_header->link_name);
    213 
    214     return(EXIT_SUCCESS);
     299    free(file_header->link_target);
     300    /* Do not free(file_header->name)! */
     301
     302    return EXIT_SUCCESS;
    215303}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_tar_bz2.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  This program is free software; you can redistribute it and/or modify
    3  *  it under the terms of the GNU General Public License as published by
    4  *  the Free Software Foundation; either version 2 of the License, or
    5  *  (at your option) any later version.
    6  *
    7  *  This program is distributed in the hope that it will be useful,
    8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  *  GNU Library General Public License for more details.
    11  *
    12  *  You should have received a copy of the GNU General Public License
    13  *  along with this program; if not, write to the Free Software
    14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    154 */
    165
    17 #include <sys/types.h>
    18 #include <sys/wait.h>
    19 #include <signal.h>
    20 #include <stdio.h>
    21 #include <stdlib.h>
    22 #include <string.h>
    23 #include <unistd.h>
    246#include "libbb.h"
    257#include "unarchive.h"
     
    279char get_header_tar_bz2(archive_handle_t *archive_handle)
    2810{
    29     /* Cant lseek over pipe's */
    30     archive_handle->seek = seek_by_char;
     11    /* Can't lseek over pipes */
     12    archive_handle->seek = seek_by_read;
    3113
    32     archive_handle->src_fd = open_transformer(archive_handle->src_fd, uncompressStream);
     14    archive_handle->src_fd = open_transformer(archive_handle->src_fd, unpack_bz2_stream, "bunzip2", "bunzip2", "-cf", "-", NULL);
    3315    archive_handle->offset = 0;
    34     while (get_header_tar(archive_handle) == EXIT_SUCCESS);
     16    while (get_header_tar(archive_handle) == EXIT_SUCCESS) /**/;
    3517
    3618    /* Can only do one file at a time */
    37     return(EXIT_FAILURE);
     19    return EXIT_FAILURE;
    3820}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_tar_gz.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  This program is free software; you can redistribute it and/or modify
    3  *  it under the terms of the GNU General Public License as published by
    4  *  the Free Software Foundation; either version 2 of the License, or
    5  *  (at your option) any later version.
    6  *
    7  *  This program is distributed in the hope that it will be useful,
    8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  *  GNU Library General Public License for more details.
    11  *
    12  *  You should have received a copy of the GNU General Public License
    13  *  along with this program; if not, write to the Free Software
    14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    154 */
    16 
    17 #include <stdlib.h>
    185
    196#include "libbb.h"
     
    229char get_header_tar_gz(archive_handle_t *archive_handle)
    2310{
     11#if BB_MMU
    2412    unsigned char magic[2];
     13#endif
    2514
    26     /* Cant lseek over pipe's */
    27     archive_handle->seek = seek_by_char;
     15    /* Can't lseek over pipes */
     16    archive_handle->seek = seek_by_read;
    2817
    29     archive_xread_all(archive_handle, &magic, 2);
     18    /* Check gzip magic only if open_transformer will invoke unpack_gz_stream (MMU case).
     19     * Otherwise, it will invoke an external helper "gunzip -cf" (NOMMU case) which will
     20     * need the header. */
     21#if BB_MMU
     22    xread(archive_handle->src_fd, &magic, 2);
    3023    if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) {
    31         bb_error_msg_and_die("Invalid gzip magic");
     24        bb_error_msg_and_die("invalid gzip magic");
    3225    }
    3326
    34     check_header_gzip(archive_handle->src_fd);
     27    check_header_gzip_or_die(archive_handle->src_fd);
     28#endif
    3529
    36     archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip);
     30    archive_handle->src_fd = open_transformer(archive_handle->src_fd, unpack_gz_stream, "gunzip", "gunzip", "-cf", "-", NULL);
    3731    archive_handle->offset = 0;
    38     while (get_header_tar(archive_handle) == EXIT_SUCCESS);
     32    while (get_header_tar(archive_handle) == EXIT_SUCCESS) /**/;
    3933
    4034    /* Can only do one file at a time */
    41     return(EXIT_FAILURE);
     35    return EXIT_FAILURE;
    4236}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_tar_lzma.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * Small lzma deflate implementation.
     
    67 */
    78
     9#include "libbb.h"
    810#include "unarchive.h"
    911
     
    1113{
    1214    /* Can't lseek over pipes */
    13     archive_handle->seek = seek_by_char;
     15    archive_handle->seek = seek_by_read;
    1416
    15     archive_handle->src_fd = open_transformer(archive_handle->src_fd, unlzma);
     17    archive_handle->src_fd = open_transformer(archive_handle->src_fd, unpack_lzma_stream, "unlzma", "unlzma", "-cf", "-", NULL);
    1618    archive_handle->offset = 0;
    17     while (get_header_tar(archive_handle) == EXIT_SUCCESS);
     19    while (get_header_tar(archive_handle) == EXIT_SUCCESS) /**/;
    1820
    1921    /* Can only do one file at a time */
    2022    return EXIT_FAILURE;
    2123}
    22 
    23 /* vi:set ts=4: */
  • branches/2.2.5/mindi-busybox/archival/libunarchive/header_list.c

    r821 r1765  
    1 #include <stdio.h>
     1/* vi: set sw=4 ts=4: */
     2/*
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     4 */
     5#include "libbb.h"
    26#include "unarchive.h"
    37
  • branches/2.2.5/mindi-busybox/archival/libunarchive/header_skip.c

    r821 r1765  
    1 #include <stdio.h>
     1/* vi: set sw=4 ts=4: */
     2/*
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     4 */
     5#include "libbb.h"
    26#include "unarchive.h"
    37
  • branches/2.2.5/mindi-busybox/archival/libunarchive/header_verbose_list.c

    r821 r1765  
    1 #include <stdio.h>
    2 #include <string.h>
    3 #include <time.h>
     1/* vi: set sw=4 ts=4: */
     2/*
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     4 */
     5
    46#include "libbb.h"
    57#include "unarchive.h"
     
    911    struct tm *mtime = localtime(&(file_header->mtime));
    1012
    11     printf("%s %d/%d%10u %4u-%02u-%02u %02u:%02u:%02u %s",
     13    printf("%s %d/%d %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s",
    1214        bb_mode_string(file_header->mode),
    1315        file_header->uid,
    1416        file_header->gid,
    15         (unsigned int) file_header->size,
     17        file_header->size,
    1618        1900 + mtime->tm_year,
    1719        1 + mtime->tm_mon,
     
    2224        file_header->name);
    2325
    24     if (file_header->link_name) {
    25         printf(" -> %s", file_header->link_name);
     26    if (file_header->link_target) {
     27        printf(" -> %s", file_header->link_target);
    2628    }
    2729    /* putchar isnt used anywhere else i dont think */
  • branches/2.2.5/mindi-busybox/archival/libunarchive/init_handle.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  This program is free software; you can redistribute it and/or modify
    3  *  it under the terms of the GNU General Public License as published by
    4  *  the Free Software Foundation; either version 2 of the License, or
    5  *  (at your option) any later version.
    6  *
    7  *  This program is distributed in the hope that it will be useful,
    8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  *  GNU General Public License for more details.
    11  *
    12  *  You should have received a copy of the GNU General Public License
    13  *  along with this program; if not, write to the Free Software
    14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    154 */
    165
    17 #include <unistd.h>
    18 #include <string.h>
    196#include "libbb.h"
    207#include "unarchive.h"
     
    2411    archive_handle_t *archive_handle;
    2512
    26     /* Initialise default values */
     13    /* Initialize default values */
    2714    archive_handle = xzalloc(sizeof(archive_handle_t));
    28     archive_handle->file_header = xmalloc(sizeof(file_header_t));
     15    archive_handle->file_header = xzalloc(sizeof(file_header_t));
    2916    archive_handle->action_header = header_skip;
    3017    archive_handle->action_data = data_skip;
     
    3219    archive_handle->seek = seek_by_jump;
    3320
    34     return(archive_handle);
     21    return archive_handle;
    3522}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/open_transformer.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    34 */
    45
    5 #include <stdlib.h>
    6 #include <unistd.h>
    7 
    86#include "libbb.h"
    9 
    107#include "unarchive.h"
    118
    129/* transformer(), more than meets the eye */
    13 int open_transformer(int src_fd, int (*transformer)(int src_fd, int dst_fd))
     10/*
     11 * On MMU machine, the transform_prog and ... are stripped
     12 * by a macro in include/unarchive.h. On NOMMU, transformer is stripped.
     13 */
     14int open_transformer(int src_fd,
     15    USE_DESKTOP(long long) int (*transformer)(int src_fd, int dst_fd),
     16    const char *transform_prog, ...)
    1417{
    1518    int fd_pipe[2];
    1619    int pid;
    1720
    18     if (pipe(fd_pipe) != 0) {
    19         bb_perror_msg_and_die("Can't create pipe");
    20     }
     21    xpipe(fd_pipe);
    2122
     23#if BB_MMU
    2224    pid = fork();
    23     if (pid == -1) {
    24         bb_perror_msg_and_die("Fork failed");
    25     }
     25#else
     26    pid = vfork();
     27#endif
     28    if (pid == -1)
     29        bb_perror_msg_and_die("fork failed");
    2630
    2731    if (pid == 0) {
     32#if !BB_MMU
     33        va_list ap;
     34#endif
    2835        /* child process */
    29         close(fd_pipe[0]); /* We don't wan't to read from the parent */
    30         transformer(src_fd, fd_pipe[1]);
    31         close(fd_pipe[1]); /* Send EOF */
    32         close(src_fd);
    33         exit(0);
    34         /* notreached */
     36        close(fd_pipe[0]); /* We don't wan't to read from the parent */
     37        // FIXME: error check?
     38#if BB_MMU
     39        transformer(src_fd, fd_pipe[1]);
     40        if (ENABLE_FEATURE_CLEAN_UP) {
     41            close(fd_pipe[1]); /* Send EOF */
     42            close(src_fd);
     43        }
     44        exit(0);
     45#else
     46        xmove_fd(src_fd, 0);
     47        xmove_fd(fd_pipe[1], 1);
     48        va_start(ap, transform_prog);
     49        BB_EXECVP(transform_prog, ap);
     50        bb_perror_and_die("exec failed");
     51#endif
     52        /* notreached */
    3553    }
    3654
     
    3856    close(fd_pipe[1]); /* Don't want to write to the child */
    3957
    40     return(fd_pipe[0]);
     58    return fd_pipe[0];
    4159}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/seek_by_jump.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  This program is free software; you can redistribute it and/or modify
    3  *  it under the terms of the GNU General Public License as published by
    4  *  the Free Software Foundation; either version 2 of the License, or
    5  *  (at your option) any later version.
    6  *
    7  *  This program is distributed in the hope that it will be useful,
    8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  *  GNU Library General Public License for more details.
    11  *
    12  *  You should have received a copy of the GNU General Public License
    13  *  along with this program; if not, write to the Free Software
    14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    154 */
    16 
    17 #include <sys/types.h>
    18 #include <errno.h>
    19 #include <unistd.h>
    20 #include <stdlib.h>
    215
    226#include "libbb.h"
     
    2610{
    2711    if (lseek(archive_handle->src_fd, (off_t) amount, SEEK_CUR) == (off_t) -1) {
    28 #ifdef CONFIG_FEATURE_UNARCHIVE_TAPE
     12#if ENABLE_FEATURE_UNARCHIVE_TAPE
    2913        if (errno == ESPIPE) {
    30             seek_by_char(archive_handle, amount);
     14            seek_by_read(archive_handle, amount);
    3115        } else
    3216#endif
    33             bb_perror_msg_and_die("Seek failure");
     17            bb_perror_msg_and_die("seek failure");
    3418    }
    3519}
  • branches/2.2.5/mindi-busybox/archival/libunarchive/unpack_ar_archive.c

    r821 r1765  
    1 /* vi:set ts=4:*/
     1/* vi: set sw=4 ts=4: */
    22/*
    33 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    44 */
    5 #include <fcntl.h>
    6 #include <stdlib.h>
    7 #include <string.h>
     5
     6#include "libbb.h"
    87#include "unarchive.h"
    9 #include "libbb.h"
    108
    119void unpack_ar_archive(archive_handle_t *ar_archive)
     
    1311    char magic[7];
    1412
    15     archive_xread_all(ar_archive, magic, 7);
     13    xread(ar_archive->src_fd, magic, 7);
    1614    if (strncmp(magic, "!<arch>", 7) != 0) {
    17         bb_error_msg_and_die("Invalid ar magic");
     15        bb_error_msg_and_die("invalid ar magic");
    1816    }
    1917    ar_archive->offset += 7;
  • branches/2.2.5/mindi-busybox/archival/rpm.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <unistd.h>
    12 #include <signal.h>
    13 #include <stdlib.h>
    14 #include <fcntl.h>
    15 #include <netinet/in.h> /* For ntohl & htonl function */
    16 #include <string.h> /* For strncmp */
    17 #include <sys/mman.h> /* For mmap */
    18 #include <time.h> /* For ctime */
    19 
    20 #include "busybox.h"
     10#include "libbb.h"
    2111#include "unarchive.h"
    2212
    23 #define RPM_HEADER_MAGIC "\216\255\350"
    24 #define RPM_CHAR_TYPE       1
    25 #define RPM_INT8_TYPE       2
    26 #define RPM_INT16_TYPE      3
    27 #define RPM_INT32_TYPE      4
    28 /* #define RPM_INT64_TYPE   5   ---- These aren't supported (yet) */
    29 #define RPM_STRING_TYPE     6
    30 #define RPM_BIN_TYPE        7
    31 #define RPM_STRING_ARRAY_TYPE   8
    32 #define RPM_I18NSTRING_TYPE 9
    33 
    34 #define RPMTAG_NAME             1000
    35 #define RPMTAG_VERSION          1001
    36 #define RPMTAG_RELEASE          1002
    37 #define RPMTAG_SUMMARY          1004
    38 #define RPMTAG_DESCRIPTION      1005
    39 #define RPMTAG_BUILDTIME        1006
    40 #define RPMTAG_BUILDHOST        1007
    41 #define RPMTAG_SIZE         1009
    42 #define RPMTAG_VENDOR           1011
    43 #define RPMTAG_LICENSE          1014
    44 #define RPMTAG_PACKAGER         1015
    45 #define RPMTAG_GROUP            1016
    46 #define RPMTAG_URL          1020
    47 #define RPMTAG_PREIN            1023
    48 #define RPMTAG_POSTIN           1024
    49 #define RPMTAG_FILEFLAGS        1037
    50 #define RPMTAG_FILEUSERNAME     1039
    51 #define RPMTAG_FILEGROUPNAME        1040
    52 #define RPMTAG_SOURCERPM        1044
    53 #define RPMTAG_PREINPROG        1085
    54 #define RPMTAG_POSTINPROG       1086
    55 #define RPMTAG_PREFIXS          1098
    56 #define RPMTAG_DIRINDEXES       1116
    57 #define RPMTAG_BASENAMES        1117
    58 #define RPMTAG_DIRNAMES         1118
    59 #define RPMFILE_CONFIG          (1 << 0)
    60 #define RPMFILE_DOC         (1 << 1)
     13#define RPM_HEADER_MAGIC        "\216\255\350"
     14#define RPM_CHAR_TYPE           1
     15#define RPM_INT8_TYPE           2
     16#define RPM_INT16_TYPE          3
     17#define RPM_INT32_TYPE          4
     18/* #define RPM_INT64_TYPE       5   ---- These aren't supported (yet) */
     19#define RPM_STRING_TYPE         6
     20#define RPM_BIN_TYPE            7
     21#define RPM_STRING_ARRAY_TYPE   8
     22#define RPM_I18NSTRING_TYPE     9
     23
     24#define TAG_NAME                1000
     25#define TAG_VERSION             1001
     26#define TAG_RELEASE             1002
     27#define TAG_SUMMARY             1004
     28#define TAG_DESCRIPTION         1005
     29#define TAG_BUILDTIME           1006
     30#define TAG_BUILDHOST           1007
     31#define TAG_SIZE                1009
     32#define TAG_VENDOR              1011
     33#define TAG_LICENSE             1014
     34#define TAG_PACKAGER            1015
     35#define TAG_GROUP               1016
     36#define TAG_URL                 1020
     37#define TAG_PREIN               1023
     38#define TAG_POSTIN              1024
     39#define TAG_FILEFLAGS           1037
     40#define TAG_FILEUSERNAME        1039
     41#define TAG_FILEGROUPNAME       1040
     42#define TAG_SOURCERPM           1044
     43#define TAG_PREINPROG           1085
     44#define TAG_POSTINPROG          1086
     45#define TAG_PREFIXS             1098
     46#define TAG_DIRINDEXES          1116
     47#define TAG_BASENAMES           1117
     48#define TAG_DIRNAMES            1118
     49#define RPMFILE_CONFIG          (1 << 0)
     50#define RPMFILE_DOC             (1 << 1)
    6151
    6252enum rpm_functions_e {
     
    8171static int tagcount;
    8272
    83 void extract_cpio_gz(int fd);
    84 rpm_index **rpm_gettags(int fd, int *num_tags);
    85 int bsearch_rpmtag(const void *key, const void *item);
    86 char *rpm_getstring(int tag, int itemindex);
    87 int rpm_getint(int tag, int itemindex);
    88 int rpm_getcount(int tag);
    89 void exec_script(int progtag, int datatag, char *prefix);
    90 void fileaction_dobackup(char *filename, int fileref);
    91 void fileaction_setowngrp(char *filename, int fileref);
    92 void fileaction_list(char *filename, int itemno);
    93 void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref));
    94 
     73static void extract_cpio_gz(int fd);
     74static rpm_index **rpm_gettags(int fd, int *num_tags);
     75static int bsearch_rpmtag(const void *key, const void *item);
     76static char *rpm_getstr(int tag, int itemindex);
     77static int rpm_getint(int tag, int itemindex);
     78static int rpm_getcount(int tag);
     79static void fileaction_dobackup(char *filename, int fileref);
     80static void fileaction_setowngrp(char *filename, int fileref);
     81static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref));
     82
     83int rpm_main(int argc, char **argv);
    9584int rpm_main(int argc, char **argv)
    9685{
    9786    int opt = 0, func = 0, rpm_fd, offset;
     87    const int pagesize = getpagesize();
    9888
    9989    while ((opt = getopt(argc, argv, "iqpldc")) != -1) {
    10090        switch (opt) {
    101         case 'i': // First arg: Install mode, with q: Information
    102             if (!func) func |= rpm_install;
     91        case 'i': /* First arg: Install mode, with q: Information */
     92            if (!func) func = rpm_install;
    10393            else func |= rpm_query_info;
    10494            break;
    105         case 'q': // First arg: Query mode
    106             if (!func) func |= rpm_query;
    107             else bb_show_usage();
    108             break;
    109         case 'p': // Query a package
     95        case 'q': /* First arg: Query mode */
     96            if (func) bb_show_usage();
     97            func = rpm_query;
     98            break;
     99        case 'p': /* Query a package */
    110100            func |= rpm_query_package;
    111101            break;
    112         case 'l': // List files in a package
     102        case 'l': /* List files in a package */
    113103            func |= rpm_query_list;
    114104            break;
    115         case 'd': // List doc files in a package (implies list)
     105        case 'd': /* List doc files in a package (implies list) */
    116106            func |= rpm_query_list;
    117107            func |= rpm_query_list_doc;
    118108            break;
    119         case 'c': // List config files in a package (implies list)
     109        case 'c': /* List config files in a package (implies list) */
    120110            func |= rpm_query_list;
    121111            func |= rpm_query_list_config;
     
    125115        }
    126116    }
    127 
    128     if (optind == argc) bb_show_usage();
    129     while (optind < argc) {
    130         rpm_fd = bb_xopen(argv[optind], O_RDONLY);
    131         mytags = rpm_gettags(rpm_fd, (int *) &tagcount);
    132         offset = lseek(rpm_fd, 0, SEEK_CUR);
    133         if (!mytags) { printf("Error reading rpm header\n"); exit(-1); }
    134         map = mmap(0, offset > getpagesize() ? (offset + offset % getpagesize()) : getpagesize(), PROT_READ, MAP_PRIVATE, rpm_fd, 0); // Mimimum is one page
     117    argv += optind;
     118    argc -= optind;
     119    if (!argc) bb_show_usage();
     120
     121    while (*argv) {
     122        rpm_fd = xopen(*argv++, O_RDONLY);
     123        mytags = rpm_gettags(rpm_fd, &tagcount);
     124        if (!mytags)
     125            bb_error_msg_and_die("error reading rpm header");
     126        offset = xlseek(rpm_fd, 0, SEEK_CUR);
     127        /* Mimimum is one page */
     128        map = mmap(0, offset > pagesize ? (offset + offset % pagesize) : pagesize, PROT_READ, MAP_PRIVATE, rpm_fd, 0);
     129
    135130        if (func & rpm_install) {
    136             loop_through_files(RPMTAG_BASENAMES, fileaction_dobackup); /* Backup any config files */
    137             extract_cpio_gz(rpm_fd); // Extact the archive
    138             loop_through_files(RPMTAG_BASENAMES, fileaction_setowngrp); /* Set the correct file uid/gid's */
    139         } else if (func & rpm_query && func & rpm_query_package) {
    140             if (!((func & rpm_query_info) || (func & rpm_query_list))) { // If just a straight query, just give package name
    141                 printf("%s-%s-%s\n", rpm_getstring(RPMTAG_NAME, 0), rpm_getstring(RPMTAG_VERSION, 0), rpm_getstring(RPMTAG_RELEASE, 0));
     131            /* Backup any config files */
     132            loop_through_files(TAG_BASENAMES, fileaction_dobackup);
     133            /* Extact the archive */
     134            extract_cpio_gz(rpm_fd);
     135            /* Set the correct file uid/gid's */
     136            loop_through_files(TAG_BASENAMES, fileaction_setowngrp);
     137        }
     138        else if ((func & (rpm_query|rpm_query_package)) == (rpm_query|rpm_query_package)) {
     139            if (!(func & (rpm_query_info|rpm_query_list))) {
     140                /* If just a straight query, just give package name */
     141                printf("%s-%s-%s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_RELEASE, 0));
    142142            }
    143143            if (func & rpm_query_info) {
     
    146146                struct tm *bdate;
    147147                char bdatestring[50];
    148                 printf("Name        : %-29sRelocations: %s\n", rpm_getstring(RPMTAG_NAME, 0), rpm_getstring(RPMTAG_PREFIXS, 0) ? rpm_getstring(RPMTAG_PREFIXS, 0) : "(not relocateable)");
    149                 printf("Version     : %-34sVendor: %s\n", rpm_getstring(RPMTAG_VERSION, 0), rpm_getstring(RPMTAG_VENDOR, 0) ? rpm_getstring(RPMTAG_VENDOR, 0) : "(none)");
    150                 bdate_time = rpm_getint(RPMTAG_BUILDTIME, 0);
     148                printf("Name        : %-29sRelocations: %s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_PREFIXS, 0) ? rpm_getstr(TAG_PREFIXS, 0) : "(not relocateable)");
     149                printf("Version     : %-34sVendor: %s\n", rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_VENDOR, 0) ? rpm_getstr(TAG_VENDOR, 0) : "(none)");
     150                bdate_time = rpm_getint(TAG_BUILDTIME, 0);
    151151                bdate = localtime((time_t *) &bdate_time);
    152152                strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate);
    153                 printf("Release     : %-30sBuild Date: %s\n", rpm_getstring(RPMTAG_RELEASE, 0), bdatestring);
    154                 printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstring(RPMTAG_BUILDHOST, 0));
    155                 printf("Group       : %-30sSource RPM: %s\n", rpm_getstring(RPMTAG_GROUP, 0), rpm_getstring(RPMTAG_SOURCERPM, 0));
    156                 printf("Size        : %-33dLicense: %s\n", rpm_getint(RPMTAG_SIZE, 0), rpm_getstring(RPMTAG_LICENSE, 0));
    157                 printf("URL         : %s\n", rpm_getstring(RPMTAG_URL, 0));
    158                 printf("Summary     : %s\n", rpm_getstring(RPMTAG_SUMMARY, 0));
    159                 printf("Description :\n%s\n", rpm_getstring(RPMTAG_DESCRIPTION, 0));
     153                printf("Release     : %-30sBuild Date: %s\n", rpm_getstr(TAG_RELEASE, 0), bdatestring);
     154                printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstr(TAG_BUILDHOST, 0));
     155                printf("Group       : %-30sSource RPM: %s\n", rpm_getstr(TAG_GROUP, 0), rpm_getstr(TAG_SOURCERPM, 0));
     156                printf("Size        : %-33dLicense: %s\n", rpm_getint(TAG_SIZE, 0), rpm_getstr(TAG_LICENSE, 0));
     157                printf("URL         : %s\n", rpm_getstr(TAG_URL, 0));
     158                printf("Summary     : %s\n", rpm_getstr(TAG_SUMMARY, 0));
     159                printf("Description :\n%s\n", rpm_getstr(TAG_DESCRIPTION, 0));
    160160            }
    161161            if (func & rpm_query_list) {
    162162                int count, it, flags;
    163                 count = rpm_getcount(RPMTAG_BASENAMES);
     163                count = rpm_getcount(TAG_BASENAMES);
    164164                for (it = 0; it < count; it++) {
    165                     flags = rpm_getint(RPMTAG_FILEFLAGS, it);
    166                     switch ((func & rpm_query_list_doc) + (func & rpm_query_list_config))
    167                     {
    168                         case rpm_query_list_doc: if (!(flags & RPMFILE_DOC)) continue; break;
    169                         case rpm_query_list_config: if (!(flags & RPMFILE_CONFIG)) continue; break;
    170                         case rpm_query_list_doc + rpm_query_list_config: if (!((flags & RPMFILE_CONFIG) || (flags & RPMFILE_DOC))) continue; break;
     165                    flags = rpm_getint(TAG_FILEFLAGS, it);
     166                    switch (func & (rpm_query_list_doc|rpm_query_list_config)) {
     167                    case rpm_query_list_doc:
     168                        if (!(flags & RPMFILE_DOC)) continue;
     169                        break;
     170                    case rpm_query_list_config:
     171                        if (!(flags & RPMFILE_CONFIG)) continue;
     172                        break;
     173                    case rpm_query_list_doc|rpm_query_list_config:
     174                        if (!(flags & (RPMFILE_CONFIG|RPMFILE_DOC))) continue;
     175                        break;
    171176                    }
    172                     printf("%s%s\n", rpm_getstring(RPMTAG_DIRNAMES, rpm_getint(RPMTAG_DIRINDEXES, it)), rpm_getstring(RPMTAG_BASENAMES, it));
     177                    printf("%s%s\n",
     178                        rpm_getstr(TAG_DIRNAMES, rpm_getint(TAG_DIRINDEXES, it)),
     179                        rpm_getstr(TAG_BASENAMES, it));
    173180                }
    174181            }
    175182        }
    176         optind++;
    177         free (mytags);
     183        free(mytags);
    178184    }
    179185    return 0;
    180186}
    181187
    182 void extract_cpio_gz(int fd) {
     188static void extract_cpio_gz(int fd)
     189{
    183190    archive_handle_t *archive_handle;
    184191    unsigned char magic[2];
    185 
    186     /* Initialise */
     192#if BB_MMU
     193    USE_DESKTOP(long long) int (*xformer)(int src_fd, int dst_fd);
     194    enum { xformer_prog = 0 };
     195#else
     196    enum { xformer = 0 };
     197    const char *xformer_prog;
     198#endif
     199
     200    /* Initialize */
    187201    archive_handle = init_handle();
    188     archive_handle->seek = seek_by_char;
     202    archive_handle->seek = seek_by_read;
    189203    //archive_handle->action_header = header_list;
    190204    archive_handle->action_data = data_extract_all;
     
    194208    archive_handle->offset = 0;
    195209
    196     bb_xread_all(archive_handle->src_fd, &magic, 2);
     210    xread(archive_handle->src_fd, &magic, 2);
     211#if BB_MMU
     212    xformer = unpack_gz_stream;
     213#else
     214    xformer_prog = "gunzip";
     215#endif
    197216    if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) {
    198         bb_error_msg_and_die("Invalid gzip magic");
    199     }
    200     check_header_gzip(archive_handle->src_fd);
    201     bb_xchdir("/"); // Install RPM's to root
    202 
    203     archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip);
     217        if (ENABLE_FEATURE_RPM_BZ2
     218         && (magic[0] == 0x42) && (magic[1] == 0x5a)) {
     219#if BB_MMU
     220            xformer = unpack_bz2_stream;
     221#else
     222            xformer_prog = "bunzip2";
     223#endif
     224    /* We can do better, need modifying unpack_bz2_stream to not require
     225     * first 2 bytes. Not very hard to do... I mean, TODO :) */
     226            xlseek(archive_handle->src_fd, -2, SEEK_CUR);
     227        } else
     228            bb_error_msg_and_die("no gzip"
     229                USE_FEATURE_RPM_BZ2("/bzip")
     230                " magic");
     231    } else {
     232        check_header_gzip_or_die(archive_handle->src_fd);
     233#if !BB_MMU
     234        /* NOMMU version of open_transformer execs an external unzipper that should
     235         * have the file position at the start of the file */
     236        xlseek(archive_handle->src_fd, 0, SEEK_SET);
     237#endif
     238    }
     239
     240    xchdir("/"); /* Install RPM's to root */
     241    archive_handle->src_fd = open_transformer(archive_handle->src_fd, xformer, xformer_prog, xformer_prog, "-cf", "-", NULL);
    204242    archive_handle->offset = 0;
    205     while (get_header_cpio(archive_handle) == EXIT_SUCCESS);
    206 }
    207 
    208 
    209 rpm_index **rpm_gettags(int fd, int *num_tags)
    210 {
    211     rpm_index **tags = xzalloc(200 * sizeof(struct rpmtag *)); /* We should never need mode than 200, and realloc later */
     243    while (get_header_cpio(archive_handle) == EXIT_SUCCESS)
     244        continue;
     245}
     246
     247
     248static rpm_index **rpm_gettags(int fd, int *num_tags)
     249{
     250    /* We should never need mode than 200, and realloc later */
     251    rpm_index **tags = xzalloc(200 * sizeof(struct rpmtag *));
    212252    int pass, tagindex = 0;
    213     lseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */
    214 
    215     for (pass = 0; pass < 2; pass++) { /* 1st pass is the signature headers, 2nd is the main stuff */
     253
     254    xlseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */
     255
     256    /* 1st pass is the signature headers, 2nd is the main stuff */
     257    for (pass = 0; pass < 2; pass++) {
    216258        struct {
    217259            char magic[3]; /* 3 byte magic: 0x8e 0xad 0xe8 */
     
    224266        int storepos;
    225267
    226         read(fd, &header, sizeof(header));
    227         if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0) return NULL; /* Invalid magic */
    228         if (header.version != 1) return NULL; /* This program only supports v1 headers */
     268        xread(fd, &header, sizeof(header));
     269        if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0)
     270            return NULL; /* Invalid magic */
     271        if (header.version != 1)
     272            return NULL; /* This program only supports v1 headers */
    229273        header.size = ntohl(header.size);
    230274        header.entries = ntohl(header.entries);
    231         storepos = lseek(fd,0,SEEK_CUR) + header.entries * 16;
     275        storepos = xlseek(fd,0,SEEK_CUR) + header.entries * 16;
    232276
    233277        while (header.entries--) {
    234278            tmpindex = tags[tagindex++] = xmalloc(sizeof(rpm_index));
    235             read(fd, tmpindex, sizeof(rpm_index));
    236             tmpindex->tag = ntohl(tmpindex->tag); tmpindex->type = ntohl(tmpindex->type); tmpindex->count = ntohl(tmpindex->count);
     279            xread(fd, tmpindex, sizeof(rpm_index));
     280            tmpindex->tag = ntohl(tmpindex->tag);
     281            tmpindex->type = ntohl(tmpindex->type);
     282            tmpindex->count = ntohl(tmpindex->count);
    237283            tmpindex->offset = storepos + ntohl(tmpindex->offset);
    238             if (pass==0) tmpindex->tag -= 743;
    239         }
    240         lseek(fd, header.size, SEEK_CUR); /* Seek past store */
    241         if (pass==0) lseek(fd, (8 - (lseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR); /* Skip padding to 8 byte boundary after reading signature headers */
    242     }
    243     tags = realloc(tags, tagindex * sizeof(struct rpmtag *)); /* realloc tags to save space */
     284            if (pass==0)
     285                tmpindex->tag -= 743;
     286        }
     287        xlseek(fd, header.size, SEEK_CUR); /* Seek past store */
     288        /* Skip padding to 8 byte boundary after reading signature headers */
     289        if (pass==0)
     290            xlseek(fd, (8 - (xlseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR);
     291    }
     292    tags = xrealloc(tags, tagindex * sizeof(struct rpmtag *)); /* realloc tags to save space */
    244293    *num_tags = tagindex;
    245294    return tags; /* All done, leave the file at the start of the gzipped cpio archive */
    246295}
    247296
    248 int bsearch_rpmtag(const void *key, const void *item)
     297static int bsearch_rpmtag(const void *key, const void *item)
    249298{
    250299    int *tag = (int *)key;
     
    253302}
    254303
    255 int rpm_getcount(int tag)
     304static int rpm_getcount(int tag)
    256305{
    257306    rpm_index **found;
    258307    found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
    259     if (!found) return 0;
    260     else return found[0]->count;
    261 }
    262 
    263 char *rpm_getstring(int tag, int itemindex)
     308    if (!found)
     309        return 0;
     310    return found[0]->count;
     311}
     312
     313static char *rpm_getstr(int tag, int itemindex)
    264314{
    265315    rpm_index **found;
    266316    found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
    267     if (!found || itemindex >= found[0]->count) return NULL;
     317    if (!found || itemindex >= found[0]->count)
     318        return NULL;
    268319    if (found[0]->type == RPM_STRING_TYPE || found[0]->type == RPM_I18NSTRING_TYPE || found[0]->type == RPM_STRING_ARRAY_TYPE) {
    269320        int n;
    270321        char *tmpstr = (char *) (map + found[0]->offset);
    271         for (n=0; n < itemindex; n++) tmpstr = tmpstr + strlen(tmpstr) + 1;
     322        for (n=0; n < itemindex; n++)
     323            tmpstr = tmpstr + strlen(tmpstr) + 1;
    272324        return tmpstr;
    273     } else return NULL;
    274 }
    275 
    276 int rpm_getint(int tag, int itemindex)
     325    }
     326    return NULL;
     327}
     328
     329static int rpm_getint(int tag, int itemindex)
    277330{
    278331    rpm_index **found;
    279     int n, *tmpint;
     332    int *tmpint; /* NB: using int8_t* would be easier to code */
     333
    280334    /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ...
    281335     * it's ok to ignore it because tag won't be used as a pointer */
    282336    found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
    283     if (!found || itemindex >= found[0]->count) return -1;
     337    if (!found || itemindex >= found[0]->count)
     338        return -1;
     339
    284340    tmpint = (int *) (map + found[0]->offset);
     341
    285342    if (found[0]->type == RPM_INT32_TYPE) {
    286         for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 4);
    287         return ntohl(*tmpint);
    288     } else if (found[0]->type == RPM_INT16_TYPE) {
    289         for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 2);
    290         return ntohs(*tmpint);
    291     } else if (found[0]->type == RPM_INT8_TYPE) {
    292         for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 1);
    293         return ntohs(*tmpint);
    294     } else return -1;
    295 }
    296 
    297 void fileaction_dobackup(char *filename, int fileref)
     343        tmpint = (int *) ((char *) tmpint + itemindex*4);
     344        /*return ntohl(*tmpint);*/
     345        /* int can be != int32_t */
     346        return ntohl(*(int32_t*)tmpint);
     347    }
     348    if (found[0]->type == RPM_INT16_TYPE) {
     349        tmpint = (int *) ((char *) tmpint + itemindex*2);
     350        /* ??? read int, and THEN ntohs() it?? */
     351        /*return ntohs(*tmpint);*/
     352        return ntohs(*(int16_t*)tmpint);
     353    }
     354    if (found[0]->type == RPM_INT8_TYPE) {
     355        tmpint = (int *) ((char *) tmpint + itemindex);
     356        /* ??? why we don't read byte here??? */
     357        /*return ntohs(*tmpint);*/
     358        return *(int8_t*)tmpint;
     359    }
     360    return -1;
     361}
     362
     363static void fileaction_dobackup(char *filename, int fileref)
    298364{
    299365    struct stat oldfile;
    300366    int stat_res;
    301367    char *newname;
    302     if (rpm_getint(RPMTAG_FILEFLAGS, fileref) & RPMFILE_CONFIG) { /* Only need to backup config files */
    303         stat_res = lstat (filename, &oldfile);
    304         if (stat_res == 0 && S_ISREG(oldfile.st_mode)) { /* File already exists  - really should check MD5's etc to see if different */
    305             newname = bb_xstrdup(filename);
    306             newname = strcat(newname, ".rpmorig");
     368    if (rpm_getint(TAG_FILEFLAGS, fileref) & RPMFILE_CONFIG) {
     369        /* Only need to backup config files */
     370        stat_res = lstat(filename, &oldfile);
     371        if (stat_res == 0 && S_ISREG(oldfile.st_mode)) {
     372            /* File already exists  - really should check MD5's etc to see if different */
     373            newname = xasprintf("%s.rpmorig", filename);
    307374            copy_file(filename, newname, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS);
    308375            remove_file(filename, FILEUTILS_RECUR | FILEUTILS_FORCE);
     
    312379}
    313380
    314 void fileaction_setowngrp(char *filename, int fileref)
     381static void fileaction_setowngrp(char *filename, int fileref)
    315382{
    316383    int uid, gid;
    317     uid = bb_xgetpwnam(rpm_getstring(RPMTAG_FILEUSERNAME, fileref));
    318     gid = bb_xgetgrnam(rpm_getstring(RPMTAG_FILEGROUPNAME, fileref));
    319     chown (filename, uid, gid);
    320 }
    321 
    322 void fileaction_list(char *filename, int ATTRIBUTE_UNUSED fileref)
    323 {
    324     printf("%s\n", filename);
    325 }
    326 
    327 void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref))
     384    uid = xuname2uid(rpm_getstr(TAG_FILEUSERNAME, fileref));
     385    gid = xgroup2gid(rpm_getstr(TAG_FILEGROUPNAME, fileref));
     386    chown(filename, uid, gid);
     387}
     388
     389static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref))
    328390{
    329391    int count = 0;
    330     while (rpm_getstring(filetag, count)) {
    331         char * filename = bb_xasprintf("%s%s",
    332             rpm_getstring(RPMTAG_DIRNAMES, rpm_getint(RPMTAG_DIRINDEXES,
    333             count)), rpm_getstring(RPMTAG_BASENAMES, count));
     392    while (rpm_getstr(filetag, count)) {
     393        char* filename = xasprintf("%s%s",
     394            rpm_getstr(TAG_DIRNAMES, rpm_getint(TAG_DIRINDEXES, count)),
     395            rpm_getstr(TAG_BASENAMES, count));
    334396        fileaction(filename, count++);
    335397        free(filename);
  • branches/2.2.5/mindi-busybox/archival/rpm2cpio.c

    r821 r1765  
    55 * Copyright (C) 2001 by Laurence Anderson
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    208 */
    21 #include <sys/types.h>
    22 #include <netinet/in.h> /* For ntohl & htonl function */
    23 #include <fcntl.h>
    24 #include <unistd.h>
    25 #include <string.h>
    26 #include "busybox.h"
     9#include "libbb.h"
    2710#include "unarchive.h"
    2811
     
    5336    struct rpm_header header;
    5437
    55     bb_xread_all(rpm_fd, &header, sizeof(struct rpm_header));
     38    xread(rpm_fd, &header, sizeof(struct rpm_header));
    5639    if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0) {
    57         bb_error_msg_and_die("Invalid RPM header magic"); /* Invalid magic */
     40        bb_error_msg_and_die("invalid RPM header magic"); /* Invalid magic */
    5841    }
    5942    if (header.version != 1) {
    60         bb_error_msg_and_die("Unsupported RPM header version"); /* This program only supports v1 headers */
     43        bb_error_msg_and_die("unsupported RPM header version"); /* This program only supports v1 headers */
    6144    }
    6245    header.entries = ntohl(header.entries);
     
    6750
    6851/* No getopt required */
     52int rpm2cpio_main(int argc, char **argv);
    6953int rpm2cpio_main(int argc, char **argv)
    7054{
     
    7660        rpm_fd = STDIN_FILENO;
    7761    } else {
    78         rpm_fd = bb_xopen(argv[1], O_RDONLY);
     62        rpm_fd = xopen(argv[1], O_RDONLY);
    7963    }
    8064
    81     bb_xread_all(rpm_fd, &lead, sizeof(struct rpm_lead));
     65    xread(rpm_fd, &lead, sizeof(struct rpm_lead));
    8266    if (strncmp((char *) &lead.magic, RPM_MAGIC, 4) != 0) {
    83         bb_error_msg_and_die("Invalid RPM magic"); /* Just check the magic, the rest is irrelevant */
     67        bb_error_msg_and_die("invalid RPM magic"); /* Just check the magic, the rest is irrelevant */
    8468    }
    8569
     
    9175    skip_header(rpm_fd);
    9276
    93     bb_xread_all(rpm_fd, &magic, 2);
     77    xread(rpm_fd, &magic, 2);
    9478    if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) {
    95         bb_error_msg_and_die("Invalid gzip magic");
     79        bb_error_msg_and_die("invalid gzip magic");
    9680    }
    9781
    98     check_header_gzip(rpm_fd);
    99     if (inflate_gunzip(rpm_fd, STDOUT_FILENO) != 0) {
    100         bb_error_msg("Error inflating");
     82    check_header_gzip_or_die(rpm_fd);
     83    if (unpack_gz_stream(rpm_fd, STDOUT_FILENO) < 0) {
     84        bb_error_msg("error inflating");
    10185    }
    10286
  • branches/2.2.5/mindi-busybox/archival/tar.c

    r821 r1765  
    2424 */
    2525
    26 #include <fcntl.h>
     26#include <fnmatch.h>
    2727#include <getopt.h>
    28 #include <search.h>
    29 #include <stdio.h>
    30 #include <stdlib.h>
    31 #include <unistd.h>
    32 #include <fnmatch.h>
    33 #include <string.h>
    34 #include <errno.h>
    35 #include <signal.h>
    36 #include <sys/wait.h>
    37 #include <sys/socket.h>
    38 #include <sys/sysmacros.h>     /* major() and minor() */
     28#include "libbb.h"
    3929#include "unarchive.h"
    40 #include "busybox.h"
    41 
    42 #ifdef CONFIG_FEATURE_TAR_CREATE
     30
     31#define block_buf bb_common_bufsiz1
     32
     33#if ENABLE_FEATURE_TAR_CREATE
    4334
    4435/* Tar file constants  */
     
    4738
    4839/* POSIX tar Header Block, from POSIX 1003.1-1990  */
    49 #define NAME_SIZE           100
    50 struct TarHeader {      /* byte offset */
    51     char name[NAME_SIZE];   /*   0-99 */
    52     char mode[8];       /* 100-107 */
    53     char uid[8];        /* 108-115 */
    54     char gid[8];        /* 116-123 */
    55     char size[12];      /* 124-135 */
    56     char mtime[12];     /* 136-147 */
    57     char chksum[8];     /* 148-155 */
    58     char typeflag;      /* 156-156 */
    59     char linkname[NAME_SIZE];   /* 157-256 */
    60     char magic[6];      /* 257-262 */
    61     char version[2];    /* 263-264 */
    62     char uname[32];     /* 265-296 */
    63     char gname[32];     /* 297-328 */
    64     char devmajor[8];   /* 329-336 */
    65     char devminor[8];   /* 337-344 */
    66     char prefix[155];   /* 345-499 */
    67     char padding[12];   /* 500-512 (pad to exactly the TAR_BLOCK_SIZE) */
     40#define NAME_SIZE      100
     41#define NAME_SIZE_STR "100"
     42typedef struct TarHeader TarHeader;
     43struct TarHeader {        /* byte offset */
     44    char name[NAME_SIZE];     /*   0-99 */
     45    char mode[8];             /* 100-107 */
     46    char uid[8];              /* 108-115 */
     47    char gid[8];              /* 116-123 */
     48    char size[12];            /* 124-135 */
     49    char mtime[12];           /* 136-147 */
     50    char chksum[8];           /* 148-155 */
     51    char typeflag;            /* 156-156 */
     52    char linkname[NAME_SIZE]; /* 157-256 */
     53    char magic[6];            /* 257-262 */
     54    char version[2];          /* 263-264 */
     55    char uname[32];           /* 265-296 */
     56    char gname[32];           /* 297-328 */
     57    char devmajor[8];         /* 329-336 */
     58    char devminor[8];         /* 337-344 */
     59    char prefix[155];         /* 345-499 */
     60    char padding[12];         /* 500-512 (pad to exactly the TAR_BLOCK_SIZE) */
    6861};
    69 typedef struct TarHeader TarHeader;
    7062
    7163/*
    72 ** writeTarFile(),  writeFileToTarball(), and writeTarHeader() are
     64** writeTarFile(), writeFileToTarball(), and writeTarHeader() are
    7365** the only functions that deal with the HardLinkInfo structure.
    7466** Even these functions use the xxxHardLinkInfo() functions.
     
    8476
    8577/* Some info to be carried along when creating a new tarball */
     78typedef struct TarBallInfo TarBallInfo;
    8679struct TarBallInfo {
    87     char *fileName;         /* File name of the tarball */
    8880    int tarFd;              /* Open-for-write file descriptor
    8981                               for the tarball */
     
    9789    HardLinkInfo *hlInfo;   /* Hard Link Info for the current file */
    9890};
    99 typedef struct TarBallInfo TarBallInfo;
    10091
    10192/* A nice enum with all the possible tar file content types */
     
    116107
    117108/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
    118 static inline void addHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr,
     109static void addHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr,
    119110                    struct stat *statbuf,
    120                     const char *name)
     111                    const char *fileName)
    121112{
    122113    /* Note: hlInfoHeadPtr can never be NULL! */
    123114    HardLinkInfo *hlInfo;
    124115
    125     hlInfo = (HardLinkInfo *) xmalloc(sizeof(HardLinkInfo) + strlen(name));
     116    hlInfo = xmalloc(sizeof(HardLinkInfo) + strlen(fileName));
    126117    hlInfo->next = *hlInfoHeadPtr;
    127118    *hlInfoHeadPtr = hlInfo;
     
    129120    hlInfo->ino = statbuf->st_ino;
    130121    hlInfo->linkCount = statbuf->st_nlink;
    131     strcpy(hlInfo->name, name);
     122    strcpy(hlInfo->name, fileName);
    132123}
    133124
    134125static void freeHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr)
    135126{
    136     HardLinkInfo *hlInfo = NULL;
    137     HardLinkInfo *hlInfoNext = NULL;
     127    HardLinkInfo *hlInfo;
     128    HardLinkInfo *hlInfoNext;
    138129
    139130    if (hlInfoHeadPtr) {
     
    146137        *hlInfoHeadPtr = NULL;
    147138    }
    148     return;
    149139}
    150140
    151141/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
    152 static inline HardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, struct stat *statbuf)
     142static HardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, struct stat *statbuf)
    153143{
    154144    while (hlInfo) {
     
    157147        hlInfo = hlInfo->next;
    158148    }
    159     return (hlInfo);
     149    return hlInfo;
    160150}
    161151
    162152/* Put an octal string into the specified buffer.
    163  * The number is zero and space padded and possibly null padded.
    164  * Returns TRUE if successful.  */
    165 static int putOctal(char *cp, int len, long value)
    166 {
    167     int tempLength;
    168     char tempBuffer[32];
     153 * The number is zero padded and possibly null terminated.
     154 * Stores low-order bits only if whole value does not fit. */
     155static void putOctal(char *cp, int len, off_t value)
     156{
     157    char tempBuffer[sizeof(off_t)*3+1];
    169158    char *tempString = tempBuffer;
    170 
    171     /* Create a string of the specified length with an initial space,
    172      * leading zeroes and the octal number, and a trailing null.  */
    173     sprintf(tempString, "%0*lo", len - 1, value);
    174 
    175     /* If the string is too large, suppress the leading space. */
    176     tempLength = strlen(tempString) + 1;
    177     if (tempLength > len) {
    178         tempLength--;
     159    int width;
     160
     161    width = sprintf(tempBuffer, "%0*"OFF_FMT"o", len, value);
     162    tempString += (width - len);
     163
     164    /* If string has leading zeroes, we can drop one */
     165    /* and field will have trailing '\0' */
     166    /* (increases chances of compat with other tars) */
     167    if (tempString[0] == '0')
    179168        tempString++;
    180     }
    181 
    182     /* If the string is still too large, suppress the trailing null.  */
    183     if (tempLength > len)
    184         tempLength--;
    185 
    186     /* If the string is still too large, fail.  */
    187     if (tempLength > len)
    188         return FALSE;
    189 
    190     /* Copy the string to the field.  */
     169
     170    /* Copy the string to the field */
    191171    memcpy(cp, tempString, len);
    192 
    193     return TRUE;
    194 }
     172}
     173#define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b))
     174
     175static void chksum_and_xwrite(int fd, struct TarHeader* hp)
     176{
     177    /* POSIX says that checksum is done on unsigned bytes
     178     * (Sun and HP-UX gets it wrong... more details in
     179     * GNU tar source) */
     180    const unsigned char *cp;
     181    int chksum, size;
     182
     183    strcpy(hp->magic, "ustar  ");
     184
     185    /* Calculate and store the checksum (i.e., the sum of all of the bytes of
     186     * the header).  The checksum field must be filled with blanks for the
     187     * calculation.  The checksum field is formatted differently from the
     188     * other fields: it has 6 digits, a null, then a space -- rather than
     189     * digits, followed by a null like the other fields... */
     190    memset(hp->chksum, ' ', sizeof(hp->chksum));
     191    cp = (const unsigned char *) hp;
     192    chksum = 0;
     193    size = sizeof(*hp);
     194    do { chksum += *cp++; } while (--size);
     195    putOctal(hp->chksum, sizeof(hp->chksum)-1, chksum);
     196
     197    /* Now write the header out to disk */
     198    xwrite(fd, hp, sizeof(*hp));
     199}
     200
     201#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
     202static void writeLongname(int fd, int type, const char *name, int dir)
     203{
     204    static const struct {
     205        char mode[8];             /* 100-107 */
     206        char uid[8];              /* 108-115 */
     207        char gid[8];              /* 116-123 */
     208        char size[12];            /* 124-135 */
     209        char mtime[12];           /* 136-147 */
     210    } prefilled = {
     211        "0000000",
     212        "0000000",
     213        "0000000",
     214        "00000000000",
     215        "00000000000",
     216    };
     217    struct TarHeader header;
     218    int size;
     219
     220    dir = !!dir; /* normalize: 0/1 */
     221    size = strlen(name) + 1 + dir; /* GNU tar uses strlen+1 */
     222    /* + dir: account for possible '/' */
     223
     224    memset(&header, 0, sizeof(header));
     225    strcpy(header.name, "././@LongLink");
     226    memcpy(header.mode, prefilled.mode, sizeof(prefilled));
     227    PUT_OCTAL(header.size, size);
     228    header.typeflag = type;
     229    chksum_and_xwrite(fd, &header);
     230
     231    /* Write filename[/] and pad the block. */
     232    /* dir=0: writes 'name<NUL>', pads */
     233    /* dir=1: writes 'name', writes '/<NUL>', pads */
     234    dir *= 2;
     235    xwrite(fd, name, size - dir);
     236    xwrite(fd, "/", dir);
     237    size = (-size) & (TAR_BLOCK_SIZE-1);
     238    memset(&header, 0, size);
     239    xwrite(fd, &header, size);
     240}
     241#endif
    195242
    196243/* Write out a tar header for the specified file/directory/whatever */
    197 static inline int writeTarHeader(struct TarBallInfo *tbInfo,
    198         const char *header_name, const char *real_name, struct stat *statbuf)
    199 {
    200     long chksum = 0;
     244void BUG_tar_header_size(void);
     245static int writeTarHeader(struct TarBallInfo *tbInfo,
     246        const char *header_name, const char *fileName, struct stat *statbuf)
     247{
    201248    struct TarHeader header;
    202     const unsigned char *cp = (const unsigned char *) &header;
    203     ssize_t size = sizeof(struct TarHeader);
    204 
    205     memset(&header, 0, size);
    206 
    207     safe_strncpy(header.name, header_name, sizeof(header.name));
    208 
    209     putOctal(header.mode, sizeof(header.mode), statbuf->st_mode);
    210     putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
    211     putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
    212     putOctal(header.size, sizeof(header.size), 0);  /* Regular file size is handled later */
    213     putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
    214     strcpy(header.magic, "ustar  ");
    215 
    216     /* Enter the user and group names (default to root if it fails) */
    217     if (bb_getpwuid(header.uname, statbuf->st_uid, sizeof(header.uname)) == NULL)
    218         strcpy(header.uname, "root");
    219     if (bb_getgrgid(header.gname, statbuf->st_gid, sizeof(header.gname)) == NULL)
    220         strcpy(header.gname, "root");
     249
     250    if (sizeof(header) != 512)
     251        BUG_tar_header_size();
     252
     253    memset(&header, 0, sizeof(struct TarHeader));
     254
     255    strncpy(header.name, header_name, sizeof(header.name));
     256
     257    /* POSIX says to mask mode with 07777. */
     258    PUT_OCTAL(header.mode, statbuf->st_mode & 07777);
     259    PUT_OCTAL(header.uid, statbuf->st_uid);
     260    PUT_OCTAL(header.gid, statbuf->st_gid);
     261    memset(header.size, '0', sizeof(header.size)-1); /* Regular file size is handled later */
     262    PUT_OCTAL(header.mtime, statbuf->st_mtime);
     263
     264    /* Enter the user and group names */
     265    safe_strncpy(header.uname, get_cached_username(statbuf->st_uid), sizeof(header.uname));
     266    safe_strncpy(header.gname, get_cached_groupname(statbuf->st_gid), sizeof(header.gname));
    221267
    222268    if (tbInfo->hlInfo) {
     
    225271        strncpy(header.linkname, tbInfo->hlInfo->name,
    226272                sizeof(header.linkname));
     273#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
     274        /* Write out long linkname if needed */
     275        if (header.linkname[sizeof(header.linkname)-1])
     276            writeLongname(tbInfo->tarFd, GNULONGLINK,
     277                    tbInfo->hlInfo->name, 0);
     278#endif
    227279    } else if (S_ISLNK(statbuf->st_mode)) {
    228         char *lpath = xreadlink(real_name);
    229 
    230         if (!lpath)     /* Already printed err msg inside xreadlink() */
    231             return (FALSE);
     280        char *lpath = xmalloc_readlink_or_warn(fileName);
     281        if (!lpath)
     282            return FALSE;
    232283        header.typeflag = SYMTYPE;
    233284        strncpy(header.linkname, lpath, sizeof(header.linkname));
     285#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
     286        /* Write out long linkname if needed */
     287        if (header.linkname[sizeof(header.linkname)-1])
     288            writeLongname(tbInfo->tarFd, GNULONGLINK, lpath, 0);
     289#else
     290        /* If it is larger than 100 bytes, bail out */
     291        if (header.linkname[sizeof(header.linkname)-1]) {
     292            free(lpath);
     293            bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported");
     294            return FALSE;
     295        }
     296#endif
    234297        free(lpath);
    235298    } else if (S_ISDIR(statbuf->st_mode)) {
    236299        header.typeflag = DIRTYPE;
    237         strncat(header.name, "/", sizeof(header.name));
     300        /* Append '/' only if there is a space for it */
     301        if (!header.name[sizeof(header.name)-1])
     302            header.name[strlen(header.name)] = '/';
    238303    } else if (S_ISCHR(statbuf->st_mode)) {
    239304        header.typeflag = CHRTYPE;
    240         putOctal(header.devmajor, sizeof(header.devmajor),
    241                  major(statbuf->st_rdev));
    242         putOctal(header.devminor, sizeof(header.devminor),
    243                  minor(statbuf->st_rdev));
     305        PUT_OCTAL(header.devmajor, major(statbuf->st_rdev));
     306        PUT_OCTAL(header.devminor, minor(statbuf->st_rdev));
    244307    } else if (S_ISBLK(statbuf->st_mode)) {
    245308        header.typeflag = BLKTYPE;
    246         putOctal(header.devmajor, sizeof(header.devmajor),
    247                  major(statbuf->st_rdev));
    248         putOctal(header.devminor, sizeof(header.devminor),
    249                  minor(statbuf->st_rdev));
     309        PUT_OCTAL(header.devmajor, major(statbuf->st_rdev));
     310        PUT_OCTAL(header.devminor, minor(statbuf->st_rdev));
    250311    } else if (S_ISFIFO(statbuf->st_mode)) {
    251312        header.typeflag = FIFOTYPE;
    252313    } else if (S_ISREG(statbuf->st_mode)) {
     314        if (sizeof(statbuf->st_size) > 4
     315         && statbuf->st_size > (off_t)0777777777777LL
     316        ) {
     317            bb_error_msg_and_die("cannot store file '%s' "
     318                "of size %"OFF_FMT"d, aborting",
     319                fileName, statbuf->st_size);
     320        }
    253321        header.typeflag = REGTYPE;
    254         putOctal(header.size, sizeof(header.size), statbuf->st_size);
     322        PUT_OCTAL(header.size, statbuf->st_size);
    255323    } else {
    256         bb_error_msg("%s: Unknown file type", real_name);
    257         return (FALSE);
    258     }
    259 
    260     /* Calculate and store the checksum (i.e., the sum of all of the bytes of
    261      * the header).  The checksum field must be filled with blanks for the
    262      * calculation.  The checksum field is formatted differently from the
    263      * other fields: it has [6] digits, a null, then a space -- rather than
    264      * digits, followed by a null like the other fields... */
    265     memset(header.chksum, ' ', sizeof(header.chksum));
    266     cp = (const unsigned char *) &header;
    267     while (size-- > 0)
    268         chksum += *cp++;
    269     putOctal(header.chksum, 7, chksum);
     324        bb_error_msg("%s: unknown file type", fileName);
     325        return FALSE;
     326    }
     327
     328#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
     329    /* Write out long name if needed */
     330    /* (we, like GNU tar, output long linkname *before* long name) */
     331    if (header.name[sizeof(header.name)-1])
     332        writeLongname(tbInfo->tarFd, GNULONGNAME,
     333                header_name, S_ISDIR(statbuf->st_mode));
     334#endif
    270335
    271336    /* Now write the header out to disk */
    272     if ((size =
    273          bb_full_write(tbInfo->tarFd, (char *) &header,
    274                     sizeof(struct TarHeader))) < 0) {
    275         bb_error_msg(bb_msg_io_error, real_name);
    276         return (FALSE);
    277     }
    278     /* Pad the header up to the tar block size */
    279     for (; size < TAR_BLOCK_SIZE; size++) {
    280         write(tbInfo->tarFd, "\0", 1);
    281     }
     337    chksum_and_xwrite(tbInfo->tarFd, &header);
     338
    282339    /* Now do the verbose thing (or not) */
    283 
    284340    if (tbInfo->verboseFlag) {
    285341        FILE *vbFd = stdout;
     
    287343        if (tbInfo->tarFd == STDOUT_FILENO) /* If the archive goes to stdout, verbose to stderr */
    288344            vbFd = stderr;
    289 
    290         fprintf(vbFd, "%s\n", header.name);
    291     }
    292 
    293     return (TRUE);
    294 }
    295 
    296 # ifdef CONFIG_FEATURE_TAR_FROM
    297 static inline int exclude_file(const llist_t *excluded_files, const char *file)
     345        /* GNU "tar cvvf" prints "extended" listing a-la "ls -l" */
     346        /* We don't have such excesses here: for us "v" == "vv" */
     347        /* '/' is probably a GNUism */
     348        fprintf(vbFd, "%s%s\n", header_name,
     349                S_ISDIR(statbuf->st_mode) ? "/" : "");
     350    }
     351
     352    return TRUE;
     353}
     354
     355#if ENABLE_FEATURE_TAR_FROM
     356static int exclude_file(const llist_t *excluded_files, const char *file)
    298357{
    299358    while (excluded_files) {
     
    317376    return 0;
    318377}
    319 # else
     378#else
    320379#define exclude_file(excluded_files, file) 0
    321 # endif
     380#endif
    322381
    323382static int writeFileToTarball(const char *fileName, struct stat *statbuf,
    324                               void *userData)
     383            void *userData, int depth ATTRIBUTE_UNUSED)
    325384{
    326385    struct TarBallInfo *tbInfo = (struct TarBallInfo *) userData;
     
    329388
    330389    /*
    331        ** Check to see if we are dealing with a hard link.
    332        ** If so -
    333        ** Treat the first occurance of a given dev/inode as a file while
    334        ** treating any additional occurances as hard links.  This is done
    335        ** by adding the file information to the HardLinkInfo linked list.
     390     * Check to see if we are dealing with a hard link.
     391     * If so -
     392     * Treat the first occurance of a given dev/inode as a file while
     393     * treating any additional occurances as hard links.  This is done
     394     * by adding the file information to the HardLinkInfo linked list.
    336395     */
    337396    tbInfo->hlInfo = NULL;
     
    345404    if (S_ISSOCK(statbuf->st_mode)) {
    346405        bb_error_msg("%s: socket ignored", fileName);
    347         return (TRUE);
     406        return TRUE;
    348407    }
    349408
     
    354413        tbInfo->statBuf.st_ino == statbuf->st_ino) {
    355414        bb_error_msg("%s: file is the archive; skipping", fileName);
    356         return (TRUE);
     415        return TRUE;
    357416    }
    358417
    359418    header_name = fileName;
    360419    while (header_name[0] == '/') {
    361         static int alreadyWarned = FALSE;
    362 
    363         if (alreadyWarned == FALSE) {
    364             bb_error_msg("Removing leading '/' from member names");
    365             alreadyWarned = TRUE;
     420        static smallint warned;
     421
     422        if (!warned) {
     423            bb_error_msg("removing leading '/' from member names");
     424            warned = 1;
    366425        }
    367426        header_name++;
    368427    }
    369428
     429#if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS
    370430    if (strlen(fileName) >= NAME_SIZE) {
    371         bb_error_msg(bb_msg_name_longer_than_foo, NAME_SIZE);
    372         return (TRUE);
    373     }
     431        bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported");
     432        return TRUE;
     433    }
     434#endif
    374435
    375436    if (header_name[0] == '\0')
    376437        return TRUE;
    377438
    378     if (ENABLE_FEATURE_TAR_FROM &&
    379             exclude_file(tbInfo->excludeList, header_name)) {
     439    if (exclude_file(tbInfo->excludeList, header_name))
    380440        return SKIP;
    381     }
    382441
    383442    /* Is this a regular file? */
    384     if ((tbInfo->hlInfo == NULL) && (S_ISREG(statbuf->st_mode))) {
    385 
     443    if (tbInfo->hlInfo == NULL && S_ISREG(statbuf->st_mode)) {
    386444        /* open the file we want to archive, and make sure all is well */
    387         if ((inputFileFd = open(fileName, O_RDONLY)) < 0) {
    388             bb_perror_msg("%s: Cannot open", fileName);
    389             return (FALSE);
     445        inputFileFd = open_or_warn(fileName, O_RDONLY);
     446        if (inputFileFd < 0) {
     447            return FALSE;
    390448        }
    391449    }
     
    393451    /* Add an entry to the tarball */
    394452    if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) {
    395         return (FALSE);
     453        return FALSE;
    396454    }
    397455
    398456    /* If it was a regular file, write out the body */
    399     if (inputFileFd >= 0 ) {
    400         ssize_t readSize = 0;
    401 
    402         /* write the file to the archive */
    403         readSize = bb_copyfd_eof(inputFileFd, tbInfo->tarFd);
     457    if (inputFileFd >= 0) {
     458        size_t readSize;
     459        /* Write the file to the archive. */
     460        /* We record size into header first, */
     461        /* and then write out file. If file shrinks in between, */
     462        /* tar will be corrupted. So we don't allow for that. */
     463        /* NB: GNU tar 1.16 warns and pads with zeroes */
     464        /* or even seeks back and updates header */
     465        bb_copyfd_exact_size(inputFileFd, tbInfo->tarFd, statbuf->st_size);
     466        ////off_t readSize;
     467        ////readSize = bb_copyfd_size(inputFileFd, tbInfo->tarFd, statbuf->st_size);
     468        ////if (readSize != statbuf->st_size && readSize >= 0) {
     469        ////    bb_error_msg_and_die("short read from %s, aborting", fileName);
     470        ////}
     471
     472        /* Check that file did not grow in between? */
     473        /* if (safe_read(inputFileFd, 1) == 1) warn but continue? */
     474
    404475        close(inputFileFd);
    405476
    406477        /* Pad the file up to the tar block size */
    407         for (; (readSize % TAR_BLOCK_SIZE) != 0; readSize++)
    408             write(tbInfo->tarFd, "\0", 1);
    409     }
    410 
    411     return (TRUE);
    412 }
    413 
    414 static inline int writeTarFile(const int tar_fd, const int verboseFlag,
     478        /* (a few tricks here in the name of code size) */
     479        readSize = (-(int)statbuf->st_size) & (TAR_BLOCK_SIZE-1);
     480        memset(block_buf, 0, readSize);
     481        xwrite(tbInfo->tarFd, block_buf, readSize);
     482    }
     483
     484    return TRUE;
     485}
     486
     487static int writeTarFile(const int tar_fd, const int verboseFlag,
    415488    const unsigned long dereferenceFlag, const llist_t *include,
    416489    const llist_t *exclude, const int gzip)
    417490{
    418491    pid_t gzipPid = 0;
    419 
    420492    int errorFlag = FALSE;
    421     ssize_t size;
    422493    struct TarBallInfo tbInfo;
    423494
     
    431502     * can avoid including the tarball into itself....  */
    432503    if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0)
    433         bb_perror_msg_and_die("Couldnt stat tar file");
     504        bb_perror_msg_and_die("cannot stat tar file");
    434505
    435506    if ((ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2) && gzip) {
     
    437508        int gzipStatusPipe[2] = { -1, -1 };
    438509        volatile int vfork_exec_errno = 0;
    439         char *zip_exec = (gzip == 1) ? "gzip" : "bzip2";
    440 
    441 
    442         if (pipe(gzipDataPipe) < 0 || pipe(gzipStatusPipe) < 0)
    443             bb_perror_msg_and_die("create pipe");
    444 
    445         signal(SIGPIPE, SIG_IGN);   /* we only want EPIPE on errors */
    446 
    447 # if __GNUC__
    448             /* Avoid vfork clobbering */
    449             (void) &include;
    450             (void) &errorFlag;
    451             (void) &zip_exec;
    452 # endif
     510        const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2";
     511
     512        xpipe(gzipDataPipe);
     513        xpipe(gzipStatusPipe);
     514
     515        signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */
     516
     517#if defined(__GNUC__) && __GNUC__
     518        /* Avoid vfork clobbering */
     519        (void) &include;
     520        (void) &errorFlag;
     521        (void) &zip_exec;
     522#endif
    453523
    454524        gzipPid = vfork();
     
    458528            close(gzipDataPipe[1]);
    459529
    460             if (tbInfo.tarFd != 1)
    461                 dup2(tbInfo.tarFd, 1);
     530            dup2(tbInfo.tarFd, 1);
    462531
    463532            close(gzipStatusPipe[0]);
    464533            fcntl(gzipStatusPipe[1], F_SETFD, FD_CLOEXEC);  /* close on exec shows success */
    465534
    466             execlp(zip_exec, zip_exec, "-f", NULL);
     535            BB_EXECLP(zip_exec, zip_exec, "-f", NULL);
    467536            vfork_exec_errno = errno;
    468537
     
    476545                char buf;
    477546
    478                 int n = bb_full_read(gzipStatusPipe[0], &buf, 1);
     547                int n = full_read(gzipStatusPipe[0], &buf, 1);
    479548
    480549                if (n == 0 && vfork_exec_errno != 0) {
    481550                    errno = vfork_exec_errno;
    482                     bb_perror_msg_and_die("Could not exec %s", zip_exec);
     551                    bb_perror_msg_and_die("cannot exec %s", zip_exec);
    483552                } else if ((n < 0) && (errno == EAGAIN || errno == EINTR))
    484553                    continue;   /* try it again */
     
    495564    /* Read the directory/files and iterate over them one at a time */
    496565    while (include) {
    497         if (!recursive_action(include->data, TRUE, dereferenceFlag,
    498                 FALSE, writeFileToTarball, writeFileToTarball, &tbInfo))
     566        if (!recursive_action(include->data, ACTION_RECURSE |
     567                (dereferenceFlag ? ACTION_FOLLOWLINKS : 0),
     568                writeFileToTarball, writeFileToTarball, &tbInfo, 0))
    499569        {
    500570            errorFlag = TRUE;
     
    503573    }
    504574    /* Write two empty blocks to the end of the archive */
    505     for (size = 0; size < (2 * TAR_BLOCK_SIZE); size++)
    506         write(tbInfo.tarFd, "\0", 1);
     575    memset(block_buf, 0, 2*TAR_BLOCK_SIZE);
     576    xwrite(tbInfo.tarFd, block_buf, 2*TAR_BLOCK_SIZE);
    507577
    508578    /* To be pedantically correct, we would check if the tarball
     
    519589
    520590    if (errorFlag)
    521         bb_error_msg("Error exit delayed from previous errors");
    522 
    523     if (gzipPid && waitpid(gzipPid, NULL, 0)==-1)
    524         bb_error_msg("Couldnt wait");
    525 
    526     return !errorFlag;
     591        bb_error_msg("error exit delayed from previous errors");
     592
     593    if (gzipPid) {
     594        int status;
     595        if (waitpid(gzipPid, &status, 0) == -1)
     596            bb_perror_msg("waitpid");
     597        else if (!WIFEXITED(status) || WEXITSTATUS(status))
     598            /* gzip was killed or has exited with nonzero! */
     599            errorFlag = TRUE;
     600    }
     601    return errorFlag;
    527602}
    528603#else
     
    530605    const unsigned long dereferenceFlag, const llist_t *include,
    531606    const llist_t *exclude, const int gzip);
    532 #endif  /* tar_create */
    533 
    534 #ifdef CONFIG_FEATURE_TAR_FROM
     607#endif /* FEATURE_TAR_CREATE */
     608
     609#if ENABLE_FEATURE_TAR_FROM
    535610static llist_t *append_file_list_to_list(llist_t *list)
    536611{
     
    542617
    543618    while (cur) {
    544         src_stream = bb_xfopen(cur->data, "r");
     619        src_stream = xfopen(cur->data, "r");
    545620        tmp = cur;
    546621        cur = cur->link;
    547622        free(tmp);
    548         while ((line = bb_get_chomped_line_from_file(src_stream)) != NULL)
    549                 llist_add_to(&newlist, line);
     623        while ((line = xmalloc_getline(src_stream)) != NULL) {
     624            /* kill trailing '/' unless the string is just "/" */
     625            char *cp = last_char_is(line, '/');
     626            if (cp > line)
     627                *cp = '\0';
     628            llist_add_to(&newlist, line);
     629        }
    550630        fclose(src_stream);
    551631    }
     
    553633}
    554634#else
    555 #define append_file_list_to_list(x) 0
    556 #endif
    557 
    558 #ifdef CONFIG_FEATURE_TAR_COMPRESS
     635#define append_file_list_to_list(x) 0
     636#endif
     637
     638#if ENABLE_FEATURE_TAR_COMPRESS
    559639static char get_header_tar_Z(archive_handle_t *archive_handle)
    560640{
    561     /* Cant lseek over pipe's */
    562     archive_handle->seek = seek_by_char;
     641    /* Can't lseek over pipes */
     642    archive_handle->seek = seek_by_read;
    563643
    564644    /* do the decompression, and cleanup */
    565     if (bb_xread_char(archive_handle->src_fd) != 0x1f ||
    566         bb_xread_char(archive_handle->src_fd) != 0x9d)
    567     {
    568         bb_error_msg_and_die("Invalid magic");
    569     }
    570 
    571     archive_handle->src_fd = open_transformer(archive_handle->src_fd, uncompress);
     645    if (xread_char(archive_handle->src_fd) != 0x1f
     646     || xread_char(archive_handle->src_fd) != 0x9d
     647    ) {
     648        bb_error_msg_and_die("invalid magic");
     649    }
     650
     651    archive_handle->src_fd = open_transformer(archive_handle->src_fd, uncompress, "uncompress", "uncompress", "-cf", "-", NULL);
    572652    archive_handle->offset = 0;
    573     while (get_header_tar(archive_handle) == EXIT_SUCCESS);
     653    while (get_header_tar(archive_handle) == EXIT_SUCCESS)
     654        /* nothing */;
    574655
    575656    /* Can only do one file at a time */
    576     return(EXIT_FAILURE);
     657    return EXIT_FAILURE;
    577658}
    578659#else
    579 #define get_header_tar_Z    0
    580 #endif
    581 
    582 #define CTX_TEST                          (1 << 0)
    583 #define CTX_EXTRACT                       (1 << 1)
    584 #define TAR_OPT_BASEDIR                   (1 << 2)
    585 #define TAR_OPT_TARNAME                   (1 << 3)
    586 #define TAR_OPT_2STDOUT                   (1 << 4)
    587 #define TAR_OPT_P                         (1 << 5)
    588 #define TAR_OPT_VERBOSE                   (1 << 6)
    589 #define TAR_OPT_KEEP_OLD                  (1 << 7)
    590 
    591 #define TAR_OPT_AFTER_START               8
    592 
    593 #define CTX_CREATE                        (1 << (TAR_OPT_AFTER_START))
    594 #define TAR_OPT_DEREFERENCE               (1 << (TAR_OPT_AFTER_START + 1))
    595 #ifdef CONFIG_FEATURE_TAR_CREATE
    596 # define TAR_OPT_STR_CREATE               "ch"
    597 # define TAR_OPT_AFTER_CREATE             TAR_OPT_AFTER_START + 2
    598 #else
    599 # define TAR_OPT_STR_CREATE               ""
    600 # define TAR_OPT_AFTER_CREATE             TAR_OPT_AFTER_START
    601 #endif
    602 
    603 #define TAR_OPT_BZIP2                     (1 << (TAR_OPT_AFTER_CREATE))
    604 #ifdef CONFIG_FEATURE_TAR_BZIP2
    605 # define TAR_OPT_STR_BZIP2                "j"
    606 # define TAR_OPT_AFTER_BZIP2              TAR_OPT_AFTER_CREATE + 1
    607 #else
    608 # define TAR_OPT_STR_BZIP2                ""
    609 # define TAR_OPT_AFTER_BZIP2              TAR_OPT_AFTER_CREATE
    610 #endif
    611 
    612 #define TAR_OPT_LZMA                      (1 << (TAR_OPT_AFTER_BZIP2))
    613 #ifdef CONFIG_FEATURE_TAR_LZMA
    614 # define TAR_OPT_STR_LZMA                 "a"
    615 # define TAR_OPT_AFTER_LZMA               TAR_OPT_AFTER_BZIP2 + 1
    616 #else
    617 # define TAR_OPT_STR_LZMA                 ""
    618 # define TAR_OPT_AFTER_LZMA               TAR_OPT_AFTER_BZIP2
    619 #endif
    620 
    621 #define TAR_OPT_INCLUDE_FROM              (1 << (TAR_OPT_AFTER_LZMA))
    622 #define TAR_OPT_EXCLUDE_FROM              (1 << (TAR_OPT_AFTER_LZMA + 1))
    623 #ifdef CONFIG_FEATURE_TAR_FROM
    624 # define TAR_OPT_STR_FROM                 "T:X:"
    625 # define TAR_OPT_AFTER_FROM               TAR_OPT_AFTER_LZMA + 2
    626 #else
    627 # define TAR_OPT_STR_FROM                 ""
    628 # define TAR_OPT_AFTER_FROM               TAR_OPT_AFTER_LZMA
    629 #endif
    630 
    631 #define TAR_OPT_GZIP                      (1 << (TAR_OPT_AFTER_FROM))
    632 #ifdef CONFIG_FEATURE_TAR_GZIP
    633 # define TAR_OPT_STR_GZIP                 "z"
    634 # define TAR_OPT_AFTER_GZIP               TAR_OPT_AFTER_FROM + 1
    635 #else
    636 # define TAR_OPT_STR_GZIP                 ""
    637 # define TAR_OPT_AFTER_GZIP               TAR_OPT_AFTER_FROM
    638 #endif
    639 
    640 #define TAR_OPT_UNCOMPRESS                (1 << (TAR_OPT_AFTER_GZIP))
    641 #ifdef CONFIG_FEATURE_TAR_COMPRESS
    642 # define TAR_OPT_STR_COMPRESS             "Z"
    643 # define TAR_OPT_AFTER_COMPRESS           TAR_OPT_AFTER_GZIP + 1
    644 #else
    645 # define TAR_OPT_STR_COMPRESS             ""
    646 # define TAR_OPT_AFTER_COMPRESS           TAR_OPT_AFTER_GZIP
    647 #endif
    648 
    649 #define TAR_OPT_NOPRESERVE_OWN            (1 << (TAR_OPT_AFTER_COMPRESS))
    650 #define TAR_OPT_NOPRESERVE_PERM           (1 << (TAR_OPT_AFTER_COMPRESS + 1))
    651 #define TAR_OPT_STR_NOPRESERVE            "\203\213"
    652 #define TAR_OPT_AFTER_NOPRESERVE          TAR_OPT_AFTER_COMPRESS + 2
    653 
    654 static const char tar_options[]="txC:f:Opvk" \
    655     TAR_OPT_STR_CREATE \
    656     TAR_OPT_STR_BZIP2 \
    657     TAR_OPT_STR_LZMA \
    658     TAR_OPT_STR_FROM \
    659     TAR_OPT_STR_GZIP \
    660     TAR_OPT_STR_COMPRESS \
    661     TAR_OPT_STR_NOPRESERVE;
    662 
    663 #ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS
    664 static const struct option tar_long_options[] = {
    665     { "list",               0,  NULL,   't' },
    666     { "extract",            0,  NULL,   'x' },
    667     { "directory",          1,  NULL,   'C' },
    668     { "file",               1,  NULL,   'f' },
    669     { "to-stdout",          0,  NULL,   'O' },
    670     { "same-permissions",   0,  NULL,   'p' },
    671     { "verbose",            0,  NULL,   'v' },
    672     { "keep-old",           0,  NULL,   'k' },
    673     { "no-same-owner",      0,  NULL,   '\203' },
    674     { "no-same-permissions",0,  NULL,   '\213' },
    675 # ifdef CONFIG_FEATURE_TAR_CREATE
    676     { "create",             0,  NULL,   'c' },
    677     { "dereference",        0,  NULL,   'h' },
     660#define get_header_tar_Z NULL
     661#endif
     662
     663#ifdef CHECK_FOR_CHILD_EXITCODE
     664/* Looks like it isn't needed - tar detects malformed (truncated)
     665 * archive if e.g. bunzip2 fails */
     666static int child_error;
     667
     668static void handle_SIGCHLD(int status)
     669{
     670    /* Actually, 'status' is a signo. We reuse it for other needs */
     671
     672    /* Wait for any child without blocking */
     673    if (waitpid(-1, &status, WNOHANG) < 0)
     674        /* wait failed?! I'm confused... */
     675        return;
     676
     677    if (WIFEXITED(status) && WEXITSTATUS(status)==0)
     678        /* child exited with 0 */
     679        return;
     680    /* Cannot happen?
     681    if (!WIFSIGNALED(status) && !WIFEXITED(status)) return; */
     682    child_error = 1;
     683}
     684#endif
     685
     686enum {
     687    OPTBIT_KEEP_OLD = 7,
     688    USE_FEATURE_TAR_CREATE(  OPTBIT_CREATE      ,)
     689    USE_FEATURE_TAR_CREATE(  OPTBIT_DEREFERENCE ,)
     690    USE_FEATURE_TAR_BZIP2(   OPTBIT_BZIP2       ,)
     691    USE_FEATURE_TAR_LZMA(    OPTBIT_LZMA        ,)
     692    USE_FEATURE_TAR_FROM(    OPTBIT_INCLUDE_FROM,)
     693    USE_FEATURE_TAR_FROM(    OPTBIT_EXCLUDE_FROM,)
     694    USE_FEATURE_TAR_GZIP(    OPTBIT_GZIP        ,)
     695    USE_FEATURE_TAR_COMPRESS(OPTBIT_COMPRESS    ,)
     696    OPTBIT_NOPRESERVE_OWN,
     697    OPTBIT_NOPRESERVE_PERM,
     698    OPT_TEST         = 1 << 0, // t
     699    OPT_EXTRACT      = 1 << 1, // x
     700    OPT_BASEDIR      = 1 << 2, // C
     701    OPT_TARNAME      = 1 << 3, // f
     702    OPT_2STDOUT      = 1 << 4, // O
     703    OPT_P            = 1 << 5, // p
     704    OPT_VERBOSE      = 1 << 6, // v
     705    OPT_KEEP_OLD     = 1 << 7, // k
     706    OPT_CREATE       = USE_FEATURE_TAR_CREATE(  (1<<OPTBIT_CREATE      )) + 0, // c
     707    OPT_DEREFERENCE  = USE_FEATURE_TAR_CREATE(  (1<<OPTBIT_DEREFERENCE )) + 0, // h
     708    OPT_BZIP2        = USE_FEATURE_TAR_BZIP2(   (1<<OPTBIT_BZIP2       )) + 0, // j
     709    OPT_LZMA         = USE_FEATURE_TAR_LZMA(    (1<<OPTBIT_LZMA        )) + 0, // a
     710    OPT_INCLUDE_FROM = USE_FEATURE_TAR_FROM(    (1<<OPTBIT_INCLUDE_FROM)) + 0, // T
     711    OPT_EXCLUDE_FROM = USE_FEATURE_TAR_FROM(    (1<<OPTBIT_EXCLUDE_FROM)) + 0, // X
     712    OPT_GZIP         = USE_FEATURE_TAR_GZIP(    (1<<OPTBIT_GZIP        )) + 0, // z
     713    OPT_COMPRESS     = USE_FEATURE_TAR_COMPRESS((1<<OPTBIT_COMPRESS    )) + 0, // Z
     714    OPT_NOPRESERVE_OWN  = 1 << OPTBIT_NOPRESERVE_OWN , // no-same-owner
     715    OPT_NOPRESERVE_PERM = 1 << OPTBIT_NOPRESERVE_PERM, // no-same-permissions
     716};
     717#if ENABLE_FEATURE_TAR_LONG_OPTIONS
     718static const char tar_longopts[] ALIGN1 =
     719    "list\0"                No_argument       "t"
     720    "extract\0"             No_argument       "x"
     721    "directory\0"           Required_argument "C"
     722    "file\0"                Required_argument "f"
     723    "to-stdout\0"           No_argument       "O"
     724    "same-permissions\0"    No_argument       "p"
     725    "verbose\0"             No_argument       "v"
     726    "keep-old\0"            No_argument       "k"
     727# if ENABLE_FEATURE_TAR_CREATE
     728    "create\0"              No_argument       "c"
     729    "dereference\0"         No_argument       "h"
    678730# endif
    679 # ifdef CONFIG_FEATURE_TAR_BZIP2
    680     { "bzip2",              0,  NULL,   'j' },
     731# if ENABLE_FEATURE_TAR_BZIP2
     732    "bzip2\0"               No_argument       "j"
    681733# endif
    682 # ifdef CONFIG_FEATURE_TAR_LZMA
    683     { "lzma",               0,  NULL,   'a' },
     734# if ENABLE_FEATURE_TAR_LZMA
     735    "lzma\0"                No_argument       "a"
    684736# endif
    685 # ifdef CONFIG_FEATURE_TAR_FROM
    686     { "files-from",         1,  NULL,   'T' },
    687     { "exclude-from",       1,  NULL,   'X' },
    688     { "exclude",            1,  NULL,   '\n' },
     737# if ENABLE_FEATURE_TAR_FROM
     738    "files-from\0"          Required_argument "T"
     739    "exclude-from\0"        Required_argument "X"
    689740# endif
    690 # ifdef CONFIG_FEATURE_TAR_GZIP
    691     { "gzip",               0,  NULL,   'z' },
     741# if ENABLE_FEATURE_TAR_GZIP
     742    "gzip\0"                No_argument       "z"
    692743# endif
    693 # ifdef CONFIG_FEATURE_TAR_COMPRESS
    694     { "compress",           0,  NULL,   'Z' },
     744# if ENABLE_FEATURE_TAR_COMPRESS
     745    "compress\0"            No_argument       "Z"
    695746# endif
    696     { 0,                    0, 0, 0 }
    697 };
    698 #else
    699 #define tar_long_options    0
    700 #endif
    701 
     747    "no-same-owner\0"       No_argument       "\xfd"
     748    "no-same-permissions\0" No_argument       "\xfe"
     749    /* --exclude takes next bit position in option mask, */
     750    /* therefore we have to either put it _after_ --no-same-perm */
     751    /* or add OPT[BIT]_EXCLUDE before OPT[BIT]_NOPRESERVE_OWN */
     752# if ENABLE_FEATURE_TAR_FROM
     753    "exclude\0"             Required_argument "\xff"
     754# endif
     755    ;
     756#endif
     757
     758int tar_main(int argc, char **argv);
    702759int tar_main(int argc, char **argv)
    703760{
     
    706763    char *base_dir = NULL;
    707764    const char *tar_filename = "-";
    708     unsigned long opt;
     765    unsigned opt;
     766    int verboseFlag = 0;
     767#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
    709768    llist_t *excludes = NULL;
     769#endif
    710770
    711771    /* Initialise default values */
    712772    tar_handle = init_handle();
    713     tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL;
     773    tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS
     774                      | ARCHIVE_PRESERVE_DATE
     775                      | ARCHIVE_EXTRACT_UNCONDITIONAL;
    714776
    715777    /* Prepend '-' to the first argument if required */
    716     bb_opt_complementally = ENABLE_FEATURE_TAR_CREATE ?
    717         "--:X::T::\n::c:t:x:?:c--tx:t--cx:x--ct" :
    718         "--:X::T::\n::t:x:?:t--x:x--t";
    719     if (ENABLE_FEATURE_TAR_LONG_OPTIONS)
    720         bb_applet_long_options = tar_long_options;
    721     opt = bb_getopt_ulflags(argc, argv, tar_options,
    722                 &base_dir,      /* Change to dir <optarg> */
    723                 &tar_filename /* archive filename */
    724 #ifdef CONFIG_FEATURE_TAR_FROM
    725                 , &(tar_handle->accept),
    726                 &(tar_handle->reject),
    727                 &excludes
    728 #endif
    729                 );
    730 
    731     if (opt & CTX_TEST) {
    732         if ((tar_handle->action_header == header_list) ||
    733             (tar_handle->action_header == header_verbose_list))
    734         {
    735                 tar_handle->action_header = header_verbose_list;
    736         } else tar_handle->action_header = header_list;
    737     }
    738     if((opt & CTX_EXTRACT) && tar_handle->action_data != data_extract_to_stdout)
     778    opt_complementary = "--:" // first arg is options
     779        "tt:vv:" // count -t,-v
     780        "?:" // bail out with usage instead of error return
     781        "X::T::" // cumulative lists
     782#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
     783        "\xff::" // cumulative lists for --exclude
     784#endif
     785        USE_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd
     786        USE_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive
     787        SKIP_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive
     788#if ENABLE_FEATURE_TAR_LONG_OPTIONS
     789    applet_long_options = tar_longopts;
     790#endif
     791    opt = getopt32(argv,
     792        "txC:f:Opvk"
     793        USE_FEATURE_TAR_CREATE(  "ch"  )
     794        USE_FEATURE_TAR_BZIP2(   "j"   )
     795        USE_FEATURE_TAR_LZMA(    "a"   )
     796        USE_FEATURE_TAR_FROM(    "T:X:")
     797        USE_FEATURE_TAR_GZIP(    "z"   )
     798        USE_FEATURE_TAR_COMPRESS("Z"   )
     799        , &base_dir // -C dir
     800        , &tar_filename // -f filename
     801        USE_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T
     802        USE_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X
     803#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
     804        , &excludes // --exclude
     805#endif
     806        , &verboseFlag // combined count for -t and -v
     807        , &verboseFlag // combined count for -t and -v
     808        );
     809
     810    if (verboseFlag) tar_handle->action_header = header_verbose_list;
     811    if (verboseFlag == 1) tar_handle->action_header = header_list;
     812
     813    if (opt & OPT_EXTRACT)
    739814        tar_handle->action_data = data_extract_all;
    740815
    741     if (opt & TAR_OPT_2STDOUT)
     816    if (opt & OPT_2STDOUT)
    742817        tar_handle->action_data = data_extract_to_stdout;
    743818
    744     if (opt & TAR_OPT_VERBOSE) {
    745         if ((tar_handle->action_header == header_list) ||
    746             (tar_handle->action_header == header_verbose_list))
    747         {
    748             tar_handle->action_header = header_verbose_list;
    749         } else
    750             tar_handle->action_header = header_list;
    751     }
    752     if (opt & TAR_OPT_KEEP_OLD)
     819    if (opt & OPT_KEEP_OLD)
    753820        tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL;
    754821
    755     if (opt & TAR_OPT_NOPRESERVE_OWN)
     822    if (opt & OPT_NOPRESERVE_OWN)
    756823        tar_handle->flags |= ARCHIVE_NOPRESERVE_OWN;
    757824
    758     if (opt & TAR_OPT_NOPRESERVE_PERM)
     825    if (opt & OPT_NOPRESERVE_PERM)
    759826        tar_handle->flags |= ARCHIVE_NOPRESERVE_PERM;
    760827
    761     if (ENABLE_FEATURE_TAR_GZIP && (opt & TAR_OPT_GZIP))
     828    if (opt & OPT_GZIP)
    762829        get_header_ptr = get_header_tar_gz;
    763830
    764     if (ENABLE_FEATURE_TAR_BZIP2 && (opt & TAR_OPT_BZIP2))
     831    if (opt & OPT_BZIP2)
    765832        get_header_ptr = get_header_tar_bz2;
    766833
    767     if (ENABLE_FEATURE_TAR_LZMA && (opt & TAR_OPT_LZMA))
     834    if (opt & OPT_LZMA)
    768835        get_header_ptr = get_header_tar_lzma;
    769836
    770     if (ENABLE_FEATURE_TAR_COMPRESS && (opt & TAR_OPT_UNCOMPRESS))
     837    if (opt & OPT_COMPRESS)
    771838        get_header_ptr = get_header_tar_Z;
    772839
    773     if (ENABLE_FEATURE_TAR_FROM) {
    774         tar_handle->reject = append_file_list_to_list(tar_handle->reject);
    775         /* Append excludes to reject */
    776         while (excludes) {
    777             llist_t *temp = excludes->link;
    778             excludes->link = tar_handle->reject;
    779             tar_handle->reject = excludes;
    780             excludes = temp;
    781         }
    782         tar_handle->accept = append_file_list_to_list(tar_handle->accept);
    783     }
     840#if ENABLE_FEATURE_TAR_FROM
     841    tar_handle->reject = append_file_list_to_list(tar_handle->reject);
     842#if ENABLE_FEATURE_TAR_LONG_OPTIONS
     843    /* Append excludes to reject */
     844    while (excludes) {
     845        llist_t *next = excludes->link;
     846        excludes->link = tar_handle->reject;
     847        tar_handle->reject = excludes;
     848        excludes = next;
     849    }
     850#endif
     851    tar_handle->accept = append_file_list_to_list(tar_handle->accept);
     852#endif
    784853
    785854    /* Check if we are reading from stdin */
     
    792861    /* TODO: This is the same as in ar, separate function ? */
    793862    while (optind < argc) {
    794         char *filename_ptr = last_char_is(argv[optind], '/');
    795         if (filename_ptr > argv[optind])
    796             *filename_ptr = '\0';
    797 
    798         llist_add_to(&(tar_handle->accept), argv[optind]);
     863        /* kill trailing '/' unless the string is just "/" */
     864        char *cp = last_char_is(argv[optind], '/');
     865        if (cp > argv[optind])
     866            *cp = '\0';
     867        llist_add_to_end(&tar_handle->accept, argv[optind]);
    799868        optind++;
    800869    }
    801870
    802     if ((tar_handle->accept) || (tar_handle->reject))
     871    if (tar_handle->accept || tar_handle->reject)
    803872        tar_handle->filter = filter_accept_reject_list;
    804873
     
    808877        int flags;
    809878
    810         if (ENABLE_FEATURE_TAR_CREATE && (opt & CTX_CREATE)) {
     879        if (opt & OPT_CREATE) {
    811880            /* Make sure there is at least one file to tar up.  */
    812881            if (tar_handle->accept == NULL)
     
    814883
    815884            tar_stream = stdout;
    816             flags = O_WRONLY | O_CREAT | O_EXCL;
    817             unlink(tar_filename);
     885            /* Mimicking GNU tar 1.15.1: */
     886            flags = O_WRONLY|O_CREAT|O_TRUNC;
     887        /* was doing unlink; open(O_WRONLY|O_CREAT|O_EXCL); why? */
    818888        } else {
    819889            tar_stream = stdin;
     
    821891        }
    822892
    823         if ((tar_filename[0] == '-') && (tar_filename[1] == '\0')) {
     893        if (LONE_DASH(tar_filename)) {
    824894            tar_handle->src_fd = fileno(tar_stream);
    825             tar_handle->seek = seek_by_char;
     895            tar_handle->seek = seek_by_read;
    826896        } else {
    827             tar_handle->src_fd = bb_xopen(tar_filename, flags);
     897            tar_handle->src_fd = xopen(tar_filename, flags);
    828898        }
    829899    }
    830900
    831901    if (base_dir)
    832         bb_xchdir(base_dir);
     902        xchdir(base_dir);
     903
     904#ifdef CHECK_FOR_CHILD_EXITCODE
     905    /* We need to know whether child (gzip/bzip/etc) exits abnormally */
     906    signal(SIGCHLD, handle_SIGCHLD);
     907#endif
    833908
    834909    /* create an archive */
    835     if (ENABLE_FEATURE_TAR_CREATE && (opt & CTX_CREATE)) {
    836         int verboseFlag = FALSE;
     910    if (opt & OPT_CREATE) {
    837911        int zipMode = 0;
    838 
    839912        if (ENABLE_FEATURE_TAR_GZIP && get_header_ptr == get_header_tar_gz)
    840913            zipMode = 1;
    841914        if (ENABLE_FEATURE_TAR_BZIP2 && get_header_ptr == get_header_tar_bz2)
    842915            zipMode = 2;
    843 
    844         if ((tar_handle->action_header == header_list) ||
    845                 (tar_handle->action_header == header_verbose_list))
    846         {
    847             verboseFlag = TRUE;
    848         }
    849         writeTarFile(tar_handle->src_fd, verboseFlag, opt & TAR_OPT_DEREFERENCE,
     916        /* NB: writeTarFile() closes tar_handle->src_fd */
     917        return writeTarFile(tar_handle->src_fd, verboseFlag, opt & OPT_DEREFERENCE,
    850918                tar_handle->accept,
    851             tar_handle->reject, zipMode);
    852     } else {
    853         while (get_header_ptr(tar_handle) == EXIT_SUCCESS);
    854 
    855         /* Check that every file that should have been extracted was */
    856         while (tar_handle->accept) {
    857             if (!find_list_entry(tar_handle->reject, tar_handle->accept->data)
    858                 && !find_list_entry(tar_handle->passed, tar_handle->accept->data))
    859             {
    860                 bb_error_msg_and_die("%s: Not found in archive", tar_handle->accept->data);
    861             }
    862             tar_handle->accept = tar_handle->accept->link;
    863         }
    864     }
    865 
    866     if (ENABLE_FEATURE_CLEAN_UP && tar_handle->src_fd != STDIN_FILENO)
     919                tar_handle->reject, zipMode);
     920    }
     921
     922    while (get_header_ptr(tar_handle) == EXIT_SUCCESS)
     923        /* nothing */;
     924
     925    /* Check that every file that should have been extracted was */
     926    while (tar_handle->accept) {
     927        if (!find_list_entry(tar_handle->reject, tar_handle->accept->data)
     928         && !find_list_entry(tar_handle->passed, tar_handle->accept->data)
     929        ) {
     930            bb_error_msg_and_die("%s: not found in archive",
     931                tar_handle->accept->data);
     932        }
     933        tar_handle->accept = tar_handle->accept->link;
     934    }
     935    if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */)
    867936        close(tar_handle->src_fd);
    868937
    869     return(EXIT_SUCCESS);
    870 }
     938    return EXIT_SUCCESS;
     939}
  • branches/2.2.5/mindi-busybox/archival/unzip.c

    r821 r1765  
    2525 */
    2626
    27 #include <fcntl.h>
    28 #include <stdlib.h>
    29 #include <string.h>
    30 #include <unistd.h>
    31 #include <errno.h>
     27#include "libbb.h"
    3228#include "unarchive.h"
    33 #include "busybox.h"
    34 
    35 #if BB_BIG_ENDIAN
    36 static inline unsigned short
    37 __swap16(unsigned short x) {
    38     return (((uint16_t)(x) & 0xFF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8);
    39 }
    40 
    41 static inline uint32_t
    42 __swap32(uint32_t x) {
    43      return (((x & 0xFF) << 24) |
    44         ((x & 0xFF00) << 8) |
    45         ((x & 0xFF0000) >> 8) |
    46         ((x & 0xFF000000) >> 24));
    47 }
    48 #else /* it's little-endian */
    49 # define __swap16(x) (x)
    50 # define __swap32(x) (x)
    51 #endif /* BB_BIG_ENDIAN */
    52 
    53 #define ZIP_FILEHEADER_MAGIC        __swap32(0x04034b50)
    54 #define ZIP_CDS_MAGIC           __swap32(0x02014b50)
    55 #define ZIP_CDS_END_MAGIC       __swap32(0x06054b50)
    56 #define ZIP_DD_MAGIC            __swap32(0x08074b50)
    57 
    58 extern unsigned int gunzip_crc;
    59 extern unsigned int gunzip_bytes_out;
     29
     30#define ZIP_FILEHEADER_MAGIC        SWAP_LE32(0x04034b50)
     31#define ZIP_CDS_MAGIC           SWAP_LE32(0x02014b50)
     32#define ZIP_CDS_END_MAGIC       SWAP_LE32(0x06054b50)
     33#define ZIP_DD_MAGIC            SWAP_LE32(0x08074b50)
    6034
    6135typedef union {
     
    7246        unsigned short filename_len;    /* 22-23 */
    7347        unsigned short extra_len;       /* 24-25 */
    74     } formated ATTRIBUTE_PACKED;
     48    } formatted ATTRIBUTE_PACKED;
    7549} zip_header_t;
    7650
     
    7852{
    7953    if (lseek(fd, skip, SEEK_CUR) == (off_t)-1) {
    80         if ((errno != ESPIPE) || (bb_copyfd_size(fd, -1, skip) != skip)) {
    81             bb_error_msg_and_die("Seek failure");
    82         }
    83     }
    84 }
    85 
    86 static void unzip_read(int fd, void *buf, size_t count)
    87 {
    88     if (bb_xread(fd, buf, count) != count) {
    89         bb_error_msg_and_die(bb_msg_read_error);
     54        if (errno != ESPIPE)
     55            bb_error_msg_and_die("seek failure");
     56        bb_copyfd_exact_size(fd, -1, skip);
    9057    }
    9158}
     
    9461{
    9562    /* Create all leading directories */
    96     char *name = bb_xstrdup(fn);
     63    char *name = xstrdup(fn);
    9764    if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) {
    98         bb_error_msg_and_die("Exiting"); /* bb_make_directory is noisy */
     65        bb_error_msg_and_die("exiting"); /* bb_make_directory is noisy */
    9966    }
    10067    free(name);
     
    10370static int unzip_extract(zip_header_t *zip_header, int src_fd, int dst_fd)
    10471{
    105     if (zip_header->formated.method == 0) {
     72    if (zip_header->formatted.method == 0) {
    10673        /* Method 0 - stored (not compressed) */
    107         int size = zip_header->formated.ucmpsize;
    108         if (size && (bb_copyfd_size(src_fd, dst_fd, size) != size)) {
    109             bb_error_msg_and_die("Cannot complete extraction");
    110         }
    111 
     74        off_t size = zip_header->formatted.ucmpsize;
     75        if (size)
     76            bb_copyfd_exact_size(src_fd, dst_fd, size);
    11277    } else {
    11378        /* Method 8 - inflate */
    114         inflate_init(zip_header->formated.cmpsize);
    115         inflate_unzip(src_fd, dst_fd);
    116         inflate_cleanup();
     79        inflate_unzip_result res;
     80        /* err = */ inflate_unzip(&res, zip_header->formatted.cmpsize, src_fd, dst_fd);
     81// we should check for -1 error return
    11782        /* Validate decompression - crc */
    118         if (zip_header->formated.crc32 != (gunzip_crc ^ 0xffffffffL)) {
    119             bb_error_msg("Invalid compressed data--crc error");
     83        if (zip_header->formatted.crc32 != (res.crc ^ 0xffffffffL)) {
     84            bb_error_msg("invalid compressed data--%s error", "crc");
    12085            return 1;
    12186        }
    12287        /* Validate decompression - size */
    123         if (zip_header->formated.ucmpsize != gunzip_bytes_out) {
    124             bb_error_msg("Invalid compressed data--length error");
     88        if (zip_header->formatted.ucmpsize != res.bytes_out) {
     89            bb_error_msg("invalid compressed data--%s error", "length");
    12590            return 1;
    12691        }
     
    12994}
    13095
     96int unzip_main(int argc, char **argv);
    13197int unzip_main(int argc, char **argv)
    13298{
     
    145111    struct stat stat_buf;
    146112
    147     while((opt = getopt(argc, argv, "-d:lnopqx")) != -1) {
    148         switch(opt_range) {
     113    while ((opt = getopt(argc, argv, "-d:lnopqx")) != -1) {
     114        switch (opt_range) {
    149115        case 0: /* Options */
    150             switch(opt) {
     116            switch (opt) {
    151117            case 'l': /* List */
    152118                verbosity = v_list;
     
    169135
    170136            case 1 : /* The zip file */
    171                 src_fn = bb_xstrndup(optarg, strlen(optarg)+4);
     137                src_fn = xmalloc(strlen(optarg)+4);
     138                strcpy(src_fn, optarg);
    172139                opt_range++;
    173140                break;
     
    218185
    219186    /* Open input file */
    220     if (strcmp("-", src_fn) == 0) {
     187    if (LONE_DASH(src_fn)) {
    221188        src_fd = STDIN_FILENO;
    222189        /* Cannot use prompt mode since zip data is arriving on STDIN */
    223190        overwrite = (overwrite == o_prompt) ? o_never : overwrite;
    224 
    225191    } else {
    226192        static const char *const extn[] = {"", ".zip", ".ZIP"};
    227193        int orig_src_fn_len = strlen(src_fn);
    228         for(i = 0; (i < 3) && (src_fd == -1); i++) {
     194        for (i = 0; (i < 3) && (src_fd == -1); i++) {
    229195            strcpy(src_fn + orig_src_fn_len, extn[i]);
    230196            src_fd = open(src_fn, O_RDONLY);
    231197        }
    232198        if (src_fd == -1) {
    233             src_fn[orig_src_fn_len] = 0;
    234             bb_error_msg_and_die("Cannot open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn);
     199            src_fn[orig_src_fn_len] = '\0';
     200            bb_error_msg_and_die("cannot open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn);
    235201        }
    236202    }
     
    238204    /* Change dir if necessary */
    239205    if (base_dir)
    240         bb_xchdir(base_dir);
     206        xchdir(base_dir);
    241207
    242208    if (verbosity != v_silent)
     
    249215
    250216        /* Check magic number */
    251         unzip_read(src_fd, &magic, 4);
     217        xread(src_fd, &magic, 4);
    252218        if (magic == ZIP_CDS_MAGIC) {
    253219            break;
    254220        } else if (magic != ZIP_FILEHEADER_MAGIC) {
    255             bb_error_msg_and_die("Invalid zip magic %08X", magic);
     221            bb_error_msg_and_die("invalid zip magic %08X", magic);
    256222        }
    257223
    258224        /* Read the file header */
    259         unzip_read(src_fd, zip_header.raw, 26);
    260 #if BB_BIG_ENDIAN
    261         zip_header.formated.version = __swap16(zip_header.formated.version);
    262         zip_header.formated.flags = __swap16(zip_header.formated.flags);
    263         zip_header.formated.method = __swap16(zip_header.formated.method);
    264         zip_header.formated.modtime = __swap16(zip_header.formated.modtime);
    265         zip_header.formated.moddate = __swap16(zip_header.formated.moddate);
    266         zip_header.formated.crc32 = __swap32(zip_header.formated.crc32);
    267         zip_header.formated.cmpsize = __swap32(zip_header.formated.cmpsize);
    268         zip_header.formated.ucmpsize = __swap32(zip_header.formated.ucmpsize);
    269         zip_header.formated.filename_len = __swap16(zip_header.formated.filename_len);
    270         zip_header.formated.extra_len = __swap16(zip_header.formated.extra_len);
    271 #endif /* BB_BIG_ENDIAN */
    272         if ((zip_header.formated.method != 0) && (zip_header.formated.method != 8)) {
    273             bb_error_msg_and_die("Unsupported compression method %d", zip_header.formated.method);
     225        xread(src_fd, zip_header.raw, 26);
     226        zip_header.formatted.version = SWAP_LE32(zip_header.formatted.version);
     227        zip_header.formatted.flags = SWAP_LE32(zip_header.formatted.flags);
     228        zip_header.formatted.method = SWAP_LE32(zip_header.formatted.method);
     229        zip_header.formatted.modtime = SWAP_LE32(zip_header.formatted.modtime);
     230        zip_header.formatted.moddate = SWAP_LE32(zip_header.formatted.moddate);
     231        zip_header.formatted.crc32 = SWAP_LE32(zip_header.formatted.crc32);
     232        zip_header.formatted.cmpsize = SWAP_LE32(zip_header.formatted.cmpsize);
     233        zip_header.formatted.ucmpsize = SWAP_LE32(zip_header.formatted.ucmpsize);
     234        zip_header.formatted.filename_len = SWAP_LE32(zip_header.formatted.filename_len);
     235        zip_header.formatted.extra_len = SWAP_LE32(zip_header.formatted.extra_len);
     236        if ((zip_header.formatted.method != 0) && (zip_header.formatted.method != 8)) {
     237            bb_error_msg_and_die("unsupported compression method %d", zip_header.formatted.method);
    274238        }
    275239
    276240        /* Read filename */
    277241        free(dst_fn);
    278         dst_fn = xzalloc(zip_header.formated.filename_len + 1);
    279         unzip_read(src_fd, dst_fn, zip_header.formated.filename_len);
     242        dst_fn = xzalloc(zip_header.formatted.filename_len + 1);
     243        xread(src_fd, dst_fn, zip_header.formatted.filename_len);
    280244
    281245        /* Skip extra header bytes */
    282         unzip_skip(src_fd, zip_header.formated.extra_len);
     246        unzip_skip(src_fd, zip_header.formatted.extra_len);
    283247
    284248        if ((verbosity == v_list) && !list_header_done){
    285             printf("  Length     Date   Time    Name\n"
    286                    " --------    ----   ----    ----\n");
     249            puts("  Length     Date   Time    Name\n"
     250                 " --------    ----   ----    ----");
    287251            list_header_done = 1;
    288252        }
     
    294258
    295259        } else { /* Extract entry */
    296             total_size += zip_header.formated.ucmpsize;
     260            total_size += zip_header.formatted.ucmpsize;
    297261
    298262            if (verbosity == v_list) { /* List entry */
    299                 unsigned int dostime = zip_header.formated.modtime | (zip_header.formated.moddate << 16);
     263                unsigned int dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16);
    300264                printf("%9u  %02u-%02u-%02u %02u:%02u   %s\n",
    301                        zip_header.formated.ucmpsize,
     265                       zip_header.formatted.ucmpsize,
    302266                       (dostime & 0x01e00000) >> 21,
    303267                       (dostime & 0x001f0000) >> 16,
     
    308272                total_entries++;
    309273                i = 'n';
    310 
    311274            } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */
    312275                i = -1;
    313 
    314276            } else if (last_char_is(dst_fn, '/')) { /* Extract directory */
    315277                if (stat(dst_fn, &stat_buf) == -1) {
    316278                    if (errno != ENOENT) {
    317                         bb_perror_msg_and_die("Cannot stat '%s'",dst_fn);
     279                        bb_perror_msg_and_die("cannot stat '%s'",dst_fn);
    318280                    }
    319281                    if (verbosity == v_normal) {
     
    322284                    unzip_create_leading_dirs(dst_fn);
    323285                    if (bb_make_directory(dst_fn, 0777, 0)) {
    324                         bb_error_msg_and_die("Exiting");
     286                        bb_error_msg_and_die("exiting");
    325287                    }
    326288                } else {
     
    332294
    333295            } else {  /* Extract file */
    334             _check_file:
     296 _check_file:
    335297                if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */
    336298                    if (errno != ENOENT) {
    337                         bb_perror_msg_and_die("Cannot stat '%s'",dst_fn);
     299                        bb_perror_msg_and_die("cannot stat '%s'",dst_fn);
    338300                    }
    339301                    i = 'y';
    340 
    341302                } else { /* File already exists */
    342303                    if (overwrite == o_never) {
    343304                        i = 'n';
    344 
    345305                    } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */
    346306                        if (overwrite == o_always) {
     
    349309                            printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn);
    350310                            if (!fgets(key_buf, 512, stdin)) {
    351                                 bb_perror_msg_and_die("Cannot read input");
     311                                bb_perror_msg_and_die("cannot read input");
    352312                            }
    353313                            i = key_buf[0];
    354314                        }
    355 
    356315                    } else { /* File is not regular file */
    357316                        bb_error_msg_and_die("'%s' exists but is not regular file",dst_fn);
     
    366325        case 'y': /* Open file and fall into unzip */
    367326            unzip_create_leading_dirs(dst_fn);
    368             dst_fd = bb_xopen(dst_fn, O_WRONLY | O_CREAT);
     327            dst_fd = xopen(dst_fn, O_WRONLY | O_CREAT | O_TRUNC);
    369328        case -1: /* Unzip */
    370329            if (verbosity == v_normal) {
     
    372331            }
    373332            if (unzip_extract(&zip_header, src_fd, dst_fd)) {
    374                 failed = 1;
     333                failed = 1;
    375334            }
    376335            if (dst_fd != STDOUT_FILENO) {
     
    384343        case 'n':
    385344            /* Skip entry data */
    386             unzip_skip(src_fd, zip_header.formated.cmpsize);
     345            unzip_skip(src_fd, zip_header.formatted.cmpsize);
    387346            break;
    388347
     
    391350            printf("new name: ");
    392351            if (!fgets(key_buf, 512, stdin)) {
    393                 bb_perror_msg_and_die("Cannot read input");
     352                bb_perror_msg_and_die("cannot read input");
    394353            }
    395354            free(dst_fn);
    396             dst_fn = bb_xstrdup(key_buf);
     355            dst_fn = xstrdup(key_buf);
    397356            chomp(dst_fn);
    398357            goto _check_file;
     
    404363
    405364        /* Data descriptor section */
    406         if (zip_header.formated.flags & 4) {
     365        if (zip_header.formatted.flags & 4) {
    407366            /* skip over duplicate crc, compressed size and uncompressed size */
    408367            unzip_skip(src_fd, 12);
Note: See TracChangeset for help on using the changeset viewer.