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