19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* minigzip.c -- simulate gzip using the zlib compression library
27291b8caf18844362881750df5cebd045d672c43Leon Scroggins III * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly
39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * For conditions of distribution and use, see copyright notice in zlib.h
49e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*
79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * minigzip is a minimal implementation of the gzip utility. This is
89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * only an example of using zlib and isn't meant to replace the
99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * full-featured gzip. No attempt is made to deal with file systems
109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * limiting names to 14 or 8+3 characters, etc... Error checking is
119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * very limited. So use minigzip only for testing; use gzip for the
129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * real thing. On MSDOS, use only on file names without extension
139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * or in pipe mode.
149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* @(#) $Id$ */
179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zlib.h"
19381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#include <stdio.h>
209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef STDC
229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <string.h>
239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <stdlib.h>
249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef USE_MMAP
279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <sys/types.h>
289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <sys/mman.h>
299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <sys/stat.h>
309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <fcntl.h>
349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <io.h>
35381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  ifdef UNDER_CE
36381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#    include <stdlib.h>
37381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  endif
389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else
409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define SET_BINARY_MODE(file)
419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
437291b8caf18844362881750df5cebd045d672c43Leon Scroggins III#if defined(_MSC_VER) && _MSC_VER < 1900
4404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#  define snprintf _snprintf
4504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#endif
4604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes
479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef VMS
489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define unlink delete
499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define GZ_SUFFIX "-gz"
509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef RISCOS
529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define unlink remove
539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define GZ_SUFFIX "-gz"
549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define fileno(file) file->__file
559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <unix.h> /* for fileno */
589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
60381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  extern int unlink OF((const char *));
639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
64381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
65381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
66381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#if defined(UNDER_CE)
67381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  include <windows.h>
68381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  define perror(s) pwinerror(s)
69381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
70381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Map the Windows error number in ERROR to a locale-dependent error
71381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   message string and return a pointer to it.  Typically, the values
72381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   for ERROR come from GetLastError.
73381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
74381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   The string pointed to shall not be modified by the application,
75381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   but may be overwritten by a subsequent call to strwinerror
76381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
77381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   The strwinerror function does not change the current setting
78381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   of GetLastError.  */
79381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
80381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesstatic char *strwinerror (error)
81381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes     DWORD error;
82381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
83381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    static char buf[1024];
84381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
85381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    wchar_t *msgbuf;
86381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    DWORD lasterr = GetLastError();
87381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
88381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
89381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        NULL,
90381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        error,
91381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        0, /* Default language */
92381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        (LPVOID)&msgbuf,
93381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        0,
94381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        NULL);
95381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (chars != 0) {
96381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /* If there is an \r\n appended, zap it.  */
97381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (chars >= 2
98381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
99381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            chars -= 2;
100381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            msgbuf[chars] = 0;
101381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
102381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
103381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (chars > sizeof (buf) - 1) {
104381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            chars = sizeof (buf) - 1;
105381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            msgbuf[chars] = 0;
106381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
107381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
108381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        wcstombs(buf, msgbuf, chars + 1);
109381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        LocalFree(msgbuf);
110381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
111381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else {
112381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        sprintf(buf, "unknown win32 error (%ld)", error);
113381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
114381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
115381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    SetLastError(lasterr);
116381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return buf;
117381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
118381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
119381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesstatic void pwinerror (s)
120381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    const char *s;
121381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
122381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (s && *s)
123381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
124381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
125381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
126381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
127381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
128381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif /* UNDER_CE */
1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef GZ_SUFFIX
1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define GZ_SUFFIX ".gz"
1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define BUFLEN      16384
1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define MAX_NAME_LEN 1024
1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAXSEG_64K
1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define local static
1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project   /* Needed for systems with limitation on stack size. */
1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else
1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define local
1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
145ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#ifdef Z_SOLO
146ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
147ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
148ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
149ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#  include <unistd.h>       /* for unlink() */
150ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#endif
151ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
152ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesvoid *myalloc OF((void *, unsigned, unsigned));
153ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesvoid myfree OF((void *, void *));
154ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
155ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesvoid *myalloc(q, n, m)
156ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    void *q;
157ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned n, m;
158ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
1597291b8caf18844362881750df5cebd045d672c43Leon Scroggins III    (void)q;
160ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return calloc(n, m);
161ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
162ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
163ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesvoid myfree(q, p)
164ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    void *q, *p;
165ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
1667291b8caf18844362881750df5cebd045d672c43Leon Scroggins III    (void)q;
167ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    free(p);
168ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
169ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
170ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughestypedef struct gzFile_s {
171ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    FILE *file;
172ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int write;
173ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int err;
174ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    char *msg;
175ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    z_stream strm;
176ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes} *gzFile;
177ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
178ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gzopen OF((const char *, const char *));
179ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gzdopen OF((int, const char *));
180ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gz_open OF((const char *, int, const char *));
181ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
182ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gzopen(path, mode)
183ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesconst char *path;
184ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesconst char *mode;
185ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
186ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return gz_open(path, -1, mode);
187ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
188ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
189ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gzdopen(fd, mode)
190ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint fd;
191ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesconst char *mode;
192ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
193ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return gz_open(NULL, fd, mode);
194ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
195ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
196ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gz_open(path, fd, mode)
197ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    const char *path;
198ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int fd;
199ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    const char *mode;
200ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
201ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gzFile gz;
202ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int ret;
203ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
20409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    gz = malloc(sizeof(struct gzFile_s));
205ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz == NULL)
206ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return NULL;
207ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->write = strchr(mode, 'w') != NULL;
208ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->strm.zalloc = myalloc;
209ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->strm.zfree = myfree;
210ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->strm.opaque = Z_NULL;
211ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz->write)
212ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
213ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    else {
214ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        gz->strm.next_in = 0;
215ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        gz->strm.avail_in = Z_NULL;
216ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        ret = inflateInit2(&(gz->strm), 15 + 16);
217ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
218ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (ret != Z_OK) {
219ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        free(gz);
220ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return NULL;
221ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
222ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
223ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes                              fopen(path, gz->write ? "wb" : "rb");
224ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz->file == NULL) {
225ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
226ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        free(gz);
227ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return NULL;
228ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
229ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->err = 0;
230ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->msg = "";
231ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return gz;
232ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
233ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
234ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzwrite OF((gzFile, const void *, unsigned));
235ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
236ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzwrite(gz, buf, len)
237ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gzFile gz;
238ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    const void *buf;
239ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned len;
240ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
241ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    z_stream *strm;
242ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned char out[BUFLEN];
243ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
244ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz == NULL || !gz->write)
245ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return 0;
246ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm = &(gz->strm);
247ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm->next_in = (void *)buf;
248ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm->avail_in = len;
249ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    do {
250ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->next_out = out;
251ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->avail_out = BUFLEN;
252ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        (void)deflate(strm, Z_NO_FLUSH);
253ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
254ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    } while (strm->avail_out == 0);
255ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return len;
256ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
257ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
258ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzread OF((gzFile, void *, unsigned));
259ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
260ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzread(gz, buf, len)
261ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gzFile gz;
262ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    void *buf;
263ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned len;
264ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
265ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int ret;
266ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned got;
267ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned char in[1];
268ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    z_stream *strm;
269ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
270ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz == NULL || gz->write)
271ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return 0;
272ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz->err)
273ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return 0;
274ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm = &(gz->strm);
275ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm->next_out = (void *)buf;
276ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm->avail_out = len;
277ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    do {
278ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        got = fread(in, 1, 1, gz->file);
279ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if (got == 0)
280ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            break;
281ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->next_in = in;
282ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->avail_in = 1;
283ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        ret = inflate(strm, Z_NO_FLUSH);
284ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if (ret == Z_DATA_ERROR) {
285ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            gz->err = Z_DATA_ERROR;
286ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            gz->msg = strm->msg;
287ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            return 0;
288ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        }
289ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if (ret == Z_STREAM_END)
290ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            inflateReset(strm);
291ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    } while (strm->avail_out);
292ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return len - strm->avail_out;
293ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
294ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
295ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzclose OF((gzFile));
296ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
297ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzclose(gz)
298ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gzFile gz;
299ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
300ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    z_stream *strm;
301ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned char out[BUFLEN];
302ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
303ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz == NULL)
304ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return Z_STREAM_ERROR;
305ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm = &(gz->strm);
306ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz->write) {
307ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->next_in = Z_NULL;
308ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->avail_in = 0;
309ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        do {
310ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            strm->next_out = out;
311ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            strm->avail_out = BUFLEN;
312ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            (void)deflate(strm, Z_FINISH);
313ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
314ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        } while (strm->avail_out == 0);
315ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        deflateEnd(strm);
316ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
317ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    else
318ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        inflateEnd(strm);
319ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    fclose(gz->file);
320ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    free(gz);
321ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return Z_OK;
322ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
323ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
324ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesconst char *gzerror OF((gzFile, int *));
325ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
326ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesconst char *gzerror(gz, err)
327ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gzFile gz;
328ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int *err;
329ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
330ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    *err = gz->err;
331ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return gz->msg;
332ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
333ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
334ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#endif
335ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
3367291b8caf18844362881750df5cebd045d672c43Leon Scroggins IIIstatic char *prog;
3379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid error            OF((const char *msg));
3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid gz_compress      OF((FILE   *in, gzFile out));
3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef USE_MMAP
3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint  gz_compress_mmap OF((FILE   *in, gzFile out));
3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid gz_uncompress    OF((gzFile in, FILE   *out));
3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid file_compress    OF((char  *file, char *mode));
3459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid file_uncompress  OF((char  *file));
3469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint  main             OF((int argc, char *argv[]));
3479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
3499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Display error message and exit
3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid error(msg)
3529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    const char *msg;
3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    fprintf(stderr, "%s: %s\n", prog, msg);
3559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    exit(1);
3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Compress input to output then close both files.
3609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
3619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid gz_compress(in, out)
3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE   *in;
3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile out;
3659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    local char buf[BUFLEN];
3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int len;
3689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err;
3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef USE_MMAP
3719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* Try first compressing with mmap. If mmap fails (minigzip used in a
3729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project     * pipe), use the normal fread loop.
3739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project     */
3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (gz_compress_mmap(in, out) == Z_OK) return;
3759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
3769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (;;) {
3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len = (int)fread(buf, 1, sizeof(buf), in);
3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (ferror(in)) {
3799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            perror("fread");
3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            exit(1);
3819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
3829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (len == 0) break;
3839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
3859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    fclose(in);
3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (gzclose(out) != Z_OK) error("failed gzclose");
3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
3919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Try compressing the input file at once using mmap. Return Z_OK if
3939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * if success, Z_ERRNO otherwise.
3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
3959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint gz_compress_mmap(in, out)
3969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE   *in;
3979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile out;
3989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int len;
4009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err;
4019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int ifd = fileno(in);
4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    caddr_t buf;    /* mmap'ed buffer for the entire input file */
4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    off_t buf_len;  /* length of the input file */
4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    struct stat sb;
4059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* Determine the size of the file, needed for mmap: */
4079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
4089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buf_len = sb.st_size;
4099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (buf_len <= 0) return Z_ERRNO;
4109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* Now do the actual mmap: */
4129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
4139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (buf == (caddr_t)(-1)) return Z_ERRNO;
4149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* Compress the whole file at once: */
4169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
4179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (len != (int)buf_len) error(gzerror(out, &err));
4199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    munmap(buf, buf_len);
4219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    fclose(in);
4229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (gzclose(out) != Z_OK) error("failed gzclose");
4239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return Z_OK;
4249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* USE_MMAP */
4269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
4289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Uncompress input to output then close both files.
4299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
4309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid gz_uncompress(in, out)
4319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile in;
4329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE   *out;
4339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    local char buf[BUFLEN];
4359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int len;
4369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err;
4379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (;;) {
4399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len = gzread(in, buf, sizeof(buf));
4409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (len < 0) error (gzerror(in, &err));
4419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (len == 0) break;
4429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
4449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            error("failed fwrite");
4459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
4469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
4479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (fclose(out)) error("failed fclose");
4489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (gzclose(in) != Z_OK) error("failed gzclose");
4509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
4549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Compress the given file: create a corresponding .gz file and remove the
4559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * original.
4569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
4579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid file_compress(file, mode)
4589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char  *file;
4599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char  *mode;
4609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    local char outfile[MAX_NAME_LEN];
4629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE  *in;
4639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile out;
4649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
465381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
466381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        fprintf(stderr, "%s: filename too long\n", prog);
467381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        exit(1);
468381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
469381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
47004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
47104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes    snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
47204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#else
4739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcpy(outfile, file);
4749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcat(outfile, GZ_SUFFIX);
47504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#endif
4769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    in = fopen(file, "rb");
4789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (in == NULL) {
4799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        perror(file);
4809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        exit(1);
4819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
4829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    out = gzopen(outfile, mode);
4839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (out == NULL) {
4849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
4859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        exit(1);
4869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
4879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gz_compress(in, out);
4889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unlink(file);
4909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
4949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Uncompress the given file and remove the original.
4959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
4969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid file_uncompress(file)
4979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char  *file;
4989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    local char buf[MAX_NAME_LEN];
5009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char *infile, *outfile;
5019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE  *out;
5029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile in;
5037291b8caf18844362881750df5cebd045d672c43Leon Scroggins III    unsigned len = strlen(file);
504381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
505381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
506381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        fprintf(stderr, "%s: filename too long\n", prog);
507381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        exit(1);
508381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
5099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
51004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
51104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes    snprintf(buf, sizeof(buf), "%s", file);
51204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#else
5139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcpy(buf, file);
51404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#endif
5159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
5179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        infile = file;
5189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outfile = buf;
5199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outfile[len-3] = '\0';
5209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    } else {
5219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outfile = file;
5229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        infile = buf;
52304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
52404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes        snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
52504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#else
5269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        strcat(infile, GZ_SUFFIX);
52704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#endif
5289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
5299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    in = gzopen(infile, "rb");
5309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (in == NULL) {
5319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
5329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        exit(1);
5339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
5349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    out = fopen(outfile, "wb");
5359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (out == NULL) {
5369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        perror(file);
5379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        exit(1);
5389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
5399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gz_uncompress(in, out);
5419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unlink(infile);
5439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
5449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
547381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
548381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes *   -c : write to standard output
5499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *   -d : decompress
5509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *   -f : compress with Z_FILTERED
5519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *   -h : compress with Z_HUFFMAN_ONLY
5529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *   -r : compress with Z_RLE
5539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *   -1 to -9 : compression level
5549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
5559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint main(argc, argv)
5579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int argc;
5589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char *argv[];
5599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
560381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int copyout = 0;
5619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int uncompr = 0;
5629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile file;
563381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    char *bname, outmode[20];
5649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
56504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
56604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes    snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
56704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#else
5689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcpy(outmode, "wb6 ");
56904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#endif
5709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    prog = argv[0];
572381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    bname = strrchr(argv[0], '/');
573381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (bname)
574381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      bname++;
575381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
576381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      bname = argv[0];
5779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    argc--, argv++;
5789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
579381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (!strcmp(bname, "gunzip"))
580381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      uncompr = 1;
581381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else if (!strcmp(bname, "zcat"))
582381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      copyout = uncompr = 1;
583381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
5849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (argc > 0) {
585381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if (strcmp(*argv, "-c") == 0)
586381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        copyout = 1;
587381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      else if (strcmp(*argv, "-d") == 0)
5889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        uncompr = 1;
5899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else if (strcmp(*argv, "-f") == 0)
5909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outmode[3] = 'f';
5919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else if (strcmp(*argv, "-h") == 0)
5929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outmode[3] = 'h';
5939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else if (strcmp(*argv, "-r") == 0)
5949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outmode[3] = 'R';
5959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
5969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project               (*argv)[2] == 0)
5979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outmode[2] = (*argv)[1];
5989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else
5999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        break;
6009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      argc--, argv++;
6019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
6029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (outmode[3] == ' ')
6039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outmode[3] = 0;
6049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (argc == 0) {
6059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        SET_BINARY_MODE(stdin);
6069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        SET_BINARY_MODE(stdout);
6079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (uncompr) {
6089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            file = gzdopen(fileno(stdin), "rb");
6099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (file == NULL) error("can't gzdopen stdin");
6109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            gz_uncompress(file, stdout);
6119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        } else {
6129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            file = gzdopen(fileno(stdout), outmode);
6139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (file == NULL) error("can't gzdopen stdout");
6149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            gz_compress(stdin, file);
6159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
6169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    } else {
617381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (copyout) {
618381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            SET_BINARY_MODE(stdout);
619381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
6209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        do {
6219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (uncompr) {
622381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                if (copyout) {
623381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    file = gzopen(*argv, "rb");
624381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    if (file == NULL)
625381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
626381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    else
627381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        gz_uncompress(file, stdout);
628381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                } else {
629381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    file_uncompress(*argv);
630381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                }
6319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            } else {
632381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                if (copyout) {
633381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    FILE * in = fopen(*argv, "rb");
634381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
635381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    if (in == NULL) {
636381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        perror(*argv);
637381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    } else {
638381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        file = gzdopen(fileno(stdout), outmode);
639381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        if (file == NULL) error("can't gzdopen stdout");
640381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
641381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        gz_compress(in, file);
642381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    }
643381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
644381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                } else {
645381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    file_compress(*argv, outmode);
646381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                }
6479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
6489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        } while (argv++, --argc);
6499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
6509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return 0;
6519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
652