kusano 7d535a
/* minigzip.c -- simulate gzip using the zlib compression library
kusano 7d535a
 * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly.
kusano 7d535a
 * For conditions of distribution and use, see copyright notice in zlib.h
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
/*
kusano 7d535a
 * minigzip is a minimal implementation of the gzip utility. This is
kusano 7d535a
 * only an example of using zlib and isn't meant to replace the
kusano 7d535a
 * full-featured gzip. No attempt is made to deal with file systems
kusano 7d535a
 * limiting names to 14 or 8+3 characters, etc... Error checking is
kusano 7d535a
 * very limited. So use minigzip only for testing; use gzip for the
kusano 7d535a
 * real thing. On MSDOS, use only on file names without extension
kusano 7d535a
 * or in pipe mode.
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
/* @(#) $Id$ */
kusano 7d535a
kusano 7d535a
#include "zlib.h"
kusano 7d535a
#include <stdio.h></stdio.h>
kusano 7d535a
kusano 7d535a
#ifdef STDC
kusano 7d535a
#  include <string.h></string.h>
kusano 7d535a
#  include <stdlib.h></stdlib.h>
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#ifdef USE_MMAP
kusano 7d535a
#  include <sys types.h=""></sys>
kusano 7d535a
#  include <sys mman.h=""></sys>
kusano 7d535a
#  include <sys stat.h=""></sys>
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
kusano 7d535a
#  include <fcntl.h></fcntl.h>
kusano 7d535a
#  include <io.h></io.h>
kusano 7d535a
#  ifdef UNDER_CE
kusano 7d535a
#    include <stdlib.h></stdlib.h>
kusano 7d535a
#  endif
kusano 7d535a
#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
kusano 7d535a
#else
kusano 7d535a
#  define SET_BINARY_MODE(file)
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#ifdef VMS
kusano 7d535a
#  define unlink delete
kusano 7d535a
#  define GZ_SUFFIX "-gz"
kusano 7d535a
#endif
kusano 7d535a
#ifdef RISCOS
kusano 7d535a
#  define unlink remove
kusano 7d535a
#  define GZ_SUFFIX "-gz"
kusano 7d535a
#  define fileno(file) file->__file
kusano 7d535a
#endif
kusano 7d535a
#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
kusano 7d535a
#  include <unix.h> /* for fileno */</unix.h>
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
kusano 7d535a
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
kusano 7d535a
  extern int unlink OF((const char *));
kusano 7d535a
#endif
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#if defined(UNDER_CE)
kusano 7d535a
#  include <windows.h></windows.h>
kusano 7d535a
#  define perror(s) pwinerror(s)
kusano 7d535a
kusano 7d535a
/* Map the Windows error number in ERROR to a locale-dependent error
kusano 7d535a
   message string and return a pointer to it.  Typically, the values
kusano 7d535a
   for ERROR come from GetLastError.
kusano 7d535a
kusano 7d535a
   The string pointed to shall not be modified by the application,
kusano 7d535a
   but may be overwritten by a subsequent call to strwinerror
kusano 7d535a
kusano 7d535a
   The strwinerror function does not change the current setting
kusano 7d535a
   of GetLastError.  */
kusano 7d535a
kusano 7d535a
static char *strwinerror (error)
kusano 7d535a
     DWORD error;
kusano 7d535a
{
kusano 7d535a
    static char buf[1024];
kusano 7d535a
kusano 7d535a
    wchar_t *msgbuf;
kusano 7d535a
    DWORD lasterr = GetLastError();
kusano 7d535a
    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
kusano 7d535a
        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
kusano 7d535a
        NULL,
kusano 7d535a
        error,
kusano 7d535a
        0, /* Default language */
kusano 7d535a
        (LPVOID)&msgbuf,
kusano 7d535a
        0,
kusano 7d535a
        NULL);
kusano 7d535a
    if (chars != 0) {
kusano 7d535a
        /* If there is an \r\n appended, zap it.  */
kusano 7d535a
        if (chars >= 2
kusano 7d535a
            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
kusano 7d535a
            chars -= 2;
kusano 7d535a
            msgbuf[chars] = 0;
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
        if (chars > sizeof (buf) - 1) {
kusano 7d535a
            chars = sizeof (buf) - 1;
kusano 7d535a
            msgbuf[chars] = 0;
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
        wcstombs(buf, msgbuf, chars + 1);
kusano 7d535a
        LocalFree(msgbuf);
kusano 7d535a
    }
kusano 7d535a
    else {
kusano 7d535a
        sprintf(buf, "unknown win32 error (%ld)", error);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    SetLastError(lasterr);
kusano 7d535a
    return buf;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
static void pwinerror (s)
kusano 7d535a
    const char *s;
kusano 7d535a
{
kusano 7d535a
    if (s && *s)
kusano 7d535a
        fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
kusano 7d535a
    else
kusano 7d535a
        fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
#endif /* UNDER_CE */
kusano 7d535a
kusano 7d535a
#ifndef GZ_SUFFIX
kusano 7d535a
#  define GZ_SUFFIX ".gz"
kusano 7d535a
#endif
kusano 7d535a
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
kusano 7d535a
kusano 7d535a
#define BUFLEN      16384
kusano 7d535a
#define MAX_NAME_LEN 1024
kusano 7d535a
kusano 7d535a
#ifdef MAXSEG_64K
kusano 7d535a
#  define local static
kusano 7d535a
   /* Needed for systems with limitation on stack size. */
kusano 7d535a
#else
kusano 7d535a
#  define local
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#ifdef Z_SOLO
kusano 7d535a
/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
kusano 7d535a
kusano 7d535a
#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
kusano 7d535a
#  include <unistd.h>       /* for unlink() */</unistd.h>
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
void *myalloc OF((void *, unsigned, unsigned));
kusano 7d535a
void myfree OF((void *, void *));
kusano 7d535a
kusano 7d535a
void *myalloc(q, n, m)
kusano 7d535a
    void *q;
kusano 7d535a
    unsigned n, m;
kusano 7d535a
{
kusano 7d535a
    q = Z_NULL;
kusano 7d535a
    return calloc(n, m);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
void myfree(q, p)
kusano 7d535a
    void *q, *p;
kusano 7d535a
{
kusano 7d535a
    q = Z_NULL;
kusano 7d535a
    free(p);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
typedef struct gzFile_s {
kusano 7d535a
    FILE *file;
kusano 7d535a
    int write;
kusano 7d535a
    int err;
kusano 7d535a
    char *msg;
kusano 7d535a
    z_stream strm;
kusano 7d535a
} *gzFile;
kusano 7d535a
kusano 7d535a
gzFile gzopen OF((const char *, const char *));
kusano 7d535a
gzFile gzdopen OF((int, const char *));
kusano 7d535a
gzFile gz_open OF((const char *, int, const char *));
kusano 7d535a
kusano 7d535a
gzFile gzopen(path, mode)
kusano 7d535a
const char *path;
kusano 7d535a
const char *mode;
kusano 7d535a
{
kusano 7d535a
    return gz_open(path, -1, mode);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
gzFile gzdopen(fd, mode)
kusano 7d535a
int fd;
kusano 7d535a
const char *mode;
kusano 7d535a
{
kusano 7d535a
    return gz_open(NULL, fd, mode);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
gzFile gz_open(path, fd, mode)
kusano 7d535a
    const char *path;
kusano 7d535a
    int fd;
kusano 7d535a
    const char *mode;
kusano 7d535a
{
kusano 7d535a
    gzFile gz;
kusano 7d535a
    int ret;
kusano 7d535a
kusano 7d535a
    gz = malloc(sizeof(struct gzFile_s));
kusano 7d535a
    if (gz == NULL)
kusano 7d535a
        return NULL;
kusano 7d535a
    gz->write = strchr(mode, 'w') != NULL;
kusano 7d535a
    gz->strm.zalloc = myalloc;
kusano 7d535a
    gz->strm.zfree = myfree;
kusano 7d535a
    gz->strm.opaque = Z_NULL;
kusano 7d535a
    if (gz->write)
kusano 7d535a
        ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
kusano 7d535a
    else {
kusano 7d535a
        gz->strm.next_in = 0;
kusano 7d535a
        gz->strm.avail_in = Z_NULL;
kusano 7d535a
        ret = inflateInit2(&(gz->strm), 15 + 16);
kusano 7d535a
    }
kusano 7d535a
    if (ret != Z_OK) {
kusano 7d535a
        free(gz);
kusano 7d535a
        return NULL;
kusano 7d535a
    }
kusano 7d535a
    gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
kusano 7d535a
                              fopen(path, gz->write ? "wb" : "rb");
kusano 7d535a
    if (gz->file == NULL) {
kusano 7d535a
        gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
kusano 7d535a
        free(gz);
kusano 7d535a
        return NULL;
kusano 7d535a
    }
kusano 7d535a
    gz->err = 0;
kusano 7d535a
    gz->msg = "";
kusano 7d535a
    return gz;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
int gzwrite OF((gzFile, const void *, unsigned));
kusano 7d535a
kusano 7d535a
int gzwrite(gz, buf, len)
kusano 7d535a
    gzFile gz;
kusano 7d535a
    const void *buf;
kusano 7d535a
    unsigned len;
kusano 7d535a
{
kusano 7d535a
    z_stream *strm;
kusano 7d535a
    unsigned char out[BUFLEN];
kusano 7d535a
kusano 7d535a
    if (gz == NULL || !gz->write)
kusano 7d535a
        return 0;
kusano 7d535a
    strm = &(gz->strm);
kusano 7d535a
    strm->next_in = (void *)buf;
kusano 7d535a
    strm->avail_in = len;
kusano 7d535a
    do {
kusano 7d535a
        strm->next_out = out;
kusano 7d535a
        strm->avail_out = BUFLEN;
kusano 7d535a
        (void)deflate(strm, Z_NO_FLUSH);
kusano 7d535a
        fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
kusano 7d535a
    } while (strm->avail_out == 0);
kusano 7d535a
    return len;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
int gzread OF((gzFile, void *, unsigned));
kusano 7d535a
kusano 7d535a
int gzread(gz, buf, len)
kusano 7d535a
    gzFile gz;
kusano 7d535a
    void *buf;
kusano 7d535a
    unsigned len;
kusano 7d535a
{
kusano 7d535a
    int ret;
kusano 7d535a
    unsigned got;
kusano 7d535a
    unsigned char in[1];
kusano 7d535a
    z_stream *strm;
kusano 7d535a
kusano 7d535a
    if (gz == NULL || gz->write)
kusano 7d535a
        return 0;
kusano 7d535a
    if (gz->err)
kusano 7d535a
        return 0;
kusano 7d535a
    strm = &(gz->strm);
kusano 7d535a
    strm->next_out = (void *)buf;
kusano 7d535a
    strm->avail_out = len;
kusano 7d535a
    do {
kusano 7d535a
        got = fread(in, 1, 1, gz->file);
kusano 7d535a
        if (got == 0)
kusano 7d535a
            break;
kusano 7d535a
        strm->next_in = in;
kusano 7d535a
        strm->avail_in = 1;
kusano 7d535a
        ret = inflate(strm, Z_NO_FLUSH);
kusano 7d535a
        if (ret == Z_DATA_ERROR) {
kusano 7d535a
            gz->err = Z_DATA_ERROR;
kusano 7d535a
            gz->msg = strm->msg;
kusano 7d535a
            return 0;
kusano 7d535a
        }
kusano 7d535a
        if (ret == Z_STREAM_END)
kusano 7d535a
            inflateReset(strm);
kusano 7d535a
    } while (strm->avail_out);
kusano 7d535a
    return len - strm->avail_out;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
int gzclose OF((gzFile));
kusano 7d535a
kusano 7d535a
int gzclose(gz)
kusano 7d535a
    gzFile gz;
kusano 7d535a
{
kusano 7d535a
    z_stream *strm;
kusano 7d535a
    unsigned char out[BUFLEN];
kusano 7d535a
kusano 7d535a
    if (gz == NULL)
kusano 7d535a
        return Z_STREAM_ERROR;
kusano 7d535a
    strm = &(gz->strm);
kusano 7d535a
    if (gz->write) {
kusano 7d535a
        strm->next_in = Z_NULL;
kusano 7d535a
        strm->avail_in = 0;
kusano 7d535a
        do {
kusano 7d535a
            strm->next_out = out;
kusano 7d535a
            strm->avail_out = BUFLEN;
kusano 7d535a
            (void)deflate(strm, Z_FINISH);
kusano 7d535a
            fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
kusano 7d535a
        } while (strm->avail_out == 0);
kusano 7d535a
        deflateEnd(strm);
kusano 7d535a
    }
kusano 7d535a
    else
kusano 7d535a
        inflateEnd(strm);
kusano 7d535a
    fclose(gz->file);
kusano 7d535a
    free(gz);
kusano 7d535a
    return Z_OK;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
const char *gzerror OF((gzFile, int *));
kusano 7d535a
kusano 7d535a
const char *gzerror(gz, err)
kusano 7d535a
    gzFile gz;
kusano 7d535a
    int *err;
kusano 7d535a
{
kusano 7d535a
    *err = gz->err;
kusano 7d535a
    return gz->msg;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
char *prog;
kusano 7d535a
kusano 7d535a
void error            OF((const char *msg));
kusano 7d535a
void gz_compress      OF((FILE   *in, gzFile out));
kusano 7d535a
#ifdef USE_MMAP
kusano 7d535a
int  gz_compress_mmap OF((FILE   *in, gzFile out));
kusano 7d535a
#endif
kusano 7d535a
void gz_uncompress    OF((gzFile in, FILE   *out));
kusano 7d535a
void file_compress    OF((char  *file, char *mode));
kusano 7d535a
void file_uncompress  OF((char  *file));
kusano 7d535a
int  main             OF((int argc, char *argv[]));
kusano 7d535a
kusano 7d535a
/* ===========================================================================
kusano 7d535a
 * Display error message and exit
kusano 7d535a
 */
kusano 7d535a
void error(msg)
kusano 7d535a
    const char *msg;
kusano 7d535a
{
kusano 7d535a
    fprintf(stderr, "%s: %s\n", prog, msg);
kusano 7d535a
    exit(1);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
/* ===========================================================================
kusano 7d535a
 * Compress input to output then close both files.
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
void gz_compress(in, out)
kusano 7d535a
    FILE   *in;
kusano 7d535a
    gzFile out;
kusano 7d535a
{
kusano 7d535a
    local char buf[BUFLEN];
kusano 7d535a
    int len;
kusano 7d535a
    int err;
kusano 7d535a
kusano 7d535a
#ifdef USE_MMAP
kusano 7d535a
    /* Try first compressing with mmap. If mmap fails (minigzip used in a
kusano 7d535a
     * pipe), use the normal fread loop.
kusano 7d535a
     */
kusano 7d535a
    if (gz_compress_mmap(in, out) == Z_OK) return;
kusano 7d535a
#endif
kusano 7d535a
    for (;;) {
kusano 7d535a
        len = (int)fread(buf, 1, sizeof(buf), in);
kusano 7d535a
        if (ferror(in)) {
kusano 7d535a
            perror("fread");
kusano 7d535a
            exit(1);
kusano 7d535a
        }
kusano 7d535a
        if (len == 0) break;
kusano 7d535a
kusano 7d535a
        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
kusano 7d535a
    }
kusano 7d535a
    fclose(in);
kusano 7d535a
    if (gzclose(out) != Z_OK) error("failed gzclose");
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */</malbrech@eso.org>
kusano 7d535a
kusano 7d535a
/* Try compressing the input file at once using mmap. Return Z_OK if
kusano 7d535a
 * if success, Z_ERRNO otherwise.
kusano 7d535a
 */
kusano 7d535a
int gz_compress_mmap(in, out)
kusano 7d535a
    FILE   *in;
kusano 7d535a
    gzFile out;
kusano 7d535a
{
kusano 7d535a
    int len;
kusano 7d535a
    int err;
kusano 7d535a
    int ifd = fileno(in);
kusano 7d535a
    caddr_t buf;    /* mmap'ed buffer for the entire input file */
kusano 7d535a
    off_t buf_len;  /* length of the input file */
kusano 7d535a
    struct stat sb;
kusano 7d535a
kusano 7d535a
    /* Determine the size of the file, needed for mmap: */
kusano 7d535a
    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
kusano 7d535a
    buf_len = sb.st_size;
kusano 7d535a
    if (buf_len <= 0) return Z_ERRNO;
kusano 7d535a
kusano 7d535a
    /* Now do the actual mmap: */
kusano 7d535a
    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
kusano 7d535a
    if (buf == (caddr_t)(-1)) return Z_ERRNO;
kusano 7d535a
kusano 7d535a
    /* Compress the whole file at once: */
kusano 7d535a
    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
kusano 7d535a
kusano 7d535a
    if (len != (int)buf_len) error(gzerror(out, &err));
kusano 7d535a
kusano 7d535a
    munmap(buf, buf_len);
kusano 7d535a
    fclose(in);
kusano 7d535a
    if (gzclose(out) != Z_OK) error("failed gzclose");
kusano 7d535a
    return Z_OK;
kusano 7d535a
}
kusano 7d535a
#endif /* USE_MMAP */
kusano 7d535a
kusano 7d535a
/* ===========================================================================
kusano 7d535a
 * Uncompress input to output then close both files.
kusano 7d535a
 */
kusano 7d535a
void gz_uncompress(in, out)
kusano 7d535a
    gzFile in;
kusano 7d535a
    FILE   *out;
kusano 7d535a
{
kusano 7d535a
    local char buf[BUFLEN];
kusano 7d535a
    int len;
kusano 7d535a
    int err;
kusano 7d535a
kusano 7d535a
    for (;;) {
kusano 7d535a
        len = gzread(in, buf, sizeof(buf));
kusano 7d535a
        if (len < 0) error (gzerror(in, &err));
kusano 7d535a
        if (len == 0) break;
kusano 7d535a
kusano 7d535a
        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
kusano 7d535a
            error("failed fwrite");
kusano 7d535a
        }
kusano 7d535a
    }
kusano 7d535a
    if (fclose(out)) error("failed fclose");
kusano 7d535a
kusano 7d535a
    if (gzclose(in) != Z_OK) error("failed gzclose");
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/* ===========================================================================
kusano 7d535a
 * Compress the given file: create a corresponding .gz file and remove the
kusano 7d535a
 * original.
kusano 7d535a
 */
kusano 7d535a
void file_compress(file, mode)
kusano 7d535a
    char  *file;
kusano 7d535a
    char  *mode;
kusano 7d535a
{
kusano 7d535a
    local char outfile[MAX_NAME_LEN];
kusano 7d535a
    FILE  *in;
kusano 7d535a
    gzFile out;
kusano 7d535a
kusano 7d535a
    if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
kusano 7d535a
        fprintf(stderr, "%s: filename too long\n", prog);
kusano 7d535a
        exit(1);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    strcpy(outfile, file);
kusano 7d535a
    strcat(outfile, GZ_SUFFIX);
kusano 7d535a
kusano 7d535a
    in = fopen(file, "rb");
kusano 7d535a
    if (in == NULL) {
kusano 7d535a
        perror(file);
kusano 7d535a
        exit(1);
kusano 7d535a
    }
kusano 7d535a
    out = gzopen(outfile, mode);
kusano 7d535a
    if (out == NULL) {
kusano 7d535a
        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
kusano 7d535a
        exit(1);
kusano 7d535a
    }
kusano 7d535a
    gz_compress(in, out);
kusano 7d535a
kusano 7d535a
    unlink(file);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/* ===========================================================================
kusano 7d535a
 * Uncompress the given file and remove the original.
kusano 7d535a
 */
kusano 7d535a
void file_uncompress(file)
kusano 7d535a
    char  *file;
kusano 7d535a
{
kusano 7d535a
    local char buf[MAX_NAME_LEN];
kusano 7d535a
    char *infile, *outfile;
kusano 7d535a
    FILE  *out;
kusano 7d535a
    gzFile in;
kusano 7d535a
    size_t len = strlen(file);
kusano 7d535a
kusano 7d535a
    if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
kusano 7d535a
        fprintf(stderr, "%s: filename too long\n", prog);
kusano 7d535a
        exit(1);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    strcpy(buf, file);
kusano 7d535a
kusano 7d535a
    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
kusano 7d535a
        infile = file;
kusano 7d535a
        outfile = buf;
kusano 7d535a
        outfile[len-3] = '\0';
kusano 7d535a
    } else {
kusano 7d535a
        outfile = file;
kusano 7d535a
        infile = buf;
kusano 7d535a
        strcat(infile, GZ_SUFFIX);
kusano 7d535a
    }
kusano 7d535a
    in = gzopen(infile, "rb");
kusano 7d535a
    if (in == NULL) {
kusano 7d535a
        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
kusano 7d535a
        exit(1);
kusano 7d535a
    }
kusano 7d535a
    out = fopen(outfile, "wb");
kusano 7d535a
    if (out == NULL) {
kusano 7d535a
        perror(file);
kusano 7d535a
        exit(1);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    gz_uncompress(in, out);
kusano 7d535a
kusano 7d535a
    unlink(infile);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/* ===========================================================================
kusano 7d535a
 * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
kusano 7d535a
 *   -c : write to standard output
kusano 7d535a
 *   -d : decompress
kusano 7d535a
 *   -f : compress with Z_FILTERED
kusano 7d535a
 *   -h : compress with Z_HUFFMAN_ONLY
kusano 7d535a
 *   -r : compress with Z_RLE
kusano 7d535a
 *   -1 to -9 : compression level
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
int main(argc, argv)
kusano 7d535a
    int argc;
kusano 7d535a
    char *argv[];
kusano 7d535a
{
kusano 7d535a
    int copyout = 0;
kusano 7d535a
    int uncompr = 0;
kusano 7d535a
    gzFile file;
kusano 7d535a
    char *bname, outmode[20];
kusano 7d535a
kusano 7d535a
    strcpy(outmode, "wb6 ");
kusano 7d535a
kusano 7d535a
    prog = argv[0];
kusano 7d535a
    bname = strrchr(argv[0], '/');
kusano 7d535a
    if (bname)
kusano 7d535a
      bname++;
kusano 7d535a
    else
kusano 7d535a
      bname = argv[0];
kusano 7d535a
    argc--, argv++;
kusano 7d535a
kusano 7d535a
    if (!strcmp(bname, "gunzip"))
kusano 7d535a
      uncompr = 1;
kusano 7d535a
    else if (!strcmp(bname, "zcat"))
kusano 7d535a
      copyout = uncompr = 1;
kusano 7d535a
kusano 7d535a
    while (argc > 0) {
kusano 7d535a
      if (strcmp(*argv, "-c") == 0)
kusano 7d535a
        copyout = 1;
kusano 7d535a
      else if (strcmp(*argv, "-d") == 0)
kusano 7d535a
        uncompr = 1;
kusano 7d535a
      else if (strcmp(*argv, "-f") == 0)
kusano 7d535a
        outmode[3] = 'f';
kusano 7d535a
      else if (strcmp(*argv, "-h") == 0)
kusano 7d535a
        outmode[3] = 'h';
kusano 7d535a
      else if (strcmp(*argv, "-r") == 0)
kusano 7d535a
        outmode[3] = 'R';
kusano 7d535a
      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
kusano 7d535a
               (*argv)[2] == 0)
kusano 7d535a
        outmode[2] = (*argv)[1];
kusano 7d535a
      else
kusano 7d535a
        break;
kusano 7d535a
      argc--, argv++;
kusano 7d535a
    }
kusano 7d535a
    if (outmode[3] == ' ')
kusano 7d535a
        outmode[3] = 0;
kusano 7d535a
    if (argc == 0) {
kusano 7d535a
        SET_BINARY_MODE(stdin);
kusano 7d535a
        SET_BINARY_MODE(stdout);
kusano 7d535a
        if (uncompr) {
kusano 7d535a
            file = gzdopen(fileno(stdin), "rb");
kusano 7d535a
            if (file == NULL) error("can't gzdopen stdin");
kusano 7d535a
            gz_uncompress(file, stdout);
kusano 7d535a
        } else {
kusano 7d535a
            file = gzdopen(fileno(stdout), outmode);
kusano 7d535a
            if (file == NULL) error("can't gzdopen stdout");
kusano 7d535a
            gz_compress(stdin, file);
kusano 7d535a
        }
kusano 7d535a
    } else {
kusano 7d535a
        if (copyout) {
kusano 7d535a
            SET_BINARY_MODE(stdout);
kusano 7d535a
        }
kusano 7d535a
        do {
kusano 7d535a
            if (uncompr) {
kusano 7d535a
                if (copyout) {
kusano 7d535a
                    file = gzopen(*argv, "rb");
kusano 7d535a
                    if (file == NULL)
kusano 7d535a
                        fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
kusano 7d535a
                    else
kusano 7d535a
                        gz_uncompress(file, stdout);
kusano 7d535a
                } else {
kusano 7d535a
                    file_uncompress(*argv);
kusano 7d535a
                }
kusano 7d535a
            } else {
kusano 7d535a
                if (copyout) {
kusano 7d535a
                    FILE * in = fopen(*argv, "rb");
kusano 7d535a
kusano 7d535a
                    if (in == NULL) {
kusano 7d535a
                        perror(*argv);
kusano 7d535a
                    } else {
kusano 7d535a
                        file = gzdopen(fileno(stdout), outmode);
kusano 7d535a
                        if (file == NULL) error("can't gzdopen stdout");
kusano 7d535a
kusano 7d535a
                        gz_compress(in, file);
kusano 7d535a
                    }
kusano 7d535a
kusano 7d535a
                } else {
kusano 7d535a
                    file_compress(*argv, outmode);
kusano 7d535a
                }
kusano 7d535a
            }
kusano 7d535a
        } while (argv++, --argc);
kusano 7d535a
    }
kusano 7d535a
    return 0;
kusano 7d535a
}