]> Dogcows Code - chaz/tar/blob - src/list.c
(time): Declare if not defined.
[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 char const *tartime PARAMS ((time_t));
39 static uintmax_t from_header PARAMS ((const char *, size_t, const char *,
40 uintmax_t, uintmax_t));
41
42 /* Base 64 digits; see Internet RFC 2045 Table 1. */
43 static char const base_64_digits[64] =
44 {
45 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
46 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
47 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
48 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
49 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
50 };
51
52 /* Table of base-64 digit values indexed by unsigned chars.
53 The value is 64 for unsigned chars that are not base-64 digits. */
54 static char base64_map[UCHAR_MAX + 1];
55
56 static void
57 base64_init (void)
58 {
59 int i;
60 memset (base64_map, 64, sizeof base64_map);
61 for (i = 0; i < 64; i++)
62 base64_map[(int) base_64_digits[i]] = i;
63 }
64
65 /*-----------------------------------.
66 | Main loop for reading an archive. |
67 `-----------------------------------*/
68
69 void
70 read_and (void (*do_something) ())
71 {
72 enum read_header status = HEADER_STILL_UNREAD;
73 enum read_header prev_status;
74
75 base64_init ();
76 name_gather ();
77 open_archive (ACCESS_READ);
78
79 while (1)
80 {
81 prev_status = status;
82 status = read_header ();
83 switch (status)
84 {
85 case HEADER_STILL_UNREAD:
86 abort ();
87
88 case HEADER_SUCCESS:
89
90 /* Valid header. We should decode next field (mode) first.
91 Ensure incoming names are null terminated. */
92
93 if (!name_match (current_file_name)
94 || (newer_mtime_option != TYPE_MINIMUM (time_t)
95 /* FIXME: We get mtime now, and again later; this
96 causes duplicate diagnostics if header.mtime is
97 bogus. */
98 && ((current_stat.st_mtime
99 = TIME_FROM_HEADER (current_header->header.mtime))
100 < newer_mtime_option))
101 || excluded_name (current_file_name))
102 {
103 char save_typeflag;
104
105 if (current_header->header.typeflag == GNUTYPE_VOLHDR
106 || current_header->header.typeflag == GNUTYPE_MULTIVOL
107 || current_header->header.typeflag == GNUTYPE_NAMES)
108 {
109 (*do_something) ();
110 continue;
111 }
112 if (show_omitted_dirs_option
113 && current_header->header.typeflag == DIRTYPE)
114 WARN ((0, 0, _("Omitting %s"), current_file_name));
115
116 /* Skip past it in the archive. */
117
118 save_typeflag = current_header->header.typeflag;
119 set_next_block_after (current_header);
120 if (current_header->oldgnu_header.isextended)
121 skip_extended_headers ();
122
123 /* Skip to the next header on the archive. */
124
125 if (save_typeflag != DIRTYPE)
126 skip_file (current_stat.st_size);
127 continue;
128 }
129
130 (*do_something) ();
131 continue;
132
133 case HEADER_ZERO_BLOCK:
134 if (block_number_option)
135 {
136 char buf[UINTMAX_STRSIZE_BOUND];
137 fprintf (stdlis, _("block %s: ** Block of NULs **\n"),
138 STRINGIFY_BIGINT (current_block_ordinal (), buf));
139 }
140
141 set_next_block_after (current_header);
142 status = prev_status;
143 if (ignore_zeros_option)
144 continue;
145 break;
146
147 case HEADER_END_OF_FILE:
148 if (block_number_option)
149 {
150 char buf[UINTMAX_STRSIZE_BOUND];
151 fprintf (stdlis, _("block %s: ** End of File **\n"),
152 STRINGIFY_BIGINT (current_block_ordinal (), buf));
153 }
154 break;
155
156 case HEADER_FAILURE:
157 /* If the previous header was good, tell them that we are
158 skipping bad ones. */
159 set_next_block_after (current_header);
160 switch (prev_status)
161 {
162 case HEADER_STILL_UNREAD:
163 WARN ((0, 0, _("This does not look like a tar archive")));
164 /* Fall through. */
165
166 case HEADER_ZERO_BLOCK:
167 case HEADER_SUCCESS:
168 WARN ((0, 0, _("Skipping to next header")));
169 break;
170
171 case HEADER_END_OF_FILE:
172 case HEADER_FAILURE:
173 /* We are in the middle of a cascade of errors. */
174 break;
175 }
176 continue;
177 }
178 break;
179 }
180
181 apply_delayed_set_stat ();
182 close_archive ();
183 names_notfound (); /* print names not found */
184 }
185
186 /*---------------------------------------------.
187 | Print a header block, based on tar options. |
188 `---------------------------------------------*/
189
190 void
191 list_archive (void)
192 {
193 /* Print the header block. */
194
195 if (verbose_option)
196 {
197 if (verbose_option > 1)
198 decode_header (current_header, &current_stat, &current_format, 0);
199 print_header ();
200 }
201
202 if (incremental_option && current_header->header.typeflag == GNUTYPE_DUMPDIR)
203 {
204 off_t size;
205 size_t written, check;
206 union block *data_block;
207
208 set_next_block_after (current_header);
209 if (multi_volume_option)
210 {
211 assign_string (&save_name, current_file_name);
212 save_totsize = current_stat.st_size;
213 }
214 for (size = current_stat.st_size; size > 0; size -= written)
215 {
216 if (multi_volume_option)
217 save_sizeleft = size;
218 data_block = find_next_block ();
219 if (!data_block)
220 {
221 ERROR ((0, 0, _("EOF in archive file")));
222 break; /* FIXME: What happens, then? */
223 }
224 written = available_space_after (data_block);
225 if (written > size)
226 written = size;
227 errno = 0; /* FIXME: errno should be read-only */
228 check = fwrite (data_block->buffer, sizeof (char), written, stdlis);
229 set_next_block_after ((union block *)
230 (data_block->buffer + written - 1));
231 if (check != written)
232 {
233 ERROR ((0, errno, _("Only wrote %lu of %lu bytes to file %s"),
234 (unsigned long) check,
235 (unsigned long) written, 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. */
570 if ((overflow || maxval < value) && '4' <= *where1)
571 {
572 /* Compute the negative of the input value, assuming two's
573 complement. */
574 for (value = 0, where = where1, overflow = 0; ; )
575 {
576 value += 7 - (*where++ - '0');
577 if (where == lim || ! ISODIGIT (*where))
578 break;
579 overflow |= value ^ (value << LG_8 >> LG_8);
580 value <<= LG_8;
581 }
582 value++;
583 overflow |= !value;
584
585 if (!overflow && value <= minus_minval)
586 {
587 WARN ((0, 0,
588 _("Archive octal value %.*s is out of %s range; assuming two's complement"),
589 (int) (where - where1), where1, type));
590 negative = 1;
591 }
592 }
593
594 if (overflow)
595 {
596 ERROR ((0, 0,
597 _("Archive octal value %.*s is out of %s range"),
598 (int) (where - where1), where1, type));
599 return -1;
600 }
601 }
602 else if (type)
603 {
604 /* The following forms cannot appear as checksums, so we don't
605 check for them if TYPE is null. */
606
607 if (*where == '-' || *where == '+')
608 {
609 /* Parse base-64 output produced only by tar test versions
610 1.13.6 (1999-08-11) through 1.13.11 (1999-08-23).
611 Support for this will be withdrawn in future releases. */
612 int dig;
613 static int warned_once;
614 if (! warned_once)
615 {
616 warned_once = 1;
617 WARN ((0, 0,
618 _("Archive contains obsolescent base-64 headers")));
619 }
620 negative = *where++ == '-';
621 while (where != lim
622 && (dig = base64_map[(unsigned char) *where]) < 64)
623 {
624 if (value << LG_64 >> LG_64 != value)
625 {
626 ERROR ((0, 0,
627 _("Archive signed base-64 string `%.*s' is out of %s range"),
628 (int) digs, where0, type));
629 return -1;
630 }
631 value = (value << LG_64) | dig;
632 where++;
633 }
634 }
635 else if (*where == '\200' /* positive base-256 */
636 || *where == '\377' /* negative base-256 */)
637 {
638 /* Parse base-256 output. A nonnegative number N is
639 represented as (256**DIGS)/2 + N; a negative number -N is
640 represented as (256**DIGS) - N, i.e. as two's complement.
641 The representation guarantees that the leading bit is
642 always on, so that we don't confuse this format with the
643 others (assuming ASCII bytes of 8 bits or more). */
644 int signbit = *where & (1 << (LG_256 - 2));
645 uintmax_t topbits = (((uintmax_t) - signbit)
646 << (CHAR_BIT * sizeof (uintmax_t)
647 - LG_256 - (LG_256 - 2)));
648 value = (*where++ & ((1 << (LG_256 - 2)) - 1)) - signbit;
649 for (;;)
650 {
651 value = (value << LG_256) + (unsigned char) *where++;
652 if (where == lim)
653 break;
654 if (((value << LG_256 >> LG_256) | topbits) != value)
655 {
656 ERROR ((0, 0,
657 _("Archive base-256 value is out of %s range"),
658 type));
659 return -1;
660 }
661 }
662 negative = signbit;
663 if (negative)
664 value = -value;
665 }
666 }
667
668 if (where != lim && *where && !ISSPACE ((unsigned char) *where))
669 {
670 if (type)
671 {
672 char buf[1000]; /* Big enough to represent any header. */
673 static struct quoting_options *o;
674
675 if (!o)
676 {
677 o = clone_quoting_options (0);
678 set_quoting_style (o, c_quoting_style);
679 }
680
681 while (where0 != lim && ! lim[-1])
682 lim--;
683 quotearg_buffer (buf, sizeof buf, where0, lim - where, o);
684 ERROR ((0, 0,
685 _("Archive contains `%.*s' where numeric %s value expected"),
686 (int) sizeof buf, buf, type));
687 }
688
689 return -1;
690 }
691
692 if (value <= (negative ? minus_minval : maxval))
693 return negative ? -value : value;
694
695 if (type)
696 {
697 char minval_buf[UINTMAX_STRSIZE_BOUND + 1];
698 char maxval_buf[UINTMAX_STRSIZE_BOUND];
699 char value_buf[UINTMAX_STRSIZE_BOUND + 1];
700 char *minval_string = STRINGIFY_BIGINT (minus_minval, minval_buf + 1);
701 char *value_string = STRINGIFY_BIGINT (value, value_buf + 1);
702 if (negative)
703 *--value_string = '-';
704 if (minus_minval)
705 *--minval_string = '-';
706 ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"),
707 value_string, type,
708 minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));
709 }
710
711 return -1;
712 }
713
714 gid_t
715 gid_from_header (const char *p, size_t s)
716 {
717 return from_header (p, s, "gid_t",
718 - (uintmax_t) TYPE_MINIMUM (gid_t),
719 (uintmax_t) TYPE_MAXIMUM (gid_t));
720 }
721
722 major_t
723 major_from_header (const char *p, size_t s)
724 {
725 return from_header (p, s, "major_t",
726 - (uintmax_t) TYPE_MINIMUM (major_t),
727 (uintmax_t) TYPE_MAXIMUM (major_t));
728 }
729
730 minor_t
731 minor_from_header (const char *p, size_t s)
732 {
733 return from_header (p, s, "minor_t",
734 - (uintmax_t) TYPE_MINIMUM (minor_t),
735 (uintmax_t) TYPE_MAXIMUM (minor_t));
736 }
737
738 mode_t
739 mode_from_header (const char *p, size_t s)
740 {
741 /* Do not complain about unrecognized mode bits. */
742 unsigned u = from_header (p, s, "mode_t",
743 - (uintmax_t) TYPE_MINIMUM (mode_t),
744 TYPE_MAXIMUM (uintmax_t));
745 return ((u & TSUID ? S_ISUID : 0)
746 | (u & TSGID ? S_ISGID : 0)
747 | (u & TSVTX ? S_ISVTX : 0)
748 | (u & TUREAD ? S_IRUSR : 0)
749 | (u & TUWRITE ? S_IWUSR : 0)
750 | (u & TUEXEC ? S_IXUSR : 0)
751 | (u & TGREAD ? S_IRGRP : 0)
752 | (u & TGWRITE ? S_IWGRP : 0)
753 | (u & TGEXEC ? S_IXGRP : 0)
754 | (u & TOREAD ? S_IROTH : 0)
755 | (u & TOWRITE ? S_IWOTH : 0)
756 | (u & TOEXEC ? S_IXOTH : 0));
757 }
758
759 off_t
760 off_from_header (const char *p, size_t s)
761 {
762 /* Negative offsets are not allowed in tar files, so invoke
763 from_header with minimum value 0, not TYPE_MINIMUM (off_t). */
764 return from_header (p, s, "off_t", (uintmax_t) 0,
765 (uintmax_t) TYPE_MAXIMUM (off_t));
766 }
767
768 size_t
769 size_from_header (const char *p, size_t s)
770 {
771 return from_header (p, s, "size_t", (uintmax_t) 0,
772 (uintmax_t) TYPE_MAXIMUM (size_t));
773 }
774
775 time_t
776 time_from_header (const char *p, size_t s)
777 {
778 time_t t = from_header (p, s, "time_t",
779 - (uintmax_t) TYPE_MINIMUM (time_t),
780 (uintmax_t) TYPE_MAXIMUM (time_t));
781 if (start_time < t && time (0) < t)
782 WARN ((0, 0, _("Archive contains future timestamp %s"), tartime (t)));
783 return t;
784 }
785
786 uid_t
787 uid_from_header (const char *p, size_t s)
788 {
789 return from_header (p, s, "uid_t",
790 - (uintmax_t) TYPE_MINIMUM (uid_t),
791 (uintmax_t) TYPE_MAXIMUM (uid_t));
792 }
793
794 uintmax_t
795 uintmax_from_header (const char *p, size_t s)
796 {
797 return from_header (p, s, "uintmax_t", (uintmax_t) 0,
798 TYPE_MAXIMUM (uintmax_t));
799 }
800
801
802 /*----------------------------------------------------------------------.
803 | Format O as a null-terminated decimal string into BUF _backwards_; |
804 | return pointer to start of result. |
805 `----------------------------------------------------------------------*/
806 char *
807 stringify_uintmax_t_backwards (uintmax_t o, char *buf)
808 {
809 *--buf = '\0';
810 do
811 *--buf = '0' + (int) (o % 10);
812 while ((o /= 10) != 0);
813 return buf;
814 }
815
816 /* Return a printable representation of T. The result points to
817 static storage that can be reused in the next call to this
818 function, to ctime, or to asctime. */
819 static char const *
820 tartime (time_t t)
821 {
822 static char buffer[max (UINTMAX_STRSIZE_BOUND + 1,
823 INT_STRLEN_BOUND (int) + 16)];
824 char *p;
825
826 #if USE_OLD_CTIME
827 p = ctime (&t);
828 if (p)
829 {
830 char const *time_stamp = p + 4;
831 for (p += 16; p[4] != '\n'; p++)
832 p[0] = p[4];
833 p[0] = '\0';
834 return time_stamp;
835 }
836 #else
837 /* Use ISO 8610 format. See:
838 http://www.cl.cam.ac.uk/~mgk25/iso-time.html */
839 struct tm *tm = localtime (&t);
840 if (tm)
841 {
842 sprintf (buffer, "%04d-%02d-%02d %02d:%02d:%02d",
843 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
844 tm->tm_hour, tm->tm_min, tm->tm_sec);
845 return buffer;
846 }
847 #endif
848
849 /* The time stamp cannot be broken down, most likely because it
850 is out of range. Convert it as an integer,
851 right-adjusted in a field with the same width as the usual
852 19-byte 4-year ISO time format. */
853 p = stringify_uintmax_t_backwards (t < 0 ? - (uintmax_t) t : (uintmax_t) t,
854 buffer + sizeof buffer);
855 if (t < 0)
856 *--p = '-';
857 while (buffer + sizeof buffer - 19 - 1 < p)
858 *--p = ' ';
859 return p;
860 }
861
862 /*-------------------------------------------------------------------------.
863 | Decode MODE from its binary form in a stat structure, and encode it into |
864 | a 9 characters string STRING, terminated with a NUL. |
865 `-------------------------------------------------------------------------*/
866
867 static void
868 decode_mode (mode_t mode, char *string)
869 {
870 *string++ = mode & S_IRUSR ? 'r' : '-';
871 *string++ = mode & S_IWUSR ? 'w' : '-';
872 *string++ = (mode & S_ISUID
873 ? (mode & S_IXUSR ? 's' : 'S')
874 : (mode & S_IXUSR ? 'x' : '-'));
875 *string++ = mode & S_IRGRP ? 'r' : '-';
876 *string++ = mode & S_IWGRP ? 'w' : '-';
877 *string++ = (mode & S_ISGID
878 ? (mode & S_IXGRP ? 's' : 'S')
879 : (mode & S_IXGRP ? 'x' : '-'));
880 *string++ = mode & S_IROTH ? 'r' : '-';
881 *string++ = mode & S_IWOTH ? 'w' : '-';
882 *string++ = (mode & S_ISVTX
883 ? (mode & S_IXOTH ? 't' : 'T')
884 : (mode & S_IXOTH ? 'x' : '-'));
885 *string = '\0';
886 }
887
888 /*-------------------------------------------------------------------------.
889 | Actually print it. |
890 | |
891 | Plain and fancy file header block logging. Non-verbose just prints the |
892 | name, e.g. for "tar t" or "tar x". This should just contain file names, |
893 | so it can be fed back into tar with xargs or the "-T" option. The |
894 | verbose option can give a bunch of info, one line per file. I doubt |
895 | anybody tries to parse its format, or if they do, they shouldn't. Unix |
896 | tar is pretty random here anyway. |
897 `-------------------------------------------------------------------------*/
898
899 /* FIXME: Note that print_header uses the globals HEAD, HSTAT, and
900 HEAD_STANDARD, which must be set up in advance. Not very clean... */
901
902 /* UGSWIDTH starts with 18, so with user and group names <= 8 chars, the
903 columns never shift during the listing. */
904 #define UGSWIDTH 18
905 static int ugswidth = UGSWIDTH; /* maximum width encountered so far */
906
907 /* DATEWIDTH is the number of columns taken by the date and time fields. */
908 #if USE_OLD_CDATE
909 # define DATEWIDTH 19
910 #else
911 # define DATEWIDTH 18
912 #endif
913
914 void
915 print_header (void)
916 {
917 char modes[11];
918 char const *time_stamp;
919 /* These hold formatted ints. */
920 char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
921 char *user, *group;
922 char size[2 * UINTMAX_STRSIZE_BOUND];
923 /* holds formatted size or major,minor */
924 char uintbuf[UINTMAX_STRSIZE_BOUND];
925 int pad;
926 char *name;
927
928 if (block_number_option)
929 {
930 char buf[UINTMAX_STRSIZE_BOUND];
931 fprintf (stdlis, _("block %s: "),
932 STRINGIFY_BIGINT (current_block_ordinal (), buf));
933 }
934
935 if (verbose_option <= 1)
936 {
937 /* Just the fax, mam. */
938
939 char *quoted_name = quote_copy_string (current_file_name);
940
941 if (quoted_name)
942 {
943 fprintf (stdlis, "%s\n", quoted_name);
944 free (quoted_name);
945 }
946 else
947 fprintf (stdlis, "%s\n", current_file_name);
948 }
949 else
950 {
951 /* File type and modes. */
952
953 modes[0] = '?';
954 switch (current_header->header.typeflag)
955 {
956 case GNUTYPE_VOLHDR:
957 modes[0] = 'V';
958 break;
959
960 case GNUTYPE_MULTIVOL:
961 modes[0] = 'M';
962 break;
963
964 case GNUTYPE_NAMES:
965 modes[0] = 'N';
966 break;
967
968 case GNUTYPE_LONGNAME:
969 case GNUTYPE_LONGLINK:
970 ERROR ((0, 0, _("Visible longname error")));
971 break;
972
973 case GNUTYPE_SPARSE:
974 case REGTYPE:
975 case AREGTYPE:
976 case LNKTYPE:
977 modes[0] = '-';
978 if (current_file_name[strlen (current_file_name) - 1] == '/')
979 modes[0] = 'd';
980 break;
981 case GNUTYPE_DUMPDIR:
982 modes[0] = 'd';
983 break;
984 case DIRTYPE:
985 modes[0] = 'd';
986 break;
987 case SYMTYPE:
988 modes[0] = 'l';
989 break;
990 case BLKTYPE:
991 modes[0] = 'b';
992 break;
993 case CHRTYPE:
994 modes[0] = 'c';
995 break;
996 case FIFOTYPE:
997 modes[0] = 'p';
998 break;
999 case CONTTYPE:
1000 modes[0] = 'C';
1001 break;
1002 }
1003
1004 decode_mode (current_stat.st_mode, modes + 1);
1005
1006 /* Time stamp. */
1007
1008 time_stamp = tartime (current_stat.st_mtime);
1009
1010 /* User and group names. */
1011
1012 if (*current_header->header.uname && current_format != V7_FORMAT
1013 && !numeric_owner_option)
1014 user = current_header->header.uname;
1015 else
1016 user = STRINGIFY_BIGINT (UINTMAX_FROM_HEADER
1017 (current_header->header.uid),
1018 uform);
1019
1020 if (*current_header->header.gname && current_format != V7_FORMAT
1021 && !numeric_owner_option)
1022 group = current_header->header.gname;
1023 else
1024 group = STRINGIFY_BIGINT (UINTMAX_FROM_HEADER
1025 (current_header->header.gid),
1026 gform);
1027
1028 /* Format the file size or major/minor device numbers. */
1029
1030 switch (current_header->header.typeflag)
1031 {
1032 case CHRTYPE:
1033 case BLKTYPE:
1034 strcpy (size,
1035 STRINGIFY_BIGINT (major (current_stat.st_rdev), uintbuf));
1036 strcat (size, ",");
1037 strcat (size,
1038 STRINGIFY_BIGINT (minor (current_stat.st_rdev), uintbuf));
1039 break;
1040 case GNUTYPE_SPARSE:
1041 strcpy (size,
1042 STRINGIFY_BIGINT
1043 (UINTMAX_FROM_HEADER (current_header
1044 ->oldgnu_header.realsize),
1045 uintbuf));
1046 break;
1047 default:
1048 strcpy (size, STRINGIFY_BIGINT (current_stat.st_size, uintbuf));
1049 break;
1050 }
1051
1052 /* Figure out padding and print the whole line. */
1053
1054 pad = strlen (user) + strlen (group) + strlen (size) + 1;
1055 if (pad > ugswidth)
1056 ugswidth = pad;
1057
1058 fprintf (stdlis, "%s %s/%s %*s%s %s",
1059 modes, user, group, ugswidth - pad, "", size, time_stamp);
1060
1061 name = quote_copy_string (current_file_name);
1062 if (name)
1063 {
1064 fprintf (stdlis, " %s", name);
1065 free (name);
1066 }
1067 else
1068 fprintf (stdlis, " %s", current_file_name);
1069
1070 switch (current_header->header.typeflag)
1071 {
1072 case SYMTYPE:
1073 name = quote_copy_string (current_link_name);
1074 if (name)
1075 {
1076 fprintf (stdlis, " -> %s\n", name);
1077 free (name);
1078 }
1079 else
1080 fprintf (stdlis, " -> %s\n", current_link_name);
1081 break;
1082
1083 case LNKTYPE:
1084 name = quote_copy_string (current_link_name);
1085 if (name)
1086 {
1087 fprintf (stdlis, _(" link to %s\n"), name);
1088 free (name);
1089 }
1090 else
1091 fprintf (stdlis, _(" link to %s\n"), current_link_name);
1092 break;
1093
1094 default:
1095 fprintf (stdlis, _(" unknown file type `%c'\n"),
1096 current_header->header.typeflag);
1097 break;
1098
1099 case AREGTYPE:
1100 case REGTYPE:
1101 case GNUTYPE_SPARSE:
1102 case CHRTYPE:
1103 case BLKTYPE:
1104 case DIRTYPE:
1105 case FIFOTYPE:
1106 case CONTTYPE:
1107 case GNUTYPE_DUMPDIR:
1108 putc ('\n', stdlis);
1109 break;
1110
1111 case GNUTYPE_VOLHDR:
1112 fprintf (stdlis, _("--Volume Header--\n"));
1113 break;
1114
1115 case GNUTYPE_MULTIVOL:
1116 strcpy (size,
1117 STRINGIFY_BIGINT
1118 (UINTMAX_FROM_HEADER (current_header->oldgnu_header.offset),
1119 uintbuf));
1120 fprintf (stdlis, _("--Continued at byte %s--\n"), size);
1121 break;
1122
1123 case GNUTYPE_NAMES:
1124 fprintf (stdlis, _("--Mangled file names--\n"));
1125 break;
1126 }
1127 }
1128 fflush (stdlis);
1129 }
1130
1131 /*--------------------------------------------------------------.
1132 | Print a similar line when we make a directory automatically. |
1133 `--------------------------------------------------------------*/
1134
1135 void
1136 print_for_mkdir (char *pathname, int length, mode_t mode)
1137 {
1138 char modes[11];
1139 char *name;
1140
1141 if (verbose_option > 1)
1142 {
1143 /* File type and modes. */
1144
1145 modes[0] = 'd';
1146 decode_mode (mode, modes + 1);
1147
1148 if (block_number_option)
1149 {
1150 char buf[UINTMAX_STRSIZE_BOUND];
1151 fprintf (stdlis, _("block %s: "),
1152 STRINGIFY_BIGINT (current_block_ordinal (), buf));
1153 }
1154 name = quote_copy_string (pathname);
1155 if (name)
1156 {
1157 fprintf (stdlis, "%s %*s %.*s\n", modes, ugswidth + DATEWIDTH,
1158 _("Creating directory:"), length, name);
1159 free (name);
1160 }
1161 else
1162 fprintf (stdlis, "%s %*s %.*s\n", modes, ugswidth + DATEWIDTH,
1163 _("Creating directory:"), length, pathname);
1164 }
1165 }
1166
1167 /*--------------------------------------------------------.
1168 | Skip over SIZE bytes of data in blocks in the archive. |
1169 `--------------------------------------------------------*/
1170
1171 void
1172 skip_file (off_t size)
1173 {
1174 union block *x;
1175
1176 if (multi_volume_option)
1177 {
1178 save_totsize = size;
1179 save_sizeleft = size;
1180 }
1181
1182 while (size > 0)
1183 {
1184 x = find_next_block ();
1185 if (! x)
1186 FATAL_ERROR ((0, 0, _("Unexpected EOF on archive file")));
1187
1188 set_next_block_after (x);
1189 size -= BLOCKSIZE;
1190 if (multi_volume_option)
1191 save_sizeleft -= BLOCKSIZE;
1192 }
1193 }
1194
1195 /*---.
1196 | ? |
1197 `---*/
1198
1199 void
1200 skip_extended_headers (void)
1201 {
1202 union block *exhdr;
1203
1204 do
1205 {
1206 exhdr = find_next_block ();
1207 if (!exhdr)
1208 FATAL_ERROR ((0, 0, _("Unexpected EOF on archive file")));
1209 set_next_block_after (exhdr);
1210 }
1211 while (exhdr->sparse_header.isextended);
1212 }
This page took 0.089982 seconds and 5 git commands to generate.