]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/zstd/zlibWrapper/examples/minigzip.c
Merge llvm trunk r321414 to contrib/llvm.
[FreeBSD/FreeBSD.git] / sys / contrib / zstd / zlibWrapper / examples / minigzip.c
1 /* minigzip.c contains minimal changes required to be compiled with zlibWrapper:
2  * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h"        */
3
4 /* minigzip.c -- simulate gzip using the zlib compression library
5  * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly.
6  * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html
7  */
8
9 /*
10  * minigzip is a minimal implementation of the gzip utility. This is
11  * only an example of using zlib and isn't meant to replace the
12  * full-featured gzip. No attempt is made to deal with file systems
13  * limiting names to 14 or 8+3 characters, etc... Error checking is
14  * very limited. So use minigzip only for testing; use gzip for the
15  * real thing. On MSDOS, use only on file names without extension
16  * or in pipe mode.
17  */
18
19 /* @(#) $Id$ */
20
21 #include "zstd_zlibwrapper.h"
22 #include <stdio.h>
23
24 #ifdef STDC
25 #  include <string.h>
26 #  include <stdlib.h>
27 #endif
28
29 #ifdef USE_MMAP
30 #  include <sys/types.h>
31 #  include <sys/mman.h>
32 #  include <sys/stat.h>
33 #endif
34
35 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
36 #  include <fcntl.h>
37 #  include <io.h>
38 #  ifdef UNDER_CE
39 #    include <stdlib.h>
40 #  endif
41 #  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
42 #else
43 #  define SET_BINARY_MODE(file)
44 #endif
45
46 #ifdef _MSC_VER
47 #  define snprintf _snprintf
48 #endif
49
50 #ifdef VMS
51 #  define unlink delete
52 #  define GZ_SUFFIX "-gz"
53 #endif
54 #ifdef RISCOS
55 #  define unlink remove
56 #  define GZ_SUFFIX "-gz"
57 #  define fileno(file) file->__file
58 #endif
59 #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
60 #  include <unix.h> /* for fileno */
61 #endif
62
63 #if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
64 #ifndef WIN32 /* unlink already in stdio.h for WIN32 */
65   extern int unlink OF((const char *));
66 #endif
67 #endif
68
69 #if defined(UNDER_CE)
70 #  include <windows.h>
71 #  define perror(s) pwinerror(s)
72
73 /* Map the Windows error number in ERROR to a locale-dependent error
74    message string and return a pointer to it.  Typically, the values
75    for ERROR come from GetLastError.
76
77    The string pointed to shall not be modified by the application,
78    but may be overwritten by a subsequent call to strwinerror
79
80    The strwinerror function does not change the current setting
81    of GetLastError.  */
82
83 static char *strwinerror (error)
84      DWORD error;
85 {
86     static char buf[1024];
87
88     wchar_t *msgbuf;
89     DWORD lasterr = GetLastError();
90     DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
91         | FORMAT_MESSAGE_ALLOCATE_BUFFER,
92         NULL,
93         error,
94         0, /* Default language */
95         (LPVOID)&msgbuf,
96         0,
97         NULL);
98     if (chars != 0) {
99         /* If there is an \r\n appended, zap it.  */
100         if (chars >= 2
101             && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
102             chars -= 2;
103             msgbuf[chars] = 0;
104         }
105
106         if (chars > sizeof (buf) - 1) {
107             chars = sizeof (buf) - 1;
108             msgbuf[chars] = 0;
109         }
110
111         wcstombs(buf, msgbuf, chars + 1);
112         LocalFree(msgbuf);
113     }
114     else {
115         sprintf(buf, "unknown win32 error (%ld)", error);
116     }
117
118     SetLastError(lasterr);
119     return buf;
120 }
121
122 static void pwinerror (s)
123     const char *s;
124 {
125     if (s && *s)
126         fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
127     else
128         fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
129 }
130
131 #endif /* UNDER_CE */
132
133 #ifndef GZ_SUFFIX
134 #  define GZ_SUFFIX ".gz"
135 #endif
136 #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
137
138 #define BUFLEN      16384
139 #define MAX_NAME_LEN 1024
140
141 #ifdef MAXSEG_64K
142 #  define local static
143    /* Needed for systems with limitation on stack size. */
144 #else
145 #  define local
146 #endif
147
148 #ifdef Z_SOLO
149 /* for Z_SOLO, create simplified gz* functions using deflate and inflate */
150
151 #if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
152 #  include <unistd.h>       /* for unlink() */
153 #endif
154
155 void *myalloc OF((void *, unsigned, unsigned));
156 void myfree OF((void *, void *));
157
158 void *myalloc(q, n, m)
159     void *q;
160     unsigned n, m;
161 {
162     q = Z_NULL;
163     return calloc(n, m);
164 }
165
166 void myfree(q, p)
167     void *q, *p;
168 {
169     q = Z_NULL;
170     free(p);
171 }
172
173 typedef struct gzFile_s {
174     FILE *file;
175     int write;
176     int err;
177     char *msg;
178     z_stream strm;
179 } *gzFile;
180
181 gzFile gzopen OF((const char *, const char *));
182 gzFile gzdopen OF((int, const char *));
183 gzFile gz_open OF((const char *, int, const char *));
184
185 gzFile gzopen(path, mode)
186 const char *path;
187 const char *mode;
188 {
189     return gz_open(path, -1, mode);
190 }
191
192 gzFile gzdopen(fd, mode)
193 int fd;
194 const char *mode;
195 {
196     return gz_open(NULL, fd, mode);
197 }
198
199 gzFile gz_open(path, fd, mode)
200     const char *path;
201     int fd;
202     const char *mode;
203 {
204     gzFile gz;
205     int ret;
206
207     gz = malloc(sizeof(struct gzFile_s));
208     if (gz == NULL)
209         return NULL;
210     gz->write = strchr(mode, 'w') != NULL;
211     gz->strm.zalloc = myalloc;
212     gz->strm.zfree = myfree;
213     gz->strm.opaque = Z_NULL;
214     if (gz->write)
215         ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
216     else {
217         gz->strm.next_in = 0;
218         gz->strm.avail_in = Z_NULL;
219         ret = inflateInit2(&(gz->strm), 15 + 16);
220     }
221     if (ret != Z_OK) {
222         free(gz);
223         return NULL;
224     }
225     gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
226                               fopen(path, gz->write ? "wb" : "rb");
227     if (gz->file == NULL) {
228         gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
229         free(gz);
230         return NULL;
231     }
232     gz->err = 0;
233     gz->msg = "";
234     return gz;
235 }
236
237 int gzwrite OF((gzFile, const void *, unsigned));
238
239 int gzwrite(gz, buf, len)
240     gzFile gz;
241     const void *buf;
242     unsigned len;
243 {
244     z_stream *strm;
245     unsigned char out[BUFLEN];
246
247     if (gz == NULL || !gz->write)
248         return 0;
249     strm = &(gz->strm);
250     strm->next_in = (void *)buf;
251     strm->avail_in = len;
252     do {
253         strm->next_out = out;
254         strm->avail_out = BUFLEN;
255         (void)deflate(strm, Z_NO_FLUSH);
256         fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
257     } while (strm->avail_out == 0);
258     return len;
259 }
260
261 int gzread OF((gzFile, void *, unsigned));
262
263 int gzread(gz, buf, len)
264     gzFile gz;
265     void *buf;
266     unsigned len;
267 {
268     int ret;
269     unsigned got;
270     unsigned char in[1];
271     z_stream *strm;
272
273     if (gz == NULL || gz->write)
274         return 0;
275     if (gz->err)
276         return 0;
277     strm = &(gz->strm);
278     strm->next_out = (void *)buf;
279     strm->avail_out = len;
280     do {
281         got = fread(in, 1, 1, gz->file);
282         if (got == 0)
283             break;
284         strm->next_in = in;
285         strm->avail_in = 1;
286         ret = inflate(strm, Z_NO_FLUSH);
287         if (ret == Z_DATA_ERROR) {
288             gz->err = Z_DATA_ERROR;
289             gz->msg = strm->msg;
290             return 0;
291         }
292         if (ret == Z_STREAM_END)
293             inflateReset(strm);
294     } while (strm->avail_out);
295     return len - strm->avail_out;
296 }
297
298 int gzclose OF((gzFile));
299
300 int gzclose(gz)
301     gzFile gz;
302 {
303     z_stream *strm;
304     unsigned char out[BUFLEN];
305
306     if (gz == NULL)
307         return Z_STREAM_ERROR;
308     strm = &(gz->strm);
309     if (gz->write) {
310         strm->next_in = Z_NULL;
311         strm->avail_in = 0;
312         do {
313             strm->next_out = out;
314             strm->avail_out = BUFLEN;
315             (void)deflate(strm, Z_FINISH);
316             fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
317         } while (strm->avail_out == 0);
318         deflateEnd(strm);
319     }
320     else
321         inflateEnd(strm);
322     fclose(gz->file);
323     free(gz);
324     return Z_OK;
325 }
326
327 const char *gzerror OF((gzFile, int *));
328
329 const char *gzerror(gz, err)
330     gzFile gz;
331     int *err;
332 {
333     *err = gz->err;
334     return gz->msg;
335 }
336
337 #endif
338
339 char *prog;
340
341 void error            OF((const char *msg));
342 void gz_compress      OF((FILE   *in, gzFile out));
343 #ifdef USE_MMAP
344 int  gz_compress_mmap OF((FILE   *in, gzFile out));
345 #endif
346 void gz_uncompress    OF((gzFile in, FILE   *out));
347 void file_compress    OF((char  *file, char *mode));
348 void file_uncompress  OF((char  *file));
349 int  main             OF((int argc, char *argv[]));
350
351 /* ===========================================================================
352  * Display error message and exit
353  */
354 void error(msg)
355     const char *msg;
356 {
357     fprintf(stderr, "%s: %s\n", prog, msg);
358     exit(1);
359 }
360
361 /* ===========================================================================
362  * Compress input to output then close both files.
363  */
364
365 void gz_compress(in, out)
366     FILE   *in;
367     gzFile out;
368 {
369     local char buf[BUFLEN];
370     int len;
371     int err;
372
373 #ifdef USE_MMAP
374     /* Try first compressing with mmap. If mmap fails (minigzip used in a
375      * pipe), use the normal fread loop.
376      */
377     if (gz_compress_mmap(in, out) == Z_OK) return;
378 #endif
379     for (;;) {
380         len = (int)fread(buf, 1, sizeof(buf), in);
381         if (ferror(in)) {
382             perror("fread");
383             exit(1);
384         }
385         if (len == 0) break;
386
387         if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
388     }
389     fclose(in);
390     if (gzclose(out) != Z_OK) error("failed gzclose");
391 }
392
393 #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
394
395 /* Try compressing the input file at once using mmap. Return Z_OK if
396  * if success, Z_ERRNO otherwise.
397  */
398 int gz_compress_mmap(in, out)
399     FILE   *in;
400     gzFile out;
401 {
402     int len;
403     int err;
404     int ifd = fileno(in);
405     caddr_t buf;    /* mmap'ed buffer for the entire input file */
406     off_t buf_len;  /* length of the input file */
407     struct stat sb;
408
409     /* Determine the size of the file, needed for mmap: */
410     if (fstat(ifd, &sb) < 0) return Z_ERRNO;
411     buf_len = sb.st_size;
412     if (buf_len <= 0) return Z_ERRNO;
413
414     /* Now do the actual mmap: */
415     buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
416     if (buf == (caddr_t)(-1)) return Z_ERRNO;
417
418     /* Compress the whole file at once: */
419     len = gzwrite(out, (char *)buf, (unsigned)buf_len);
420
421     if (len != (int)buf_len) error(gzerror(out, &err));
422
423     munmap(buf, buf_len);
424     fclose(in);
425     if (gzclose(out) != Z_OK) error("failed gzclose");
426     return Z_OK;
427 }
428 #endif /* USE_MMAP */
429
430 /* ===========================================================================
431  * Uncompress input to output then close both files.
432  */
433 void gz_uncompress(in, out)
434     gzFile in;
435     FILE   *out;
436 {
437     local char buf[BUFLEN];
438     int len;
439     int err;
440
441     for (;;) {
442         len = gzread(in, buf, sizeof(buf));
443         if (len < 0) error (gzerror(in, &err));
444         if (len == 0) break;
445
446         if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
447             error("failed fwrite");
448         }
449     }
450     if (fclose(out)) error("failed fclose");
451
452     if (gzclose(in) != Z_OK) error("failed gzclose");
453 }
454
455
456 /* ===========================================================================
457  * Compress the given file: create a corresponding .gz file and remove the
458  * original.
459  */
460 void file_compress(file, mode)
461     char  *file;
462     char  *mode;
463 {
464     local char outfile[MAX_NAME_LEN];
465     FILE  *in;
466     gzFile out;
467
468     if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
469         fprintf(stderr, "%s: filename too long\n", prog);
470         exit(1);
471     }
472
473 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
474     snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
475 #else
476     strcpy(outfile, file);
477     strcat(outfile, GZ_SUFFIX);
478 #endif
479
480     in = fopen(file, "rb");
481     if (in == NULL) {
482         perror(file);
483         exit(1);
484     }
485     out = gzopen(outfile, mode);
486     if (out == NULL) {
487         fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
488         exit(1);
489     }
490     gz_compress(in, out);
491
492     unlink(file);
493 }
494
495
496 /* ===========================================================================
497  * Uncompress the given file and remove the original.
498  */
499 void file_uncompress(file)
500     char  *file;
501 {
502     local char buf[MAX_NAME_LEN];
503     char *infile, *outfile;
504     FILE  *out;
505     gzFile in;
506     size_t len = strlen(file);
507
508     if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
509         fprintf(stderr, "%s: filename too long\n", prog);
510         exit(1);
511     }
512
513 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
514     snprintf(buf, sizeof(buf), "%s", file);
515 #else
516     strcpy(buf, file);
517 #endif
518
519     if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
520         infile = file;
521         outfile = buf;
522         outfile[len-3] = '\0';
523     } else {
524         outfile = file;
525         infile = buf;
526 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
527         snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
528 #else
529         strcat(infile, GZ_SUFFIX);
530 #endif
531     }
532     in = gzopen(infile, "rb");
533     if (in == NULL) {
534         fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
535         exit(1);
536     }
537     out = fopen(outfile, "wb");
538     if (out == NULL) {
539         perror(file);
540         exit(1);
541     }
542
543     gz_uncompress(in, out);
544
545     unlink(infile);
546 }
547
548
549 /* ===========================================================================
550  * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
551  *   -c : write to standard output
552  *   -d : decompress
553  *   -f : compress with Z_FILTERED
554  *   -h : compress with Z_HUFFMAN_ONLY
555  *   -r : compress with Z_RLE
556  *   -1 to -9 : compression level
557  */
558
559 int main(argc, argv)
560     int argc;
561     char *argv[];
562 {
563     int copyout = 0;
564     int uncompr = 0;
565     gzFile file;
566     char *bname, outmode[20];
567
568 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
569     snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
570 #else
571     strcpy(outmode, "wb6 ");
572 #endif
573
574     prog = argv[0];
575     bname = strrchr(argv[0], '/');
576     if (bname)
577       bname++;
578     else
579       bname = argv[0];
580     argc--, argv++;
581
582     if (!strcmp(bname, "gunzip"))
583       uncompr = 1;
584     else if (!strcmp(bname, "zcat"))
585       copyout = uncompr = 1;
586
587     while (argc > 0) {
588       if (strcmp(*argv, "-c") == 0)
589         copyout = 1;
590       else if (strcmp(*argv, "-d") == 0)
591         uncompr = 1;
592       else if (strcmp(*argv, "-f") == 0)
593         outmode[3] = 'f';
594       else if (strcmp(*argv, "-h") == 0)
595         outmode[3] = 'h';
596       else if (strcmp(*argv, "-r") == 0)
597         outmode[3] = 'R';
598       else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
599                (*argv)[2] == 0)
600         outmode[2] = (*argv)[1];
601       else
602         break;
603       argc--, argv++;
604     }
605     if (outmode[3] == ' ')
606         outmode[3] = 0;
607     if (argc == 0) {
608         SET_BINARY_MODE(stdin);
609         SET_BINARY_MODE(stdout);
610         if (uncompr) {
611             file = gzdopen(fileno(stdin), "rb");
612             if (file == NULL) error("can't gzdopen stdin");
613             gz_uncompress(file, stdout);
614         } else {
615             file = gzdopen(fileno(stdout), outmode);
616             if (file == NULL) error("can't gzdopen stdout");
617             gz_compress(stdin, file);
618         }
619     } else {
620         if (copyout) {
621             SET_BINARY_MODE(stdout);
622         }
623         do {
624             if (uncompr) {
625                 if (copyout) {
626                     file = gzopen(*argv, "rb");
627                     if (file == NULL)
628                         fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
629                     else
630                         gz_uncompress(file, stdout);
631                 } else {
632                     file_uncompress(*argv);
633                 }
634             } else {
635                 if (copyout) {
636                     FILE * in = fopen(*argv, "rb");
637
638                     if (in == NULL) {
639                         perror(*argv);
640                     } else {
641                         file = gzdopen(fileno(stdout), outmode);
642                         if (file == NULL) error("can't gzdopen stdout");
643
644                         gz_compress(in, file);
645                     }
646
647                 } else {
648                     file_compress(*argv, outmode);
649                 }
650             }
651         } while (argv++, --argc);
652     }
653     return 0;
654 }