delete mention of ^Y; currently don't allow ^Y or ^E.
[unix-history] / usr / src / usr.bin / compress / compress.c
CommitLineData
58777538
KB
1/*
2 * Copyright (c) 1985, 1986 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * James A. Woods, derived from original work by Spencer Thomas
7 * and Joseph Orost.
8 *
9 * Redistribution and use in source and binary forms are permitted
10 * provided that the above copyright notice and this paragraph are
11 * duplicated in all such forms and that any documentation,
12 * advertising materials, and other materials related to such
13 * distribution and use acknowledge that the software was developed
14 * by the University of California, Berkeley. The name of the
15 * University may not be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
19 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22#ifndef lint
23char copyright[] =
24"@(#) Copyright (c) 1985, 1986 The Regents of the University of California.\n\
25 All rights reserved.\n";
26#endif /* not lint */
27
64d06f2f 28#ifndef lint
58777538
KB
29static char sccsid[] = "@(#)compress.c 5.10 (Berkeley) %G%";
30#endif /* not lint */
64d06f2f 31
4eeb10d4
JL
32/*
33 * Compress - data compression program
34 */
a2de8fe3
KM
35#define min(a,b) ((a>b) ? b : a)
36
64d06f2f 37/*
a2de8fe3
KM
38 * machine variants which require cc -Dmachine: pdp11, z8000, pcxt
39 */
40
4eeb10d4
JL
41/*
42 * Set USERMEM to the maximum amount of physical user memory available
64d06f2f 43 * in bytes. USERMEM is used to determine the maximum BITS that can be used
4eeb10d4 44 * for compression.
64d06f2f
KM
45 *
46 * SACREDMEM is the amount of physical memory saved for others; compress
47 * will hog the rest.
48 */
49#ifndef SACREDMEM
50#define SACREDMEM 0
51#endif
52
a2de8fe3 53#ifndef USERMEM
4eeb10d4
JL
54# define USERMEM 450000 /* default user memory */
55#endif
56
57#ifdef interdata /* (Perkin-Elmer) */
58#define SIGNED_COMPARE_SLOW /* signed compare is slower than unsigned */
a2de8fe3
KM
59#endif
60
64d06f2f
KM
61#ifdef pdp11
62# define BITS 12 /* max bits/code for 16-bit machine */
63# define NO_UCHAR /* also if "unsigned char" functions as signed char */
64# undef USERMEM
4eeb10d4 65#endif /* pdp11 */ /* don't forget to compile with -i */
a2de8fe3
KM
66
67#ifdef z8000
68# define BITS 12
a2de8fe3
KM
69# undef vax /* weird preprocessor */
70# undef USERMEM
4eeb10d4 71#endif /* z8000 */
a2de8fe3
KM
72
73#ifdef pcxt
74# define BITS 12
a2de8fe3 75# undef USERMEM
4eeb10d4 76#endif /* pcxt */
64d06f2f
KM
77
78#ifdef USERMEM
4eeb10d4
JL
79# if USERMEM >= (433484+SACREDMEM)
80# define PBITS 16
81# else
82# if USERMEM >= (229600+SACREDMEM)
83# define PBITS 15
84# else
85# if USERMEM >= (127536+SACREDMEM)
86# define PBITS 14
87# else
88# if USERMEM >= (73464+SACREDMEM)
89# define PBITS 13
64d06f2f 90# else
4eeb10d4 91# define PBITS 12
64d06f2f 92# endif
4eeb10d4
JL
93# endif
94# endif
95# endif
96# undef USERMEM
97#endif /* USERMEM */
64d06f2f
KM
98
99#ifdef PBITS /* Preferred BITS for this memory size */
100# ifndef BITS
101# define BITS PBITS
102# endif BITS
4eeb10d4 103#endif /* PBITS */
64d06f2f
KM
104
105#if BITS == 16
106# define HSIZE 69001 /* 95% occupancy */
107#endif
108#if BITS == 15
109# define HSIZE 35023 /* 94% occupancy */
110#endif
111#if BITS == 14
112# define HSIZE 18013 /* 91% occupancy */
113#endif
114#if BITS == 13
115# define HSIZE 9001 /* 91% occupancy */
116#endif
a2de8fe3 117#if BITS <= 12
64d06f2f
KM
118# define HSIZE 5003 /* 80% occupancy */
119#endif
4eeb10d4
JL
120
121#ifdef M_XENIX /* Stupid compiler can't handle arrays with */
122# if BITS == 16 /* more than 65535 bytes - so we fake it */
123# define XENIX_16
124# else
125# if BITS > 13 /* Code only handles BITS = 12, 13, or 16 */
126# define BITS 13
127# endif
128# endif
129#endif
64d06f2f
KM
130
131/*
132 * a code_int must be able to hold 2**BITS values of type int, and also -1
133 */
134#if BITS > 15
135typedef long int code_int;
136#else
137typedef int code_int;
138#endif
139
4eeb10d4 140#ifdef SIGNED_COMPARE_SLOW
64d06f2f
KM
141typedef unsigned long int count_int;
142typedef unsigned short int count_short;
143#else
144typedef long int count_int;
145#endif
146
147#ifdef NO_UCHAR
148 typedef char char_type;
4eeb10d4 149#else
64d06f2f 150 typedef unsigned char char_type;
4eeb10d4 151#endif /* UCHAR */
64d06f2f
KM
152char_type magic_header[] = { "\037\235" }; /* 1F 9D */
153
154/* Defines for third byte of header */
155#define BIT_MASK 0x1f
156#define BLOCK_MASK 0x80
157/* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
158 a fourth header byte (for expansion).
159*/
160#define INIT_BITS 9 /* initial number of bits/code */
161
162/*
a2de8fe3 163 * compress.c - File compression ala IEEE Computer, June 1984.
64d06f2f 164 *
c8f1fe84 165 * Authors: Spencer W. Thomas (decvax!utah-cs!thomas)
64d06f2f
KM
166 * Jim McKie (decvax!mcvax!jim)
167 * Steve Davies (decvax!vax135!petsd!peora!srd)
168 * Ken Turkowski (decvax!decwrl!turtlevax!ken)
169 * James A. Woods (decvax!ihnp4!ames!jaw)
170 * Joe Orost (decvax!vax135!petsd!joe)
171 *
4eeb10d4 172 * $Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release $
64d06f2f 173 * $Log: compress.c,v $
4eeb10d4
JL
174 * Revision 4.0 85/07/30 12:50:00 joe
175 * Removed ferror() calls in output routine on every output except first.
176 * Prepared for release to the world.
177 *
178 * Revision 3.6 85/07/04 01:22:21 joe
179 * Remove much wasted storage by overlaying hash table with the tables
180 * used by decompress: tab_suffix[1<<BITS], stack[8000]. Updated USERMEM
181 * computations. Fixed dump_tab() DEBUG routine.
182 *
183 * Revision 3.5 85/06/30 20:47:21 jaw
184 * Change hash function to use exclusive-or. Rip out hash cache. These
185 * speedups render the megamemory version defunct, for now. Make decoder
186 * stack global. Parts of the RCS trunks 2.7, 2.6, and 2.1 no longer apply.
187 *
188 * Revision 3.4 85/06/27 12:00:00 ken
189 * Get rid of all floating-point calculations by doing all compression ratio
190 * calculations in fixed point.
191 *
192 * Revision 3.3 85/06/24 21:53:24 joe
193 * Incorporate portability suggestion for M_XENIX. Got rid of text on #else
194 * and #endif lines. Cleaned up #ifdefs for vax and interdata.
195 *
a2de8fe3
KM
196 * Revision 3.2 85/06/06 21:53:24 jaw
197 * Incorporate portability suggestions for Z8000, IBM PC/XT from mailing list.
198 * Default to "quiet" output (no compression statistics).
199 *
200 * Revision 3.1 85/05/12 18:56:13 jaw
201 * Integrate decompress() stack speedups (from early pointer mods by McKie).
202 * Repair multi-file USERMEM gaffe. Unify 'force' flags to mimic semantics
203 * of SVR2 'pack'. Streamline block-compress table clear logic. Increase
204 * output byte count by magic number size.
205 *
64d06f2f
KM
206 * Revision 3.0 84/11/27 11:50:00 petsd!joe
207 * Set HSIZE depending on BITS. Set BITS depending on USERMEM. Unrolled
a2de8fe3 208 * loops in clear routines. Added "-C" flag for 2.0 compatibility. Used
64d06f2f
KM
209 * unsigned compares on Perkin-Elmer. Fixed foreground check.
210 *
211 * Revision 2.7 84/11/16 19:35:39 ames!jaw
212 * Cache common hash codes based on input statistics; this improves
213 * performance for low-density raster images. Pass on #ifdef bundle
214 * from Turkowski.
215 *
216 * Revision 2.6 84/11/05 19:18:21 ames!jaw
217 * Vary size of hash tables to reduce time for small files.
218 * Tune PDP-11 hash function.
219 *
220 * Revision 2.5 84/10/30 20:15:14 ames!jaw
221 * Junk chaining; replace with the simpler (and, on the VAX, faster)
222 * double hashing, discussed within. Make block compression standard.
223 *
224 * Revision 2.4 84/10/16 11:11:11 ames!jaw
225 * Introduce adaptive reset for block compression, to boost the rate
226 * another several percent. (See mailing list notes.)
227 *
228 * Revision 2.3 84/09/22 22:00:00 petsd!joe
229 * Implemented "-B" block compress. Implemented REVERSE sorting of tab_next.
230 * Bug fix for last bits. Changed fwrite to putchar loop everywhere.
231 *
232 * Revision 2.2 84/09/18 14:12:21 ames!jaw
233 * Fold in news changes, small machine typedef from thomas,
234 * #ifdef interdata from joe.
235 *
236 * Revision 2.1 84/09/10 12:34:56 ames!jaw
237 * Configured fast table lookup for 32-bit machines.
238 * This cuts user time in half for b <= FBITS, and is useful for news batching
239 * from VAX to PDP sites. Also sped up decompress() [fwrite->putc] and
240 * added signal catcher [plus beef in writeerr()] to delete effluvia.
241 *
242 * Revision 2.0 84/08/28 22:00:00 petsd!joe
243 * Add check for foreground before prompting user. Insert maxbits into
244 * compressed file. Force file being uncompressed to end with ".Z".
245 * Added "-c" flag and "zcat". Prepared for release.
246 *
247 * Revision 1.10 84/08/24 18:28:00 turtlevax!ken
248 * Will only compress regular files (no directories), added a magic number
249 * header (plus an undocumented -n flag to handle old files without headers),
250 * added -f flag to force overwriting of possibly existing destination file,
251 * otherwise the user is prompted for a response. Will tack on a .Z to a
252 * filename if it doesn't have one when decompressing. Will only replace
253 * file if it was compressed.
254 *
255 * Revision 1.9 84/08/16 17:28:00 turtlevax!ken
256 * Removed scanargs(), getopt(), added .Z extension and unlimited number of
257 * filenames to compress. Flags may be clustered (-Ddvb12) or separated
258 * (-D -d -v -b 12), or combination thereof. Modes and other status is
259 * copied with copystat(). -O bug for 4.2 seems to have disappeared with
260 * 1.8.
261 *
262 * Revision 1.8 84/08/09 23:15:00 joe
263 * Made it compatible with vax version, installed jim's fixes/enhancements
264 *
265 * Revision 1.6 84/08/01 22:08:00 joe
266 * Sped up algorithm significantly by sorting the compress chain.
267 *
268 * Revision 1.5 84/07/13 13:11:00 srd
269 * Added C version of vax asm routines. Changed structure to arrays to
270 * save much memory. Do unsigned compares where possible (faster on
271 * Perkin-Elmer)
272 *
273 * Revision 1.4 84/07/05 03:11:11 thomas
274 * Clean up the code a little and lint it. (Lint complains about all
275 * the regs used in the asm, but I'm not going to "fix" this.)
276 *
277 * Revision 1.3 84/07/05 02:06:54 thomas
278 * Minor fixes.
279 *
280 * Revision 1.2 84/07/05 00:27:27 thomas
281 * Add variable bit length output.
282 *
283 */
4eeb10d4 284static char rcs_ident[] = "$Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release $";
64d06f2f
KM
285
286#include <stdio.h>
287#include <ctype.h>
288#include <signal.h>
289#include <sys/types.h>
290#include <sys/stat.h>
c8f1fe84
JL
291#ifdef notdef
292#include <sys/ioctl.h>
293#endif
64d06f2f
KM
294
295#define ARGVAL() (*++(*argv) || (--argc && *++argv))
296
297int n_bits; /* number of bits/code */
298int maxbits = BITS; /* user settable max # bits/code */
299code_int maxcode; /* maximum code, given n_bits */
300code_int maxmaxcode = 1 << BITS; /* should NEVER generate this code */
301#ifdef COMPATIBLE /* But wrong! */
302# define MAXCODE(n_bits) (1 << (n_bits) - 1)
4eeb10d4 303#else
64d06f2f 304# define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
4eeb10d4
JL
305#endif /* COMPATIBLE */
306
307#ifdef XENIX_16
308count_int htab0[8192];
309count_int htab1[8192];
310count_int htab2[8192];
311count_int htab3[8192];
312count_int htab4[8192];
313count_int htab5[8192];
314count_int htab6[8192];
315count_int htab7[8192];
316count_int htab8[HSIZE-65536];
317count_int * htab[9] = {
318 htab0, htab1, htab2, htab3, htab4, htab5, htab6, htab7, htab8 };
319
320#define htabof(i) (htab[(i) >> 13][(i) & 0x1fff])
321unsigned short code0tab[16384];
322unsigned short code1tab[16384];
323unsigned short code2tab[16384];
324unsigned short code3tab[16384];
325unsigned short code4tab[16384];
326unsigned short * codetab[5] = {
327 code0tab, code1tab, code2tab, code3tab, code4tab };
328
329#define codetabof(i) (codetab[(i) >> 14][(i) & 0x3fff])
330
331#else /* Normal machine */
c8f1fe84
JL
332
333#ifdef sel /* gould base register braindamage */
334/*NOBASE*/
335count_int htab [HSIZE];
336unsigned short codetab [HSIZE];
337/*NOBASE*/
338#else
64d06f2f
KM
339count_int htab [HSIZE];
340unsigned short codetab [HSIZE];
c8f1fe84
JL
341#endif sel
342
4eeb10d4
JL
343#define htabof(i) htab[i]
344#define codetabof(i) codetab[i]
345#endif /* XENIX_16 */
64d06f2f
KM
346code_int hsize = HSIZE; /* for dynamic table sizing */
347count_int fsize;
348
4eeb10d4
JL
349/*
350 * To save much memory, we overlay the table used by compress() with those
351 * used by decompress(). The tab_prefix table is the same size and type
352 * as the codetab. The tab_suffix table needs 2**BITS characters. We
353 * get this from the beginning of htab. The output stack uses the rest
354 * of htab, and contains characters. There is plenty of room for any
355 * possible stack (stack used to be 8000 characters).
356 */
64d06f2f 357
4eeb10d4
JL
358#define tab_prefixof(i) codetabof(i)
359#ifdef XENIX_16
360# define tab_suffixof(i) ((char_type *)htab[(i)>>15])[(i) & 0x7fff]
361# define de_stack ((char_type *)(htab2))
362#else /* Normal machine */
363# define tab_suffixof(i) ((char_type *)(htab))[i]
364# define de_stack ((char_type *)&tab_suffixof(1<<BITS))
365#endif /* XENIX_16 */
64d06f2f
KM
366
367code_int free_ent = 0; /* first unused entry */
c8f1fe84
JL
368int exit_stat = 0; /* per-file status */
369int perm_stat = 0; /* permanent status */
64d06f2f
KM
370
371code_int getcode();
372
373Usage() {
374#ifdef DEBUG
a2de8fe3 375fprintf(stderr,"Usage: compress [-dDVfc] [-b maxbits] [file ...]\n");
64d06f2f
KM
376}
377int debug = 0;
4eeb10d4 378#else
bffb9eb4 379fprintf(stderr,"Usage: compress [-fvc] [-b maxbits] [file ...]\n");
64d06f2f 380}
4eeb10d4 381#endif /* DEBUG */
a2de8fe3 382int nomagic = 0; /* Use a 3-byte magic number header, unless old file */
64d06f2f 383int zcat_flg = 0; /* Write output on stdout, suppress messages */
be5873af 384int precious = 1; /* Don't unlink output file on interrupt */
a2de8fe3 385int quiet = 1; /* don't tell me about compression */
64d06f2f
KM
386
387/*
388 * block compression parameters -- after all codes are used up,
389 * and compression rate changes, start over.
390 */
391int block_compress = BLOCK_MASK;
392int clear_flg = 0;
4eeb10d4 393long int ratio = 0;
64d06f2f
KM
394#define CHECK_GAP 10000 /* ratio check interval */
395count_int checkpoint = CHECK_GAP;
396/*
397 * the next two codes should not be changed lightly, as they must not
398 * lie within the contiguous general code space.
399 */
400#define FIRST 257 /* first free entry */
401#define CLEAR 256 /* table clear output code */
402
403int force = 0;
404char ofname [100];
405#ifdef DEBUG
406int verbose = 0;
4eeb10d4 407#endif /* DEBUG */
c8f1fe84
JL
408int (*oldint)();
409int bgnd_flag;
64d06f2f 410
4eeb10d4 411int do_decomp = 0;
a2de8fe3 412
64d06f2f
KM
413/*****************************************************************
414 * TAG( main )
415 *
416 * Algorithm from "A Technique for High Performance Data Compression",
417 * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
418 *
a2de8fe3 419 * Usage: compress [-dfvc] [-b bits] [file ...]
64d06f2f
KM
420 * Inputs:
421 * -d: If given, decompression is done instead.
422 *
423 * -c: Write output on stdout, don't remove original.
424 *
425 * -b: Parameter limits the max number of bits/code.
426 *
427 * -f: Forces output file to be generated, even if one already
a2de8fe3
KM
428 * exists, and even if no space is saved by compressing.
429 * If -f is not used, the user will be prompted if stdin is
430 * a tty, otherwise, the output file will not be overwritten.
64d06f2f 431 *
a2de8fe3 432 * -v: Write compression statistics
64d06f2f
KM
433 *
434 * file ...: Files to be compressed. If none specified, stdin
435 * is used.
436 * Outputs:
437 * file.Z: Compressed form of file with same mode, owner, and utimes
438 * or stdout (if stdin used as input)
439 *
440 * Assumptions:
441 * When filenames are given, replaces with the compressed version
a2de8fe3 442 * (.Z suffix) only if the file decreases in size.
64d06f2f
KM
443 * Algorithm:
444 * Modified Lempel-Ziv method (LZW). Basically finds common
445 * substrings and replaces them with a variable size code. This is
446 * deterministic, and can be done on the fly. Thus, the decompression
a2de8fe3 447 * procedure needs no input table, but tracks the way the table was built.
64d06f2f 448 */
4eeb10d4 449
64d06f2f
KM
450main( argc, argv )
451register int argc; char **argv;
452{
64d06f2f
KM
453 int overwrite = 0; /* Do not overwrite unless given -f flag */
454 char tempname[100];
455 char **filelist, **fileptr;
a2de8fe3 456 char *cp, *rindex(), *malloc();
64d06f2f 457 struct stat statbuf;
4eeb10d4 458 extern onintr(), oops();
64d06f2f 459
c8f1fe84
JL
460 /* This bg check only works for sh. */
461 if ( (oldint = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
64d06f2f 462 signal ( SIGINT, onintr );
4eeb10d4
JL
463 signal ( SIGSEGV, oops );
464 }
c8f1fe84
JL
465 bgnd_flag = oldint != SIG_DFL;
466#ifdef notdef /* This works for csh but we don't want it. */
467 { int tgrp;
468 if (bgnd_flag == 0 && ioctl(2, TIOCGPGRP, (char *)&tgrp) == 0 &&
469 getpgrp(0) != tgrp)
470 bgnd_flag = 1;
471 }
472#endif
473
64d06f2f
KM
474#ifdef COMPATIBLE
475 nomagic = 1; /* Original didn't have a magic number */
4eeb10d4 476#endif /* COMPATIBLE */
64d06f2f
KM
477
478 filelist = fileptr = (char **)(malloc(argc * sizeof(*argv)));
479 *filelist = NULL;
480
481 if((cp = rindex(argv[0], '/')) != 0) {
482 cp++;
483 } else {
484 cp = argv[0];
485 }
486 if(strcmp(cp, "uncompress") == 0) {
487 do_decomp = 1;
488 } else if(strcmp(cp, "zcat") == 0) {
489 do_decomp = 1;
490 zcat_flg = 1;
491 }
492
493#ifdef BSD4_2
494 /* 4.2BSD dependent - take it out if not */
495 setlinebuf( stderr );
4eeb10d4 496#endif /* BSD4_2 */
64d06f2f
KM
497
498 /* Argument Processing
499 * All flags are optional.
500 * -D => debug
4eeb10d4 501 * -V => print Version; debug verbose
64d06f2f 502 * -d => do_decomp
a2de8fe3 503 * -v => unquiet
64d06f2f
KM
504 * -f => force overwrite of output file
505 * -n => no header: useful to uncompress old files
506 * -b maxbits => maxbits. If -b is specified, then maxbits MUST be
507 * given also.
508 * -c => cat all output to stdout
a2de8fe3 509 * -C => generate output compatible with compress 2.0.
64d06f2f
KM
510 * if a string is left, must be an input filename.
511 */
512 for (argc--, argv++; argc > 0; argc--, argv++) {
513 if (**argv == '-') { /* A flag argument */
514 while (*++(*argv)) { /* Process all flags in this arg */
515 switch (**argv) {
516#ifdef DEBUG
517 case 'D':
518 debug = 1;
519 break;
a2de8fe3 520 case 'V':
64d06f2f 521 verbose = 1;
4eeb10d4
JL
522 version();
523 break;
524#else
525 case 'V':
526 version();
64d06f2f 527 break;
4eeb10d4 528#endif /* DEBUG */
a2de8fe3
KM
529 case 'v':
530 quiet = 0;
531 break;
64d06f2f
KM
532 case 'd':
533 do_decomp = 1;
534 break;
535 case 'f':
a2de8fe3 536 case 'F':
64d06f2f 537 overwrite = 1;
a2de8fe3 538 force = 1;
64d06f2f
KM
539 break;
540 case 'n':
541 nomagic = 1;
542 break;
543 case 'C':
544 block_compress = 0;
545 break;
546 case 'b':
547 if (!ARGVAL()) {
548 fprintf(stderr, "Missing maxbits\n");
549 Usage();
550 exit(1);
551 }
552 maxbits = atoi(*argv);
553 goto nextarg;
554 case 'c':
555 zcat_flg = 1;
556 break;
557 case 'q':
558 quiet = 1;
559 break;
64d06f2f
KM
560 default:
561 fprintf(stderr, "Unknown flag: '%c'; ", **argv);
562 Usage();
563 exit(1);
564 }
565 }
566 }
567 else { /* Input file name */
568 *fileptr++ = *argv; /* Build input file list */
569 *fileptr = NULL;
4eeb10d4 570 /* process nextarg; */
64d06f2f
KM
571 }
572 nextarg: continue;
573 }
574
575 if(maxbits < INIT_BITS) maxbits = INIT_BITS;
576 if (maxbits > BITS) maxbits = BITS;
577 maxmaxcode = 1 << maxbits;
578
579 if (*filelist != NULL) {
580 for (fileptr = filelist; *fileptr; fileptr++) {
581 exit_stat = 0;
c8f1fe84 582 if (do_decomp) { /* DECOMPRESSION */
64d06f2f
KM
583 /* Check for .Z suffix */
584 if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) {
585 /* No .Z: tack one on */
586 strcpy(tempname, *fileptr);
587 strcat(tempname, ".Z");
588 *fileptr = tempname;
589 }
590 /* Open input file */
591 if ((freopen(*fileptr, "r", stdin)) == NULL) {
c8f1fe84
JL
592 perror(*fileptr);
593 perm_stat = 1;
594 continue;
64d06f2f
KM
595 }
596 /* Check the magic number */
597 if (nomagic == 0) {
598 if ((getchar() != (magic_header[0] & 0xFF))
599 || (getchar() != (magic_header[1] & 0xFF))) {
600 fprintf(stderr, "%s: not in compressed format\n",
601 *fileptr);
602 continue;
603 }
604 maxbits = getchar(); /* set -b from file */
605 block_compress = maxbits & BLOCK_MASK;
606 maxbits &= BIT_MASK;
607 maxmaxcode = 1 << maxbits;
608 if(maxbits > BITS) {
609 fprintf(stderr,
610 "%s: compressed with %d bits, can only handle %d bits\n",
611 *fileptr, maxbits, BITS);
612 continue;
613 }
614 }
615 /* Generate output filename */
616 strcpy(ofname, *fileptr);
617 ofname[strlen(*fileptr) - 2] = '\0'; /* Strip off .Z */
618 } else { /* COMPRESSION */
619 if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") == 0) {
a2de8fe3 620 fprintf(stderr, "%s: already has .Z suffix -- no change\n",
64d06f2f
KM
621 *fileptr);
622 continue;
623 }
624 /* Open input file */
625 if ((freopen(*fileptr, "r", stdin)) == NULL) {
c8f1fe84
JL
626 perror(*fileptr);
627 perm_stat = 1;
628 continue;
64d06f2f
KM
629 }
630 stat ( *fileptr, &statbuf );
631 fsize = (long) statbuf.st_size;
632 /*
4eeb10d4
JL
633 * tune hash table size for small files -- ad hoc,
634 * but the sizes match earlier #defines, which
635 * serve as upper bounds on the number of output codes.
64d06f2f 636 */
a2de8fe3 637 hsize = HSIZE;
64d06f2f 638 if ( fsize < (1 << 12) )
a2de8fe3 639 hsize = min ( 5003, HSIZE );
64d06f2f 640 else if ( fsize < (1 << 13) )
a2de8fe3 641 hsize = min ( 9001, HSIZE );
64d06f2f 642 else if ( fsize < (1 << 14) )
a2de8fe3 643 hsize = min ( 18013, HSIZE );
64d06f2f 644 else if ( fsize < (1 << 15) )
a2de8fe3 645 hsize = min ( 35023, HSIZE );
64d06f2f 646 else if ( fsize < 47000 )
a2de8fe3
KM
647 hsize = min ( 50021, HSIZE );
648
64d06f2f
KM
649 /* Generate output filename */
650 strcpy(ofname, *fileptr);
651#ifndef BSD4_2 /* Short filenames */
652 if ((cp=rindex(ofname,'/')) != NULL) cp++;
653 else cp = ofname;
654 if (strlen(cp) > 12) {
655 fprintf(stderr,"%s: filename too long to tack on .Z\n",cp);
656 continue;
657 }
4eeb10d4 658#endif /* BSD4_2 Long filenames allowed */
64d06f2f
KM
659 strcat(ofname, ".Z");
660 }
661 /* Check for overwrite of existing file */
662 if (overwrite == 0 && zcat_flg == 0) {
663 if (stat(ofname, &statbuf) == 0) {
664 char response[2];
665 response[0] = 'n';
666 fprintf(stderr, "%s already exists;", ofname);
c8f1fe84 667 if (bgnd_flag == 0 && isatty(2)) {
a2de8fe3 668 fprintf(stderr, " do you wish to overwrite %s (y or n)? ",
64d06f2f
KM
669 ofname);
670 fflush(stderr);
671 read(2, response, 2);
672 while (response[1] != '\n') {
673 if (read(2, response+1, 1) < 0) { /* Ack! */
674 perror("stderr"); break;
675 }
676 }
677 }
678 if (response[0] != 'y') {
679 fprintf(stderr, "\tnot overwritten\n");
680 continue;
681 }
682 }
683 }
684 if(zcat_flg == 0) { /* Open output file */
685 if (freopen(ofname, "w", stdout) == NULL) {
686 perror(ofname);
c8f1fe84 687 perm_stat = 1;
64d06f2f
KM
688 continue;
689 }
be5873af 690 precious = 0;
64d06f2f
KM
691 if(!quiet)
692 fprintf(stderr, "%s: ", *fileptr);
693 }
694
695 /* Actually do the compression/decompression */
696 if (do_decomp == 0) compress();
697#ifndef DEBUG
698 else decompress();
4eeb10d4 699#else
64d06f2f
KM
700 else if (debug == 0) decompress();
701 else printcodes();
702 if (verbose) dump_tab();
4eeb10d4 703#endif /* DEBUG */
64d06f2f
KM
704 if(zcat_flg == 0) {
705 copystat(*fileptr, ofname); /* Copy stats */
be5873af 706 precious = 1;
4eeb10d4 707 if((exit_stat == 1) || (!quiet))
64d06f2f
KM
708 putc('\n', stderr);
709 }
710 }
711 } else { /* Standard input */
712 if (do_decomp == 0) {
713 compress();
4eeb10d4
JL
714#ifdef DEBUG
715 if(verbose) dump_tab();
716#endif /* DEBUG */
64d06f2f
KM
717 if(!quiet)
718 putc('\n', stderr);
719 } else {
720 /* Check the magic number */
721 if (nomagic == 0) {
722 if ((getchar()!=(magic_header[0] & 0xFF))
723 || (getchar()!=(magic_header[1] & 0xFF))) {
724 fprintf(stderr, "stdin: not in compressed format\n");
725 exit(1);
726 }
727 maxbits = getchar(); /* set -b from file */
728 block_compress = maxbits & BLOCK_MASK;
729 maxbits &= BIT_MASK;
730 maxmaxcode = 1 << maxbits;
731 fsize = 100000; /* assume stdin large for USERMEM */
732 if(maxbits > BITS) {
733 fprintf(stderr,
734 "stdin: compressed with %d bits, can only handle %d bits\n",
735 maxbits, BITS);
736 exit(1);
737 }
738 }
739#ifndef DEBUG
740 decompress();
4eeb10d4 741#else
64d06f2f
KM
742 if (debug == 0) decompress();
743 else printcodes();
744 if (verbose) dump_tab();
4eeb10d4 745#endif /* DEBUG */
64d06f2f
KM
746 }
747 }
c8f1fe84 748 exit(perm_stat ? perm_stat : exit_stat);
64d06f2f
KM
749}
750
751static int offset;
752long int in_count = 1; /* length of input */
753long int bytes_out; /* length of compressed output */
754long int out_count = 0; /* # of codes output (for debugging) */
755
64d06f2f
KM
756/*
757 * compress stdin to stdout
758 *
4eeb10d4
JL
759 * Algorithm: use open addressing double hashing (no chaining) on the
760 * prefix code / next character combination. We do a variant of Knuth's
761 * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
762 * secondary probe. Here, the modular division first probe is gives way
763 * to a faster exclusive-or manipulation. Also do block compression with
764 * an adaptive reset, whereby the code table is cleared when the compression
765 * ratio decreases, but after the table fills. The variable-length output
766 * codes are re-sized at this point, and a special CLEAR code is generated
767 * for the decompressor. Late addition: construct the table according to
768 * file size for noticeable speed improvement on small files. Please direct
769 * questions about this implementation to ames!jaw.
64d06f2f
KM
770 */
771
64d06f2f
KM
772compress() {
773 register long fcode;
774 register code_int i = 0;
775 register int c;
776 register code_int ent;
4eeb10d4
JL
777#ifdef XENIX_16
778 register code_int disp;
779#else /* Normal machine */
64d06f2f 780 register int disp;
4eeb10d4 781#endif
64d06f2f 782 register code_int hsize_reg;
4eeb10d4 783 register int hshift;
64d06f2f
KM
784
785#ifndef COMPATIBLE
786 if (nomagic == 0) {
787 putchar(magic_header[0]); putchar(magic_header[1]);
788 putchar((char)(maxbits | block_compress));
4eeb10d4
JL
789 if(ferror(stdout))
790 writeerr();
64d06f2f 791 }
4eeb10d4 792#endif /* COMPATIBLE */
64d06f2f
KM
793
794 offset = 0;
a2de8fe3 795 bytes_out = 3; /* includes 3-byte header mojo */
64d06f2f
KM
796 out_count = 0;
797 clear_flg = 0;
4eeb10d4 798 ratio = 0;
64d06f2f
KM
799 in_count = 1;
800 checkpoint = CHECK_GAP;
801 maxcode = MAXCODE(n_bits = INIT_BITS);
802 free_ent = ((block_compress) ? FIRST : 256 );
64d06f2f 803
4eeb10d4 804 ent = getchar ();
a2de8fe3 805
4eeb10d4
JL
806 hshift = 0;
807 for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L )
808 hshift++;
809 hshift = 8 - hshift; /* set hash code range bound */
64d06f2f 810
64d06f2f 811 hsize_reg = hsize;
4eeb10d4 812 cl_hash( (count_int) hsize_reg); /* clear hash table */
64d06f2f 813
4eeb10d4 814#ifdef SIGNED_COMPARE_SLOW
64d06f2f 815 while ( (c = getchar()) != (unsigned) EOF ) {
4eeb10d4
JL
816#else
817 while ( (c = getchar()) != EOF ) {
818#endif
64d06f2f 819 in_count++;
64d06f2f 820 fcode = (long) (((long) c << maxbits) + ent);
4eeb10d4
JL
821 i = ((c << hshift) ^ ent); /* xor hashing */
822
823 if ( htabof (i) == fcode ) {
824 ent = codetabof (i);
64d06f2f 825 continue;
4eeb10d4 826 } else if ( (long)htabof (i) < 0 ) /* empty slot */
64d06f2f 827 goto nomatch;
4eeb10d4 828 disp = hsize_reg - i; /* secondary hash (after G. Knott) */
64d06f2f
KM
829 if ( i == 0 )
830 disp = 1;
831probe:
832 if ( (i -= disp) < 0 )
833 i += hsize_reg;
834
4eeb10d4
JL
835 if ( htabof (i) == fcode ) {
836 ent = codetabof (i);
64d06f2f
KM
837 continue;
838 }
4eeb10d4 839 if ( (long)htabof (i) > 0 )
64d06f2f
KM
840 goto probe;
841nomatch:
842 output ( (code_int) ent );
843 out_count++;
4eeb10d4
JL
844 ent = c;
845#ifdef SIGNED_COMPARE_SLOW
64d06f2f
KM
846 if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
847#else
848 if ( free_ent < maxmaxcode ) {
849#endif
4eeb10d4
JL
850 codetabof (i) = free_ent++; /* code -> hashtable */
851 htabof (i) = fcode;
64d06f2f
KM
852 }
853 else if ( (count_int)in_count >= checkpoint && block_compress )
a2de8fe3 854 cl_block ();
64d06f2f 855 }
64d06f2f
KM
856 /*
857 * Put out the final code.
858 */
859 output( (code_int)ent );
860 out_count++;
861 output( (code_int)-1 );
862
863 /*
864 * Print out stats on stderr
865 */
866 if(zcat_flg == 0 && !quiet) {
867#ifdef DEBUG
868 fprintf( stderr,
4eeb10d4
JL
869 "%ld chars in, %ld codes (%ld bytes) out, compression factor: ",
870 in_count, out_count, bytes_out );
871 prratio( stderr, in_count, bytes_out );
872 fprintf( stderr, "\n");
873 fprintf( stderr, "\tCompression as in compact: " );
874 prratio( stderr, in_count-bytes_out, in_count );
875 fprintf( stderr, "\n");
876 fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n",
877 free_ent - 1, n_bits );
878#else /* !DEBUG */
879 fprintf( stderr, "Compression: " );
880 prratio( stderr, in_count-bytes_out, in_count );
881#endif /* DEBUG */
64d06f2f
KM
882 }
883 if(bytes_out > in_count) /* exit(2) if no savings */
884 exit_stat = 2;
885 return;
886}
887
888/*****************************************************************
889 * TAG( output )
890 *
891 * Output the given code.
892 * Inputs:
893 * code: A n_bits-bit integer. If == -1, then EOF. This assumes
894 * that n_bits =< (long)wordsize - 1.
895 * Outputs:
896 * Outputs code to the file.
897 * Assumptions:
898 * Chars are 8 bits long.
899 * Algorithm:
900 * Maintain a BITS character long buffer (so that 8 codes will
901 * fit in it exactly). Use the VAX insv instruction to insert each
902 * code in turn. When the buffer fills up empty it and start over.
903 */
904
905static char buf[BITS];
906
907#ifndef vax
908char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
909char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
4eeb10d4 910#endif /* vax */
64d06f2f
KM
911
912output( code )
913code_int code;
914{
915#ifdef DEBUG
916 static int col = 0;
4eeb10d4 917#endif /* DEBUG */
64d06f2f
KM
918
919 /*
920 * On the VAX, it is important to have the register declarations
921 * in exactly the order given, or the asm will break.
922 */
923 register int r_off = offset, bits= n_bits;
924 register char * bp = buf;
925
4eeb10d4
JL
926#ifdef DEBUG
927 if ( verbose )
928 fprintf( stderr, "%5d%c", code,
929 (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
930#endif /* DEBUG */
64d06f2f
KM
931 if ( code >= 0 ) {
932#ifdef vax
4eeb10d4 933 /* VAX DEPENDENT!! Implementation on other machines is below.
64d06f2f
KM
934 *
935 * Translation: Insert BITS bits from the argument starting at
936 * offset bits from the beginning of buf.
937 */
4eeb10d4 938 0; /* Work around for pcc -O bug with asm and if stmt */
64d06f2f 939 asm( "insv 4(ap),r11,r10,(r9)" );
4eeb10d4 940#else /* not a vax */
a2de8fe3
KM
941/*
942 * byte/bit numbering on the VAX is simulated by the following code
943 */
64d06f2f
KM
944 /*
945 * Get to the first byte.
946 */
947 bp += (r_off >> 3);
948 r_off &= 7;
949 /*
950 * Since code is always >= 8 bits, only need to mask the first
951 * hunk on the left.
952 */
953 *bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
954 bp++;
955 bits -= (8 - r_off);
956 code >>= 8 - r_off;
957 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
958 if ( bits >= 8 ) {
959 *bp++ = code;
960 code >>= 8;
961 bits -= 8;
962 }
963 /* Last bits. */
964 if(bits)
965 *bp = code;
4eeb10d4 966#endif /* vax */
64d06f2f
KM
967 offset += n_bits;
968 if ( offset == (n_bits << 3) ) {
969 bp = buf;
970 bits = n_bits;
971 bytes_out += bits;
972 do
973 putchar(*bp++);
974 while(--bits);
64d06f2f
KM
975 offset = 0;
976 }
64d06f2f
KM
977
978 /*
979 * If the next entry is going to be too big for the code size,
980 * then increase it, if possible.
981 */
982 if ( free_ent > maxcode || (clear_flg > 0))
983 {
984 /*
985 * Write the whole buffer, because the input side won't
986 * discover the size increase until after it has read it.
987 */
988 if ( offset > 0 ) {
989 if( fwrite( buf, 1, n_bits, stdout ) != n_bits)
990 writeerr();
991 bytes_out += n_bits;
992 }
993 offset = 0;
994
995 if ( clear_flg ) {
996 maxcode = MAXCODE (n_bits = INIT_BITS);
997 clear_flg = 0;
998 }
999 else {
1000 n_bits++;
1001 if ( n_bits == maxbits )
1002 maxcode = maxmaxcode;
1003 else
1004 maxcode = MAXCODE(n_bits);
1005 }
1006#ifdef DEBUG
1007 if ( debug ) {
1008 fprintf( stderr, "\nChange to %d bits\n", n_bits );
1009 col = 0;
1010 }
4eeb10d4 1011#endif /* DEBUG */
64d06f2f
KM
1012 }
1013 } else {
1014 /*
1015 * At EOF, write the rest of the buffer.
1016 */
1017 if ( offset > 0 )
1018 fwrite( buf, 1, (offset + 7) / 8, stdout );
1019 bytes_out += (offset + 7) / 8;
1020 offset = 0;
1021 fflush( stdout );
1022#ifdef DEBUG
1023 if ( verbose )
1024 fprintf( stderr, "\n" );
4eeb10d4 1025#endif /* DEBUG */
64d06f2f
KM
1026 if( ferror( stdout ) )
1027 writeerr();
1028 }
1029}
1030
4eeb10d4
JL
1031/*
1032 * Decompress stdin to stdout. This routine adapts to the codes in the
1033 * file building the "string" table on-the-fly; requiring no table to
1034 * be stored in the compressed file. The tables used herein are shared
1035 * with those of the compress() routine. See the definitions above.
1036 */
a2de8fe3 1037
64d06f2f 1038decompress() {
a2de8fe3 1039 register char_type *stackp;
64d06f2f 1040 register int finchar;
a2de8fe3
KM
1041 register code_int code, oldcode, incode;
1042
64d06f2f
KM
1043 /*
1044 * As above, initialize the first 256 entries in the table.
1045 */
1046 maxcode = MAXCODE(n_bits = INIT_BITS);
1047 for ( code = 255; code >= 0; code-- ) {
4eeb10d4
JL
1048 tab_prefixof(code) = 0;
1049 tab_suffixof(code) = (char_type)code;
64d06f2f
KM
1050 }
1051 free_ent = ((block_compress) ? FIRST : 256 );
1052
1053 finchar = oldcode = getcode();
4eeb10d4
JL
1054 if(oldcode == -1) /* EOF already? */
1055 return; /* Get out of here */
64d06f2f 1056 putchar( (char)finchar ); /* first code must be 8 bits = char */
4eeb10d4
JL
1057 if(ferror(stdout)) /* Crash if can't write */
1058 writeerr();
1059 stackp = de_stack;
64d06f2f 1060
4eeb10d4 1061 while ( (code = getcode()) > -1 ) {
64d06f2f
KM
1062
1063 if ( (code == CLEAR) && block_compress ) {
a2de8fe3 1064 for ( code = 255; code >= 0; code-- )
4eeb10d4 1065 tab_prefixof(code) = 0;
64d06f2f
KM
1066 clear_flg = 1;
1067 free_ent = FIRST - 1;
1068 if ( (code = getcode ()) == -1 ) /* O, untimely death! */
1069 break;
1070 }
1071 incode = code;
1072 /*
1073 * Special case for KwKwK string.
1074 */
1075 if ( code >= free_ent ) {
a2de8fe3 1076 *stackp++ = finchar;
64d06f2f
KM
1077 code = oldcode;
1078 }
1079
1080 /*
1081 * Generate output characters in reverse order
1082 */
4eeb10d4 1083#ifdef SIGNED_COMPARE_SLOW
64d06f2f 1084 while ( ((unsigned long)code) >= ((unsigned long)256) ) {
4eeb10d4 1085#else
64d06f2f 1086 while ( code >= 256 ) {
4eeb10d4
JL
1087#endif
1088 *stackp++ = tab_suffixof(code);
1089 code = tab_prefixof(code);
64d06f2f 1090 }
4eeb10d4 1091 *stackp++ = finchar = tab_suffixof(code);
64d06f2f
KM
1092
1093 /*
1094 * And put them out in forward order
1095 */
4eeb10d4
JL
1096 do
1097 putchar ( *--stackp );
1098 while ( stackp > de_stack );
64d06f2f
KM
1099
1100 /*
1101 * Generate the new entry.
1102 */
1103 if ( (code=free_ent) < maxmaxcode ) {
4eeb10d4
JL
1104 tab_prefixof(code) = (unsigned short)oldcode;
1105 tab_suffixof(code) = finchar;
64d06f2f
KM
1106 free_ent = code+1;
1107 }
1108 /*
1109 * Remember previous code.
1110 */
1111 oldcode = incode;
1112 }
1113 fflush( stdout );
1114 if(ferror(stdout))
1115 writeerr();
1116}
1117
64d06f2f
KM
1118/*****************************************************************
1119 * TAG( getcode )
1120 *
1121 * Read one code from the standard input. If EOF, return -1.
1122 * Inputs:
1123 * stdin
1124 * Outputs:
1125 * code or -1 is returned.
1126 */
1127
1128code_int
1129getcode() {
1130 /*
1131 * On the VAX, it is important to have the register declarations
1132 * in exactly the order given, or the asm will break.
1133 */
1134 register code_int code;
1135 static int offset = 0, size = 0;
1136 static char_type buf[BITS];
1137 register int r_off, bits;
1138 register char_type *bp = buf;
1139
1140 if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
1141 /*
1142 * If the next entry will be too big for the current code
1143 * size, then we must increase the size. This implies reading
1144 * a new buffer full, too.
1145 */
1146 if ( free_ent > maxcode ) {
1147 n_bits++;
1148 if ( n_bits == maxbits )
1149 maxcode = maxmaxcode; /* won't get any bigger now */
1150 else
1151 maxcode = MAXCODE(n_bits);
1152 }
1153 if ( clear_flg > 0) {
1154 maxcode = MAXCODE (n_bits = INIT_BITS);
1155 clear_flg = 0;
1156 }
1157 size = fread( buf, 1, n_bits, stdin );
1158 if ( size <= 0 )
1159 return -1; /* end of file */
1160 offset = 0;
1161 /* Round size down to integral number of codes */
1162 size = (size << 3) - (n_bits - 1);
1163 }
1164 r_off = offset;
1165 bits = n_bits;
1166#ifdef vax
1167 asm( "extzv r10,r9,(r8),r11" );
4eeb10d4 1168#else /* not a vax */
64d06f2f
KM
1169 /*
1170 * Get to the first byte.
1171 */
1172 bp += (r_off >> 3);
1173 r_off &= 7;
1174 /* Get first part (low order bits) */
1175#ifdef NO_UCHAR
1176 code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
4eeb10d4 1177#else
64d06f2f 1178 code = (*bp++ >> r_off);
4eeb10d4 1179#endif /* NO_UCHAR */
64d06f2f
KM
1180 bits -= (8 - r_off);
1181 r_off = 8 - r_off; /* now, offset into code word */
1182 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
1183 if ( bits >= 8 ) {
1184#ifdef NO_UCHAR
1185 code |= (*bp++ & 0xff) << r_off;
4eeb10d4 1186#else
64d06f2f 1187 code |= *bp++ << r_off;
4eeb10d4 1188#endif /* NO_UCHAR */
64d06f2f
KM
1189 r_off += 8;
1190 bits -= 8;
1191 }
1192 /* high order bits. */
1193 code |= (*bp & rmask[bits]) << r_off;
4eeb10d4 1194#endif /* vax */
64d06f2f
KM
1195 offset += n_bits;
1196
1197 return code;
1198}
1199
1200char *
1201rindex(s, c) /* For those who don't have it in libc.a */
1202register char *s, c;
1203{
1204 char *p;
1205 for (p = NULL; *s; s++)
1206 if (*s == c)
1207 p = s;
1208 return(p);
1209}
1210
1211#ifdef DEBUG
1212printcodes()
1213{
1214 /*
a2de8fe3 1215 * Just print out codes from input file. For debugging.
64d06f2f
KM
1216 */
1217 code_int code;
1218 int col = 0, bits;
1219
1220 bits = n_bits = INIT_BITS;
1221 maxcode = MAXCODE(n_bits);
1222 free_ent = ((block_compress) ? FIRST : 256 );
1223 while ( ( code = getcode() ) >= 0 ) {
1224 if ( (code == CLEAR) && block_compress ) {
1225 free_ent = FIRST - 1;
1226 clear_flg = 1;
1227 }
1228 else if ( free_ent < maxmaxcode )
1229 free_ent++;
1230 if ( bits != n_bits ) {
1231 fprintf(stderr, "\nChange to %d bits\n", n_bits );
1232 bits = n_bits;
1233 col = 0;
1234 }
1235 fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
1236 }
1237 putc( '\n', stderr );
1238 exit( 0 );
1239}
1240
4eeb10d4
JL
1241code_int sorttab[1<<BITS]; /* sorted pointers into htab */
1242
64d06f2f
KM
1243dump_tab() /* dump string table */
1244{
4eeb10d4 1245 register int i, first;
64d06f2f 1246 register ent;
4eeb10d4
JL
1247#define STACK_SIZE 15000
1248 int stack_top = STACK_SIZE;
1249 register c;
1250
1251 if(do_decomp == 0) { /* compressing */
1252 register int flag = 1;
1253
1254 for(i=0; i<hsize; i++) { /* build sort pointers */
1255 if((long)htabof(i) >= 0) {
1256 sorttab[codetabof(i)] = i;
64d06f2f 1257 }
64d06f2f 1258 }
4eeb10d4
JL
1259 first = block_compress ? FIRST : 256;
1260 for(i = first; i < free_ent; i++) {
1261 fprintf(stderr, "%5d: \"", i);
1262 de_stack[--stack_top] = '\n';
1263 de_stack[--stack_top] = '"';
1264 stack_top = in_stack((htabof(sorttab[i])>>maxbits)&0xff,
1265 stack_top);
1266 for(ent=htabof(sorttab[i]) & ((1<<maxbits)-1);
1267 ent > 256;
1268 ent=htabof(sorttab[ent]) & ((1<<maxbits)-1)) {
1269 stack_top = in_stack(htabof(sorttab[ent]) >> maxbits,
1270 stack_top);
1271 }
1272 stack_top = in_stack(ent, stack_top);
1273 fwrite( &de_stack[stack_top], 1, STACK_SIZE-stack_top, stderr);
1274 stack_top = STACK_SIZE;
1275 }
1276 } else if(!debug) { /* decompressing */
1277
1278 for ( i = 0; i < free_ent; i++ ) {
1279 ent = i;
1280 c = tab_suffixof(ent);
1281 if ( isascii(c) && isprint(c) )
1282 fprintf( stderr, "%5d: %5d/'%c' \"",
1283 ent, tab_prefixof(ent), c );
1284 else
1285 fprintf( stderr, "%5d: %5d/\\%03o \"",
1286 ent, tab_prefixof(ent), c );
1287 de_stack[--stack_top] = '\n';
1288 de_stack[--stack_top] = '"';
1289 for ( ; ent != NULL;
1290 ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) {
1291 stack_top = in_stack(tab_suffixof(ent), stack_top);
1292 }
1293 fwrite( &de_stack[stack_top], 1, STACK_SIZE - stack_top, stderr );
1294 stack_top = STACK_SIZE;
1295 }
64d06f2f
KM
1296 }
1297}
64d06f2f 1298
4eeb10d4
JL
1299int
1300in_stack(c, stack_top)
1301 register c, stack_top;
1302{
1303 if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) {
1304 de_stack[--stack_top] = c;
1305 } else {
1306 switch( c ) {
1307 case '\n': de_stack[--stack_top] = 'n'; break;
1308 case '\t': de_stack[--stack_top] = 't'; break;
1309 case '\b': de_stack[--stack_top] = 'b'; break;
1310 case '\f': de_stack[--stack_top] = 'f'; break;
1311 case '\r': de_stack[--stack_top] = 'r'; break;
1312 case '\\': de_stack[--stack_top] = '\\'; break;
1313 default:
1314 de_stack[--stack_top] = '0' + c % 8;
1315 de_stack[--stack_top] = '0' + (c / 8) % 8;
1316 de_stack[--stack_top] = '0' + c / 64;
1317 break;
1318 }
1319 de_stack[--stack_top] = '\\';
1320 }
1321 return stack_top;
1322}
1323#endif /* DEBUG */
64d06f2f
KM
1324
1325writeerr()
1326{
1327 perror ( ofname );
1328 unlink ( ofname );
1329 exit ( 1 );
1330}
1331
1332copystat(ifname, ofname)
1333char *ifname, *ofname;
1334{
1335 struct stat statbuf;
1336 int mode;
1337 time_t timep[2];
1338
1339 fclose(stdout);
1340 if (stat(ifname, &statbuf)) { /* Get stat on input file */
1341 perror(ifname);
1342 return;
1343 }
1344 if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) {
1345 if(quiet)
a2de8fe3 1346 fprintf(stderr, "%s: ", ifname);
64d06f2f
KM
1347 fprintf(stderr, " -- not a regular file: unchanged");
1348 exit_stat = 1;
c8f1fe84 1349 perm_stat = 1;
64d06f2f
KM
1350 } else if (statbuf.st_nlink > 1) {
1351 if(quiet)
a2de8fe3 1352 fprintf(stderr, "%s: ", ifname);
64d06f2f
KM
1353 fprintf(stderr, " -- has %d other links: unchanged",
1354 statbuf.st_nlink - 1);
1355 exit_stat = 1;
c8f1fe84 1356 perm_stat = 1;
4eeb10d4
JL
1357 } else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
1358 if(!quiet)
1359 fprintf(stderr, " -- file unchanged");
64d06f2f
KM
1360 } else { /* ***** Successful Compression ***** */
1361 exit_stat = 0;
1362 mode = statbuf.st_mode & 07777;
1363 if (chmod(ofname, mode)) /* Copy modes */
1364 perror(ofname);
1365 chown(ofname, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */
1366 timep[0] = statbuf.st_atime;
1367 timep[1] = statbuf.st_mtime;
1368 utime(ofname, timep); /* Update last accessed and modified times */
1369 if (unlink(ifname)) /* Remove input file */
1370 perror(ifname);
1371 if(!quiet)
1372 fprintf(stderr, " -- replaced with %s", ofname);
1373 return; /* Successful return */
1374 }
1375
1376 /* Unsuccessful return -- one of the tests failed */
1377 if (unlink(ofname))
1378 perror(ofname);
1379}
64d06f2f
KM
1380
1381onintr ( )
1382{
be5873af 1383 if (!precious)
ea90d69f 1384 unlink ( ofname );
4eeb10d4
JL
1385 exit ( 1 );
1386}
1387
1388oops ( ) /* wild pointer -- assume bad input */
1389{
c8f1fe84 1390 if ( do_decomp )
4eeb10d4
JL
1391 fprintf ( stderr, "uncompress: corrupt input\n" );
1392 unlink ( ofname );
64d06f2f
KM
1393 exit ( 1 );
1394}
1395
a2de8fe3 1396cl_block () /* table clear for block compress */
64d06f2f 1397{
4eeb10d4 1398 register long int rat;
64d06f2f
KM
1399
1400 checkpoint = in_count + CHECK_GAP;
4eeb10d4
JL
1401#ifdef DEBUG
1402 if ( debug ) {
1403 fprintf ( stderr, "count: %ld, ratio: ", in_count );
1404 prratio ( stderr, in_count, bytes_out );
1405 fprintf ( stderr, "\n");
1406 }
1407#endif /* DEBUG */
1408
1409 if(in_count > 0x007fffff) { /* shift will overflow */
1410 rat = bytes_out >> 8;
1411 if(rat == 0) { /* Don't divide by zero */
1412 rat = 0x7fffffff;
1413 } else {
1414 rat = in_count / rat;
64d06f2f 1415 }
4eeb10d4
JL
1416 } else {
1417 rat = (in_count << 8) / bytes_out; /* 8 fractional bits */
1418 }
1419 if ( rat > ratio ) {
1420 ratio = rat;
1421 } else {
1422 ratio = 0;
1423#ifdef DEBUG
1424 if(verbose)
1425 dump_tab(); /* dump string table */
1426#endif
1427 cl_hash ( (count_int) hsize );
64d06f2f
KM
1428 free_ent = FIRST;
1429 clear_flg = 1;
1430 output ( (code_int) CLEAR );
1431#ifdef DEBUG
1432 if(debug)
1433 fprintf ( stderr, "clear\n" );
4eeb10d4 1434#endif /* DEBUG */
64d06f2f
KM
1435 }
1436}
1437
4eeb10d4 1438cl_hash(hsize) /* reset code table */
a2de8fe3 1439 register count_int hsize;
64d06f2f 1440{
4eeb10d4 1441#ifndef XENIX_16 /* Normal machine */
64d06f2f 1442 register count_int *htab_p = htab+hsize;
4eeb10d4
JL
1443#else
1444 register j;
1445 register long k = hsize;
1446 register count_int *htab_p;
1447#endif
dad1b88c 1448 register long i;
64d06f2f
KM
1449 register long m1 = -1;
1450
4eeb10d4
JL
1451#ifdef XENIX_16
1452 for(j=0; j<=8 && k>=0; j++,k-=8192) {
1453 i = 8192;
1454 if(k < 8192) {
1455 i = k;
1456 }
1457 htab_p = &(htab[j][i]);
1458 i -= 16;
1459 if(i > 0) {
1460#else
64d06f2f 1461 i = hsize - 16;
4eeb10d4
JL
1462#endif
1463 do { /* might use Sys V memset(3) here */
64d06f2f
KM
1464 *(htab_p-16) = m1;
1465 *(htab_p-15) = m1;
1466 *(htab_p-14) = m1;
1467 *(htab_p-13) = m1;
1468 *(htab_p-12) = m1;
1469 *(htab_p-11) = m1;
1470 *(htab_p-10) = m1;
1471 *(htab_p-9) = m1;
1472 *(htab_p-8) = m1;
1473 *(htab_p-7) = m1;
1474 *(htab_p-6) = m1;
1475 *(htab_p-5) = m1;
1476 *(htab_p-4) = m1;
1477 *(htab_p-3) = m1;
1478 *(htab_p-2) = m1;
1479 *(htab_p-1) = m1;
1480 htab_p -= 16;
1481 } while ((i -= 16) >= 0);
4eeb10d4
JL
1482#ifdef XENIX_16
1483 }
1484 }
1485#endif
64d06f2f
KM
1486 for ( i += 16; i > 0; i-- )
1487 *--htab_p = m1;
1488}
a2de8fe3 1489
4eeb10d4
JL
1490prratio(stream, num, den)
1491FILE *stream;
1492long int num, den;
a2de8fe3 1493{
4eeb10d4
JL
1494 register int q; /* Doesn't need to be long */
1495
1496 if(num > 214748L) { /* 2147483647/10000 */
1497 q = num / (den / 10000L);
1498 } else {
1499 q = 10000L * num / den; /* Long calculations, though */
1500 }
1501 if (q < 0) {
1502 putc('-', stream);
1503 q = -q;
1504 }
1505 fprintf(stream, "%d.%02d%%", q / 100, q % 100);
1506}
a2de8fe3 1507
4eeb10d4
JL
1508version()
1509{
58777538 1510 fprintf(stderr, "%s, Berkeley 5.10 %G%\n", rcs_ident);
4eeb10d4
JL
1511 fprintf(stderr, "Options: ");
1512#ifdef vax
1513 fprintf(stderr, "vax, ");
1514#endif
1515#ifdef NO_UCHAR
1516 fprintf(stderr, "NO_UCHAR, ");
1517#endif
1518#ifdef SIGNED_COMPARE_SLOW
1519 fprintf(stderr, "SIGNED_COMPARE_SLOW, ");
1520#endif
1521#ifdef XENIX_16
1522 fprintf(stderr, "XENIX_16, ");
1523#endif
1524#ifdef COMPATIBLE
1525 fprintf(stderr, "COMPATIBLE, ");
1526#endif
1527#ifdef DEBUG
1528 fprintf(stderr, "DEBUG, ");
1529#endif
1530#ifdef BSD4_2
1531 fprintf(stderr, "BSD4_2, ");
1532#endif
1533 fprintf(stderr, "BITS = %d\n", BITS);
a2de8fe3 1534}