]> Dogcows Code - chaz/tar/blob - src/list.c
8169a7968704294d4aafeefeb746cfcd244b1f1e
[chaz/tar] / src / list.c
1 /* List a tar archive, with support routines for reading a tar archive.
2
3 Copyright 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
4 2001 Free Software Foundation, Inc.
5
6 Written by John Gilmore, on 1985-08-26.
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22 /* Define to non-zero for forcing old ctime format instead of ISO format. */
23 #undef USE_OLD_CTIME
24
25 #include "system.h"
26 #include <quotearg.h>
27
28 #include "common.h"
29
30 #define max(a, b) ((a) < (b) ? (b) : (a))
31
32 union block *current_header; /* points to current archive header */
33 struct stat current_stat; /* stat struct corresponding */
34 enum archive_format current_format; /* recognized format */
35 union block *recent_long_name; /* recent long name header and contents */
36 union block *recent_long_link; /* likewise, for long link */
37 size_t recent_long_name_blocks; /* number of blocks in recent_long_name */
38 size_t recent_long_link_blocks; /* likewise, for long link */
39
40 static uintmax_t from_header PARAMS ((const char *, size_t, const char *,
41 uintmax_t, uintmax_t));
42
43 /* Base 64 digits; see Internet RFC 2045 Table 1. */
44 static char const base_64_digits[64] =
45 {
46 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
47 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
48 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
49 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
50 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
51 };
52
53 /* Table of base-64 digit values indexed by unsigned chars.
54 The value is 64 for unsigned chars that are not base-64 digits. */
55 static char base64_map[UCHAR_MAX + 1];
56
57 static void
58 base64_init (void)
59 {
60 int i;
61 memset (base64_map, 64, sizeof base64_map);
62 for (i = 0; i < 64; i++)
63 base64_map[(int) base_64_digits[i]] = i;
64 }
65
66 /* Main loop for reading an archive. */
67 void
68 read_and (void (*do_something) ())
69 {
70 enum read_header status = HEADER_STILL_UNREAD;
71 enum read_header prev_status;
72
73 base64_init ();
74 name_gather ();
75 open_archive (ACCESS_READ);
76
77 while (1)
78 {
79 prev_status = status;
80 status = read_header (0);
81 switch (status)
82 {
83 case HEADER_STILL_UNREAD:
84 abort ();
85
86 case HEADER_SUCCESS:
87
88 /* Valid header. We should decode next field (mode) first.
89 Ensure incoming names are null terminated. */
90
91 if (! name_match (current_file_name)
92 || (newer_mtime_option != TYPE_MINIMUM (time_t)
93 /* FIXME: We get mtime now, and again later; this causes
94 duplicate diagnostics if header.mtime is bogus. */
95 && ((current_stat.st_mtime
96 = TIME_FROM_HEADER (current_header->header.mtime))
97 < newer_mtime_option))
98 || excluded_name (current_file_name))
99 {
100 switch (current_header->header.typeflag)
101 {
102 case GNUTYPE_VOLHDR:
103 case GNUTYPE_MULTIVOL:
104 case GNUTYPE_NAMES:
105 break;
106
107 case DIRTYPE:
108 if (show_omitted_dirs_option)
109 WARN ((0, 0, _("%s: Omitting"),
110 quotearg_colon (current_file_name)));
111 /* Fall through. */
112 default:
113 skip_member ();
114 continue;
115 }
116 }
117
118 (*do_something) ();
119 continue;
120
121 case HEADER_ZERO_BLOCK:
122 if (block_number_option)
123 {
124 char buf[UINTMAX_STRSIZE_BOUND];
125 fprintf (stdlis, _("block %s: ** Block of NULs **\n"),
126 STRINGIFY_BIGINT (current_block_ordinal (), buf));
127 }
128
129 set_next_block_after (current_header);
130 status = prev_status;
131 if (ignore_zeros_option)
132 continue;
133 break;
134
135 case HEADER_END_OF_FILE:
136 if (block_number_option)
137 {
138 char buf[UINTMAX_STRSIZE_BOUND];
139 fprintf (stdlis, _("block %s: ** End of File **\n"),
140 STRINGIFY_BIGINT (current_block_ordinal (), buf));
141 }
142 break;
143
144 case HEADER_FAILURE:
145 /* If the previous header was good, tell them that we are
146 skipping bad ones. */
147 set_next_block_after (current_header);
148 switch (prev_status)
149 {
150 case HEADER_STILL_UNREAD:
151 ERROR ((0, 0, _("This does not look like a tar archive")));
152 /* Fall through. */
153
154 case HEADER_ZERO_BLOCK:
155 case HEADER_SUCCESS:
156 ERROR ((0, 0, _("Skipping to next header")));
157 break;
158
159 case HEADER_END_OF_FILE:
160 case HEADER_FAILURE:
161 /* We are in the middle of a cascade of errors. */
162 break;
163 }
164 continue;
165 }
166 break;
167 }
168
169 close_archive ();
170 names_notfound (); /* print names not found */
171 }
172
173 /* Print a header block, based on tar options. */
174 void
175 list_archive (void)
176 {
177 /* Print the header block. */
178
179 if (verbose_option)
180 {
181 if (verbose_option > 1)
182 decode_header (current_header, &current_stat, &current_format, 0);
183 print_header ();
184 }
185
186 if (incremental_option && current_header->header.typeflag == GNUTYPE_DUMPDIR)
187 {
188 off_t size;
189 size_t written, check;
190 union block *data_block;
191
192 set_next_block_after (current_header);
193 if (multi_volume_option)
194 {
195 assign_string (&save_name, current_file_name);
196 save_totsize = current_stat.st_size;
197 }
198 for (size = current_stat.st_size; size > 0; size -= written)
199 {
200 if (multi_volume_option)
201 save_sizeleft = size;
202 data_block = find_next_block ();
203 if (!data_block)
204 {
205 ERROR ((0, 0, _("Unexpected EOF in archive")));
206 break; /* FIXME: What happens, then? */
207 }
208 written = available_space_after (data_block);
209 if (written > size)
210 written = size;
211 errno = 0;
212 check = fwrite (data_block->buffer, sizeof (char), written, stdlis);
213 set_next_block_after ((union block *)
214 (data_block->buffer + written - 1));
215 if (check != written)
216 {
217 write_error_details (current_file_name, check, written);
218 skip_file (size - written);
219 break;
220 }
221 }
222 if (multi_volume_option)
223 assign_string (&save_name, 0);
224 fputc ('\n', stdlis);
225 fflush (stdlis);
226 return;
227
228 }
229
230 if (multi_volume_option)
231 assign_string (&save_name, current_file_name);
232
233 skip_member ();
234
235 if (multi_volume_option)
236 assign_string (&save_name, 0);
237 }
238
239 /* Read a block that's supposed to be a header block. Return its
240 address in "current_header", and if it is good, the file's size in
241 current_stat.st_size.
242
243 Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a
244 block full of zeros (EOF marker).
245
246 If RAW_EXTENDED_HEADERS is nonzero, do not automagically fold the
247 GNU long name and link headers into later headers.
248
249 You must always set_next_block_after(current_header) to skip past
250 the header which this routine reads. */
251
252 /* The standard BSD tar sources create the checksum by adding up the
253 bytes in the header as type char. I think the type char was unsigned
254 on the PDP-11, but it's signed on the Next and Sun. It looks like the
255 sources to BSD tar were never changed to compute the checksum
256 correctly, so both the Sun and Next add the bytes of the header as
257 signed chars. This doesn't cause a problem until you get a file with
258 a name containing characters with the high bit set. So read_header
259 computes two checksums -- signed and unsigned. */
260
261 enum read_header
262 read_header (bool raw_extended_headers)
263 {
264 size_t i;
265 int unsigned_sum; /* the POSIX one :-) */
266 int signed_sum; /* the Sun one :-( */
267 int recorded_sum;
268 uintmax_t parsed_sum;
269 char *p;
270 union block *header;
271 union block **longp;
272 char *bp;
273 union block *data_block;
274 size_t size, written;
275 static union block *next_long_name;
276 static union block *next_long_link;
277 static size_t next_long_name_blocks;
278 static size_t next_long_link_blocks;
279
280 while (1)
281 {
282 header = find_next_block ();
283 current_header = header;
284 if (!header)
285 return HEADER_END_OF_FILE;
286
287 unsigned_sum = 0;
288 signed_sum = 0;
289 p = header->buffer;
290 for (i = sizeof *header; i-- != 0;)
291 {
292 unsigned_sum += (unsigned char) *p;
293 signed_sum += (signed char) (*p++);
294 }
295
296 if (unsigned_sum == 0)
297 return HEADER_ZERO_BLOCK;
298
299 /* Adjust checksum to count the "chksum" field as blanks. */
300
301 for (i = sizeof header->header.chksum; i-- != 0;)
302 {
303 unsigned_sum -= (unsigned char) header->header.chksum[i];
304 signed_sum -= (signed char) (header->header.chksum[i]);
305 }
306 unsigned_sum += ' ' * sizeof header->header.chksum;
307 signed_sum += ' ' * sizeof header->header.chksum;
308
309 parsed_sum = from_header (header->header.chksum,
310 sizeof header->header.chksum, 0,
311 (uintmax_t) 0,
312 (uintmax_t) TYPE_MAXIMUM (int));
313 if (parsed_sum == (uintmax_t) -1)
314 return HEADER_FAILURE;
315
316 recorded_sum = parsed_sum;
317
318 if (unsigned_sum != recorded_sum && signed_sum != recorded_sum)
319 return HEADER_FAILURE;
320
321 /* Good block. Decode file size and return. */
322
323 if (header->header.typeflag == LNKTYPE)
324 current_stat.st_size = 0; /* links 0 size on tape */
325 else
326 current_stat.st_size = OFF_FROM_HEADER (header->header.size);
327
328 if (header->header.typeflag == GNUTYPE_LONGNAME
329 || header->header.typeflag == GNUTYPE_LONGLINK)
330 {
331 if (raw_extended_headers)
332 return HEADER_SUCCESS_EXTENDED;
333 else
334 {
335 size_t name_size = current_stat.st_size;
336 size = name_size - name_size % BLOCKSIZE + 2 * BLOCKSIZE;
337 if (name_size != current_stat.st_size || size < name_size)
338 xalloc_die ();
339 }
340
341 if (header->header.typeflag == GNUTYPE_LONGNAME)
342 {
343 longp = &next_long_name;
344 next_long_name_blocks = size / BLOCKSIZE;
345 }
346 else
347 {
348 longp = &next_long_link;
349 next_long_link_blocks = size / BLOCKSIZE;
350 }
351
352 set_next_block_after (header);
353 if (*longp)
354 free (*longp);
355 *longp = xmalloc (size);
356 **longp = *header;
357 bp = (*longp)->buffer + BLOCKSIZE;
358
359 for (size -= BLOCKSIZE; size > 0; size -= written)
360 {
361 data_block = find_next_block ();
362 if (! data_block)
363 {
364 ERROR ((0, 0, _("Unexpected EOF in archive")));
365 break;
366 }
367 written = available_space_after (data_block);
368 if (written > size)
369 written = size;
370
371 memcpy (bp, data_block->buffer, written);
372 bp += written;
373 set_next_block_after ((union block *)
374 (data_block->buffer + written - 1));
375 }
376
377 *bp = '\0';
378
379 /* Loop! */
380
381 }
382 else
383 {
384 char const *name;
385 struct posix_header const *h = &current_header->header;
386 char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1];
387
388 if (next_long_name)
389 {
390 name = next_long_name->buffer + BLOCKSIZE;
391 recent_long_name = next_long_name;
392 recent_long_name_blocks = next_long_name_blocks;
393 }
394 else
395 {
396 /* Accept file names as specified by POSIX.1-1996
397 section 10.1.1. */
398 char *np = namebuf;
399
400 if (h->prefix[0] && strcmp (h->magic, TMAGIC) == 0)
401 {
402 memcpy (np, h->prefix, sizeof h->prefix);
403 np[sizeof h->prefix] = '\0';
404 np += strlen (np);
405 *np++ = '/';
406
407 /* Prevent later references to current_header from
408 mistakenly treating this as an old GNU header.
409 This assignment invalidates h->prefix. */
410 current_header->oldgnu_header.isextended = 0;
411 }
412 memcpy (np, h->name, sizeof h->name);
413 np[sizeof h->name] = '\0';
414 name = namebuf;
415 recent_long_name_blocks = 0;
416 }
417 assign_string (&current_file_name, name);
418
419 if (next_long_link)
420 {
421 name = next_long_link->buffer + BLOCKSIZE;
422 recent_long_link = next_long_link;
423 recent_long_link_blocks = next_long_link_blocks;
424 }
425 else
426 {
427 memcpy (namebuf, h->linkname, sizeof h->linkname);
428 namebuf[sizeof h->linkname] = '\0';
429 name = namebuf;
430 recent_long_link_blocks = 0;
431 }
432 assign_string (&current_link_name, name);
433
434 return HEADER_SUCCESS;
435 }
436 }
437 }
438
439 /* Decode things from a file HEADER block into STAT_INFO, also setting
440 *FORMAT_POINTER depending on the header block format. If
441 DO_USER_GROUP, decode the user/group information (this is useful
442 for extraction, but waste time when merely listing).
443
444 read_header() has already decoded the checksum and length, so we don't.
445
446 This routine should *not* be called twice for the same block, since
447 the two calls might use different DO_USER_GROUP values and thus
448 might end up with different uid/gid for the two calls. If anybody
449 wants the uid/gid they should decode it first, and other callers
450 should decode it without uid/gid before calling a routine,
451 e.g. print_header, that assumes decoded data. */
452 void
453 decode_header (union block *header, struct stat *stat_info,
454 enum archive_format *format_pointer, int do_user_group)
455 {
456 enum archive_format format;
457
458 if (strcmp (header->header.magic, TMAGIC) == 0)
459 format = POSIX_FORMAT;
460 else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0)
461 format = OLDGNU_FORMAT;
462 else
463 format = V7_FORMAT;
464 *format_pointer = format;
465
466 stat_info->st_mode = MODE_FROM_HEADER (header->header.mode);
467 stat_info->st_mtime = TIME_FROM_HEADER (header->header.mtime);
468
469 if (format == OLDGNU_FORMAT && incremental_option)
470 {
471 stat_info->st_atime = TIME_FROM_HEADER (header->oldgnu_header.atime);
472 stat_info->st_ctime = TIME_FROM_HEADER (header->oldgnu_header.ctime);
473 }
474
475 if (format == V7_FORMAT)
476 {
477 stat_info->st_uid = UID_FROM_HEADER (header->header.uid);
478 stat_info->st_gid = GID_FROM_HEADER (header->header.gid);
479 stat_info->st_rdev = 0;
480 }
481 else
482 {
483 if (do_user_group)
484 {
485 /* FIXME: Decide if this should somewhat depend on -p. */
486
487 if (numeric_owner_option
488 || !*header->header.uname
489 || !uname_to_uid (header->header.uname, &stat_info->st_uid))
490 stat_info->st_uid = UID_FROM_HEADER (header->header.uid);
491
492 if (numeric_owner_option
493 || !*header->header.gname
494 || !gname_to_gid (header->header.gname, &stat_info->st_gid))
495 stat_info->st_gid = GID_FROM_HEADER (header->header.gid);
496 }
497 switch (header->header.typeflag)
498 {
499 case BLKTYPE:
500 stat_info->st_rdev
501 = makedev (MAJOR_FROM_HEADER (header->header.devmajor),
502 MINOR_FROM_HEADER (header->header.devminor));
503 break;
504
505 case CHRTYPE:
506 stat_info->st_rdev
507 = makedev (MAJOR_FROM_HEADER (header->header.devmajor),
508 MINOR_FROM_HEADER (header->header.devminor));
509 break;
510
511 default:
512 stat_info->st_rdev = 0;
513 }
514 }
515 }
516
517 /* Convert buffer at WHERE0 of size DIGS from external format to
518 uintmax_t. The data is of type TYPE. The buffer must represent a
519 value in the range -MINUS_MINVAL through MAXVAL. DIGS must be
520 positive. Return -1 on error, diagnosing the error if TYPE is
521 nonzero. */
522 static uintmax_t
523 from_header (char const *where0, size_t digs, char const *type,
524 uintmax_t minus_minval, uintmax_t maxval)
525 {
526 uintmax_t value;
527 char const *where = where0;
528 char const *lim = where + digs;
529 int negative = 0;
530
531 /* Accommodate buggy tar of unknown vintage, which outputs leading
532 NUL if the previous field overflows. */
533 where += !*where;
534
535 /* Accommodate older tars, which output leading spaces. */
536 for (;;)
537 {
538 if (where == lim)
539 {
540 if (type)
541 ERROR ((0, 0,
542 _("Blanks in header where numeric %s value expected"),
543 type));
544 return -1;
545 }
546 if (!ISSPACE ((unsigned char) *where))
547 break;
548 where++;
549 }
550
551 value = 0;
552 if (ISODIGIT (*where))
553 {
554 char const *where1 = where;
555 uintmax_t overflow = 0;
556
557 for (;;)
558 {
559 value += *where++ - '0';
560 if (where == lim || ! ISODIGIT (*where))
561 break;
562 overflow |= value ^ (value << LG_8 >> LG_8);
563 value <<= LG_8;
564 }
565
566 /* Parse the output of older, unportable tars, which generate
567 negative values in two's complement octal. If the leading
568 nonzero digit is 1, we can't recover the original value
569 reliably; so do this only if the digit is 2 or more. This
570 catches the common case of 32-bit negative time stamps. */
571 if ((overflow || maxval < value) && '2' <= *where1 && type)
572 {
573 /* Compute the negative of the input value, assuming two's
574 complement. */
575 int digit = (*where1 - '0') | 4;
576 overflow = 0;
577 value = 0;
578 where = where1;
579 for (;;)
580 {
581 value += 7 - digit;
582 where++;
583 if (where == lim || ! ISODIGIT (*where))
584 break;
585 digit = *where - '0';
586 overflow |= value ^ (value << LG_8 >> LG_8);
587 value <<= LG_8;
588 }
589 value++;
590 overflow |= !value;
591
592 if (!overflow && value <= minus_minval)
593 {
594 WARN ((0, 0,
595 _("Archive octal value %.*s is out of %s range; assuming two's complement"),
596 (int) (where - where1), where1, type));
597 negative = 1;
598 }
599 }
600
601 if (overflow)
602 {
603 if (type)
604 ERROR ((0, 0,
605 _("Archive octal value %.*s is out of %s range"),
606 (int) (where - where1), where1, type));
607 return -1;
608 }
609 }
610 else if (*where == '-' || *where == '+')
611 {
612 /* Parse base-64 output produced only by tar test versions
613 1.13.6 (1999-08-11) through 1.13.11 (1999-08-23).
614 Support for this will be withdrawn in future releases. */
615 int dig;
616 static int warned_once;
617 if (! warned_once)
618 {
619 warned_once = 1;
620 WARN ((0, 0,
621 _("Archive contains obsolescent base-64 headers")));
622 }
623 negative = *where++ == '-';
624 while (where != lim
625 && (dig = base64_map[(unsigned char) *where]) < 64)
626 {
627 if (value << LG_64 >> LG_64 != value)
628 {
629 char *string = alloca (digs + 1);
630 memcpy (string, where0, digs);
631 string[digs] = '\0';
632 if (type)
633 ERROR ((0, 0,
634 _("Archive signed base-64 string %s is out of %s range"),
635 quote (string), type));
636 return -1;
637 }
638 value = (value << LG_64) | dig;
639 where++;
640 }
641 }
642 else if (*where == '\200' /* positive base-256 */
643 || *where == '\377' /* negative base-256 */)
644 {
645 /* Parse base-256 output. A nonnegative number N is
646 represented as (256**DIGS)/2 + N; a negative number -N is
647 represented as (256**DIGS) - N, i.e. as two's complement.
648 The representation guarantees that the leading bit is
649 always on, so that we don't confuse this format with the
650 others (assuming ASCII bytes of 8 bits or more). */
651 int signbit = *where & (1 << (LG_256 - 2));
652 uintmax_t topbits = (((uintmax_t) - signbit)
653 << (CHAR_BIT * sizeof (uintmax_t)
654 - LG_256 - (LG_256 - 2)));
655 value = (*where++ & ((1 << (LG_256 - 2)) - 1)) - signbit;
656 for (;;)
657 {
658 value = (value << LG_256) + (unsigned char) *where++;
659 if (where == lim)
660 break;
661 if (((value << LG_256 >> LG_256) | topbits) != value)
662 {
663 if (type)
664 ERROR ((0, 0,
665 _("Archive base-256 value is out of %s range"),
666 type));
667 return -1;
668 }
669 }
670 negative = signbit;
671 if (negative)
672 value = -value;
673 }
674
675 if (where != lim && *where && !ISSPACE ((unsigned char) *where))
676 {
677 if (type)
678 {
679 char buf[1000]; /* Big enough to represent any header. */
680 static struct quoting_options *o;
681
682 if (!o)
683 {
684 o = clone_quoting_options (0);
685 set_quoting_style (o, locale_quoting_style);
686 }
687
688 while (where0 != lim && ! lim[-1])
689 lim--;
690 quotearg_buffer (buf, sizeof buf, where0, lim - where, o);
691 ERROR ((0, 0,
692 _("Archive contains %.*s where numeric %s value expected"),
693 (int) sizeof buf, buf, type));
694 }
695
696 return -1;
697 }
698
699 if (value <= (negative ? minus_minval : maxval))
700 return negative ? -value : value;
701
702 if (type)
703 {
704 char minval_buf[UINTMAX_STRSIZE_BOUND + 1];
705 char maxval_buf[UINTMAX_STRSIZE_BOUND];
706 char value_buf[UINTMAX_STRSIZE_BOUND + 1];
707 char *minval_string = STRINGIFY_BIGINT (minus_minval, minval_buf + 1);
708 char *value_string = STRINGIFY_BIGINT (value, value_buf + 1);
709 if (negative)
710 *--value_string = '-';
711 if (minus_minval)
712 *--minval_string = '-';
713 ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"),
714 value_string, type,
715 minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));
716 }
717
718 return -1;
719 }
720
721 gid_t
722 gid_from_header (const char *p, size_t s)
723 {
724 return from_header (p, s, "gid_t",
725 - (uintmax_t) TYPE_MINIMUM (gid_t),
726 (uintmax_t) TYPE_MAXIMUM (gid_t));
727 }
728
729 major_t
730 major_from_header (const char *p, size_t s)
731 {
732 return from_header (p, s, "major_t",
733 - (uintmax_t) TYPE_MINIMUM (major_t),
734 (uintmax_t) TYPE_MAXIMUM (major_t));
735 }
736
737 minor_t
738 minor_from_header (const char *p, size_t s)
739 {
740 return from_header (p, s, "minor_t",
741 - (uintmax_t) TYPE_MINIMUM (minor_t),
742 (uintmax_t) TYPE_MAXIMUM (minor_t));
743 }
744
745 mode_t
746 mode_from_header (const char *p, size_t s)
747 {
748 /* Do not complain about unrecognized mode bits. */
749 unsigned u = from_header (p, s, "mode_t",
750 - (uintmax_t) TYPE_MINIMUM (mode_t),
751 TYPE_MAXIMUM (uintmax_t));
752 return ((u & TSUID ? S_ISUID : 0)
753 | (u & TSGID ? S_ISGID : 0)
754 | (u & TSVTX ? S_ISVTX : 0)
755 | (u & TUREAD ? S_IRUSR : 0)
756 | (u & TUWRITE ? S_IWUSR : 0)
757 | (u & TUEXEC ? S_IXUSR : 0)
758 | (u & TGREAD ? S_IRGRP : 0)
759 | (u & TGWRITE ? S_IWGRP : 0)
760 | (u & TGEXEC ? S_IXGRP : 0)
761 | (u & TOREAD ? S_IROTH : 0)
762 | (u & TOWRITE ? S_IWOTH : 0)
763 | (u & TOEXEC ? S_IXOTH : 0));
764 }
765
766 off_t
767 off_from_header (const char *p, size_t s)
768 {
769 /* Negative offsets are not allowed in tar files, so invoke
770 from_header with minimum value 0, not TYPE_MINIMUM (off_t). */
771 return from_header (p, s, "off_t", (uintmax_t) 0,
772 (uintmax_t) TYPE_MAXIMUM (off_t));
773 }
774
775 size_t
776 size_from_header (const char *p, size_t s)
777 {
778 return from_header (p, s, "size_t", (uintmax_t) 0,
779 (uintmax_t) TYPE_MAXIMUM (size_t));
780 }
781
782 time_t
783 time_from_header (const char *p, size_t s)
784 {
785 return from_header (p, s, "time_t",
786 - (uintmax_t) TYPE_MINIMUM (time_t),
787 (uintmax_t) TYPE_MAXIMUM (time_t));
788 }
789
790 uid_t
791 uid_from_header (const char *p, size_t s)
792 {
793 return from_header (p, s, "uid_t",
794 - (uintmax_t) TYPE_MINIMUM (uid_t),
795 (uintmax_t) TYPE_MAXIMUM (uid_t));
796 }
797
798 uintmax_t
799 uintmax_from_header (const char *p, size_t s)
800 {
801 return from_header (p, s, "uintmax_t", (uintmax_t) 0,
802 TYPE_MAXIMUM (uintmax_t));
803 }
804
805
806 /* Format O as a null-terminated decimal string into BUF _backwards_;
807 return pointer to start of result. */
808 char *
809 stringify_uintmax_t_backwards (uintmax_t o, char *buf)
810 {
811 *--buf = '\0';
812 do
813 *--buf = '0' + (int) (o % 10);
814 while ((o /= 10) != 0);
815 return buf;
816 }
817
818 /* Return a printable representation of T. The result points to
819 static storage that can be reused in the next call to this
820 function, to ctime, or to asctime. */
821 char const *
822 tartime (time_t t)
823 {
824 static char buffer[max (UINTMAX_STRSIZE_BOUND + 1,
825 INT_STRLEN_BOUND (int) + 16)];
826 char *p;
827
828 #if USE_OLD_CTIME
829 p = ctime (&t);
830 if (p)
831 {
832 char const *time_stamp = p + 4;
833 for (p += 16; p[3] != '\n'; p++)
834 p[0] = p[3];
835 p[0] = '\0';
836 return time_stamp;
837 }
838 #else
839 /* Use ISO 8610 format. See:
840 http://www.cl.cam.ac.uk/~mgk25/iso-time.html */
841 struct tm *tm = localtime (&t);
842 if (tm)
843 {
844 sprintf (buffer, "%04d-%02d-%02d %02d:%02d:%02d",
845 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
846 tm->tm_hour, tm->tm_min, tm->tm_sec);
847 return buffer;
848 }
849 #endif
850
851 /* The time stamp cannot be broken down, most likely because it
852 is out of range. Convert it as an integer,
853 right-adjusted in a field with the same width as the usual
854 19-byte 4-year ISO time format. */
855 p = stringify_uintmax_t_backwards (t < 0 ? - (uintmax_t) t : (uintmax_t) t,
856 buffer + sizeof buffer);
857 if (t < 0)
858 *--p = '-';
859 while (buffer + sizeof buffer - 19 - 1 < p)
860 *--p = ' ';
861 return p;
862 }
863
864 /* Actually print it.
865
866 Plain and fancy file header block logging. Non-verbose just prints
867 the name, e.g. for "tar t" or "tar x". This should just contain
868 file names, so it can be fed back into tar with xargs or the "-T"
869 option. The verbose option can give a bunch of info, one line per
870 file. I doubt anybody tries to parse its format, or if they do,
871 they shouldn't. Unix tar is pretty random here anyway. */
872
873
874 /* FIXME: Note that print_header uses the globals HEAD, HSTAT, and
875 HEAD_STANDARD, which must be set up in advance. Not very clean... */
876
877 /* UGSWIDTH starts with 18, so with user and group names <= 8 chars, the
878 columns never shift during the listing. */
879 #define UGSWIDTH 18
880 static int ugswidth = UGSWIDTH; /* maximum width encountered so far */
881
882 /* DATEWIDTH is the number of columns taken by the date and time fields. */
883 #if USE_OLD_CDATE
884 # define DATEWIDTH 19
885 #else
886 # define DATEWIDTH 18
887 #endif
888
889 void
890 print_header (void)
891 {
892 char modes[11];
893 char const *time_stamp;
894 /* These hold formatted ints. */
895 char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
896 char *user, *group;
897 char size[2 * UINTMAX_STRSIZE_BOUND];
898 /* holds formatted size or major,minor */
899 char uintbuf[UINTMAX_STRSIZE_BOUND];
900 int pad;
901
902 if (block_number_option)
903 {
904 char buf[UINTMAX_STRSIZE_BOUND];
905 fprintf (stdlis, _("block %s: "),
906 STRINGIFY_BIGINT (current_block_ordinal (), buf));
907 }
908
909 if (verbose_option <= 1)
910 {
911 /* Just the fax, mam. */
912 fprintf (stdlis, "%s\n", quotearg (current_file_name));
913 }
914 else
915 {
916 /* File type and modes. */
917
918 modes[0] = '?';
919 switch (current_header->header.typeflag)
920 {
921 case GNUTYPE_VOLHDR:
922 modes[0] = 'V';
923 break;
924
925 case GNUTYPE_MULTIVOL:
926 modes[0] = 'M';
927 break;
928
929 case GNUTYPE_NAMES:
930 modes[0] = 'N';
931 break;
932
933 case GNUTYPE_LONGNAME:
934 case GNUTYPE_LONGLINK:
935 ERROR ((0, 0, _("Visible longname error")));
936 break;
937
938 case GNUTYPE_SPARSE:
939 case REGTYPE:
940 case AREGTYPE:
941 case LNKTYPE:
942 modes[0] = '-';
943 if (current_file_name[strlen (current_file_name) - 1] == '/')
944 modes[0] = 'd';
945 break;
946 case GNUTYPE_DUMPDIR:
947 modes[0] = 'd';
948 break;
949 case DIRTYPE:
950 modes[0] = 'd';
951 break;
952 case SYMTYPE:
953 modes[0] = 'l';
954 break;
955 case BLKTYPE:
956 modes[0] = 'b';
957 break;
958 case CHRTYPE:
959 modes[0] = 'c';
960 break;
961 case FIFOTYPE:
962 modes[0] = 'p';
963 break;
964 case CONTTYPE:
965 modes[0] = 'C';
966 break;
967 }
968
969 decode_mode (current_stat.st_mode, modes + 1);
970
971 /* Time stamp. */
972
973 time_stamp = tartime (current_stat.st_mtime);
974
975 /* User and group names. */
976
977 if (*current_header->header.uname && current_format != V7_FORMAT
978 && !numeric_owner_option)
979 user = current_header->header.uname;
980 else
981 {
982 /* Try parsing it as an unsigned integer first, and as a
983 uid_t if that fails. This method can list positive user
984 ids that are too large to fit in a uid_t. */
985 uintmax_t u = from_header (current_header->header.uid,
986 sizeof current_header->header.uid, 0,
987 (uintmax_t) 0,
988 (uintmax_t) TYPE_MAXIMUM (uintmax_t));
989 if (u != -1)
990 user = STRINGIFY_BIGINT (u, uform);
991 else
992 {
993 sprintf (uform, "%ld",
994 (long) UID_FROM_HEADER (current_header->header.uid));
995 user = uform;
996 }
997 }
998
999 if (*current_header->header.gname && current_format != V7_FORMAT
1000 && !numeric_owner_option)
1001 group = current_header->header.gname;
1002 else
1003 {
1004 /* Try parsing it as an unsigned integer first, and as a
1005 gid_t if that fails. This method can list positive group
1006 ids that are too large to fit in a gid_t. */
1007 uintmax_t g = from_header (current_header->header.gid,
1008 sizeof current_header->header.gid, 0,
1009 (uintmax_t) 0,
1010 (uintmax_t) TYPE_MAXIMUM (uintmax_t));
1011 if (g != -1)
1012 group = STRINGIFY_BIGINT (g, gform);
1013 else
1014 {
1015 sprintf (gform, "%ld",
1016 (long) GID_FROM_HEADER (current_header->header.gid));
1017 group = gform;
1018 }
1019 }
1020
1021 /* Format the file size or major/minor device numbers. */
1022
1023 switch (current_header->header.typeflag)
1024 {
1025 case CHRTYPE:
1026 case BLKTYPE:
1027 strcpy (size,
1028 STRINGIFY_BIGINT (major (current_stat.st_rdev), uintbuf));
1029 strcat (size, ",");
1030 strcat (size,
1031 STRINGIFY_BIGINT (minor (current_stat.st_rdev), uintbuf));
1032 break;
1033 case GNUTYPE_SPARSE:
1034 strcpy (size,
1035 STRINGIFY_BIGINT
1036 (UINTMAX_FROM_HEADER (current_header
1037 ->oldgnu_header.realsize),
1038 uintbuf));
1039 break;
1040 default:
1041 strcpy (size, STRINGIFY_BIGINT (current_stat.st_size, uintbuf));
1042 break;
1043 }
1044
1045 /* Figure out padding and print the whole line. */
1046
1047 pad = strlen (user) + strlen (group) + strlen (size) + 1;
1048 if (pad > ugswidth)
1049 ugswidth = pad;
1050
1051 fprintf (stdlis, "%s %s/%s %*s%s %s",
1052 modes, user, group, ugswidth - pad, "", size, time_stamp);
1053
1054 fprintf (stdlis, " %s", quotearg (current_file_name));
1055
1056 switch (current_header->header.typeflag)
1057 {
1058 case SYMTYPE:
1059 fprintf (stdlis, " -> %s\n", quotearg (current_link_name));
1060 break;
1061
1062 case LNKTYPE:
1063 fprintf (stdlis, _(" link to %s\n"), quotearg (current_link_name));
1064 break;
1065
1066 default:
1067 {
1068 char type_string[2];
1069 type_string[0] = current_header->header.typeflag;
1070 type_string[1] = '\0';
1071 fprintf (stdlis, _(" unknown file type %s\n"),
1072 quote (type_string));
1073 }
1074 break;
1075
1076 case AREGTYPE:
1077 case REGTYPE:
1078 case GNUTYPE_SPARSE:
1079 case CHRTYPE:
1080 case BLKTYPE:
1081 case DIRTYPE:
1082 case FIFOTYPE:
1083 case CONTTYPE:
1084 case GNUTYPE_DUMPDIR:
1085 putc ('\n', stdlis);
1086 break;
1087
1088 case GNUTYPE_VOLHDR:
1089 fprintf (stdlis, _("--Volume Header--\n"));
1090 break;
1091
1092 case GNUTYPE_MULTIVOL:
1093 strcpy (size,
1094 STRINGIFY_BIGINT
1095 (UINTMAX_FROM_HEADER (current_header->oldgnu_header.offset),
1096 uintbuf));
1097 fprintf (stdlis, _("--Continued at byte %s--\n"), size);
1098 break;
1099
1100 case GNUTYPE_NAMES:
1101 fprintf (stdlis, _("--Mangled file names--\n"));
1102 break;
1103 }
1104 }
1105 fflush (stdlis);
1106 }
1107
1108 /* Print a similar line when we make a directory automatically. */
1109 void
1110 print_for_mkdir (char *pathname, int length, mode_t mode)
1111 {
1112 char modes[11];
1113
1114 if (verbose_option > 1)
1115 {
1116 /* File type and modes. */
1117
1118 modes[0] = 'd';
1119 decode_mode (mode, modes + 1);
1120
1121 if (block_number_option)
1122 {
1123 char buf[UINTMAX_STRSIZE_BOUND];
1124 fprintf (stdlis, _("block %s: "),
1125 STRINGIFY_BIGINT (current_block_ordinal (), buf));
1126 }
1127
1128 fprintf (stdlis, "%s %*s %.*s\n", modes, ugswidth + DATEWIDTH,
1129 _("Creating directory:"), length, quotearg (pathname));
1130 }
1131 }
1132
1133 /* Skip over SIZE bytes of data in blocks in the archive. */
1134 void
1135 skip_file (off_t size)
1136 {
1137 union block *x;
1138
1139 if (multi_volume_option)
1140 {
1141 save_totsize = size;
1142 save_sizeleft = size;
1143 }
1144
1145 while (size > 0)
1146 {
1147 x = find_next_block ();
1148 if (! x)
1149 FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
1150
1151 set_next_block_after (x);
1152 size -= BLOCKSIZE;
1153 if (multi_volume_option)
1154 save_sizeleft -= BLOCKSIZE;
1155 }
1156 }
1157
1158 /* Skip the current member in the archive. */
1159 void
1160 skip_member (void)
1161 {
1162 char save_typeflag = current_header->header.typeflag;
1163 set_next_block_after (current_header);
1164
1165 if (current_header->oldgnu_header.isextended)
1166 {
1167 union block *exhdr;
1168 do
1169 {
1170 exhdr = find_next_block ();
1171 if (!exhdr)
1172 FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
1173 set_next_block_after (exhdr);
1174 }
1175 while (exhdr->sparse_header.isextended);
1176 }
1177
1178 if (save_typeflag != DIRTYPE)
1179 skip_file (current_stat.st_size);
1180 }
This page took 0.084767 seconds and 3 git commands to generate.