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