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