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