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