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