|
|
1.1 ! root 1: #ifdef SCCSID ! 2: static char *SccsId = "@(#)compress.c 1.14 9/24/87"; ! 3: #endif /* SCCSID */ ! 4: static char rcs_ident[] = "Based on compress.c,v 4.0 85/07/30 12:50:00 joe Release"; ! 5: ! 6: /* ! 7: * Compress - data compression program ! 8: */ ! 9: #define min(a,b) ((a>b) ? b : a) ! 10: ! 11: /* ! 12: * machine variants which require cc -Dmachine: pdp11, z8000, pcxt ! 13: */ ! 14: ! 15: /* ! 16: * Set USERMEM to the maximum amount of physical user memory available ! 17: * in bytes. USERMEM is used to determine the maximum BITS that can be used ! 18: * for compression. ! 19: * ! 20: * SACREDMEM is the amount of physical memory saved for others; compress ! 21: * will hog the rest. ! 22: */ ! 23: #ifndef SACREDMEM ! 24: #define SACREDMEM 0 ! 25: #endif ! 26: ! 27: #ifndef USERMEM ! 28: # define USERMEM 450000 /* default user memory */ ! 29: #endif ! 30: ! 31: #ifdef interdata /* (Perkin-Elmer) */ ! 32: #define SIGNED_COMPARE_SLOW /* signed compare is slower than unsigned */ ! 33: #endif ! 34: ! 35: #ifdef pdp11 ! 36: # define BITS 12 /* max bits/code for 16-bit machine */ ! 37: # define NO_UCHAR /* also if "unsigned char" functions as signed char */ ! 38: # undef USERMEM ! 39: #endif /* pdp11 */ /* don't forget to compile with -i */ ! 40: ! 41: #ifdef z8000 ! 42: # define BITS 12 ! 43: # undef vax /* weird preprocessor */ ! 44: # undef USERMEM ! 45: #endif /* z8000 */ ! 46: ! 47: #ifdef pcxt ! 48: # define BITS 12 ! 49: # undef USERMEM ! 50: #endif /* pcxt */ ! 51: ! 52: #ifdef USERMEM ! 53: # if USERMEM >= (433484+SACREDMEM) ! 54: # define PBITS 16 ! 55: # else ! 56: # if USERMEM >= (229600+SACREDMEM) ! 57: # define PBITS 15 ! 58: # else ! 59: # if USERMEM >= (127536+SACREDMEM) ! 60: # define PBITS 14 ! 61: # else ! 62: # if USERMEM >= (73464+SACREDMEM) ! 63: # define PBITS 13 ! 64: # else ! 65: # define PBITS 12 ! 66: # endif ! 67: # endif ! 68: # endif ! 69: # endif ! 70: # undef USERMEM ! 71: #endif /* USERMEM */ ! 72: ! 73: #ifdef PBITS /* Preferred BITS for this memory size */ ! 74: # ifndef BITS ! 75: # define BITS PBITS ! 76: # endif /* BITS */ ! 77: #endif /* PBITS */ ! 78: ! 79: #if BITS == 16 ! 80: # define HSIZE 69001 /* 95% occupancy */ ! 81: #endif ! 82: #if BITS == 15 ! 83: # define HSIZE 35023 /* 94% occupancy */ ! 84: #endif ! 85: #if BITS == 14 ! 86: # define HSIZE 18013 /* 91% occupancy */ ! 87: #endif ! 88: #if BITS == 13 ! 89: # define HSIZE 9001 /* 91% occupancy */ ! 90: #endif ! 91: #if BITS <= 12 ! 92: # define HSIZE 5003 /* 80% occupancy */ ! 93: #endif ! 94: ! 95: #ifdef M_XENIX /* Stupid compiler can't handle arrays with */ ! 96: # if BITS == 16 /* more than 65535 bytes - so we fake it */ ! 97: # define XENIX_16 ! 98: # else ! 99: # if BITS > 13 /* Code only handles BITS = 12, 13, or 16 */ ! 100: # define BITS 13 ! 101: # endif ! 102: # endif ! 103: #endif ! 104: ! 105: /* ! 106: * a code_int must be able to hold 2**BITS values of type int, and also -1 ! 107: */ ! 108: #if BITS > 15 ! 109: typedef long int code_int; ! 110: #else ! 111: typedef int code_int; ! 112: #endif ! 113: ! 114: #ifdef SIGNED_COMPARE_SLOW ! 115: typedef unsigned long int count_int; ! 116: typedef unsigned short int count_short; ! 117: #else ! 118: typedef long int count_int; ! 119: #endif ! 120: ! 121: #ifdef NO_UCHAR ! 122: typedef char char_type; ! 123: #else ! 124: typedef unsigned char char_type; ! 125: #endif /* UCHAR */ ! 126: char_type magic_header[] = { "\037\235" }; /* 1F 9D */ ! 127: ! 128: /* Defines for third byte of header */ ! 129: #define BIT_MASK 0x1f ! 130: #define BLOCK_MASK 0x80 ! 131: /* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is ! 132: a fourth header byte (for expansion). ! 133: */ ! 134: #define INIT_BITS 9 /* initial number of bits/code */ ! 135: ! 136: /* ! 137: * compress.c - File compression ala IEEE Computer, June 1984. ! 138: * ! 139: * Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) ! 140: * Jim McKie (decvax!mcvax!jim) ! 141: * Steve Davies (decvax!vax135!petsd!peora!srd) ! 142: * Ken Turkowski (decvax!decwrl!turtlevax!ken) ! 143: * James A. Woods (decvax!ihnp4!ames!jaw) ! 144: * Joe Orost (decvax!vax135!petsd!joe) ! 145: * ! 146: */ ! 147: ! 148: #include <stdio.h> ! 149: #include <ctype.h> ! 150: #include <signal.h> ! 151: #include <sys/types.h> ! 152: #include <sys/stat.h> ! 153: ! 154: #define ARGVAL() (*++(*argv) || (--argc && *++argv)) ! 155: ! 156: int n_bits; /* number of bits/code */ ! 157: int maxbits = BITS; /* user settable max # bits/code */ ! 158: code_int maxcode; /* maximum code, given n_bits */ ! 159: code_int maxmaxcode = 1L << BITS; /* should NEVER generate this code */ ! 160: #ifdef COMPATIBLE /* But wrong! */ ! 161: # define MAXCODE(n_bits) (1L << (n_bits) - 1) ! 162: #else ! 163: # define MAXCODE(n_bits) ((1L << (n_bits)) - 1) ! 164: #endif /* COMPATIBLE */ ! 165: ! 166: #ifdef XENIX_16 ! 167: count_int htab0[8192]; ! 168: count_int htab1[8192]; ! 169: count_int htab2[8192]; ! 170: count_int htab3[8192]; ! 171: count_int htab4[8192]; ! 172: count_int htab5[8192]; ! 173: count_int htab6[8192]; ! 174: count_int htab7[8192]; ! 175: count_int htab8[HSIZE-65536]; ! 176: count_int * htab[9] = { ! 177: htab0, htab1, htab2, htab3, htab4, htab5, htab6, htab7, htab8 }; ! 178: ! 179: #define htabof(i) (htab[(i) >> 13][(i) & 0x1fff]) ! 180: unsigned short code0tab[16384]; ! 181: unsigned short code1tab[16384]; ! 182: unsigned short code2tab[16384]; ! 183: unsigned short code3tab[16384]; ! 184: unsigned short code4tab[16384]; ! 185: unsigned short * codetab[5] = { ! 186: code0tab, code1tab, code2tab, code3tab, code4tab }; ! 187: ! 188: #define codetabof(i) (codetab[(i) >> 14][(i) & 0x3fff]) ! 189: ! 190: #else /* Normal machine */ ! 191: # ifdef sel ! 192: /* support gould base register problems */ ! 193: /*NOBASE*/ ! 194: count_int htab [HSIZE]; ! 195: unsigned short codetab [HSIZE]; ! 196: /*NOBASE*/ ! 197: # else /* !gould */ ! 198: count_int htab [HSIZE]; ! 199: unsigned short codetab [HSIZE]; ! 200: # endif /* !gould */ ! 201: #define htabof(i) htab[i] ! 202: #define codetabof(i) codetab[i] ! 203: #endif /* !XENIX_16 */ ! 204: code_int hsize = HSIZE; /* for dynamic table sizing */ ! 205: count_int fsize; ! 206: ! 207: /* ! 208: * To save much memory, we overlay the table used by compress() with those ! 209: * used by decompress(). The tab_prefix table is the same size and type ! 210: * as the codetab. The tab_suffix table needs 2**BITS characters. We ! 211: * get this from the beginning of htab. The output stack uses the rest ! 212: * of htab, and contains characters. There is plenty of room for any ! 213: * possible stack (stack used to be 8000 characters). ! 214: */ ! 215: ! 216: #define tab_prefixof(i) codetabof(i) ! 217: #ifdef XENIX_16 ! 218: # define tab_suffixof(i) ((char_type *)htab[(i)>>15])[(i) & 0x7fff] ! 219: # define de_stack ((char_type *)(htab2)) ! 220: #else /* Normal machine */ ! 221: # define tab_suffixof(i) ((char_type *)(htab))[i] ! 222: # define de_stack ((char_type *)&tab_suffixof(1<<BITS)) ! 223: #endif /* XENIX_16 */ ! 224: ! 225: code_int free_ent = 0; /* first unused entry */ ! 226: int exit_stat = 0; ! 227: ! 228: code_int getcode(); ! 229: ! 230: Usage() { ! 231: #ifdef DEBUG ! 232: fprintf(stderr,"Usage: compress [-dDVfc] [-b maxbits] [file ...]\n"); ! 233: } ! 234: int debug = 0; ! 235: #else ! 236: fprintf(stderr,"Usage: compress [-dfvcV] [-b maxbits] [file ...]\n"); ! 237: } ! 238: #endif /* DEBUG */ ! 239: int nomagic = 0; /* Use a 3-byte magic number header, unless old file */ ! 240: int zcat_flg = 0; /* Write output on stdout, suppress messages */ ! 241: int quiet = 1; /* don't tell me about compression */ ! 242: ! 243: /* ! 244: * block compression parameters -- after all codes are used up, ! 245: * and compression rate changes, start over. ! 246: */ ! 247: int block_compress = BLOCK_MASK; ! 248: int clear_flg = 0; ! 249: long int ratio = 0; ! 250: #define CHECK_GAP 10000 /* ratio check interval */ ! 251: count_int checkpoint = CHECK_GAP; ! 252: /* ! 253: * the next two codes should not be changed lightly, as they must not ! 254: * lie within the contiguous general code space. ! 255: */ ! 256: #define FIRST 257 /* first free entry */ ! 257: #define CLEAR 256 /* table clear output code */ ! 258: ! 259: int force = 0; ! 260: char ofname [100]; ! 261: #ifdef DEBUG ! 262: int verbose = 0; ! 263: #endif /* DEBUG */ ! 264: int (*bgnd_flag)(); ! 265: ! 266: int do_decomp = 0; ! 267: ! 268: /***************************************************************** ! 269: * TAG( main ) ! 270: * ! 271: * Algorithm from "A Technique for High Performance Data Compression", ! 272: * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19. ! 273: * ! 274: * Usage: compress [-dfvc] [-b bits] [file ...] ! 275: * Inputs: ! 276: * -d: If given, decompression is done instead. ! 277: * ! 278: * -c: Write output on stdout, don't remove original. ! 279: * ! 280: * -b: Parameter limits the max number of bits/code. ! 281: * ! 282: * -f: Forces output file to be generated, even if one already ! 283: * exists, and even if no space is saved by compressing. ! 284: * If -f is not used, the user will be prompted if stdin is ! 285: * a tty, otherwise, the output file will not be overwritten. ! 286: * ! 287: * -v: Write compression statistics ! 288: * ! 289: * file ...: Files to be compressed. If none specified, stdin ! 290: * is used. ! 291: * Outputs: ! 292: * file.Z: Compressed form of file with same mode, owner, and utimes ! 293: * or stdout (if stdin used as input) ! 294: * ! 295: * Assumptions: ! 296: * When filenames are given, replaces with the compressed version ! 297: * (.Z suffix) only if the file decreases in size. ! 298: * Algorithm: ! 299: * Modified Lempel-Ziv method (LZW). Basically finds common ! 300: * substrings and replaces them with a variable size code. This is ! 301: * deterministic, and can be done on the fly. Thus, the decompression ! 302: * procedure needs no input table, but tracks the way the table was built. ! 303: */ ! 304: ! 305: main( argc, argv ) ! 306: register int argc; char **argv; ! 307: { ! 308: int overwrite = 0; /* Do not overwrite unless given -f flag */ ! 309: char tempname[100]; ! 310: char **filelist, **fileptr; ! 311: char *cp, *rindex(), *malloc(); ! 312: struct stat statbuf; ! 313: extern onintr(), oops(); ! 314: ! 315: ! 316: if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) { ! 317: signal ( SIGINT, onintr ); ! 318: signal ( SIGSEGV, oops ); ! 319: } ! 320: ! 321: #ifdef COMPATIBLE ! 322: nomagic = 1; /* Original didn't have a magic number */ ! 323: #endif /* COMPATIBLE */ ! 324: ! 325: filelist = fileptr = (char **)(malloc(argc * sizeof(*argv))); ! 326: *filelist = NULL; ! 327: ! 328: if((cp = rindex(argv[0], '/')) != 0) { ! 329: cp++; ! 330: } else { ! 331: cp = argv[0]; ! 332: } ! 333: if(strcmp(cp, "uncompress") == 0) { ! 334: do_decomp = 1; ! 335: } else if(strcmp(cp, "zcat") == 0) { ! 336: do_decomp = 1; ! 337: zcat_flg = 1; ! 338: } ! 339: ! 340: #ifdef BSD4_2 ! 341: /* 4.2BSD dependent - take it out if not */ ! 342: setlinebuf( stderr ); ! 343: #endif /* BSD4_2 */ ! 344: ! 345: /* Argument Processing ! 346: * All flags are optional. ! 347: * -D => debug ! 348: * -V => print Version; debug verbose ! 349: * -d => do_decomp ! 350: * -v => unquiet ! 351: * -f => force overwrite of output file ! 352: * -n => no header: useful to uncompress old files ! 353: * -b maxbits => maxbits. If -b is specified, then maxbits MUST be ! 354: * given also. ! 355: * -c => cat all output to stdout ! 356: * -C => generate output compatible with compress 2.0. ! 357: * if a string is left, must be an input filename. ! 358: */ ! 359: for (argc--, argv++; argc > 0; argc--, argv++) { ! 360: if (**argv == '-') { /* A flag argument */ ! 361: while (*++(*argv)) { /* Process all flags in this arg */ ! 362: switch (**argv) { ! 363: #ifdef DEBUG ! 364: case 'D': ! 365: debug = 1; ! 366: break; ! 367: case 'V': ! 368: verbose = 1; ! 369: version(); ! 370: break; ! 371: #else ! 372: case 'V': ! 373: version(); ! 374: break; ! 375: #endif /* DEBUG */ ! 376: case 'v': ! 377: quiet = 0; ! 378: break; ! 379: case 'd': ! 380: do_decomp = 1; ! 381: break; ! 382: case 'f': ! 383: case 'F': ! 384: overwrite = 1; ! 385: force = 1; ! 386: break; ! 387: case 'n': ! 388: nomagic = 1; ! 389: break; ! 390: case 'C': ! 391: block_compress = 0; ! 392: break; ! 393: case 'b': ! 394: if (!ARGVAL()) { ! 395: fprintf(stderr, "Missing maxbits\n"); ! 396: Usage(); ! 397: exit(1); ! 398: } ! 399: maxbits = atoi(*argv); ! 400: goto nextarg; ! 401: case 'c': ! 402: zcat_flg = 1; ! 403: break; ! 404: case 'q': ! 405: quiet = 1; ! 406: break; ! 407: #if COHERENT ! 408: case 'w': ! 409: if (!ARGVAL()) { ! 410: fprintf(stderr, "Missing filename for -w\n"); ! 411: Usage(); ! 412: exit(1); ! 413: } ! 414: goto nextarg; ! 415: #endif ! 416: default: ! 417: fprintf(stderr, "Unknown flag: '%c'; ", **argv); ! 418: Usage(); ! 419: exit(1); ! 420: } ! 421: } ! 422: } ! 423: else { /* Input file name */ ! 424: *fileptr++ = *argv; /* Build input file list */ ! 425: *fileptr = NULL; ! 426: /* process nextarg; */ ! 427: } ! 428: nextarg: continue; ! 429: } ! 430: ! 431: if(maxbits < INIT_BITS) maxbits = INIT_BITS; ! 432: if (maxbits > BITS) maxbits = BITS; ! 433: maxmaxcode = 1L << maxbits; ! 434: ! 435: if (*filelist != NULL) { ! 436: for (fileptr = filelist; *fileptr; fileptr++) { ! 437: exit_stat = 0; ! 438: if (do_decomp != 0) { /* DECOMPRESSION */ ! 439: /* Check for .Z suffix */ ! 440: if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) { ! 441: /* No .Z: tack one on */ ! 442: strcpy(tempname, *fileptr); ! 443: strcat(tempname, ".Z"); ! 444: *fileptr = tempname; ! 445: } ! 446: /* Open input file */ ! 447: if ((freopen(*fileptr, "r", stdin)) == NULL) { ! 448: perror(*fileptr); continue; ! 449: } ! 450: /* Check the magic number */ ! 451: if (nomagic == 0) { ! 452: if ((getchar() != (magic_header[0] & 0xFF)) ! 453: || (getchar() != (magic_header[1] & 0xFF))) { ! 454: fprintf(stderr, "%s: not in compressed format\n", ! 455: *fileptr); ! 456: continue; ! 457: } ! 458: maxbits = getchar(); /* set -b from file */ ! 459: block_compress = maxbits & BLOCK_MASK; ! 460: maxbits &= BIT_MASK; ! 461: maxmaxcode = 1L << maxbits; ! 462: if(maxbits > BITS) { ! 463: fprintf(stderr, ! 464: "%s: compressed with %d bits, can only handle %d bits\n", ! 465: *fileptr, maxbits, BITS); ! 466: continue; ! 467: } ! 468: } ! 469: /* Generate output filename */ ! 470: strcpy(ofname, *fileptr); ! 471: ofname[strlen(*fileptr) - 2] = '\0'; /* Strip off .Z */ ! 472: } else { /* COMPRESSION */ ! 473: if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") == 0) { ! 474: fprintf(stderr, "%s: already has .Z suffix -- no change\n", ! 475: *fileptr); ! 476: continue; ! 477: } ! 478: /* Open input file */ ! 479: if ((freopen(*fileptr, "r", stdin)) == NULL) { ! 480: perror(*fileptr); continue; ! 481: } ! 482: stat ( *fileptr, &statbuf ); ! 483: fsize = (long) statbuf.st_size; ! 484: /* ! 485: * tune hash table size for small files -- ad hoc, ! 486: * but the sizes match earlier #defines, which ! 487: * serve as upper bounds on the number of output codes. ! 488: */ ! 489: hsize = HSIZE; ! 490: if ( fsize < (1 << 12) ) ! 491: hsize = min ( 5003, HSIZE ); ! 492: else if ( fsize < (1 << 13) ) ! 493: hsize = min ( 9001, HSIZE ); ! 494: else if ( fsize < (1 << 14) ) ! 495: hsize = min ( 18013, HSIZE ); ! 496: else if ( fsize < (1 << 15) ) ! 497: hsize = min ( 35023, HSIZE ); ! 498: else if ( fsize < 47000 ) ! 499: hsize = min ( 50021, HSIZE ); ! 500: ! 501: /* Generate output filename */ ! 502: strcpy(ofname, *fileptr); ! 503: #ifndef BSD4_2 /* Short filenames */ ! 504: if ((cp=rindex(ofname,'/')) != NULL) cp++; ! 505: else cp = ofname; ! 506: if (strlen(cp) > 12) { ! 507: fprintf(stderr,"%s: filename too long to tack on .Z\n",cp); ! 508: continue; ! 509: } ! 510: #endif /* BSD4_2 Long filenames allowed */ ! 511: strcat(ofname, ".Z"); ! 512: } ! 513: /* Check for overwrite of existing file */ ! 514: if (overwrite == 0 && zcat_flg == 0) { ! 515: if (stat(ofname, &statbuf) == 0) { ! 516: char response[2]; ! 517: response[0] = 'n'; ! 518: fprintf(stderr, "%s already exists;", ofname); ! 519: if (foreground()) { ! 520: fprintf(stderr, " do you wish to overwrite %s (y or n)? ", ! 521: ofname); ! 522: fflush(stderr); ! 523: read(2, response, 2); ! 524: while (response[1] != '\n') { ! 525: if (read(2, response+1, 1) < 0) { /* Ack! */ ! 526: perror("stderr"); break; ! 527: } ! 528: } ! 529: } ! 530: if (response[0] != 'y') { ! 531: fprintf(stderr, "\tnot overwritten\n"); ! 532: continue; ! 533: } ! 534: } ! 535: } ! 536: if(zcat_flg == 0) { /* Open output file */ ! 537: if (freopen(ofname, "w", stdout) == NULL) { ! 538: perror(ofname); ! 539: continue; ! 540: } ! 541: if(!quiet) ! 542: fprintf(stderr, "%s: ", *fileptr); ! 543: } ! 544: ! 545: /* Actually do the compression/decompression */ ! 546: if (do_decomp == 0) compress(); ! 547: #ifndef DEBUG ! 548: else decompress(); ! 549: #else ! 550: else if (debug == 0) decompress(); ! 551: else printcodes(); ! 552: if (verbose) dump_tab(); ! 553: #endif /* DEBUG */ ! 554: if(zcat_flg == 0) { ! 555: copystat(*fileptr, ofname); /* Copy stats */ ! 556: if((exit_stat == 1) || (!quiet)) ! 557: putc('\n', stderr); ! 558: } ! 559: } ! 560: } else { /* Standard input */ ! 561: if (do_decomp == 0) { ! 562: compress(); ! 563: #ifdef DEBUG ! 564: if(verbose) dump_tab(); ! 565: #endif /* DEBUG */ ! 566: if(!quiet) ! 567: putc('\n', stderr); ! 568: } else { ! 569: /* Check the magic number */ ! 570: if (nomagic == 0) { ! 571: if ((getchar()!=(magic_header[0] & 0xFF)) ! 572: || (getchar()!=(magic_header[1] & 0xFF))) { ! 573: fprintf(stderr, "stdin: not in compressed format\n"); ! 574: exit(1); ! 575: } ! 576: maxbits = getchar(); /* set -b from file */ ! 577: block_compress = maxbits & BLOCK_MASK; ! 578: maxbits &= BIT_MASK; ! 579: maxmaxcode = 1L << maxbits; ! 580: fsize = 100000; /* assume stdin large for USERMEM */ ! 581: if(maxbits > BITS) { ! 582: fprintf(stderr, ! 583: "stdin: compressed with %d bits, can only handle %d bits\n", ! 584: maxbits, BITS); ! 585: exit(1); ! 586: } ! 587: } ! 588: #ifndef DEBUG ! 589: decompress(); ! 590: #else ! 591: if (debug == 0) decompress(); ! 592: else printcodes(); ! 593: if (verbose) dump_tab(); ! 594: #endif /* DEBUG */ ! 595: } ! 596: } ! 597: exit(exit_stat); ! 598: } ! 599: ! 600: static int offset; ! 601: long int in_count = 1; /* length of input */ ! 602: long int bytes_out; /* length of compressed output */ ! 603: long int out_count = 0; /* # of codes output (for debugging) */ ! 604: ! 605: /* ! 606: * compress stdin to stdout ! 607: * ! 608: * Algorithm: use open addressing double hashing (no chaining) on the ! 609: * prefix code / next character combination. We do a variant of Knuth's ! 610: * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime ! 611: * secondary probe. Here, the modular division first probe is gives way ! 612: * to a faster exclusive-or manipulation. Also do block compression with ! 613: * an adaptive reset, whereby the code table is cleared when the compression ! 614: * ratio decreases, but after the table fills. The variable-length output ! 615: * codes are re-sized at this point, and a special CLEAR code is generated ! 616: * for the decompressor. Late addition: construct the table according to ! 617: * file size for noticeable speed improvement on small files. Please direct ! 618: * questions about this implementation to ames!jaw. ! 619: */ ! 620: ! 621: compress() { ! 622: register long fcode; ! 623: register code_int i = 0; ! 624: register int c; ! 625: register code_int ent; ! 626: #ifdef XENIX_16 ! 627: register code_int disp; ! 628: #else /* Normal machine */ ! 629: register int disp; ! 630: #endif ! 631: register code_int hsize_reg; ! 632: register int hshift; ! 633: ! 634: #ifndef COMPATIBLE ! 635: if (nomagic == 0) { ! 636: putchar(magic_header[0]); putchar(magic_header[1]); ! 637: putchar((char)(maxbits | block_compress)); ! 638: if(ferror(stdout)) ! 639: writeerr(); ! 640: } ! 641: #endif /* COMPATIBLE */ ! 642: ! 643: offset = 0; ! 644: bytes_out = 3; /* includes 3-byte header mojo */ ! 645: out_count = 0; ! 646: clear_flg = 0; ! 647: ratio = 0; ! 648: in_count = 1; ! 649: checkpoint = CHECK_GAP; ! 650: maxcode = MAXCODE(n_bits = INIT_BITS); ! 651: free_ent = ((block_compress) ? FIRST : 256 ); ! 652: ! 653: ent = getchar (); ! 654: ! 655: hshift = 0; ! 656: for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L ) ! 657: hshift++; ! 658: hshift = 8 - hshift; /* set hash code range bound */ ! 659: ! 660: hsize_reg = hsize; ! 661: cl_hash( (count_int) hsize_reg); /* clear hash table */ ! 662: ! 663: #ifdef SIGNED_COMPARE_SLOW ! 664: while ( (c = getchar()) != (unsigned) EOF ) { ! 665: #else ! 666: while ( (c = getchar()) != EOF ) { ! 667: #endif ! 668: in_count++; ! 669: fcode = (long) (((long) c << maxbits) + ent); ! 670: i = (((long)c << hshift) ^ ent); /* xor hashing */ ! 671: ! 672: if ( htabof (i) == fcode ) { ! 673: ent = codetabof (i); ! 674: continue; ! 675: } else if ( (long)htabof (i) < 0 ) /* empty slot */ ! 676: goto nomatch; ! 677: disp = hsize_reg - i; /* secondary hash (after G. Knott) */ ! 678: if ( i == 0 ) ! 679: disp = 1; ! 680: probe: ! 681: if ( (i -= disp) < 0 ) ! 682: i += hsize_reg; ! 683: ! 684: if ( htabof (i) == fcode ) { ! 685: ent = codetabof (i); ! 686: continue; ! 687: } ! 688: if ( (long)htabof (i) > 0 ) ! 689: goto probe; ! 690: nomatch: ! 691: output ( (code_int) ent ); ! 692: out_count++; ! 693: ent = c; ! 694: #ifdef SIGNED_COMPARE_SLOW ! 695: if ( (unsigned) free_ent < (unsigned) maxmaxcode) { ! 696: #else ! 697: if ( free_ent < maxmaxcode ) { ! 698: #endif ! 699: codetabof (i) = free_ent++; /* code -> hashtable */ ! 700: htabof (i) = fcode; ! 701: } ! 702: else if ( (count_int)in_count >= checkpoint && block_compress ) ! 703: cl_block (); ! 704: } ! 705: /* ! 706: * Put out the final code. ! 707: */ ! 708: output( (code_int)ent ); ! 709: out_count++; ! 710: output( (code_int)-1 ); ! 711: ! 712: /* ! 713: * Print out stats on stderr ! 714: */ ! 715: if(zcat_flg == 0 && !quiet) { ! 716: #ifdef DEBUG ! 717: fprintf( stderr, ! 718: "%ld chars in, %ld codes (%ld bytes) out, compression factor: ", ! 719: in_count, out_count, bytes_out ); ! 720: prratio( stderr, in_count, bytes_out ); ! 721: fprintf( stderr, "\n"); ! 722: fprintf( stderr, "\tCompression as in compact: " ); ! 723: prratio( stderr, in_count-bytes_out, in_count ); ! 724: fprintf( stderr, "\n"); ! 725: fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n", ! 726: free_ent - 1, n_bits ); ! 727: #else /* !DEBUG */ ! 728: fprintf( stderr, "Compression: " ); ! 729: prratio( stderr, in_count-bytes_out, in_count ); ! 730: #endif /* DEBUG */ ! 731: } ! 732: if(bytes_out > in_count) /* exit(2) if no savings */ ! 733: exit_stat = 2; ! 734: return; ! 735: } ! 736: ! 737: /***************************************************************** ! 738: * TAG( output ) ! 739: * ! 740: * Output the given code. ! 741: * Inputs: ! 742: * code: A n_bits-bit integer. If == -1, then EOF. This assumes ! 743: * that n_bits =< (long)wordsize - 1. ! 744: * Outputs: ! 745: * Outputs code to the file. ! 746: * Assumptions: ! 747: * Chars are 8 bits long. ! 748: * Algorithm: ! 749: * Maintain a BITS character long buffer (so that 8 codes will ! 750: * fit in it exactly). Use the VAX insv instruction to insert each ! 751: * code in turn. When the buffer fills up empty it and start over. ! 752: */ ! 753: ! 754: static char buf[BITS]; ! 755: ! 756: #ifndef vax ! 757: char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; ! 758: char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; ! 759: #endif /* vax */ ! 760: ! 761: output( code ) ! 762: code_int code; ! 763: { ! 764: #ifdef DEBUG ! 765: static int col = 0; ! 766: #endif /* DEBUG */ ! 767: ! 768: /* ! 769: * On the VAX, it is important to have the register declarations ! 770: * in exactly the order given, or the asm will break. ! 771: */ ! 772: register int r_off = offset, bits= n_bits; ! 773: register char * bp = buf; ! 774: ! 775: #ifdef DEBUG ! 776: if ( verbose ) ! 777: fprintf( stderr, "%5d%c", code, ! 778: (col+=6) >= 74 ? (col = 0, '\n') : ' ' ); ! 779: #endif /* DEBUG */ ! 780: if ( code >= 0 ) { ! 781: #ifdef vax ! 782: /* VAX DEPENDENT!! Implementation on other machines is below. ! 783: * ! 784: * Translation: Insert BITS bits from the argument starting at ! 785: * offset bits from the beginning of buf. ! 786: */ ! 787: 0; /* Work around for pcc -O bug with asm and if stmt */ ! 788: asm( "insv 4(ap),r11,r10,(r9)" ); ! 789: #else /* not a vax */ ! 790: /* ! 791: * byte/bit numbering on the VAX is simulated by the following code ! 792: */ ! 793: /* ! 794: * Get to the first byte. ! 795: */ ! 796: bp += (r_off >> 3); ! 797: r_off &= 7; ! 798: /* ! 799: * Since code is always >= 8 bits, only need to mask the first ! 800: * hunk on the left. ! 801: */ ! 802: *bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off]; ! 803: bp++; ! 804: bits -= (8 - r_off); ! 805: code >>= 8 - r_off; ! 806: /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ ! 807: if ( bits >= 8 ) { ! 808: *bp++ = code; ! 809: code >>= 8; ! 810: bits -= 8; ! 811: } ! 812: /* Last bits. */ ! 813: if(bits) ! 814: *bp = code; ! 815: #endif /* vax */ ! 816: offset += n_bits; ! 817: if ( offset == (n_bits << 3) ) { ! 818: bp = buf; ! 819: bits = n_bits; ! 820: bytes_out += bits; ! 821: do ! 822: putchar(*bp++); ! 823: while(--bits); ! 824: offset = 0; ! 825: } ! 826: ! 827: /* ! 828: * If the next entry is going to be too big for the code size, ! 829: * then increase it, if possible. ! 830: */ ! 831: if ( free_ent > maxcode || (clear_flg > 0)) ! 832: { ! 833: /* ! 834: * Write the whole buffer, because the input side won't ! 835: * discover the size increase until after it has read it. ! 836: */ ! 837: if ( offset > 0 ) { ! 838: if( fwrite( buf, 1, n_bits, stdout ) != n_bits) ! 839: writeerr(); ! 840: bytes_out += n_bits; ! 841: } ! 842: offset = 0; ! 843: ! 844: if ( clear_flg ) { ! 845: maxcode = MAXCODE (n_bits = INIT_BITS); ! 846: clear_flg = 0; ! 847: } ! 848: else { ! 849: n_bits++; ! 850: if ( n_bits == maxbits ) ! 851: maxcode = maxmaxcode; ! 852: else ! 853: maxcode = MAXCODE(n_bits); ! 854: } ! 855: #ifdef DEBUG ! 856: if ( debug ) { ! 857: fprintf( stderr, "\nChange to %d bits\n", n_bits ); ! 858: col = 0; ! 859: } ! 860: #endif /* DEBUG */ ! 861: } ! 862: } else { ! 863: /* ! 864: * At EOF, write the rest of the buffer. ! 865: */ ! 866: if ( offset > 0 ) ! 867: fwrite( buf, 1, (offset + 7) / 8, stdout ); ! 868: bytes_out += (offset + 7) / 8; ! 869: offset = 0; ! 870: fflush( stdout ); ! 871: #ifdef DEBUG ! 872: if ( verbose ) ! 873: fprintf( stderr, "\n" ); ! 874: #endif /* DEBUG */ ! 875: if( ferror( stdout ) ) ! 876: writeerr(); ! 877: } ! 878: } ! 879: ! 880: /* ! 881: * Decompress stdin to stdout. This routine adapts to the codes in the ! 882: * file building the "string" table on-the-fly; requiring no table to ! 883: * be stored in the compressed file. The tables used herein are shared ! 884: * with those of the compress() routine. See the definitions above. ! 885: */ ! 886: ! 887: decompress() { ! 888: register char_type *stackp; ! 889: register int finchar; ! 890: register code_int code, oldcode, incode; ! 891: ! 892: /* ! 893: * As above, initialize the first 256 entries in the table. ! 894: */ ! 895: maxcode = MAXCODE(n_bits = INIT_BITS); ! 896: for ( code = 255; code >= 0; code-- ) { ! 897: tab_prefixof(code) = 0; ! 898: tab_suffixof(code) = (char_type)code; ! 899: } ! 900: free_ent = ((block_compress) ? FIRST : 256 ); ! 901: ! 902: finchar = oldcode = getcode(); ! 903: if(oldcode == -1) /* EOF already? */ ! 904: return; /* Get out of here */ ! 905: putchar( (char)finchar ); /* first code must be 8 bits = char */ ! 906: if(ferror(stdout)) /* Crash if can't write */ ! 907: writeerr(); ! 908: stackp = de_stack; ! 909: ! 910: while ( (code = getcode()) > -1 ) { ! 911: ! 912: if ( (code == CLEAR) && block_compress ) { ! 913: for ( code = 255; code >= 0; code-- ) ! 914: tab_prefixof(code) = 0; ! 915: clear_flg = 1; ! 916: free_ent = FIRST - 1; ! 917: if ( (code = getcode ()) == -1 ) /* O, untimely death! */ ! 918: break; ! 919: } ! 920: incode = code; ! 921: /* ! 922: * Special case for KwKwK string. ! 923: */ ! 924: if ( code >= free_ent ) { ! 925: *stackp++ = finchar; ! 926: code = oldcode; ! 927: } ! 928: ! 929: /* ! 930: * Generate output characters in reverse order ! 931: */ ! 932: #ifdef SIGNED_COMPARE_SLOW ! 933: while ( ((unsigned long)code) >= ((unsigned long)256) ) { ! 934: #else ! 935: while ( code >= 256 ) { ! 936: #endif ! 937: *stackp++ = tab_suffixof(code); ! 938: code = tab_prefixof(code); ! 939: } ! 940: *stackp++ = finchar = tab_suffixof(code); ! 941: ! 942: /* ! 943: * And put them out in forward order ! 944: */ ! 945: do ! 946: putchar ( *--stackp ); ! 947: while ( stackp > de_stack ); ! 948: ! 949: /* ! 950: * Generate the new entry. ! 951: */ ! 952: if ( (code=free_ent) < maxmaxcode ) { ! 953: tab_prefixof(code) = (unsigned short)oldcode; ! 954: tab_suffixof(code) = finchar; ! 955: free_ent = code+1; ! 956: } ! 957: /* ! 958: * Remember previous code. ! 959: */ ! 960: oldcode = incode; ! 961: } ! 962: fflush( stdout ); ! 963: if(ferror(stdout)) ! 964: writeerr(); ! 965: } ! 966: ! 967: /***************************************************************** ! 968: * TAG( getcode ) ! 969: * ! 970: * Read one code from the standard input. If EOF, return -1. ! 971: * Inputs: ! 972: * stdin ! 973: * Outputs: ! 974: * code or -1 is returned. ! 975: */ ! 976: ! 977: code_int ! 978: getcode() { ! 979: /* ! 980: * On the VAX, it is important to have the register declarations ! 981: * in exactly the order given, or the asm will break. ! 982: */ ! 983: register code_int code; ! 984: static int offset = 0, size = 0; ! 985: static char_type buf[BITS]; ! 986: register int r_off, bits; ! 987: register char_type *bp = buf; ! 988: ! 989: if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) { ! 990: /* ! 991: * If the next entry will be too big for the current code ! 992: * size, then we must increase the size. This implies reading ! 993: * a new buffer full, too. ! 994: */ ! 995: if ( free_ent > maxcode ) { ! 996: n_bits++; ! 997: if ( n_bits == maxbits ) ! 998: maxcode = maxmaxcode; /* won't get any bigger now */ ! 999: else ! 1000: maxcode = MAXCODE(n_bits); ! 1001: } ! 1002: if ( clear_flg > 0) { ! 1003: maxcode = MAXCODE (n_bits = INIT_BITS); ! 1004: clear_flg = 0; ! 1005: } ! 1006: size = fread( buf, 1, n_bits, stdin ); ! 1007: if ( size <= 0 ) ! 1008: return -1; /* end of file */ ! 1009: offset = 0; ! 1010: /* Round size down to integral number of codes */ ! 1011: size = (size << 3) - (n_bits - 1); ! 1012: } ! 1013: r_off = offset; ! 1014: bits = n_bits; ! 1015: #ifdef vax ! 1016: asm( "extzv r10,r9,(r8),r11" ); ! 1017: #else /* not a vax */ ! 1018: /* ! 1019: * Get to the first byte. ! 1020: */ ! 1021: bp += (r_off >> 3); ! 1022: r_off &= 7; ! 1023: /* Get first part (low order bits) */ ! 1024: #ifdef NO_UCHAR ! 1025: code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff; ! 1026: #else ! 1027: code = (*bp++ >> r_off); ! 1028: #endif /* NO_UCHAR */ ! 1029: bits -= (8 - r_off); ! 1030: r_off = 8 - r_off; /* now, offset into code word */ ! 1031: /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ ! 1032: if ( bits >= 8 ) { ! 1033: #ifdef NO_UCHAR ! 1034: code |= (*bp++ & 0xff) << r_off; ! 1035: #else ! 1036: code |= *bp++ << r_off; ! 1037: #endif /* NO_UCHAR */ ! 1038: r_off += 8; ! 1039: bits -= 8; ! 1040: } ! 1041: /* high order bits. */ ! 1042: code |= (*bp & rmask[bits]) << r_off; ! 1043: #endif /* vax */ ! 1044: offset += n_bits; ! 1045: ! 1046: return code; ! 1047: } ! 1048: ! 1049: char * ! 1050: rindex(s, c) /* For those who don't have it in libc.a */ ! 1051: register char *s, c; ! 1052: { ! 1053: char *p; ! 1054: for (p = NULL; *s; s++) ! 1055: if (*s == c) ! 1056: p = s; ! 1057: return(p); ! 1058: } ! 1059: ! 1060: #ifdef DEBUG ! 1061: printcodes() ! 1062: { ! 1063: /* ! 1064: * Just print out codes from input file. For debugging. ! 1065: */ ! 1066: code_int code; ! 1067: int col = 0, bits; ! 1068: ! 1069: bits = n_bits = INIT_BITS; ! 1070: maxcode = MAXCODE(n_bits); ! 1071: free_ent = ((block_compress) ? FIRST : 256 ); ! 1072: while ( ( code = getcode() ) >= 0 ) { ! 1073: if ( (code == CLEAR) && block_compress ) { ! 1074: free_ent = FIRST - 1; ! 1075: clear_flg = 1; ! 1076: } ! 1077: else if ( free_ent < maxmaxcode ) ! 1078: free_ent++; ! 1079: if ( bits != n_bits ) { ! 1080: fprintf(stderr, "\nChange to %d bits\n", n_bits ); ! 1081: bits = n_bits; ! 1082: col = 0; ! 1083: } ! 1084: fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' ); ! 1085: } ! 1086: putc( '\n', stderr ); ! 1087: exit( 0 ); ! 1088: } ! 1089: ! 1090: #ifdef XENIX_16 ! 1091: code_int stab1[8192] ; ! 1092: code_int stab2[8192] ; ! 1093: code_int stab3[8192] ; ! 1094: code_int stab4[8192] ; ! 1095: code_int stab5[8192] ; ! 1096: code_int stab6[8192] ; ! 1097: code_int stab7[8192] ; ! 1098: code_int stab8[8192] ; ! 1099: code_int * sorttab[8] = {stab1, stab2, stab3, stab4, stab5, stab6, stab7, ! 1100: stab8 } ; ! 1101: #define stabof(i) (sorttab[(i) >> 13][(i) & 0x1fff]) ! 1102: #else ! 1103: code_int sorttab[HSIZE]; /* sorted pointers into htab */ ! 1104: #define stabof(i) (sorttab[i]) ! 1105: #endif ! 1106: ! 1107: dump_tab() /* dump string table */ ! 1108: { ! 1109: register int i, first; ! 1110: register ent; ! 1111: #define STACK_SIZE 15000 ! 1112: int stack_top = STACK_SIZE; ! 1113: register c; ! 1114: unsigned mbshift ; ! 1115: ! 1116: if(do_decomp == 0) { /* compressing */ ! 1117: register int flag = 1; ! 1118: ! 1119: for(i=0; i<hsize; i++) { /* build sort pointers */ ! 1120: if((long)htabof(i) >= 0) { ! 1121: stabof(codetabof(i)) = i; ! 1122: } ! 1123: } ! 1124: first = block_compress ? FIRST : 256; ! 1125: for(i = first; i < free_ent; i++) { ! 1126: fprintf(stderr, "%5d: \"", i); ! 1127: de_stack[--stack_top] = '\n'; ! 1128: de_stack[--stack_top] = '"'; ! 1129: stack_top = in_stack((htabof(stabof(i))>>maxbits)&0xff, ! 1130: stack_top); ! 1131: /* for(ent=htabof(stabof(i)) & ((1<<maxbits)-1); */ ! 1132: mbshift = ((1 << maxbits) - 1) ; ! 1133: ent = htabof(stabof(i)) & mbshift ; ! 1134: for(; ! 1135: ent > 256; ! 1136: /* ent=htabof(stabof(ent)) & ((1<<maxbits)-1)) { */ ! 1137: ent=htabof(stabof(ent)) & mbshift) { ! 1138: stack_top = in_stack(htabof(stabof(ent)) >> maxbits, ! 1139: stack_top); ! 1140: } ! 1141: stack_top = in_stack(ent, stack_top); ! 1142: fwrite( &de_stack[stack_top], 1, STACK_SIZE-stack_top, stderr); ! 1143: stack_top = STACK_SIZE; ! 1144: } ! 1145: } else if(!debug) { /* decompressing */ ! 1146: ! 1147: for ( i = 0; i < free_ent; i++ ) { ! 1148: ent = i; ! 1149: c = tab_suffixof(ent); ! 1150: if ( isascii(c) && isprint(c) ) ! 1151: fprintf( stderr, "%5d: %5d/'%c' \"", ! 1152: ent, tab_prefixof(ent), c ); ! 1153: else ! 1154: fprintf( stderr, "%5d: %5d/\\%03o \"", ! 1155: ent, tab_prefixof(ent), c ); ! 1156: de_stack[--stack_top] = '\n'; ! 1157: de_stack[--stack_top] = '"'; ! 1158: for ( ; ent != 0; ! 1159: ent = (ent >= FIRST ? tab_prefixof(ent) : 0) ) { ! 1160: stack_top = in_stack(tab_suffixof(ent), stack_top); ! 1161: } ! 1162: fwrite( &de_stack[stack_top], 1, STACK_SIZE - stack_top, stderr ); ! 1163: stack_top = STACK_SIZE; ! 1164: } ! 1165: } ! 1166: } ! 1167: ! 1168: int ! 1169: in_stack(c, stack_top) ! 1170: register c, stack_top; ! 1171: { ! 1172: if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) { ! 1173: de_stack[--stack_top] = c; ! 1174: } else { ! 1175: switch( c ) { ! 1176: case '\n': de_stack[--stack_top] = 'n'; break; ! 1177: case '\t': de_stack[--stack_top] = 't'; break; ! 1178: case '\b': de_stack[--stack_top] = 'b'; break; ! 1179: case '\f': de_stack[--stack_top] = 'f'; break; ! 1180: case '\r': de_stack[--stack_top] = 'r'; break; ! 1181: case '\\': de_stack[--stack_top] = '\\'; break; ! 1182: default: ! 1183: de_stack[--stack_top] = '0' + c % 8; ! 1184: de_stack[--stack_top] = '0' + (c / 8) % 8; ! 1185: de_stack[--stack_top] = '0' + c / 64; ! 1186: break; ! 1187: } ! 1188: de_stack[--stack_top] = '\\'; ! 1189: } ! 1190: return stack_top; ! 1191: } ! 1192: #endif /* DEBUG */ ! 1193: ! 1194: writeerr() ! 1195: { ! 1196: perror ( ofname ); ! 1197: unlink ( ofname ); ! 1198: exit ( 1 ); ! 1199: } ! 1200: ! 1201: copystat(ifname, ofname) ! 1202: char *ifname, *ofname; ! 1203: { ! 1204: struct stat statbuf; ! 1205: int mode; ! 1206: time_t timep[2]; ! 1207: ! 1208: fclose(stdout); ! 1209: if (stat(ifname, &statbuf)) { /* Get stat on input file */ ! 1210: perror(ifname); ! 1211: return; ! 1212: } ! 1213: if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) { ! 1214: if(quiet) ! 1215: fprintf(stderr, "%s: ", ifname); ! 1216: fprintf(stderr, " -- not a regular file: unchanged"); ! 1217: exit_stat = 1; ! 1218: } else if (statbuf.st_nlink > 1) { ! 1219: if(quiet) ! 1220: fprintf(stderr, "%s: ", ifname); ! 1221: fprintf(stderr, " -- has %d other links: unchanged", ! 1222: statbuf.st_nlink - 1); ! 1223: exit_stat = 1; ! 1224: } else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */ ! 1225: if(!quiet) ! 1226: fprintf(stderr, " -- file unchanged"); ! 1227: } else { /* ***** Successful Compression ***** */ ! 1228: exit_stat = 0; ! 1229: mode = statbuf.st_mode & 07777; ! 1230: if (chmod(ofname, mode)) /* Copy modes */ ! 1231: perror(ofname); ! 1232: chown(ofname, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */ ! 1233: timep[0] = statbuf.st_atime; ! 1234: timep[1] = statbuf.st_mtime; ! 1235: utime(ofname, timep); /* Update last accessed and modified times */ ! 1236: if (unlink(ifname)) /* Remove input file */ ! 1237: perror(ifname); ! 1238: if(!quiet) ! 1239: fprintf(stderr, " -- replaced with %s", ofname); ! 1240: return; /* Successful return */ ! 1241: } ! 1242: ! 1243: /* Unsuccessful return -- one of the tests failed */ ! 1244: if (unlink(ofname)) ! 1245: perror(ofname); ! 1246: } ! 1247: /* ! 1248: * This routine returns 1 if we are running in the foreground and stderr ! 1249: * is a tty. ! 1250: */ ! 1251: foreground() ! 1252: { ! 1253: if(bgnd_flag) { /* background? */ ! 1254: return(0); ! 1255: } else { /* foreground */ ! 1256: if(isatty(2)) { /* and stderr is a tty */ ! 1257: return(1); ! 1258: } else { ! 1259: return(0); ! 1260: } ! 1261: } ! 1262: } ! 1263: ! 1264: onintr ( ) ! 1265: { ! 1266: unlink ( ofname ); ! 1267: exit ( 1 ); ! 1268: } ! 1269: ! 1270: oops ( ) /* wild pointer -- assume bad input */ ! 1271: { ! 1272: if ( do_decomp == 1 ) ! 1273: fprintf ( stderr, "uncompress: corrupt input\n" ); ! 1274: unlink ( ofname ); ! 1275: exit ( 1 ); ! 1276: } ! 1277: ! 1278: cl_block () /* table clear for block compress */ ! 1279: { ! 1280: register long int rat; ! 1281: ! 1282: checkpoint = in_count + CHECK_GAP; ! 1283: #ifdef DEBUG ! 1284: if ( debug ) { ! 1285: fprintf ( stderr, "count: %ld, ratio: ", in_count ); ! 1286: prratio ( stderr, in_count, bytes_out ); ! 1287: fprintf ( stderr, "\n"); ! 1288: } ! 1289: #endif /* DEBUG */ ! 1290: ! 1291: if(in_count > 0x007fffff) { /* shift will overflow */ ! 1292: rat = bytes_out >> 8; ! 1293: if(rat == 0) { /* Don't divide by zero */ ! 1294: rat = 0x7fffffff; ! 1295: } else { ! 1296: rat = in_count / rat; ! 1297: } ! 1298: } else { ! 1299: rat = (in_count << 8) / bytes_out; /* 8 fractional bits */ ! 1300: } ! 1301: if ( rat > ratio ) { ! 1302: ratio = rat; ! 1303: } else { ! 1304: ratio = 0; ! 1305: #ifdef DEBUG ! 1306: if(verbose) ! 1307: dump_tab(); /* dump string table */ ! 1308: #endif ! 1309: cl_hash ( (count_int) hsize ); ! 1310: free_ent = FIRST; ! 1311: clear_flg = 1; ! 1312: output ( (code_int) CLEAR ); ! 1313: #ifdef DEBUG ! 1314: if(debug) ! 1315: fprintf ( stderr, "clear\n" ); ! 1316: #endif /* DEBUG */ ! 1317: } ! 1318: } ! 1319: ! 1320: cl_hash(hsize) /* reset code table */ ! 1321: register count_int hsize; ! 1322: { ! 1323: #ifndef XENIX_16 /* Normal machine */ ! 1324: register count_int *htab_p = htab+hsize; ! 1325: #else ! 1326: register j; ! 1327: register long k = hsize; ! 1328: register count_int *htab_p; ! 1329: #endif ! 1330: register long i; ! 1331: register long m1 = -1; ! 1332: ! 1333: #ifdef XENIX_16 ! 1334: for(j=0; j<=8 && k>=0; j++,k-=8192) { ! 1335: i = 8192; ! 1336: if(k < 8192) { ! 1337: i = k; ! 1338: } ! 1339: htab_p = &(htab[j][i]); ! 1340: i -= 16; ! 1341: if(i > 0) { ! 1342: #else ! 1343: i = hsize - 16; ! 1344: #endif ! 1345: do { /* might use Sys V memset(3) here */ ! 1346: *(htab_p-16) = m1; ! 1347: *(htab_p-15) = m1; ! 1348: *(htab_p-14) = m1; ! 1349: *(htab_p-13) = m1; ! 1350: *(htab_p-12) = m1; ! 1351: *(htab_p-11) = m1; ! 1352: *(htab_p-10) = m1; ! 1353: *(htab_p-9) = m1; ! 1354: *(htab_p-8) = m1; ! 1355: *(htab_p-7) = m1; ! 1356: *(htab_p-6) = m1; ! 1357: *(htab_p-5) = m1; ! 1358: *(htab_p-4) = m1; ! 1359: *(htab_p-3) = m1; ! 1360: *(htab_p-2) = m1; ! 1361: *(htab_p-1) = m1; ! 1362: htab_p -= 16; ! 1363: } while ((i -= 16) >= 0); ! 1364: #ifdef XENIX_16 ! 1365: } ! 1366: } ! 1367: #endif ! 1368: for ( i += 16; i > 0; i-- ) ! 1369: *--htab_p = m1; ! 1370: } ! 1371: ! 1372: prratio(stream, num, den) ! 1373: FILE *stream; ! 1374: long int num, den; ! 1375: { ! 1376: register int q; /* Doesn't need to be long */ ! 1377: ! 1378: if(num > 214748L) { /* 2147483647/10000 */ ! 1379: q = num / (den / 10000L); ! 1380: } else { ! 1381: q = 10000L * num / den; /* Long calculations, though */ ! 1382: } ! 1383: if (q < 0) { ! 1384: putc('-', stream); ! 1385: q = -q; ! 1386: } ! 1387: fprintf(stream, "%d.%02d%%", q / 100, q % 100); ! 1388: } ! 1389: ! 1390: version() ! 1391: { ! 1392: fprintf(stderr, "%s\n", rcs_ident); ! 1393: fprintf(stderr, "Options: "); ! 1394: #ifdef vax ! 1395: fprintf(stderr, "vax, "); ! 1396: #endif ! 1397: #ifdef NO_UCHAR ! 1398: fprintf(stderr, "NO_UCHAR, "); ! 1399: #endif ! 1400: #ifdef SIGNED_COMPARE_SLOW ! 1401: fprintf(stderr, "SIGNED_COMPARE_SLOW, "); ! 1402: #endif ! 1403: #ifdef XENIX_16 ! 1404: fprintf(stderr, "XENIX_16, "); ! 1405: #endif ! 1406: #ifdef COMPATIBLE ! 1407: fprintf(stderr, "COMPATIBLE, "); ! 1408: #endif ! 1409: #ifdef DEBUG ! 1410: fprintf(stderr, "DEBUG, "); ! 1411: #endif ! 1412: #ifdef BSD4_2 ! 1413: fprintf(stderr, "BSD4_2, "); ! 1414: #endif ! 1415: fprintf(stderr, "BITS = %d\n", BITS); ! 1416: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.