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