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