19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* minigzip.c -- simulate gzip using the zlib compression library
2ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes * Copyright (C) 1995-2006, 2010, 2011 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
439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef VMS
449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define unlink delete
459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define GZ_SUFFIX "-gz"
469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef RISCOS
489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define unlink remove
499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define GZ_SUFFIX "-gz"
509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define fileno(file) file->__file
519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <unix.h> /* for fileno */
549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
56381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  extern int unlink OF((const char *));
599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
60381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
61381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
62381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#if defined(UNDER_CE)
63381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  include <windows.h>
64381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  define perror(s) pwinerror(s)
65381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
66381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Map the Windows error number in ERROR to a locale-dependent error
67381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   message string and return a pointer to it.  Typically, the values
68381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   for ERROR come from GetLastError.
69381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
70381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   The string pointed to shall not be modified by the application,
71381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   but may be overwritten by a subsequent call to strwinerror
72381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
73381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   The strwinerror function does not change the current setting
74381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   of GetLastError.  */
75381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
76381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesstatic char *strwinerror (error)
77381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes     DWORD error;
78381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
79381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    static char buf[1024];
80381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
81381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    wchar_t *msgbuf;
82381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    DWORD lasterr = GetLastError();
83381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
84381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
85381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        NULL,
86381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        error,
87381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        0, /* Default language */
88381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        (LPVOID)&msgbuf,
89381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        0,
90381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        NULL);
91381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (chars != 0) {
92381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /* If there is an \r\n appended, zap it.  */
93381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (chars >= 2
94381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
95381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            chars -= 2;
96381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            msgbuf[chars] = 0;
97381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
98381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
99381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (chars > sizeof (buf) - 1) {
100381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            chars = sizeof (buf) - 1;
101381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            msgbuf[chars] = 0;
102381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
103381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
104381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        wcstombs(buf, msgbuf, chars + 1);
105381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        LocalFree(msgbuf);
106381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
107381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else {
108381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        sprintf(buf, "unknown win32 error (%ld)", error);
109381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
110381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
111381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    SetLastError(lasterr);
112381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return buf;
113381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
114381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
115381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesstatic void pwinerror (s)
116381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    const char *s;
117381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
118381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (s && *s)
119381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
120381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
121381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
122381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
123381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
124381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif /* UNDER_CE */
1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef GZ_SUFFIX
1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define GZ_SUFFIX ".gz"
1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define BUFLEN      16384
1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define MAX_NAME_LEN 1024
1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAXSEG_64K
1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define local static
1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project   /* Needed for systems with limitation on stack size. */
1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else
1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define local
1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
141ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#ifdef Z_SOLO
142ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
143ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
144ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
145ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#  include <unistd.h>       /* for unlink() */
146ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#endif
147ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
148ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesvoid *myalloc OF((void *, unsigned, unsigned));
149ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesvoid myfree OF((void *, void *));
150ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
151ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesvoid *myalloc(q, n, m)
152ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    void *q;
153ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned n, m;
154ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
155ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    q = Z_NULL;
156ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return calloc(n, m);
157ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
158ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
159ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesvoid myfree(q, p)
160ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    void *q, *p;
161ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
162ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    q = Z_NULL;
163ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    free(p);
164ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
165ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
166ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughestypedef struct gzFile_s {
167ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    FILE *file;
168ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int write;
169ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int err;
170ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    char *msg;
171ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    z_stream strm;
172ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes} *gzFile;
173ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
174ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gzopen OF((const char *, const char *));
175ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gzdopen OF((int, const char *));
176ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gz_open OF((const char *, int, const char *));
177ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
178ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gzopen(path, mode)
179ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesconst char *path;
180ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesconst char *mode;
181ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
182ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return gz_open(path, -1, mode);
183ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
184ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
185ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gzdopen(fd, mode)
186ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint fd;
187ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesconst char *mode;
188ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
189ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return gz_open(NULL, fd, mode);
190ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
191ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
192ee9e11d0d4e3361533860bf04896abb86a291bfbElliott HughesgzFile gz_open(path, fd, mode)
193ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    const char *path;
194ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int fd;
195ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    const char *mode;
196ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
197ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gzFile gz;
198ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int ret;
199ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
20009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    gz = malloc(sizeof(struct gzFile_s));
201ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz == NULL)
202ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return NULL;
203ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->write = strchr(mode, 'w') != NULL;
204ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->strm.zalloc = myalloc;
205ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->strm.zfree = myfree;
206ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->strm.opaque = Z_NULL;
207ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz->write)
208ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
209ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    else {
210ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        gz->strm.next_in = 0;
211ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        gz->strm.avail_in = Z_NULL;
212ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        ret = inflateInit2(&(gz->strm), 15 + 16);
213ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
214ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (ret != Z_OK) {
215ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        free(gz);
216ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return NULL;
217ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
218ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
219ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes                              fopen(path, gz->write ? "wb" : "rb");
220ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz->file == NULL) {
221ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
222ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        free(gz);
223ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return NULL;
224ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
225ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->err = 0;
226ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gz->msg = "";
227ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return gz;
228ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
229ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
230ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzwrite OF((gzFile, const void *, unsigned));
231ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
232ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzwrite(gz, buf, len)
233ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gzFile gz;
234ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    const void *buf;
235ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned len;
236ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
237ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    z_stream *strm;
238ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned char out[BUFLEN];
239ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
240ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz == NULL || !gz->write)
241ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return 0;
242ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm = &(gz->strm);
243ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm->next_in = (void *)buf;
244ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm->avail_in = len;
245ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    do {
246ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->next_out = out;
247ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->avail_out = BUFLEN;
248ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        (void)deflate(strm, Z_NO_FLUSH);
249ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
250ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    } while (strm->avail_out == 0);
251ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return len;
252ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
253ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
254ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzread OF((gzFile, void *, unsigned));
255ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
256ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzread(gz, buf, len)
257ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gzFile gz;
258ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    void *buf;
259ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned len;
260ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
261ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int ret;
262ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned got;
263ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned char in[1];
264ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    z_stream *strm;
265ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
266ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz == NULL || gz->write)
267ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return 0;
268ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz->err)
269ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return 0;
270ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm = &(gz->strm);
271ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm->next_out = (void *)buf;
272ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm->avail_out = len;
273ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    do {
274ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        got = fread(in, 1, 1, gz->file);
275ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if (got == 0)
276ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            break;
277ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->next_in = in;
278ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->avail_in = 1;
279ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        ret = inflate(strm, Z_NO_FLUSH);
280ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if (ret == Z_DATA_ERROR) {
281ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            gz->err = Z_DATA_ERROR;
282ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            gz->msg = strm->msg;
283ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            return 0;
284ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        }
285ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if (ret == Z_STREAM_END)
286ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            inflateReset(strm);
287ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    } while (strm->avail_out);
288ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return len - strm->avail_out;
289ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
290ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
291ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzclose OF((gzFile));
292ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
293ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint gzclose(gz)
294ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gzFile gz;
295ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
296ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    z_stream *strm;
297ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    unsigned char out[BUFLEN];
298ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
299ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz == NULL)
300ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return Z_STREAM_ERROR;
301ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    strm = &(gz->strm);
302ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (gz->write) {
303ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->next_in = Z_NULL;
304ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->avail_in = 0;
305ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        do {
306ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            strm->next_out = out;
307ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            strm->avail_out = BUFLEN;
308ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            (void)deflate(strm, Z_FINISH);
309ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
310ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        } while (strm->avail_out == 0);
311ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        deflateEnd(strm);
312ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
313ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    else
314ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        inflateEnd(strm);
315ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    fclose(gz->file);
316ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    free(gz);
317ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return Z_OK;
318ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
319ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
320ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesconst char *gzerror OF((gzFile, int *));
321ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
322ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesconst char *gzerror(gz, err)
323ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    gzFile gz;
324ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int *err;
325ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{
326ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    *err = gz->err;
327ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return gz->msg;
328ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
329ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
330ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#endif
331ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
3329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectchar *prog;
3339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid error            OF((const char *msg));
3359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid gz_compress      OF((FILE   *in, gzFile out));
3369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef USE_MMAP
3379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint  gz_compress_mmap OF((FILE   *in, gzFile out));
3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid gz_uncompress    OF((gzFile in, FILE   *out));
3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid file_compress    OF((char  *file, char *mode));
3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid file_uncompress  OF((char  *file));
3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint  main             OF((int argc, char *argv[]));
3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
3459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Display error message and exit
3469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
3479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid error(msg)
3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    const char *msg;
3499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    fprintf(stderr, "%s: %s\n", prog, msg);
3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    exit(1);
3529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
3559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Compress input to output then close both files.
3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid gz_compress(in, out)
3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE   *in;
3609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile out;
3619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    local char buf[BUFLEN];
3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int len;
3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err;
3659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef USE_MMAP
3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* Try first compressing with mmap. If mmap fails (minigzip used in a
3689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project     * pipe), use the normal fread loop.
3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project     */
3709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (gz_compress_mmap(in, out) == Z_OK) return;
3719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
3729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (;;) {
3739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len = (int)fread(buf, 1, sizeof(buf), in);
3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (ferror(in)) {
3759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            perror("fread");
3769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            exit(1);
3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (len == 0) break;
3799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
3819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    fclose(in);
3839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (gzclose(out) != Z_OK) error("failed gzclose");
3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Try compressing the input file at once using mmap. Return Z_OK if
3899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * if success, Z_ERRNO otherwise.
3909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
3919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint gz_compress_mmap(in, out)
3929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE   *in;
3939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile out;
3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int len;
3969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err;
3979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int ifd = fileno(in);
3989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    caddr_t buf;    /* mmap'ed buffer for the entire input file */
3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    off_t buf_len;  /* length of the input file */
4009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    struct stat sb;
4019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* Determine the size of the file, needed for mmap: */
4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buf_len = sb.st_size;
4059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (buf_len <= 0) return Z_ERRNO;
4069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* Now do the actual mmap: */
4089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
4099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (buf == (caddr_t)(-1)) return Z_ERRNO;
4109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* Compress the whole file at once: */
4129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
4139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (len != (int)buf_len) error(gzerror(out, &err));
4159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    munmap(buf, buf_len);
4179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    fclose(in);
4189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (gzclose(out) != Z_OK) error("failed gzclose");
4199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return Z_OK;
4209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* USE_MMAP */
4229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
4249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Uncompress input to output then close both files.
4259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
4269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid gz_uncompress(in, out)
4279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile in;
4289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE   *out;
4299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    local char buf[BUFLEN];
4319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int len;
4329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err;
4339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (;;) {
4359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len = gzread(in, buf, sizeof(buf));
4369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (len < 0) error (gzerror(in, &err));
4379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (len == 0) break;
4389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
4409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            error("failed fwrite");
4419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
4429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
4439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (fclose(out)) error("failed fclose");
4449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (gzclose(in) != Z_OK) error("failed gzclose");
4469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
4509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Compress the given file: create a corresponding .gz file and remove the
4519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * original.
4529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
4539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid file_compress(file, mode)
4549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char  *file;
4559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char  *mode;
4569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    local char outfile[MAX_NAME_LEN];
4589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE  *in;
4599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile out;
4609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
461381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
462381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        fprintf(stderr, "%s: filename too long\n", prog);
463381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        exit(1);
464381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
465381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
4669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcpy(outfile, file);
4679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcat(outfile, GZ_SUFFIX);
4689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    in = fopen(file, "rb");
4709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (in == NULL) {
4719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        perror(file);
4729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        exit(1);
4739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
4749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    out = gzopen(outfile, mode);
4759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (out == NULL) {
4769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
4779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        exit(1);
4789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
4799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gz_compress(in, out);
4809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unlink(file);
4829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
4869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Uncompress the given file and remove the original.
4879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
4889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid file_uncompress(file)
4899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char  *file;
4909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    local char buf[MAX_NAME_LEN];
4929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char *infile, *outfile;
4939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    FILE  *out;
4949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile in;
495381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    size_t len = strlen(file);
496381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
497381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
498381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        fprintf(stderr, "%s: filename too long\n", prog);
499381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        exit(1);
500381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
5019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcpy(buf, file);
5039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
5059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        infile = file;
5069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outfile = buf;
5079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outfile[len-3] = '\0';
5089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    } else {
5099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outfile = file;
5109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        infile = buf;
5119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        strcat(infile, GZ_SUFFIX);
5129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
5139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    in = gzopen(infile, "rb");
5149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (in == NULL) {
5159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
5169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        exit(1);
5179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
5189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    out = fopen(outfile, "wb");
5199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (out == NULL) {
5209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        perror(file);
5219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        exit(1);
5229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
5239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gz_uncompress(in, out);
5259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unlink(infile);
5279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
5289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
531381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
532381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes *   -c : write to standard output
5339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *   -d : decompress
5349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *   -f : compress with Z_FILTERED
5359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *   -h : compress with Z_HUFFMAN_ONLY
5369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *   -r : compress with Z_RLE
5379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *   -1 to -9 : compression level
5389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
5399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint main(argc, argv)
5419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int argc;
5429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char *argv[];
5439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
544381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int copyout = 0;
5459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int uncompr = 0;
5469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile file;
547381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    char *bname, outmode[20];
5489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcpy(outmode, "wb6 ");
5509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    prog = argv[0];
552381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    bname = strrchr(argv[0], '/');
553381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (bname)
554381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      bname++;
555381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
556381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      bname = argv[0];
5579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    argc--, argv++;
5589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
559381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (!strcmp(bname, "gunzip"))
560381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      uncompr = 1;
561381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else if (!strcmp(bname, "zcat"))
562381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      copyout = uncompr = 1;
563381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
5649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (argc > 0) {
565381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if (strcmp(*argv, "-c") == 0)
566381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        copyout = 1;
567381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      else if (strcmp(*argv, "-d") == 0)
5689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        uncompr = 1;
5699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else if (strcmp(*argv, "-f") == 0)
5709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outmode[3] = 'f';
5719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else if (strcmp(*argv, "-h") == 0)
5729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outmode[3] = 'h';
5739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else if (strcmp(*argv, "-r") == 0)
5749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outmode[3] = 'R';
5759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
5769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project               (*argv)[2] == 0)
5779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outmode[2] = (*argv)[1];
5789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else
5799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        break;
5809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      argc--, argv++;
5819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
5829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (outmode[3] == ' ')
5839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        outmode[3] = 0;
5849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (argc == 0) {
5859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        SET_BINARY_MODE(stdin);
5869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        SET_BINARY_MODE(stdout);
5879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (uncompr) {
5889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            file = gzdopen(fileno(stdin), "rb");
5899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (file == NULL) error("can't gzdopen stdin");
5909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            gz_uncompress(file, stdout);
5919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        } else {
5929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            file = gzdopen(fileno(stdout), outmode);
5939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (file == NULL) error("can't gzdopen stdout");
5949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            gz_compress(stdin, file);
5959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
5969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    } else {
597381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (copyout) {
598381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            SET_BINARY_MODE(stdout);
599381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
6009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        do {
6019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (uncompr) {
602381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                if (copyout) {
603381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    file = gzopen(*argv, "rb");
604381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    if (file == NULL)
605381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
606381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    else
607381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        gz_uncompress(file, stdout);
608381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                } else {
609381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    file_uncompress(*argv);
610381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                }
6119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            } else {
612381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                if (copyout) {
613381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    FILE * in = fopen(*argv, "rb");
614381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
615381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    if (in == NULL) {
616381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        perror(*argv);
617381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    } else {
618381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        file = gzdopen(fileno(stdout), outmode);
619381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        if (file == NULL) error("can't gzdopen stdout");
620381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
621381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        gz_compress(in, file);
622381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    }
623381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
624381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                } else {
625381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    file_compress(*argv, outmode);
626381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                }
6279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
6289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        } while (argv++, --argc);
6299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
6309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return 0;
6319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
632