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