zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
minigzip.c
Go to the documentation of this file.
1 /* minigzip.c -- simulate gzip using the zlib compression library
2  * Copyright (C) 1995-2006, 2010 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 
76 static 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 
115 static 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 char *prog;
142 
143 void error OF((const char *msg));
144 void gz_compress OF((FILE *in, gzFile out));
145 #ifdef USE_MMAP
146 int gz_compress_mmap OF((FILE *in, gzFile out));
147 #endif
148 void gz_uncompress OF((gzFile in, FILE *out));
149 void file_compress OF((char *file, char *mode));
150 void file_uncompress OF((char *file));
151 int main OF((int argc, char *argv[]));
152 
153 /* ===========================================================================
154  * Display error message and exit
155  */
156 void error(msg)
157  const char *msg;
158 {
159  fprintf(stderr, "%s: %s\n", prog, msg);
160  exit(1);
161 }
162 
163 /* ===========================================================================
164  * Compress input to output then close both files.
165  */
166 
167 void gz_compress(in, out)
168  FILE *in;
169  gzFile out;
170 {
171  local char buf[BUFLEN];
172  int len;
173  int err;
174 
175 #ifdef USE_MMAP
176  /* Try first compressing with mmap. If mmap fails (minigzip used in a
177  * pipe), use the normal fread loop.
178  */
179  if (gz_compress_mmap(in, out) == Z_OK) return;
180 #endif
181  for (;;) {
182  len = (int)fread(buf, 1, sizeof(buf), in);
183  if (ferror(in)) {
184  perror("fread");
185  exit(1);
186  }
187  if (len == 0) break;
188 
189  if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
190  }
191  fclose(in);
192  if (gzclose(out) != Z_OK) error("failed gzclose");
193 }
194 
195 #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
196 
197 /* Try compressing the input file at once using mmap. Return Z_OK if
198  * if success, Z_ERRNO otherwise.
199  */
200 int gz_compress_mmap(in, out)
201  FILE *in;
202  gzFile out;
203 {
204  int len;
205  int err;
206  int ifd = fileno(in);
207  caddr_t buf; /* mmap'ed buffer for the entire input file */
208  off_t buf_len; /* length of the input file */
209  struct stat sb;
210 
211  /* Determine the size of the file, needed for mmap: */
212  if (fstat(ifd, &sb) < 0) return Z_ERRNO;
213  buf_len = sb.st_size;
214  if (buf_len <= 0) return Z_ERRNO;
215 
216  /* Now do the actual mmap: */
217  buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
218  if (buf == (caddr_t)(-1)) return Z_ERRNO;
219 
220  /* Compress the whole file at once: */
221  len = gzwrite(out, (char *)buf, (unsigned)buf_len);
222 
223  if (len != (int)buf_len) error(gzerror(out, &err));
224 
225  munmap(buf, buf_len);
226  fclose(in);
227  if (gzclose(out) != Z_OK) error("failed gzclose");
228  return Z_OK;
229 }
230 #endif /* USE_MMAP */
231 
232 /* ===========================================================================
233  * Uncompress input to output then close both files.
234  */
235 void gz_uncompress(in, out)
236  gzFile in;
237  FILE *out;
238 {
239  local char buf[BUFLEN];
240  int len;
241  int err;
242 
243  for (;;) {
244  len = gzread(in, buf, sizeof(buf));
245  if (len < 0) error (gzerror(in, &err));
246  if (len == 0) break;
247 
248  if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
249  error("failed fwrite");
250  }
251  }
252  if (fclose(out)) error("failed fclose");
253 
254  if (gzclose(in) != Z_OK) error("failed gzclose");
255 }
256 
257 
258 /* ===========================================================================
259  * Compress the given file: create a corresponding .gz file and remove the
260  * original.
261  */
263  char *file;
264  char *mode;
265 {
266  local char outfile[MAX_NAME_LEN];
267  FILE *in;
268  gzFile out;
269 
270  if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
271  fprintf(stderr, "%s: filename too long\n", prog);
272  exit(1);
273  }
274 
275  strcpy(outfile, file);
276  strcat(outfile, GZ_SUFFIX);
277 
278  in = fopen(file, "rb");
279  if (in == NULL) {
280  perror(file);
281  exit(1);
282  }
283  out = gzopen(outfile, mode);
284  if (out == NULL) {
285  fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
286  exit(1);
287  }
288  gz_compress(in, out);
289 
290  unlink(file);
291 }
292 
293 
294 /* ===========================================================================
295  * Uncompress the given file and remove the original.
296  */
298  char *file;
299 {
300  local char buf[MAX_NAME_LEN];
301  char *infile, *outfile;
302  FILE *out;
303  gzFile in;
304  size_t len = strlen(file);
305 
306  if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
307  fprintf(stderr, "%s: filename too long\n", prog);
308  exit(1);
309  }
310 
311  strcpy(buf, file);
312 
313  if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
314  infile = file;
315  outfile = buf;
316  outfile[len-3] = '\0';
317  } else {
318  outfile = file;
319  infile = buf;
320  strcat(infile, GZ_SUFFIX);
321  }
322  in = gzopen(infile, "rb");
323  if (in == NULL) {
324  fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
325  exit(1);
326  }
327  out = fopen(outfile, "wb");
328  if (out == NULL) {
329  perror(file);
330  exit(1);
331  }
332 
333  gz_uncompress(in, out);
334 
335  unlink(infile);
336 }
337 
338 
339 /* ===========================================================================
340  * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
341  * -c : write to standard output
342  * -d : decompress
343  * -f : compress with Z_FILTERED
344  * -h : compress with Z_HUFFMAN_ONLY
345  * -r : compress with Z_RLE
346  * -1 to -9 : compression level
347  */
348 
349 int main(argc, argv)
350  int argc;
351  char *argv[];
352 {
353  int copyout = 0;
354  int uncompr = 0;
355  gzFile file;
356  char *bname, outmode[20];
357 
358  strcpy(outmode, "wb6 ");
359 
360  prog = argv[0];
361  bname = strrchr(argv[0], '/');
362  if (bname)
363  bname++;
364  else
365  bname = argv[0];
366  argc--, argv++;
367 
368  if (!strcmp(bname, "gunzip"))
369  uncompr = 1;
370  else if (!strcmp(bname, "zcat"))
371  copyout = uncompr = 1;
372 
373  while (argc > 0) {
374  if (strcmp(*argv, "-c") == 0)
375  copyout = 1;
376  else if (strcmp(*argv, "-d") == 0)
377  uncompr = 1;
378  else if (strcmp(*argv, "-f") == 0)
379  outmode[3] = 'f';
380  else if (strcmp(*argv, "-h") == 0)
381  outmode[3] = 'h';
382  else if (strcmp(*argv, "-r") == 0)
383  outmode[3] = 'R';
384  else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
385  (*argv)[2] == 0)
386  outmode[2] = (*argv)[1];
387  else
388  break;
389  argc--, argv++;
390  }
391  if (outmode[3] == ' ')
392  outmode[3] = 0;
393  if (argc == 0) {
394  SET_BINARY_MODE(stdin);
395  SET_BINARY_MODE(stdout);
396  if (uncompr) {
397  file = gzdopen(fileno(stdin), "rb");
398  if (file == NULL) error("can't gzdopen stdin");
399  gz_uncompress(file, stdout);
400  } else {
401  file = gzdopen(fileno(stdout), outmode);
402  if (file == NULL) error("can't gzdopen stdout");
403  gz_compress(stdin, file);
404  }
405  } else {
406  if (copyout) {
407  SET_BINARY_MODE(stdout);
408  }
409  do {
410  if (uncompr) {
411  if (copyout) {
412  file = gzopen(*argv, "rb");
413  if (file == NULL)
414  fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
415  else
416  gz_uncompress(file, stdout);
417  } else {
418  file_uncompress(*argv);
419  }
420  } else {
421  if (copyout) {
422  FILE * in = fopen(*argv, "rb");
423 
424  if (in == NULL) {
425  perror(*argv);
426  } else {
427  file = gzdopen(fileno(stdout), outmode);
428  if (file == NULL) error("can't gzdopen stdout");
429 
430  gz_compress(in, file);
431  }
432 
433  } else {
434  file_compress(*argv, outmode);
435  }
436  }
437  } while (argv++, --argc);
438  }
439  return 0;
440 }
voidp gzFile
Definition: zlib.h:1165
#define local
Definition: minigzip.c:138
GLdouble s
Definition: glew.h:1376
int main(int argc, char **argv)
Definition: bootstrap.cpp:102
#define NULL
Definition: ftobjs.h:61
gzFile ZEXPORT gzdopen(int fd, const char *mode)
Definition: gzio.c:219
int ZEXPORT gzclose(gzFile file)
Definition: gzclose.c:11
GLuint in
Definition: glew.h:10672
FILE * file
Definition: visualinfo.c:88
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len)
Definition: gzio.c:394
int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len)
Definition: gzio.c:559
GLenum GLsizei len
Definition: glew.h:7035
#define Z_ERRNO
Definition: zlib.h:135
#define Z_OK
Definition: zlib.h:132
gzFile ZEXPORT gzopen(char *path, const char *mode) const
Definition: gzio.c:208
char * prog
Definition: minigzip.c:141
#define MAX_NAME_LEN
Definition: minigzip.c:132
void file_compress(char *file, char *mode)
Definition: minigzip.c:262
#define SET_BINARY_MODE(file)
Definition: minigzip.c:40
int
Definition: SDL_systhread.c:37
FT_Error error
Definition: cffdrivr.c:407
const char *ZEXPORT gzerror(gzFile file, int *errnum)
Definition: gzio.c:987
void file_uncompress(char *file)
Definition: minigzip.c:297
#define GZ_SUFFIX
Definition: minigzip.c:127
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
#define OF(args)
Definition: zconf.h:146
#define const
Definition: zconf.h:91
GLenum GLuint GLsizei const GLchar * buf
Definition: glew.h:2539
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
void gz_compress(FILE *in, gzFile out)
Definition: minigzip.c:167
void gz_uncompress(gzFile in, FILE *out)
Definition: minigzip.c:235
#define BUFLEN
Definition: minigzip.c:131
GLenum mode
Definition: glew.h:2394
#define SUFFIX_LEN
Definition: minigzip.c:129