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