· 8 years ago · Feb 21, 2018, 04:40 AM
1/* untar.c */
2
3#define VERSION "1.4"
4
5/* DESCRIPTION:
6 * Untar extracts files from an uncompressed tar archive, or one which
7 * has been compressed with gzip. Usually such archives will have file
8 * names that end with ".tar" or ".tgz" respectively, although untar
9 * doesn't depend on any naming conventions. For a summary of the
10 * command-line options, run untar with no arguments.
11 *
12 * HOW TO COMPILE:
13 * Untar doesn't require any special libraries or compile-time flags.
14 * A simple "cc untar.c -o untar" (or the local equivalent) is
15 * sufficient. Even "make untar" works, without needing a Makefile.
16 * For Microsoft Visual C++, the command is "cl /D_WEAK_POSIX untar.c"
17 * (for 32 bit compilers) or "cl /F 1400 untar.c" (for 16-bit).
18 *
19 * IF YOU SEE COMPILER WARNINGS, THAT'S NORMAL; you can ignore them.
20 * Most of the warnings could be eliminated by adding #include <string.h>
21 * but that isn't portable -- some systems require <strings.h> and
22 * <malloc.h>, for example. Because <string.h> isn't quite portable,
23 * and isn't really necessary in the context of this program, it isn't
24 * included.
25 *
26 * PORTABILITY:
27 * Untar only requires the <stdio.h> header. It uses old-style function
28 * definitions. It opens all files in binary mode. Taken together,
29 * this means that untar should compile & run on just about anything.
30 *
31 * If your system supports the POSIX chmod(2), utime(2), link(2), and
32 * symlink(2) calls, then you may wish to compile with -D_POSIX_SOURCE,
33 * which will enable untar to use those system calls to restore the
34 * timestamp and permissions of the extracted files, and restore links.
35 * (For Linux, _POSIX_SOURCE is always defined.)
36 *
37 * For systems which support some POSIX features but not enough to support
38 * -D_POSIX_SOURCE, you might be able to use -D_WEAK_POSIX. This allows
39 * untar to restore time stamps and file permissions, but not links.
40 * This should work for Microsoft systems, and hopefully others as well.
41 *
42 * AUTHOR & COPYRIGHT INFO:
43 * Written by Steve Kirkendall, kirkenda@cs.pdx.edu
44 * Placed in public domain, 6 October 1995
45 *
46 * Portions derived from inflate.c -- Not copyrighted 1992 by Mark Adler
47 * version c10p1, 10 January 1993
48 */
49
50#include <stdio.h>
51#ifndef SEEK_SET
52# define SEEK_SET 0
53#endif
54
55#ifdef _WEAK_POSIX
56# ifndef _POSIX_SOURCE
57# define _POSIX_SOURCE
58# endif
59#endif
60
61#ifdef _POSIX_SOURCE
62# include <sys/types.h>
63# include <sys/stat.h>
64# include <utime.h>
65# ifdef _WEAK_POSIX
66# define mode_t int
67# else
68# include <unistd.h>
69# endif
70#endif
71
72#define WSIZE 32768 /* size of decompression buffer */
73#define TSIZE 512 /* size of a "tape" block */
74#define CR 13 /* carriage-return character */
75#define LF 10 /* line-feed character */
76
77typedef unsigned char Uchar_t;
78typedef unsigned short Ushort_t;
79typedef unsigned long Ulong_t;
80
81typedef struct
82{
83 Uchar_t magic[2]; /* magic: 0x1F, 0x8b */
84 Uchar_t compression; /* compression method: 8=deflated */
85 Uchar_t flags; /* content flags: 0x08 bit -> name present */
86 Uchar_t mtime[4]; /* time_t when archive created */
87 Uchar_t extraflags; /* ? */
88 Uchar_t os; /* operating system: 3=UNIX */
89 /* if flags&0x08, then original file name goes here, '\0'-terminated */
90} gzhdr_t;
91#define MAGIC0 0x1f
92#define MAGIC1 0x8b
93#define DEFLATE 0x08
94#define NAME 0x08
95
96typedef struct
97{
98 char filename[100]; /* 0 name of next file */
99 char mode[8]; /* 100 Permissions and type (octal digits) */
100 char owner[8]; /* 108 Owner ID (ignored) */
101 char group[8]; /* 116 Group ID (ignored) */
102 char size[12]; /* 124 Bytes in file (octal digits) */
103 char mtime[12]; /* 136 Modification time stamp (octal digits)*/
104 char checksum[8]; /* 148 Header checksum (ignored) */
105 char type; /* 156 File type (see below) */
106 char linkto[100]; /* 157 Linked-to name */
107 char brand[8]; /* 257 Identifies tar version (ignored) */
108 char ownername[32]; /* 265 Name of owner (ignored) */
109 char groupname[32]; /* 297 Name of group (ignored) */
110 char devmajor[8]; /* 329 Device major number (ignored) */
111 char defminor[8]; /* 337 Device minor number (ignored) */
112 char prefix[155]; /* 345 Prefix of name (optional) */
113 char RESERVED[12]; /* 500 Pad header size to 512 bytes */
114} tar_t;
115#define ISREGULAR(hdr) ((hdr).type < '1' || (hdr).type > '6')
116
117typedef struct huft {
118 Uchar_t e; /* number of extra bits or operation */
119 Uchar_t b; /* number of bits in this code or subcode */
120 union {
121 Ushort_t n; /* literal, length base, or distance base */
122 struct huft *t;/* pointer to next level of table */
123 } v;
124} huft_t;
125
126int wp; /* output counter */
127Uchar_t slide[WSIZE];
128#define error(desc) {fprintf(stderr, "%s:%s", inname, (desc)); exit(1);}
129
130/* Tables for deflate from PKZIP's appnote.txt. */
131static unsigned border[] = { /* Order of the bit length code lengths */
132 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
133static Ushort_t cplens[] = { /* Copy lengths for literal codes 257..285 */
134 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
135 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
136 /* note: see note #13 above about the 258 in this list. */
137static Ushort_t cplext[] = { /* Extra bits for literal codes 257..285 */
138 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
139 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
140static Ushort_t cpdist[] = { /* Copy offsets for distance codes 0..29 */
141 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
142 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
143 8193, 12289, 16385, 24577};
144static Ushort_t cpdext[] = { /* Extra bits for distance codes */
145 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
146 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
147 12, 12, 13, 13};
148
149
150char *inname;/* name of input archive */
151FILE *infp; /* input byte stream */
152FILE *outfp; /* output stream, for file currently being extracted */
153Ulong_t outsize;/* number of bytes remainin in file currently being extracted */
154FILE *tarfp; /* usually NULL; else file for writing gunzipped data */
155int maketar;/* -d: 1 to gunzip only, 0 to gunzip and extract tar files */
156int listing;/* -t: 1 if listing, 0 if extracting */
157int quiet; /* -q: 1 to write nothing to stdout, 0 for normal chatter */
158int verbose;/* -v: 1 to write extra information to stdout */
159int force; /* -f: 1 to overwrite existing files, 0 to skip them */
160int abspath;/* -p: 1 to allow leading '/', 0 to strip leading '/' */
161int convert;/* -c: 1 to convert newlines, 0 to leave unchanged */
162int noname; /* -n: 1 to ignore gzip name, 0 to use gzip name */
163char **only; /* array of filenames to extract/list */
164int nonlys; /* number of filenames in "only" array; 0=extract all */
165int didabs; /* were any filenames affected by the absence of -p? */
166
167Ulong_t bb; /* bit buffer */
168unsigned bk; /* bits in bit buffer */
169
170Ushort_t mask_bits[] = {
171 0x0000,
172 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
173 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
174};
175
176#define NEXTBYTE() (Uchar_t)getc(infp)
177#define NEEDBITS(n) {while(k<(n)){b|=((Ulong_t)NEXTBYTE())<<k;k+=8;}}
178#define DUMPBITS(n) {b>>=(n);k-=(n);}
179
180int lbits = 9; /* bits in base literal/length lookup table */
181int dbits = 6; /* bits in base distance lookup table */
182
183
184/* If BMAX needs to be larger than 16, then h and x[] should be Ulong_t. */
185#define BMAX 16 /* maximum bit length of any code (16 for explode) */
186#define N_MAX 288 /* maximum number of codes in any set */
187
188
189unsigned hufts; /* track memory usage */
190
191/*----------------------------------------------------------------------------*/
192
193/* create a file for writing. If necessary, create the directories leading up
194 * to that file as well.
195 */
196static FILE *createpath(name)
197 char *name; /* pathname of file to create */
198{
199 FILE *fp;
200 int i;
201
202 /* if we aren't allowed to overwrite and this file exists, return NULL */
203 if (!force && access(name, 0) == 0)
204 {
205 fprintf(stderr, "%s: exists, will not overwrite without \"-f\"\n", name);
206 return NULL;
207 }
208
209 /* first try creating it the easy way */
210 fp = fopen(name, convert ? "w" : "wb");
211 if (fp)
212 return fp;
213
214 /* Else try making all of its directories, and then try creating
215 * the file again.
216 */
217 for (i = 0; name[i]; i++)
218 {
219 /* If this is a slash, then temporarily replace the '/'
220 * with a '\0' and do a mkdir() on the resulting string.
221 * Ignore errors for now.
222 */
223 if (name[i] == '/')
224 {
225 name[i] = '\0';
226 (void)mkdir(name, 0777);
227 name[i] = '/';
228 }
229 }
230 fp = fopen(name, convert ? "w" : "wb");
231 if (!fp)
232 perror(name);
233 return fp;
234}
235
236/* Create a link, or copy a file. If the file is copied (not linked) then
237 * give a warning.
238 */
239static void linkorcopy(src, dst, sym)
240 char *src; /* name of existing source file */
241 char *dst; /* name of new destination file */
242 int sym; /* use symlink instead of link */
243{
244 FILE *fpsrc;
245 FILE *fpdst;
246 int c;
247
248 /* Open the source file. We do this first to make sure it exists */
249 fpsrc = fopen(src, "rb");
250 if (!fpsrc)
251 {
252 perror(src);
253 return;
254 }
255
256 /* Create the destination file. On POSIX systems, this is just to
257 * make sure the directory path exists.
258 */
259 fpdst = createpath(dst);
260 if (!fpdst)
261 /* error message already given */
262 return;
263
264#ifdef _POSIX_SOURCE
265# ifndef _WEAK_POSIX
266 /* first try to link it over, instead of copying */
267 fclose(fpdst);
268 unlink(dst);
269 if (sym)
270 {
271 if (symlink(src, dst))
272 {
273 perror(dst);
274 }
275 fclose(fpsrc);
276 return;
277 }
278 if (!link(src, dst))
279 {
280 /* This story had a happy ending */
281 fclose(fpsrc);
282 return;
283 }
284
285 /* Dang. Reopen the destination again */
286 fpdst = fopen(dst, "wb");
287 /* This *can't* fail */
288
289# endif /* _WEAK_POSIX */
290#endif /* _POSIX_SOURCE */
291
292 /* Copy characters */
293 while ((c = getc(fpsrc)) != EOF)
294 putc(c, fpdst);
295
296 /* Close the files */
297 fclose(fpsrc);
298 fclose(fpdst);
299
300 /* Give a warning */
301 printf("%s: copy instead of link\n", dst);
302}
303
304/* This calls fwrite(), possibly after converting CR-LF to LF */
305static void cvtwrite(blk, size, fp)
306 Uchar_t *blk; /* the block to be written */
307 Ulong_t size; /* number of characters to be written */
308 FILE *fp; /* file to write to */
309{
310 int i, j;
311 static Uchar_t mod[TSIZE];
312
313 if (convert)
314 {
315 for (i = j = 0; i < size; i++)
316 {
317 /* convert LF to local newline convention */
318 if (blk[i] == LF)
319 mod[j++] = '\n';
320 /* If CR-LF pair, then delete the CR */
321 else if (blk[i] == CR && (i+1 >= size || blk[i+1] == LF))
322 ;
323 /* other characters copied literally */
324 else
325 mod[j++] = blk[i];
326 }
327 size = j;
328 blk = mod;
329 }
330
331 fwrite(blk, (size_t)size, sizeof(Uchar_t), fp);
332}
333
334
335/* Compute the checksum of a tar header block, and return it as a long int.
336 * The checksum can be computed using either POSIX rules (unsigned bytes)
337 * or Sun rules (signed bytes).
338 */
339static long checksum(tblk, sunny)
340 tar_t *tblk; /* buffer containing the tar header block */
341 int sunny; /* Boolean: Sun-style checksums? (else POSIX) */
342{
343 long sum;
344 char *scan;
345
346 /* compute the sum of the first 148 bytes -- everything up to but not
347 * including the checksum field itself.
348 */
349 sum = 0L;
350 for (scan = (char *)tblk; scan < tblk->checksum; scan++)
351 {
352 sum += (*scan) & 0xff;
353 if (sunny && (*scan & 0x80) != 0)
354 sum -= 256;
355 }
356
357 /* for the 8 bytes of the checksum field, add blanks to the sum */
358 sum += ' ' * sizeof tblk->checksum;
359 scan += sizeof tblk->checksum;
360
361 /* finish counting the sum of the rest of the block */
362 for (; scan < (char *)tblk + sizeof *tblk; scan++)
363 {
364 sum += (*scan) & 0xff;
365 if (sunny && (*scan & 0x80) != 0)
366 sum -= 256;
367 }
368
369 return sum;
370}
371
372
373
374/* list files in an archive, and optionally extract them as well */
375static void untar(blk)
376 Uchar_t *blk; /* a tape block */
377{
378 static char nbuf[256];/* storage space for prefix+name, combined */
379 static char *name,*n2;/* prefix and name, combined */
380 static int first = 1;/* Boolean: first block of archive? */
381 long sum; /* checksum for this block */
382 int i;
383 tar_t tblk[1];
384
385#ifdef _POSIX_SOURCE
386 static mode_t mode; /* file permissions */
387 static struct utimbuf timestamp; /* file timestamp */
388#endif
389
390 /* make a local copy of the block, and treat it as a tar header */
391 tblk[0] = *(tar_t *)blk;
392
393 /* process each type of tape block differently */
394 if (outsize > TSIZE)
395 {
396 /* data block, but not the last one */
397 if (outfp)
398 cvtwrite(blk, (Ulong_t)TSIZE, outfp);
399 outsize -= TSIZE;
400 }
401 else if (outsize > 0)
402 {
403 /* last data block of current file */
404 if (outfp)
405 {
406 cvtwrite(blk, outsize, outfp);
407 fclose(outfp);
408 outfp = NULL;
409#ifdef _POSIX_SOURCE
410 utime(nbuf, ×tamp);
411 chmod(nbuf, mode);
412#endif
413 }
414 outsize = 0;
415 }
416 else if ((tblk)->filename[0] == '\0')
417 {
418 /* end-of-archive marker */
419 if (didabs)
420 fprintf(stderr, "WARNING: Removed leading slashes because \"-p\" wasn't given.\n");
421 exit(0);
422 }
423 else
424 {
425 /* file header */
426
427 /* half-assed verification -- does it look like header? */
428 if ((tblk)->filename[99] != '\0'
429 || ((tblk)->size[0] < '0'
430 && (tblk)->size[0] != ' ')
431 || (tblk)->size[0] > '9')
432 {
433 if (first)
434 {
435 fprintf(stderr, "%s: not a valid tar file\n", inname);
436 exit(2);
437 }
438 else
439 {
440 printf("WARNING: Garbage detected; preceding file may be damaged\n");
441 exit(2);
442 }
443 }
444
445 /* combine prefix and filename */
446 memset(nbuf, 0, sizeof nbuf);
447 name = nbuf;
448 if ((tblk)->prefix[0])
449 {
450 strncpy(name, (tblk)->prefix, sizeof (tblk)->prefix);
451 strcat(name, "/");
452 strncat(name + strlen(name), (tblk)->filename,
453 sizeof (tblk)->filename);
454 }
455 else
456 {
457 strncpy(name, (tblk)->filename,
458 sizeof (tblk)->filename);
459 }
460
461 /* Convert any backslashes to forward slashes, and guard
462 * against doubled-up slashes. (Some DOS versions of "tar"
463 * get this wrong.) Also strip off leading slashes.
464 */
465 if (!abspath && (*name == '/' || *name == '\\'))
466 didabs = 1;
467 for (n2 = nbuf; *name; name++)
468 {
469 if (*name == '\\')
470 *name = '/';
471 if (*name != '/'
472 || (abspath && n2 == nbuf)
473 || (n2 != nbuf && n2[-1] != '/'))
474 *n2++ = *name;
475 }
476 if (n2 == nbuf)
477 *n2++ = '/';
478 *n2 = '\0';
479
480 /* verify the checksum */
481 for (sum = 0L, i = 0; i < sizeof((tblk)->checksum); i++)
482 {
483 if ((tblk)->checksum[i] >= '0'
484 && (tblk)->checksum[i] <= '7')
485 sum = sum * 8 + (tblk)->checksum[i] - '0';
486 }
487 if (sum != checksum(tblk, 0) && sum != checksum(tblk, 1))
488 {
489 if (!first)
490 printf("WARNING: Garbage detected; preceding file may be damaged\n");
491 fflush(stdout);
492 fprintf(stderr, "%s: header has bad checksum for %s\n", inname, nbuf);
493 exit(2);
494 }
495
496 /* From this point on, we don't care whether this is the first
497 * block or not. Might as well reset the "first" flag now.
498 */
499 first = 0;
500
501 /* if last character of name is '/' then assume directory */
502 if (*nbuf && nbuf[strlen(nbuf) - 1] == '/')
503 (tblk)->type = '5';
504
505 /* convert file size */
506 for (outsize = 0L, i = 0; i < sizeof((tblk)->size); i++)
507 {
508 if ((tblk)->size[i] >= '0' && (tblk)->size[i] <= '7')
509 outsize = outsize * 8 + (tblk)->size[i] - '0';
510 }
511
512#ifdef _POSIX_SOURCE
513 /* convert file timestamp */
514 for (timestamp.modtime=0L, i=0; i < sizeof((tblk)->mtime); i++)
515 {
516 if ((tblk)->mtime[i] >= '0' && (tblk)->mtime[i] <= '7')
517 timestamp.modtime = timestamp.modtime * 8
518 + (tblk)->mtime[i] - '0';
519 }
520 timestamp.actime = timestamp.modtime;
521
522 /* convert file permissions */
523 for (mode = i = 0; i < sizeof((tblk)->mode); i++)
524 {
525 if ((tblk)->mode[i] >= '0' && (tblk)->mode[i] <= '7')
526 mode = mode * 8 + (tblk)->mode[i] - '0';
527 }
528#endif
529
530 /* If we have an "only" list, and this file isn't in it,
531 * then skip it.
532 */
533 if (nonlys > 0)
534 {
535 for (i = 0;
536 i < nonlys
537 && strcmp(only[i], nbuf)
538 && (strncmp(only[i], nbuf, strlen(only[i]))
539 || nbuf[strlen(only[i])] != '/');
540 i++)
541 {
542 }
543 if (i >= nonlys)
544 {
545 outfp = NULL;
546 return;
547 }
548 }
549
550 /* list the file */
551 if (verbose)
552 printf("%c %s",
553 ISREGULAR(*tblk) ? '-' : ("hlcbdp"[(tblk)->type - '1']),
554 nbuf);
555 else if (!quiet)
556 printf("%s\n", nbuf);
557
558 /* if link, then do the link-or-copy thing */
559 if (tblk->type == '1' || tblk->type == '2')
560 {
561 if (verbose)
562 printf(" -> %s\n", tblk->linkto);
563 if (!listing)
564 linkorcopy(tblk->linkto, nbuf, tblk->type == '2');
565 outsize = 0L;
566 return;
567 }
568
569 /* If directory, then make a weak attempt to create it.
570 * Ideally we would do the "create path" thing, but that
571 * seems like more trouble than it's worth since traditional
572 * tar archives don't contain directories anyway.
573 */
574 if (tblk->type == '5')
575 {
576 if (listing)
577 n2 = " directory";
578#ifdef _POSIX_SOURCE
579 else if (mkdir(nbuf, mode) == 0)
580#else
581 else if (mkdir(nbuf, 0755) == 0)
582#endif
583 n2 = " created";
584 else
585 n2 = " ignored";
586 if (verbose)
587 printf("%s\n", n2);
588 return;
589 }
590
591 /* if not a regular file, then skip it */
592 if (!ISREGULAR(*tblk))
593 {
594 if (verbose)
595 printf(" ignored\n");
596 outsize = 0L;
597 return;
598 }
599
600 /* print file statistics */
601 if (verbose)
602 {
603 printf(" (%ld byte%s, %ld tape block%s)\n",
604 outsize,
605 outsize == 1 ? "" : "s",
606 (outsize + TSIZE - 1) / TSIZE,
607 (outsize > 0 && outsize <= TSIZE) ? "" : "s");
608 }
609
610 /* if extracting, then try to create the file */
611 if (!listing)
612 outfp = createpath(nbuf);
613 else
614 outfp = NULL;
615
616 /* if file is 0 bytes long, then we're done already! */
617 if (outsize == 0 && outfp)
618 {
619 fclose(outfp);
620#ifdef _POSIX_SOURCE
621 utime(nbuf, ×tamp);
622 chmod(nbuf, mode);
623#endif
624 }
625 }
626}
627
628/* send decompressed tape blocks to untar() */
629void flush_output(w)
630 unsigned w; /* number of bytes in slide[] */
631{
632 unsigned i;
633
634 if (tarfp)
635 {
636 cvtwrite(slide, (Ulong_t)w, tarfp);
637 }
638 else
639 {
640 /* send each block to untar() */
641 for (i = 0; i + TSIZE <= w; i += TSIZE)
642 {
643 untar(&slide[i]);
644 }
645 }
646}
647
648/*----------------------------------------------------------------------------*/
649
650/* Given a list of code lengths and a maximum table size, make a set of
651 * tables to decode that set of codes. Return zero on success, one if
652 * the given code set is incomplete (the tables are still built in this
653 * case), two if the input is invalid (all zero length codes or an
654 * oversubscribed set of lengths), and three if not enough memory.
655 */
656int huft_build(b, n, s, d, e, t, m)
657 unsigned *b; /* code lengths in bits (all assumed <= BMAX) */
658 unsigned n; /* number of codes (assumed <= N_MAX) */
659 unsigned s; /* number of simple-valued codes (0..s-1) */
660 Ushort_t *d; /* list of base values for non-simple codes */
661 Ushort_t *e; /* list of extra bits for non-simple codes */
662 huft_t **t; /* result: starting table */
663 int *m; /* maximum lookup bits, returns actual */
664{
665 unsigned a; /* counter for codes of length k */
666 unsigned c[BMAX+1]; /* bit length count table */
667 unsigned f; /* i repeats in table every f entries */
668 int g; /* maximum code length */
669 int h; /* table level */
670 register unsigned i; /* counter, current code */
671 register unsigned j; /* counter */
672 register int k; /* number of bits in current code */
673 int l; /* bits per table (returned in m) */
674 register unsigned *p; /* pointer into c[], b[], or v[] */
675 register huft_t *q; /* points to current table */
676 huft_t r; /* table entry for structure assignment */
677 huft_t *u[BMAX]; /* table stack */
678 unsigned v[N_MAX]; /* values in order of bit length */
679 register int w; /* bits before this table == (l * h) */
680 unsigned x[BMAX+1]; /* bit offsets, then code stack */
681 unsigned *xp; /* pointer into x */
682 int y; /* number of dummy codes added */
683 unsigned z; /* number of entries in current table */
684
685
686 /* Generate counts for each bit length */
687 memset(c, 0, sizeof(c));
688 p = b; i = n;
689 do {
690 c[*p++]++; /* assume all entries <= BMAX */
691 } while (--i);
692 if (c[0] == n) /* null input--all zero length codes */
693 {
694 *t = (huft_t *)NULL;
695 *m = 0;
696 return 0;
697 }
698
699
700 /* Find minimum and maximum length, bound *m by those */
701 l = *m;
702 for (j = 1; j <= BMAX; j++)
703 if (c[j])
704 break;
705 k = j; /* minimum code length */
706 if ((unsigned)l < j)
707 l = j;
708 for (i = BMAX; i; i--)
709 if (c[i])
710 break;
711 g = i; /* maximum code length */
712 if ((unsigned)l > i)
713 l = i;
714 *m = l;
715
716
717 /* Adjust last length count to fill out codes, if needed */
718 for (y = 1 << j; j < i; j++, y <<= 1)
719 if ((y -= c[j]) < 0)
720 return 2; /* bad input: more codes than bits */
721 if ((y -= c[i]) < 0)
722 return 2;
723 c[i] += y;
724
725
726 /* Generate starting offsets into the value table for each length */
727 x[1] = j = 0;
728 p = c + 1; xp = x + 2;
729 while (--i) { /* note that i == g from above */
730 *xp++ = (j += *p++);
731 }
732
733 /* Make a table of values in order of bit lengths */
734 p = b; i = 0;
735 do {
736 if ((j = *p++) != 0)
737 v[x[j]++] = i;
738 } while (++i < n);
739
740
741 /* Generate the Huffman codes and for each, make the table entries */
742 x[0] = i = 0; /* first Huffman code is zero */
743 p = v; /* grab values in bit order */
744 h = -1; /* no tables yet--level -1 */
745 w = -l; /* bits decoded == (l * h) */
746 u[0] = (huft_t *)NULL; /* just to keep compilers happy */
747 q = (huft_t *)NULL; /* ditto */
748 z = 0; /* ditto */
749
750 /* go through the bit lengths (k already is bits in shortest code) */
751 for (; k <= g; k++)
752 {
753 a = c[k];
754 while (a--)
755 {
756 /* here i is the Huffman code of length k bits for value *p */
757 /* make tables up to required level */
758 while (k > w + l)
759 {
760 h++;
761 w += l; /* previous table always l bits */
762
763 /* compute minimum size table less than or equal to l bits */
764 z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */
765 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
766 { /* too few codes for k-w bit table */
767 f -= a + 1; /* deduct codes from patterns left */
768 xp = c + k;
769 while (++j < z) /* try smaller tables up to z bits */
770 {
771 if ((f <<= 1) <= *++xp)
772 break; /* enough codes to use up j bits */
773 f -= *xp; /* else deduct codes from patterns */
774 }
775 }
776 z = 1 << j; /* table entries for j-bit table */
777
778 /* allocate and link in new table */
779 q = (huft_t *)malloc((z + 1)*sizeof(huft_t));
780 hufts += z + 1; /* track memory usage */
781 *t = q + 1; /* link to list for huft_free() */
782 *(t = &(q->v.t)) = (huft_t *)NULL;
783 u[h] = ++q; /* table starts after link */
784
785 /* connect to last table, if there is one */
786 if (h)
787 {
788 x[h] = i; /* save pattern for backing up */
789 r.b = (Uchar_t)l; /* bits to dump before this table */
790 r.e = (Uchar_t)(16 + j);/* bits in this table */
791 r.v.t = q; /* pointer to this table */
792 j = i >> (w - l); /* (get around Turbo C bug) */
793 u[h-1][j] = r; /* connect to last table */
794 }
795 }
796
797 /* set up table entry in r */
798 r.b = (Uchar_t)(k - w);
799 if (p >= v + n)
800 r.e = 99;/* out of values--invalid code */
801 else if (*p < s)
802 {
803 r.e = (Uchar_t)(*p < 256 ? 16 : 15);/* 256 is end-of-block code */
804 r.v.n = *p++; /* simple code is just the value */
805 }
806 else
807 {
808 r.e = (Uchar_t)e[*p - s]; /* non-simple--look up in lists */
809 r.v.n = d[*p++ - s];
810 }
811
812 /* fill code-like entries with r */
813 f = 1 << (k - w);
814 for (j = i >> w; j < z; j += f)
815 q[j] = r;
816
817 /* backwards increment the k-bit code i */
818 for (j = 1 << (k - 1); i & j; j >>= 1)
819 i ^= j;
820 i ^= j;
821
822 /* backup over finished tables */
823 while ((i & ((1 << w) - 1)) != x[h])
824 {
825 h--; /* don't need to update q */
826 w -= l;
827 }
828 }
829 }
830
831
832 /* Return true (1) if we were given an incomplete table */
833 return y != 0 && g != 1;
834}
835
836
837
838/* Free the malloc'ed tables built by huft_build(), which makes a linked
839 * list of the tables it made, with the links in a dummy first entry of
840 * each table.
841 */
842int huft_free(t)
843 huft_t *t; /* table to free */
844{
845 register huft_t *p, *q;
846
847
848 /* Go through linked list, freeing from the malloced (t[-1]) address. */
849 p = t;
850 while (p != (huft_t *)NULL)
851 {
852 q = (--p)->v.t;
853 free(p);
854 p = q;
855 }
856 return 0;
857}
858
859
860/* Inflate (decompress) the codes in a deflated (compressed) block.
861 * Return an error code or zero if it all goes ok.
862 */
863int inflate_codes(tl, td, bl, bd)
864 huft_t *tl, *td; /* literal/length and distance decoder tables */
865 int bl, bd; /* number of bits decoded by tl[] and td[] */
866{
867 register unsigned e; /* table entry flag/number of extra bits */
868 unsigned n, d; /* length and index for copy */
869 unsigned w; /* current window position */
870 huft_t *t; /* pointer to table entry */
871 unsigned ml, md; /* masks for bl and bd bits */
872 register Ulong_t b; /* bit buffer */
873 register unsigned k; /* number of bits in bit buffer */
874
875
876 /* make local copies of globals */
877 b = bb; /* initialize bit buffer */
878 k = bk;
879 w = wp; /* initialize window position */
880
881 /* inflate the coded data */
882 ml = mask_bits[bl]; /* precompute masks for speed */
883 md = mask_bits[bd];
884 for (;;) /* do until end of block */
885 {
886 NEEDBITS((unsigned)bl)
887 if ((e = (t = tl + ((unsigned)b & ml))->e) > 16)
888 do
889 {
890 if (e == 99)
891 return 1;
892 DUMPBITS(t->b)
893 e -= 16;
894 NEEDBITS(e)
895 } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
896 DUMPBITS(t->b)
897 if (e == 16) /* then it's a literal */
898 {
899 slide[w++] = (Uchar_t)t->v.n;
900 if (w == WSIZE)
901 {
902 flush_output(w);
903 w = 0;
904 }
905 }
906 else /* it's an EOB or a length */
907 {
908 /* exit if end of block */
909 if (e == 15)
910 break;
911
912 /* get length of block to copy */
913 NEEDBITS(e)
914 n = t->v.n + ((unsigned)b & mask_bits[e]);
915 DUMPBITS(e);
916
917 /* decode distance of block to copy */
918 NEEDBITS((unsigned)bd)
919 if ((e = (t = td + ((unsigned)b & md))->e) > 16)
920 do
921 {
922 if (e == 99)
923 return 1;
924 DUMPBITS(t->b)
925 e -= 16;
926 NEEDBITS(e)
927 } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
928 DUMPBITS(t->b)
929 NEEDBITS(e)
930 d = w - t->v.n - ((unsigned)b & mask_bits[e]);
931 DUMPBITS(e)
932
933 /* do the copy */
934 do
935 {
936 n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
937#if !defined(NOMEMCPY) && !defined(DEBUG)
938 if (w - d >= e) /* (this test assumes unsigned comparison) */
939 {
940 memcpy(slide + w, slide + d, e);
941 w += e;
942 d += e;
943 }
944 else /* do it slow to avoid memcpy() overlap */
945#endif /* !NOMEMCPY */
946 do
947 {
948 slide[w++] = slide[d++];
949 } while (--e);
950 if (w == WSIZE)
951 {
952 flush_output(w);
953 w = 0;
954 }
955 } while (n);
956 }
957 }
958
959 /* restore the globals from the locals */
960 wp = w; /* restore global window pointer */
961 bb = b; /* restore global bit buffer */
962 bk = k;
963
964 /* done */
965 return 0;
966}
967
968
969
970/* "decompress" an inflated type 0 (stored) block. */
971int inflate_stored()
972{
973 unsigned n; /* number of bytes in block */
974 unsigned w; /* current window position */
975 register Ulong_t b; /* bit buffer */
976 register unsigned k; /* number of bits in bit buffer */
977
978 /* make local copies of globals */
979 b = bb; /* initialize bit buffer */
980 k = bk;
981 w = wp; /* initialize window position */
982
983 /* go to byte boundary */
984 n = k & 7;
985 DUMPBITS(n);
986
987 /* get the length and its complement */
988 NEEDBITS(16)
989 n = ((unsigned)b & 0xffff);
990 DUMPBITS(16)
991 NEEDBITS(16)
992 if (n != (unsigned)((~b) & 0xffff))
993 return 1; /* error in compressed data */
994 DUMPBITS(16)
995
996 /* read and output the compressed data */
997 while (n--)
998 {
999 NEEDBITS(8)
1000 slide[w++] = (Uchar_t)b;
1001 if (w == WSIZE)
1002 {
1003 flush_output(w);
1004 w = 0;
1005 }
1006 DUMPBITS(8)
1007 }
1008
1009
1010 /* restore the globals from the locals */
1011 wp = w; /* restore global window pointer */
1012 bb = b; /* restore global bit buffer */
1013 bk = k;
1014
1015 return 0;
1016}
1017
1018/* Decompress an inflated type 1 (fixed Huffman codes) block. We should
1019 * either replace this with a custom decoder, or at least precompute the
1020 * Huffman tables.
1021 */
1022int inflate_fixed()
1023{
1024 int i; /* temporary variable */
1025 huft_t *tl; /* literal/length code table */
1026 huft_t *td; /* distance code table */
1027 int bl; /* lookup bits for tl */
1028 int bd; /* lookup bits for td */
1029 unsigned l[288]; /* length list for huft_build */
1030
1031
1032 /* set up literal table */
1033 for (i = 0; i < 144; i++)
1034 l[i] = 8;
1035 for (; i < 256; i++)
1036 l[i] = 9;
1037 for (; i < 280; i++)
1038 l[i] = 7;
1039 for (; i < 288; i++) /* make a complete, but wrong code set */
1040 l[i] = 8;
1041 bl = 7;
1042 if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0)
1043 return i;
1044
1045 /* set up distance table */
1046 for (i = 0; i < 30; i++) /* make an incomplete code set */
1047 l[i] = 5;
1048 bd = 5;
1049 if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1)
1050 {
1051 huft_free(tl);
1052
1053 return i;
1054 }
1055
1056 /* decompress until an end-of-block code */
1057 if (inflate_codes(tl, td, bl, bd))
1058 return 1;
1059
1060 /* free the decoding tables, return */
1061 huft_free(tl);
1062 huft_free(td);
1063 return 0;
1064}
1065
1066
1067
1068/* decompress an inflated type 2 (dynamic Huffman codes) block. */
1069int inflate_dynamic()
1070{
1071 int i; /* temporary variables */
1072 unsigned j;
1073 unsigned l; /* last length */
1074 unsigned m; /* mask for bit lengths table */
1075 unsigned n; /* number of lengths to get */
1076 huft_t *tl; /* literal/length code table */
1077 huft_t *td; /* distance code table */
1078 int bl; /* lookup bits for tl */
1079 int bd; /* lookup bits for td */
1080 unsigned nb; /* number of bit length codes */
1081 unsigned nl; /* number of literal/length codes */
1082 unsigned nd; /* number of distance codes */
1083 unsigned ll[286+30];/* literal/length and distance code lengths */
1084 register Ulong_t b; /* bit buffer */
1085 register unsigned k; /* number of bits in bit buffer */
1086
1087
1088 /* make local bit buffer */
1089 b = bb;
1090 k = bk;
1091
1092 /* read in table lengths */
1093 NEEDBITS(5)
1094 nl = 257 + ((unsigned)b & 0x1f);/* number of literal/length codes */
1095 DUMPBITS(5)
1096 NEEDBITS(5)
1097 nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */
1098 DUMPBITS(5)
1099 NEEDBITS(4)
1100 nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */
1101 DUMPBITS(4)
1102 if (nl > 286 || nd > 30)
1103 return 1; /* bad lengths */
1104
1105 /* read in bit-length-code lengths */
1106 for (j = 0; j < nb; j++)
1107 {
1108 NEEDBITS(3)
1109 ll[border[j]] = (unsigned)b & 7;
1110 DUMPBITS(3)
1111 }
1112 for (; j < 19; j++)
1113 ll[border[j]] = 0;
1114
1115 /* build decoding table for trees--single level, 7 bit lookup */
1116 bl = 7;
1117 if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
1118 {
1119 if (i == 1)
1120 huft_free(tl);
1121 return i; /* incomplete code set */
1122 }
1123
1124 /* read in literal and distance code lengths */
1125 n = nl + nd;
1126 m = mask_bits[bl];
1127 i = l = 0;
1128 while ((unsigned)i < n)
1129 {
1130 NEEDBITS((unsigned)bl)
1131 j = (td = tl + ((unsigned)b & m))->b;
1132 DUMPBITS(j)
1133 j = td->v.n;
1134 if (j < 16) /* length of code in bits (0..15) */
1135 ll[i++] = l = j;/* save last length in l */
1136 else if (j == 16) /* repeat last length 3 to 6 times */
1137 {
1138 NEEDBITS(2)
1139 j = 3 + ((unsigned)b & 3);
1140 DUMPBITS(2)
1141 if ((unsigned)i + j > n)
1142 return 1;
1143 while (j--)
1144 ll[i++] = l;
1145 }
1146 else if (j == 17) /* 3 to 10 zero length codes */
1147 {
1148 NEEDBITS(3)
1149 j = 3 + ((unsigned)b & 7);
1150 DUMPBITS(3)
1151 if ((unsigned)i + j > n)
1152 return 1;
1153 while (j--)
1154 ll[i++] = 0;
1155 l = 0;
1156 }
1157 else /* j == 18: 11 to 138 zero length codes */
1158 {
1159 NEEDBITS(7)
1160 j = 11 + ((unsigned)b & 0x7f);
1161 DUMPBITS(7)
1162 if ((unsigned)i + j > n)
1163 return 1;
1164 while (j--)
1165 ll[i++] = 0;
1166 l = 0;
1167 }
1168 }
1169
1170
1171 /* free decoding table for trees */
1172 huft_free(tl);
1173
1174 /* restore the global bit buffer */
1175 bb = b;
1176 bk = k;
1177
1178 /* build the decoding tables for literal/length and distance codes */
1179 bl = lbits;
1180 if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
1181 {
1182 if (i == 1) {
1183 error(" incomplete literal tree\n");
1184 huft_free(tl);
1185 }
1186 return i; /* incomplete code set */
1187 }
1188 bd = dbits;
1189 if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
1190 {
1191 if (i == 1) {
1192 error(" incomplete distance tree\n");
1193 huft_free(td);
1194 }
1195 huft_free(tl);
1196 return i; /* incomplete code set */
1197 }
1198
1199 /* decompress until an end-of-block code */
1200 if (inflate_codes(tl, td, bl, bd))
1201 return 1;
1202
1203 /* free the decoding tables, return */
1204 huft_free(tl);
1205 huft_free(td);
1206
1207 return 0;
1208}
1209
1210
1211
1212/* decompress an inflated block */
1213int inflate_block(e)
1214 int *e; /* last block flag */
1215{
1216 unsigned t; /* block type */
1217 register Ulong_t b; /* bit buffer */
1218 register unsigned k; /* number of bits in bit buffer */
1219
1220 /* make local bit buffer */
1221 b = bb;
1222 k = bk;
1223
1224 /* read in last block bit */
1225 NEEDBITS(1)
1226 *e = (int)b & 1;
1227 DUMPBITS(1)
1228
1229 /* read in block type */
1230 NEEDBITS(2)
1231 t = (unsigned)b & 3;
1232 DUMPBITS(2)
1233
1234 /* restore the global bit buffer */
1235 bb = b;
1236 bk = k;
1237
1238 /* inflate that block type */
1239 if (t == 2)
1240 return inflate_dynamic();
1241 if (t == 0)
1242 return inflate_stored();
1243 if (t == 1)
1244 return inflate_fixed();
1245
1246 /* bad block type */
1247 return 2;
1248}
1249
1250
1251
1252/* decompress an inflated entry */
1253int inflate()
1254{
1255 int e; /* last block flag */
1256 int r; /* result code */
1257 unsigned h; /* maximum huft_t's malloc'ed */
1258
1259
1260 /* initialize window, bit buffer */
1261 wp = 0;
1262 bk = 0;
1263 bb = 0;
1264
1265 /* decompress until the last block */
1266 h = 0;
1267 do
1268 {
1269 hufts = 0;
1270 if ((r = inflate_block(&e)) != 0)
1271 return r;
1272 if (hufts > h)
1273 h = hufts;
1274 } while (!e);
1275
1276 /* Undo too much lookahead. The next read will be byte aligned so we
1277 * can discard unused bits in the last meaningful byte.
1278 */
1279 while (bk >= 8)
1280 {
1281 bk -= 8;
1282 /* inptr--;*/
1283 }
1284
1285 /* flush out slide */
1286 flush_output(wp);
1287
1288 /* return success */
1289 return 0;
1290}
1291
1292
1293/* Process an archive file. This involves reading the blocks one at a time
1294 * (decompressing if necessary as it goes along) and passing them to a untar()
1295 * function.
1296 */
1297static void doarchive(filename)
1298 char *filename; /* name of the archive file */
1299{
1300 char gunzipname[300];
1301 int ch, len;
1302
1303 /* open the archive */
1304 inname = filename;
1305 infp = fopen(filename, "rb");
1306 if (!infp)
1307 {
1308 perror(filename);
1309 return;
1310 }
1311
1312 /* read the first few bytes, so we can determine whether to decompress */
1313 fread(slide, 1, sizeof(gzhdr_t), infp);
1314 if (((gzhdr_t *)slide)->magic[0] == MAGIC0
1315 && ((gzhdr_t *)slide)->magic[1] == MAGIC1)
1316 {
1317 /* COMPRESSED WITH GZIP */
1318
1319 /* Check for unsupported compression types */
1320 if (((gzhdr_t *)slide)->compression != DEFLATE)
1321 {
1322 fprintf(stderr, "Unsupported compression type\n");
1323 exit(1);
1324 }
1325
1326 /* If original file name present, use it (unless noname) */
1327 if (!noname && (((gzhdr_t *)slide)->flags & NAME) != 0)
1328 {
1329 for (len = 0; (ch = getc(infp)) != '\0'; len++)
1330 {
1331 gunzipname[len] = ch;
1332 }
1333 gunzipname[len] = '\0';
1334 }
1335 else if (maketar)
1336 {
1337 /* skip the original file name, if any */
1338 if ((((gzhdr_t *)slide)->flags & NAME) != 0)
1339 while ((ch = getc(infp)) != '\0')
1340 {
1341 }
1342
1343 /* we need to make up a name */
1344 strcpy(gunzipname, filename);
1345 len = strlen(filename);
1346 if (len > 3 && (!strcmp(filename + len - 3, ".gz")
1347 || !strcmp(filename + len - 3, ".GZ")))
1348 {
1349 gunzipname[len - 3] = '\0';
1350 }
1351 else if (len > 2 && (!strcmp(filename + len - 2, ".z")
1352 || !strcmp(filename + len - 2, ".Z")))
1353 {
1354 gunzipname[len - 2] = '\0';
1355 }
1356 else if (len > 4 && (!strcmp(filename + len - 4, ".tgz")
1357 || !strcmp(filename + len - 4, ".TGZ")))
1358 {
1359 strcpy(&gunzipname[len - 4], ".tar");
1360 }
1361 else
1362 {
1363 strcpy(gunzipname, "untar.out");
1364 }
1365 }
1366
1367 /* if we're writing the gunzip output, then create the output file */
1368 if (maketar)
1369 {
1370 if (!quiet && listing)
1371 {
1372 printf("%s: would be gunzipped to %s\n", filename, gunzipname);
1373 fclose(infp);
1374 return;
1375 }
1376
1377 /* if not allowed to overwrite and file exists, complain */
1378 if (!force && access(gunzipname, 0) == 0)
1379 {
1380 fprintf(stderr, "%s: exists, will not overwrite without \"-f\"\n", gunzipname);
1381 exit(2);
1382 }
1383 tarfp = fopen(gunzipname, convert ? "w" : "wb");
1384 if (!tarfp)
1385 {
1386 perror(gunzipname);
1387 exit(2);
1388 }
1389 }
1390
1391 /* inflate the blocks */
1392 if (inflate() != 0)
1393 {
1394 fprintf(stderr, "%s: bad compression data\n", filename);
1395 exit(2);
1396 }
1397 }
1398 else
1399 {
1400 /* UNCOMPRESSED */
1401
1402 /* if we were supposed to just decompress, complain */
1403 if (maketar)
1404 {
1405 fprintf(stderr, "%s: isn't gzipped\n", filename);
1406 fclose(infp);
1407 return;
1408 }
1409
1410 /* read the rest of the first block */
1411 fread(&slide[sizeof(gzhdr_t)], 1, TSIZE - sizeof(gzhdr_t), infp);
1412
1413 /* send each block to the untar() function */
1414 do
1415 {
1416 untar(slide);
1417 } while (fread(slide, 1, TSIZE, infp) == TSIZE);
1418 }
1419
1420 /* close the archive file. */
1421 fclose(infp);
1422 if (tarfp)
1423 {
1424 fclose(tarfp);
1425 tarfp = NULL;
1426 if (!quiet)
1427 {
1428 printf("%s: gunzipped to %s\n", filename, gunzipname);
1429 }
1430 }
1431 if (outsize > 0)
1432 {
1433 printf("WARNING: Last file might be truncated!\n");
1434 fclose(outfp);
1435 outfp = NULL;
1436 }
1437}
1438
1439static void usage(argv0, exitcode)
1440 char *argv0; /* name of program */
1441 int exitcode;/* exit status -- 0 for success, non-0 for failure */
1442{
1443 /* Give a usage message and exit */
1444 printf("Usage: %s [options] archive.tgz [filename] ...\n", argv0);
1445 printf(" or: %s [options] -d filename.gz ...\n", argv0);
1446 printf("\n");
1447 printf("Options: -t Test -- list contents but don't extract\n");
1448 printf(" -f Force -- allow existing files to be overwritten\n");
1449 printf(" -q Quiet -- suppress the normal chatter\n");
1450 printf(" -v Verbose -- output extra information about each file\n");
1451 printf(" -p Path -- allow absolute pathnames (don't strip leading '/')\n");
1452 printf(" -c Convert -- convert files to local text format\n");
1453 printf(" -d Decompress -- perform \"gunzip\" but not \"tar x\"\n");
1454 printf(" -n No-name -- with \"-d\", ignore original name in gzip header\n");
1455 printf("\n");
1456 printf("This program lists/extracts files from a \"*.tar\" or \"*.tgz\" archive. You can\n");
1457 printf("optionally specify certain files or directories to list/extract; otherwise it\n");
1458#ifdef _POSIX_SOURCE
1459# ifdef _WEAK_POSIX
1460 printf("will list/extract them all. File attributes are preserved fairly well, but\n");
1461 printf("linked files are restored via COPYING. This program can also be used (with -d)\n");
1462 printf("to gunzip non-tar files.\n");
1463# else /* not _WEAK_POSIX */
1464 printf("will list/extract them all. File attributes are preserved, and linked files\n");
1465 printf("will be restored as links. This program can also be used (with -d) to gunzip\n");
1466 printf("non-tar files.\n");
1467# endif /* not _WEAK_POSIX */
1468#else /* not _POSIX_SOURCE */
1469 printf("will list/extract them all. File attributes are NOT preserved. Linked files\n");
1470 printf("will be restored via COPYING. This program can also be used (with -d) to\n");
1471 printf("gunzip non-tar files.\n");
1472#endif /* not _POSIX_SOURCE */
1473 printf("\n");
1474 printf("THIS PROGRAM IS IN THE PUBLIC DOMAIN, AND IS FREELY REDISTRIBUTABLE.\n");
1475 printf("Report bugs to kirkenda@cs.pdx.edu\n");
1476 exit(exitcode);
1477}
1478
1479/* parse command-line arguments, and process each file */
1480int main(argc, argv)
1481 int argc;
1482 char **argv;
1483{
1484 int i, j;
1485
1486 /* GNUish flags */
1487 if (argc < 2 || (argc == 2 && !strcmp(argv[1], "--help")))
1488 usage(argv[0], 0);
1489 if (argc == 2 && !strcmp(argv[1], "--version"))
1490 {
1491 printf("untar %s\n", VERSION);
1492 printf("Placed in public domain by the author, Steve Kirkendall\n");
1493 exit(0);
1494 }
1495
1496 /* listing? extracting? */
1497 for (i = 1; i < argc && argv[i][0] == '-'; i++)
1498 {
1499 if (!argv[i][1])
1500 usage(argv[0], 2);
1501 for (j = 1; argv[i][j]; j++)
1502 {
1503 switch (argv[i][j])
1504 {
1505 case 'd': maketar = 1; break;
1506 case 'n': noname = 1; break;
1507 case 't': listing = 1; break;
1508 case 'f': force = 1; break;
1509 case 'q': quiet = 1; break;
1510 case 'c': convert = 1; break;
1511 case 'p': abspath = 1; break;
1512 case 'v': verbose = 1; break;
1513 default:
1514 usage(argv[0], 2);
1515 }
1516 }
1517 }
1518 if (i >= argc)
1519 {
1520 usage(argv[0], 2);
1521 }
1522
1523 if (maketar)
1524 {
1525 /* decompress each argument */
1526 for (; i < argc; i++)
1527 {
1528 doarchive(argv[i]);
1529 }
1530 }
1531 else
1532 {
1533 /* detect whether we have an extraction list */
1534 if (i + 1 < argc)
1535 {
1536 only = &argv[i + 1];
1537 nonlys = argc - (i + 1);
1538 }
1539 else
1540 {
1541 nonlys = 0;
1542 }
1543
1544 /* list/extract files from archive */
1545 doarchive(argv[i]);
1546 }
1547
1548 if (didabs)
1549 fprintf(stderr, "WARNING: Removed leading slashes because \"-p\" wasn't given.\n");
1550 exit(0);
1551}