annotate src/zlib-1.2.7/test/minigzip.c @ 23:619f715526df sv_v2.1

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