the code in gzip uses a function pointer abstraction but tries to shove too
much code into the same functions. this is impeding work to refactor the code
to fork + pledge helper processes.

in many cases, the duplication results absurd code like this:

        error = (decomp ? dodecompress : docompress)
            (infile, outfile, method, bits, entry->fts_statp);

what? why are we passing bits to a decompressor? because somebody was a little
too enamored with ?: operations.

this diff doesn't change any behavior, but creates separate read and write
open functions (which currently share quite a bit of code) that only take the
necessary arguments.

it also deletes a never used zopen function. and removes completely unncessary
mode checking, because these functions were only ever called with fixed
strings.


Index: compress.h
===================================================================
RCS file: /cvs/src/usr.bin/compress/compress.h,v
retrieving revision 1.12
diff -u -p -r1.12 compress.h
--- compress.h  22 Sep 2011 10:41:04 -0000      1.12
+++ compress.h  2 Sep 2016 15:53:55 -0000
@@ -58,26 +58,23 @@ enum program_mode {
 
 extern char null_magic[];
 
-extern void *z_open(int, const char *, char *, int, u_int32_t, int);
+extern void *z_ropen(int, char *, int);
+extern void *z_wopen(int, char *, int, u_int32_t);
 extern FILE *zopen(const char *, const char *,int);
 extern int zread(void *, char *, int);
 extern int zwrite(void *, const char *, int);
 extern int z_close(void *, struct z_info *, const char *, struct stat *);
 
 
-extern void *gz_open(int, const char *, char *, int, u_int32_t, int);
+extern void *gz_ropen(int, char *, int);
+extern void *gz_wopen(int, char *, int, u_int32_t);
 extern int gz_read(void *, char *, int);
 extern int gz_write(void *, const char *, int);
 extern int gz_close(void *, struct z_info *, const char *, struct stat *);
 extern int gz_flush(void *, int);
 
-extern void *lzh_open(int, const char *, char *, int, u_int32_t, int);
-extern int lzh_read(void *, char *, int);
-extern int lzh_write(void *, const char *, int);
-extern int lzh_close(void *, struct z_info *);
-extern int lzh_flush(void *, int);
-
-extern void *null_open(int, const char *, char *, int, u_int32_t, int);
+extern void *null_ropen(int, char *, int);
+extern void *null_wopen(int, char *, int, u_int32_t);
 extern int null_read(void *, char *, int);
 extern int null_write(void *, const char *, int);
 extern int null_close(void *, struct z_info *, const char *, struct stat *);
Index: gzopen.c
===================================================================
RCS file: /cvs/src/usr.bin/compress/gzopen.c,v
retrieving revision 1.32
diff -u -p -r1.32 gzopen.c
--- gzopen.c    17 Aug 2016 12:02:38 -0000      1.32
+++ gzopen.c    2 Sep 2016 15:57:39 -0000
@@ -103,16 +103,14 @@ static int put_header(gz_stream *, char 
 static int get_byte(gz_stream *);
 
 void *
-gz_open(int fd, const char *mode, char *name, int bits,
-    u_int32_t mtime, int gotmagic)
+gz_wopen(int fd, char *name, int bits, u_int32_t mtime)
 {
        gz_stream *s;
 
-       if (fd < 0 || !mode)
+       if (fd < 0)
                return NULL;
 
-       if ((mode[0] != 'r' && mode[0] != 'w') || mode[1] != '\0' ||
-           bits < 0 || bits > Z_BEST_COMPRESSION) {
+       if (bits < 0 || bits > Z_BEST_COMPRESSION) {
                errno = EINVAL;
                return NULL;
        }
@@ -132,45 +130,74 @@ gz_open(int fd, const char *mode, char *
        s->z_total_in = 0;
        s->z_total_out = 0;
        s->z_crc = crc32(0L, Z_NULL, 0);
-       s->z_mode = mode[0];
+       s->z_mode = 'w';
 
-       if (s->z_mode == 'w') {
 #ifndef SMALL
-               /* windowBits is passed < 0 to suppress zlib header */
-               if (deflateInit2(&(s->z_stream), bits, Z_DEFLATED,
-                                -MAX_WBITS, DEF_MEM_LEVEL, 0) != Z_OK) {
-                       free (s);
-                       return NULL;
-               }
-               s->z_stream.next_out = s->z_buf;
+       /* windowBits is passed < 0 to suppress zlib header */
+       if (deflateInit2(&(s->z_stream), bits, Z_DEFLATED,
+                        -MAX_WBITS, DEF_MEM_LEVEL, 0) != Z_OK) {
+               free (s);
+               return NULL;
+       }
+       s->z_stream.next_out = s->z_buf;
 #else
-               free(s);
-               return (NULL);
+       free(s);
+       return (NULL);
 #endif
-       } else {
-               if (inflateInit2(&(s->z_stream), -MAX_WBITS) != Z_OK) {
-                       free (s);
-                       return NULL;
-               }
-               s->z_stream.next_in = s->z_buf;
+       s->z_stream.avail_out = Z_BUFSIZE;
+
+       errno = 0;
+       s->z_fd = fd;
+
+       /* write the .gz header */
+       if (put_header(s, name, mtime, bits) != 0) {
+               gz_close(s, NULL, NULL, NULL);
+               s = NULL;
+       }
+
+       return s;
+}
+
+void *
+gz_ropen(int fd, char *name, int gotmagic)
+{
+       gz_stream *s;
+
+       if (fd < 0)
+               return NULL;
+
+       if ((s = calloc(1, sizeof(gz_stream))) == NULL)
+               return NULL;
+
+       s->z_stream.zalloc = (alloc_func)0;
+       s->z_stream.zfree = (free_func)0;
+       s->z_stream.opaque = (voidpf)0;
+       s->z_stream.next_in = Z_NULL;
+       s->z_stream.next_out = Z_NULL;
+       s->z_stream.avail_in = s->z_stream.avail_out = 0;
+       s->z_fd = 0;
+       s->z_eof = 0;
+       s->z_time = 0;
+       s->z_hlen = 0;
+       s->z_total_in = 0;
+       s->z_total_out = 0;
+       s->z_crc = crc32(0L, Z_NULL, 0);
+       s->z_mode = 'r';
+
+       if (inflateInit2(&(s->z_stream), -MAX_WBITS) != Z_OK) {
+               free (s);
+               return NULL;
        }
+       s->z_stream.next_in = s->z_buf;
        s->z_stream.avail_out = Z_BUFSIZE;
 
        errno = 0;
        s->z_fd = fd;
 
-       if (s->z_mode == 'w') {
-               /* write the .gz header */
-               if (put_header(s, name, mtime, bits) != 0) {
-                       gz_close(s, NULL, NULL, NULL);
-                       s = NULL;
-               }
-       } else {
-               /* read the .gz header */
-               if (get_header(s, name, gotmagic) != 0) {
-                       gz_close(s, NULL, NULL, NULL);
-                       s = NULL;
-               }
+       /* read the .gz header */
+       if (get_header(s, name, gotmagic) != 0) {
+               gz_close(s, NULL, NULL, NULL);
+               s = NULL;
        }
 
        return s;
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/compress/main.c,v
retrieving revision 1.91
diff -u -p -r1.91 main.c
--- main.c      14 Jul 2016 08:31:18 -0000      1.91
+++ main.c      2 Sep 2016 15:54:32 -0000
@@ -60,7 +60,8 @@ const struct compressor {
        const char *comp_opts;
        const char *decomp_opts;
        const char *cat_opts;
-       void *(*open)(int, const char *, char *, int, u_int32_t, int);
+       void *(*ropen)(int, char *, int);
+       void *(*wopen)(int, char *, int, u_int32_t);
        int (*read)(void *, char *, int);
        int (*write)(void *, const char *, int);
        int (*close)(void *, struct z_info *, const char *, struct stat *);
@@ -73,7 +74,8 @@ const struct compressor {
                "123456789ab:cdfhLlNnOo:qrS:tVv",
                "cfhLlNno:qrtVv",
                "fhqr",
-               gz_open,
+               gz_ropen,
+               gz_wopen,
                gz_read,
                gz_write,
                gz_close
@@ -87,20 +89,13 @@ const struct compressor {
                "123456789ab:cdfghlNnOo:qrS:tv",
                "cfhlNno:qrtv",
                "fghqr",
-               z_open,
+               z_ropen,
+               z_wopen,
                zread,
                zwrite,
                z_close
        },
 #endif /* SMALL */
-#if 0
-#define M_LZH (&c_table[2])
-  { "lzh", ".lzh", "\037\240", lzh_open, lzh_read, lzh_write, lzh_close },
-#define M_ZIP (&c_table[3])
-  { "zip", ".zip", "PK", zip_open, zip_read, zip_write, zip_close },
-#define M_PACK (&c_table[4])
-  { "pack", ".pak", "\037\036", pak_open, pak_read, pak_write, pak_close },
-#endif
   { NULL }
 };
 
@@ -112,7 +107,8 @@ const struct compressor null_method = {
        "123456789ab:cdfghlNnOo:qrS:tv",
        "cfhlNno:qrtv",
        "fghqr",
-       null_open,
+       null_ropen,
+       null_wopen,
        null_read,
        null_write,
        null_close
@@ -123,8 +119,7 @@ int permission(const char *);
 __dead void usage(int);
 int docompress(const char *, char *, const struct compressor *,
     int, struct stat *);
-int dodecompress(const char *, char *, const struct compressor *,
-    int, struct stat *);
+int dodecompress(const char *, char *, struct stat *);
 const struct compressor *check_method(int);
 const char *check_suffix(const char *);
 char *set_outfile(const char *, char *, size_t);
@@ -450,8 +445,10 @@ main(int argc, char *argv[])
                if (verbose > 0 && !pipin && !list)
                        fprintf(stderr, "%s:\t", infile);
 
-               error = (decomp ? dodecompress : docompress)
-                   (infile, outfile, method, bits, entry->fts_statp);
+               if (decomp)
+                       error = dodecompress(infile, outfile, entry->fts_statp);
+               else
+                       error = docompress(infile, outfile, method, bits, 
entry->fts_statp);
 
                switch (error) {
                case SUCCESS:
@@ -481,7 +478,7 @@ docompress(const char *in, char *out, co
 #ifndef SMALL
        u_char buf[Z_BUFSIZE];
        char *name;
-       int error, ifd, ofd, flags, oreg;
+       int error, ifd, ofd, oreg;
        void *cookie;
        ssize_t nr;
        u_int32_t mtime;
@@ -489,7 +486,7 @@ docompress(const char *in, char *out, co
        struct stat osb;
 
        mtime = 0;
-       flags = oreg = 0;
+       oreg = 0;
        error = SUCCESS;
        name = NULL;
        cookie  = NULL;
@@ -536,7 +533,7 @@ docompress(const char *in, char *out, co
                name = basename(in);
                mtime = (u_int32_t)sb->st_mtime;
        }
-       if ((cookie = (*method->open)(ofd, "w", name, bits, mtime, flags)) == 
NULL) {
+       if ((cookie = method->wopen(ofd, name, bits, mtime)) == NULL) {
                if (verbose >= 0)
                        warn("%s", out);
                if (oreg)
@@ -616,9 +613,9 @@ check_method(int fd)
 }
 
 int
-dodecompress(const char *in, char *out, const struct compressor *method,
-    int bits, struct stat *sb)
+dodecompress(const char *in, char *out, struct stat *sb)
 {
+       const struct compressor *method;
        u_char buf[Z_BUFSIZE];
        char oldname[PATH_MAX];
        int error, oreg, ifd, ofd;
@@ -658,7 +655,7 @@ dodecompress(const char *in, char *out, 
 
        /* XXX - open constrains outfile to MAXPATHLEN so this is safe */
        oldname[0] = '\0';
-       if ((cookie = (*method->open)(ifd, "r", oldname, bits, 0, 1)) == NULL) {
+       if ((cookie = method->ropen(ifd, oldname, 1)) == NULL) {
                if (verbose >= 0)
                        warn("%s", in);
                close (ifd);
Index: nullopen.c
===================================================================
RCS file: /cvs/src/usr.bin/compress/nullopen.c,v
retrieving revision 1.5
diff -u -p -r1.5 nullopen.c
--- nullopen.c  20 Aug 2015 22:32:41 -0000      1.5
+++ nullopen.c  2 Sep 2016 15:50:12 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nullopen.c,v 1.5 2015/08/20 22:32:41 deraadt Exp $    */
+/*     $OpenBSD: nullopen.c,v 1.4 2011/09/22 10:41:04 deraadt Exp $    */
 
 /*
  * Copyright (c) 2003 Can Erkin Acar
@@ -47,26 +47,39 @@ char null_magic[2];
 
 
 void *
-null_open(int fd, const char *mode, char *name, int bits,
-    u_int32_t mtime, int gotmagic)
+null_ropen(int fd, char *name, int gotmagic)
 {
        null_stream *s;
 
-       if (fd < 0 || !mode)
+       if (fd < 0)
                return NULL;
 
-       if ((mode[0] != 'r' && mode[0] != 'w') || mode[1] != '\0') {
-               errno = EINVAL;
+       if ((s = calloc(1, sizeof(null_stream))) == NULL)
+               return NULL;
+
+       s->fd = fd;
+       s->gotmagic = gotmagic;
+       s->total_in = s->total_out = 0;
+       s->mode = 'r';
+
+       return s;
+}
+
+void *
+null_wopen(int fd, char *name, int bits, u_int32_t mtime)
+{
+       null_stream *s;
+
+       if (fd < 0)
                return NULL;
-       }
 
        if ((s = calloc(1, sizeof(null_stream))) == NULL)
                return NULL;
 
        s->fd = fd;
-       s->gotmagic = gotmagic;
+       s->gotmagic = 0;
        s->total_in = s->total_out = 0;
-       s->mode = mode[0];
+       s->mode = 'w';
 
        return s;
 }
Index: zopen.c
===================================================================
RCS file: /cvs/src/usr.bin/compress/zopen.c,v
retrieving revision 1.20
diff -u -p -r1.20 zopen.c
--- zopen.c     1 Feb 2015 11:50:23 -0000       1.20
+++ zopen.c     2 Sep 2016 15:56:57 -0000
@@ -735,36 +735,12 @@ cl_hash(struct s_zstate *zs, count_int c
                *--htab_p = m1;
 }
 
-FILE *
-zopen(const char *name, const char *mode, int bits)
-{
-       FILE *fp;
-       int fd;
-       void *cookie;
-       if ((fd = open(name, (*mode=='r'? O_RDONLY:O_WRONLY|O_CREAT),
-           S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
-               return NULL;
-       if ((cookie = z_open(fd, mode, NULL, bits, 0, 0)) == NULL) {
-               close(fd);
-               return NULL;
-       }
-       if ((fp = funopen(cookie, (*mode == 'r'?zread:NULL),
-           (*mode == 'w'?zwrite:NULL), NULL, zclose)) == NULL) {
-               close(fd);
-               free(cookie);
-               return NULL;
-       }
-       return fp;
-}
-
 void *
-z_open(int fd, const char *mode, char *name, int bits,
-    u_int32_t mtime, int gotmagic)
+z_wopen(int fd, char *name, int bits, u_int32_t mtime)
 {
        struct s_zstate *zs;
 
-       if ((mode[0] != 'r' && mode[0] != 'w') || mode[1] != '\0' ||
-           bits < 0 || bits > BITS) {
+       if (bits < 0 || bits > BITS) {
                errno = EINVAL;
                return (NULL);
        }
@@ -784,10 +760,40 @@ z_open(int fd, const char *mode, char *n
        zs->zs_checkpoint = CHECK_GAP;
        zs->zs_in_count = 0;            /* Length of input. */
        zs->zs_out_count = 0;           /* # of codes output (for debugging).*/
+       zs->zs_state = S_START;
+       zs->zs_offset = 0;
+       zs->zs_size = 0;
+       zs->zs_mode = 'w';
+       zs->zs_bp = zs->zs_ebp = zs->zs_buf;
+
+       zs->zs_fd = fd;
+       return zs;
+}
+
+void *
+z_ropen(int fd, char *name, int gotmagic)
+{
+       struct s_zstate *zs;
+
+       if ((zs = calloc(1, sizeof(struct s_zstate))) == NULL)
+               return (NULL);
+
+       /* User settable max # bits/code. */
+       zs->zs_maxbits = BITS;
+       /* Should NEVER generate this code. */
+       zs->zs_maxmaxcode = 1 << zs->zs_maxbits;
+       zs->zs_hsize = HSIZE;           /* For dynamic table sizing. */
+       zs->zs_free_ent = 0;            /* First unused entry. */
+       zs->zs_block_compress = BLOCK_MASK;
+       zs->zs_clear_flg = 0;
+       zs->zs_ratio = 0;
+       zs->zs_checkpoint = CHECK_GAP;
+       zs->zs_in_count = 0;            /* Length of input. */
+       zs->zs_out_count = 0;           /* # of codes output (for debugging).*/
        zs->zs_state = gotmagic ? S_MAGIC : S_START;
        zs->zs_offset = 0;
        zs->zs_size = 0;
-       zs->zs_mode = mode[0];
+       zs->zs_mode = 'r';
        zs->zs_bp = zs->zs_ebp = zs->zs_buf;
 
        zs->zs_fd = fd;

Reply via email to