annotate src/zlib-1.2.7/test/minigzip.c @ 89:8a15ff55d9af

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