X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=gunzip.c;h=d6382aed0a35fb11e41486ee4c3a93ad16278bdf;hb=f1f6d58598ae6628b6a31d512e9148674349ee98;hp=7aa896469319879f26d0e0db84460501c5f8bd71;hpb=1dbe340ebab31aa85446e83e8bc42f184b59b25b;p=oweals%2Fbusybox.git diff --git a/gunzip.c b/gunzip.c index 7aa896469..d6382aed0 100644 --- a/gunzip.c +++ b/gunzip.c @@ -1,20 +1,58 @@ /* vi: set sw=4 ts=4: */ -/* zcat : stripped version based on gzip sources - Sven Rudolph - */ +/* + * Gzip implementation for busybox + * + * Based on GNU gzip Copyright (C) 1992-1993 Jean-loup Gailly. + * + * Originally adjusted for busybox by Sven Rudolph + * based on gzip sources + * + * Adjusted further by Erik Andersen , + * to support files as well as stdin/stdout, and to generally behave itself wrt + * command line handling. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ #include "internal.h" -#define bb_need_name_too_long -#define BB_DECLARE_EXTERN -#include "messages.c" +#include static const char gunzip_usage[] = - "gunzip [OPTION]... FILE\n\n" - "Uncompress FILE (or standard input if FILE is '-').\n\n" + "gunzip [OPTION]... FILE\n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nUncompress FILE (or standard input if FILE is '-').\n\n" "Options:\n" "\t-c\tWrite output to standard output\n" - "\t-t\tTest compressed file integrity\n"; + "\t-t\tTest compressed file integrity\n" +#endif + ; + + + /* These defines are very important for BusyBox. Without these, + * huge chunks of ram are pre-allocated making the BusyBox bss + * size Freaking Huge(tm), which is a bad thing.*/ +#define SMALL_MEM +#define DYN_ALLOC + +#define BB_DECLARE_EXTERN +#define bb_need_memory_exhausted +#define bb_need_name_too_long +#include "messages.c" + /* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface * Copyright (C) 1992-1993 Jean-loup Gailly @@ -70,7 +108,6 @@ static char *license_msg[] = { #include #include #include -#include /* for PATH_MAX */ /* #include "tailor.h" */ @@ -89,25 +126,6 @@ static char *license_msg[] = { #define get_char() get_byte() #define put_char(c) put_byte(c) -/* #include "gzip.h" */ - -/* gzip.h -- common declarations for all gzip modules - * Copyright (C) 1992-1993 Jean-loup Gailly. - * This is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License, see the file COPYING. - */ - -#if defined(__STDC__) || defined(PROTO) -# define OF(args) args -#else -# define OF(args) () -#endif - -#ifdef __STDC__ -typedef void *voidp; -#else -typedef char *voidp; -#endif /* I don't like nested includes, but the string and io functions are used * too often @@ -118,7 +136,7 @@ typedef char *voidp; # if !defined(STDC_HEADERS) && !defined(NO_MEMORY_H) && !defined(__GNUC__) # include # endif -# define memzero(s, n) memset ((voidp)(s), 0, (n)) +# define memzero(s, n) memset ((void *)(s), 0, (n)) #else # include # define strchr index @@ -194,7 +212,7 @@ extern int method; /* compression method */ # define DECLARE(type, array, size) type * array # define ALLOC(type, array, size) { \ array = (type*)calloc((size_t)(((size)+1L)/2), 2*sizeof(type)); \ - if (array == NULL) errorMsg("insufficient memory"); \ + if (array == NULL) errorMsg(memory_exhausted, "gunzip"); \ } # define FREE(array) {if (array != NULL) free(array), array=NULL;} #else @@ -329,49 +347,44 @@ extern int save_orig_name; /* set if original name must be saved */ #define WARN(msg) {fprintf msg ; \ if (exit_code == OK) exit_code = WARNING;} -#define do_exit(c) exit(c) - - /* in unzip.c */ -extern int unzip OF((int in, int out)); +extern int unzip (int in, int out); /* in gzip.c */ -RETSIGTYPE abort_gzip OF((void)); +RETSIGTYPE abort_gzip (void); /* in deflate.c */ -void lm_init OF((int pack_level, ush * flags)); -ulg deflate OF((void)); +void lm_init (int pack_level, ush * flags); +ulg deflate (void); /* in trees.c */ -void ct_init OF((ush * attr, int *method)); -int ct_tally OF((int dist, int lc)); -ulg flush_block OF((char *buf, ulg stored_len, int eof)); +void ct_init (ush * attr, int *method); +int ct_tally (int dist, int lc); +ulg flush_block (char *buf, ulg stored_len, int eof); /* in bits.c */ -void bi_init OF((file_t zipfile)); -void send_bits OF((int value, int length)); -unsigned bi_reverse OF((unsigned value, int length)); -void bi_windup OF((void)); -void copy_block OF((char *buf, unsigned len, int header)); -extern int (*read_buf) OF((char *buf, unsigned size)); +void bi_init (file_t zipfile); +void send_bits (int value, int length); +unsigned bi_reverse (unsigned value, int length); +void bi_windup (void); +void copy_block (char *buf, unsigned len, int header); /* in util.c: */ -extern int copy OF((int in, int out)); -extern ulg updcrc OF((uch * s, unsigned n)); -extern void clear_bufs OF((void)); -extern int fill_inbuf OF((int eof_ok)); -extern void flush_outbuf OF((void)); -extern void flush_window OF((void)); -extern void write_buf OF((int fd, voidp buf, unsigned cnt)); +extern ulg updcrc (uch * s, unsigned n); +extern void clear_bufs (void); +static int fill_inbuf (int eof_ok); +extern void flush_outbuf (void); +static void flush_window (void); +extern void write_buf (int fd, void * buf, unsigned cnt); #ifndef __linux__ -extern char *basename OF((char *fname)); +static char *basename (char *fname); #endif /* not __linux__ */ -extern void read_error OF((void)); -extern void write_error OF((void)); +void read_error_msg (void); +void write_error_msg (void); /* in inflate.c */ -extern int inflate OF((void)); +static int inflate (void); /* #include "lzw.h" */ @@ -415,8 +428,8 @@ extern int inflate OF((void)); extern int maxbits; /* max bits per code for LZW */ extern int block_mode; /* block compress mode -C compatible with 2.0 */ -extern int lzw OF((int in, int out)); -extern int unlzw OF((int in, int out)); +extern int lzw (int in, int out); +extern int unlzw (int in, int out); /* #include "revision.h" */ @@ -436,133 +449,6 @@ extern int unlzw OF((int in, int out)); # undef LZW #endif -/* #include "getopt.h" */ - -/* Declarations for getopt. - Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -#ifdef __cplusplus -extern "C" { -#endif -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - - extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - - extern int opterr; - -/* Set to an option character which was unrecognized. */ - - extern int optopt; - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - - struct option { -#if __STDC__ - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; - }; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -#if __STDC__ || defined(PROTO) -#if defined(__GNU_LIBRARY__) -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ - extern int getopt(int argc, char *const *argv, const char *shortopts); -#endif /* not __GNU_LIBRARY__ */ - extern int getopt_long(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - extern int getopt_long_only(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, - int *longind); - -/* Internal only. Users should not call this directly. */ - extern int _getopt_internal(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, - int *longind, int long_only); -#else /* not __STDC__ */ - extern int getopt(); - extern int getopt_long(); - extern int getopt_long_only(); - - extern int _getopt_internal(); -#endif /* not __STDC__ */ - -#ifdef __cplusplus -} -#endif -#endif /* _GETOPT_H */ #include #include #include @@ -605,7 +491,7 @@ typedef struct direct dir_type; #if !defined(S_ISREG) && defined(S_IFREG) # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #endif -typedef RETSIGTYPE(*sig_type) OF((int)); +typedef RETSIGTYPE(*sig_type) (int); #ifndef O_BINARY # define O_BINARY 0 /* creation mode for open() */ @@ -631,8 +517,8 @@ typedef RETSIGTYPE(*sig_type) OF((int)); #define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */ #ifndef MAX_PATH_LEN /* max pathname length */ -# ifdef PATH_MAX -# define MAX_PATH_LEN PATH_MAX +# ifdef BUFSIZ +# define MAX_PATH_LEN BUFSIZ # else # define MAX_PATH_LEN 1024 # endif @@ -644,7 +530,7 @@ typedef RETSIGTYPE(*sig_type) OF((int)); #ifdef NO_OFF_T typedef long off_t; -off_t lseek OF((int fd, off_t offset, int whence)); +off_t lseek (int fd, off_t offset, int whence); #endif @@ -687,7 +573,7 @@ long header_bytes; /* number of bytes in gzip header */ /* local functions */ -local int get_method OF((int in)); +local int get_method (int in); #define strequ(s1, s2) (strcmp((s1),(s2)) == 0) @@ -706,11 +592,12 @@ int gunzip_main(int argc, char **argv) char ifname[MAX_PATH_LEN + 1]; /* input file name */ char ofname[MAX_PATH_LEN + 1]; /* output file name */ - if (argc == 1) - usage(gunzip_usage); - - if (strcmp(*argv, "zcat") == 0) + if (strcmp(*argv, "zcat") == 0) { to_stdout = 1; + if (argc == 1) { + fromstdin = 1; + } + } /* Parse any options */ while (--argc > 0 && **(++argv) == '-') { @@ -773,7 +660,7 @@ int gunzip_main(int argc, char **argv) usage(gunzip_usage); if (strlen(*argv) > MAX_PATH_LEN) { fprintf(stderr, name_too_long, "gunzip"); - do_exit(WARNING); + exit(WARNING); } strcpy(ifname, *argv); @@ -781,13 +668,13 @@ int gunzip_main(int argc, char **argv) inFileNum = open(ifname, O_RDONLY); if (inFileNum < 0) { perror(ifname); - do_exit(WARNING); + exit(WARNING); } /* Get the time stamp on the input file. */ result = stat(ifname, &statBuf); if (result < 0) { perror(ifname); - do_exit(WARNING); + exit(WARNING); } ifile_size = statBuf.st_size; } @@ -812,7 +699,7 @@ int gunzip_main(int argc, char **argv) /* And get to work */ if (strlen(ifname) > MAX_PATH_LEN - 4) { fprintf(stderr, name_too_long, "gunzip"); - do_exit(WARNING); + exit(WARNING); } strcpy(ofname, ifname); pos = strstr(ofname, ".gz"); @@ -836,7 +723,7 @@ int gunzip_main(int argc, char **argv) #endif if (outFileNum < 0) { perror(ofname); - do_exit(WARNING); + exit(WARNING); } /* Set permissions on the file */ fchmod(outFileNum, statBuf.st_mode); @@ -860,7 +747,7 @@ int gunzip_main(int argc, char **argv) exit(FALSE); } } - do_exit(exit_code); + return(exit_code); } @@ -953,7 +840,7 @@ int in; /* input file descriptor */ */ RETSIGTYPE abort_gzip() { - do_exit(ERROR); + exit(ERROR); } /* unzip.c -- decompress files in gzip or pkzip format. @@ -1027,7 +914,7 @@ int in, out; /* input and output file descriptors */ ofd = out; method = get_method(ifd); if (method < 0) { - do_exit(exit_code); /* error message already emitted */ + exit(exit_code); /* error message already emitted */ } updcrc(NULL, 0); /* initialize crc */ @@ -1043,7 +930,7 @@ int in, out; /* input and output file descriptors */ int res = inflate(); if (res == 3) { - errorMsg("out of memory"); + errorMsg(memory_exhausted, "gunzip"); } else if (res != 0) { errorMsg("invalid compressed data--format violated"); } @@ -1146,7 +1033,7 @@ unsigned n; /* number of bytes in s[] */ /* =========================================================================== * Clear input and output buffers */ -void clear_bufs() +void clear_bufs(void) { outcnt = 0; insize = inptr = 0; @@ -1174,7 +1061,7 @@ int eof_ok; /* set if EOF acceptable as a result */ if (insize == 0) { if (eof_ok) return EOF; - read_error(); + read_error_msg(); } bytes_in += (ulg) insize; inptr = 1; @@ -1218,17 +1105,17 @@ void flush_window() */ void write_buf(fd, buf, cnt) int fd; -voidp buf; +void * buf; unsigned cnt; { unsigned n; while ((n = write(fd, buf, cnt)) != cnt) { if (n == (unsigned) (-1)) { - write_error(); + write_error_msg(); } cnt -= n; - buf = (voidp) ((char *) buf + n); + buf = (void *) ((char *) buf + n); } } @@ -1240,8 +1127,8 @@ unsigned cnt; # define const # endif -int strspn OF((const char *s, const char *accept)); -int strcspn OF((const char *s, const char *reject)); +int strspn (const char *s, const char *accept); +int strcspn (const char *s, const char *reject); /* ======================================================================== * Return the length of the maximum initial segment @@ -1291,7 +1178,7 @@ const char *reject; /* ======================================================================== * Error handlers. */ -void read_error() +void read_error_msg() { fprintf(stderr, "\n"); if (errno != 0) { @@ -1302,7 +1189,7 @@ void read_error() abort_gzip(); } -void write_error() +void write_error_msg() { fprintf(stderr, "\n"); perror(""); @@ -1493,15 +1380,15 @@ struct huft { /* Function prototypes */ -int huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *, - struct huft **, int *)); -int huft_free OF((struct huft *)); -int inflate_codes OF((struct huft *, struct huft *, int, int)); -int inflate_stored OF((void)); -int inflate_fixed OF((void)); -int inflate_dynamic OF((void)); -int inflate_block OF((int *)); -int inflate OF((void)); +int huft_build (unsigned *, unsigned, unsigned, ush *, ush *, + struct huft **, int *); +int huft_free (struct huft *); +int inflate_codes (struct huft *, struct huft *, int, int); +int inflate_stored (void); +int inflate_fixed (void); +int inflate_dynamic (void); +int inflate_block (int *); +int inflate (void); /* The inflate algorithm uses a sliding 32K byte window on the uncompressed