Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
gun.c
Go to the documentation of this file.
1 /* gun.c -- simple gunzip to give an example of the use of inflateBack()
2  * Copyright (C) 2003, 2005, 2008, 2010, 2012 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  Version 1.7 12 August 2012 Mark Adler */
5 
6 /* Version history:
7  1.0 16 Feb 2003 First version for testing of inflateBack()
8  1.1 21 Feb 2005 Decompress concatenated gzip streams
9  Remove use of "this" variable (C++ keyword)
10  Fix return value for in()
11  Improve allocation failure checking
12  Add typecasting for void * structures
13  Add -h option for command version and usage
14  Add a bunch of comments
15  1.2 20 Mar 2005 Add Unix compress (LZW) decompression
16  Copy file attributes from input file to output file
17  1.3 12 Jun 2005 Add casts for error messages [Oberhumer]
18  1.4 8 Dec 2006 LZW decompression speed improvements
19  1.5 9 Feb 2008 Avoid warning in latest version of gcc
20  1.6 17 Jan 2010 Avoid signed/unsigned comparison warnings
21  1.7 12 Aug 2012 Update for z_const usage in zlib 1.2.8
22  */
23 
24 /*
25  gun [ -t ] [ name ... ]
26 
27  decompresses the data in the named gzip files. If no arguments are given,
28  gun will decompress from stdin to stdout. The names must end in .gz, -gz,
29  .z, -z, _z, or .Z. The uncompressed data will be written to a file name
30  with the suffix stripped. On success, the original file is deleted. On
31  failure, the output file is deleted. For most failures, the command will
32  continue to process the remaining names on the command line. A memory
33  allocation failure will abort the command. If -t is specified, then the
34  listed files or stdin will be tested as gzip files for integrity (without
35  checking for a proper suffix), no output will be written, and no files
36  will be deleted.
37 
38  Like gzip, gun allows concatenated gzip streams and will decompress them,
39  writing all of the uncompressed data to the output. Unlike gzip, gun allows
40  an empty file on input, and will produce no error writing an empty output
41  file.
42 
43  gun will also decompress files made by Unix compress, which uses LZW
44  compression. These files are automatically detected by virtue of their
45  magic header bytes. Since the end of Unix compress stream is marked by the
46  end-of-file, they cannot be concantenated. If a Unix compress stream is
47  encountered in an input file, it is the last stream in that file.
48 
49  Like gunzip and uncompress, the file attributes of the orignal compressed
50  file are maintained in the final uncompressed file, to the extent that the
51  user permissions allow it.
52 
53  On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version
54  1.2.4) is on the same file, when gun is linked with zlib 1.2.2. Also the
55  LZW decompression provided by gun is about twice as fast as the standard
56  Unix uncompress command.
57  */
58 
59 /* external functions and related types and constants */
60 #include <stdio.h> /* fprintf() */
61 #include <stdlib.h> /* malloc(), free() */
62 #include <string.h> /* strerror(), strcmp(), strlen(), memcpy() */
63 #include <errno.h> /* errno */
64 #include <fcntl.h> /* open() */
65 #include <unistd.h> /* read(), write(), close(), chown(), unlink() */
66 #include <sys/types.h>
67 #include <sys/stat.h> /* stat(), chmod() */
68 #include <utime.h> /* utime() */
69 #include "zlib.h" /* inflateBackInit(), inflateBack(), */
70  /* inflateBackEnd(), crc32() */
71 
72 /* function declaration */
73 #define local static
74 
75 /* buffer constants */
76 #define SIZE 32768U /* input and output buffer sizes */
77 #define PIECE 16384 /* limits i/o chunks for 16-bit int case */
78 
79 /* structure for infback() to pass to input function in() -- it maintains the
80  input file and a buffer of size SIZE */
81 struct ind {
82  int infile;
83  unsigned char *inbuf;
84 };
85 
86 /* Load input buffer, assumed to be empty, and return bytes loaded and a
87  pointer to them. read() is called until the buffer is full, or until it
88  returns end-of-file or error. Return 0 on error. */
89 local unsigned in(void *in_desc, z_const unsigned char **buf)
90 {
91  int ret;
92  unsigned len;
93  unsigned char *next;
94  struct ind *me = (struct ind *)in_desc;
95 
96  next = me->inbuf;
97  *buf = next;
98  len = 0;
99  do {
100  ret = PIECE;
101  if ((unsigned)ret > SIZE - len)
102  ret = (int)(SIZE - len);
103  ret = (int)read(me->infile, next, ret);
104  if (ret == -1) {
105  len = 0;
106  break;
107  }
108  next += ret;
109  len += ret;
110  } while (ret != 0 && len < SIZE);
111  return len;
112 }
113 
114 /* structure for infback() to pass to output function out() -- it maintains the
115  output file, a running CRC-32 check on the output and the total number of
116  bytes output, both for checking against the gzip trailer. (The length in
117  the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and
118  the output is greater than 4 GB.) */
119 struct outd {
120  int outfile;
121  int check; /* true if checking crc and total */
122  unsigned long crc;
123  unsigned long total;
124 };
125 
126 /* Write output buffer and update the CRC-32 and total bytes written. write()
127  is called until all of the output is written or an error is encountered.
128  On success out() returns 0. For a write failure, out() returns 1. If the
129  output file descriptor is -1, then nothing is written.
130  */
131 local int out(void *out_desc, unsigned char *buf, unsigned len)
132 {
133  int ret;
134  struct outd *me = (struct outd *)out_desc;
135 
136  if (me->check) {
137  me->crc = crc32(me->crc, buf, len);
138  me->total += len;
139  }
140  if (me->outfile != -1)
141  do {
142  ret = PIECE;
143  if ((unsigned)ret > len)
144  ret = (int)len;
145  ret = (int)write(me->outfile, buf, ret);
146  if (ret == -1)
147  return 1;
148  buf += ret;
149  len -= ret;
150  } while (len != 0);
151  return 0;
152 }
153 
154 /* next input byte macro for use inside lunpipe() and gunpipe() */
155 #define NEXT() (have ? 0 : (have = in(indp, &next)), \
156  last = have ? (have--, (int)(*next++)) : -1)
157 
158 /* memory for gunpipe() and lunpipe() --
159  the first 256 entries of prefix[] and suffix[] are never used, could
160  have offset the index, but it's faster to waste the memory */
161 unsigned char inbuf[SIZE]; /* input buffer */
162 unsigned char outbuf[SIZE]; /* output buffer */
163 unsigned short prefix[65536]; /* index to LZW prefix string */
164 unsigned char suffix[65536]; /* one-character LZW suffix */
165 unsigned char match[65280 + 2]; /* buffer for reversed match or gzip
166  32K sliding window */
167 
168 /* throw out what's left in the current bits byte buffer (this is a vestigial
169  aspect of the compressed data format derived from an implementation that
170  made use of a special VAX machine instruction!) */
171 #define FLUSHCODE() \
172  do { \
173  left = 0; \
174  rem = 0; \
175  if (chunk > have) { \
176  chunk -= have; \
177  have = 0; \
178  if (NEXT() == -1) \
179  break; \
180  chunk--; \
181  if (chunk > have) { \
182  chunk = have = 0; \
183  break; \
184  } \
185  } \
186  have -= chunk; \
187  next += chunk; \
188  chunk = 0; \
189  } while (0)
190 
191 /* Decompress a compress (LZW) file from indp to outfile. The compress magic
192  header (two bytes) has already been read and verified. There are have bytes
193  of buffered input at next. strm is used for passing error information back
194  to gunpipe().
195 
196  lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of
197  file, read error, or write error (a write error indicated by strm->next_in
198  not equal to Z_NULL), or Z_DATA_ERROR for invalid input.
199  */
200 local int lunpipe(unsigned have, z_const unsigned char *next, struct ind *indp,
201  int outfile, z_stream *strm)
202 {
203  int last; /* last byte read by NEXT(), or -1 if EOF */
204  unsigned chunk; /* bytes left in current chunk */
205  int left; /* bits left in rem */
206  unsigned rem; /* unused bits from input */
207  int bits; /* current bits per code */
208  unsigned code; /* code, table traversal index */
209  unsigned mask; /* mask for current bits codes */
210  int max; /* maximum bits per code for this stream */
211  unsigned flags; /* compress flags, then block compress flag */
212  unsigned end; /* last valid entry in prefix/suffix tables */
213  unsigned temp; /* current code */
214  unsigned prev; /* previous code */
215  unsigned final; /* last character written for previous code */
216  unsigned stack; /* next position for reversed string */
217  unsigned outcnt; /* bytes in output buffer */
218  struct outd outd; /* output structure */
219  unsigned char *p;
220 
221  /* set up output */
222  outd.outfile = outfile;
223  outd.check = 0;
224 
225  /* process remainder of compress header -- a flags byte */
226  flags = NEXT();
227  if (last == -1)
228  return Z_BUF_ERROR;
229  if (flags & 0x60) {
230  strm->msg = (char *)"unknown lzw flags set";
231  return Z_DATA_ERROR;
232  }
233  max = flags & 0x1f;
234  if (max < 9 || max > 16) {
235  strm->msg = (char *)"lzw bits out of range";
236  return Z_DATA_ERROR;
237  }
238  if (max == 9) /* 9 doesn't really mean 9 */
239  max = 10;
240  flags &= 0x80; /* true if block compress */
241 
242  /* clear table */
243  bits = 9;
244  mask = 0x1ff;
245  end = flags ? 256 : 255;
246 
247  /* set up: get first 9-bit code, which is the first decompressed byte, but
248  don't create a table entry until the next code */
249  if (NEXT() == -1) /* no compressed data is ok */
250  return Z_OK;
251  final = prev = (unsigned)last; /* low 8 bits of code */
252  if (NEXT() == -1) /* missing a bit */
253  return Z_BUF_ERROR;
254  if (last & 1) { /* code must be < 256 */
255  strm->msg = (char *)"invalid lzw code";
256  return Z_DATA_ERROR;
257  }
258  rem = (unsigned)last >> 1; /* remaining 7 bits */
259  left = 7;
260  chunk = bits - 2; /* 7 bytes left in this chunk */
261  outbuf[0] = (unsigned char)final; /* write first decompressed byte */
262  outcnt = 1;
263 
264  /* decode codes */
265  stack = 0;
266  for (;;) {
267  /* if the table will be full after this, increment the code size */
268  if (end >= mask && bits < max) {
269  FLUSHCODE();
270  bits++;
271  mask <<= 1;
272  mask++;
273  }
274 
275  /* get a code of length bits */
276  if (chunk == 0) /* decrement chunk modulo bits */
277  chunk = bits;
278  code = rem; /* low bits of code */
279  if (NEXT() == -1) { /* EOF is end of compressed data */
280  /* write remaining buffered output */
281  if (outcnt && out(&outd, outbuf, outcnt)) {
282  strm->next_in = outbuf; /* signal write error */
283  return Z_BUF_ERROR;
284  }
285  return Z_OK;
286  }
287  code += (unsigned)last << left; /* middle (or high) bits of code */
288  left += 8;
289  chunk--;
290  if (bits > left) { /* need more bits */
291  if (NEXT() == -1) /* can't end in middle of code */
292  return Z_BUF_ERROR;
293  code += (unsigned)last << left; /* high bits of code */
294  left += 8;
295  chunk--;
296  }
297  code &= mask; /* mask to current code length */
298  left -= bits; /* number of unused bits */
299  rem = (unsigned)last >> (8 - left); /* unused bits from last byte */
300 
301  /* process clear code (256) */
302  if (code == 256 && flags) {
303  FLUSHCODE();
304  bits = 9; /* initialize bits and mask */
305  mask = 0x1ff;
306  end = 255; /* empty table */
307  continue; /* get next code */
308  }
309 
310  /* special code to reuse last match */
311  temp = code; /* save the current code */
312  if (code > end) {
313  /* Be picky on the allowed code here, and make sure that the code
314  we drop through (prev) will be a valid index so that random
315  input does not cause an exception. The code != end + 1 check is
316  empirically derived, and not checked in the original uncompress
317  code. If this ever causes a problem, that check could be safely
318  removed. Leaving this check in greatly improves gun's ability
319  to detect random or corrupted input after a compress header.
320  In any case, the prev > end check must be retained. */
321  if (code != end + 1 || prev > end) {
322  strm->msg = (char *)"invalid lzw code";
323  return Z_DATA_ERROR;
324  }
325  match[stack++] = (unsigned char)final;
326  code = prev;
327  }
328 
329  /* walk through linked list to generate output in reverse order */
330  p = match + stack;
331  while (code >= 256) {
332  *p++ = suffix[code];
333  code = prefix[code];
334  }
335  stack = p - match;
336  match[stack++] = (unsigned char)code;
337  final = code;
338 
339  /* link new table entry */
340  if (end < mask) {
341  end++;
342  prefix[end] = (unsigned short)prev;
343  suffix[end] = (unsigned char)final;
344  }
345 
346  /* set previous code for next iteration */
347  prev = temp;
348 
349  /* write output in forward order */
350  while (stack > SIZE - outcnt) {
351  while (outcnt < SIZE)
352  outbuf[outcnt++] = match[--stack];
353  if (out(&outd, outbuf, outcnt)) {
354  strm->next_in = outbuf; /* signal write error */
355  return Z_BUF_ERROR;
356  }
357  outcnt = 0;
358  }
359  p = match + stack;
360  do {
361  outbuf[outcnt++] = *--p;
362  } while (p > match);
363  stack = 0;
364 
365  /* loop for next code with final and prev as the last match, rem and
366  left provide the first 0..7 bits of the next code, end is the last
367  valid table entry */
368  }
369 }
370 
371 /* Decompress a gzip file from infile to outfile. strm is assumed to have been
372  successfully initialized with inflateBackInit(). The input file may consist
373  of a series of gzip streams, in which case all of them will be decompressed
374  to the output file. If outfile is -1, then the gzip stream(s) integrity is
375  checked and nothing is written.
376 
377  The return value is a zlib error code: Z_MEM_ERROR if out of memory,
378  Z_DATA_ERROR if the header or the compressed data is invalid, or if the
379  trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends
380  prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip
381  stream) follows a valid gzip stream.
382  */
383 local int gunpipe(z_stream *strm, int infile, int outfile)
384 {
385  int ret, first, last;
386  unsigned have, flags, len;
387  z_const unsigned char *next = NULL;
388  struct ind ind, *indp;
389  struct outd outd;
390 
391  /* setup input buffer */
392  ind.infile = infile;
393  ind.inbuf = inbuf;
394  indp = &ind;
395 
396  /* decompress concatenated gzip streams */
397  have = 0; /* no input data read in yet */
398  first = 1; /* looking for first gzip header */
399  strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */
400  for (;;) {
401  /* look for the two magic header bytes for a gzip stream */
402  if (NEXT() == -1) {
403  ret = Z_OK;
404  break; /* empty gzip stream is ok */
405  }
406  if (last != 31 || (NEXT() != 139 && last != 157)) {
407  strm->msg = (char *)"incorrect header check";
408  ret = first ? Z_DATA_ERROR : Z_ERRNO;
409  break; /* not a gzip or compress header */
410  }
411  first = 0; /* next non-header is junk */
412 
413  /* process a compress (LZW) file -- can't be concatenated after this */
414  if (last == 157) {
415  ret = lunpipe(have, next, indp, outfile, strm);
416  break;
417  }
418 
419  /* process remainder of gzip header */
420  ret = Z_BUF_ERROR;
421  if (NEXT() != 8) { /* only deflate method allowed */
422  if (last == -1) break;
423  strm->msg = (char *)"unknown compression method";
424  ret = Z_DATA_ERROR;
425  break;
426  }
427  flags = NEXT(); /* header flags */
428  NEXT(); /* discard mod time, xflgs, os */
429  NEXT();
430  NEXT();
431  NEXT();
432  NEXT();
433  NEXT();
434  if (last == -1) break;
435  if (flags & 0xe0) {
436  strm->msg = (char *)"unknown header flags set";
437  ret = Z_DATA_ERROR;
438  break;
439  }
440  if (flags & 4) { /* extra field */
441  len = NEXT();
442  len += (unsigned)(NEXT()) << 8;
443  if (last == -1) break;
444  while (len > have) {
445  len -= have;
446  have = 0;
447  if (NEXT() == -1) break;
448  len--;
449  }
450  if (last == -1) break;
451  have -= len;
452  next += len;
453  }
454  if (flags & 8) /* file name */
455  while (NEXT() != 0 && last != -1)
456  ;
457  if (flags & 16) /* comment */
458  while (NEXT() != 0 && last != -1)
459  ;
460  if (flags & 2) { /* header crc */
461  NEXT();
462  NEXT();
463  }
464  if (last == -1) break;
465 
466  /* set up output */
467  outd.outfile = outfile;
468  outd.check = 1;
469  outd.crc = crc32(0L, Z_NULL, 0);
470  outd.total = 0;
471 
472  /* decompress data to output */
473  strm->next_in = next;
474  strm->avail_in = have;
475  ret = inflateBack(strm, in, indp, out, &outd);
476  if (ret != Z_STREAM_END) break;
477  next = strm->next_in;
478  have = strm->avail_in;
479  strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */
480 
481  /* check trailer */
482  ret = Z_BUF_ERROR;
483  if (NEXT() != (int)(outd.crc & 0xff) ||
484  NEXT() != (int)((outd.crc >> 8) & 0xff) ||
485  NEXT() != (int)((outd.crc >> 16) & 0xff) ||
486  NEXT() != (int)((outd.crc >> 24) & 0xff)) {
487  /* crc error */
488  if (last != -1) {
489  strm->msg = (char *)"incorrect data check";
490  ret = Z_DATA_ERROR;
491  }
492  break;
493  }
494  if (NEXT() != (int)(outd.total & 0xff) ||
495  NEXT() != (int)((outd.total >> 8) & 0xff) ||
496  NEXT() != (int)((outd.total >> 16) & 0xff) ||
497  NEXT() != (int)((outd.total >> 24) & 0xff)) {
498  /* length error */
499  if (last != -1) {
500  strm->msg = (char *)"incorrect length check";
501  ret = Z_DATA_ERROR;
502  }
503  break;
504  }
505 
506  /* go back and look for another gzip stream */
507  }
508 
509  /* clean up and return */
510  return ret;
511 }
512 
513 /* Copy file attributes, from -> to, as best we can. This is best effort, so
514  no errors are reported. The mode bits, including suid, sgid, and the sticky
515  bit are copied (if allowed), the owner's user id and group id are copied
516  (again if allowed), and the access and modify times are copied. */
517 local void copymeta(char *from, char *to)
518 {
519  struct stat was;
520  struct utimbuf when;
521 
522  /* get all of from's Unix meta data, return if not a regular file */
523  if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG)
524  return;
525 
526  /* set to's mode bits, ignore errors */
527  (void)chmod(to, was.st_mode & 07777);
528 
529  /* copy owner's user and group, ignore errors */
530  (void)chown(to, was.st_uid, was.st_gid);
531 
532  /* copy access and modify times, ignore errors */
533  when.actime = was.st_atime;
534  when.modtime = was.st_mtime;
535  (void)utime(to, &when);
536 }
537 
538 /* Decompress the file inname to the file outnname, of if test is true, just
539  decompress without writing and check the gzip trailer for integrity. If
540  inname is NULL or an empty string, read from stdin. If outname is NULL or
541  an empty string, write to stdout. strm is a pre-initialized inflateBack
542  structure. When appropriate, copy the file attributes from inname to
543  outname.
544 
545  gunzip() returns 1 if there is an out-of-memory error or an unexpected
546  return code from gunpipe(). Otherwise it returns 0.
547  */
548 local int gunzip(z_stream *strm, char *inname, char *outname, int test)
549 {
550  int ret;
551  int infile, outfile;
552 
553  /* open files */
554  if (inname == NULL || *inname == 0) {
555  inname = "-";
556  infile = 0; /* stdin */
557  }
558  else {
559  infile = open(inname, O_RDONLY, 0);
560  if (infile == -1) {
561  fprintf(stderr, "gun cannot open %s\n", inname);
562  return 0;
563  }
564  }
565  if (test)
566  outfile = -1;
567  else if (outname == NULL || *outname == 0) {
568  outname = "-";
569  outfile = 1; /* stdout */
570  }
571  else {
572  outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666);
573  if (outfile == -1) {
574  close(infile);
575  fprintf(stderr, "gun cannot create %s\n", outname);
576  return 0;
577  }
578  }
579  errno = 0;
580 
581  /* decompress */
582  ret = gunpipe(strm, infile, outfile);
583  if (outfile > 2) close(outfile);
584  if (infile > 2) close(infile);
585 
586  /* interpret result */
587  switch (ret) {
588  case Z_OK:
589  case Z_ERRNO:
590  if (infile > 2 && outfile > 2) {
591  copymeta(inname, outname); /* copy attributes */
592  unlink(inname);
593  }
594  if (ret == Z_ERRNO)
595  fprintf(stderr, "gun warning: trailing garbage ignored in %s\n",
596  inname);
597  break;
598  case Z_DATA_ERROR:
599  if (outfile > 2) unlink(outname);
600  fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg);
601  break;
602  case Z_MEM_ERROR:
603  if (outfile > 2) unlink(outname);
604  fprintf(stderr, "gun out of memory error--aborting\n");
605  return 1;
606  case Z_BUF_ERROR:
607  if (outfile > 2) unlink(outname);
608  if (strm->next_in != Z_NULL) {
609  fprintf(stderr, "gun write error on %s: %s\n",
610  outname, strerror(errno));
611  }
612  else if (errno) {
613  fprintf(stderr, "gun read error on %s: %s\n",
614  inname, strerror(errno));
615  }
616  else {
617  fprintf(stderr, "gun unexpected end of file on %s\n",
618  inname);
619  }
620  break;
621  default:
622  if (outfile > 2) unlink(outname);
623  fprintf(stderr, "gun internal error--aborting\n");
624  return 1;
625  }
626  return 0;
627 }
628 
629 /* Process the gun command line arguments. See the command syntax near the
630  beginning of this source file. */
631 int main(int argc, char **argv)
632 {
633  int ret, len, test;
634  char *outname;
635  unsigned char *window;
636  z_stream strm;
637 
638  /* initialize inflateBack state for repeated use */
639  window = match; /* reuse LZW match buffer */
640  strm.zalloc = Z_NULL;
641  strm.zfree = Z_NULL;
642  strm.opaque = Z_NULL;
643  ret = inflateBackInit(&strm, 15, window);
644  if (ret != Z_OK) {
645  fprintf(stderr, "gun out of memory error--aborting\n");
646  return 1;
647  }
648 
649  /* decompress each file to the same name with the suffix removed */
650  argc--;
651  argv++;
652  test = 0;
653  if (argc && strcmp(*argv, "-h") == 0) {
654  fprintf(stderr, "gun 1.6 (17 Jan 2010)\n");
655  fprintf(stderr, "Copyright (C) 2003-2010 Mark Adler\n");
656  fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n");
657  return 0;
658  }
659  if (argc && strcmp(*argv, "-t") == 0) {
660  test = 1;
661  argc--;
662  argv++;
663  }
664  if (argc)
665  do {
666  if (test)
667  outname = NULL;
668  else {
669  len = (int)strlen(*argv);
670  if (strcmp(*argv + len - 3, ".gz") == 0 ||
671  strcmp(*argv + len - 3, "-gz") == 0)
672  len -= 3;
673  else if (strcmp(*argv + len - 2, ".z") == 0 ||
674  strcmp(*argv + len - 2, "-z") == 0 ||
675  strcmp(*argv + len - 2, "_z") == 0 ||
676  strcmp(*argv + len - 2, ".Z") == 0)
677  len -= 2;
678  else {
679  fprintf(stderr, "gun error: no gz type on %s--skipping\n",
680  *argv);
681  continue;
682  }
683  outname = malloc(len + 1);
684  if (outname == NULL) {
685  fprintf(stderr, "gun out of memory error--aborting\n");
686  ret = 1;
687  break;
688  }
689  memcpy(outname, *argv, len);
690  outname[len] = 0;
691  }
692  ret = gunzip(&strm, *argv, outname, test);
693  if (outname != NULL) free(outname);
694  if (ret) break;
695  } while (argv++, --argc);
696  else
697  ret = gunzip(&strm, NULL, NULL, test);
698 
699  /* clean up */
700  inflateBackEnd(&strm);
701  return ret;
702 }
unsigned char match[65280+2]
Definition: gun.c:165
unsigned char outbuf[SIZE]
Definition: gun.c:162
GLfloat GLfloat p
local unsigned in(void *in_desc, z_const unsigned char **buf)
Definition: gun.c:89
Bytef * next_in
Definition: zlib.h:69
int write(int fd, const char *buf, int nbytes)
Definition: tif_acorn.c:325
int read(int fd, char *buf, int nbytes)
Definition: tif_acorn.c:331
#define NULL
Definition: ftobjs.h:61
int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc)
Definition: infback.c:250
uInt avail_in
Definition: zlib.h:70
char * malloc()
char * msg
Definition: zlib.h:77
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
#define bits
Definition: infblock.c:15
unsigned short prefix[65536]
Definition: gun.c:163
#define Z_BUF_ERROR
Definition: zlib.h:139
voidpf opaque
Definition: zlib.h:82
#define inflateBackInit(strm, windowBits, window)
Definition: zlib.h:1657
GLenum GLuint GLenum GLsizei const GLchar * buf
free_func zfree
Definition: zlib.h:81
#define FLUSHCODE()
Definition: gun.c:171
#define Z_OK
Definition: zlib.h:132
#define NEXT()
Definition: gun.c:155
#define z_const
Definition: zconf.h:224
FILE * outfile
Definition: jpeglib.h:910
GLenum GLint GLuint mask
GLenum GLsizei len
#define Z_MEM_ERROR
Definition: zlib.h:138
GLint left
local int gunzip(z_stream *strm, char *inname, char *outname, int test)
Definition: gun.c:548
local int out(void *out_desc, unsigned char *buf, unsigned len)
Definition: gun.c:131
GLbitfield flags
unsigned char inbuf[SIZE]
Definition: gun.c:161
int close(int fd)
Definition: tif_acorn.c:320
#define local
Definition: gun.c:73
#define Z_NULL
Definition: zlib.h:164
alloc_func zalloc
Definition: zlib.h:80
int free()
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
Definition: crc32.c:204
int ZEXPORT inflateBackEnd(z_streamp strm)
Definition: infback.c:631
const GLint * first
unsigned char suffix[65536]
Definition: gun.c:164
local void copymeta(char *from, char *to)
Definition: gun.c:517
GLuint GLuint end
local int max
Definition: enough.c:170
typedef int
Definition: png.h:978
int main(int argc, char **argv)
Definition: gun.c:631
FILE * infile
Definition: cdjpeg.h:141
int open(const char *name, int flags, int mode)
Definition: tif_acorn.c:285
GLuint in
#define PIECE
Definition: gun.c:77
png_infop int chunk
Definition: png.h:2339
#define SIZE
Definition: gun.c:76
local int * code
Definition: enough.c:174
#define Z_DATA_ERROR
Definition: zlib.h:137
local int lunpipe(unsigned have, z_const unsigned char *next, struct ind *indp, int outfile, z_stream *strm)
Definition: gun.c:200
local int gunpipe(z_stream *strm, int infile, int outfile)
Definition: gun.c:383
#define Z_ERRNO
Definition: zlib.h:135
#define Z_STREAM_END
Definition: zlib.h:133