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