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