00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #define AZTEC86 1
00053
00054 #define min(a,b) ((a>b) ? b : a)
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #ifndef SACREDMEM
00065 #define SACREDMEM 0
00066 #endif
00067
00068 #ifndef USERMEM
00069 # define USERMEM 450000
00070 #endif
00071
00072 #define REGISTER register
00073 #define DOTZ ".Z"
00074
00075 #include <limits.h>
00076 #include <dirent.h>
00077
00078
00079 #define DEFAULTBITS 13
00080 #if INT_MAX == 32767
00081 # define BITS 13
00082 #else
00083 # define BITS 16
00084 #endif
00085
00086 #ifdef USERMEM
00087 # if USERMEM >= (433484+SACREDMEM)
00088 # define PBITS 16
00089 # else
00090 # if USERMEM >= (229600+SACREDMEM)
00091 # define PBITS 15
00092 # else
00093 # if USERMEM >= (127536+SACREDMEM)
00094 # define PBITS 14
00095 # else
00096 # if USERMEM >= (73464+SACREDMEM)
00097 # define PBITS 13
00098 # else
00099 # define PBITS 12
00100 # endif
00101 # endif
00102 # endif
00103 # endif
00104 # undef USERMEM
00105 #endif
00106
00107 #ifdef PBITS
00108 # ifndef BITS
00109 # define BITS PBITS
00110 # endif
00111 #endif
00112
00113 #if BITS == 16
00114 # define HSIZE 69001
00115 #endif
00116 #if BITS == 15
00117 # define HSIZE 35023
00118 #endif
00119 #if BITS == 14
00120 # define HSIZE 18013
00121 #endif
00122 #if BITS == 13
00123 # define HSIZE 9001
00124 #endif
00125 #if BITS <= 12
00126 # define HSIZE 5003
00127 #endif
00128
00129
00130
00131
00132
00133 #if BITS > 15
00134 typedef long int code_int;
00135 #else
00136 typedef int code_int;
00137 #endif
00138
00139 #ifdef SIGNED_COMPARE_SLOW
00140 typedef unsigned long int count_int;
00141 typedef unsigned short int count_short;
00142 #else
00143 typedef long int count_int;
00144 #endif
00145
00146 #ifdef NO_UCHAR
00147 typedef char char_type;
00148 #else
00149 typedef unsigned char char_type;
00150 #endif
00151 char_type magic_header[] = "\037\235";
00152
00153
00154 #define BIT_MASK 0x1f
00155 #define BLOCK_MASK 0x80
00156
00157
00158
00159 #define INIT_BITS 9
00160
00161 #include <sys/types.h>
00162 #include <sys/stat.h>
00163 #include <fcntl.h>
00164 #include <ctype.h>
00165 #include <signal.h>
00166 #include <stdlib.h>
00167 #include <string.h>
00168 #include <unistd.h>
00169 #include <utime.h>
00170 #include <stdio.h>
00171
00172 #define ARGVAL() (*++(*argv) || (--argc && *++argv))
00173
00174 int n_bits;
00175 int maxbits = DEFAULTBITS;
00176 code_int maxcode;
00177 code_int maxmaxcode = 1 << BITS;
00178 #ifdef COMPATIBLE
00179 # define MAXCODE(n_bits) (1 << (n_bits) - 1)
00180 #else
00181 # define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
00182 #endif
00183
00184 #ifndef AZTEC86
00185 count_int htab [HSIZE];
00186 unsigned short codetab [HSIZE];
00187 #else
00188 count_int *htab;
00189 unsigned short *codetab;
00190 # define HTABSIZE ((size_t)(HSIZE*sizeof(count_int)))
00191 # define CODETABSIZE ((size_t)(HSIZE*sizeof(unsigned short)))
00192
00193
00194 #define htabof(i) htab[i]
00195 #define codetabof(i) codetab[i]
00196 #endif
00197 code_int hsize = HSIZE;
00198 count_int fsize;
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 #define tab_prefixof(i) codetabof(i)
00210 #ifdef XENIX_16
00211 # define tab_suffixof(i) ((char_type *)htab[(i)>>15])[(i) & 0x7fff]
00212 # define de_stack ((char_type *)(htab2))
00213 #else
00214 # define tab_suffixof(i) ((char_type *)(htab))[i]
00215 # define de_stack ((char_type *)&tab_suffixof(1<<BITS))
00216 #endif
00217
00218 code_int free_ent = 0;
00219 int exit_stat = 0;
00220
00221 _PROTOTYPE(int main, (int argc, char **argv));
00222 _PROTOTYPE(void Usage, (void));
00223 _PROTOTYPE(void compress, (void));
00224 _PROTOTYPE(void onintr, (int dummy));
00225 _PROTOTYPE(void oops, (int dummy));
00226 _PROTOTYPE(void output, (code_int code));
00227 _PROTOTYPE(int foreground, (void));
00228 _PROTOTYPE(void decompress, (void));
00229 _PROTOTYPE(code_int getcode, (void));
00230 _PROTOTYPE(void writeerr, (void));
00231 _PROTOTYPE(void copystat, (char *ifname, char *ofname));
00232 _PROTOTYPE(int foreground, (void));
00233 _PROTOTYPE(void cl_block , (void));
00234 _PROTOTYPE(void cl_hash, (count_int hsize));
00235 _PROTOTYPE(void prratio, (FILE *stream, long int num, long int den));
00236 _PROTOTYPE(void version, (void));
00237
00238 void Usage() {
00239 #ifdef DEBUG
00240 fprintf(stderr,"Usage: compress [-dDVfc] [-b maxbits] [file ...]\n");
00241 }
00242 int debug = 0;
00243 #else
00244 fprintf(stderr,"Usage: compress [-dfvcV] [-b maxbits] [file ...]\n");
00245 }
00246 #endif
00247 int nomagic = 0;
00248 int zcat_flg = 0;
00249 int quiet = 0;
00250
00251
00252
00253
00254
00255 int block_compress = BLOCK_MASK;
00256 int clear_flg = 0;
00257 long int ratio = 0;
00258 #define CHECK_GAP 10000
00259 count_int checkpoint = CHECK_GAP;
00260
00261
00262
00263
00264 #define FIRST 257
00265 #define CLEAR 256
00266
00267 int force = 0;
00268 char ofname [100];
00269 #ifdef DEBUG
00270 int verbose = 0;
00271 #endif
00272
00273 #ifndef METAWARE
00274 #ifdef AZTEC86
00275 void
00276 #else
00277 int
00278 #endif
00279 #ifndef __STDC__
00280 (*bgnd_flag)();
00281 #else
00282 (*bgnd_flag)(int);
00283 #endif
00284 #endif
00285
00286 int do_decomp = 0;
00287
00288
00289 int main(argc, argv)
00290 int argc;
00291 char **argv;
00292 {
00293 int overwrite = 0;
00294 char tempname[100];
00295 char **filelist, **fileptr;
00296 char *cp;
00297 struct stat statbuf;
00298 #ifndef METAWARE
00299 if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
00300 signal ( SIGINT, onintr );
00301 signal ( SIGSEGV, oops );
00302 }
00303 #endif
00304 #ifdef AZTEC86
00305 #ifdef METAWARE
00306 _setmode(NULL,_ALL_FILES_BINARY);
00307 _setmode(stdin,_BINARY);
00308 _setmode(stdout,_BINARY);
00309 _setmode(stderr,_TEXT);
00310 #endif
00311 if (NULL == (htab = (count_int *)malloc(HTABSIZE)))
00312 {
00313 fprintf(stderr,"Can't allocate htab\n");
00314 exit(1);
00315 }
00316 if (NULL == (codetab = (unsigned short *)malloc(CODETABSIZE)))
00317 {
00318 fprintf(stderr,"Can't allocate codetab\n");
00319 exit(1);
00320 }
00321 #endif
00322 #ifdef COMPATIBLE
00323 nomagic = 1;
00324 #endif
00325
00326 filelist = fileptr = (char **)(malloc((size_t)(argc * sizeof(*argv))));
00327 *filelist = NULL;
00328
00329 if((cp = strrchr(argv[0], '/')) != 0) {
00330 cp++;
00331 } else {
00332 cp = argv[0];
00333 }
00334 if(strcmp(cp, "uncompress") == 0) {
00335 do_decomp = 1;
00336 } else if(strcmp(cp, "zcat") == 0) {
00337 do_decomp = 1;
00338 zcat_flg = 1;
00339 }
00340
00341 #ifdef BSD4_2
00342
00343 setlinebuf( stderr );
00344 #endif
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 for (argc--, argv++; argc > 0; argc--, argv++)
00361 {
00362 if (**argv == '-')
00363 {
00364 while (*++(*argv))
00365 {
00366 switch (**argv)
00367 {
00368 #ifdef DEBUG
00369 case 'D':
00370 debug = 1;
00371 break;
00372 case 'V':
00373 verbose = 1;
00374 version();
00375 break;
00376 #else
00377 case 'V':
00378 version();
00379 break;
00380 #endif
00381 case 'v':
00382 quiet = 0;
00383 break;
00384 case 'd':
00385 do_decomp = 1;
00386 break;
00387 case 'f':
00388 case 'F':
00389 overwrite = 1;
00390 force = 1;
00391 break;
00392 case 'n':
00393 nomagic = 1;
00394 break;
00395 case 'C':
00396 block_compress = 0;
00397 break;
00398 case 'b':
00399 if (!ARGVAL())
00400 {
00401 fprintf(stderr, "Missing maxbits\n");
00402 Usage();
00403 exit(1);
00404 }
00405 maxbits = atoi(*argv);
00406 goto nextarg;
00407 case 'c':
00408 zcat_flg = 1;
00409 break;
00410 case 'q':
00411 quiet = 1;
00412 break;
00413 default:
00414 fprintf(stderr, "Unknown flag: '%c'; ", **argv);
00415 Usage();
00416 exit(1);
00417 }
00418 }
00419 }
00420 else
00421 {
00422 *fileptr++ = *argv;
00423 *fileptr = NULL;
00424
00425 }
00426 nextarg: continue;
00427 }
00428
00429 if(maxbits < INIT_BITS) maxbits = INIT_BITS;
00430 if (maxbits > BITS) maxbits = BITS;
00431 maxmaxcode = 1 << maxbits;
00432
00433 if (*filelist != NULL)
00434 {
00435 for (fileptr = filelist; *fileptr; fileptr++)
00436 {
00437 exit_stat = 0;
00438 if (do_decomp != 0)
00439 {
00440
00441 #ifndef PCDOS
00442 if (strcmp(*fileptr + strlen(*fileptr) - 2, DOTZ) != 0)
00443 #else
00444 if (strcmp(*fileptr + strlen(*fileptr) - 1, DOTZ) != 0)
00445 #endif
00446 {
00447
00448 strcpy(tempname, *fileptr);
00449 #ifndef PCDOS
00450 strcat(tempname, DOTZ);
00451 #else
00452
00453 {
00454 char *dot;
00455 if (NULL == (dot = strchr(tempname,'.')))
00456 {
00457 strcat(tempname,".Z");
00458 }
00459 else
00460
00461
00462 {
00463 if (strlen(dot) < 4)
00464 strcat(tempname,DOTZ);
00465 else
00466 dot[3] = 'Z';
00467 }
00468 }
00469 #endif
00470 *fileptr = tempname;
00471 }
00472
00473 if ((freopen(*fileptr, "r", stdin)) == NULL)
00474 {
00475 perror(*fileptr); continue;
00476 }
00477
00478 if (nomagic == 0)
00479 {
00480 unsigned magic1, magic2;
00481 if (((magic1 = getc(stdin)) != (magic_header[0] & 0xFF))
00482 || ((magic2 = getc(stdin)) != (magic_header[1] & 0xFF)))
00483 {
00484 fprintf(stderr,
00485 "%s: not in compressed format %x %x\n",
00486 *fileptr,magic1,magic2);
00487 continue;
00488 }
00489 maxbits = getc(stdin);
00490 block_compress = maxbits & BLOCK_MASK;
00491 maxbits &= BIT_MASK;
00492 maxmaxcode = 1 << maxbits;
00493 if(maxbits > BITS)
00494 {
00495 fprintf(stderr,
00496 "%s: compressed with %d bits, can only handle %d bits\n",
00497 *fileptr, maxbits, BITS);
00498 continue;
00499 }
00500 }
00501
00502 strcpy(ofname, *fileptr);
00503 #ifndef PCDOS
00504 ofname[strlen(*fileptr) - 2] = '\0';
00505 #else
00506
00507 {
00508 char *dot;
00509 char fixup = '\0';
00510
00511 for (dot = ofname; *dot; dot++)
00512 *dot = toupper(*dot);
00513 if (NULL == (dot = strchr(ofname,'.')))
00514 {
00515 fprintf(stderr,"Bad filename %s\n",ofname);
00516 exit(1);
00517 }
00518 if (strlen(dot) == 4)
00519
00520 {
00521 if (strcmp(dot,".EXZ") == 0)
00522 fixup = 'E';
00523 else if (strcmp(dot,".COZ") == 0)
00524 fixup = 'M';
00525 else if (strcmp(dot,".BAZ") == 0)
00526 fixup = 'S';
00527 else if (strcmp(dot,".OBZ") == 0)
00528 fixup = 'J';
00529 else if (strcmp(dot,".SYZ") == 0)
00530 fixup = 'S';
00531 else if (strcmp(dot,".DOZ") == 0)
00532 fixup = 'C';
00533
00534 }
00535
00536 ofname[strlen(*fileptr) - 1] = fixup;
00537 }
00538 #endif
00539 } else
00540 {
00541 if (strcmp(*fileptr + strlen(*fileptr) - 2, DOTZ) == 0)
00542 {
00543 fprintf(stderr, "%s: already has .Z suffix -- no change\n",
00544 *fileptr);
00545 continue;
00546 }
00547
00548 if ((freopen(*fileptr, "r", stdin)) == NULL)
00549 {
00550 perror(*fileptr); continue;
00551 }
00552 (void)stat( *fileptr, &statbuf );
00553 fsize = (long) statbuf.st_size;
00554
00555
00556
00557
00558
00559 hsize = HSIZE;
00560 if ( fsize < (1 << 12) )
00561 hsize = min ( 5003, HSIZE );
00562 else if ( fsize < (1 << 13) )
00563 hsize = min ( 9001, HSIZE );
00564 else if ( fsize < (1 << 14) )
00565 hsize = min ( 18013, HSIZE );
00566 else if ( fsize < (1 << 15) )
00567 hsize = min ( 35023, HSIZE );
00568 else if ( fsize < 47000 )
00569 hsize = min ( 50021, HSIZE );
00570
00571
00572 strcpy(ofname, *fileptr);
00573 #ifndef BSD4_2
00574 if ((cp=strrchr(ofname,'/')) != NULL)
00575 cp++;
00576 else
00577 cp = ofname;
00578 if (strlen(cp) >= _DIRENT_NAME_LEN-3)
00579 {
00580 fprintf(stderr,"%s: filename too long to tack on .Z\n",cp);
00581 continue;
00582 }
00583 #ifdef PCDOS
00584 else
00585 {
00586
00587 char *dot;
00588 if (NULL == (dot = strchr(cp,'.')))
00589 {
00590 strcat(cp,".Z");
00591 }
00592 else
00593
00594
00595 {
00596 if (strlen(dot) < 4)
00597 strcat(cp,DOTZ);
00598 else
00599 dot[3] = 'Z';
00600 }
00601 }
00602 #endif
00603 #endif
00604 #ifndef PCDOS
00605
00606 strcat(ofname, DOTZ);
00607 #endif
00608 }
00609
00610 if (overwrite == 0 && zcat_flg == 0)
00611 {
00612 if (stat(ofname, &statbuf) == 0)
00613 {
00614 char response[2]; int fd;
00615 response[0] = 'n';
00616 fprintf(stderr, "%s already exists;", ofname);
00617 if (foreground())
00618 {
00619 fd = open("/dev/tty", O_RDONLY);
00620 fprintf(stderr,
00621 " do you wish to overwrite %s (y or n)? ", ofname);
00622 fflush(stderr);
00623 (void)read(fd, response, 2);
00624 while (response[1] != '\n')
00625 {
00626 if (read(fd, response+1, 1) < 0)
00627 {
00628 perror("stderr");
00629 break;
00630 }
00631 }
00632 close(fd);
00633 }
00634 if (response[0] != 'y')
00635 {
00636 fprintf(stderr, "\tnot overwritten\n");
00637 continue;
00638 }
00639 }
00640 }
00641 if(zcat_flg == 0)
00642 {
00643 if (freopen(ofname, "w", stdout) == NULL)
00644 {
00645 perror(ofname);
00646 continue;
00647 }
00648 if(!quiet)
00649 fprintf(stderr, "%s: ", *fileptr);
00650 }
00651
00652
00653 if (do_decomp == 0)
00654 compress();
00655 #ifndef DEBUG
00656 else
00657 decompress();
00658 #else
00659 else if (debug == 0)
00660 decompress();
00661 else
00662 printcodes();
00663 if (verbose)
00664 dump_tab();
00665 #endif
00666 if(zcat_flg == 0)
00667 {
00668 copystat(*fileptr, ofname);
00669 if((exit_stat == 1) || (!quiet))
00670 putc('\n', stderr);
00671 }
00672 }
00673 } else
00674 {
00675 if (do_decomp == 0)
00676 {
00677 compress();
00678 #ifdef DEBUG
00679 if(verbose) dump_tab();
00680 #endif
00681 if(!quiet)
00682 putc('\n', stderr);
00683 } else
00684 {
00685
00686 if (nomagic == 0)
00687 {
00688 if ((getc(stdin)!=(magic_header[0] & 0xFF))
00689 || (getc(stdin)!=(magic_header[1] & 0xFF)))
00690 {
00691 fprintf(stderr, "stdin: not in compressed format\n");
00692 exit(1);
00693 }
00694 maxbits = getc(stdin);
00695 block_compress = maxbits & BLOCK_MASK;
00696 maxbits &= BIT_MASK;
00697 maxmaxcode = 1 << maxbits;
00698 fsize = 100000;
00699 if(maxbits > BITS)
00700 {
00701 fprintf(stderr,
00702 "stdin: compressed with %d bits, can only handle %d bits\n",
00703 maxbits, BITS);
00704 exit(1);
00705 }
00706 }
00707 #ifndef DEBUG
00708 decompress();
00709 #else
00710 if (debug == 0) decompress();
00711 else printcodes();
00712 if (verbose) dump_tab();
00713 #endif
00714 }
00715 }
00716 return(exit_stat);
00717 }
00718
00719 static int offset;
00720 long int in_count = 1;
00721 long int bytes_out;
00722 long int out_count = 0;
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 void compress()
00741 {
00742 REGISTER long fcode;
00743 REGISTER code_int i = 0;
00744 REGISTER int c;
00745 REGISTER code_int ent;
00746 #ifdef XENIX_16
00747 REGISTER code_int disp;
00748 #else
00749 REGISTER int disp;
00750 #endif
00751 REGISTER code_int hsize_reg;
00752 REGISTER int hshift;
00753
00754 #ifndef COMPATIBLE
00755 if (nomagic == 0)
00756 {
00757 putc(magic_header[0],stdout);
00758 putc(magic_header[1],stdout);
00759 putc((char)(maxbits | block_compress),stdout);
00760 if(ferror(stdout))
00761 writeerr();
00762 }
00763 #endif
00764
00765 offset = 0;
00766 bytes_out = 3;
00767 out_count = 0;
00768 clear_flg = 0;
00769 ratio = 0;
00770 in_count = 1;
00771 checkpoint = CHECK_GAP;
00772 maxcode = MAXCODE(n_bits = INIT_BITS);
00773 free_ent = ((block_compress) ? FIRST : 256 );
00774
00775 ent = getc(stdin);
00776
00777 hshift = 0;
00778 for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L )
00779 hshift++;
00780 hshift = 8 - hshift;
00781
00782 hsize_reg = hsize;
00783 cl_hash( (count_int) hsize_reg);
00784
00785 #ifdef SIGNED_COMPARE_SLOW
00786 while ( (c = getc(stdin)) != (unsigned) EOF )
00787 #else
00788 while ( (c = getc(stdin)) != EOF )
00789 #endif
00790 {
00791 in_count++;
00792 fcode = (long) (((long) c << maxbits) + ent);
00793 i = ((c << hshift) ^ ent);
00794
00795 if ( htabof (i) == fcode )
00796 {
00797 ent = codetabof (i);
00798 continue;
00799 } else if ( (long)htabof (i) < 0 )
00800 goto nomatch;
00801 disp = hsize_reg - i;
00802 if ( i == 0 )
00803 disp = 1;
00804 probe:
00805 if ( (i -= disp) < 0 )
00806 i += hsize_reg;
00807
00808 if ( htabof (i) == fcode )
00809 {
00810 ent = codetabof (i);
00811 continue;
00812 }
00813 if ( (long)htabof (i) > 0 )
00814 goto probe;
00815 nomatch:
00816 output ( (code_int) ent );
00817 out_count++;
00818 ent = c;
00819 #ifdef SIGNED_COMPARE_SLOW
00820 if ( (unsigned) free_ent < (unsigned) maxmaxcode)
00821 #else
00822 if ( free_ent < maxmaxcode )
00823 #endif
00824 {
00825 codetabof (i) = free_ent++;
00826 htabof (i) = fcode;
00827 }
00828 else if ( (count_int)in_count >= checkpoint && block_compress )
00829 cl_block ();
00830 }
00831
00832
00833
00834 output( (code_int)ent );
00835 out_count++;
00836 output( (code_int)-1 );
00837
00838
00839
00840
00841 if(zcat_flg == 0 && !quiet)
00842 {
00843 #ifdef DEBUG
00844 fprintf( stderr,
00845 "%ld chars in, %ld codes (%ld bytes) out, compression factor: ",
00846 in_count, out_count, bytes_out );
00847 prratio( stderr, in_count, bytes_out );
00848 fprintf( stderr, "\n");
00849 fprintf( stderr, "\tCompression as in compact: " );
00850 prratio( stderr, in_count-bytes_out, in_count );
00851 fprintf( stderr, "\n");
00852 fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n",
00853 free_ent - 1, n_bits );
00854 #else
00855 fprintf( stderr, "Compression: " );
00856 prratio( stderr, in_count-bytes_out, in_count );
00857 #endif
00858 }
00859 if(bytes_out > in_count)
00860 exit_stat = 2;
00861 return;
00862 }
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881 static char buf[BITS];
00882
00883 #ifndef vax
00884 char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
00885 char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
00886 #endif
00887 void output( code )
00888 code_int code;
00889 {
00890 #ifdef DEBUG
00891 static int col = 0;
00892 #endif
00893
00894
00895
00896
00897
00898 REGISTER int r_off = offset, bits= n_bits;
00899 REGISTER char * bp = buf;
00900 #ifndef BREAKHIGHC
00901 #ifdef METAWARE
00902 int temp;
00903 #endif
00904 #endif
00905 #ifdef DEBUG
00906 if ( verbose )
00907 fprintf( stderr, "%5d%c", code,
00908 (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
00909 #endif
00910 if ( code >= 0 )
00911 {
00912 #ifdef vax
00913
00914
00915
00916
00917
00918 0;
00919 asm( "insv 4(ap),r11,r10,(r9)" );
00920 #else
00921
00922
00923
00924
00925
00926
00927 bp += (r_off >> 3);
00928 r_off &= 7;
00929
00930
00931
00932
00933 #ifndef BREAKHIGHC
00934 #ifdef METAWARE
00935 *bp &= rmask[r_off];
00936 temp = (code << r_off) & lmask[r_off];
00937 *bp |= temp;
00938 #else
00939 *bp = (*bp & rmask[r_off]) | ((code << r_off) & lmask[r_off]);
00940 #endif
00941 #else
00942 *bp = (*bp & rmask[r_off]) | ((code << r_off) & lmask[r_off]);
00943 #endif
00944 bp++;
00945 bits -= (8 - r_off);
00946 code >>= (8 - r_off);
00947
00948 if ( bits >= 8 )
00949 {
00950 *bp++ = code;
00951 code >>= 8;
00952 bits -= 8;
00953 }
00954
00955 if(bits)
00956 *bp = code;
00957 #endif
00958 offset += n_bits;
00959 if ( offset == (n_bits << 3) )
00960 {
00961 bp = buf;
00962 bits = n_bits;
00963 bytes_out += bits;
00964 do
00965 putc(*bp++,stdout);
00966 while(--bits);
00967 offset = 0;
00968 }
00969
00970
00971
00972
00973
00974 if ( free_ent > maxcode || (clear_flg > 0))
00975 {
00976
00977
00978
00979
00980 if ( offset > 0 )
00981 {
00982 if( fwrite( buf, (size_t)1, (size_t)n_bits, stdout ) != n_bits)
00983 writeerr();
00984 bytes_out += n_bits;
00985 }
00986 offset = 0;
00987
00988 if ( clear_flg )
00989 {
00990 maxcode = MAXCODE (n_bits = INIT_BITS);
00991 clear_flg = 0;
00992 }
00993 else
00994 {
00995 n_bits++;
00996 if ( n_bits == maxbits )
00997 maxcode = maxmaxcode;
00998 else
00999 maxcode = MAXCODE(n_bits);
01000 }
01001 #ifdef DEBUG
01002 if ( debug )
01003 {
01004 fprintf( stderr, "\nChange to %d bits\n", n_bits );
01005 col = 0;
01006 }
01007 #endif
01008 }
01009 } else
01010 {
01011
01012
01013
01014 if ( offset > 0 )
01015 fwrite( buf, (size_t)1, (size_t)(offset + 7) / 8, stdout );
01016 bytes_out += (offset + 7) / 8;
01017 offset = 0;
01018 fflush( stdout );
01019 #ifdef DEBUG
01020 if ( verbose )
01021 fprintf( stderr, "\n" );
01022 #endif
01023 if( ferror( stdout ) )
01024 writeerr();
01025 }
01026 }
01027
01028
01029
01030
01031
01032
01033
01034 void decompress() {
01035 REGISTER char_type *stackp;
01036 REGISTER int finchar;
01037 REGISTER code_int code, oldcode, incode;
01038
01039
01040
01041
01042 maxcode = MAXCODE(n_bits = INIT_BITS);
01043 for ( code = 255; code >= 0; code-- ) {
01044 tab_prefixof(code) = 0;
01045 tab_suffixof(code) = (char_type)code;
01046 }
01047 free_ent = ((block_compress) ? FIRST : 256 );
01048
01049 finchar = oldcode = getcode();
01050 if(oldcode == -1)
01051 return;
01052 putc( (char)finchar,stdout );
01053 if(ferror(stdout))
01054 writeerr();
01055 stackp = de_stack;
01056
01057 while ( (code = getcode()) > -1 ) {
01058
01059 if ( (code == CLEAR) && block_compress ) {
01060 for ( code = 255; code >= 0; code-- )
01061 tab_prefixof(code) = 0;
01062 clear_flg = 1;
01063 free_ent = FIRST - 1;
01064 if ( (code = getcode ()) == -1 )
01065 break;
01066 }
01067 incode = code;
01068
01069
01070
01071 if ( code >= free_ent ) {
01072 *stackp++ = finchar;
01073 code = oldcode;
01074 }
01075
01076
01077
01078
01079 #ifdef SIGNED_COMPARE_SLOW
01080 while ( ((unsigned long)code) >= ((unsigned long)256) ) {
01081 #else
01082 while ( code >= 256 ) {
01083 #endif
01084 *stackp++ = tab_suffixof(code);
01085 code = tab_prefixof(code);
01086 }
01087 *stackp++ = finchar = tab_suffixof(code);
01088
01089
01090
01091
01092 do
01093 putc ( *--stackp ,stdout);
01094 while ( stackp > de_stack );
01095
01096
01097
01098
01099 if ( (code=free_ent) < maxmaxcode )
01100 {
01101 tab_prefixof(code) = (unsigned short)oldcode;
01102 tab_suffixof(code) = finchar;
01103 free_ent = code+1;
01104 }
01105
01106
01107
01108 oldcode = incode;
01109 }
01110 fflush( stdout );
01111 if(ferror(stdout))
01112 writeerr();
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125 code_int
01126 getcode()
01127 {
01128
01129
01130
01131
01132 REGISTER code_int code;
01133 static int offset = 0, size = 0;
01134 static char_type buf[BITS];
01135 REGISTER int r_off, bits;
01136 REGISTER char_type *bp = buf;
01137
01138 if ( clear_flg > 0 || offset >= size || free_ent > maxcode )
01139 {
01140
01141
01142
01143
01144
01145 if ( free_ent > maxcode )
01146 {
01147 n_bits++;
01148 if ( n_bits == maxbits )
01149 maxcode = maxmaxcode;
01150 else
01151 maxcode = MAXCODE(n_bits);
01152 }
01153 if ( clear_flg > 0)
01154 {
01155 maxcode = MAXCODE (n_bits = INIT_BITS);
01156 clear_flg = 0;
01157 }
01158 size = fread( buf, (size_t)1, (size_t)n_bits, stdin );
01159 if ( size <= 0 )
01160 return -1;
01161 offset = 0;
01162
01163 size = (size << 3) - (n_bits - 1);
01164 }
01165 r_off = offset;
01166 bits = n_bits;
01167 #ifdef vax
01168 asm( "extzv r10,r9,(r8),r11" );
01169 #else
01170
01171
01172
01173 bp += (r_off >> 3);
01174 r_off &= 7;
01175
01176 #ifdef NO_UCHAR
01177 code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
01178 #else
01179 code = (*bp++ >> r_off);
01180 #endif
01181 bits -= (8 - r_off);
01182 r_off = 8 - r_off;
01183
01184 if ( bits >= 8 )
01185 {
01186 #ifdef NO_UCHAR
01187 code |= (*bp++ & 0xff) << r_off;
01188 #else
01189 code |= *bp++ << r_off;
01190 #endif
01191 r_off += 8;
01192 bits -= 8;
01193 }
01194
01195 code |= (*bp & rmask[bits]) << r_off;
01196 #endif
01197 offset += n_bits;
01198
01199 return code;
01200 }
01201
01202 #ifndef AZTEC86
01203 char *
01204 strrchr(s, c)
01205 REGISTER char *s, c;
01206 {
01207 char *p;
01208 for (p = NULL; *s; s++)
01209 if (*s == c)
01210 p = s;
01211 return(p);
01212 }
01213 #endif
01214
01215
01216 #ifndef METAWARE
01217 #ifdef DEBUG
01218 printcodes()
01219 {
01220
01221
01222
01223 code_int code;
01224 int col = 0, bits;
01225
01226 bits = n_bits = INIT_BITS;
01227 maxcode = MAXCODE(n_bits);
01228 free_ent = ((block_compress) ? FIRST : 256 );
01229 while ( ( code = getcode() ) >= 0 ) {
01230 if ( (code == CLEAR) && block_compress ) {
01231 free_ent = FIRST - 1;
01232 clear_flg = 1;
01233 }
01234 else if ( free_ent < maxmaxcode )
01235 free_ent++;
01236 if ( bits != n_bits ) {
01237 fprintf(stderr, "\nChange to %d bits\n", n_bits );
01238 bits = n_bits;
01239 col = 0;
01240 }
01241 fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
01242 }
01243 putc( '\n', stderr );
01244 exit( 0 );
01245 }
01246 #ifdef DEBUG2
01247 code_int sorttab[1<<BITS];
01248 #define STACK_SIZE 500
01249 static char stack[STACK_SIZE];
01250
01251 dump_tab()
01252 {
01253 REGISTER int i, first;
01254 REGISTER ent;
01255 int stack_top = STACK_SIZE;
01256 REGISTER c;
01257
01258 if(do_decomp == 0) {
01259 REGISTER int flag = 1;
01260
01261 for(i=0; i<hsize; i++) {
01262 if((long)htabof(i) >= 0) {
01263 sorttab[codetabof(i)] = i;
01264 }
01265 }
01266 first = block_compress ? FIRST : 256;
01267 for(i = first; i < free_ent; i++) {
01268 fprintf(stderr, "%5d: \"", i);
01269 stack[--stack_top] = '\n';
01270 stack[--stack_top] = '"';
01271 stack_top = in_stack((int)(htabof(sorttab[i])>>maxbits)&0xff,
01272 stack_top);
01273 for(ent=htabof(sorttab[i]) & ((1<<maxbits)-1);
01274 ent > 256;
01275 ent=htabof(sorttab[ent]) & ((1<<maxbits)-1)) {
01276 stack_top = in_stack((int)(htabof(sorttab[ent]) >> maxbits),
01277 stack_top);
01278 }
01279 stack_top = in_stack(ent, stack_top);
01280 fwrite( &stack[stack_top], (size_t)1, (size_t)(STACK_SIZE-stack_top), stderr);
01281 stack_top = STACK_SIZE;
01282 }
01283 } else if(!debug) {
01284
01285 for ( i = 0; i < free_ent; i++ ) {
01286 ent = i;
01287 c = tab_suffixof(ent);
01288 if ( isascii(c) && isprint(c) )
01289 fprintf( stderr, "%5d: %5d/'%c' \"",
01290 ent, tab_prefixof(ent), c );
01291 else
01292 fprintf( stderr, "%5d: %5d/\\%03o \"",
01293 ent, tab_prefixof(ent), c );
01294 stack[--stack_top] = '\n';
01295 stack[--stack_top] = '"';
01296 for ( ; ent != NULL;
01297 ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) {
01298 stack_top = in_stack(tab_suffixof(ent), stack_top);
01299 }
01300 fwrite( &stack[stack_top], (size_t)1, (size_t)(STACK_SIZE - stack_top), stderr );
01301 stack_top = STACK_SIZE;
01302 }
01303 }
01304 }
01305
01306 int
01307 in_stack(c, stack_top)
01308 REGISTER int c, stack_top;
01309 {
01310 if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) {
01311 stack[--stack_top] = c;
01312 } else {
01313 switch( c ) {
01314 case '\n': stack[--stack_top] = 'n'; break;
01315 case '\t': stack[--stack_top] = 't'; break;
01316 case '\b': stack[--stack_top] = 'b'; break;
01317 case '\f': stack[--stack_top] = 'f'; break;
01318 case '\r': stack[--stack_top] = 'r'; break;
01319 case '\\': stack[--stack_top] = '\\'; break;
01320 default:
01321 stack[--stack_top] = '0' + c % 8;
01322 stack[--stack_top] = '0' + (c / 8) % 8;
01323 stack[--stack_top] = '0' + c / 64;
01324 break;
01325 }
01326 stack[--stack_top] = '\\';
01327 }
01328 if (stack_top<0) {
01329 fprintf(stderr,"dump_tab stack overflow!!!\n");
01330 exit(1);
01331 }
01332 return stack_top;
01333 }
01334 #else
01335 dump_tab() {}
01336 #endif
01337 #endif
01338 #endif
01339
01340 void writeerr()
01341 {
01342 perror ( ofname );
01343 unlink ( ofname );
01344 exit ( 1 );
01345 }
01346
01347 void copystat(ifname, ofname)
01348 char *ifname, *ofname;
01349 {
01350 struct stat statbuf;
01351 int mode;
01352 #ifndef AZTEC86
01353 time_t timep[2];
01354 #else
01355 unsigned long timep[2];
01356 #endif
01357 fflush(stdout);
01358 close(fileno(stdout));
01359 if (stat(ifname, &statbuf))
01360 {
01361 perror(ifname);
01362 return;
01363 }
01364 #ifndef PCDOS
01365
01366 if ((statbuf.st_mode & S_IFMT) != S_IFREG)
01367 {
01368 if(quiet)
01369 fprintf(stderr, "%s: ", ifname);
01370 fprintf(stderr, " -- not a regular file: unchanged");
01371 exit_stat = 1;
01372 } else if (statbuf.st_nlink > 1)
01373 {
01374 if(quiet)
01375 fprintf(stderr, "%s: ", ifname);
01376 fprintf(stderr, " -- has %d other links: unchanged",
01377 statbuf.st_nlink - 1);
01378 exit_stat = 1;
01379 } else
01380 #endif
01381 if (exit_stat == 2 && (!force))
01382 {
01383 if(!quiet)
01384 fprintf(stderr, " -- file unchanged");
01385 } else
01386 {
01387 exit_stat = 0;
01388 #ifndef PCDOS
01389 mode = statbuf.st_mode & 07777;
01390 #else
01391 mode = statbuf.st_attr & 07777;
01392 #endif
01393 if (chmod(ofname, mode))
01394 perror(ofname);
01395 #ifndef PCDOS
01396 chown(ofname, statbuf.st_uid, statbuf.st_gid);
01397 timep[0] = statbuf.st_atime;
01398 timep[1] = statbuf.st_mtime;
01399 #else
01400 timep[0] = statbuf.st_mtime;
01401 timep[1] = statbuf.st_mtime;
01402 #endif
01403 utime(ofname, (struct utimbuf *)timep);
01404
01405
01406
01407
01408 if(!quiet)
01409 if(do_decomp == 0)
01410 fprintf(stderr, " -- compressed to %s", ofname);
01411 else
01412 fprintf(stderr, " -- decompressed to %s", ofname);
01413 return;
01414 }
01415
01416
01417 if (unlink(ofname))
01418 perror(ofname);
01419 }
01420
01421
01422
01423
01424 int foreground()
01425 {
01426 #ifndef METAWARE
01427 if(bgnd_flag) {
01428 return(0);
01429 } else {
01430 #endif
01431 if(isatty(2)) {
01432 return(1);
01433 } else {
01434 return(0);
01435 }
01436 #ifndef METAWARE
01437 }
01438 #endif
01439 }
01440 #ifndef METAWARE
01441 void onintr (dummy)
01442 int dummy;
01443 {
01444 (void)signal(SIGINT,SIG_IGN);
01445 unlink ( ofname );
01446 exit ( 1 );
01447 }
01448
01449 void oops (dummy)
01450 int dummy;
01451 {
01452 (void)signal(SIGSEGV,SIG_IGN);
01453 if ( do_decomp == 1 )
01454 fprintf ( stderr, "uncompress: corrupt input\n" );
01455 unlink ( ofname );
01456 exit ( 1 );
01457 }
01458 #endif
01459 void cl_block ()
01460 {
01461 REGISTER long int rat;
01462
01463 checkpoint = in_count + CHECK_GAP;
01464 #ifdef DEBUG
01465 if ( debug ) {
01466 fprintf ( stderr, "count: %ld, ratio: ", in_count );
01467 prratio ( stderr, in_count, bytes_out );
01468 fprintf ( stderr, "\n");
01469 }
01470 #endif
01471
01472 if(in_count > 0x007fffff) {
01473 rat = bytes_out >> 8;
01474 if(rat == 0) {
01475 rat = 0x7fffffff;
01476 } else {
01477 rat = in_count / rat;
01478 }
01479 } else {
01480 rat = (in_count << 8) / bytes_out;
01481 }
01482 if ( rat > ratio ) {
01483 ratio = rat;
01484 } else {
01485 ratio = 0;
01486 #ifdef DEBUG
01487 if(verbose)
01488 dump_tab();
01489 #endif
01490 cl_hash ( (count_int) hsize );
01491 free_ent = FIRST;
01492 clear_flg = 1;
01493 output ( (code_int) CLEAR );
01494 #ifdef DEBUG
01495 if(debug)
01496 fprintf ( stderr, "clear\n" );
01497 #endif
01498 }
01499 }
01500
01501 void cl_hash(hsize)
01502 REGISTER count_int hsize;
01503 {
01504 #ifdef AZTEC86
01505 #ifdef PCDOS
01506
01507 memset(htab,-1, hsize * sizeof(count_int));
01508 #else
01509
01510 #ifndef XENIX_16
01511 REGISTER count_int *htab_p = htab+hsize;
01512 #else
01513 REGISTER j;
01514 REGISTER long k = hsize;
01515 REGISTER count_int *htab_p;
01516 #endif
01517 REGISTER long i;
01518 REGISTER long m1 = -1;
01519
01520 #ifdef XENIX_16
01521 for(j=0; j<=8 && k>=0; j++,k-=8192)
01522 {
01523 i = 8192;
01524 if(k < 8192)
01525 {
01526 i = k;
01527 }
01528 htab_p = &(htab[j][i]);
01529 i -= 16;
01530 if(i > 0)
01531 {
01532 #else
01533 i = hsize - 16;
01534 #endif
01535 do
01536 {
01537 *(htab_p-16) = m1;
01538 *(htab_p-15) = m1;
01539 *(htab_p-14) = m1;
01540 *(htab_p-13) = m1;
01541 *(htab_p-12) = m1;
01542 *(htab_p-11) = m1;
01543 *(htab_p-10) = m1;
01544 *(htab_p-9) = m1;
01545 *(htab_p-8) = m1;
01546 *(htab_p-7) = m1;
01547 *(htab_p-6) = m1;
01548 *(htab_p-5) = m1;
01549 *(htab_p-4) = m1;
01550 *(htab_p-3) = m1;
01551 *(htab_p-2) = m1;
01552 *(htab_p-1) = m1;
01553 htab_p -= 16;
01554 } while ((i -= 16) >= 0);
01555 #ifdef XENIX_16
01556 }
01557 }
01558 #endif
01559 for ( i += 16; i > 0; i-- )
01560 *--htab_p = m1;
01561 #endif
01562 #endif
01563 }
01564
01565 void prratio(stream, num, den)
01566 FILE *stream;
01567 long int num;
01568 long int den;
01569 {
01570 REGISTER int q;
01571 if(num > 214748L)
01572 {
01573 q = (int)(num / (den / 10000L));
01574 } else
01575 {
01576 q = (int)(10000L * num / den);
01577 }
01578 if (q < 0)
01579 {
01580 putc('-', stream);
01581 q = -q;
01582 }
01583 fprintf(stream, "%d.%02d%c", q / 100, q % 100, '%');
01584 }
01585
01586 void version()
01587 {
01588 fprintf(stderr, "compress 4.1\n");
01589 fprintf(stderr, "Options: ");
01590 #ifdef vax
01591 fprintf(stderr, "vax, ");
01592 #endif
01593 #ifdef _MINIX
01594 fprintf(stderr, "MINIX, ");
01595 #endif
01596 #ifdef NO_UCHAR
01597 fprintf(stderr, "NO_UCHAR, ");
01598 #endif
01599 #ifdef SIGNED_COMPARE_SLOW
01600 fprintf(stderr, "SIGNED_COMPARE_SLOW, ");
01601 #endif
01602 #ifdef XENIX_16
01603 fprintf(stderr, "XENIX_16, ");
01604 #endif
01605 #ifdef COMPATIBLE
01606 fprintf(stderr, "COMPATIBLE, ");
01607 #endif
01608 #ifdef DEBUG
01609 fprintf(stderr, "DEBUG, ");
01610 #endif
01611 #ifdef BSD4_2
01612 fprintf(stderr, "BSD4_2, ");
01613 #endif
01614 fprintf(stderr, "BITS = %d\n", BITS);
01615 }
01616
01617