1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 7 /* All Rights Reserved */ 8 9 10 /* 11 * Copyright (c) 1986 Regents of the University of California. 12 * All rights reserved. The Berkeley software License Agreement 13 * specifies the terms and conditions for redistribution. 14 */ 15 16 /* 17 * Copyright (c) 2018, Joyent, Inc. 18 */ 19 20 /* 21 * Compress - data compression program 22 */ 23 #define min(a, b) ((a > b) ? b : a) 24 25 /* 26 * machine variants which require cc -Dmachine: pdp11, z8000, pcxt 27 */ 28 29 /* 30 * Set USERMEM to the maximum amount of physical user memory available 31 * in bytes. USERMEM is used to determine the maximum BITS that can be used 32 * for compression. 33 * 34 * SACREDMEM is the amount of physical memory saved for others; compress 35 * will hog the rest. 36 */ 37 #ifndef SACREDMEM 38 #define SACREDMEM 0 39 #endif 40 41 #ifndef USERMEM 42 #define USERMEM 450000 /* default user memory */ 43 #endif 44 45 #ifdef USERMEM 46 #if USERMEM >= (433484+SACREDMEM) 47 #define PBITS 16 48 #else 49 #if USERMEM >= (229600+SACREDMEM) 50 #define PBITS 15 51 #else 52 #if USERMEM >= (127536+SACREDMEM) 53 #define PBITS 14 54 #else 55 #if USERMEM >= (73464+SACREDMEM) 56 #define PBITS 13 57 #else 58 #define PBITS 12 59 #endif 60 #endif 61 #endif 62 #endif 63 #undef USERMEM 64 #endif /* USERMEM */ 65 66 #ifdef PBITS /* Preferred BITS for this memory size */ 67 #ifndef BITS 68 #define BITS PBITS 69 #endif /* BITS */ 70 #endif /* PBITS */ 71 72 #if BITS == 16 73 #define HSIZE 69001 /* 95% occupancy */ 74 #endif 75 #if BITS == 15 76 #define HSIZE 35023 /* 94% occupancy */ 77 #endif 78 #if BITS == 14 79 #define HSIZE 18013 /* 91% occupancy */ 80 #endif 81 #if BITS == 13 82 #define HSIZE 9001 /* 91% occupancy */ 83 #endif 84 #if BITS <= 12 85 #define HSIZE 5003 /* 80% occupancy */ 86 #endif 87 88 #define OUTSTACKSIZE (2<<BITS) 89 90 /* 91 * a code_int must be able to hold 2**BITS values of type int, and also -1 92 */ 93 #if BITS > 15 94 typedef long int code_int; 95 #else 96 typedef int code_int; 97 #endif 98 99 typedef long int count_int; 100 typedef long long count_long; 101 102 typedef unsigned char char_type; 103 104 static char_type magic_header[] = { "\037\235" }; /* 1F 9D */ 105 106 /* Defines for third byte of header */ 107 #define BIT_MASK 0x1f 108 #define BLOCK_MASK 0x80 109 /* 110 * Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is 111 * a fourth header byte(for expansion). 112 */ 113 #define INIT_BITS 9 /* initial number of bits/code */ 114 115 /* 116 * compress.c - File compression ala IEEE Computer, June 1984. 117 */ 118 static char rcs_ident[] = 119 "$Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release $"; 120 121 #include <ctype.h> 122 #include <signal.h> 123 #include <sys/param.h> 124 #include <locale.h> 125 #include <langinfo.h> 126 #include <sys/acl.h> 127 #include <utime.h> 128 #include <libgen.h> 129 #include <setjmp.h> 130 #include <aclutils.h> 131 #include <libcmdutils.h> 132 #include "getresponse.h" 133 134 135 static int n_bits; /* number of bits/code */ 136 static int maxbits = BITS; /* user settable max # bits/code */ 137 static code_int maxcode; /* maximum code, given n_bits */ 138 /* should NEVER generate this code */ 139 static code_int maxmaxcode = 1 << BITS; 140 #define MAXCODE(n_bits) ((1 << (n_bits)) - 1) 141 142 static count_int htab [OUTSTACKSIZE]; 143 static unsigned short codetab [OUTSTACKSIZE]; 144 145 #define htabof(i) htab[i] 146 #define codetabof(i) codetab[i] 147 static code_int hsize = HSIZE; /* for dynamic table sizing */ 148 static off_t fsize; /* file size of input file */ 149 150 /* 151 * To save much memory, we overlay the table used by compress() with those 152 * used by decompress(). The tab_prefix table is the same size and type 153 * as the codetab. The tab_suffix table needs 2**BITS characters. We 154 * get this from the beginning of htab. The output stack uses the rest 155 * of htab, and contains characters. There is plenty of room for any 156 * possible stack (stack used to be 8000 characters). 157 */ 158 159 #define tab_prefixof(i) codetabof(i) 160 #define tab_suffixof(i) ((char_type *)(htab))[i] 161 #define de_stack ((char_type *)&tab_suffixof(1<<BITS)) 162 #define stack_max ((char_type *)&tab_suffixof(OUTSTACKSIZE)) 163 164 static code_int free_ent = 0; /* first unused entry */ 165 static int newline_needed = 0; 166 static int didnt_shrink = 0; 167 static int perm_stat = 0; /* permanent status */ 168 169 static code_int getcode(); 170 171 /* Use a 3-byte magic number header, unless old file */ 172 static int nomagic = 0; 173 /* Write output on stdout, suppress messages */ 174 static int zcat_flg = 0; /* use stdout on all files */ 175 static int zcat_cmd = 0; /* zcat cmd */ 176 static int use_stdout = 0; /* set for each file processed */ 177 /* Don't unlink output file on interrupt */ 178 static int precious = 1; 179 static int quiet = 1; /* don't tell me about compression */ 180 181 /* 182 * block compression parameters -- after all codes are used up, 183 * and compression rate changes, start over. 184 */ 185 static int block_compress = BLOCK_MASK; 186 static int clear_flg = 0; 187 static long int ratio = 0; 188 #define CHECK_GAP 10000 /* ratio check interval */ 189 static count_long checkpoint = CHECK_GAP; 190 /* 191 * the next two codes should not be changed lightly, as they must not 192 * lie within the contiguous general code space. 193 */ 194 #define FIRST 257 /* first free entry */ 195 #define CLEAR 256 /* table clear output code */ 196 197 static int force = 0; 198 static char ofname [MAXPATHLEN]; 199 200 static int Vflg = 0; 201 static int vflg = 0; 202 static int qflg = 0; 203 static int bflg = 0; 204 static int Fflg = 0; 205 static int dflg = 0; 206 static int cflg = 0; 207 static int Cflg = 0; 208 209 #ifdef DEBUG 210 int verbose = 0; 211 int debug = 0; 212 #endif /* DEBUG */ 213 214 static void (*oldint)(); 215 static int bgnd_flag; 216 217 static int do_decomp = 0; 218 219 static char *progname; 220 static char *optstr; 221 /* 222 * Fix lint errors 223 */ 224 225 static char *local_basename(char *); 226 227 static int addDotZ(char *, size_t); 228 229 static void Usage(void); 230 static void cl_block(count_long); 231 static void cl_hash(count_int); 232 static void compress(void); 233 static void copystat(char *, struct stat *, char *); 234 static void decompress(void); 235 static void ioerror(void); 236 static void onintr(); 237 static void oops(); 238 static void output(code_int); 239 static void prratio(FILE *, count_long, count_long); 240 static void version(void); 241 242 #ifdef DEBUG 243 static int in_stack(int, int); 244 static void dump_tab(void); 245 static void printcodes(void); 246 #endif 247 248 /* For error-handling */ 249 250 static jmp_buf env; 251 252 /* For input and ouput */ 253 254 static FILE *inp; /* the current input file */ 255 static FILE *infile; /* disk-based input stream */ 256 static FILE *outp; /* current output file */ 257 static FILE *outfile; /* disk-based output stream */ 258 259 /* For output() */ 260 261 static char buf[BITS]; 262 263 static char_type lmask[9] = 264 {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; 265 static char_type rmask[9] = 266 {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; 267 268 /* For compress () */ 269 270 static int offset; 271 static count_long bytes_out; /* length of compressed output */ 272 /* # of codes output (for debugging) */ 273 274 /* For dump_tab() */ 275 276 #define STACK_SIZE 15000 277 #ifdef DEBUG 278 code_int sorttab[1<<BITS]; /* sorted pointers into htab */ 279 #endif 280 281 /* Extended system attribute support */ 282 283 static int saflg = 0; 284 285 /* 286 * ************************************************************* 287 * TAG( main ) 288 * 289 * Algorithm from "A Technique for High Performance Data Compression", 290 * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19. 291 * 292 * Usage: compress [-dfvc/] [-b bits] [file ...] 293 * Inputs: 294 * -d: If given, decompression is done instead. 295 * 296 * -c: Write output on stdout, don't remove original. 297 * 298 * -b: Parameter limits the max number of bits/code. 299 * 300 * -f: Forces output file to be generated, even if one already 301 * exists, and even if no space is saved by compressing. 302 * If -f is not used, the user will be prompted if stdin is 303 * a tty, otherwise, the output file will not be overwritten. 304 * 305 * -/ Copies extended attributes and extended system attributes. 306 * 307 * -v: Write compression statistics 308 * 309 * file ...: Files to be compressed. If none specified, stdin 310 * is used. 311 * Outputs: 312 * file.Z: Compressed form of file with same mode, owner, and utimes 313 * or stdout (if stdin used as input) 314 * 315 * Assumptions: 316 * When filenames are given, replaces with the compressed version 317 * (.Z suffix) only if the file decreases in size. 318 * Algorithm: 319 * Modified Lempel-Ziv method (LZW). Basically finds common 320 * substrings and replaces them with a variable size code. This is 321 * deterministic, and can be done on the fly. Thus, the decompression 322 * procedure needs no input table, but tracks the way the table was built. 323 */ 324 325 int 326 main(int argc, char *argv[]) 327 { 328 int overwrite = 0; /* Do not overwrite unless given -f flag */ 329 char tempname[MAXPATHLEN]; 330 char line[LINE_MAX]; 331 char **filelist, **fileptr; 332 char *cp; 333 struct stat statbuf; 334 struct stat ostatbuf; 335 int ch; /* XCU4 */ 336 char *p; 337 extern int optind, optopt; 338 extern char *optarg; 339 int dash_count = 0; /* times "-" is on cmdline */ 340 341 /* XCU4 changes */ 342 (void) setlocale(LC_ALL, ""); 343 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 344 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 345 #endif 346 (void) textdomain(TEXT_DOMAIN); 347 348 if (init_yes() < 0) { 349 (void) fprintf(stderr, gettext(ERR_MSG_INIT_YES), 350 strerror(errno)); 351 exit(1); 352 } 353 354 /* This bg check only works for sh. */ 355 if ((oldint = signal(SIGINT, SIG_IGN)) != SIG_IGN) { 356 (void) signal(SIGINT, onintr); 357 (void) signal(SIGSEGV, oops); 358 } 359 bgnd_flag = oldint != SIG_DFL; 360 361 /* Allocate room for argv + "-" (if stdin needs to be added) */ 362 363 filelist = fileptr = (char **)(malloc((argc + 1) * sizeof (*argv))); 364 *filelist = NULL; 365 366 if ((cp = rindex(argv[0], '/')) != 0) { 367 cp++; 368 } else { 369 cp = argv[0]; 370 } 371 372 if (strcmp(cp, "uncompress") == 0) { 373 do_decomp = 1; 374 } else if (strcmp(cp, "zcat") == 0) { 375 do_decomp = 1; 376 zcat_cmd = zcat_flg = 1; 377 } 378 379 progname = local_basename(argv[0]); 380 381 /* 382 * Argument Processing 383 * All flags are optional. 384 * -D = > debug 385 * -V = > print Version; debug verbose 386 * -d = > do_decomp 387 * -v = > unquiet 388 * -f = > force overwrite of output file 389 * -n = > no header: useful to uncompress old files 390 * -b maxbits => maxbits. If -b is specified, 391 * then maxbits MUST be given also. 392 * -c = > cat all output to stdout 393 * -C = > generate output compatible with compress 2.0. 394 * if a string is left, must be an input filename. 395 */ 396 #ifdef DEBUG 397 optstr = "b:cCdDfFnqvV/"; 398 #else 399 optstr = "b:cCdfFnqvV/"; 400 #endif 401 402 while ((ch = getopt(argc, argv, optstr)) != EOF) { 403 /* Process all flags in this arg */ 404 switch (ch) { 405 #ifdef DEBUG 406 case 'D': 407 debug = 1; 408 break; 409 case 'V': 410 verbose = 1; 411 version(); 412 break; 413 #else 414 case 'V': 415 version(); 416 Vflg++; 417 break; 418 #endif /* DEBUG */ 419 case 'v': 420 quiet = 0; 421 vflg++; 422 break; 423 case 'd': 424 do_decomp = 1; 425 dflg++; 426 break; 427 case 'f': 428 case 'F': 429 Fflg++; 430 overwrite = 1; 431 force = 1; 432 break; 433 case 'n': 434 nomagic = 1; 435 break; 436 case 'C': 437 Cflg++; 438 block_compress = 0; 439 break; 440 case 'b': 441 bflg++; 442 p = optarg; 443 if (!p) { 444 (void) fprintf(stderr, gettext( 445 "Missing maxbits\n")); 446 Usage(); 447 exit(1); 448 } 449 maxbits = strtoul(optarg, &p, 10); 450 if (*p) { 451 (void) fprintf(stderr, gettext( 452 "Missing maxbits\n")); 453 Usage(); 454 exit(1); 455 } 456 break; 457 458 case 'c': 459 cflg++; 460 zcat_flg = 1; 461 break; 462 case 'q': 463 qflg++; 464 quiet = 1; 465 break; 466 case '/': 467 saflg++; 468 break; 469 default: 470 (void) fprintf(stderr, gettext( 471 "Unknown flag: '%c'\n"), optopt); 472 Usage(); 473 exit(1); 474 } 475 } /* while */ 476 477 /* 478 * Validate zcat syntax 479 */ 480 481 if (zcat_cmd && (Fflg | Cflg | cflg | 482 bflg | qflg | dflg | nomagic)) { 483 (void) fprintf(stderr, gettext( 484 "Invalid Option\n")); 485 Usage(); 486 exit(1); 487 } 488 489 /* 490 * Process the file list 491 */ 492 493 for (; optind < argc; optind++) { 494 if (strcmp(argv[optind], "-") == 0) { 495 dash_count++; 496 } 497 498 *fileptr++ = argv[optind]; /* Build input file list */ 499 *fileptr = NULL; 500 } 501 502 if (dash_count > 1) { 503 (void) fprintf(stderr, 504 gettext("%s may only appear once in the file" 505 " list\n"), "\"-\""); 506 exit(1); 507 } 508 509 if (fileptr - filelist == 0) { 510 *fileptr++ = "-"; 511 *fileptr = NULL; 512 } 513 514 if (fileptr - filelist > 1 && cflg && !do_decomp) { 515 (void) fprintf(stderr, 516 gettext("compress: only one file may be compressed" 517 " to stdout\n")); 518 exit(1); 519 } 520 521 if (maxbits < INIT_BITS) 522 maxbits = INIT_BITS; 523 if (maxbits > BITS) 524 maxbits = BITS; 525 maxmaxcode = 1 << maxbits; 526 527 /* Need to open something to close with freopen later */ 528 529 if ((infile = fopen("/dev/null", "r")) == NULL) { 530 (void) fprintf(stderr, gettext("Error opening /dev/null for " 531 "input\n")); 532 exit(1); 533 } 534 535 if ((outfile = fopen("/dev/null", "w")) == NULL) { 536 (void) fprintf(stderr, gettext("Error opening /dev/null for " 537 "output\n")); 538 exit(1); 539 } 540 541 for (fileptr = filelist; *fileptr; fileptr++) { 542 int jmpval = 0; 543 didnt_shrink = 0; 544 newline_needed = 0; 545 546 if (do_decomp) { 547 /* DECOMPRESSION */ 548 549 if (strcmp(*fileptr, "-") == 0) { 550 /* process stdin */ 551 inp = stdin; 552 outp = stdout; 553 use_stdout = 1; 554 *fileptr = "stdin"; /* for error messages */ 555 } else { 556 /* process the named file */ 557 558 inp = infile; 559 outp = outfile; 560 use_stdout = 0; 561 562 if (zcat_flg) { 563 use_stdout = 1; 564 outp = stdout; 565 } 566 567 /* Check for .Z suffix */ 568 569 if (strcmp(*fileptr + 570 strlen(*fileptr) - 2, ".Z") != 0) { 571 /* No .Z: tack one on */ 572 573 if (strlcpy(tempname, *fileptr, 574 sizeof (tempname)) >= 575 sizeof (tempname)) { 576 (void) fprintf(stderr, 577 gettext("%s: filename " 578 "too long\n"), 579 *fileptr); 580 perm_stat = 1; 581 continue; 582 } 583 584 if (addDotZ(tempname, 585 sizeof (tempname)) < 0) { 586 perm_stat = 1; 587 continue; 588 } 589 590 *fileptr = tempname; 591 } 592 593 /* Open input file */ 594 595 if (stat(*fileptr, &statbuf) < 0) { 596 perror(*fileptr); 597 perm_stat = 1; 598 continue; 599 } 600 601 if ((freopen(*fileptr, "r", inp)) == NULL) { 602 perror(*fileptr); 603 perm_stat = 1; 604 continue; 605 } 606 } 607 608 /* Check the magic number */ 609 610 if (nomagic == 0) { 611 if ((getc(inp) != 612 (magic_header[0] & 0xFF)) || 613 (getc(inp) != 614 (magic_header[1] & 0xFF))) { 615 (void) fprintf(stderr, gettext( 616 "%s: not in compressed " 617 "format\n"), 618 *fileptr); 619 perm_stat = 1; 620 continue; 621 } 622 623 /* set -b from file */ 624 if ((maxbits = getc(inp)) == EOF && 625 ferror(inp)) { 626 perror(*fileptr); 627 perm_stat = 1; 628 continue; 629 } 630 631 block_compress = maxbits & BLOCK_MASK; 632 maxbits &= BIT_MASK; 633 maxmaxcode = 1 << maxbits; 634 635 if (maxbits > BITS) { 636 (void) fprintf(stderr, 637 gettext("%s: compressed " 638 "with %d bits, " 639 "can only handle" 640 " %d bits\n"), 641 *fileptr, maxbits, BITS); 642 perm_stat = 1; 643 continue; 644 } 645 } 646 647 if (!use_stdout) { 648 /* Generate output filename */ 649 650 if (strlcpy(ofname, *fileptr, 651 sizeof (ofname)) >= 652 sizeof (ofname)) { 653 (void) fprintf(stderr, 654 gettext("%s: filename " 655 "too long\n"), 656 *fileptr); 657 perm_stat = 1; 658 continue; 659 } 660 661 /* Strip off .Z */ 662 663 ofname[strlen(*fileptr) - 2] = '\0'; 664 } 665 } else { 666 /* COMPRESSION */ 667 668 if (strcmp(*fileptr, "-") == 0) { 669 /* process stdin */ 670 inp = stdin; 671 outp = stdout; 672 use_stdout = 1; 673 *fileptr = "stdin"; /* for error messages */ 674 675 /* Use the largest possible hash table */ 676 hsize = HSIZE; 677 } else { 678 /* process the named file */ 679 680 inp = infile; 681 outp = outfile; 682 use_stdout = 0; 683 684 if (zcat_flg) { 685 use_stdout = 1; 686 outp = stdout; 687 } 688 689 if (strcmp(*fileptr + 690 strlen(*fileptr) - 2, ".Z") == 0) { 691 (void) fprintf(stderr, gettext( 692 "%s: already has .Z " 693 "suffix -- no change\n"), 694 *fileptr); 695 perm_stat = 1; 696 continue; 697 } 698 /* Open input file */ 699 700 if (stat(*fileptr, &statbuf) < 0) { 701 perror(*fileptr); 702 perm_stat = 1; 703 continue; 704 } 705 706 if ((freopen(*fileptr, "r", inp)) == NULL) { 707 perror(*fileptr); 708 perm_stat = 1; 709 continue; 710 } 711 712 fsize = (off_t)statbuf.st_size; 713 714 /* 715 * tune hash table size for small 716 * files -- ad hoc, 717 * but the sizes match earlier #defines, which 718 * serve as upper bounds on the number of 719 * output codes. 720 */ 721 hsize = HSIZE; 722 if (fsize < (1 << 12)) 723 hsize = min(5003, HSIZE); 724 else if (fsize < (1 << 13)) 725 hsize = min(9001, HSIZE); 726 else if (fsize < (1 << 14)) 727 hsize = min(18013, HSIZE); 728 else if (fsize < (1 << 15)) 729 hsize = min(35023, HSIZE); 730 else if (fsize < 47000) 731 hsize = min(50021, HSIZE); 732 733 if (!use_stdout) { 734 /* Generate output filename */ 735 736 if (strlcpy(ofname, *fileptr, 737 sizeof (ofname)) >= 738 sizeof (ofname)) { 739 (void) fprintf(stderr, 740 gettext("%s: filename " 741 "too long\n"), 742 *fileptr); 743 perm_stat = 1; 744 continue; 745 } 746 747 if (addDotZ(ofname, 748 sizeof (ofname)) < 0) { 749 perm_stat = 1; 750 continue; 751 } 752 } 753 } 754 } /* if (do_decomp) */ 755 756 /* Check for overwrite of existing file */ 757 758 if (!overwrite && !use_stdout) { 759 if (stat(ofname, &ostatbuf) == 0) { 760 (void) fprintf(stderr, gettext( 761 "%s already exists;"), ofname); 762 if (bgnd_flag == 0 && isatty(2)) { 763 int cin; 764 765 (void) fprintf(stderr, gettext( 766 " do you wish to overwr" 767 "ite %s (%s or %s)? "), 768 ofname, yesstr, nostr); 769 (void) fflush(stderr); 770 for (cin = 0; cin < LINE_MAX; cin++) 771 line[cin] = 0; 772 (void) read(2, line, LINE_MAX); 773 774 if (yes_check(line) == 0) { 775 (void) fprintf(stderr, 776 gettext( 777 "\tnot overwri" 778 "tten\n")); 779 continue; 780 } 781 } else { 782 /* 783 * XPG4: Assertion 1009 784 * Standard input is not 785 * terminal, and no '-f', 786 * and file exists. 787 */ 788 789 (void) fprintf(stderr, gettext( 790 "%s: File exists, -f not" 791 " specified, and ru" 792 "nning in the backgro" 793 "und.\n"), *fileptr); 794 perm_stat = 1; 795 continue; 796 } 797 } 798 } 799 if (!use_stdout) { 800 if ((pathconf(ofname, _PC_XATTR_EXISTS) == 1) || 801 (saflg && sysattr_support(ofname, 802 _PC_SATTR_EXISTS) == 1)) { 803 (void) unlink(ofname); 804 } 805 /* Open output file */ 806 if (freopen(ofname, "w", outp) == NULL) { 807 perror(ofname); 808 perm_stat = 1; 809 continue; 810 } 811 precious = 0; 812 if (!quiet) { 813 (void) fprintf(stderr, "%s: ", 814 *fileptr); 815 newline_needed = 1; 816 } 817 } else if (!quiet && !do_decomp) { 818 (void) fprintf(stderr, "%s: ", 819 *fileptr); 820 newline_needed = 1; 821 } 822 823 /* Actually do the compression/decompression */ 824 825 if ((jmpval = setjmp(env)) == 0) { 826 /* We'll see how things go */ 827 #ifndef DEBUG 828 if (do_decomp == 0) { 829 compress(); 830 } else { 831 decompress(); 832 } 833 #else 834 if (do_decomp == 0) { 835 compress(); 836 } else if (debug == 0) { 837 decompress(); 838 } else { 839 printcodes(); 840 } 841 842 if (verbose) { 843 dump_tab(); 844 } 845 #endif 846 } else { 847 /* 848 * Things went badly - clean up and go on. 849 * jmpval's values break down as follows: 850 * 1 == message determined by ferror() values. 851 * 2 == input problem message needed. 852 * 3 == output problem message needed. 853 */ 854 855 if (ferror(inp) || jmpval == 2) { 856 if (do_decomp) { 857 (void) fprintf(stderr, gettext( 858 "uncompress: %s: corrupt" 859 " input\n"), *fileptr); 860 } else { 861 perror(*fileptr); 862 } 863 } 864 865 if (ferror(outp) || jmpval == 3) { 866 /* handle output errors */ 867 868 if (use_stdout) { 869 perror(""); 870 } else { 871 perror(ofname); 872 } 873 } 874 875 if (ofname[0] != '\0') { 876 if (unlink(ofname) < 0) { 877 perror(ofname); 878 } 879 880 ofname[0] = '\0'; 881 } 882 883 perm_stat = 1; 884 continue; 885 } 886 887 /* Things went well */ 888 889 if (!use_stdout) { 890 /* Copy stats */ 891 copystat(*fileptr, &statbuf, ofname); 892 precious = 1; 893 if (newline_needed) { 894 (void) putc('\n', stderr); 895 } 896 /* 897 * Print the info. for unchanged file 898 * when no -v 899 */ 900 901 if (didnt_shrink) { 902 if (!force && perm_stat == 0) { 903 if (quiet) { 904 (void) fprintf(stderr, gettext( 905 "%s: -- file " 906 "unchanged\n"), 907 *fileptr); 908 } 909 910 perm_stat = 2; 911 } 912 } 913 } else { 914 if (didnt_shrink && !force && perm_stat == 0) { 915 perm_stat = 2; 916 } 917 918 if (newline_needed) { 919 (void) fprintf(stderr, "\n"); 920 } 921 } 922 } /* for */ 923 924 return (perm_stat); 925 } 926 927 static void 928 cinterr(int hshift) 929 { 930 /* we have exceeded the hash table */ 931 (void) fprintf(stderr, 932 "internal error: hashtable exceeded - hsize = %ld\n", hsize); 933 (void) fprintf(stderr, "hshift = %d, %d\n", hshift, (1 << hshift) -1); 934 (void) fprintf(stderr, "maxbits = %d\n", maxbits); 935 (void) fprintf(stderr, "n_bits = %d\n", n_bits); 936 (void) fprintf(stderr, "maxcode = %ld\n", maxcode); 937 longjmp(env, 1); 938 } 939 940 static code_int 941 adjusti(code_int i, code_int hsize_reg) 942 { 943 while (i < 0) { 944 i += hsize_reg; 945 } 946 947 while (i >= hsize_reg) { 948 i -= hsize_reg; 949 } 950 return (i); 951 } 952 953 /* 954 * compress inp to outp 955 * 956 * Algorithm: use open addressing double hashing(no chaining) on the 957 * prefix code / next character combination. We do a variant of Knuth's 958 * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime 959 * secondary probe. Here, the modular division first probe is gives way 960 * to a faster exclusive-or manipulation. Also do block compression with 961 * an adaptive reset, whereby the code table is cleared when the compression 962 * ratio decreases, but after the table fills. The variable-length output 963 * codes are re-sized at this point, and a special CLEAR code is generated 964 * for the decompressor. Late addition: construct the table according to 965 * file size for noticeable speed improvement on small files. Please direct 966 * questions about this implementation to ames!jaw. 967 */ 968 969 static void 970 compress() 971 { 972 long fcode; 973 code_int i = 0; 974 int c; 975 code_int ent; 976 int disp; 977 code_int hsize_reg; 978 int hshift; 979 int probecnt; 980 count_long in_count; 981 uint32_t inchi, inclo; 982 int maxbits_reg; 983 FILE *fin = inp; 984 #ifdef DEBUG 985 count_long out_count = 0; 986 #endif 987 988 if (nomagic == 0) { 989 if ((putc(magic_header[0], outp) == EOF || 990 putc(magic_header[1], outp) == EOF || 991 putc((char)(maxbits | block_compress), 992 outp) == EOF) && 993 ferror(outp)) { 994 ioerror(); 995 } 996 } 997 998 offset = 0; 999 bytes_out = 3; /* includes 3-byte header mojo */ 1000 clear_flg = 0; 1001 ratio = 0; 1002 in_count = 1; 1003 inchi = 0; 1004 inclo = 1; 1005 checkpoint = CHECK_GAP; 1006 maxcode = MAXCODE(n_bits = INIT_BITS); 1007 free_ent = ((block_compress) ? FIRST : 256); 1008 1009 if ((ent = getc(fin)) == EOF && ferror(fin)) { 1010 ioerror(); 1011 } 1012 1013 hshift = 0; 1014 1015 for (fcode = (long)hsize; fcode < 65536L; fcode *= 2L) 1016 hshift++; 1017 1018 hshift = 8 - hshift; /* set hash code range bound */ 1019 1020 hsize_reg = hsize; 1021 maxbits_reg = maxbits; 1022 1023 cl_hash((count_int) hsize_reg); /* clear hash table */ 1024 1025 while ((c = getc(fin)) != EOF) { 1026 if (++inclo == 0) 1027 inchi++; 1028 fcode = (long)(((long)c << maxbits_reg) + ent); 1029 i = ((c << hshift) ^ ent); /* xor hashing */ 1030 1031 if ((unsigned int)i >= hsize_reg) 1032 i = adjusti(i, hsize_reg); 1033 1034 if (htabof(i) == fcode) { 1035 ent = codetabof(i); 1036 continue; 1037 } else if ((long)htabof(i) < 0) { 1038 /* empty slot */ 1039 goto nomatch; 1040 } 1041 1042 /* secondary hash (after G. Knott) */ 1043 disp = hsize_reg - i; 1044 1045 if (i == 0) { 1046 disp = 1; 1047 } 1048 1049 probecnt = 0; 1050 probe: 1051 if (++probecnt > hsize_reg) 1052 cinterr(hshift); 1053 1054 if ((i -= disp) < 0) { 1055 while (i < 0) 1056 i += hsize_reg; 1057 } 1058 1059 if (htabof(i) == fcode) { 1060 ent = codetabof(i); 1061 continue; 1062 } 1063 1064 if ((long)htabof(i) > 0) { 1065 goto probe; 1066 } 1067 nomatch: 1068 output((code_int) ent); 1069 #ifdef DEBUG 1070 out_count++; 1071 #endif 1072 ent = c; 1073 if (free_ent < maxmaxcode) { 1074 codetabof(i) = free_ent++; 1075 /* code -> hashtable */ 1076 htabof(i) = fcode; 1077 } else { 1078 in_count = ((long long)inchi<<32|inclo); 1079 if ((count_long)in_count >= 1080 (count_long)checkpoint && block_compress) { 1081 cl_block(in_count); 1082 } 1083 } 1084 } 1085 1086 in_count = ((long long)inchi<<32|inclo); 1087 1088 if (ferror(fin) != 0) { 1089 ioerror(); 1090 } 1091 1092 /* 1093 * Put out the final code. 1094 */ 1095 output((code_int)ent); 1096 #ifdef DEBUG 1097 out_count++; 1098 #endif 1099 1100 output((code_int)-1); 1101 1102 /* 1103 * Print out stats on stderr 1104 */ 1105 if (!quiet) { 1106 #ifdef DEBUG 1107 (void) fprintf(stderr, 1108 "%lld chars in, %lld codes (%lld bytes) out, " 1109 "compression factor: ", 1110 (count_long)in_count, (count_long)out_count, 1111 (count_long) bytes_out); 1112 prratio(stderr, (count_long)in_count, 1113 (count_long)bytes_out); 1114 (void) fprintf(stderr, "\n"); 1115 (void) fprintf(stderr, "\tCompression as in compact: "); 1116 prratio(stderr, 1117 (count_long)in_count-(count_long)bytes_out, 1118 (count_long)in_count); 1119 (void) fprintf(stderr, "\n"); 1120 (void) fprintf(stderr, 1121 "\tLargest code (of last block) was %d" 1122 " (%d bits)\n", 1123 free_ent - 1, n_bits); 1124 #else /* !DEBUG */ 1125 (void) fprintf(stderr, gettext("Compression: ")); 1126 prratio(stderr, 1127 (count_long)in_count-(count_long)bytes_out, 1128 (count_long)in_count); 1129 #endif /* DEBUG */ 1130 } 1131 /* report if no savings */ 1132 if ((count_long)bytes_out > (count_long)in_count) { 1133 didnt_shrink = 1; 1134 } 1135 } 1136 1137 /* 1138 * ************************************************************** 1139 * TAG(output) 1140 * 1141 * Output the given code. 1142 * Inputs: 1143 * code: A n_bits-bit integer. If == -1, then EOF. This assumes 1144 * that n_bits = < (long)wordsize - 1. 1145 * Outputs: 1146 * Outputs code to the file. 1147 * Assumptions: 1148 * Chars are 8 bits long. 1149 * Algorithm: 1150 * Maintain a BITS character long buffer(so that 8 codes will 1151 * fit in it exactly). Use the VAX insv instruction to insert each 1152 * code in turn. When the buffer fills up empty it and start over. 1153 */ 1154 1155 static void 1156 output(code_int code) 1157 { 1158 #ifdef DEBUG 1159 static int col = 0; 1160 #endif /* DEBUG */ 1161 1162 int r_off = offset, bits = n_bits; 1163 char *bp = buf; 1164 1165 #ifdef DEBUG 1166 if (verbose) 1167 (void) fprintf(stderr, "%5d%c", code, 1168 (col += 6) >= 74 ? (col = 0, '\n') : ' '); 1169 #endif /* DEBUG */ 1170 if (code >= 0) { 1171 /* 1172 * byte/bit numbering on the VAX is simulated 1173 * by the following code 1174 */ 1175 /* 1176 * Get to the first byte. 1177 */ 1178 bp += (r_off >> 3); 1179 r_off &= 7; 1180 /* 1181 * Since code is always >= 8 bits, only need to mask the first 1182 * hunk on the left. 1183 */ 1184 *bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off]; 1185 bp++; 1186 bits -= (8 - r_off); 1187 code >>= 8 - r_off; 1188 /* 1189 * Get any 8 bit parts in the middle (<=1 for up to 16 1190 * bits). 1191 */ 1192 if (bits >= 8) { 1193 *bp++ = code; 1194 code >>= 8; 1195 bits -= 8; 1196 } 1197 /* Last bits. */ 1198 if (bits) 1199 *bp = code; 1200 offset += n_bits; 1201 if (offset == (n_bits << 3)) { 1202 bp = buf; 1203 bits = n_bits; 1204 bytes_out += bits; 1205 do { 1206 if (putc(*bp, outp) == EOF && 1207 ferror(outp)) { 1208 ioerror(); 1209 } 1210 bp++; 1211 } while (--bits); 1212 offset = 0; 1213 } 1214 1215 /* 1216 * If the next entry is going to be too big for the code size, 1217 * then increase it, if possible. 1218 */ 1219 if (free_ent > maxcode || (clear_flg > 0)) { 1220 /* 1221 * Write the whole buffer, because the input 1222 * side won't discover the size increase until 1223 * after it has read it. 1224 */ 1225 if (offset > 0) { 1226 if (fwrite(buf, 1, n_bits, outp) != n_bits) { 1227 longjmp(env, 3); 1228 } 1229 bytes_out += n_bits; 1230 } 1231 offset = 0; 1232 1233 if (clear_flg) { 1234 maxcode = MAXCODE(n_bits = INIT_BITS); 1235 clear_flg = 0; 1236 } else { 1237 n_bits++; 1238 if (n_bits == maxbits) 1239 maxcode = maxmaxcode; 1240 else 1241 maxcode = MAXCODE(n_bits); 1242 } 1243 #ifdef DEBUG 1244 if (debug) { 1245 (void) fprintf(stderr, 1246 "\nChange to %d bits\n", n_bits); 1247 col = 0; 1248 } 1249 #endif /* DEBUG */ 1250 } 1251 } else { 1252 /* 1253 * At EOF, write the rest of the buffer. 1254 */ 1255 if (offset > 0) { 1256 if (fwrite(buf, 1, (offset + 7) / 8, outp) == 0 && 1257 ferror(outp)) { 1258 ioerror(); 1259 } 1260 bytes_out += (offset + 7) / 8; 1261 } 1262 offset = 0; 1263 (void) fflush(outp); 1264 #ifdef DEBUG 1265 if (verbose) 1266 (void) fprintf(stderr, "\n"); 1267 #endif /* DEBUG */ 1268 if (ferror(outp)) 1269 ioerror(); 1270 } 1271 } 1272 1273 /* 1274 * Decompress inp to outp. This routine adapts to the codes in the 1275 * file building the "string" table on-the-fly; requiring no table to 1276 * be stored in the compressed file. The tables used herein are shared 1277 * with those of the compress() routine. See the definitions above. 1278 */ 1279 1280 static void 1281 decompress() 1282 { 1283 char_type *stackp, *stack_lim; 1284 int finchar; 1285 code_int code, oldcode, incode; 1286 FILE *fout = outp; 1287 1288 /* 1289 * As above, initialize the first 256 entries in the table. 1290 */ 1291 maxcode = MAXCODE(n_bits = INIT_BITS); 1292 for (code = 255; code >= 0; code--) { 1293 tab_prefixof(code) = 0; 1294 tab_suffixof(code) = (char_type)code; 1295 } 1296 free_ent = ((block_compress) ? FIRST : 256); 1297 1298 finchar = oldcode = getcode(); 1299 if (oldcode == -1) /* EOF already? */ 1300 return; /* Get out of here */ 1301 /* first code must be 8 bits = char */ 1302 if (putc((char)finchar, outp) == EOF && ferror(outp)) { 1303 /* Crash if can't write */ 1304 ioerror(); 1305 } 1306 stackp = de_stack; 1307 stack_lim = stack_max; 1308 1309 while ((code = getcode()) > -1) { 1310 1311 if ((code == CLEAR) && block_compress) { 1312 for (code = 255; code >= 0; code--) 1313 tab_prefixof(code) = 0; 1314 clear_flg = 1; 1315 free_ent = FIRST - 1; 1316 if ((code = getcode()) == -1) /* O, untimely death! */ 1317 break; 1318 } 1319 incode = code; 1320 /* 1321 * Special case for KwKwK string. 1322 */ 1323 if (code >= free_ent) { 1324 if (stackp < stack_lim) { 1325 *stackp++ = (char_type) finchar; 1326 code = oldcode; 1327 } else { 1328 /* badness */ 1329 longjmp(env, 2); 1330 } 1331 } 1332 1333 /* 1334 * Generate output characters in reverse order 1335 */ 1336 while (code >= 256) { 1337 if (stackp < stack_lim) { 1338 *stackp++ = tab_suffixof(code); 1339 code = tab_prefixof(code); 1340 } else { 1341 /* badness */ 1342 longjmp(env, 2); 1343 } 1344 } 1345 *stackp++ = finchar = tab_suffixof(code); 1346 1347 /* 1348 * And put them out in forward order 1349 */ 1350 do { 1351 stackp--; 1352 (void) putc(*stackp, fout); 1353 } while (stackp > de_stack); 1354 1355 if (ferror(fout)) 1356 ioerror(); 1357 1358 /* 1359 * Generate the new entry. 1360 */ 1361 if ((code = free_ent) < maxmaxcode) { 1362 tab_prefixof(code) = (unsigned short) oldcode; 1363 tab_suffixof(code) = (char_type) finchar; 1364 free_ent = code+1; 1365 } 1366 /* 1367 * Remember previous code. 1368 */ 1369 oldcode = incode; 1370 } 1371 (void) fflush(outp); 1372 if (ferror(outp)) 1373 ioerror(); 1374 } 1375 1376 /* 1377 * ************************************************************** 1378 * TAG( getcode ) 1379 * 1380 * Read one code from the standard input. If EOF, return -1. 1381 * Inputs: 1382 * inp 1383 * Outputs: 1384 * code or -1 is returned. 1385 */ 1386 1387 code_int 1388 getcode() { 1389 code_int code; 1390 static int offset = 0, size = 0; 1391 static char_type buf[BITS]; 1392 int r_off, bits; 1393 char_type *bp = buf; 1394 1395 if (clear_flg > 0 || offset >= size || free_ent > maxcode) { 1396 /* 1397 * If the next entry will be too big for the current code 1398 * size, then we must increase the size. This implies reading 1399 * a new buffer full, too. 1400 */ 1401 if (free_ent > maxcode) { 1402 n_bits++; 1403 if (n_bits == maxbits) 1404 /* won't get any bigger now */ 1405 maxcode = maxmaxcode; 1406 else 1407 maxcode = MAXCODE(n_bits); 1408 } 1409 if (clear_flg > 0) { 1410 maxcode = MAXCODE(n_bits = INIT_BITS); 1411 clear_flg = 0; 1412 } 1413 size = fread(buf, 1, n_bits, inp); 1414 1415 if (size <= 0) { 1416 if (feof(inp)) { 1417 /* end of file */ 1418 return (-1); 1419 } else if (ferror(inp)) { 1420 ioerror(); 1421 } 1422 } 1423 1424 offset = 0; 1425 /* Round size down to integral number of codes */ 1426 size = (size << 3) - (n_bits - 1); 1427 } 1428 r_off = offset; 1429 bits = n_bits; 1430 /* 1431 * Get to the first byte. 1432 */ 1433 bp += (r_off >> 3); 1434 r_off &= 7; 1435 /* Get first part (low order bits) */ 1436 code = (*bp++ >> r_off); 1437 bits -= (8 - r_off); 1438 r_off = 8 - r_off; /* now, offset into code word */ 1439 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ 1440 if (bits >= 8) { 1441 code |= *bp++ << r_off; 1442 r_off += 8; 1443 bits -= 8; 1444 } 1445 /* high order bits. */ 1446 code |= (*bp & rmask[bits]) << r_off; 1447 offset += n_bits; 1448 1449 return (code); 1450 } 1451 1452 #ifdef DEBUG 1453 static void 1454 printcodes() 1455 { 1456 /* 1457 * Just print out codes from input file. For debugging. 1458 */ 1459 code_int code; 1460 int col = 0, bits; 1461 1462 bits = n_bits = INIT_BITS; 1463 maxcode = MAXCODE(n_bits); 1464 free_ent = ((block_compress) ? FIRST : 256); 1465 while ((code = getcode()) >= 0) { 1466 if ((code == CLEAR) && block_compress) { 1467 free_ent = FIRST - 1; 1468 clear_flg = 1; 1469 } else if (free_ent < maxmaxcode) 1470 free_ent++; 1471 if (bits != n_bits) { 1472 (void) fprintf(stderr, "\nChange to %d bits\n", n_bits); 1473 bits = n_bits; 1474 col = 0; 1475 } 1476 (void) fprintf(stderr, "%5d%c", 1477 code, (col += 6) >= 74 ? (col = 0, '\n') : ' '); 1478 } 1479 (void) putc('\n', stderr); 1480 } 1481 1482 #endif /* DEBUG */ 1483 1484 #ifdef DEBUG 1485 static void 1486 dump_tab() /* dump string table */ 1487 { 1488 int i, first; 1489 int ent; 1490 int stack_top = STACK_SIZE; 1491 int c; 1492 1493 if (do_decomp == 0) { /* compressing */ 1494 int flag = 1; 1495 1496 for (i = 0; i < hsize; i++) { /* build sort pointers */ 1497 if ((long)htabof(i) >= 0) { 1498 sorttab[codetabof(i)] = i; 1499 } 1500 } 1501 first = block_compress ? FIRST : 256; 1502 for (i = first; i < free_ent; i++) { 1503 (void) fprintf(stderr, "%5d: \"", i); 1504 de_stack[--stack_top] = '\n'; 1505 de_stack[--stack_top] = '"'; 1506 stack_top = 1507 in_stack((htabof(sorttab[i]) >> maxbits) & 0xff, 1508 stack_top); 1509 for (ent = htabof(sorttab[i]) & ((1 << maxbits) -1); 1510 ent > 256; 1511 ent = htabof(sorttab[ent]) & ((1<<maxbits)-1)) { 1512 stack_top = in_stack( 1513 htabof(sorttab[ent]) >> maxbits, 1514 stack_top); 1515 } 1516 stack_top = in_stack(ent, stack_top); 1517 (void) fwrite(&de_stack[stack_top], 1, 1518 STACK_SIZE - stack_top, stderr); 1519 stack_top = STACK_SIZE; 1520 } 1521 } else if (!debug) { /* decompressing */ 1522 1523 for (i = 0; i < free_ent; i++) { 1524 ent = i; 1525 c = tab_suffixof(ent); 1526 if (isascii(c) && isprint(c)) 1527 (void) fprintf(stderr, "%5d: %5d/'%c' \"", 1528 ent, tab_prefixof(ent), c); 1529 else 1530 (void) fprintf(stderr, "%5d: %5d/\\%03o \"", 1531 ent, tab_prefixof(ent), c); 1532 de_stack[--stack_top] = '\n'; 1533 de_stack[--stack_top] = '"'; 1534 for (; ent != NULL; 1535 ent = (ent >= FIRST ? tab_prefixof(ent) : 1536 NULL)) { 1537 stack_top = in_stack(tab_suffixof(ent), 1538 stack_top); 1539 } 1540 (void) fwrite(&de_stack[stack_top], 1, 1541 STACK_SIZE - stack_top, stderr); 1542 stack_top = STACK_SIZE; 1543 } 1544 } 1545 } 1546 1547 #endif /* DEBUG */ 1548 #ifdef DEBUG 1549 static int 1550 in_stack(int c, int stack_top) 1551 { 1552 if ((isascii(c) && isprint(c) && c != '\\') || c == ' ') { 1553 de_stack[--stack_top] = c; 1554 } else { 1555 switch (c) { 1556 case '\n': de_stack[--stack_top] = 'n'; break; 1557 case '\t': de_stack[--stack_top] = 't'; break; 1558 case '\b': de_stack[--stack_top] = 'b'; break; 1559 case '\f': de_stack[--stack_top] = 'f'; break; 1560 case '\r': de_stack[--stack_top] = 'r'; break; 1561 case '\\': de_stack[--stack_top] = '\\'; break; 1562 default: 1563 de_stack[--stack_top] = '0' + c % 8; 1564 de_stack[--stack_top] = '0' + (c / 8) % 8; 1565 de_stack[--stack_top] = '0' + c / 64; 1566 break; 1567 } 1568 de_stack[--stack_top] = '\\'; 1569 } 1570 return (stack_top); 1571 } 1572 1573 #endif /* DEBUG */ 1574 static void 1575 ioerror() 1576 { 1577 longjmp(env, 1); 1578 } 1579 1580 static void 1581 copystat(char *ifname, struct stat *ifstat, char *ofname) 1582 { 1583 mode_t mode; 1584 struct utimbuf timep; 1585 acl_t *aclp = NULL; 1586 int error; 1587 int sattr_exist = 0; 1588 int xattr_exist = 0; 1589 1590 if (pathconf(ifname, _PC_XATTR_EXISTS) == 1) 1591 xattr_exist = 1; 1592 if (saflg && sysattr_support(ifname, _PC_SATTR_EXISTS) == 1) 1593 sattr_exist = 1; 1594 1595 if (fclose(outp)) { 1596 perror(ofname); 1597 if (!quiet) { 1598 (void) fprintf(stderr, gettext(" -- file unchanged")); 1599 newline_needed = 1; 1600 } 1601 perm_stat = 1; 1602 } else if (ifstat == NULL) { /* Get stat on input file */ 1603 perror(ifname); 1604 return; 1605 } else if ((ifstat->st_mode & 1606 S_IFMT /* 0170000 */) != S_IFREG /* 0100000 */) { 1607 if (quiet) { 1608 (void) fprintf(stderr, "%s: ", ifname); 1609 } 1610 (void) fprintf(stderr, gettext( 1611 " -- not a regular file: unchanged")); 1612 newline_needed = 1; 1613 perm_stat = 1; 1614 } else if (ifstat->st_nlink > 1) { 1615 if (quiet) { 1616 (void) fprintf(stderr, "%s: ", ifname); 1617 } 1618 (void) fprintf(stderr, gettext( 1619 " -- has %d other links: unchanged"), 1620 (uint_t)ifstat->st_nlink - 1); 1621 newline_needed = 1; 1622 perm_stat = 1; 1623 } else if (didnt_shrink && !force) { 1624 /* No compression: remove file.Z */ 1625 if (!quiet) { 1626 (void) fprintf(stderr, gettext( 1627 " -- file unchanged")); 1628 newline_needed = 1; 1629 } 1630 } else if ((xattr_exist || sattr_exist) && 1631 (mv_xattrs(progname, ifname, ofname, sattr_exist, 0) 1632 != 0)) { 1633 (void) fprintf(stderr, gettext( 1634 "%s: -- cannot preserve extended attributes or " 1635 "system attributes, file unchanged"), ifname); 1636 newline_needed = 1; 1637 /* Move attributes back ... */ 1638 xattr_exist = 0; 1639 sattr_exist = 0; 1640 if (pathconf(ofname, _PC_XATTR_EXISTS) == 1) 1641 xattr_exist = 1; 1642 if (saflg && sysattr_support(ofname, _PC_SATTR_EXISTS) == 1) 1643 sattr_exist = 1; 1644 if (sattr_exist || xattr_exist) 1645 (void) mv_xattrs(progname, ofname, ifname, 1646 sattr_exist, 1); 1647 perm_stat = 1; 1648 } else { /* ***** Successful Compression ***** */ 1649 mode = ifstat->st_mode & 07777; 1650 if (chmod(ofname, mode)) { /* Copy modes */ 1651 if (errno == EPERM) { 1652 (void) fprintf(stderr, 1653 gettext("failed to chmod %s" 1654 "- permisssion denied\n"), ofname); 1655 } 1656 perror(ofname); 1657 } 1658 error = acl_get(ifname, ACL_NO_TRIVIAL, &aclp); 1659 if (error != 0) { 1660 (void) fprintf(stderr, gettext( 1661 "%s: failed to retrieve acl : %s\n"), 1662 ifname, acl_strerror(error)); 1663 perm_stat = 1; 1664 } 1665 if (aclp && (acl_set(ofname, aclp) < 0)) { 1666 (void) fprintf(stderr, 1667 gettext("%s: failed to set acl " 1668 "entries\n"), ofname); 1669 perm_stat = 1; 1670 } 1671 if (aclp) { 1672 acl_free(aclp); 1673 aclp = NULL; 1674 } 1675 1676 /* Copy ownership */ 1677 (void) chown(ofname, ifstat->st_uid, ifstat->st_gid); 1678 timep.actime = ifstat->st_atime; 1679 timep.modtime = ifstat->st_mtime; 1680 /* Update last accessed and modified times */ 1681 (void) utime(ofname, &timep); 1682 if (unlink(ifname)) { /* Remove input file */ 1683 if (errno == EPERM) { 1684 (void) fprintf(stderr, 1685 gettext("failed to remove %s" 1686 "- permisssion denied\n"), ifname); 1687 } 1688 perror(ifname); 1689 } 1690 if (!quiet) { 1691 (void) fprintf(stderr, gettext( 1692 " -- replaced with %s"), ofname); 1693 newline_needed = 1; 1694 } 1695 return; /* Successful return */ 1696 } 1697 1698 /* Unsuccessful return -- one of the tests failed */ 1699 if (ofname[0] != '\0') { 1700 if (unlink(ofname)) { 1701 if (errno == EPERM) { 1702 (void) fprintf(stderr, 1703 gettext("failed to remove %s" 1704 "- permisssion denied\n"), ifname); 1705 } 1706 perror(ofname); 1707 } 1708 1709 ofname[0] = '\0'; 1710 } 1711 } 1712 1713 static void 1714 onintr() 1715 { 1716 if (!precious && !use_stdout && ofname[0] != '\0') 1717 (void) unlink(ofname); 1718 exit(1); 1719 } 1720 1721 static void 1722 oops() /* wild pointer -- assume bad input */ 1723 { 1724 if (do_decomp) { 1725 (void) fprintf(stderr, gettext("uncompress: corrupt input\n")); 1726 } 1727 1728 if (!use_stdout && ofname[0] != '\0') { 1729 (void) unlink(ofname); 1730 } 1731 1732 exit(1); 1733 } 1734 1735 static void 1736 cl_block(count_long in_count) /* table clear for block compress */ 1737 { 1738 count_long rat; 1739 1740 checkpoint = (count_long)in_count + (count_long)CHECK_GAP; 1741 #ifdef DEBUG 1742 if (debug) { 1743 (void) fprintf(stderr, "count: %lld, ratio: ", 1744 (count_long)in_count); 1745 prratio(stderr, (count_long)in_count, (count_long)bytes_out); 1746 (void) fprintf(stderr, "\n"); 1747 } 1748 #endif /* DEBUG */ 1749 1750 /* shift will overflow */ 1751 if ((count_long)in_count > 0x007fffffffffffffLL) { 1752 rat = (count_long)bytes_out >> 8; 1753 if (rat == 0) { /* Don't divide by zero */ 1754 rat = 0x7fffffffffffffffLL; 1755 } else { 1756 rat = (count_long)in_count / (count_long)rat; 1757 } 1758 } else { 1759 /* 8 fractional bits */ 1760 rat = ((count_long)in_count << 8) /(count_long)bytes_out; 1761 } 1762 if (rat > ratio) { 1763 ratio = rat; 1764 } else { 1765 ratio = 0; 1766 #ifdef DEBUG 1767 if (verbose) 1768 dump_tab(); /* dump string table */ 1769 #endif 1770 cl_hash((count_int) hsize); 1771 free_ent = FIRST; 1772 clear_flg = 1; 1773 output((code_int) CLEAR); 1774 #ifdef DEBUG 1775 if (debug) 1776 (void) fprintf(stderr, "clear\n"); 1777 #endif /* DEBUG */ 1778 } 1779 } 1780 1781 static void 1782 cl_hash(count_int hsize) /* reset code table */ 1783 { 1784 count_int *htab_p = htab+hsize; 1785 long i; 1786 long m1 = -1; 1787 1788 i = hsize - 16; 1789 do { /* might use Sys V memset(3) here */ 1790 *(htab_p-16) = m1; 1791 *(htab_p-15) = m1; 1792 *(htab_p-14) = m1; 1793 *(htab_p-13) = m1; 1794 *(htab_p-12) = m1; 1795 *(htab_p-11) = m1; 1796 *(htab_p-10) = m1; 1797 *(htab_p-9) = m1; 1798 *(htab_p-8) = m1; 1799 *(htab_p-7) = m1; 1800 *(htab_p-6) = m1; 1801 *(htab_p-5) = m1; 1802 *(htab_p-4) = m1; 1803 *(htab_p-3) = m1; 1804 *(htab_p-2) = m1; 1805 *(htab_p-1) = m1; 1806 htab_p -= 16; 1807 } while ((i -= 16) >= 0); 1808 1809 for (i += 16; i > 0; i--) 1810 *--htab_p = m1; 1811 } 1812 1813 static void 1814 prratio(FILE *stream, count_long num, count_long den) 1815 { 1816 int q; /* store percentage */ 1817 1818 q = (int)(10000LL * (count_long)num / (count_long)den); 1819 if (q < 0) { 1820 (void) putc('-', stream); 1821 q = -q; 1822 } 1823 (void) fprintf(stream, "%d%s%02d%%", q / 100, 1824 localeconv()->decimal_point, q % 100); 1825 } 1826 1827 static void 1828 version() 1829 { 1830 (void) fprintf(stderr, "%s, Berkeley 5.9 5/11/86\n", rcs_ident); 1831 (void) fprintf(stderr, "Options: "); 1832 #ifdef DEBUG 1833 (void) fprintf(stderr, "DEBUG, "); 1834 #endif 1835 (void) fprintf(stderr, "BITS = %d\n", BITS); 1836 } 1837 1838 static void 1839 Usage() 1840 { 1841 #ifdef DEBUG 1842 (void) fprintf(stderr, 1843 "Usage: compress [-dDVfc/] [-b maxbits] [file ...]\n"); 1844 #else 1845 if (strcmp(progname, "compress") == 0) { 1846 (void) fprintf(stderr, 1847 gettext( 1848 "Usage: compress [-fv/] [-b maxbits] [file ...]\n"\ 1849 " compress c [-fv] [-b maxbits] [file]\n")); 1850 } else if (strcmp(progname, "uncompress") == 0) 1851 (void) fprintf(stderr, gettext( 1852 "Usage: uncompress [-fv] [-c || -/] [file ...]\n")); 1853 else if (strcmp(progname, "zcat") == 0) 1854 (void) fprintf(stderr, gettext("Usage: zcat [file ...]\n")); 1855 1856 #endif /* DEBUG */ 1857 } 1858 1859 static char * 1860 local_basename(char *path) 1861 { 1862 char *p; 1863 char *ret = (char *)path; 1864 1865 while ((p = (char *)strpbrk(ret, "/")) != NULL) 1866 ret = p + 1; 1867 return (ret); 1868 } 1869 1870 static int 1871 addDotZ(char *fn, size_t fnsize) 1872 { 1873 char *fn_dup; 1874 char *dir; 1875 long int max_name; 1876 long int max_path; 1877 1878 fn_dup = strdup(fn); 1879 dir = dirname(fn_dup); 1880 max_name = pathconf(dir, _PC_NAME_MAX); 1881 max_path = pathconf(dir, _PC_PATH_MAX); 1882 free(fn_dup); 1883 1884 /* Check for component length too long */ 1885 1886 if ((strlen(local_basename(fn)) + 2) > (size_t)max_name) { 1887 (void) fprintf(stderr, 1888 gettext("%s: filename too long to tack on .Z:" 1889 " %s\n"), progname, fn); 1890 return (-1); 1891 } 1892 1893 /* Check for path length too long */ 1894 1895 if ((strlen(fn) + 2) > (size_t)max_path - 1) { 1896 (void) fprintf(stderr, 1897 gettext("%s: Pathname too long to tack on .Z:" 1898 " %s\n"), progname, fn); 1899 return (-1); 1900 } 1901 1902 if (strlcat(fn, ".Z", fnsize) >= fnsize) { 1903 (void) fprintf(stderr, 1904 gettext("%s: Buffer overflow adding .Z to %s\n"), 1905 progname, fn); 1906 return (-1); 1907 } 1908 1909 return (0); 1910 } 1911