annotate src/zlib-1.2.8/test/minigzip.c @ 83:ae30d91d2ffe

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