/* * lzdcmp [-options] [infile [outfile]] */ #ifdef DOCUMENTATION title lzdcmp File Decompression index File decompression synopsis .s.nf lzdcmp [-options] [infile [outfile]] .s.f description lzdcmp decompresses files compressed by lzcomp. The documentation for lzcomp describes the process in greater detail. Options may be given in either case. .lm +8 .p -8 -B Output file is "binary", not text. .p -8 -N Don't read magic header (for reading old files) .p -8 -Q Quiet -- don't write status messages. .p -8 -D val Debug (if compiled in), val is debug level. -V Verbose dump (of string tables, debug must == 0) Author This version by Martin Minow. See lzcomp for more details. #endif /* * Compatible with compress.c, v3.0 84/11/27 */ /*)BUILD * $(PROGRAM) = lzdcmp * $(INCLUDE) = lz.h * $(FILES) = { lzdcm1.c lzdcm2.c lzio.c } */ #include "lz.h" #ifdef DEBUG # ifdef unix # include # include # else # include # endif static struct timeb start_time; static struct timeb end_time; #endif /* * These global parameters are read from the compressed file. * The decompressor needs them. */ short maxbits = BITS; /* settable max # bits/code */ short block_compress = BLOCK_MASK; code_int maxmaxcode = 1 << BITS; flag binary = FALSE; /* Read text if false */ flag nomagic = FALSE; /* No magic header if TRUE */ flag quiet = FALSE; /* don't talk about compression */ #ifdef DEBUG flag debug = 0; flag verbose = FALSE; /* Dump string tables */ #endif static char_type magic_header[] = /* First 2 bytes of compressed */ { HEAD1_MAGIC, HEAD2_MAGIC, 0 }; /* data file. */ char *infilename = NULL; /* For error printouts */ char *outfilename = NULL; /* For openoutput and errors */ main(argc, argv) int argc; char *argv[]; /* * Decompress mainline */ { #ifdef DEBUG int msec; #endif setup(argc, argv); if (maxbits < INIT_BITS) maxbits = INIT_BITS; if (maxbits > BITS) maxbits = BITS; maxmaxcode = 1 << maxbits; if (nomagic == FALSE) { if (GET() != (magic_header[0] & 0xFF) || GET() != (magic_header[1] & 0xFF)) { fprintf(stderr, "%s: not in compressed format\n", infilename); exit(IO_ERROR); } else { if ((maxbits = GET()) == -1) { perror(infilename); /* Early eof */ exit(IO_ERROR); } block_compress = maxbits & BLOCK_MASK; maxbits &= BIT_MASK; maxmaxcode = 1 << maxbits; if (maxbits > BITS) { fprintf(stderr, "%s: compressed with %d bits,", infilename, maxbits); fprintf(stderr, " can only handle %d bits\n", BITS); exit(IO_ERROR); } #ifdef DEBUG fprintf(stderr, "%s: compressed with %d bits,", infilename, maxbits); fprintf(stderr, " block compression %s.\n", (block_compress != 0) ? "enabled" : "disabled"); #endif } } openoutput(); #ifndef DEBUG decompress(); #else if (debug == 0) { ftime(&start_time); decompress(); if (!quiet) { ftime(&end_time); end_time.time -= start_time.time; msec = end_time.millitm - start_time.millitm; if (msec < 0) { msec += 1000; end_time.time--; } fprintf(stderr, "%ld.%03d seconds for decompression\n", end_time.time, msec); } } else { printcodes(stdout); } if (verbose) dump_tab(stdout); #endif exit(IO_SUCCESS); } static setup(argc, argv) int argc; char *argv[]; /* * Get parameters and open files. Exit fatally on errors. */ { register char *ap; register int c; int i, j; char *arg; #ifndef unix char filename[80]; #endif #ifdef vms argc = getredirection(argc, argv); #endif for (i = j = 1; i < argc; i++) { arg = ap = argv[i]; if (*ap++ != '-' || *ap == EOS) /* Filename? */ argv[j++] = argv[i]; /* Just copy it */ else { c = *ap++; /* Option byte */ if (islower(c)) c = toupper(c); switch (c) { case 'B': binary = TRUE; break; case 'N': nomagic = TRUE; break; case 'Q': quiet = TRUE; break; #ifdef DEBUG case 'D': if (isdigit(*ap)) { debug = atoi(ap); continue; } debug = 1; break; case 'V': verbose = TRUE; break; #endif default: fprintf(stderr, "Unknown option \"%s\"\n", arg); fprintf(stderr, "The following options are valid:\n\ -B\tBinary file (important on VMS/RSX, ignored on Unix)\n\ -N\tDon't look for header code\n\ -Q\tNo output to stderr, unless error.\n"); #ifdef DEBUG fprintf(stderr, "-Dn\tDebug (n = level)\n"); fprintf(stderr, "-V\tVerbose printouts\n"); #endif exit(IO_ERROR); } /* Switch on options */ } /* If -option */ } /* outfilename = NULL; */ /* Openoutput signal */ switch (j) { /* Any file arguments? */ case 3: /* both files given */ if (!streq(argv[2], "-")) outfilename = argv[2]; case 2: /* Input file given */ if (!streq(argv[1], "-")) { #ifdef decus if (freopen(argv[1], "rn", stdin) == NULL) { perror(argv[2]); exit(IO_ERROR); } #else /* * Special case for vms too? */ if (freopen(argv[1], "r", stdin) == NULL) { perror(argv[2]); exit(IO_ERROR); } #endif infilename = argv[1]; } break; case 0: /* None! */ case 1: /* No file arguments */ #ifdef vms fgetname(stdin, filename); infilename = malloc(strlen(filename) + 1); strcpy(infilename, filename); #else #ifdef decus fgetname(stdin, filename); infilename = malloc(strlen(filename) + 1); strcpy(infilename, filename); #else infilename = "stdin"; #endif #endif break; default: fprintf(stderr, "Too many file arguments\n"); exit(IO_ERROR); } } openoutput() { #ifndef unix char filename[80]; #endif if (outfilename == NULL) { #ifdef vms fgetname(stdout, filename); outfilename = malloc(strlen(filename) + 1); strcpy(outfilename, filename); #else #ifdef decus fgetname(stdout, filename); outfilename = malloc(strlen(filename) + 1); strcpy(outfilename, filename); #else outfilename = ""; #endif #endif } else { #ifdef vms if (binary) { if (freopen(outfilename, "w", stdout) == NULL) { perror(outfilename); exit(IO_ERROR); } } else { int i; if ((i = creat(outfilename, 0, "rat=cr", "rfm=var")) == -1 || dup2(i, fileno(stdout)) == -1) { perror(outfilename); exit(IO_ERROR); } } #else #ifdef decus if (freopen(outfilename, (binary) ? "wn" : "w", stdout) == NULL) { perror(outfilename); exit(IO_ERROR); } #else if (freopen(outfilename, "w", stdout) == NULL) { perror(outfilename); exit(IO_ERROR); } #endif #endif } }