xref: /titanic_44/usr/src/cmd/compress/compress.c (revision ace1a5f11236a072fca1b5e0ea1416a083a9f2aa)
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