"Fossies" - the Fresh Open Source Software Archive 
Member "ncompress-5.0/compress.c" (2 Feb 2021, 44489 Bytes) of package /linux/privat/ncompress-5.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "compress.c" see the
Fossies "Dox" file reference documentation.
1 /* (N)compress.c - File compression ala IEEE Computer, Mar 1992.
2 *
3 * Authors:
4 * Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
5 * Jim McKie (decvax!mcvax!jim)
6 * Steve Davies (decvax!vax135!petsd!peora!srd)
7 * Ken Turkowski (decvax!decwrl!turtlevax!ken)
8 * James A. Woods (decvax!ihnp4!ames!jaw)
9 * Joe Orost (decvax!vax135!petsd!joe)
10 * Dave Mack (csu@alembic.acs.com)
11 * Peter Jannesen, Network Communication Systems
12 * (peter@ncs.nl)
13 * Mike Frysinger (vapier@gmail.com)
14 *
15 * Revision 4.2.3 92/03/14 peter@ncs.nl
16 * Optimise compress and decompress function and a lot of cleanups.
17 * New fast hash algoritme added (if more than 800Kb available).
18 *
19 * Revision 4.1 91/05/26 csu@alembic.acs.com
20 * Modified to recursively compress directories ('r' flag). As a side
21 * effect, compress will no longer attempt to compress things that
22 * aren't "regular" files. See Changes.
23 *
24 * Revision 4.0 85/07/30 12:50:00 joe
25 * Removed ferror() calls in output routine on every output except first.
26 * Prepared for release to the world.
27 *
28 * Revision 3.6 85/07/04 01:22:21 joe
29 * Remove much wasted storage by overlaying hash table with the tables
30 * used by decompress: tab_suffix[1<<BITS], stack[8000]. Updated USERMEM
31 * computations. Fixed dump_tab() DEBUG routine.
32 *
33 * Revision 3.5 85/06/30 20:47:21 jaw
34 * Change hash function to use exclusive-or. Rip out hash cache. These
35 * speedups render the megamemory version defunct, for now. Make decoder
36 * stack global. Parts of the RCS trunks 2.7, 2.6, and 2.1 no longer apply.
37 *
38 * Revision 3.4 85/06/27 12:00:00 ken
39 * Get rid of all floating-point calculations by doing all compression ratio
40 * calculations in fixed point.
41 *
42 * Revision 3.3 85/06/24 21:53:24 joe
43 * Incorporate portability suggestion for M_XENIX. Got rid of text on #else
44 * and #endif lines. Cleaned up #ifdefs for vax and interdata.
45 *
46 * Revision 3.2 85/06/06 21:53:24 jaw
47 * Incorporate portability suggestions for Z8000, IBM PC/XT from mailing list.
48 * Default to "quiet" output (no compression statistics).
49 *
50 * Revision 3.1 85/05/12 18:56:13 jaw
51 * Integrate decompress() stack speedups (from early pointer mods by McKie).
52 * Repair multi-file USERMEM gaffe. Unify 'force' flags to mimic semantics
53 * of SVR2 'pack'. Streamline block-compress table clear logic. Increase
54 * output byte count by magic number size.
55 *
56 * Revision 3.0 84/11/27 11:50:00 petsd!joe
57 * Set HSIZE depending on BITS. Set BITS depending on USERMEM. Unrolled
58 * loops in clear routines. Added "-C" flag for 2.0 compatibility. Used
59 * unsigned compares on Perkin-Elmer. Fixed foreground check.
60 *
61 * Revision 2.7 84/11/16 19:35:39 ames!jaw
62 * Cache common hash codes based on input statistics; this improves
63 * performance for low-density raster images. Pass on #ifdef bundle
64 * from Turkowski.
65 *
66 * Revision 2.6 84/11/05 19:18:21 ames!jaw
67 * Vary size of hash tables to reduce time for small files.
68 * Tune PDP-11 hash function.
69 *
70 * Revision 2.5 84/10/30 20:15:14 ames!jaw
71 * Junk chaining; replace with the simpler (and, on the VAX, faster)
72 * double hashing, discussed within. Make block compression standard.
73 *
74 * Revision 2.4 84/10/16 11:11:11 ames!jaw
75 * Introduce adaptive reset for block compression, to boost the rate
76 * another several percent. (See mailing list notes.)
77 *
78 * Revision 2.3 84/09/22 22:00:00 petsd!joe
79 * Implemented "-B" block compress. Implemented REVERSE sorting of tab_next.
80 * Bug fix for last bits. Changed fwrite to putchar loop everywhere.
81 *
82 * Revision 2.2 84/09/18 14:12:21 ames!jaw
83 * Fold in news changes, small machine typedef from thomas,
84 * #ifdef interdata from joe.
85 *
86 * Revision 2.1 84/09/10 12:34:56 ames!jaw
87 * Configured fast table lookup for 32-bit machines.
88 * This cuts user time in half for b <= FBITS, and is useful for news batching
89 * from VAX to PDP sites. Also sped up decompress() [fwrite->putc] and
90 * added signal catcher [plus beef in write_error()] to delete effluvia.
91 *
92 * Revision 2.0 84/08/28 22:00:00 petsd!joe
93 * Add check for foreground before prompting user. Insert maxbits into
94 * compressed file. Force file being uncompressed to end with ".Z".
95 * Added "-c" flag and "zcat". Prepared for release.
96 *
97 * Revision 1.10 84/08/24 18:28:00 turtlevax!ken
98 * Will only compress regular files (no directories), added a magic number
99 * header (plus an undocumented -n flag to handle old files without headers),
100 * added -f flag to force overwriting of possibly existing destination file,
101 * otherwise the user is prompted for a response. Will tack on a .Z to a
102 * filename if it doesn't have one when decompressing. Will only replace
103 * file if it was compressed.
104 *
105 * Revision 1.9 84/08/16 17:28:00 turtlevax!ken
106 * Removed scanargs(), getopt(), added .Z extension and unlimited number of
107 * filenames to compress. Flags may be clustered (-Ddvb12) or separated
108 * (-D -d -v -b 12), or combination thereof. Modes and other status is
109 * copied with copystat(). -O bug for 4.2 seems to have disappeared with
110 * 1.8.
111 *
112 * Revision 1.8 84/08/09 23:15:00 joe
113 * Made it compatible with vax version, installed jim's fixes/enhancements
114 *
115 * Revision 1.6 84/08/01 22:08:00 joe
116 * Sped up algorithm significantly by sorting the compress chain.
117 *
118 * Revision 1.5 84/07/13 13:11:00 srd
119 * Added C version of vax asm routines. Changed structure to arrays to
120 * save much memory. Do unsigned compares where possible (faster on
121 * Perkin-Elmer)
122 *
123 * Revision 1.4 84/07/05 03:11:11 thomas
124 * Clean up the code a little and lint it. (Lint complains about all
125 * the regs used in the asm, but I'm not going to "fix" this.)
126 *
127 * Revision 1.3 84/07/05 02:06:54 thomas
128 * Minor fixes.
129 *
130 * Revision 1.2 84/07/05 00:27:27 thomas
131 * Add variable bit length output.
132 *
133 */
134
135 #ifdef _MSC_VER
136 # define WINDOWS
137 #endif
138
139 #ifdef __MINGW32__
140 # define MINGW
141 #endif
142
143 #include <stdint.h>
144 #include <stdio.h>
145 #include <stdlib.h>
146 #include <string.h>
147 #include <fcntl.h>
148 #include <ctype.h>
149 #include <signal.h>
150 #include <sys/types.h>
151 #include <sys/stat.h>
152 #include <errno.h>
153
154 #if !defined(DOS) && !defined(WINDOWS)
155 # include <dirent.h>
156 # define RECURSIVE 1
157 # include <unistd.h>
158 #else
159 # include <io.h>
160 #endif
161
162 #ifdef UTIME_H
163 # include <utime.h>
164 #else
165 struct utimbuf {
166 time_t actime;
167 time_t modtime;
168 };
169 #endif
170
171 #ifdef __STDC__
172 # define ARGS(a) a
173 #else
174 # define ARGS(a) ()
175 #endif
176
177 #ifndef SIG_TYPE
178 # define SIG_TYPE void (*)()
179 #endif
180
181 #if defined(AMIGA) || defined(DOS) || defined(MINGW) || defined(WINDOWS)
182 # define chmod(pathname, mode) 0
183 # define chown(pathname, owner, group) 0
184 # define utime(pathname, times) 0
185 #endif
186
187 #if defined(MINGW) || defined(WINDOWS)
188 # define isatty(fd) 0
189 # define open _open
190 # define close _close
191 # define read _read
192 # define strdup _strdup
193 # define unlink _unlink
194 # define write _write
195 #else
196 /* NB: macOS has a setmode() that is different from Windows. */
197 # define setmode(fd, mode)
198 #endif
199
200 #ifndef LSTAT
201 # define lstat stat
202 #endif
203
204 #if defined(DOS) || defined(WINDOWS)
205 # define F_OK 0
206 static inline int access(const char *pathname, int mode)
207 {
208 struct stat st;
209 return lstat(pathname, &st);
210 }
211 #endif
212
213 #include "patchlevel.h"
214
215 #undef min
216 #define min(a,b) ((a>b) ? b : a)
217
218 #ifndef IBUFSIZ
219 # define IBUFSIZ BUFSIZ /* Defailt input buffer size */
220 #endif
221 #ifndef OBUFSIZ
222 # define OBUFSIZ BUFSIZ /* Default output buffer size */
223 #endif
224
225 /* Defines for third byte of header */
226 #define MAGIC_1 (char_type)'\037'/* First byte of compressed file */
227 #define MAGIC_2 (char_type)'\235'/* Second byte of compressed file */
228 #define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */
229 /* Masks 0x20 and 0x40 are free. */
230 /* I think 0x20 should mean that there is */
231 /* a fourth header byte (for expansion). */
232 #define BLOCK_MODE 0x80 /* Block compresssion if table is full and */
233 /* compression rate is dropping flush tables */
234
235 /* the next two codes should not be changed lightly, as they must not */
236 /* lie within the contiguous general code space. */
237 #define FIRST 257 /* first free entry */
238 #define CLEAR 256 /* table clear output code */
239
240 #define INIT_BITS 9 /* initial number of bits/code */
241
242 #ifndef SACREDMEM
243 /*
244 * SACREDMEM is the amount of physical memory saved for others; compress
245 * will hog the rest.
246 */
247 # define SACREDMEM 0
248 #endif
249
250 #ifndef USERMEM
251 /*
252 * Set USERMEM to the maximum amount of physical user memory available
253 * in bytes. USERMEM is used to determine the maximum BITS that can be used
254 * for compression.
255 */
256 # define USERMEM 450000 /* default user memory */
257 #endif
258
259 #ifndef BYTEORDER
260 # define BYTEORDER 0000
261 #endif
262
263 /*
264 * machine variants which require cc -Dmachine: pdp11, z8000, DOS
265 */
266
267 #ifdef DOS /* PC/XT/AT (8088) processor */
268 # define BITS 16 /* 16-bits processor max 12 bits */
269 # if BITS == 16
270 # define MAXSEG_64K
271 # endif
272 # undef BYTEORDER
273 # define BYTEORDER 4321
274 #endif /* DOS */
275
276 #ifndef O_BINARY
277 # define O_BINARY 0 /* System has no binary mode */
278 #endif
279
280 #ifdef M_XENIX /* Stupid compiler can't handle arrays with */
281 # if BITS == 16 /* more than 65535 bytes - so we fake it */
282 # define MAXSEG_64K
283 # else
284 # if BITS > 13 /* Code only handles BITS = 12, 13, or 16 */
285 # define BITS 13
286 # endif
287 # endif
288 #endif
289
290 #ifndef BITS /* General processor calculate BITS */
291 # if USERMEM >= (800000+SACREDMEM)
292 # define FAST
293 # else
294 # if USERMEM >= (433484+SACREDMEM)
295 # define BITS 16
296 # else
297 # if USERMEM >= (229600+SACREDMEM)
298 # define BITS 15
299 # else
300 # if USERMEM >= (127536+SACREDMEM)
301 # define BITS 14
302 # else
303 # if USERMEM >= (73464+SACREDMEM)
304 # define BITS 13
305 # else
306 # define BITS 12
307 # endif
308 # endif
309 # endif
310 # endif
311 # endif
312 #endif /* BITS */
313
314 #ifdef FAST
315 # define HBITS 17 /* 50% occupancy */
316 # define HSIZE (1<<HBITS)
317 # define HMASK (HSIZE-1)
318 # define HPRIME 9941
319 # define BITS 16
320 # undef MAXSEG_64K
321 #else
322 # if BITS == 16
323 # define HSIZE 69001 /* 95% occupancy */
324 # endif
325 # if BITS == 15
326 # define HSIZE 35023 /* 94% occupancy */
327 # endif
328 # if BITS == 14
329 # define HSIZE 18013 /* 91% occupancy */
330 # endif
331 # if BITS == 13
332 # define HSIZE 9001 /* 91% occupancy */
333 # endif
334 # if BITS <= 12
335 # define HSIZE 5003 /* 80% occupancy */
336 # endif
337 #endif
338
339 #define CHECK_GAP 10000
340
341 typedef long int code_int;
342
343 #ifdef SIGNED_COMPARE_SLOW
344 typedef unsigned long int count_int;
345 typedef unsigned short int count_short;
346 typedef unsigned long int cmp_code_int; /* Cast to make compare faster */
347 #else
348 typedef long int count_int;
349 typedef long int cmp_code_int;
350 #endif
351
352 typedef unsigned char char_type;
353
354 #define ARGVAL() (*++(*argv) || (--argc && *++argv))
355
356 #define MAXCODE(n) (1L << (n))
357
358 union bytes
359 {
360 long word;
361 struct
362 {
363 #if BYTEORDER == 4321
364 char_type b1;
365 char_type b2;
366 char_type b3;
367 char_type b4;
368 #else
369 #if BYTEORDER == 1234
370 char_type b4;
371 char_type b3;
372 char_type b2;
373 char_type b1;
374 #else
375 # undef BYTEORDER
376 int dummy;
377 #endif
378 #endif
379 } bytes;
380 } ;
381 #ifdef BYTEORDER
382 #define output(b,o,c,n) { char_type *p = &(b)[(o)>>3]; \
383 union bytes i; \
384 i.word = ((long)(c))<<((o)&0x7); \
385 p[0] |= i.bytes.b1; \
386 p[1] |= i.bytes.b2; \
387 p[2] |= i.bytes.b3; \
388 (o) += (n); \
389 }
390 #else
391 #define output(b,o,c,n) { char_type *p = &(b)[(o)>>3]; \
392 long i = ((long)(c))<<((o)&0x7); \
393 p[0] |= (char_type)(i); \
394 p[1] |= (char_type)(i>>8); \
395 p[2] |= (char_type)(i>>16); \
396 (o) += (n); \
397 }
398 #endif
399 #define input(b,o,c,n,m){ char_type *p = &(b)[(o)>>3]; \
400 (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \
401 ((long)(p[2])<<16))>>((o)&0x7))&(m); \
402 (o) += (n); \
403 }
404
405 char *progname; /* Program name */
406 int silent = 0; /* don't tell me about errors */
407 int quiet = 1; /* don't tell me about compression */
408 int do_decomp = 0; /* Decompress mode */
409 int force = 0; /* Force overwrite of files and links */
410 int keep = 0; /* Keep input files */
411 int nomagic = 0; /* Use a 3-byte magic number header, */
412 /* unless old file */
413 int maxbits = BITS; /* user settable max # bits/code */
414 int zcat_flg = 0; /* Write output on stdout, suppress messages */
415 int recursive = 0; /* compress directories */
416 int exit_code = -1; /* Exitcode of compress (-1 no file compressed) */
417
418 char_type inbuf[IBUFSIZ+64]; /* Input buffer */
419 char_type outbuf[OBUFSIZ+2048];/* Output buffer */
420
421 struct stat infstat; /* Input file status */
422 char *ifname; /* Input filename */
423 int remove_ofname = 0; /* Remove output file on a error */
424 char *ofname = NULL; /* Output filename */
425 int fgnd_flag = 0; /* Running in background (SIGINT=SIGIGN) */
426
427 long bytes_in; /* Total number of byte from input */
428 long bytes_out; /* Total number of byte to output */
429
430 /*
431 * 8086 & 80286 Has a problem with array bigger than 64K so fake the array
432 * For processors with a limited address space and segments.
433 */
434 /*
435 * To save much memory, we overlay the table used by compress() with those
436 * used by decompress(). The tab_prefix table is the same size and type
437 * as the codetab. The tab_suffix table needs 2**BITS characters. We
438 * get this from the beginning of htab. The output stack uses the rest
439 * of htab, and contains characters. There is plenty of room for any
440 * possible stack (stack used to be 8000 characters).
441 */
442 #ifdef MAXSEG_64K
443 count_int htab0[8192];
444 count_int htab1[8192];
445 count_int htab2[8192];
446 count_int htab3[8192];
447 count_int htab4[8192];
448 count_int htab5[8192];
449 count_int htab6[8192];
450 count_int htab7[8192];
451 count_int htab8[HSIZE-65536];
452 count_int * htab[9] = {htab0,htab1,htab2,htab3,htab4,htab5,htab6,htab7,htab8};
453
454 unsigned short code0tab[16384];
455 unsigned short code1tab[16384];
456 unsigned short code2tab[16384];
457 unsigned short code3tab[16384];
458 unsigned short code4tab[16384];
459 unsigned short * codetab[5] = {code0tab,code1tab,code2tab,code3tab,code4tab};
460
461 # define htabof(i) (htab[(i) >> 13][(i) & 0x1fff])
462 # define codetabof(i) (codetab[(i) >> 14][(i) & 0x3fff])
463 # define tab_prefixof(i) codetabof(i)
464 # define tab_suffixof(i) ((char_type *)htab[(i)>>15])[(i) & 0x7fff]
465 # define de_stack ((char_type *)(&htab2[8191]))
466 void clear_htab()
467 {
468 memset(htab0, -1, sizeof(htab0));
469 memset(htab1, -1, sizeof(htab1));
470 memset(htab2, -1, sizeof(htab2));
471 memset(htab3, -1, sizeof(htab3));
472 memset(htab4, -1, sizeof(htab4));
473 memset(htab5, -1, sizeof(htab5));
474 memset(htab6, -1, sizeof(htab6));
475 memset(htab7, -1, sizeof(htab7));
476 memset(htab8, -1, sizeof(htab8));
477 }
478 # define clear_tab_prefixof() memset(code0tab, 0, 256);
479 #else /* Normal machine */
480 count_int htab[HSIZE];
481 unsigned short codetab[HSIZE];
482
483 # define htabof(i) htab[i]
484 # define codetabof(i) codetab[i]
485 # define tab_prefixof(i) codetabof(i)
486 # define tab_suffixof(i) ((char_type *)(htab))[i]
487 # define de_stack ((char_type *)&(htab[HSIZE-1]))
488 # define clear_htab() memset(htab, -1, sizeof(htab))
489 # define clear_tab_prefixof() memset(codetab, 0, 256);
490 #endif /* MAXSEG_64K */
491
492 #ifdef FAST
493 int primetab[256] = /* Special secudary hash table. */
494 {
495 1013, -1061, 1109, -1181, 1231, -1291, 1361, -1429,
496 1481, -1531, 1583, -1627, 1699, -1759, 1831, -1889,
497 1973, -2017, 2083, -2137, 2213, -2273, 2339, -2383,
498 2441, -2531, 2593, -2663, 2707, -2753, 2819, -2887,
499 2957, -3023, 3089, -3181, 3251, -3313, 3361, -3449,
500 3511, -3557, 3617, -3677, 3739, -3821, 3881, -3931,
501 4013, -4079, 4139, -4219, 4271, -4349, 4423, -4493,
502 4561, -4639, 4691, -4783, 4831, -4931, 4973, -5023,
503 5101, -5179, 5261, -5333, 5413, -5471, 5521, -5591,
504 5659, -5737, 5807, -5857, 5923, -6029, 6089, -6151,
505 6221, -6287, 6343, -6397, 6491, -6571, 6659, -6709,
506 6791, -6857, 6917, -6983, 7043, -7129, 7213, -7297,
507 7369, -7477, 7529, -7577, 7643, -7703, 7789, -7873,
508 7933, -8017, 8093, -8171, 8237, -8297, 8387, -8461,
509 8543, -8627, 8689, -8741, 8819, -8867, 8963, -9029,
510 9109, -9181, 9241, -9323, 9397, -9439, 9511, -9613,
511 9677, -9743, 9811, -9871, 9941,-10061,10111,-10177,
512 10259,-10321,10399,-10477,10567,-10639,10711,-10789,
513 10867,-10949,11047,-11113,11173,-11261,11329,-11423,
514 11491,-11587,11681,-11777,11827,-11903,11959,-12041,
515 12109,-12197,12263,-12343,12413,-12487,12541,-12611,
516 12671,-12757,12829,-12917,12979,-13043,13127,-13187,
517 13291,-13367,13451,-13523,13619,-13691,13751,-13829,
518 13901,-13967,14057,-14153,14249,-14341,14419,-14489,
519 14557,-14633,14717,-14767,14831,-14897,14983,-15083,
520 15149,-15233,15289,-15359,15427,-15497,15583,-15649,
521 15733,-15791,15881,-15937,16057,-16097,16189,-16267,
522 16363,-16447,16529,-16619,16691,-16763,16879,-16937,
523 17021,-17093,17183,-17257,17341,-17401,17477,-17551,
524 17623,-17713,17791,-17891,17957,-18041,18097,-18169,
525 18233,-18307,18379,-18451,18523,-18637,18731,-18803,
526 18919,-19031,19121,-19211,19273,-19381,19429,-19477
527 } ;
528 #endif
529
530 int main ARGS((int,char **));
531 void Usage ARGS((int));
532 void comprexx ARGS((const char *));
533 void compdir ARGS((char *));
534 void compress ARGS((int,int));
535 void decompress ARGS((int,int));
536 void read_error ARGS((void));
537 void write_error ARGS((void));
538 void abort_compress ARGS((void));
539 void prratio ARGS((FILE *,long,long));
540 void about ARGS((void));
541
542 /*****************************************************************
543 * TAG( main )
544 *
545 * Algorithm from "A Technique for High Performance Data Compression",
546 * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
547 *
548 * Usage: compress [-dfvc] [-b bits] [file ...]
549 * Inputs:
550 * -d: If given, decompression is done instead.
551 *
552 * -c: Write output on stdout, don't remove original.
553 *
554 * -b: Parameter limits the max number of bits/code.
555 *
556 * -f: Forces output file to be generated, even if one already
557 * exists, and even if no space is saved by compressing.
558 * If -f is not used, the user will be prompted if stdin is
559 * a tty, otherwise, the output file will not be overwritten.
560 *
561 * -v: Write compression statistics
562 *
563 * -r: Recursive. If a filename is a directory, descend
564 * into it and compress everything in it.
565 *
566 * file ...:
567 * Files to be compressed. If none specified, stdin is used.
568 * Outputs:
569 * file.Z: Compressed form of file with same mode, owner, and utimes
570 * or stdout (if stdin used as input)
571 *
572 * Assumptions:
573 * When filenames are given, replaces with the compressed version
574 * (.Z suffix) only if the file decreases in size.
575 *
576 * Algorithm:
577 * Modified Lempel-Ziv method (LZW). Basically finds common
578 * substrings and replaces them with a variable size code. This is
579 * deterministic, and can be done on the fly. Thus, the decompression
580 * procedure needs no input table, but tracks the way the table was built.
581 */
582 int
583 main(argc, argv)
584 int argc;
585 char *argv[];
586 {
587 char **filelist;
588 char **fileptr;
589 int seen_double_dash = 0;
590
591 #ifdef SIGINT
592 if ((fgnd_flag = (signal(SIGINT, SIG_IGN)) != SIG_IGN))
593 signal(SIGINT, (SIG_TYPE)abort_compress);
594 #endif
595
596 #ifdef SIGTERM
597 signal(SIGTERM, (SIG_TYPE)abort_compress);
598 #endif
599 #ifdef SIGHUP
600 signal(SIGHUP, (SIG_TYPE)abort_compress);
601 #endif
602
603 #ifdef COMPATIBLE
604 nomagic = 1; /* Original didn't have a magic number */
605 #endif
606
607 filelist = (char **)malloc(argc*sizeof(char *));
608 if (filelist == NULL)
609 {
610 fprintf(stderr, "Cannot allocate memory for file list.\n");
611 exit (1);
612 }
613 fileptr = filelist;
614 *filelist = NULL;
615
616 if((progname = strrchr(argv[0], '/')) != 0)
617 progname++;
618 else
619 progname = argv[0];
620
621 if (strcmp(progname, "uncompress") == 0)
622 do_decomp = 1;
623 else
624 if (strcmp(progname, "zcat") == 0)
625 do_decomp = zcat_flg = 1;
626
627 /* Argument Processing
628 * All flags are optional.
629 * -V => print Version; debug verbose
630 * -d => do_decomp
631 * -v => unquiet
632 * -f => force overwrite of output file
633 * -k => keep input files
634 * -n => no header: useful to uncompress old files
635 * -b maxbits => maxbits. If -b is specified, then maxbits MUST be given also.
636 * -c => cat all output to stdout
637 * -C => generate output compatible with compress 2.0.
638 * -r => recursively compress directories
639 * if a string is left, must be an input filename.
640 */
641
642 for (argc--, argv++; argc > 0; argc--, argv++)
643 {
644 if (strcmp(*argv, "--") == 0)
645 {
646 seen_double_dash = 1;
647 continue;
648 }
649
650 if (seen_double_dash == 0 && **argv == '-')
651 {/* A flag argument */
652 while (*++(*argv))
653 {/* Process all flags in this arg */
654 switch (**argv)
655 {
656 case 'V':
657 about();
658 break;
659
660 case 's':
661 silent = 1;
662 quiet = 1;
663 break;
664
665 case 'v':
666 silent = 0;
667 quiet = 0;
668 break;
669
670 case 'd':
671 do_decomp = 1;
672 break;
673
674 case 'k':
675 keep = 1;
676 break;
677
678 case 'f':
679 case 'F':
680 force = 1;
681 break;
682
683 case 'n':
684 nomagic = 1;
685 break;
686
687 case 'b':
688 if (!ARGVAL())
689 {
690 fprintf(stderr, "Missing maxbits\n");
691 Usage(1);
692 }
693
694 maxbits = atoi(*argv);
695 goto nextarg;
696
697 case 'c':
698 zcat_flg = 1;
699 break;
700
701 case 'q':
702 quiet = 1;
703 break;
704 case 'r':
705 case 'R':
706 #ifdef RECURSIVE
707 recursive = 1;
708 #else
709 fprintf(stderr, "%s -r not available (due to missing directory functions)\n", *argv);
710 #endif
711 break;
712
713 case 'h':
714 Usage(0);
715 break;
716
717 default:
718 fprintf(stderr, "Unknown flag: '%c'; ", **argv);
719 Usage(1);
720 }
721 }
722 }
723 else
724 {
725 *fileptr++ = *argv; /* Build input file list */
726 *fileptr = NULL;
727 }
728
729 nextarg: continue;
730 }
731
732 if (maxbits < INIT_BITS) maxbits = INIT_BITS;
733 if (maxbits > BITS) maxbits = BITS;
734
735 if (*filelist != NULL)
736 {
737 for (fileptr = filelist; *fileptr; fileptr++)
738 comprexx(*fileptr);
739 }
740 else
741 {/* Standard input */
742 ifname = "";
743 exit_code = 0;
744 remove_ofname = 0;
745
746 setmode(0, O_BINARY);
747 setmode(1, O_BINARY);
748
749 if (do_decomp == 0)
750 {
751 compress(0, 1);
752
753 if (zcat_flg == 0 && !quiet)
754 {
755 fprintf(stderr, "Compression: ");
756 prratio(stderr, bytes_in-bytes_out, bytes_in);
757 fprintf(stderr, "\n");
758 }
759
760 if (bytes_out >= bytes_in && !(force))
761 exit_code = 2;
762 }
763 else
764 decompress(0, 1);
765 }
766
767 if (recursive && exit_code == -1) {
768 fprintf(stderr, "no files processed after recursive search\n");
769 }
770 exit((exit_code== -1) ? 1:exit_code);
771 }
772
773 void
774 Usage(int status)
775 {
776 fprintf(status ? stderr : stdout, "\
777 Usage: %s [-dfhvcVr] [-b maxbits] [--] [path ...]\n\
778 -- Halt option processing and treat all remaining args as paths.\n\
779 -d If given, decompression is done instead.\n\
780 -c Write output on stdout, don't remove original.\n\
781 -k Keep input files (do not automatically remove).\n\
782 -b Parameter limits the max number of bits/code.\n\
783 -f Forces output file to be generated, even if one already.\n\
784 exists, and even if no space is saved by compressing.\n\
785 If -f is not used, the user will be prompted if stdin is.\n\
786 a tty, otherwise, the output file will not be overwritten.\n\
787 -h This help output.\n\
788 -v Write compression statistics.\n\
789 -V Output version and compile options.\n\
790 -r Recursive. If a path is a directory, compress everything in it.\n",
791 progname);
792
793 exit(status);
794 }
795
796 void
797 comprexx(fileptr)
798 const char *fileptr;
799 {
800 int fdin = -1;
801 int fdout = -1;
802 int has_z_suffix;
803 char *tempname;
804 unsigned long namesize = strlen(fileptr);
805
806 /* Create a temp buffer to add/remove the .Z suffix. */
807 tempname = malloc(namesize + 3);
808 if (tempname == NULL)
809 {
810 perror("malloc");
811 goto error;
812 }
813
814 strcpy(tempname,fileptr);
815 has_z_suffix = (namesize >= 2 && strcmp(&tempname[namesize - 2], ".Z") == 0);
816 errno = 0;
817
818 if (lstat(tempname,&infstat) == -1)
819 {
820 if (do_decomp)
821 {
822 switch (errno)
823 {
824 case ENOENT: /* file doesn't exist */
825 /*
826 ** if the given name doesn't end with .Z, try appending one
827 ** This is obviously the wrong thing to do if it's a
828 ** directory, but it shouldn't do any harm.
829 */
830 if (!has_z_suffix)
831 {
832 memcpy(&tempname[namesize], ".Z", 3);
833 namesize += 2;
834 has_z_suffix = 1;
835 errno = 0;
836 if (lstat(tempname,&infstat) == -1)
837 {
838 perror(tempname);
839 goto error;
840 }
841
842 if ((infstat.st_mode & S_IFMT) != S_IFREG)
843 {
844 fprintf(stderr, "%s: Not a regular file.\n", tempname);
845 goto error;
846 }
847 }
848 else
849 {
850 perror(tempname);
851 goto error;
852 }
853
854 break;
855
856 default:
857 perror(tempname);
858 goto error;
859 }
860 }
861 else
862 {
863 perror(tempname);
864 goto error;
865 }
866 }
867
868 switch (infstat.st_mode & S_IFMT)
869 {
870 case S_IFDIR: /* directory */
871 #ifdef RECURSIVE
872 if (recursive)
873 compdir(tempname);
874 else
875 #endif
876 if (!quiet)
877 fprintf(stderr,"%s is a directory -- ignored\n", tempname);
878 break;
879
880 case S_IFREG: /* regular file */
881 if (do_decomp != 0)
882 {/* DECOMPRESSION */
883 if (!zcat_flg)
884 {
885 if (!has_z_suffix)
886 {
887 /* Ignore this scenario in recursive mode: while we
888 * decompress files in this dir, our readdir scan
889 * might turn up those new files. There is no way
890 * to efficiently handle this on very large dirs,
891 * so we ignore it. This also allows the user to
892 * easily resume partial decompressions.
893 */
894 if (recursive) {
895 free(tempname);
896 return;
897 }
898
899 if (!quiet)
900 fprintf(stderr,"%s - no .Z suffix\n",tempname);
901
902 goto error;
903 }
904 }
905
906 free(ofname);
907 ofname = strdup(tempname);
908 if (ofname == NULL)
909 {
910 perror("strdup");
911 goto error;
912 }
913
914 /* Strip of .Z suffix */
915 if (has_z_suffix)
916 ofname[namesize - 2] = '\0';
917 }
918 else
919 {/* COMPRESSION */
920 if (!zcat_flg)
921 {
922 if (has_z_suffix)
923 {
924 /* Ignore this scenario in recursive mode.
925 * See comment above in the decompress path.
926 */
927 if (!recursive)
928 fprintf(stderr, "%s: already has .Z suffix -- no change\n", tempname);
929 free(tempname);
930 return;
931 }
932
933 if (infstat.st_nlink > 1 && (!force))
934 {
935 fprintf(stderr, "%s has %jd other links: unchanged\n",
936 tempname, (intmax_t)(infstat.st_nlink - 1));
937 goto error;
938 }
939 }
940
941 ofname = malloc(namesize + 3);
942 if (ofname == NULL)
943 {
944 perror("malloc");
945 goto error;
946 }
947 memcpy(ofname, tempname, namesize);
948 strcpy(&ofname[namesize], ".Z");
949 }
950
951 if ((fdin = open(ifname = tempname, O_RDONLY|O_BINARY)) == -1)
952 {
953 perror(tempname);
954 goto error;
955 }
956
957 if (zcat_flg == 0)
958 {
959 if (access(ofname, F_OK) == 0)
960 {
961 if (!force)
962 {
963 inbuf[0] = 'n';
964
965 fprintf(stderr, "%s already exists.\n", ofname);
966
967 if (fgnd_flag && isatty(0))
968 {
969 fprintf(stderr, "Do you wish to overwrite %s (y or n)? ", ofname);
970 fflush(stderr);
971
972 if (read(0, inbuf, 1) > 0)
973 {
974 if (inbuf[0] != '\n')
975 {
976 do
977 {
978 if (read(0, inbuf+1, 1) <= 0)
979 {
980 perror("stdin");
981 break;
982 }
983 }
984 while (inbuf[1] != '\n');
985 }
986 }
987 else
988 perror("stdin");
989 }
990
991 if (inbuf[0] != 'y')
992 {
993 fprintf(stderr, "%s not overwritten\n", ofname);
994 goto error;
995 }
996 }
997
998 if (unlink(ofname))
999 {
1000 fprintf(stderr, "Can't remove old output file\n");
1001 perror(ofname);
1002 goto error;
1003 }
1004 }
1005
1006 if ((fdout = open(ofname, O_WRONLY|O_CREAT|O_EXCL|O_BINARY,0600)) == -1)
1007 {
1008 perror(tempname);
1009 goto error;
1010 }
1011
1012 if(!quiet)
1013 fprintf(stderr, "%s: ", tempname);
1014
1015 remove_ofname = 1;
1016 }
1017 else
1018 {
1019 fdout = 1;
1020 setmode(fdout, O_BINARY);
1021 remove_ofname = 0;
1022 }
1023
1024 if (do_decomp == 0)
1025 compress(fdin, fdout);
1026 else
1027 decompress(fdin, fdout);
1028
1029 close(fdin);
1030
1031 if (fdout != 1 && close(fdout))
1032 write_error();
1033
1034 if ( (bytes_in == 0) && (force == 0 ) )
1035 {
1036 if (remove_ofname)
1037 {
1038 if(!quiet)
1039 fprintf(stderr, "No compression -- %s unchanged\n", ifname);
1040 if (unlink(ofname)) /* Remove input file */
1041 {
1042 fprintf(stderr, "\nunlink error (ignored) ");
1043 perror(ofname);
1044 }
1045
1046 remove_ofname = 0;
1047 exit_code = 2;
1048 }
1049 }
1050 else
1051 if (zcat_flg == 0)
1052 {
1053 struct utimbuf timep;
1054
1055 if (!do_decomp && bytes_out >= bytes_in && (!force))
1056 {/* No compression: remove file.Z */
1057 if(!quiet)
1058 fprintf(stderr, "No compression -- %s unchanged\n", ifname);
1059
1060 if (unlink(ofname))
1061 {
1062 fprintf(stderr, "unlink error (ignored) ");
1063 perror(ofname);
1064 }
1065
1066 remove_ofname = 0;
1067 exit_code = 2;
1068 }
1069 else
1070 {/* ***** Successful Compression ***** */
1071 if(!quiet)
1072 {
1073 fprintf(stderr, " -- replaced with %s",ofname);
1074
1075 if (!do_decomp)
1076 {
1077 fprintf(stderr, " Compression: ");
1078 prratio(stderr, bytes_in-bytes_out, bytes_in);
1079 }
1080
1081 fprintf(stderr, "\n");
1082 }
1083
1084 timep.actime = infstat.st_atime;
1085 timep.modtime = infstat.st_mtime;
1086
1087 if (utime(ofname, &timep))
1088 {
1089 fprintf(stderr, "\nutime error (ignored) ");
1090 perror(ofname);
1091 }
1092
1093 if (chmod(ofname, infstat.st_mode & 07777)) /* Copy modes */
1094 {
1095 fprintf(stderr, "\nchmod error (ignored) ");
1096 perror(ofname);
1097 }
1098
1099 if (chown(ofname, infstat.st_uid, infstat.st_gid)) /* Copy ownership */
1100 {
1101 fprintf(stderr, "\nchown error (ignored) ");
1102 perror(ofname);
1103 }
1104
1105 remove_ofname = 0;
1106
1107 if (!keep && unlink(ifname)) /* Remove input file */
1108 {
1109 fprintf(stderr, "\nunlink error (ignored) ");
1110 perror(ifname);
1111 }
1112 }
1113 }
1114
1115 if (exit_code == -1)
1116 exit_code = 0;
1117
1118 break;
1119
1120 default:
1121 fprintf(stderr,"%s is not a directory or a regular file - ignored\n",
1122 tempname);
1123 break;
1124 }
1125
1126 free(tempname);
1127 if (!remove_ofname)
1128 {
1129 free(ofname);
1130 ofname = NULL;
1131 }
1132 return;
1133
1134 error:
1135 free(ofname);
1136 ofname = NULL;
1137 free(tempname);
1138 exit_code = 1;
1139 if (fdin != -1)
1140 close(fdin);
1141 if (fdout != -1)
1142 close(fdout);
1143 }
1144
1145 #ifdef RECURSIVE
1146 void
1147 compdir(dir)
1148 char *dir;
1149 {
1150 struct dirent *dp;
1151 DIR *dirp;
1152 char *nptr;
1153 char *fptr;
1154 unsigned long dir_size = strlen(dir);
1155 /* The +256 is a lazy optimization. We'll resize on demand. */
1156 unsigned long size = dir_size + 256;
1157
1158 nptr = malloc(size);
1159 if (nptr == NULL)
1160 {
1161 perror("malloc");
1162 exit_code = 1;
1163 return;
1164 }
1165 memcpy(nptr, dir, dir_size);
1166 nptr[dir_size] = '/';
1167 fptr = &nptr[dir_size + 1];
1168
1169 dirp = opendir(dir);
1170
1171 if (dirp == NULL)
1172 {
1173 free(nptr);
1174 printf("%s unreadable\n", dir); /* not stderr! */
1175 return ;
1176 }
1177
1178 while ((dp = readdir(dirp)) != NULL)
1179 {
1180 if (dp->d_ino == 0)
1181 continue;
1182
1183 if (strcmp(dp->d_name,".") == 0 || strcmp(dp->d_name,"..") == 0)
1184 continue;
1185
1186 if (size < dir_size + strlen(dp->d_name) + 2)
1187 {
1188 size = dir_size + strlen(dp->d_name) + 2;
1189 nptr = realloc(nptr, size);
1190 if (nptr == NULL)
1191 {
1192 perror("realloc");
1193 exit_code = 1;
1194 break;
1195 }
1196 fptr = &nptr[dir_size + 1];
1197 }
1198
1199 strcpy(fptr, dp->d_name);
1200 comprexx(nptr);
1201 }
1202
1203 closedir(dirp);
1204
1205 free(nptr);
1206 }
1207 #endif
1208 /*
1209 * compress fdin to fdout
1210 *
1211 * Algorithm: use open addressing double hashing (no chaining) on the
1212 * prefix code / next character combination. We do a variant of Knuth's
1213 * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
1214 * secondary probe. Here, the modular division first probe is gives way
1215 * to a faster exclusive-or manipulation. Also do block compression with
1216 * an adaptive reset, whereby the code table is cleared when the compression
1217 * ratio decreases, but after the table fills. The variable-length output
1218 * codes are re-sized at this point, and a special CLEAR code is generated
1219 * for the decompressor. Late addition: construct the table according to
1220 * file size for noticeable speed improvement on small files. Please direct
1221 * questions about this implementation to ames!jaw.
1222 */
1223 void
1224 compress(fdin, fdout)
1225 int fdin;
1226 int fdout;
1227 {
1228 long hp;
1229 int rpos;
1230 long fc;
1231 int outbits;
1232 int rlop;
1233 int rsize;
1234 int stcode;
1235 code_int free_ent;
1236 int boff;
1237 int n_bits;
1238 int ratio;
1239 long checkpoint;
1240 code_int extcode;
1241 union
1242 {
1243 long code;
1244 struct
1245 {
1246 char_type c;
1247 unsigned short ent;
1248 } e;
1249 } fcode;
1250
1251 ratio = 0;
1252 checkpoint = CHECK_GAP;
1253 extcode = MAXCODE(n_bits = INIT_BITS)+1;
1254 stcode = 1;
1255 free_ent = FIRST;
1256
1257 memset(outbuf, 0, sizeof(outbuf));
1258 bytes_out = 0; bytes_in = 0;
1259 outbuf[0] = MAGIC_1;
1260 outbuf[1] = MAGIC_2;
1261 outbuf[2] = (char)(maxbits | BLOCK_MODE);
1262 boff = outbits = (3<<3);
1263 fcode.code = 0;
1264
1265 clear_htab();
1266
1267 while ((rsize = read(fdin, inbuf, IBUFSIZ)) > 0)
1268 {
1269 if (bytes_in == 0)
1270 {
1271 fcode.e.ent = inbuf[0];
1272 rpos = 1;
1273 }
1274 else
1275 rpos = 0;
1276
1277 rlop = 0;
1278
1279 do
1280 {
1281 if (free_ent >= extcode && fcode.e.ent < FIRST)
1282 {
1283 if (n_bits < maxbits)
1284 {
1285 boff = outbits = (outbits-1)+((n_bits<<3)-
1286 ((outbits-boff-1+(n_bits<<3))%(n_bits<<3)));
1287 if (++n_bits < maxbits)
1288 extcode = MAXCODE(n_bits)+1;
1289 else
1290 extcode = MAXCODE(n_bits);
1291 }
1292 else
1293 {
1294 extcode = MAXCODE(16)+OBUFSIZ;
1295 stcode = 0;
1296 }
1297 }
1298
1299 if (!stcode && bytes_in >= checkpoint && fcode.e.ent < FIRST)
1300 {
1301 long int rat;
1302
1303 checkpoint = bytes_in + CHECK_GAP;
1304
1305 if (bytes_in > 0x007fffff)
1306 { /* shift will overflow */
1307 rat = (bytes_out+(outbits>>3)) >> 8;
1308
1309 if (rat == 0) /* Don't divide by zero */
1310 rat = 0x7fffffff;
1311 else
1312 rat = bytes_in / rat;
1313 }
1314 else
1315 rat = (bytes_in << 8) / (bytes_out+(outbits>>3)); /* 8 fractional bits */
1316 if (rat >= ratio)
1317 ratio = (int)rat;
1318 else
1319 {
1320 ratio = 0;
1321 clear_htab();
1322 output(outbuf,outbits,CLEAR,n_bits);
1323 boff = outbits = (outbits-1)+((n_bits<<3)-
1324 ((outbits-boff-1+(n_bits<<3))%(n_bits<<3)));
1325 extcode = MAXCODE(n_bits = INIT_BITS)+1;
1326 free_ent = FIRST;
1327 stcode = 1;
1328 }
1329 }
1330
1331 if (outbits >= (OBUFSIZ<<3))
1332 {
1333 if (write(fdout, outbuf, OBUFSIZ) != OBUFSIZ)
1334 write_error();
1335
1336 outbits -= (OBUFSIZ<<3);
1337 boff = -(((OBUFSIZ<<3)-boff)%(n_bits<<3));
1338 bytes_out += OBUFSIZ;
1339
1340 memcpy(outbuf, outbuf+OBUFSIZ, (outbits>>3)+1);
1341 memset(outbuf+(outbits>>3)+1, '\0', OBUFSIZ);
1342 }
1343
1344 {
1345 int i;
1346
1347 i = rsize-rlop;
1348
1349 if ((code_int)i > extcode-free_ent) i = (int)(extcode-free_ent);
1350 if (i > ((sizeof(outbuf) - 32)*8 - outbits)/n_bits)
1351 i = ((sizeof(outbuf) - 32)*8 - outbits)/n_bits;
1352
1353 if (!stcode && (long)i > checkpoint-bytes_in)
1354 i = (int)(checkpoint-bytes_in);
1355
1356 rlop += i;
1357 bytes_in += i;
1358 }
1359
1360 goto next;
1361 hfound: fcode.e.ent = codetabof(hp);
1362 next: if (rpos >= rlop)
1363 goto endlop;
1364 next2: fcode.e.c = inbuf[rpos++];
1365 #ifndef FAST
1366 {
1367 code_int i;
1368 fc = fcode.code;
1369 hp = (((long)(fcode.e.c)) << (BITS-8)) ^ (long)(fcode.e.ent);
1370
1371 if ((i = htabof(hp)) == fc)
1372 goto hfound;
1373
1374 if (i != -1)
1375 {
1376 long disp;
1377
1378 disp = (HSIZE - hp)-1; /* secondary hash (after G. Knott) */
1379
1380 do
1381 {
1382 if ((hp -= disp) < 0) hp += HSIZE;
1383
1384 if ((i = htabof(hp)) == fc)
1385 goto hfound;
1386 }
1387 while (i != -1);
1388 }
1389 }
1390 #else
1391 {
1392 long i;
1393 long p;
1394 fc = fcode.code;
1395 hp = ((((long)(fcode.e.c)) << (HBITS-8)) ^ (long)(fcode.e.ent));
1396
1397 if ((i = htabof(hp)) == fc) goto hfound;
1398 if (i == -1) goto out;
1399
1400 p = primetab[fcode.e.c];
1401 lookup: hp = (hp+p)&HMASK;
1402 if ((i = htabof(hp)) == fc) goto hfound;
1403 if (i == -1) goto out;
1404 hp = (hp+p)&HMASK;
1405 if ((i = htabof(hp)) == fc) goto hfound;
1406 if (i == -1) goto out;
1407 hp = (hp+p)&HMASK;
1408 if ((i = htabof(hp)) == fc) goto hfound;
1409 if (i == -1) goto out;
1410 goto lookup;
1411 }
1412 out: ;
1413 #endif
1414 output(outbuf,outbits,fcode.e.ent,n_bits);
1415
1416 {
1417 long fc = fcode.code;
1418 fcode.e.ent = fcode.e.c;
1419
1420 if (stcode)
1421 {
1422 codetabof(hp) = (unsigned short)free_ent++;
1423 htabof(hp) = fc;
1424 }
1425 }
1426
1427 goto next;
1428
1429 endlop: if (fcode.e.ent >= FIRST && rpos < rsize)
1430 goto next2;
1431
1432 if (rpos > rlop)
1433 {
1434 bytes_in += rpos-rlop;
1435 rlop = rpos;
1436 }
1437 }
1438 while (rlop < rsize);
1439 }
1440
1441 if (rsize < 0)
1442 read_error();
1443
1444 if (bytes_in > 0)
1445 output(outbuf,outbits,fcode.e.ent,n_bits);
1446
1447 if (write(fdout, outbuf, (outbits+7)>>3) != (outbits+7)>>3)
1448 write_error();
1449
1450 bytes_out += (outbits+7)>>3;
1451
1452 return;
1453 }
1454
1455 /*
1456 * Decompress stdin to stdout. This routine adapts to the codes in the
1457 * file building the "string" table on-the-fly; requiring no table to
1458 * be stored in the compressed file. The tables used herein are shared
1459 * with those of the compress() routine. See the definitions above.
1460 */
1461
1462 void
1463 decompress(fdin, fdout)
1464 int fdin;
1465 int fdout;
1466 {
1467 char_type *stackp;
1468 code_int code;
1469 int finchar;
1470 code_int oldcode;
1471 code_int incode;
1472 int inbits;
1473 int posbits;
1474 int outpos;
1475 int insize;
1476 int bitmask;
1477 code_int free_ent;
1478 code_int maxcode;
1479 code_int maxmaxcode;
1480 int n_bits;
1481 int rsize;
1482 int block_mode;
1483
1484 bytes_in = 0;
1485 bytes_out = 0;
1486 insize = 0;
1487
1488 while (insize < 3 && (rsize = read(fdin, inbuf+insize, IBUFSIZ)) > 0)
1489 insize += rsize;
1490
1491 if (insize < 3 || inbuf[0] != MAGIC_1 || inbuf[1] != MAGIC_2)
1492 {
1493 if (rsize < 0)
1494 read_error();
1495
1496 if (insize > 0)
1497 {
1498 fprintf(stderr, "%s: not in compressed format\n",
1499 (ifname[0] != '\0'? ifname : "stdin"));
1500 exit_code = 1;
1501 }
1502
1503 return ;
1504 }
1505
1506 maxbits = inbuf[2] & BIT_MASK;
1507 block_mode = inbuf[2] & BLOCK_MODE;
1508
1509 if (maxbits > BITS)
1510 {
1511 fprintf(stderr,
1512 "%s: compressed with %d bits, can only handle %d bits\n",
1513 (*ifname != '\0' ? ifname : "stdin"), maxbits, BITS);
1514 exit_code = 4;
1515 return;
1516 }
1517
1518 maxmaxcode = MAXCODE(maxbits);
1519
1520 bytes_in = insize;
1521 maxcode = MAXCODE(n_bits = INIT_BITS)-1;
1522 bitmask = (1<<n_bits)-1;
1523 oldcode = -1;
1524 finchar = 0;
1525 outpos = 0;
1526 posbits = 3<<3;
1527
1528 free_ent = ((block_mode) ? FIRST : 256);
1529
1530 clear_tab_prefixof(); /* As above, initialize the first
1531 256 entries in the table. */
1532
1533 for (code = 255 ; code >= 0 ; --code)
1534 tab_suffixof(code) = (char_type)code;
1535
1536 do
1537 {
1538 resetbuf: ;
1539 {
1540 int i;
1541 int e;
1542 int o;
1543
1544 o = posbits >> 3;
1545 e = o <= insize ? insize - o : 0;
1546
1547 for (i = 0 ; i < e ; ++i)
1548 inbuf[i] = inbuf[i+o];
1549
1550 insize = e;
1551 posbits = 0;
1552 }
1553
1554 if (insize < sizeof(inbuf)-IBUFSIZ)
1555 {
1556 if ((rsize = read(fdin, inbuf+insize, IBUFSIZ)) < 0)
1557 read_error();
1558
1559 insize += rsize;
1560 }
1561
1562 inbits = ((rsize > 0) ? (insize - insize%n_bits)<<3 :
1563 (insize<<3)-(n_bits-1));
1564
1565 while (inbits > posbits)
1566 {
1567 if (free_ent > maxcode)
1568 {
1569 posbits = ((posbits-1) + ((n_bits<<3) -
1570 (posbits-1+(n_bits<<3))%(n_bits<<3)));
1571
1572 ++n_bits;
1573 if (n_bits == maxbits)
1574 maxcode = maxmaxcode;
1575 else
1576 maxcode = MAXCODE(n_bits)-1;
1577
1578 bitmask = (1<<n_bits)-1;
1579 goto resetbuf;
1580 }
1581
1582 input(inbuf,posbits,code,n_bits,bitmask);
1583
1584 if (oldcode == -1)
1585 {
1586 if (code >= 256) {
1587 fprintf(stderr, "oldcode:-1 code:%i\n", (int)(code));
1588 fprintf(stderr, "uncompress: corrupt input\n");
1589 abort_compress();
1590 }
1591 outbuf[outpos++] = (char_type)(finchar = (int)(oldcode = code));
1592 continue;
1593 }
1594
1595 if (code == CLEAR && block_mode)
1596 {
1597 clear_tab_prefixof();
1598 free_ent = FIRST - 1;
1599 posbits = ((posbits-1) + ((n_bits<<3) -
1600 (posbits-1+(n_bits<<3))%(n_bits<<3)));
1601 maxcode = MAXCODE(n_bits = INIT_BITS)-1;
1602 bitmask = (1<<n_bits)-1;
1603 goto resetbuf;
1604 }
1605
1606 incode = code;
1607 stackp = de_stack;
1608
1609 if (code >= free_ent) /* Special case for KwKwK string. */
1610 {
1611 if (code > free_ent)
1612 {
1613 char_type *p;
1614
1615 posbits -= n_bits;
1616 p = &inbuf[posbits>>3];
1617
1618 fprintf(stderr, "insize:%d posbits:%d inbuf:%02X %02X %02X %02X %02X (%d)\n", insize, posbits,
1619 p[-1],p[0],p[1],p[2],p[3], (posbits&07));
1620 fprintf(stderr, "uncompress: corrupt input\n");
1621 abort_compress();
1622 }
1623
1624 *--stackp = (char_type)finchar;
1625 code = oldcode;
1626 }
1627
1628 while ((cmp_code_int)code >= (cmp_code_int)256)
1629 { /* Generate output characters in reverse order */
1630 *--stackp = tab_suffixof(code);
1631 code = tab_prefixof(code);
1632 }
1633
1634 *--stackp = (char_type)(finchar = tab_suffixof(code));
1635
1636 /* And put them out in forward order */
1637
1638 {
1639 int i;
1640
1641 if (outpos+(i = (de_stack-stackp)) >= OBUFSIZ)
1642 {
1643 do
1644 {
1645 if (i > OBUFSIZ-outpos) i = OBUFSIZ-outpos;
1646
1647 if (i > 0)
1648 {
1649 memcpy(outbuf+outpos, stackp, i);
1650 outpos += i;
1651 }
1652
1653 if (outpos >= OBUFSIZ)
1654 {
1655 if (write(fdout, outbuf, outpos) != outpos)
1656 write_error();
1657
1658 outpos = 0;
1659 }
1660 stackp+= i;
1661 }
1662 while ((i = (de_stack-stackp)) > 0);
1663 }
1664 else
1665 {
1666 memcpy(outbuf+outpos, stackp, i);
1667 outpos += i;
1668 }
1669 }
1670
1671 if ((code = free_ent) < maxmaxcode) /* Generate the new entry. */
1672 {
1673 tab_prefixof(code) = (unsigned short)oldcode;
1674 tab_suffixof(code) = (char_type)finchar;
1675 free_ent = code+1;
1676 }
1677
1678 oldcode = incode; /* Remember previous code. */
1679 }
1680
1681 bytes_in += rsize;
1682 }
1683 while (rsize > 0);
1684
1685 if (outpos > 0 && write(fdout, outbuf, outpos) != outpos)
1686 write_error();
1687 }
1688
1689 void
1690 read_error()
1691 {
1692 fprintf(stderr, "\nread error on");
1693 perror((ifname[0] != '\0') ? ifname : "stdin");
1694 abort_compress();
1695 }
1696
1697 void
1698 write_error()
1699 {
1700 fprintf(stderr, "\nwrite error on");
1701 perror(ofname ? ofname : "stdout");
1702 abort_compress();
1703 }
1704
1705 void
1706 abort_compress()
1707 {
1708 if (remove_ofname)
1709 unlink(ofname);
1710
1711 exit(1);
1712 }
1713
1714 void
1715 prratio(stream, num, den)
1716 FILE *stream;
1717 long int num;
1718 long int den;
1719 {
1720 int q; /* Doesn't need to be long */
1721
1722 if (den > 0)
1723 {
1724 if (num > 214748L)
1725 q = (int)(num/(den/10000L)); /* 2147483647/10000 */
1726 else
1727 q = (int)(10000L*num/den); /* Long calculations, though */
1728 }
1729 else
1730 q = 10000;
1731
1732 if (q < 0)
1733 {
1734 putc('-', stream);
1735 q = -q;
1736 }
1737
1738 fprintf(stream, "%d.%02d%%", q / 100, q % 100);
1739 }
1740
1741 void
1742 about()
1743 {
1744 printf("Compress version: %s\n", version_id);
1745 printf("Compile options:\n ");
1746 #ifdef FAST
1747 printf("FAST, ");
1748 #endif
1749 #ifdef SIGNED_COMPARE_SLOW
1750 printf("SIGNED_COMPARE_SLOW, ");
1751 #endif
1752 #ifdef MAXSEG_64K
1753 printf("MAXSEG_64K, ");
1754 #endif
1755 #ifdef DOS
1756 printf("DOS, ");
1757 #endif
1758 #ifdef DEBUG
1759 printf("DEBUG, ");
1760 #endif
1761 #ifdef LSTAT
1762 printf("LSTAT, ");
1763 #endif
1764 printf("\n IBUFSIZ=%d, OBUFSIZ=%d, BITS=%d\n",
1765 IBUFSIZ, OBUFSIZ, BITS);
1766
1767 printf("\n\
1768 Author version 5.x (Modernization):\n\
1769 Author version 4.2.4.x (Maintenance):\n\
1770 Mike Frysinger (vapier@gmail.com)\n\
1771 \n\
1772 Author version 4.2 (Speed improvement & source cleanup):\n\
1773 Peter Jannesen (peter@ncs.nl)\n\
1774 \n\
1775 Author version 4.1 (Added recursive directory compress):\n\
1776 Dave Mack (csu@alembic.acs.com)\n\
1777 \n\
1778 Authors version 4.0 (World release in 1985):\n\
1779 Spencer W. Thomas, Jim McKie, Steve Davies,\n\
1780 Ken Turkowski, James A. Woods, Joe Orost\n");
1781
1782 exit(0);
1783 }