diff options
author | Erik Troan <ewt@redhat.com> | 2001-11-25 14:37:27 +0000 |
---|---|---|
committer | Erik Troan <ewt@redhat.com> | 2001-11-25 14:37:27 +0000 |
commit | e8859d0f8b544466ff137219abfcbd61f780be10 (patch) | |
tree | 6f393fbce402897aad9fa33a366bffb932e92bcf /isys | |
parent | a55a038d9977c89903ab8c6373a03d0810fe6435 (diff) | |
download | anaconda-e8859d0f8b544466ff137219abfcbd61f780be10.tar.gz anaconda-e8859d0f8b544466ff137219abfcbd61f780be10.tar.xz anaconda-e8859d0f8b544466ff137219abfcbd61f780be10.zip |
bound compression code, removed more bloat
Diffstat (limited to 'isys')
-rw-r--r-- | isys/gzlib/Makefile | 11 | ||||
-rw-r--r-- | isys/gzlib/binding.c | 59 | ||||
-rw-r--r-- | isys/gzlib/gzip.c | 70 | ||||
-rw-r--r-- | isys/gzlib/gzlib.h | 4 | ||||
-rw-r--r-- | isys/gzlib/test.c | 38 | ||||
-rw-r--r-- | isys/gzlib/util.c | 243 | ||||
-rw-r--r-- | isys/gzlib/zip.c | 60 |
7 files changed, 185 insertions, 300 deletions
diff --git a/isys/gzlib/Makefile b/isys/gzlib/Makefile index f1c8aa323..71afdd518 100644 --- a/isys/gzlib/Makefile +++ b/isys/gzlib/Makefile @@ -1,16 +1,19 @@ include ../../Makefile.inc CFLAGS += -I . -g -SOURCES = bits.c gzip.c inflate.c lzw.c trees.c unzip.c util.c zip.c binding.c -OBJS = bits.o gzip.o inflate.o lzw.o trees.o unzip.o util.o zip.o binding.o - +SOURCES = bits.c gzip.c inflate.c lzw.c trees.c unzip.c util.c zip.c binding.c \ + deflate.c zip.c +OBJS = $(patsubst %.c,%.o,$(SOURCES)) DOBJS = $(patsubst %.o,%.do,$(OBJS)) ifeq (i386, $(ARCH)) DIETLIB=libgunzip-diet.a($(DOBJS)) endif -all: libgunzip.a($(OBJS)) $(DIETLIB) +all: libgunzip.a($(OBJS)) $(DIETLIB) test + +test: libgunzip.a + $(CC) $(CFLAGS) -o test test.c libgunzip.a clean: rm -f libgunzip.a $(OBJS) $(DOBJS) diff --git a/isys/gzlib/binding.c b/isys/gzlib/binding.c index 16dd568ad..0f779366d 100644 --- a/isys/gzlib/binding.c +++ b/isys/gzlib/binding.c @@ -27,7 +27,8 @@ gzFile gunzip_dopen(int fd) { dup2(p[1], 1); close(p[0]); close(p[1]); - gunzip_main(); + if (fd > 2) close(fd); + gunzip_main(1); exit(0); } @@ -48,7 +49,51 @@ gzFile gunzip_open(const char * file) { fd = open(file, O_RDONLY); if (fd < 0) return NULL; - return gunzip_dopen(fd); + return gunzip_dopen(fd); +} + +gzFile gzip_dopen(int fd) { + int p[2]; + void * oldsig; + pid_t child; + gzFile str; + + pipe(p); + + oldsig = signal(SIGCLD, SIG_IGN); + + child = fork(); + if (!child) { + if (fork()) exit(0); + + dup2(p[0], 0); + dup2(fd, 1); + close(p[0]); + close(p[1]); + if (fd > 2) close(fd); + gunzip_main(0); + exit(0); + } + + waitpid(child, NULL, 0); + signal(SIGCLD, oldsig); + + close(p[0]); + + str = malloc(sizeof(*str)); + str->fd = p[1]; + + return str; +} + + +gzFile gzip_open(const char * file, int flags) { + int fd; + + fd = open(file, flags); + if (fd < 0) return NULL; + + return gzip_dopen(fd); } int gunzip_read(gzFile str, void * buf, int bytes) { @@ -64,9 +109,19 @@ int gunzip_read(gzFile str, void * buf, int bytes) { return pos; } +int gzip_write(gzFile str, void * buf, int bytes) { + return write(str->fd, buf, bytes); +} + int gunzip_close(gzFile str) { close(str->fd); return 0; } +int gzip_close(gzFile str) { + close(str->fd); + + return 0; +} + diff --git a/isys/gzlib/gzip.c b/isys/gzlib/gzip.c index 36eca62c2..dd556edf9 100644 --- a/isys/gzlib/gzip.c +++ b/isys/gzlib/gzip.c @@ -195,7 +195,7 @@ unsigned strstart; /* start of string to insert */ int to_stdout = 0; /* output to stdout (-c) */ int decompress = 0; /* decompress (-d) */ -int force = 0; /* don't ask questions, compress links (-f) */ +int force = 1; /* don't ask questions, compress links (-f) */ int no_name = -1; /* don't save or restore the original file name */ int no_time = -1; /* don't save or restore the original file time */ int recursive = 0; /* recurse through directories (-r) */ @@ -204,12 +204,11 @@ int quiet = 0; /* be very quiet (-q) */ int do_lzw = 0; /* generate output compatible with old compress (-Z) */ int test = 0; /* test .gz file integrity */ int foreground; /* set if program run in foreground */ -char *progname; /* program name */ +char *progname = "gzlib"; int maxbits = BITS; /* max bits per code for LZW */ int method = DEFLATED;/* compression method */ int level = 6; /* compression level */ int exit_code = OK; /* program exit code */ -int save_orig_name; /* set if original name must be saved */ int last_member; /* set for .zip and .Z files */ int part_nb; /* number of parts in .gz file */ time_t time_stamp; /* original time stamp (modification time) */ @@ -239,7 +238,7 @@ local int input_eof OF((void)); local void treat_stdin OF((void)); local int get_method OF((int in)); local void do_exit OF((int exitcode)); -int (*work) OF((int infile, int outfile)) = NULL; +int (*work) OF((int infile, int outfile)) = zip; #define strequ(s1, s2) (strcmp((s1),(s2)) == 0) @@ -254,7 +253,7 @@ local void progerror (string) } /* ======================================================================== */ -int gunzip_main (void) +int gunzip_main (int do_decompress_arg) { int file_count; /* number of files to precess */ int proglen; /* length of progname */ @@ -264,7 +263,6 @@ int gunzip_main (void) EXPAND(argc, argv); /* wild card expansion if necessary */ - progname = base_name (argv[0]); proglen = strlen(progname); /* Suppress .exe for MSDOS, OS/2 and VMS: */ @@ -272,10 +270,6 @@ int gunzip_main (void) progname[proglen-4] = '\0'; } - /* Add options in GZIP environment variable if there is one */ - env = add_envopt(&argc, &argv, OPTIONS_VAR); - if (env != NULL) args = argv; - foreground = signal(SIGINT, SIG_IGN) != SIG_IGN; if (foreground) { (void) signal (SIGINT, (sig_type)abort_gzip); @@ -291,22 +285,8 @@ int gunzip_main (void) } #endif -#ifndef GNU_STANDARD - /* For compatibility with old compress, use program name as an option. - * If you compile with -DGNU_STANDARD, this program will behave as - * gzip even if it is invoked under the name gunzip or zcat. - * - * Systems which do not support links can still use -d or -dc. - * Ignore an .exe extension for MSDOS, OS/2 and VMS. - */ - if ( strncmp(progname, "un", 2) == 0 /* ungzip, uncompress */ - || strncmp(progname, "gun", 3) == 0) { /* gunzip */ + if (do_decompress_arg) decompress = 1; - } else if (strequ(progname+1, "cat") /* zcat, pcat, gcat */ - || strequ(progname, "gzcat")) { /* gzcat */ - decompress = to_stdout = 1; - } -#endif z_suffix = Z_SUFFIX; z_len = strlen(z_suffix); @@ -379,9 +359,11 @@ local void treat_stdin() to_stdout = 1; part_nb = 0; - method = get_method(ifd); - if (method < 0) { - do_exit(exit_code); /* error message already emitted */ + if (decompress) { + method = get_method(ifd); + if (method < 0) { + do_exit(exit_code); /* error message already emitted */ + } } /* Actually do the compression/decompression. Loop over zipped members. @@ -473,27 +455,8 @@ local int get_method(in) /* Get original file name if it was truncated */ if ((flags & ORIG_NAME) != 0) { - if (no_name || (to_stdout && !list) || part_nb > 1) { - /* Discard the old name */ - char c; /* dummy used for NeXTstep 3.0 cc optimizer bug */ - do {c=get_byte();} while (c != 0); - } else { - /* Copy the base name. Keep a directory prefix intact. */ - char *p = base_name (ofname); - char *base = p; - for (;;) { - *p = (char)get_char(); - if (*p++ == '\0') break; - if (p >= ofname+sizeof(ofname)) { - gzerror("corrupted input -- file name too large"); - } - } - /* If necessary, adapt the name to local OS conventions: */ - if (!list) { - MAKE_LEGAL_NAME(base); - if (base) list=0; /* avoid warning about unused variable */ - } - } /* no_name || to_stdout */ + char c; /* dummy used for NeXTstep 3.0 cc optimizer bug */ + do {c=get_byte();} while (c != 0); } /* ORIG_NAME */ /* Discard file comment if any */ @@ -504,7 +467,12 @@ local int get_method(in) header_bytes = inptr + 2*sizeof(long); /* include crc and size */ } - } + } else if (force && to_stdout && !list) { /* pass input unchanged */ + method = STORED; + work = copy; + inptr = 0; + last_member = 1; + } if (method >= 0) return method; @@ -562,7 +530,7 @@ RETSIGTYPE abort_gzip() { if (remove_ofname) { close(ofd); - xunlink (ofname); + unlink (ofname); } do_exit(ERROR); } diff --git a/isys/gzlib/gzlib.h b/isys/gzlib/gzlib.h index d44a37ea1..35255a401 100644 --- a/isys/gzlib/gzlib.h +++ b/isys/gzlib/gzlib.h @@ -5,7 +5,11 @@ typedef struct gzFile_s * gzFile; gzFile gunzip_open(const char * file); gzFile gunzip_dopen(int fd); +gzFile gzip_open(const char * file, int mode); +gzFile gzip_dopen(int fd); int gunzip_read(gzFile str, void * buf, int bytes); +int gzip_write(gzFile str, void * buf, int bytes); int gunzip_close(gzFile str); +int gzip_close(gzFile str); #endif diff --git a/isys/gzlib/test.c b/isys/gzlib/test.c new file mode 100644 index 000000000..1dc13a876 --- /dev/null +++ b/isys/gzlib/test.c @@ -0,0 +1,38 @@ +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> + +#include "gzlib.h" + +int main(int argc, char ** argv) { + gzFile fd; + char buf[4096]; + int i; + + if (argv[1]) { + if (!strcmp(argv[1], "-d")) { + fd = gunzip_dopen(0); + while ((i = gunzip_read(fd, buf, sizeof(buf))) > 0) + if (write(1, buf, i) != i) break; + if (i != 0) { + fprintf(stderr, "error occured: %s\n", strerror(errno)); + return -1; + } + } else { + fprintf(stderr, "unknown argument\n"); + return -1; + } + } else { + fd = gzip_dopen(1); + while ((i = read(0, buf, sizeof(buf))) > 0) + if (gzip_write(fd, buf, i) != i) break; + + if (i != 0) { + fprintf(stderr, "error occured: %s\n", strerror(errno)); + return -1; + } + } + + return 0; +} diff --git a/isys/gzlib/util.c b/isys/gzlib/util.c index 93e8b823a..af658c452 100644 --- a/isys/gzlib/util.c +++ b/isys/gzlib/util.c @@ -187,188 +187,6 @@ char *strlwr(s) } /* ======================================================================== - * Return the base name of a file (remove any directory prefix and - * any version suffix). For systems with file names that are not - * case sensitive, force the base name to lower case. - */ -char *base_name(fname) - char *fname; -{ - char *p; - - if ((p = strrchr(fname, PATH_SEP)) != NULL) fname = p+1; -#ifdef PATH_SEP2 - if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1; -#endif -#ifdef PATH_SEP3 - if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1; -#endif -#ifdef SUFFIX_SEP - if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0'; -#endif - if (casemap('A') == 'a') strlwr(fname); - return fname; -} - -/* ======================================================================== - * Unlink a file, working around the unlink readonly bug (if present). - */ -int xunlink (filename) - char *filename; -{ - int r = unlink (filename); - -#ifdef UNLINK_READONLY_BUG - if (r != 0) - { - int e = errno; - if (chmod (filename, S_IWUSR) != 0) - { - errno = e; - return -1; - } - - r = unlink (filename); - } -#endif - - return r; -} - -/* ======================================================================== - * Make a file name legal for file systems not allowing file names with - * multiple dots or starting with a dot (such as MSDOS), by changing - * all dots except the last one into underlines. A target dependent - * function can be used instead of this simple function by defining the macro - * MAKE_LEGAL_NAME in tailor.h and providing the function in a target - * dependent module. - */ -void make_simple_name(name) - char *name; -{ - char *p = strrchr(name, '.'); - if (p == NULL) return; - if (p == name) p++; - do { - if (*--p == '.') *p = '_'; - } while (p != name); -} - - -#if !defined HAVE_STRING_H && !defined STDC_HEADERS - -/* Provide missing strspn and strcspn functions. */ - -# ifndef __STDC__ -# define const -# endif - -int strspn OF((const char *s, const char *accept)); -int strcspn OF((const char *s, const char *reject)); - -/* ======================================================================== - * Return the length of the maximum initial segment - * of s which contains only characters in accept. - */ -int strspn(s, accept) - const char *s; - const char *accept; -{ - register const char *p; - register const char *a; - register int count = 0; - - for (p = s; *p != '\0'; ++p) { - for (a = accept; *a != '\0'; ++a) { - if (*p == *a) break; - } - if (*a == '\0') return count; - ++count; - } - return count; -} - -/* ======================================================================== - * Return the length of the maximum inital segment of s - * which contains no characters from reject. - */ -int strcspn(s, reject) - const char *s; - const char *reject; -{ - register int count = 0; - - while (*s != '\0') { - if (strchr(reject, *s++) != NULL) return count; - ++count; - } - return count; -} - -#endif - -/* ======================================================================== - * Add an environment variable (if any) before argv, and update argc. - * Return the expanded environment variable to be freed later, or NULL - * if no options were added to argv. - */ -#define SEPARATOR " \t" /* separators in env variable */ - -char *add_envopt(argcp, argvp, env) - int *argcp; /* pointer to argc */ - char ***argvp; /* pointer to argv */ - char *env; /* name of environment variable */ -{ - char *p; /* running pointer through env variable */ - char **oargv; /* runs through old argv array */ - char **nargv; /* runs through new argv array */ - int oargc = *argcp; /* old argc */ - int nargc = 0; /* number of arguments in env variable */ - - env = (char*)getenv(env); - if (env == NULL) return NULL; - - p = (char*)gzxmalloc(strlen(env)+1); - env = strcpy(p, env); /* keep env variable intact */ - - for (p = env; *p; nargc++ ) { /* move through env */ - p += strspn(p, SEPARATOR); /* skip leading separators */ - if (*p == '\0') break; - - p += strcspn(p, SEPARATOR); /* find end of word */ - if (*p) *p++ = '\0'; /* mark it */ - } - if (nargc == 0) { - free(env); - return NULL; - } - *argcp += nargc; - /* Allocate the new argv array, with an extra element just in case - * the original arg list did not end with a NULL. - */ - nargv = (char**)calloc(*argcp+1, sizeof(char *)); - if (nargv == NULL) gzerror("out of memory"); - oargv = *argvp; - *argvp = nargv; - - /* Copy the program name first */ - if (oargc-- < 0) gzerror("argc<=0"); - *(nargv++) = *(oargv++); - - /* Then copy the environment args */ - for (p = env; nargc > 0; nargc--) { - p += strspn(p, SEPARATOR); /* skip separators */ - *(nargv++) = p; /* store start */ - while (*p++) ; /* skip over word */ - } - - /* Finally copy the old args and add a NULL (usual convention) */ - while (oargc--) *(nargv++) = *(oargv++); - *nargv = NULL; - return env; -} - -/* ======================================================================== * Error handlers. */ void gzerror(m) @@ -407,67 +225,6 @@ void write_error() } /* ======================================================================== - * Display compression ratio on the given stream on 6 characters. - */ -void display_ratio(num, den, file) - off_t num; - off_t den; - FILE *file; -{ - long ratio; /* 1000 times the compression ratio */ - - if (den == 0) { - ratio = 0; /* no compression */ - } else if (den < 2147483L) { /* (2**31 -1)/1000 */ - ratio = 1000L*num/den; - } else { - ratio = num/(den/1000L); - } - if (ratio < 0) { - putc('-', file); - ratio = -ratio; - } else { - putc(' ', file); - } - fprint_off(file, ratio / 10, 2); - fprintf(file, ".%d%%", (int) (ratio % 10)); -} - -/* ======================================================================== - * Print an off_t. There's no completely portable way to use printf, - * so we do it ourselves. - */ -void fprint_off(file, offset, width) - FILE *file; - off_t offset; - int width; -{ - char buf[CHAR_BIT * sizeof (off_t)]; - char *p = buf + sizeof buf; - int negative = offset < 0; - /* Don't negate offset here; it might overflow. */ - do { - int remainder = offset % 10; - int quotient = offset / 10; - if (offset < 0 && 0 < remainder) { - remainder -= 10; - quotient++; - } - *--p = (remainder < 0 ? -remainder : remainder) + '0'; - width--; - offset = quotient; - } while (offset != 0); - for (width -= negative; 0 < width; width--) { - putc (' ', file); - } - if (negative) { - putc ('-', file); - } - for (; p < buf + sizeof buf; p++) - putc (*p, file); -} - -/* ======================================================================== * Semi-safe malloc -- never returns NULL. */ voidp gzxmalloc (size) diff --git a/isys/gzlib/zip.c b/isys/gzlib/zip.c index 3c1b49773..ad3379dac 100644 --- a/isys/gzlib/zip.c +++ b/isys/gzlib/zip.c @@ -25,6 +25,66 @@ static char rcsid[] = "$Id$"; local ulg crc; /* crc on uncompressed file data */ off_t header_bytes; /* number of bytes in gzip header */ +/* =========================================================================== + * Deflate in to out. + * IN assertions: the input and output buffers are cleared. + * The variables time_stamp and save_orig_name are initialized. + */ +int zip(in, out) + int in, out; /* input and output file descriptors */ +{ + uch flags = 0; /* general purpose bit flags */ + ush attr = 0; /* ascii/binary flag */ + ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ + + ifd = in; + ofd = out; + outcnt = 0; + + /* Write the header to the gzip file. See algorithm.doc for the format */ + + method = DEFLATED; + put_byte(GZIP_MAGIC[0]); /* magic header */ + put_byte(GZIP_MAGIC[1]); + put_byte(DEFLATED); /* compression method */ + + put_byte(flags); /* general flags */ + put_long(time_stamp == (time_stamp & 0xffffffff) + ? (ulg)time_stamp : (ulg)0); + + /* Write deflated file to zip file */ + crc = updcrc(0, 0); + + bi_init(out); + ct_init(&attr, &method); + lm_init(level, &deflate_flags); + + put_byte((uch)deflate_flags); /* extra flags */ + put_byte(OS_CODE); /* OS identifier */ + + header_bytes = (off_t)outcnt; + + (void)deflate(); + +#if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO) + /* Check input size (but not in VMS -- variable record lengths mess it up) + * and not on MSDOS -- diet in TSR mode reports an incorrect file size) + */ + if (ifile_size != -1L && bytes_in != ifile_size) { + fprintf(stderr, "%s: %s: file size changed while zipping\n", + progname, ifname); + } +#endif + + /* Write the crc and uncompressed size */ + put_long(crc); + put_long((ulg)bytes_in); + header_bytes += 2*sizeof(long); + + flush_outbuf(); + return OK; +} + /* =========================================================================== * Read a new buffer from the current input file, perform end-of-line |