2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
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.
17 * Compress - data compression program
19 #define min(a, b) ((a > b) ? b : a)
22 * machine variants which require cc -Dmachine: pdp11, z8000, pcxt
26 * Set USERMEM to the maximum amount of physical user memory available
27 * in bytes. USERMEM is used to determine the maximum BITS that can be used
30 * SACREDMEM is the amount of physical memory saved for others; compress
38 #define USERMEM 450000 /* default user memory */
42 #if USERMEM >= (433484+SACREDMEM)
45 #if USERMEM >= (229600+SACREDMEM)
48 #if USERMEM >= (127536+SACREDMEM)
51 #if USERMEM >= (73464+SACREDMEM)
62 #ifdef PBITS /* Preferred BITS for this memory size */
69 #define HSIZE 69001 /* 95% occupancy */
72 #define HSIZE 35023 /* 94% occupancy */
75 #define HSIZE 18013 /* 91% occupancy */
78 #define HSIZE 9001 /* 91% occupancy */
81 #define HSIZE 5003 /* 80% occupancy */
84 #define OUTSTACKSIZE (2<<BITS)
87 * a code_int must be able to hold 2**BITS values of type int, and also -1
90 typedef long int code_int
;
95 typedef long int count_int
;
96 typedef long long count_long
;
98 typedef unsigned char char_type
;
100 static char_type magic_header
[] = { "\037\235" }; /* 1F 9D */
102 /* Defines for third byte of header */
103 #define BIT_MASK 0x1f
104 #define BLOCK_MASK 0x80
106 * Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
107 * a fourth header byte(for expansion).
109 #define INIT_BITS 9 /* initial number of bits/code */
112 * compress.c - File compression ala IEEE Computer, June 1984.
114 static char rcs_ident
[] =
115 "$Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release $";
119 #include <sys/param.h>
121 #include <langinfo.h>
126 #include <aclutils.h>
127 #include <libcmdutils.h>
128 #include "getresponse.h"
131 static int n_bits
; /* number of bits/code */
132 static int maxbits
= BITS
; /* user settable max # bits/code */
133 static code_int maxcode
; /* maximum code, given n_bits */
134 /* should NEVER generate this code */
135 static code_int maxmaxcode
= 1 << BITS
;
136 #define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
138 static count_int htab
[OUTSTACKSIZE
];
139 static unsigned short codetab
[OUTSTACKSIZE
];
141 #define htabof(i) htab[i]
142 #define codetabof(i) codetab[i]
143 static code_int hsize
= HSIZE
; /* for dynamic table sizing */
144 static off_t fsize
; /* file size of input file */
147 * To save much memory, we overlay the table used by compress() with those
148 * used by decompress(). The tab_prefix table is the same size and type
149 * as the codetab. The tab_suffix table needs 2**BITS characters. We
150 * get this from the beginning of htab. The output stack uses the rest
151 * of htab, and contains characters. There is plenty of room for any
152 * possible stack (stack used to be 8000 characters).
155 #define tab_prefixof(i) codetabof(i)
156 #define tab_suffixof(i) ((char_type *)(htab))[i]
157 #define de_stack ((char_type *)&tab_suffixof(1<<BITS))
158 #define stack_max ((char_type *)&tab_suffixof(OUTSTACKSIZE))
160 static code_int free_ent
= 0; /* first unused entry */
161 static int newline_needed
= 0;
162 static int didnt_shrink
= 0;
163 static int perm_stat
= 0; /* permanent status */
165 static code_int
getcode();
167 /* Use a 3-byte magic number header, unless old file */
168 static int nomagic
= 0;
169 /* Write output on stdout, suppress messages */
170 static int zcat_flg
= 0; /* use stdout on all files */
171 static int zcat_cmd
= 0; /* zcat cmd */
172 static int use_stdout
= 0; /* set for each file processed */
173 /* Don't unlink output file on interrupt */
174 static int precious
= 1;
175 static int quiet
= 1; /* don't tell me about compression */
178 * block compression parameters -- after all codes are used up,
179 * and compression rate changes, start over.
181 static int block_compress
= BLOCK_MASK
;
182 static int clear_flg
= 0;
183 static long int ratio
= 0;
184 #define CHECK_GAP 10000 /* ratio check interval */
185 static count_long checkpoint
= CHECK_GAP
;
187 * the next two codes should not be changed lightly, as they must not
188 * lie within the contiguous general code space.
190 #define FIRST 257 /* first free entry */
191 #define CLEAR 256 /* table clear output code */
193 static int force
= 0;
194 static char ofname
[MAXPATHLEN
];
210 static void (*oldint
)();
211 static int bgnd_flag
;
213 static int do_decomp
= 0;
215 static char *progname
;
221 static char *local_basename(char *);
223 static int addDotZ(char *, size_t);
225 static void Usage(void);
226 static void cl_block(count_long
);
227 static void cl_hash(count_int
);
228 static void compress(void);
229 static void copystat(char *, struct stat
*, char *);
230 static void decompress(void);
231 static void ioerror(void);
232 static void onintr();
234 static void output(code_int
);
235 static void prratio(FILE *, count_long
, count_long
);
236 static void version(void);
239 static int in_stack(int, int);
240 static void dump_tab(void);
241 static void printcodes(void);
244 /* For error-handling */
248 /* For input and ouput */
250 static FILE *inp
; /* the current input file */
251 static FILE *infile
; /* disk-based input stream */
252 static FILE *outp
; /* current output file */
253 static FILE *outfile
; /* disk-based output stream */
257 static char buf
[BITS
];
259 static char_type lmask
[9] =
260 {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
261 static char_type rmask
[9] =
262 {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
264 /* For compress () */
267 static count_long bytes_out
; /* length of compressed output */
268 /* # of codes output (for debugging) */
272 #define STACK_SIZE 15000
274 code_int sorttab
[1<<BITS
]; /* sorted pointers into htab */
277 /* Extended system attribute support */
279 static int saflg
= 0;
282 * *************************************************************
285 * Algorithm from "A Technique for High Performance Data Compression",
286 * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
288 * Usage: compress [-dfvc/] [-b bits] [file ...]
290 * -d: If given, decompression is done instead.
292 * -c: Write output on stdout, don't remove original.
294 * -b: Parameter limits the max number of bits/code.
296 * -f: Forces output file to be generated, even if one already
297 * exists, and even if no space is saved by compressing.
298 * If -f is not used, the user will be prompted if stdin is
299 * a tty, otherwise, the output file will not be overwritten.
301 * -/ Copies extended attributes and extended system attributes.
303 * -v: Write compression statistics
305 * file ...: Files to be compressed. If none specified, stdin
308 * file.Z: Compressed form of file with same mode, owner, and utimes
309 * or stdout (if stdin used as input)
312 * When filenames are given, replaces with the compressed version
313 * (.Z suffix) only if the file decreases in size.
315 * Modified Lempel-Ziv method (LZW). Basically finds common
316 * substrings and replaces them with a variable size code. This is
317 * deterministic, and can be done on the fly. Thus, the decompression
318 * procedure needs no input table, but tracks the way the table was built.
322 main(int argc
, char *argv
[])
324 int overwrite
= 0; /* Do not overwrite unless given -f flag */
325 char tempname
[MAXPATHLEN
];
327 char **filelist
, **fileptr
;
330 struct stat ostatbuf
;
333 extern int optind
, optopt
;
335 int dash_count
= 0; /* times "-" is on cmdline */
338 (void) setlocale(LC_ALL
, "");
339 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
340 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
342 (void) textdomain(TEXT_DOMAIN
);
344 if (init_yes() < 0) {
345 (void) fprintf(stderr
, gettext(ERR_MSG_INIT_YES
),
350 /* This bg check only works for sh. */
351 if ((oldint
= signal(SIGINT
, SIG_IGN
)) != SIG_IGN
) {
352 (void) signal(SIGINT
, onintr
);
353 (void) signal(SIGSEGV
, oops
);
355 bgnd_flag
= oldint
!= SIG_DFL
;
357 /* Allocate room for argv + "-" (if stdin needs to be added) */
359 filelist
= fileptr
= (char **)(malloc((argc
+ 1) * sizeof (*argv
)));
362 if ((cp
= rindex(argv
[0], '/')) != 0) {
368 if (strcmp(cp
, "uncompress") == 0) {
370 } else if (strcmp(cp
, "zcat") == 0) {
372 zcat_cmd
= zcat_flg
= 1;
375 progname
= local_basename(argv
[0]);
378 * Argument Processing
379 * All flags are optional.
381 * -V = > print Version; debug verbose
384 * -f = > force overwrite of output file
385 * -n = > no header: useful to uncompress old files
386 * -b maxbits => maxbits. If -b is specified,
387 * then maxbits MUST be given also.
388 * -c = > cat all output to stdout
389 * -C = > generate output compatible with compress 2.0.
390 * if a string is left, must be an input filename.
393 optstr
= "b:cCdDfFnqvV/";
395 optstr
= "b:cCdfFnqvV/";
398 while ((ch
= getopt(argc
, argv
, optstr
)) != EOF
) {
399 /* Process all flags in this arg */
440 (void) fprintf(stderr
, gettext(
441 "Missing maxbits\n"));
445 maxbits
= strtoul(optarg
, &p
, 10);
447 (void) fprintf(stderr
, gettext(
448 "Missing maxbits\n"));
466 (void) fprintf(stderr
, gettext(
467 "Unknown flag: '%c'\n"), optopt
);
474 * Validate zcat syntax
477 if (zcat_cmd
&& (Fflg
| Cflg
| cflg
|
478 bflg
| qflg
| dflg
| nomagic
)) {
479 (void) fprintf(stderr
, gettext(
480 "Invalid Option\n"));
486 * Process the file list
489 for (; optind
< argc
; optind
++) {
490 if (strcmp(argv
[optind
], "-") == 0) {
494 *fileptr
++ = argv
[optind
]; /* Build input file list */
498 if (dash_count
> 1) {
499 (void) fprintf(stderr
,
500 gettext("%s may only appear once in the file"
501 " list\n"), "\"-\"");
505 if (fileptr
- filelist
== 0) {
510 if (fileptr
- filelist
> 1 && cflg
&& !do_decomp
) {
511 (void) fprintf(stderr
,
512 gettext("compress: only one file may be compressed"
517 if (maxbits
< INIT_BITS
)
521 maxmaxcode
= 1 << maxbits
;
523 /* Need to open something to close with freopen later */
525 if ((infile
= fopen("/dev/null", "r")) == NULL
) {
526 (void) fprintf(stderr
, gettext("Error opening /dev/null for "
531 if ((outfile
= fopen("/dev/null", "w")) == NULL
) {
532 (void) fprintf(stderr
, gettext("Error opening /dev/null for "
537 for (fileptr
= filelist
; *fileptr
; fileptr
++) {
545 if (strcmp(*fileptr
, "-") == 0) {
550 *fileptr
= "stdin"; /* for error messages */
552 /* process the named file */
563 /* Check for .Z suffix */
565 if (strcmp(*fileptr
+
566 strlen(*fileptr
) - 2, ".Z") != 0) {
567 /* No .Z: tack one on */
569 if (strlcpy(tempname
, *fileptr
,
570 sizeof (tempname
)) >=
572 (void) fprintf(stderr
,
573 gettext("%s: filename "
580 if (addDotZ(tempname
,
581 sizeof (tempname
)) < 0) {
589 /* Open input file */
591 if (stat(*fileptr
, &statbuf
) < 0) {
597 if ((freopen(*fileptr
, "r", inp
)) == NULL
) {
604 /* Check the magic number */
608 (magic_header
[0] & 0xFF)) ||
610 (magic_header
[1] & 0xFF))) {
611 (void) fprintf(stderr
, gettext(
612 "%s: not in compressed "
619 /* set -b from file */
620 if ((maxbits
= getc(inp
)) == EOF
&&
627 block_compress
= maxbits
& BLOCK_MASK
;
629 maxmaxcode
= 1 << maxbits
;
631 if (maxbits
> BITS
) {
632 (void) fprintf(stderr
,
633 gettext("%s: compressed "
637 *fileptr
, maxbits
, BITS
);
644 /* Generate output filename */
646 if (strlcpy(ofname
, *fileptr
,
649 (void) fprintf(stderr
,
650 gettext("%s: filename "
659 ofname
[strlen(*fileptr
) - 2] = '\0';
664 if (strcmp(*fileptr
, "-") == 0) {
669 *fileptr
= "stdin"; /* for error messages */
671 /* Use the largest possible hash table */
674 /* process the named file */
685 if (strcmp(*fileptr
+
686 strlen(*fileptr
) - 2, ".Z") == 0) {
687 (void) fprintf(stderr
, gettext(
688 "%s: already has .Z "
689 "suffix -- no change\n"),
694 /* Open input file */
696 if (stat(*fileptr
, &statbuf
) < 0) {
702 if ((freopen(*fileptr
, "r", inp
)) == NULL
) {
708 fsize
= (off_t
)statbuf
.st_size
;
711 * tune hash table size for small
713 * but the sizes match earlier #defines, which
714 * serve as upper bounds on the number of
718 if (fsize
< (1 << 12))
719 hsize
= min(5003, HSIZE
);
720 else if (fsize
< (1 << 13))
721 hsize
= min(9001, HSIZE
);
722 else if (fsize
< (1 << 14))
723 hsize
= min(18013, HSIZE
);
724 else if (fsize
< (1 << 15))
725 hsize
= min(35023, HSIZE
);
726 else if (fsize
< 47000)
727 hsize
= min(50021, HSIZE
);
730 /* Generate output filename */
732 if (strlcpy(ofname
, *fileptr
,
735 (void) fprintf(stderr
,
736 gettext("%s: filename "
744 sizeof (ofname
)) < 0) {
750 } /* if (do_decomp) */
752 /* Check for overwrite of existing file */
754 if (!overwrite
&& !use_stdout
) {
755 if (stat(ofname
, &ostatbuf
) == 0) {
756 (void) fprintf(stderr
, gettext(
757 "%s already exists;"), ofname
);
758 if (bgnd_flag
== 0 && isatty(2)) {
761 (void) fprintf(stderr
, gettext(
762 " do you wish to overwr"
765 (void) fflush(stderr
);
766 for (cin
= 0; cin
< LINE_MAX
; cin
++)
768 (void) read(2, line
, LINE_MAX
);
770 if (yes_check(line
) == 0) {
771 (void) fprintf(stderr
,
779 * XPG4: Assertion 1009
780 * Standard input is not
781 * terminal, and no '-f',
785 (void) fprintf(stderr
, gettext(
786 "%s: File exists, -f not"
788 "nning in the backgro"
789 "und.\n"), *fileptr
);
796 if ((pathconf(ofname
, _PC_XATTR_EXISTS
) == 1) ||
797 (saflg
&& sysattr_support(ofname
,
798 _PC_SATTR_EXISTS
) == 1)) {
799 (void) unlink(ofname
);
801 /* Open output file */
802 if (freopen(ofname
, "w", outp
) == NULL
) {
809 (void) fprintf(stderr
, "%s: ",
813 } else if (!quiet
&& !do_decomp
) {
814 (void) fprintf(stderr
, "%s: ",
819 /* Actually do the compression/decompression */
821 if ((jmpval
= setjmp(env
)) == 0) {
822 /* We'll see how things go */
824 if (do_decomp
== 0) {
830 if (do_decomp
== 0) {
832 } else if (debug
== 0) {
844 * Things went badly - clean up and go on.
845 * jmpval's values break down as follows:
846 * 1 == message determined by ferror() values.
847 * 2 == input problem message needed.
848 * 3 == output problem message needed.
851 if (ferror(inp
) || jmpval
== 2) {
853 (void) fprintf(stderr
, gettext(
854 "uncompress: %s: corrupt"
855 " input\n"), *fileptr
);
861 if (ferror(outp
) || jmpval
== 3) {
862 /* handle output errors */
871 if (ofname
[0] != '\0') {
872 if (unlink(ofname
) < 0) {
883 /* Things went well */
887 copystat(*fileptr
, &statbuf
, ofname
);
889 if (newline_needed
) {
890 (void) putc('\n', stderr
);
893 * Print the info. for unchanged file
898 if (!force
&& perm_stat
== 0) {
900 (void) fprintf(stderr
, gettext(
910 if (didnt_shrink
&& !force
&& perm_stat
== 0) {
914 if (newline_needed
) {
915 (void) fprintf(stderr
, "\n");
926 /* we have exceeded the hash table */
927 (void) fprintf(stderr
,
928 "internal error: hashtable exceeded - hsize = %ld\n", hsize
);
929 (void) fprintf(stderr
, "hshift = %d, %d\n", hshift
, (1 << hshift
) -1);
930 (void) fprintf(stderr
, "maxbits = %d\n", maxbits
);
931 (void) fprintf(stderr
, "n_bits = %d\n", n_bits
);
932 (void) fprintf(stderr
, "maxcode = %ld\n", maxcode
);
937 adjusti(code_int i
, code_int hsize_reg
)
943 while (i
>= hsize_reg
) {
950 * compress inp to outp
952 * Algorithm: use open addressing double hashing(no chaining) on the
953 * prefix code / next character combination. We do a variant of Knuth's
954 * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
955 * secondary probe. Here, the modular division first probe is gives way
956 * to a faster exclusive-or manipulation. Also do block compression with
957 * an adaptive reset, whereby the code table is cleared when the compression
958 * ratio decreases, but after the table fills. The variable-length output
959 * codes are re-sized at this point, and a special CLEAR code is generated
960 * for the decompressor. Late addition: construct the table according to
961 * file size for noticeable speed improvement on small files. Please direct
962 * questions about this implementation to ames!jaw.
977 uint32_t inchi
, inclo
;
981 count_long out_count
= 0;
985 if ((putc(magic_header
[0], outp
) == EOF
||
986 putc(magic_header
[1], outp
) == EOF
||
987 putc((char)(maxbits
| block_compress
),
995 bytes_out
= 3; /* includes 3-byte header mojo */
1001 checkpoint
= CHECK_GAP
;
1002 maxcode
= MAXCODE(n_bits
= INIT_BITS
);
1003 free_ent
= ((block_compress
) ? FIRST
: 256);
1005 if ((ent
= getc(fin
)) == EOF
&& ferror(fin
)) {
1011 for (fcode
= (long)hsize
; fcode
< 65536L; fcode
*= 2L)
1014 hshift
= 8 - hshift
; /* set hash code range bound */
1017 maxbits_reg
= maxbits
;
1019 cl_hash((count_int
) hsize_reg
); /* clear hash table */
1021 while ((c
= getc(fin
)) != EOF
) {
1024 fcode
= (long)(((long)c
<< maxbits_reg
) + ent
);
1025 i
= ((c
<< hshift
) ^ ent
); /* xor hashing */
1027 if ((unsigned int)i
>= hsize_reg
)
1028 i
= adjusti(i
, hsize_reg
);
1030 if (htabof(i
) == fcode
) {
1033 } else if ((long)htabof(i
) < 0) {
1038 /* secondary hash (after G. Knott) */
1039 disp
= hsize_reg
- i
;
1047 if (++probecnt
> hsize_reg
)
1050 if ((i
-= disp
) < 0) {
1055 if (htabof(i
) == fcode
) {
1060 if ((long)htabof(i
) > 0) {
1064 output((code_int
) ent
);
1069 if (free_ent
< maxmaxcode
) {
1070 codetabof(i
) = free_ent
++;
1071 /* code -> hashtable */
1074 in_count
= ((long long)inchi
<<32|inclo
);
1075 if ((count_long
)in_count
>=
1076 (count_long
)checkpoint
&& block_compress
) {
1082 in_count
= ((long long)inchi
<<32|inclo
);
1084 if (ferror(fin
) != 0) {
1089 * Put out the final code.
1091 output((code_int
)ent
);
1096 output((code_int
)-1);
1099 * Print out stats on stderr
1103 (void) fprintf(stderr
,
1104 "%lld chars in, %lld codes (%lld bytes) out, "
1105 "compression factor: ",
1106 (count_long
)in_count
, (count_long
)out_count
,
1107 (count_long
) bytes_out
);
1108 prratio(stderr
, (count_long
)in_count
,
1109 (count_long
)bytes_out
);
1110 (void) fprintf(stderr
, "\n");
1111 (void) fprintf(stderr
, "\tCompression as in compact: ");
1113 (count_long
)in_count
-(count_long
)bytes_out
,
1114 (count_long
)in_count
);
1115 (void) fprintf(stderr
, "\n");
1116 (void) fprintf(stderr
,
1117 "\tLargest code (of last block) was %d"
1119 free_ent
- 1, n_bits
);
1121 (void) fprintf(stderr
, gettext("Compression: "));
1123 (count_long
)in_count
-(count_long
)bytes_out
,
1124 (count_long
)in_count
);
1127 /* report if no savings */
1128 if ((count_long
)bytes_out
> (count_long
)in_count
) {
1134 * **************************************************************
1137 * Output the given code.
1139 * code: A n_bits-bit integer. If == -1, then EOF. This assumes
1140 * that n_bits = < (long)wordsize - 1.
1142 * Outputs code to the file.
1144 * Chars are 8 bits long.
1146 * Maintain a BITS character long buffer(so that 8 codes will
1147 * fit in it exactly). Use the VAX insv instruction to insert each
1148 * code in turn. When the buffer fills up empty it and start over.
1152 output(code_int code
)
1158 int r_off
= offset
, bits
= n_bits
;
1163 (void) fprintf(stderr
, "%5d%c", code
,
1164 (col
+= 6) >= 74 ? (col
= 0, '\n') : ' ');
1168 * byte/bit numbering on the VAX is simulated
1169 * by the following code
1172 * Get to the first byte.
1177 * Since code is always >= 8 bits, only need to mask the first
1180 *bp
= (*bp
& rmask
[r_off
]) | (code
<< r_off
) & lmask
[r_off
];
1182 bits
-= (8 - r_off
);
1185 * Get any 8 bit parts in the middle (<=1 for up to 16
1197 if (offset
== (n_bits
<< 3)) {
1202 if (putc(*bp
, outp
) == EOF
&&
1212 * If the next entry is going to be too big for the code size,
1213 * then increase it, if possible.
1215 if (free_ent
> maxcode
|| (clear_flg
> 0)) {
1217 * Write the whole buffer, because the input
1218 * side won't discover the size increase until
1219 * after it has read it.
1222 if (fwrite(buf
, 1, n_bits
, outp
) != n_bits
) {
1225 bytes_out
+= n_bits
;
1230 maxcode
= MAXCODE(n_bits
= INIT_BITS
);
1234 if (n_bits
== maxbits
)
1235 maxcode
= maxmaxcode
;
1237 maxcode
= MAXCODE(n_bits
);
1241 (void) fprintf(stderr
,
1242 "\nChange to %d bits\n", n_bits
);
1249 * At EOF, write the rest of the buffer.
1252 if (fwrite(buf
, 1, (offset
+ 7) / 8, outp
) == 0 &&
1256 bytes_out
+= (offset
+ 7) / 8;
1259 (void) fflush(outp
);
1262 (void) fprintf(stderr
, "\n");
1270 * Decompress inp to outp. This routine adapts to the codes in the
1271 * file building the "string" table on-the-fly; requiring no table to
1272 * be stored in the compressed file. The tables used herein are shared
1273 * with those of the compress() routine. See the definitions above.
1279 char_type
*stackp
, *stack_lim
;
1281 code_int code
, oldcode
, incode
;
1285 * As above, initialize the first 256 entries in the table.
1287 maxcode
= MAXCODE(n_bits
= INIT_BITS
);
1288 for (code
= 255; code
>= 0; code
--) {
1289 tab_prefixof(code
) = 0;
1290 tab_suffixof(code
) = (char_type
)code
;
1292 free_ent
= ((block_compress
) ? FIRST
: 256);
1294 finchar
= oldcode
= getcode();
1295 if (oldcode
== -1) /* EOF already? */
1296 return; /* Get out of here */
1297 /* first code must be 8 bits = char */
1298 if (putc((char)finchar
, outp
) == EOF
&& ferror(outp
)) {
1299 /* Crash if can't write */
1303 stack_lim
= stack_max
;
1305 while ((code
= getcode()) > -1) {
1307 if ((code
== CLEAR
) && block_compress
) {
1308 for (code
= 255; code
>= 0; code
--)
1309 tab_prefixof(code
) = 0;
1311 free_ent
= FIRST
- 1;
1312 if ((code
= getcode()) == -1) /* O, untimely death! */
1317 * Special case for KwKwK string.
1319 if (code
>= free_ent
) {
1320 if (stackp
< stack_lim
) {
1321 *stackp
++ = (char_type
) finchar
;
1330 * Generate output characters in reverse order
1332 while (code
>= 256) {
1333 if (stackp
< stack_lim
) {
1334 *stackp
++ = tab_suffixof(code
);
1335 code
= tab_prefixof(code
);
1341 *stackp
++ = finchar
= tab_suffixof(code
);
1344 * And put them out in forward order
1348 (void) putc(*stackp
, fout
);
1349 } while (stackp
> de_stack
);
1355 * Generate the new entry.
1357 if ((code
= free_ent
) < maxmaxcode
) {
1358 tab_prefixof(code
) = (unsigned short) oldcode
;
1359 tab_suffixof(code
) = (char_type
) finchar
;
1363 * Remember previous code.
1367 (void) fflush(outp
);
1373 * **************************************************************
1376 * Read one code from the standard input. If EOF, return -1.
1380 * code or -1 is returned.
1386 static int offset
= 0, size
= 0;
1387 static char_type buf
[BITS
];
1389 char_type
*bp
= buf
;
1391 if (clear_flg
> 0 || offset
>= size
|| free_ent
> maxcode
) {
1393 * If the next entry will be too big for the current code
1394 * size, then we must increase the size. This implies reading
1395 * a new buffer full, too.
1397 if (free_ent
> maxcode
) {
1399 if (n_bits
== maxbits
)
1400 /* won't get any bigger now */
1401 maxcode
= maxmaxcode
;
1403 maxcode
= MAXCODE(n_bits
);
1405 if (clear_flg
> 0) {
1406 maxcode
= MAXCODE(n_bits
= INIT_BITS
);
1409 size
= fread(buf
, 1, n_bits
, inp
);
1415 } else if (ferror(inp
)) {
1421 /* Round size down to integral number of codes */
1422 size
= (size
<< 3) - (n_bits
- 1);
1427 * Get to the first byte.
1431 /* Get first part (low order bits) */
1432 code
= (*bp
++ >> r_off
);
1433 bits
-= (8 - r_off
);
1434 r_off
= 8 - r_off
; /* now, offset into code word */
1435 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
1437 code
|= *bp
++ << r_off
;
1441 /* high order bits. */
1442 code
|= (*bp
& rmask
[bits
]) << r_off
;
1453 * Just print out codes from input file. For debugging.
1458 bits
= n_bits
= INIT_BITS
;
1459 maxcode
= MAXCODE(n_bits
);
1460 free_ent
= ((block_compress
) ? FIRST
: 256);
1461 while ((code
= getcode()) >= 0) {
1462 if ((code
== CLEAR
) && block_compress
) {
1463 free_ent
= FIRST
- 1;
1465 } else if (free_ent
< maxmaxcode
)
1467 if (bits
!= n_bits
) {
1468 (void) fprintf(stderr
, "\nChange to %d bits\n", n_bits
);
1472 (void) fprintf(stderr
, "%5d%c",
1473 code
, (col
+= 6) >= 74 ? (col
= 0, '\n') : ' ');
1475 (void) putc('\n', stderr
);
1482 dump_tab() /* dump string table */
1486 int stack_top
= STACK_SIZE
;
1489 if (do_decomp
== 0) { /* compressing */
1492 for (i
= 0; i
< hsize
; i
++) { /* build sort pointers */
1493 if ((long)htabof(i
) >= 0) {
1494 sorttab
[codetabof(i
)] = i
;
1497 first
= block_compress
? FIRST
: 256;
1498 for (i
= first
; i
< free_ent
; i
++) {
1499 (void) fprintf(stderr
, "%5d: \"", i
);
1500 de_stack
[--stack_top
] = '\n';
1501 de_stack
[--stack_top
] = '"';
1503 in_stack((htabof(sorttab
[i
]) >> maxbits
) & 0xff,
1505 for (ent
= htabof(sorttab
[i
]) & ((1 << maxbits
) -1);
1507 ent
= htabof(sorttab
[ent
]) & ((1<<maxbits
)-1)) {
1508 stack_top
= in_stack(
1509 htabof(sorttab
[ent
]) >> maxbits
,
1512 stack_top
= in_stack(ent
, stack_top
);
1513 (void) fwrite(&de_stack
[stack_top
], 1,
1514 STACK_SIZE
- stack_top
, stderr
);
1515 stack_top
= STACK_SIZE
;
1517 } else if (!debug
) { /* decompressing */
1519 for (i
= 0; i
< free_ent
; i
++) {
1521 c
= tab_suffixof(ent
);
1522 if (isascii(c
) && isprint(c
))
1523 (void) fprintf(stderr
, "%5d: %5d/'%c' \"",
1524 ent
, tab_prefixof(ent
), c
);
1526 (void) fprintf(stderr
, "%5d: %5d/\\%03o \"",
1527 ent
, tab_prefixof(ent
), c
);
1528 de_stack
[--stack_top
] = '\n';
1529 de_stack
[--stack_top
] = '"';
1531 ent
= (ent
>= FIRST
? tab_prefixof(ent
) :
1533 stack_top
= in_stack(tab_suffixof(ent
),
1536 (void) fwrite(&de_stack
[stack_top
], 1,
1537 STACK_SIZE
- stack_top
, stderr
);
1538 stack_top
= STACK_SIZE
;
1546 in_stack(int c
, int stack_top
)
1548 if ((isascii(c
) && isprint(c
) && c
!= '\\') || c
== ' ') {
1549 de_stack
[--stack_top
] = c
;
1552 case '\n': de_stack
[--stack_top
] = 'n'; break;
1553 case '\t': de_stack
[--stack_top
] = 't'; break;
1554 case '\b': de_stack
[--stack_top
] = 'b'; break;
1555 case '\f': de_stack
[--stack_top
] = 'f'; break;
1556 case '\r': de_stack
[--stack_top
] = 'r'; break;
1557 case '\\': de_stack
[--stack_top
] = '\\'; break;
1559 de_stack
[--stack_top
] = '0' + c
% 8;
1560 de_stack
[--stack_top
] = '0' + (c
/ 8) % 8;
1561 de_stack
[--stack_top
] = '0' + c
/ 64;
1564 de_stack
[--stack_top
] = '\\';
1577 copystat(char *ifname
, struct stat
*ifstat
, char *ofname
)
1580 struct utimbuf timep
;
1583 int sattr_exist
= 0;
1584 int xattr_exist
= 0;
1586 if (pathconf(ifname
, _PC_XATTR_EXISTS
) == 1)
1588 if (saflg
&& sysattr_support(ifname
, _PC_SATTR_EXISTS
) == 1)
1594 (void) fprintf(stderr
, gettext(" -- file unchanged"));
1598 } else if (ifstat
== NULL
) { /* Get stat on input file */
1601 } else if ((ifstat
->st_mode
&
1602 S_IFMT
/* 0170000 */) != S_IFREG
/* 0100000 */) {
1604 (void) fprintf(stderr
, "%s: ", ifname
);
1606 (void) fprintf(stderr
, gettext(
1607 " -- not a regular file: unchanged"));
1610 } else if (ifstat
->st_nlink
> 1) {
1612 (void) fprintf(stderr
, "%s: ", ifname
);
1614 (void) fprintf(stderr
, gettext(
1615 " -- has %d other links: unchanged"),
1616 (uint_t
)ifstat
->st_nlink
- 1);
1619 } else if (didnt_shrink
&& !force
) {
1620 /* No compression: remove file.Z */
1622 (void) fprintf(stderr
, gettext(
1623 " -- file unchanged"));
1626 } else if ((xattr_exist
|| sattr_exist
) &&
1627 (mv_xattrs(progname
, ifname
, ofname
, sattr_exist
, 0)
1629 (void) fprintf(stderr
, gettext(
1630 "%s: -- cannot preserve extended attributes or "
1631 "system attributes, file unchanged"), ifname
);
1633 /* Move attributes back ... */
1636 if (pathconf(ofname
, _PC_XATTR_EXISTS
) == 1)
1638 if (saflg
&& sysattr_support(ofname
, _PC_SATTR_EXISTS
) == 1)
1640 if (sattr_exist
|| xattr_exist
)
1641 (void) mv_xattrs(progname
, ofname
, ifname
,
1644 } else { /* ***** Successful Compression ***** */
1645 mode
= ifstat
->st_mode
& 07777;
1646 if (chmod(ofname
, mode
)) { /* Copy modes */
1647 if (errno
== EPERM
) {
1648 (void) fprintf(stderr
,
1649 gettext("failed to chmod %s"
1650 "- permisssion denied\n"), ofname
);
1654 error
= acl_get(ifname
, ACL_NO_TRIVIAL
, &aclp
);
1656 (void) fprintf(stderr
, gettext(
1657 "%s: failed to retrieve acl : %s\n"),
1658 ifname
, acl_strerror(error
));
1661 if (aclp
&& (acl_set(ofname
, aclp
) < 0)) {
1662 (void) fprintf(stderr
,
1663 gettext("%s: failed to set acl "
1664 "entries\n"), ofname
);
1672 /* Copy ownership */
1673 (void) chown(ofname
, ifstat
->st_uid
, ifstat
->st_gid
);
1674 timep
.actime
= ifstat
->st_atime
;
1675 timep
.modtime
= ifstat
->st_mtime
;
1676 /* Update last accessed and modified times */
1677 (void) utime(ofname
, &timep
);
1678 if (unlink(ifname
)) { /* Remove input file */
1679 if (errno
== EPERM
) {
1680 (void) fprintf(stderr
,
1681 gettext("failed to remove %s"
1682 "- permisssion denied\n"), ifname
);
1687 (void) fprintf(stderr
, gettext(
1688 " -- replaced with %s"), ofname
);
1691 return; /* Successful return */
1694 /* Unsuccessful return -- one of the tests failed */
1695 if (ofname
[0] != '\0') {
1696 if (unlink(ofname
)) {
1697 if (errno
== EPERM
) {
1698 (void) fprintf(stderr
,
1699 gettext("failed to remove %s"
1700 "- permisssion denied\n"), ifname
);
1712 if (!precious
&& !use_stdout
&& ofname
[0] != '\0')
1713 (void) unlink(ofname
);
1718 oops() /* wild pointer -- assume bad input */
1721 (void) fprintf(stderr
, gettext("uncompress: corrupt input\n"));
1724 if (!use_stdout
&& ofname
[0] != '\0') {
1725 (void) unlink(ofname
);
1732 cl_block(count_long in_count
) /* table clear for block compress */
1736 checkpoint
= (count_long
)in_count
+ (count_long
)CHECK_GAP
;
1739 (void) fprintf(stderr
, "count: %lld, ratio: ",
1740 (count_long
)in_count
);
1741 prratio(stderr
, (count_long
)in_count
, (count_long
)bytes_out
);
1742 (void) fprintf(stderr
, "\n");
1746 /* shift will overflow */
1747 if ((count_long
)in_count
> 0x007fffffffffffffLL
) {
1748 rat
= (count_long
)bytes_out
>> 8;
1749 if (rat
== 0) { /* Don't divide by zero */
1750 rat
= 0x7fffffffffffffffLL
;
1752 rat
= (count_long
)in_count
/ (count_long
)rat
;
1755 /* 8 fractional bits */
1756 rat
= ((count_long
)in_count
<< 8) /(count_long
)bytes_out
;
1764 dump_tab(); /* dump string table */
1766 cl_hash((count_int
) hsize
);
1769 output((code_int
) CLEAR
);
1772 (void) fprintf(stderr
, "clear\n");
1778 cl_hash(count_int hsize
) /* reset code table */
1780 count_int
*htab_p
= htab
+hsize
;
1785 do { /* might use Sys V memset(3) here */
1803 } while ((i
-= 16) >= 0);
1804 for (i
+= 16; i
> 0; i
--)
1809 prratio(FILE *stream
, count_long num
, count_long den
)
1811 int q
; /* store percentage */
1813 q
= (int)(10000LL * (count_long
)num
/ (count_long
)den
);
1815 (void) putc('-', stream
);
1818 (void) fprintf(stream
, "%d%s%02d%%", q
/ 100,
1819 localeconv()->decimal_point
, q
% 100);
1825 (void) fprintf(stderr
, "%s, Berkeley 5.9 5/11/86\n", rcs_ident
);
1826 (void) fprintf(stderr
, "Options: ");
1828 (void) fprintf(stderr
, "DEBUG, ");
1830 (void) fprintf(stderr
, "BITS = %d\n", BITS
);
1837 (void) fprintf(stderr
,
1838 "Usage: compress [-dDVfc/] [-b maxbits] [file ...]\n");
1840 if (strcmp(progname
, "compress") == 0) {
1841 (void) fprintf(stderr
,
1843 "Usage: compress [-fv/] [-b maxbits] [file ...]\n"\
1844 " compress c [-fv] [-b maxbits] [file]\n"));
1845 } else if (strcmp(progname
, "uncompress") == 0)
1846 (void) fprintf(stderr
, gettext(
1847 "Usage: uncompress [-fv] [-c || -/] [file ...]\n"));
1848 else if (strcmp(progname
, "zcat") == 0)
1849 (void) fprintf(stderr
, gettext("Usage: zcat [file ...]\n"));
1855 local_basename(char *path
)
1858 char *ret
= (char *)path
;
1860 while ((p
= (char *)strpbrk(ret
, "/")) != NULL
)
1866 addDotZ(char *fn
, size_t fnsize
)
1873 fn_dup
= strdup(fn
);
1874 dir
= dirname(fn_dup
);
1875 max_name
= pathconf(dir
, _PC_NAME_MAX
);
1876 max_path
= pathconf(dir
, _PC_PATH_MAX
);
1879 /* Check for component length too long */
1881 if ((strlen(local_basename(fn
)) + 2) > (size_t)max_name
) {
1882 (void) fprintf(stderr
,
1883 gettext("%s: filename too long to tack on .Z:"
1884 " %s\n"), progname
, fn
);
1888 /* Check for path length too long */
1890 if ((strlen(fn
) + 2) > (size_t)max_path
- 1) {
1891 (void) fprintf(stderr
,
1892 gettext("%s: Pathname too long to tack on .Z:"
1893 " %s\n"), progname
, fn
);
1897 if (strlcat(fn
, ".Z", fnsize
) >= fnsize
) {
1898 (void) fprintf(stderr
,
1899 gettext("%s: Buffer overflow adding .Z to %s\n"),