xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/jffs2/cyg/compress/src/minigzip.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /* minigzip.c -- simulate gzip using the zlib compression library
2*10465441SEvalZero  * Copyright (C) 1995-2005 Jean-loup Gailly.
3*10465441SEvalZero  * For conditions of distribution and use, see copyright notice in zlib.h
4*10465441SEvalZero  */
5*10465441SEvalZero 
6*10465441SEvalZero /*
7*10465441SEvalZero  * minigzip is a minimal implementation of the gzip utility. This is
8*10465441SEvalZero  * only an example of using zlib and isn't meant to replace the
9*10465441SEvalZero  * full-featured gzip. No attempt is made to deal with file systems
10*10465441SEvalZero  * limiting names to 14 or 8+3 characters, etc... Error checking is
11*10465441SEvalZero  * very limited. So use minigzip only for testing; use gzip for the
12*10465441SEvalZero  * real thing. On MSDOS, use only on file names without extension
13*10465441SEvalZero  * or in pipe mode.
14*10465441SEvalZero  */
15*10465441SEvalZero 
16*10465441SEvalZero /* @(#) $Id$ */
17*10465441SEvalZero 
18*10465441SEvalZero #include <stdio.h>
19*10465441SEvalZero #include "zlib.h"
20*10465441SEvalZero 
21*10465441SEvalZero #ifdef STDC
22*10465441SEvalZero #  include <string.h>
23*10465441SEvalZero #  include <stdlib.h>
24*10465441SEvalZero #endif
25*10465441SEvalZero 
26*10465441SEvalZero #ifdef USE_MMAP
27*10465441SEvalZero #  include <sys/types.h>
28*10465441SEvalZero #  include <sys/mman.h>
29*10465441SEvalZero #  include <sys/stat.h>
30*10465441SEvalZero #endif
31*10465441SEvalZero 
32*10465441SEvalZero #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
33*10465441SEvalZero #  include <fcntl.h>
34*10465441SEvalZero #  include <io.h>
35*10465441SEvalZero #  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
36*10465441SEvalZero #else
37*10465441SEvalZero #  define SET_BINARY_MODE(file)
38*10465441SEvalZero #endif
39*10465441SEvalZero 
40*10465441SEvalZero #ifdef VMS
41*10465441SEvalZero #  define unlink delete
42*10465441SEvalZero #  define GZ_SUFFIX "-gz"
43*10465441SEvalZero #endif
44*10465441SEvalZero #ifdef RISCOS
45*10465441SEvalZero #  define unlink remove
46*10465441SEvalZero #  define GZ_SUFFIX "-gz"
47*10465441SEvalZero #  define fileno(file) file->__file
48*10465441SEvalZero #endif
49*10465441SEvalZero #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
50*10465441SEvalZero #  include <unix.h> /* for fileno */
51*10465441SEvalZero #endif
52*10465441SEvalZero 
53*10465441SEvalZero #ifndef WIN32 /* unlink already in stdio.h for WIN32 */
54*10465441SEvalZero   extern int unlink OF((const char *));
55*10465441SEvalZero #endif
56*10465441SEvalZero 
57*10465441SEvalZero #ifndef GZ_SUFFIX
58*10465441SEvalZero #  define GZ_SUFFIX ".gz"
59*10465441SEvalZero #endif
60*10465441SEvalZero #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
61*10465441SEvalZero 
62*10465441SEvalZero #define BUFLEN      16384
63*10465441SEvalZero #define MAX_NAME_LEN 1024
64*10465441SEvalZero 
65*10465441SEvalZero #ifdef MAXSEG_64K
66*10465441SEvalZero #  define local static
67*10465441SEvalZero    /* Needed for systems with limitation on stack size. */
68*10465441SEvalZero #else
69*10465441SEvalZero #  define local
70*10465441SEvalZero #endif
71*10465441SEvalZero 
72*10465441SEvalZero char *prog;
73*10465441SEvalZero 
74*10465441SEvalZero void error            OF((const char *msg));
75*10465441SEvalZero void gz_compress      OF((FILE   *in, gzFile out));
76*10465441SEvalZero #ifdef USE_MMAP
77*10465441SEvalZero int  gz_compress_mmap OF((FILE   *in, gzFile out));
78*10465441SEvalZero #endif
79*10465441SEvalZero void gz_uncompress    OF((gzFile in, FILE   *out));
80*10465441SEvalZero void file_compress    OF((char  *file, char *mode));
81*10465441SEvalZero void file_uncompress  OF((char  *file));
82*10465441SEvalZero int  main             OF((int argc, char *argv[]));
83*10465441SEvalZero 
84*10465441SEvalZero /* ===========================================================================
85*10465441SEvalZero  * Display error message and exit
86*10465441SEvalZero  */
error(msg)87*10465441SEvalZero void error(msg)
88*10465441SEvalZero     const char *msg;
89*10465441SEvalZero {
90*10465441SEvalZero     fprintf(stderr, "%s: %s\n", prog, msg);
91*10465441SEvalZero     exit(1);
92*10465441SEvalZero }
93*10465441SEvalZero 
94*10465441SEvalZero /* ===========================================================================
95*10465441SEvalZero  * Compress input to output then close both files.
96*10465441SEvalZero  */
97*10465441SEvalZero 
gz_compress(in,out)98*10465441SEvalZero void gz_compress(in, out)
99*10465441SEvalZero     FILE   *in;
100*10465441SEvalZero     gzFile out;
101*10465441SEvalZero {
102*10465441SEvalZero     local char buf[BUFLEN];
103*10465441SEvalZero     int len;
104*10465441SEvalZero     int err;
105*10465441SEvalZero 
106*10465441SEvalZero #ifdef USE_MMAP
107*10465441SEvalZero     /* Try first compressing with mmap. If mmap fails (minigzip used in a
108*10465441SEvalZero      * pipe), use the normal fread loop.
109*10465441SEvalZero      */
110*10465441SEvalZero     if (gz_compress_mmap(in, out) == Z_OK) return;
111*10465441SEvalZero #endif
112*10465441SEvalZero     for (;;) {
113*10465441SEvalZero         len = (int)fread(buf, 1, sizeof(buf), in);
114*10465441SEvalZero         if (ferror(in)) {
115*10465441SEvalZero             perror("fread");
116*10465441SEvalZero             exit(1);
117*10465441SEvalZero         }
118*10465441SEvalZero         if (len == 0) break;
119*10465441SEvalZero 
120*10465441SEvalZero         if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
121*10465441SEvalZero     }
122*10465441SEvalZero     fclose(in);
123*10465441SEvalZero     if (gzclose(out) != Z_OK) error("failed gzclose");
124*10465441SEvalZero }
125*10465441SEvalZero 
126*10465441SEvalZero #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <[email protected]> */
127*10465441SEvalZero 
128*10465441SEvalZero /* Try compressing the input file at once using mmap. Return Z_OK if
129*10465441SEvalZero  * if success, Z_ERRNO otherwise.
130*10465441SEvalZero  */
gz_compress_mmap(in,out)131*10465441SEvalZero int gz_compress_mmap(in, out)
132*10465441SEvalZero     FILE   *in;
133*10465441SEvalZero     gzFile out;
134*10465441SEvalZero {
135*10465441SEvalZero     int len;
136*10465441SEvalZero     int err;
137*10465441SEvalZero     int ifd = fileno(in);
138*10465441SEvalZero     caddr_t buf;    /* mmap'ed buffer for the entire input file */
139*10465441SEvalZero     off_t buf_len;  /* length of the input file */
140*10465441SEvalZero     struct stat sb;
141*10465441SEvalZero 
142*10465441SEvalZero     /* Determine the size of the file, needed for mmap: */
143*10465441SEvalZero     if (fstat(ifd, &sb) < 0) return Z_ERRNO;
144*10465441SEvalZero     buf_len = sb.st_size;
145*10465441SEvalZero     if (buf_len <= 0) return Z_ERRNO;
146*10465441SEvalZero 
147*10465441SEvalZero     /* Now do the actual mmap: */
148*10465441SEvalZero     buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
149*10465441SEvalZero     if (buf == (caddr_t)(-1)) return Z_ERRNO;
150*10465441SEvalZero 
151*10465441SEvalZero     /* Compress the whole file at once: */
152*10465441SEvalZero     len = gzwrite(out, (char *)buf, (unsigned)buf_len);
153*10465441SEvalZero 
154*10465441SEvalZero     if (len != (int)buf_len) error(gzerror(out, &err));
155*10465441SEvalZero 
156*10465441SEvalZero     munmap(buf, buf_len);
157*10465441SEvalZero     fclose(in);
158*10465441SEvalZero     if (gzclose(out) != Z_OK) error("failed gzclose");
159*10465441SEvalZero     return Z_OK;
160*10465441SEvalZero }
161*10465441SEvalZero #endif /* USE_MMAP */
162*10465441SEvalZero 
163*10465441SEvalZero /* ===========================================================================
164*10465441SEvalZero  * Uncompress input to output then close both files.
165*10465441SEvalZero  */
gz_uncompress(in,out)166*10465441SEvalZero void gz_uncompress(in, out)
167*10465441SEvalZero     gzFile in;
168*10465441SEvalZero     FILE   *out;
169*10465441SEvalZero {
170*10465441SEvalZero     local char buf[BUFLEN];
171*10465441SEvalZero     int len;
172*10465441SEvalZero     int err;
173*10465441SEvalZero 
174*10465441SEvalZero     for (;;) {
175*10465441SEvalZero         len = gzread(in, buf, sizeof(buf));
176*10465441SEvalZero         if (len < 0) error (gzerror(in, &err));
177*10465441SEvalZero         if (len == 0) break;
178*10465441SEvalZero 
179*10465441SEvalZero         if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
180*10465441SEvalZero             error("failed fwrite");
181*10465441SEvalZero         }
182*10465441SEvalZero     }
183*10465441SEvalZero     if (fclose(out)) error("failed fclose");
184*10465441SEvalZero 
185*10465441SEvalZero     if (gzclose(in) != Z_OK) error("failed gzclose");
186*10465441SEvalZero }
187*10465441SEvalZero 
188*10465441SEvalZero 
189*10465441SEvalZero /* ===========================================================================
190*10465441SEvalZero  * Compress the given file: create a corresponding .gz file and remove the
191*10465441SEvalZero  * original.
192*10465441SEvalZero  */
file_compress(file,mode)193*10465441SEvalZero void file_compress(file, mode)
194*10465441SEvalZero     char  *file;
195*10465441SEvalZero     char  *mode;
196*10465441SEvalZero {
197*10465441SEvalZero     local char outfile[MAX_NAME_LEN];
198*10465441SEvalZero     FILE  *in;
199*10465441SEvalZero     gzFile out;
200*10465441SEvalZero 
201*10465441SEvalZero     strcpy(outfile, file);
202*10465441SEvalZero     strcat(outfile, GZ_SUFFIX);
203*10465441SEvalZero 
204*10465441SEvalZero     in = fopen(file, "rb");
205*10465441SEvalZero     if (in == NULL) {
206*10465441SEvalZero         perror(file);
207*10465441SEvalZero         exit(1);
208*10465441SEvalZero     }
209*10465441SEvalZero     out = gzopen(outfile, mode);
210*10465441SEvalZero     if (out == NULL) {
211*10465441SEvalZero         fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
212*10465441SEvalZero         exit(1);
213*10465441SEvalZero     }
214*10465441SEvalZero     gz_compress(in, out);
215*10465441SEvalZero 
216*10465441SEvalZero     unlink(file);
217*10465441SEvalZero }
218*10465441SEvalZero 
219*10465441SEvalZero 
220*10465441SEvalZero /* ===========================================================================
221*10465441SEvalZero  * Uncompress the given file and remove the original.
222*10465441SEvalZero  */
file_uncompress(file)223*10465441SEvalZero void file_uncompress(file)
224*10465441SEvalZero     char  *file;
225*10465441SEvalZero {
226*10465441SEvalZero     local char buf[MAX_NAME_LEN];
227*10465441SEvalZero     char *infile, *outfile;
228*10465441SEvalZero     FILE  *out;
229*10465441SEvalZero     gzFile in;
230*10465441SEvalZero     uInt len = (uInt)strlen(file);
231*10465441SEvalZero 
232*10465441SEvalZero     strcpy(buf, file);
233*10465441SEvalZero 
234*10465441SEvalZero     if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
235*10465441SEvalZero         infile = file;
236*10465441SEvalZero         outfile = buf;
237*10465441SEvalZero         outfile[len-3] = '\0';
238*10465441SEvalZero     } else {
239*10465441SEvalZero         outfile = file;
240*10465441SEvalZero         infile = buf;
241*10465441SEvalZero         strcat(infile, GZ_SUFFIX);
242*10465441SEvalZero     }
243*10465441SEvalZero     in = gzopen(infile, "rb");
244*10465441SEvalZero     if (in == NULL) {
245*10465441SEvalZero         fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
246*10465441SEvalZero         exit(1);
247*10465441SEvalZero     }
248*10465441SEvalZero     out = fopen(outfile, "wb");
249*10465441SEvalZero     if (out == NULL) {
250*10465441SEvalZero         perror(file);
251*10465441SEvalZero         exit(1);
252*10465441SEvalZero     }
253*10465441SEvalZero 
254*10465441SEvalZero     gz_uncompress(in, out);
255*10465441SEvalZero 
256*10465441SEvalZero     unlink(infile);
257*10465441SEvalZero }
258*10465441SEvalZero 
259*10465441SEvalZero 
260*10465441SEvalZero /* ===========================================================================
261*10465441SEvalZero  * Usage:  minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...]
262*10465441SEvalZero  *   -d : decompress
263*10465441SEvalZero  *   -f : compress with Z_FILTERED
264*10465441SEvalZero  *   -h : compress with Z_HUFFMAN_ONLY
265*10465441SEvalZero  *   -r : compress with Z_RLE
266*10465441SEvalZero  *   -1 to -9 : compression level
267*10465441SEvalZero  */
268*10465441SEvalZero 
main(argc,argv)269*10465441SEvalZero int main(argc, argv)
270*10465441SEvalZero     int argc;
271*10465441SEvalZero     char *argv[];
272*10465441SEvalZero {
273*10465441SEvalZero     int uncompr = 0;
274*10465441SEvalZero     gzFile file;
275*10465441SEvalZero     char outmode[20];
276*10465441SEvalZero 
277*10465441SEvalZero     strcpy(outmode, "wb6 ");
278*10465441SEvalZero 
279*10465441SEvalZero     prog = argv[0];
280*10465441SEvalZero     argc--, argv++;
281*10465441SEvalZero 
282*10465441SEvalZero     while (argc > 0) {
283*10465441SEvalZero       if (strcmp(*argv, "-d") == 0)
284*10465441SEvalZero         uncompr = 1;
285*10465441SEvalZero       else if (strcmp(*argv, "-f") == 0)
286*10465441SEvalZero         outmode[3] = 'f';
287*10465441SEvalZero       else if (strcmp(*argv, "-h") == 0)
288*10465441SEvalZero         outmode[3] = 'h';
289*10465441SEvalZero       else if (strcmp(*argv, "-r") == 0)
290*10465441SEvalZero         outmode[3] = 'R';
291*10465441SEvalZero       else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
292*10465441SEvalZero                (*argv)[2] == 0)
293*10465441SEvalZero         outmode[2] = (*argv)[1];
294*10465441SEvalZero       else
295*10465441SEvalZero         break;
296*10465441SEvalZero       argc--, argv++;
297*10465441SEvalZero     }
298*10465441SEvalZero     if (outmode[3] == ' ')
299*10465441SEvalZero         outmode[3] = 0;
300*10465441SEvalZero     if (argc == 0) {
301*10465441SEvalZero         SET_BINARY_MODE(stdin);
302*10465441SEvalZero         SET_BINARY_MODE(stdout);
303*10465441SEvalZero         if (uncompr) {
304*10465441SEvalZero             file = gzdopen(fileno(stdin), "rb");
305*10465441SEvalZero             if (file == NULL) error("can't gzdopen stdin");
306*10465441SEvalZero             gz_uncompress(file, stdout);
307*10465441SEvalZero         } else {
308*10465441SEvalZero             file = gzdopen(fileno(stdout), outmode);
309*10465441SEvalZero             if (file == NULL) error("can't gzdopen stdout");
310*10465441SEvalZero             gz_compress(stdin, file);
311*10465441SEvalZero         }
312*10465441SEvalZero     } else {
313*10465441SEvalZero         do {
314*10465441SEvalZero             if (uncompr) {
315*10465441SEvalZero                 file_uncompress(*argv);
316*10465441SEvalZero             } else {
317*10465441SEvalZero                 file_compress(*argv, outmode);
318*10465441SEvalZero             }
319*10465441SEvalZero         } while (argv++, --argc);
320*10465441SEvalZero     }
321*10465441SEvalZero     return 0;
322*10465441SEvalZero }
323