]> Dogcows Code - chaz/tar/blob - src/list.c
4ecd5b1cd1999da9f544708538a9c44909ab026b
[chaz/tar] / src / list.c
1 /* List a tar archive, with support routines for reading a tar archive.
2
3 Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
4 2001, 2003 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 (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) (void))
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 (-1);
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 *header_copy;
272 char *bp;
273 union block *data_block;
274 size_t size, written;
275 union block *next_long_name = 0;
276 union block *next_long_link = 0;
277 size_t next_long_name_blocks;
278 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 header_copy = xmalloc (size + 1);
342
343 if (header->header.typeflag == GNUTYPE_LONGNAME)
344 {
345 if (next_long_name)
346 free (next_long_name);
347 next_long_name = header_copy;
348 next_long_name_blocks = size / BLOCKSIZE;
349 }
350 else
351 {
352 if (next_long_link)
353 free (next_long_link);
354 next_long_link = header_copy;
355 next_long_link_blocks = size / BLOCKSIZE;
356 }
357
358 set_next_block_after (header);
359 *header_copy = *header;
360 bp = header_copy->buffer + BLOCKSIZE;
361
362 for (size -= BLOCKSIZE; size > 0; size -= written)
363 {
364 data_block = find_next_block ();
365 if (! data_block)
366 {
367 ERROR ((0, 0, _("Unexpected EOF in archive")));
368 break;
369 }
370 written = available_space_after (data_block);
371 if (written > size)
372 written = size;
373
374 memcpy (bp, data_block->buffer, written);
375 bp += written;
376 set_next_block_after ((union block *)
377 (data_block->buffer + written - 1));
378 }
379
380 *bp = '\0';
381
382 /* Loop! */
383
384 }
385 else
386 {
387 char const *name;
388 struct posix_header const *h = &current_header->header;
389 char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1];
390
391 if (recent_long_name)
392 free (recent_long_name);
393
394 if (next_long_name)
395 {
396 name = next_long_name->buffer + BLOCKSIZE;
397 recent_long_name = next_long_name;
398 recent_long_name_blocks = next_long_name_blocks;
399 }
400 else
401 {
402 /* Accept file names as specified by POSIX.1-1996
403 section 10.1.1. */
404 char *np = namebuf;
405
406 if (h->prefix[0] && strcmp (h->magic, TMAGIC) == 0)
407 {
408 memcpy (np, h->prefix, sizeof h->prefix);
409 np[sizeof h->prefix] = '\0';
410 np += strlen (np);
411 *np++ = '/';
412
413 /* Prevent later references to current_header from
414 mistakenly treating this as an old GNU header.
415 This assignment invalidates h->prefix. */
416 current_header->oldgnu_header.isextended = 0;
417 }
418 memcpy (np, h->name, sizeof h->name);
419 np[sizeof h->name] = '\0';
420 name = namebuf;
421 recent_long_name = 0;
422 recent_long_name_blocks = 0;
423 }
424 assign_string (&orig_file_name, name);
425 assign_string (&current_file_name, name);
426 current_trailing_slash = strip_trailing_slashes (current_file_name);
427
428 if (recent_long_link)
429 free (recent_long_link);
430
431 if (next_long_link)
432 {
433 name = next_long_link->buffer + BLOCKSIZE;
434 recent_long_link = next_long_link;
435 recent_long_link_blocks = next_long_link_blocks;
436 }
437 else
438 {
439 memcpy (namebuf, h->linkname, sizeof h->linkname);
440 namebuf[sizeof h->linkname] = '\0';
441 name = namebuf;
442 recent_long_link = 0;
443 recent_long_link_blocks = 0;
444 }
445 assign_string (&current_link_name, name);
446
447 return HEADER_SUCCESS;
448 }
449 }
450 }
451
452 /* Decode things from a file HEADER block into STAT_INFO, also setting
453 *FORMAT_POINTER depending on the header block format. If
454 DO_USER_GROUP, decode the user/group information (this is useful
455 for extraction, but waste time when merely listing).
456
457 read_header() has already decoded the checksum and length, so we don't.
458
459 This routine should *not* be called twice for the same block, since
460 the two calls might use different DO_USER_GROUP values and thus
461 might end up with different uid/gid for the two calls. If anybody
462 wants the uid/gid they should decode it first, and other callers
463 should decode it without uid/gid before calling a routine,
464 e.g. print_header, that assumes decoded data. */
465 void
466 decode_header (union block *header, struct stat *stat_info,
467 enum archive_format *format_pointer, int do_user_group)
468 {
469 enum archive_format format;
470
471 if (strcmp (header->header.magic, TMAGIC) == 0)
472 format = POSIX_FORMAT;
473 else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0)
474 format = OLDGNU_FORMAT;
475 else
476 format = V7_FORMAT;
477 *format_pointer = format;
478
479 stat_info->st_mode = MODE_FROM_HEADER (header->header.mode);
480 stat_info->st_mtime = TIME_FROM_HEADER (header->header.mtime);
481
482 if (format == OLDGNU_FORMAT && incremental_option)
483 {
484 stat_info->st_atime = TIME_FROM_HEADER (header->oldgnu_header.atime);
485 stat_info->st_ctime = TIME_FROM_HEADER (header->oldgnu_header.ctime);
486 }
487
488 if (format == V7_FORMAT)
489 {
490 stat_info->st_uid = UID_FROM_HEADER (header->header.uid);
491 stat_info->st_gid = GID_FROM_HEADER (header->header.gid);
492 stat_info->st_rdev = 0;
493 }
494 else
495 {
496 if (do_user_group)
497 {
498 /* FIXME: Decide if this should somewhat depend on -p. */
499
500 if (numeric_owner_option
501 || !*header->header.uname
502 || !uname_to_uid (header->header.uname, &stat_info->st_uid))
503 stat_info->st_uid = UID_FROM_HEADER (header->header.uid);
504
505 if (numeric_owner_option
506 || !*header->header.gname
507 || !gname_to_gid (header->header.gname, &stat_info->st_gid))
508 stat_info->st_gid = GID_FROM_HEADER (header->header.gid);
509 }
510 switch (header->header.typeflag)
511 {
512 case BLKTYPE:
513 stat_info->st_rdev
514 = makedev (MAJOR_FROM_HEADER (header->header.devmajor),
515 MINOR_FROM_HEADER (header->header.devminor));
516 break;
517
518 case CHRTYPE:
519 stat_info->st_rdev
520 = makedev (MAJOR_FROM_HEADER (header->header.devmajor),
521 MINOR_FROM_HEADER (header->header.devminor));
522 break;
523
524 default:
525 stat_info->st_rdev = 0;
526 }
527 }
528 }
529
530 /* Convert buffer at WHERE0 of size DIGS from external format to
531 uintmax_t. The data is of type TYPE. The buffer must represent a
532 value in the range -MINUS_MINVAL through MAXVAL. DIGS must be
533 positive. Return -1 on error, diagnosing the error if TYPE is
534 nonzero. */
535 static uintmax_t
536 from_header (char const *where0, size_t digs, char const *type,
537 uintmax_t minus_minval, uintmax_t maxval)
538 {
539 uintmax_t value;
540 char const *where = where0;
541 char const *lim = where + digs;
542 int negative = 0;
543
544 /* Accommodate buggy tar of unknown vintage, which outputs leading
545 NUL if the previous field overflows. */
546 where += !*where;
547
548 /* Accommodate older tars, which output leading spaces. */
549 for (;;)
550 {
551 if (where == lim)
552 {
553 if (type)
554 ERROR ((0, 0,
555 _("Blanks in header where numeric %s value expected"),
556 type));
557 return -1;
558 }
559 if (!ISSPACE ((unsigned char) *where))
560 break;
561 where++;
562 }
563
564 value = 0;
565 if (ISODIGIT (*where))
566 {
567 char const *where1 = where;
568 uintmax_t overflow = 0;
569
570 for (;;)
571 {
572 value += *where++ - '0';
573 if (where == lim || ! ISODIGIT (*where))
574 break;
575 overflow |= value ^ (value << LG_8 >> LG_8);
576 value <<= LG_8;
577 }
578
579 /* Parse the output of older, unportable tars, which generate
580 negative values in two's complement octal. If the leading
581 nonzero digit is 1, we can't recover the original value
582 reliably; so do this only if the digit is 2 or more. This
583 catches the common case of 32-bit negative time stamps. */
584 if ((overflow || maxval < value) && '2' <= *where1 && type)
585 {
586 /* Compute the negative of the input value, assuming two's
587 complement. */
588 int digit = (*where1 - '0') | 4;
589 overflow = 0;
590 value = 0;
591 where = where1;
592 for (;;)
593 {
594 value += 7 - digit;
595 where++;
596 if (where == lim || ! ISODIGIT (*where))
597 break;
598 digit = *where - '0';
599 overflow |= value ^ (value << LG_8 >> LG_8);
600 value <<= LG_8;
601 }
602 value++;
603 overflow |= !value;
604
605 if (!overflow && value <= minus_minval)
606 {
607 WARN ((0, 0,
608 _("Archive octal value %.*s is out of %s range; assuming two's complement"),
609 (int) (where - where1), where1, type));
610 negative = 1;
611 }
612 }
613
614 if (overflow)
615 {
616 if (type)
617 ERROR ((0, 0,
618 _("Archive octal value %.*s is out of %s range"),
619 (int) (where - where1), where1, type));
620 return -1;
621 }
622 }
623 else if (*where == '-' || *where == '+')
624 {
625 /* Parse base-64 output produced only by tar test versions
626 1.13.6 (1999-08-11) through 1.13.11 (1999-08-23).
627 Support for this will be withdrawn in future releases. */
628 int dig;
629 static int warned_once;
630 if (! warned_once)
631 {
632 warned_once = 1;
633 WARN ((0, 0,
634 _("Archive contains obsolescent base-64 headers")));
635 }
636 negative = *where++ == '-';
637 while (where != lim
638 && (dig = base64_map[(unsigned char) *where]) < 64)
639 {
640 if (value << LG_64 >> LG_64 != value)
641 {
642 char *string = alloca (digs + 1);
643 memcpy (string, where0, digs);
644 string[digs] = '\0';
645 if (type)
646 ERROR ((0, 0,
647 _("Archive signed base-64 string %s is out of %s range"),
648 quote (string), type));
649 return -1;
650 }
651 value = (value << LG_64) | dig;
652 where++;
653 }
654 }
655 else if (*where == '\200' /* positive base-256 */
656 || *where == '\377' /* negative base-256 */)
657 {
658 /* Parse base-256 output. A nonnegative number N is
659 represented as (256**DIGS)/2 + N; a negative number -N is
660 represented as (256**DIGS) - N, i.e. as two's complement.
661 The representation guarantees that the leading bit is
662 always on, so that we don't confuse this format with the
663 others (assuming ASCII bytes of 8 bits or more). */
664 int signbit = *where & (1 << (LG_256 - 2));
665 uintmax_t topbits = (((uintmax_t) - signbit)
666 << (CHAR_BIT * sizeof (uintmax_t)
667 - LG_256 - (LG_256 - 2)));
668 value = (*where++ & ((1 << (LG_256 - 2)) - 1)) - signbit;
669 for (;;)
670 {
671 value = (value << LG_256) + (unsigned char) *where++;
672 if (where == lim)
673 break;
674 if (((value << LG_256 >> LG_256) | topbits) != value)
675 {
676 if (type)
677 ERROR ((0, 0,
678 _("Archive base-256 value is out of %s range"),
679 type));
680 return -1;
681 }
682 }
683 negative = signbit;
684 if (negative)
685 value = -value;
686 }
687
688 if (where != lim && *where && !ISSPACE ((unsigned char) *where))
689 {
690 if (type)
691 {
692 char buf[1000]; /* Big enough to represent any header. */
693 static struct quoting_options *o;
694
695 if (!o)
696 {
697 o = clone_quoting_options (0);
698 set_quoting_style (o, locale_quoting_style);
699 }
700
701 while (where0 != lim && ! lim[-1])
702 lim--;
703 quotearg_buffer (buf, sizeof buf, where0, lim - where, o);
704 ERROR ((0, 0,
705 _("Archive contains %.*s where numeric %s value expected"),
706 (int) sizeof buf, buf, type));
707 }
708
709 return -1;
710 }
711
712 if (value <= (negative ? minus_minval : maxval))
713 return negative ? -value : value;
714
715 if (type)
716 {
717 char minval_buf[UINTMAX_STRSIZE_BOUND + 1];
718 char maxval_buf[UINTMAX_STRSIZE_BOUND];
719 char value_buf[UINTMAX_STRSIZE_BOUND + 1];
720 char *minval_string = STRINGIFY_BIGINT (minus_minval, minval_buf + 1);
721 char *value_string = STRINGIFY_BIGINT (value, value_buf + 1);
722 if (negative)
723 *--value_string = '-';
724 if (minus_minval)
725 *--minval_string = '-';
726 ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"),
727 value_string, type,
728 minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));
729 }
730
731 return -1;
732 }
733
734 gid_t
735 gid_from_header (const char *p, size_t s)
736 {
737 return from_header (p, s, "gid_t",
738 - (uintmax_t) TYPE_MINIMUM (gid_t),
739 (uintmax_t) TYPE_MAXIMUM (gid_t));
740 }
741
742 major_t
743 major_from_header (const char *p, size_t s)
744 {
745 return from_header (p, s, "major_t",
746 - (uintmax_t) TYPE_MINIMUM (major_t),
747 (uintmax_t) TYPE_MAXIMUM (major_t));
748 }
749
750 minor_t
751 minor_from_header (const char *p, size_t s)
752 {
753 return from_header (p, s, "minor_t",
754 - (uintmax_t) TYPE_MINIMUM (minor_t),
755 (uintmax_t) TYPE_MAXIMUM (minor_t));
756 }
757
758 mode_t
759 mode_from_header (const char *p, size_t s)
760 {
761 /* Do not complain about unrecognized mode bits. */
762 unsigned u = from_header (p, s, "mode_t",
763 - (uintmax_t) TYPE_MINIMUM (mode_t),
764 TYPE_MAXIMUM (uintmax_t));
765 return ((u & TSUID ? S_ISUID : 0)
766 | (u & TSGID ? S_ISGID : 0)
767 | (u & TSVTX ? S_ISVTX : 0)
768 | (u & TUREAD ? S_IRUSR : 0)
769 | (u & TUWRITE ? S_IWUSR : 0)
770 | (u & TUEXEC ? S_IXUSR : 0)
771 | (u & TGREAD ? S_IRGRP : 0)
772 | (u & TGWRITE ? S_IWGRP : 0)
773 | (u & TGEXEC ? S_IXGRP : 0)
774 | (u & TOREAD ? S_IROTH : 0)
775 | (u & TOWRITE ? S_IWOTH : 0)
776 | (u & TOEXEC ? S_IXOTH : 0));
777 }
778
779 off_t
780 off_from_header (const char *p, size_t s)
781 {
782 /* Negative offsets are not allowed in tar files, so invoke
783 from_header with minimum value 0, not TYPE_MINIMUM (off_t). */
784 return from_header (p, s, "off_t", (uintmax_t) 0,
785 (uintmax_t) TYPE_MAXIMUM (off_t));
786 }
787
788 size_t
789 size_from_header (const char *p, size_t s)
790 {
791 return from_header (p, s, "size_t", (uintmax_t) 0,
792 (uintmax_t) TYPE_MAXIMUM (size_t));
793 }
794
795 time_t
796 time_from_header (const char *p, size_t s)
797 {
798 return from_header (p, s, "time_t",
799 - (uintmax_t) TYPE_MINIMUM (time_t),
800 (uintmax_t) TYPE_MAXIMUM (time_t));
801 }
802
803 uid_t
804 uid_from_header (const char *p, size_t s)
805 {
806 return from_header (p, s, "uid_t",
807 - (uintmax_t) TYPE_MINIMUM (uid_t),
808 (uintmax_t) TYPE_MAXIMUM (uid_t));
809 }
810
811 uintmax_t
812 uintmax_from_header (const char *p, size_t s)
813 {
814 return from_header (p, s, "uintmax_t", (uintmax_t) 0,
815 TYPE_MAXIMUM (uintmax_t));
816 }
817
818
819 /* Format O as a null-terminated decimal string into BUF _backwards_;
820 return pointer to start of result. */
821 char *
822 stringify_uintmax_t_backwards (uintmax_t o, char *buf)
823 {
824 *--buf = '\0';
825 do
826 *--buf = '0' + (int) (o % 10);
827 while ((o /= 10) != 0);
828 return buf;
829 }
830
831 /* Return a printable representation of T. The result points to
832 static storage that can be reused in the next call to this
833 function, to ctime, or to asctime. */
834 char const *
835 tartime (time_t t)
836 {
837 static char buffer[max (UINTMAX_STRSIZE_BOUND + 1,
838 INT_STRLEN_BOUND (int) + 16)];
839 char *p;
840
841 #if USE_OLD_CTIME
842 p = ctime (&t);
843 if (p)
844 {
845 char const *time_stamp = p + 4;
846 for (p += 16; p[3] != '\n'; p++)
847 p[0] = p[3];
848 p[0] = '\0';
849 return time_stamp;
850 }
851 #else
852 /* Use ISO 8610 format. See:
853 http://www.cl.cam.ac.uk/~mgk25/iso-time.html */
854 struct tm *tm = localtime (&t);
855 if (tm)
856 {
857 sprintf (buffer, "%04ld-%02d-%02d %02d:%02d:%02d",
858 tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,
859 tm->tm_hour, tm->tm_min, tm->tm_sec);
860 return buffer;
861 }
862 #endif
863
864 /* The time stamp cannot be broken down, most likely because it
865 is out of range. Convert it as an integer,
866 right-adjusted in a field with the same width as the usual
867 19-byte 4-year ISO time format. */
868 p = stringify_uintmax_t_backwards (t < 0 ? - (uintmax_t) t : (uintmax_t) t,
869 buffer + sizeof buffer);
870 if (t < 0)
871 *--p = '-';
872 while (buffer + sizeof buffer - 19 - 1 < p)
873 *--p = ' ';
874 return p;
875 }
876
877 /* Actually print it.
878
879 Plain and fancy file header block logging. Non-verbose just prints
880 the name, e.g. for "tar t" or "tar x". This should just contain
881 file names, so it can be fed back into tar with xargs or the "-T"
882 option. The verbose option can give a bunch of info, one line per
883 file. I doubt anybody tries to parse its format, or if they do,
884 they shouldn't. Unix tar is pretty random here anyway. */
885
886
887 /* FIXME: Note that print_header uses the globals HEAD, HSTAT, and
888 HEAD_STANDARD, which must be set up in advance. Not very clean... */
889
890 /* UGSWIDTH starts with 18, so with user and group names <= 8 chars, the
891 columns never shift during the listing. */
892 #define UGSWIDTH 18
893 static int ugswidth = UGSWIDTH; /* maximum width encountered so far */
894
895 /* DATEWIDTH is the number of columns taken by the date and time fields. */
896 #if USE_OLD_CDATE
897 # define DATEWIDTH 19
898 #else
899 # define DATEWIDTH 18
900 #endif
901
902 void
903 print_header (off_t block_ordinal)
904 {
905 char modes[11];
906 char const *time_stamp;
907 char *temp_name = orig_file_name ? orig_file_name : current_file_name;
908
909 /* These hold formatted ints. */
910 char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
911 char *user, *group;
912 char size[2 * UINTMAX_STRSIZE_BOUND];
913 /* holds formatted size or major,minor */
914 char uintbuf[UINTMAX_STRSIZE_BOUND];
915 int pad;
916
917 if (block_number_option)
918 {
919 char buf[UINTMAX_STRSIZE_BOUND];
920 if (block_ordinal < 0)
921 block_ordinal = current_block_ordinal ();
922 block_ordinal -= recent_long_name_blocks;
923 block_ordinal -= recent_long_link_blocks;
924 fprintf (stdlis, _("block %s: "),
925 STRINGIFY_BIGINT (block_ordinal, buf));
926 }
927
928 if (verbose_option <= 1)
929 {
930 /* Just the fax, mam. */
931 fprintf (stdlis, "%s\n", quotearg (temp_name));
932 }
933 else
934 {
935 /* File type and modes. */
936
937 modes[0] = '?';
938 switch (current_header->header.typeflag)
939 {
940 case GNUTYPE_VOLHDR:
941 modes[0] = 'V';
942 break;
943
944 case GNUTYPE_MULTIVOL:
945 modes[0] = 'M';
946 break;
947
948 case GNUTYPE_NAMES:
949 modes[0] = 'N';
950 break;
951
952 case GNUTYPE_LONGNAME:
953 case GNUTYPE_LONGLINK:
954 modes[0] = 'L';
955 ERROR ((0, 0, _("Visible longname error")));
956 break;
957
958 case GNUTYPE_SPARSE:
959 case REGTYPE:
960 case AREGTYPE:
961 modes[0] = '-';
962 if (temp_name[strlen (temp_name) - 1] == '/')
963 modes[0] = 'd';
964 break;
965 case LNKTYPE:
966 modes[0] = 'h';
967 break;
968 case GNUTYPE_DUMPDIR:
969 modes[0] = 'd';
970 break;
971 case DIRTYPE:
972 modes[0] = 'd';
973 break;
974 case SYMTYPE:
975 modes[0] = 'l';
976 break;
977 case BLKTYPE:
978 modes[0] = 'b';
979 break;
980 case CHRTYPE:
981 modes[0] = 'c';
982 break;
983 case FIFOTYPE:
984 modes[0] = 'p';
985 break;
986 case CONTTYPE:
987 modes[0] = 'C';
988 break;
989 }
990
991 decode_mode (current_stat.st_mode, modes + 1);
992
993 /* Time stamp. */
994
995 time_stamp = tartime (current_stat.st_mtime);
996
997 /* User and group names. */
998
999 if (*current_header->header.uname && current_format != V7_FORMAT
1000 && !numeric_owner_option)
1001 user = current_header->header.uname;
1002 else
1003 {
1004 /* Try parsing it as an unsigned integer first, and as a
1005 uid_t if that fails. This method can list positive user
1006 ids that are too large to fit in a uid_t. */
1007 uintmax_t u = from_header (current_header->header.uid,
1008 sizeof current_header->header.uid, 0,
1009 (uintmax_t) 0,
1010 (uintmax_t) TYPE_MAXIMUM (uintmax_t));
1011 if (u != -1)
1012 user = STRINGIFY_BIGINT (u, uform);
1013 else
1014 {
1015 sprintf (uform, "%ld",
1016 (long) UID_FROM_HEADER (current_header->header.uid));
1017 user = uform;
1018 }
1019 }
1020
1021 if (*current_header->header.gname && current_format != V7_FORMAT
1022 && !numeric_owner_option)
1023 group = current_header->header.gname;
1024 else
1025 {
1026 /* Try parsing it as an unsigned integer first, and as a
1027 gid_t if that fails. This method can list positive group
1028 ids that are too large to fit in a gid_t. */
1029 uintmax_t g = from_header (current_header->header.gid,
1030 sizeof current_header->header.gid, 0,
1031 (uintmax_t) 0,
1032 (uintmax_t) TYPE_MAXIMUM (uintmax_t));
1033 if (g != -1)
1034 group = STRINGIFY_BIGINT (g, gform);
1035 else
1036 {
1037 sprintf (gform, "%ld",
1038 (long) GID_FROM_HEADER (current_header->header.gid));
1039 group = gform;
1040 }
1041 }
1042
1043 /* Format the file size or major/minor device numbers. */
1044
1045 switch (current_header->header.typeflag)
1046 {
1047 case CHRTYPE:
1048 case BLKTYPE:
1049 strcpy (size,
1050 STRINGIFY_BIGINT (major (current_stat.st_rdev), uintbuf));
1051 strcat (size, ",");
1052 strcat (size,
1053 STRINGIFY_BIGINT (minor (current_stat.st_rdev), uintbuf));
1054 break;
1055 case GNUTYPE_SPARSE:
1056 strcpy (size,
1057 STRINGIFY_BIGINT
1058 (UINTMAX_FROM_HEADER (current_header
1059 ->oldgnu_header.realsize),
1060 uintbuf));
1061 break;
1062 default:
1063 strcpy (size, STRINGIFY_BIGINT (current_stat.st_size, uintbuf));
1064 break;
1065 }
1066
1067 /* Figure out padding and print the whole line. */
1068
1069 pad = strlen (user) + strlen (group) + strlen (size) + 1;
1070 if (pad > ugswidth)
1071 ugswidth = pad;
1072
1073 fprintf (stdlis, "%s %s/%s %*s%s %s",
1074 modes, user, group, ugswidth - pad, "", size, time_stamp);
1075
1076 fprintf (stdlis, " %s", quotearg (temp_name));
1077
1078 switch (current_header->header.typeflag)
1079 {
1080 case SYMTYPE:
1081 fprintf (stdlis, " -> %s\n", quotearg (current_link_name));
1082 break;
1083
1084 case LNKTYPE:
1085 fprintf (stdlis, _(" link to %s\n"), quotearg (current_link_name));
1086 break;
1087
1088 default:
1089 {
1090 char type_string[2];
1091 type_string[0] = current_header->header.typeflag;
1092 type_string[1] = '\0';
1093 fprintf (stdlis, _(" unknown file type %s\n"),
1094 quote (type_string));
1095 }
1096 break;
1097
1098 case AREGTYPE:
1099 case REGTYPE:
1100 case GNUTYPE_SPARSE:
1101 case CHRTYPE:
1102 case BLKTYPE:
1103 case DIRTYPE:
1104 case FIFOTYPE:
1105 case CONTTYPE:
1106 case GNUTYPE_DUMPDIR:
1107 putc ('\n', stdlis);
1108 break;
1109
1110 case GNUTYPE_LONGLINK:
1111 fprintf (stdlis, _("--Long Link--\n"));
1112 break;
1113
1114 case GNUTYPE_LONGNAME:
1115 fprintf (stdlis, _("--Long Name--\n"));
1116 break;
1117
1118 case GNUTYPE_VOLHDR:
1119 fprintf (stdlis, _("--Volume Header--\n"));
1120 break;
1121
1122 case GNUTYPE_MULTIVOL:
1123 strcpy (size,
1124 STRINGIFY_BIGINT
1125 (UINTMAX_FROM_HEADER (current_header->oldgnu_header.offset),
1126 uintbuf));
1127 fprintf (stdlis, _("--Continued at byte %s--\n"), size);
1128 break;
1129
1130 case GNUTYPE_NAMES:
1131 fprintf (stdlis, _("--Mangled file names--\n"));
1132 break;
1133 }
1134 }
1135 fflush (stdlis);
1136 }
1137
1138 /* Print a similar line when we make a directory automatically. */
1139 void
1140 print_for_mkdir (char *pathname, int length, mode_t mode)
1141 {
1142 char modes[11];
1143
1144 if (verbose_option > 1)
1145 {
1146 /* File type and modes. */
1147
1148 modes[0] = 'd';
1149 decode_mode (mode, modes + 1);
1150
1151 if (block_number_option)
1152 {
1153 char buf[UINTMAX_STRSIZE_BOUND];
1154 fprintf (stdlis, _("block %s: "),
1155 STRINGIFY_BIGINT (current_block_ordinal (), buf));
1156 }
1157
1158 fprintf (stdlis, "%s %*s %.*s\n", modes, ugswidth + DATEWIDTH,
1159 _("Creating directory:"), length, quotearg (pathname));
1160 }
1161 }
1162
1163 /* Skip over SIZE bytes of data in blocks in the archive. */
1164 void
1165 skip_file (off_t size)
1166 {
1167 union block *x;
1168
1169 if (multi_volume_option)
1170 {
1171 save_totsize = size;
1172 save_sizeleft = size;
1173 }
1174
1175 while (size > 0)
1176 {
1177 x = find_next_block ();
1178 if (! x)
1179 FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
1180
1181 set_next_block_after (x);
1182 size -= BLOCKSIZE;
1183 if (multi_volume_option)
1184 save_sizeleft -= BLOCKSIZE;
1185 }
1186 }
1187
1188 /* Skip the current member in the archive. */
1189 void
1190 skip_member (void)
1191 {
1192 char save_typeflag = current_header->header.typeflag;
1193 set_next_block_after (current_header);
1194
1195 if (current_header->oldgnu_header.isextended)
1196 {
1197 union block *exhdr;
1198 do
1199 {
1200 exhdr = find_next_block ();
1201 if (!exhdr)
1202 FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
1203 set_next_block_after (exhdr);
1204 }
1205 while (exhdr->sparse_header.isextended);
1206 }
1207
1208 if (save_typeflag != DIRTYPE)
1209 skip_file (current_stat.st_size);
1210 }
This page took 0.090584 seconds and 3 git commands to generate.