]> Dogcows Code - chaz/tar/blob - src/list.c
858aa7391b4f570dce2d80ea0bd788d4501b8846
[chaz/tar] / src / list.c
1 /* List a tar archive, with support routines for reading a tar archive.
2
3 Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2013
4 Free Software Foundation, Inc.
5
6 This file is part of GNU tar.
7
8 GNU tar is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 GNU tar is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21 Written by John Gilmore, on 1985-08-26. */
22
23 #include <system.h>
24 #include <inttostr.h>
25 #include <quotearg.h>
26
27 #include "common.h"
28
29 union block *current_header; /* points to current archive header */
30 enum archive_format current_format; /* recognized format */
31 union block *recent_long_name; /* recent long name header and contents */
32 union block *recent_long_link; /* likewise, for long link */
33 size_t recent_long_name_blocks; /* number of blocks in recent_long_name */
34 size_t recent_long_link_blocks; /* likewise, for long link */
35 static union block *recent_global_header; /* Recent global header block */
36
37 #define GID_FROM_HEADER(where) gid_from_header (where, sizeof (where))
38 #define MAJOR_FROM_HEADER(where) major_from_header (where, sizeof (where))
39 #define MINOR_FROM_HEADER(where) minor_from_header (where, sizeof (where))
40 #define MODE_FROM_HEADER(where, hbits) \
41 mode_from_header (where, sizeof (where), hbits)
42 #define TIME_FROM_HEADER(where) time_from_header (where, sizeof (where))
43 #define UID_FROM_HEADER(where) uid_from_header (where, sizeof (where))
44
45 static gid_t gid_from_header (const char *buf, size_t size);
46 static major_t major_from_header (const char *buf, size_t size);
47 static minor_t minor_from_header (const char *buf, size_t size);
48 static mode_t mode_from_header (const char *buf, size_t size, bool *hbits);
49 static time_t time_from_header (const char *buf, size_t size);
50 static uid_t uid_from_header (const char *buf, size_t size);
51 static intmax_t from_header (const char *, size_t, const char *,
52 intmax_t, uintmax_t, bool, bool);
53
54 /* Base 64 digits; see Internet RFC 2045 Table 1. */
55 static char const base_64_digits[64] =
56 {
57 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
58 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
59 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
60 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
61 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
62 };
63
64 /* Table of base-64 digit values indexed by unsigned chars.
65 The value is 64 for unsigned chars that are not base-64 digits. */
66 static char base64_map[UCHAR_MAX + 1];
67
68 static void
69 base64_init (void)
70 {
71 int i;
72 memset (base64_map, 64, sizeof base64_map);
73 for (i = 0; i < 64; i++)
74 base64_map[(int) base_64_digits[i]] = i;
75 }
76
77 static char *
78 decode_xform (char *file_name, void *data)
79 {
80 int type = *(int*)data;
81
82 switch (type)
83 {
84 case XFORM_SYMLINK:
85 /* FIXME: It is not quite clear how and to which extent are the symbolic
86 links subject to filename transformation. In the absence of another
87 solution, symbolic links are exempt from component stripping and
88 name suffix normalization, but subject to filename transformation
89 proper. */
90 return file_name;
91
92 case XFORM_LINK:
93 file_name = safer_name_suffix (file_name, true, absolute_names_option);
94 break;
95
96 case XFORM_REGFILE:
97 file_name = safer_name_suffix (file_name, false, absolute_names_option);
98 break;
99 }
100
101 if (strip_name_components)
102 {
103 size_t prefix_len = stripped_prefix_len (file_name,
104 strip_name_components);
105 if (prefix_len == (size_t) -1)
106 prefix_len = strlen (file_name);
107 file_name += prefix_len;
108 }
109 return file_name;
110 }
111
112 static bool
113 transform_member_name (char **pinput, int type)
114 {
115 return transform_name_fp (pinput, type, decode_xform, &type);
116 }
117
118 void
119 transform_stat_info (int typeflag, struct tar_stat_info *stat_info)
120 {
121 if (typeflag == GNUTYPE_VOLHDR)
122 /* Name transformations don't apply to volume headers. */
123 return;
124
125 transform_member_name (&stat_info->file_name, XFORM_REGFILE);
126 switch (typeflag)
127 {
128 case SYMTYPE:
129 transform_member_name (&stat_info->link_name, XFORM_SYMLINK);
130 break;
131
132 case LNKTYPE:
133 transform_member_name (&stat_info->link_name, XFORM_LINK);
134 }
135 }
136
137 /* Main loop for reading an archive. */
138 void
139 read_and (void (*do_something) (void))
140 {
141 enum read_header status = HEADER_STILL_UNREAD;
142 enum read_header prev_status;
143 struct timespec mtime;
144
145 base64_init ();
146 name_gather ();
147
148 open_archive (ACCESS_READ);
149 do
150 {
151 prev_status = status;
152 tar_stat_destroy (&current_stat_info);
153
154 status = read_header (&current_header, &current_stat_info,
155 read_header_auto);
156 switch (status)
157 {
158 case HEADER_STILL_UNREAD:
159 case HEADER_SUCCESS_EXTENDED:
160 abort ();
161
162 case HEADER_SUCCESS:
163
164 /* Valid header. We should decode next field (mode) first.
165 Ensure incoming names are null terminated. */
166 decode_header (current_header, &current_stat_info,
167 &current_format, 1);
168 if (! name_match (current_stat_info.file_name)
169 || (NEWER_OPTION_INITIALIZED (newer_mtime_option)
170 /* FIXME: We get mtime now, and again later; this causes
171 duplicate diagnostics if header.mtime is bogus. */
172 && ((mtime.tv_sec
173 = TIME_FROM_HEADER (current_header->header.mtime)),
174 /* FIXME: Grab fractional time stamps from
175 extended header. */
176 mtime.tv_nsec = 0,
177 current_stat_info.mtime = mtime,
178 OLDER_TAR_STAT_TIME (current_stat_info, m)))
179 || excluded_name (current_stat_info.file_name))
180 {
181 switch (current_header->header.typeflag)
182 {
183 case GNUTYPE_VOLHDR:
184 case GNUTYPE_MULTIVOL:
185 break;
186
187 case DIRTYPE:
188 if (show_omitted_dirs_option)
189 WARN ((0, 0, _("%s: Omitting"),
190 quotearg_colon (current_stat_info.file_name)));
191 /* Fall through. */
192 default:
193 skip_member ();
194 continue;
195 }
196 }
197 transform_stat_info (current_header->header.typeflag,
198 &current_stat_info);
199 (*do_something) ();
200 continue;
201
202 case HEADER_ZERO_BLOCK:
203 if (block_number_option)
204 {
205 char buf[UINTMAX_STRSIZE_BOUND];
206 fprintf (stdlis, _("block %s: ** Block of NULs **\n"),
207 STRINGIFY_BIGINT (current_block_ordinal (), buf));
208 }
209
210 set_next_block_after (current_header);
211
212 if (!ignore_zeros_option)
213 {
214 char buf[UINTMAX_STRSIZE_BOUND];
215
216 status = read_header (&current_header, &current_stat_info,
217 read_header_auto);
218 if (status == HEADER_ZERO_BLOCK)
219 break;
220 WARNOPT (WARN_ALONE_ZERO_BLOCK,
221 (0, 0, _("A lone zero block at %s"),
222 STRINGIFY_BIGINT (current_block_ordinal (), buf)));
223 break;
224 }
225 status = prev_status;
226 continue;
227
228 case HEADER_END_OF_FILE:
229 if (block_number_option)
230 {
231 char buf[UINTMAX_STRSIZE_BOUND];
232 fprintf (stdlis, _("block %s: ** End of File **\n"),
233 STRINGIFY_BIGINT (current_block_ordinal (), buf));
234 }
235 break;
236
237 case HEADER_FAILURE:
238 /* If the previous header was good, tell them that we are
239 skipping bad ones. */
240 set_next_block_after (current_header);
241 switch (prev_status)
242 {
243 case HEADER_STILL_UNREAD:
244 ERROR ((0, 0, _("This does not look like a tar archive")));
245 /* Fall through. */
246
247 case HEADER_ZERO_BLOCK:
248 case HEADER_SUCCESS:
249 if (block_number_option)
250 {
251 char buf[UINTMAX_STRSIZE_BOUND];
252 off_t block_ordinal = current_block_ordinal ();
253 block_ordinal -= recent_long_name_blocks;
254 block_ordinal -= recent_long_link_blocks;
255 fprintf (stdlis, _("block %s: "),
256 STRINGIFY_BIGINT (block_ordinal, buf));
257 }
258 ERROR ((0, 0, _("Skipping to next header")));
259 break;
260
261 case HEADER_END_OF_FILE:
262 case HEADER_FAILURE:
263 /* We are in the middle of a cascade of errors. */
264 break;
265
266 case HEADER_SUCCESS_EXTENDED:
267 abort ();
268 }
269 continue;
270 }
271 break;
272 }
273 while (!all_names_found (&current_stat_info));
274
275 close_archive ();
276 names_notfound (); /* print names not found */
277 }
278
279 /* Print a header block, based on tar options. */
280 void
281 list_archive (void)
282 {
283 off_t block_ordinal = current_block_ordinal ();
284
285 /* Print the header block. */
286 if (verbose_option)
287 print_header (&current_stat_info, current_header, block_ordinal);
288
289 if (incremental_option)
290 {
291 if (verbose_option > 2)
292 {
293 if (is_dumpdir (&current_stat_info))
294 list_dumpdir (current_stat_info.dumpdir,
295 dumpdir_size (current_stat_info.dumpdir));
296 }
297 }
298
299 skip_member ();
300 }
301
302 /* Check header checksum */
303 /* The standard BSD tar sources create the checksum by adding up the
304 bytes in the header as type char. I think the type char was unsigned
305 on the PDP-11, but it's signed on the Next and Sun. It looks like the
306 sources to BSD tar were never changed to compute the checksum
307 correctly, so both the Sun and Next add the bytes of the header as
308 signed chars. This doesn't cause a problem until you get a file with
309 a name containing characters with the high bit set. So tar_checksum
310 computes two checksums -- signed and unsigned. */
311
312 enum read_header
313 tar_checksum (union block *header, bool silent)
314 {
315 size_t i;
316 int unsigned_sum = 0; /* the POSIX one :-) */
317 int signed_sum = 0; /* the Sun one :-( */
318 int recorded_sum;
319 int parsed_sum;
320 char *p;
321
322 p = header->buffer;
323 for (i = sizeof *header; i-- != 0;)
324 {
325 unsigned_sum += (unsigned char) *p;
326 signed_sum += (signed char) (*p++);
327 }
328
329 if (unsigned_sum == 0)
330 return HEADER_ZERO_BLOCK;
331
332 /* Adjust checksum to count the "chksum" field as blanks. */
333
334 for (i = sizeof header->header.chksum; i-- != 0;)
335 {
336 unsigned_sum -= (unsigned char) header->header.chksum[i];
337 signed_sum -= (signed char) (header->header.chksum[i]);
338 }
339 unsigned_sum += ' ' * sizeof header->header.chksum;
340 signed_sum += ' ' * sizeof header->header.chksum;
341
342 parsed_sum = from_header (header->header.chksum,
343 sizeof header->header.chksum, 0,
344 0, INT_MAX, true, silent);
345 if (parsed_sum < 0)
346 return HEADER_FAILURE;
347
348 recorded_sum = parsed_sum;
349
350 if (unsigned_sum != recorded_sum && signed_sum != recorded_sum)
351 return HEADER_FAILURE;
352
353 return HEADER_SUCCESS;
354 }
355
356 /* Read a block that's supposed to be a header block. Return its
357 address in *RETURN_BLOCK, and if it is good, the file's size
358 and names (file name, link name) in *INFO.
359
360 Return one of enum read_header describing the status of the
361 operation.
362
363 The MODE parameter instructs read_header what to do with special
364 header blocks, i.e.: extended POSIX, GNU long name or long link,
365 etc.:
366
367 read_header_auto process them automatically,
368 read_header_x_raw when a special header is read, return
369 HEADER_SUCCESS_EXTENDED without actually
370 processing the header,
371 read_header_x_global when a POSIX global header is read,
372 decode it and return HEADER_SUCCESS_EXTENDED.
373
374 You must always set_next_block_after(*return_block) to skip past
375 the header which this routine reads. */
376
377 enum read_header
378 read_header (union block **return_block, struct tar_stat_info *info,
379 enum read_header_mode mode)
380 {
381 union block *header;
382 union block *header_copy;
383 char *bp;
384 union block *data_block;
385 size_t size, written;
386 union block *next_long_name = 0;
387 union block *next_long_link = 0;
388 size_t next_long_name_blocks = 0;
389 size_t next_long_link_blocks = 0;
390
391 while (1)
392 {
393 enum read_header status;
394
395 header = find_next_block ();
396 *return_block = header;
397 if (!header)
398 return HEADER_END_OF_FILE;
399
400 if ((status = tar_checksum (header, false)) != HEADER_SUCCESS)
401 return status;
402
403 /* Good block. Decode file size and return. */
404
405 if (header->header.typeflag == LNKTYPE)
406 info->stat.st_size = 0; /* links 0 size on tape */
407 else
408 {
409 info->stat.st_size = OFF_FROM_HEADER (header->header.size);
410 if (info->stat.st_size < 0)
411 return HEADER_FAILURE;
412 }
413
414 if (header->header.typeflag == GNUTYPE_LONGNAME
415 || header->header.typeflag == GNUTYPE_LONGLINK
416 || header->header.typeflag == XHDTYPE
417 || header->header.typeflag == XGLTYPE
418 || header->header.typeflag == SOLARIS_XHDTYPE)
419 {
420 if (mode == read_header_x_raw)
421 return HEADER_SUCCESS_EXTENDED;
422 else if (header->header.typeflag == GNUTYPE_LONGNAME
423 || header->header.typeflag == GNUTYPE_LONGLINK)
424 {
425 size_t name_size = info->stat.st_size;
426 size_t n = name_size % BLOCKSIZE;
427 size = name_size + BLOCKSIZE;
428 if (n)
429 size += BLOCKSIZE - n;
430
431 if (name_size != info->stat.st_size || size < name_size)
432 xalloc_die ();
433
434 header_copy = xmalloc (size + 1);
435
436 if (header->header.typeflag == GNUTYPE_LONGNAME)
437 {
438 free (next_long_name);
439 next_long_name = header_copy;
440 next_long_name_blocks = size / BLOCKSIZE;
441 }
442 else
443 {
444 free (next_long_link);
445 next_long_link = header_copy;
446 next_long_link_blocks = size / BLOCKSIZE;
447 }
448
449 set_next_block_after (header);
450 *header_copy = *header;
451 bp = header_copy->buffer + BLOCKSIZE;
452
453 for (size -= BLOCKSIZE; size > 0; size -= written)
454 {
455 data_block = find_next_block ();
456 if (! data_block)
457 {
458 ERROR ((0, 0, _("Unexpected EOF in archive")));
459 break;
460 }
461 written = available_space_after (data_block);
462 if (written > size)
463 written = size;
464
465 memcpy (bp, data_block->buffer, written);
466 bp += written;
467 set_next_block_after ((union block *)
468 (data_block->buffer + written - 1));
469 }
470
471 *bp = '\0';
472 }
473 else if (header->header.typeflag == XHDTYPE
474 || header->header.typeflag == SOLARIS_XHDTYPE)
475 xheader_read (&info->xhdr, header,
476 OFF_FROM_HEADER (header->header.size));
477 else if (header->header.typeflag == XGLTYPE)
478 {
479 struct xheader xhdr;
480
481 if (!recent_global_header)
482 recent_global_header = xmalloc (sizeof *recent_global_header);
483 memcpy (recent_global_header, header,
484 sizeof *recent_global_header);
485 memset (&xhdr, 0, sizeof xhdr);
486 xheader_read (&xhdr, header,
487 OFF_FROM_HEADER (header->header.size));
488 xheader_decode_global (&xhdr);
489 xheader_destroy (&xhdr);
490 if (mode == read_header_x_global)
491 return HEADER_SUCCESS_EXTENDED;
492 }
493
494 /* Loop! */
495
496 }
497 else
498 {
499 char const *name;
500 struct posix_header const *h = &header->header;
501 char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1];
502
503 free (recent_long_name);
504
505 if (next_long_name)
506 {
507 name = next_long_name->buffer + BLOCKSIZE;
508 recent_long_name = next_long_name;
509 recent_long_name_blocks = next_long_name_blocks;
510 }
511 else
512 {
513 /* Accept file names as specified by POSIX.1-1996
514 section 10.1.1. */
515 char *np = namebuf;
516
517 if (h->prefix[0] && strcmp (h->magic, TMAGIC) == 0)
518 {
519 memcpy (np, h->prefix, sizeof h->prefix);
520 np[sizeof h->prefix] = '\0';
521 np += strlen (np);
522 *np++ = '/';
523 }
524 memcpy (np, h->name, sizeof h->name);
525 np[sizeof h->name] = '\0';
526 name = namebuf;
527 recent_long_name = 0;
528 recent_long_name_blocks = 0;
529 }
530 assign_string (&info->orig_file_name, name);
531 assign_string (&info->file_name, name);
532 info->had_trailing_slash = strip_trailing_slashes (info->file_name);
533
534 free (recent_long_link);
535
536 if (next_long_link)
537 {
538 name = next_long_link->buffer + BLOCKSIZE;
539 recent_long_link = next_long_link;
540 recent_long_link_blocks = next_long_link_blocks;
541 }
542 else
543 {
544 memcpy (namebuf, h->linkname, sizeof h->linkname);
545 namebuf[sizeof h->linkname] = '\0';
546 name = namebuf;
547 recent_long_link = 0;
548 recent_long_link_blocks = 0;
549 }
550 assign_string (&info->link_name, name);
551
552 return HEADER_SUCCESS;
553 }
554 }
555 }
556
557 #define ISOCTAL(c) ((c)>='0'&&(c)<='7')
558
559 /* Decode things from a file HEADER block into STAT_INFO, also setting
560 *FORMAT_POINTER depending on the header block format. If
561 DO_USER_GROUP, decode the user/group information (this is useful
562 for extraction, but waste time when merely listing).
563
564 read_header() has already decoded the checksum and length, so we don't.
565
566 This routine should *not* be called twice for the same block, since
567 the two calls might use different DO_USER_GROUP values and thus
568 might end up with different uid/gid for the two calls. If anybody
569 wants the uid/gid they should decode it first, and other callers
570 should decode it without uid/gid before calling a routine,
571 e.g. print_header, that assumes decoded data. */
572 void
573 decode_header (union block *header, struct tar_stat_info *stat_info,
574 enum archive_format *format_pointer, int do_user_group)
575 {
576 enum archive_format format;
577 bool hbits;
578 mode_t mode = MODE_FROM_HEADER (header->header.mode, &hbits);
579
580 if (strcmp (header->header.magic, TMAGIC) == 0)
581 {
582 if (header->star_header.prefix[130] == 0
583 && ISOCTAL (header->star_header.atime[0])
584 && header->star_header.atime[11] == ' '
585 && ISOCTAL (header->star_header.ctime[0])
586 && header->star_header.ctime[11] == ' ')
587 format = STAR_FORMAT;
588 else if (stat_info->xhdr.size)
589 format = POSIX_FORMAT;
590 else
591 format = USTAR_FORMAT;
592 }
593 else if (strcmp (header->buffer + offsetof (struct posix_header, magic),
594 OLDGNU_MAGIC)
595 == 0)
596 format = hbits ? OLDGNU_FORMAT : GNU_FORMAT;
597 else
598 format = V7_FORMAT;
599 *format_pointer = format;
600
601 stat_info->stat.st_mode = mode;
602 stat_info->mtime.tv_sec = TIME_FROM_HEADER (header->header.mtime);
603 stat_info->mtime.tv_nsec = 0;
604 assign_string (&stat_info->uname,
605 header->header.uname[0] ? header->header.uname : NULL);
606 assign_string (&stat_info->gname,
607 header->header.gname[0] ? header->header.gname : NULL);
608
609 xheader_xattr_init (stat_info);
610
611 if (format == OLDGNU_FORMAT && incremental_option)
612 {
613 stat_info->atime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.atime);
614 stat_info->ctime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.ctime);
615 stat_info->atime.tv_nsec = stat_info->ctime.tv_nsec = 0;
616 }
617 else if (format == STAR_FORMAT)
618 {
619 stat_info->atime.tv_sec = TIME_FROM_HEADER (header->star_header.atime);
620 stat_info->ctime.tv_sec = TIME_FROM_HEADER (header->star_header.ctime);
621 stat_info->atime.tv_nsec = stat_info->ctime.tv_nsec = 0;
622 }
623 else
624 stat_info->atime = stat_info->ctime = start_time;
625
626 if (format == V7_FORMAT)
627 {
628 stat_info->stat.st_uid = UID_FROM_HEADER (header->header.uid);
629 stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid);
630 stat_info->stat.st_rdev = 0;
631 }
632 else
633 {
634 if (do_user_group)
635 {
636 /* FIXME: Decide if this should somewhat depend on -p. */
637
638 if (numeric_owner_option
639 || !*header->header.uname
640 || !uname_to_uid (header->header.uname, &stat_info->stat.st_uid))
641 stat_info->stat.st_uid = UID_FROM_HEADER (header->header.uid);
642
643 if (numeric_owner_option
644 || !*header->header.gname
645 || !gname_to_gid (header->header.gname, &stat_info->stat.st_gid))
646 stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid);
647 }
648
649 switch (header->header.typeflag)
650 {
651 case BLKTYPE:
652 case CHRTYPE:
653 stat_info->stat.st_rdev =
654 makedev (MAJOR_FROM_HEADER (header->header.devmajor),
655 MINOR_FROM_HEADER (header->header.devminor));
656 break;
657
658 default:
659 stat_info->stat.st_rdev = 0;
660 }
661 }
662
663 stat_info->archive_file_size = stat_info->stat.st_size;
664 xheader_decode (stat_info);
665
666 if (sparse_member_p (stat_info))
667 {
668 sparse_fixup_header (stat_info);
669 stat_info->is_sparse = true;
670 }
671 else
672 {
673 stat_info->is_sparse = false;
674 if (((current_format == GNU_FORMAT
675 || current_format == OLDGNU_FORMAT)
676 && current_header->header.typeflag == GNUTYPE_DUMPDIR)
677 || stat_info->dumpdir)
678 stat_info->is_dumpdir = true;
679 }
680 }
681
682
683 /* Convert buffer at WHERE0 of size DIGS from external format to
684 intmax_t. DIGS must be positive. If TYPE is nonnull, the data are
685 of type TYPE. The buffer must represent a value in the range
686 MINVAL through MAXVAL; if the mathematically correct result V would
687 be greater than INTMAX_MAX, return a negative integer V such that
688 (uintmax_t) V yields the correct result. If OCTAL_ONLY, allow only octal
689 numbers instead of the other GNU extensions. Return -1 on error,
690 diagnosing the error if TYPE is nonnull and if !SILENT. */
691 #if ! (INTMAX_MAX <= UINTMAX_MAX && - (INTMAX_MIN + 1) <= UINTMAX_MAX)
692 # error "from_header internally represents intmax_t as uintmax_t + sign"
693 #endif
694 #if ! (UINTMAX_MAX / 2 <= INTMAX_MAX)
695 # error "from_header returns intmax_t to represent uintmax_t"
696 #endif
697 static intmax_t
698 from_header (char const *where0, size_t digs, char const *type,
699 intmax_t minval, uintmax_t maxval,
700 bool octal_only, bool silent)
701 {
702 uintmax_t value;
703 uintmax_t uminval = minval;
704 uintmax_t minus_minval = - uminval;
705 char const *where = where0;
706 char const *lim = where + digs;
707 bool negative = false;
708
709 /* Accommodate buggy tar of unknown vintage, which outputs leading
710 NUL if the previous field overflows. */
711 where += !*where;
712
713 /* Accommodate older tars, which output leading spaces. */
714 for (;;)
715 {
716 if (where == lim)
717 {
718 if (type && !silent)
719 ERROR ((0, 0,
720 /* TRANSLATORS: %s is type of the value (gid_t, uid_t,
721 etc.) */
722 _("Blanks in header where numeric %s value expected"),
723 type));
724 return -1;
725 }
726 if (!ISSPACE ((unsigned char) *where))
727 break;
728 where++;
729 }
730
731 value = 0;
732 if (ISODIGIT (*where))
733 {
734 char const *where1 = where;
735 bool overflow = false;
736
737 for (;;)
738 {
739 value += *where++ - '0';
740 if (where == lim || ! ISODIGIT (*where))
741 break;
742 overflow |= value != (value << LG_8 >> LG_8);
743 value <<= LG_8;
744 }
745
746 /* Parse the output of older, unportable tars, which generate
747 negative values in two's complement octal. If the leading
748 nonzero digit is 1, we can't recover the original value
749 reliably; so do this only if the digit is 2 or more. This
750 catches the common case of 32-bit negative time stamps. */
751 if ((overflow || maxval < value) && '2' <= *where1 && type)
752 {
753 /* Compute the negative of the input value, assuming two's
754 complement. */
755 int digit = (*where1 - '0') | 4;
756 overflow = 0;
757 value = 0;
758 where = where1;
759 for (;;)
760 {
761 value += 7 - digit;
762 where++;
763 if (where == lim || ! ISODIGIT (*where))
764 break;
765 digit = *where - '0';
766 overflow |= value != (value << LG_8 >> LG_8);
767 value <<= LG_8;
768 }
769 value++;
770 overflow |= !value;
771
772 if (!overflow && value <= minus_minval)
773 {
774 if (!silent)
775 WARN ((0, 0,
776 /* TRANSLATORS: Second %s is a type name (gid_t,uid_t,etc.) */
777 _("Archive octal value %.*s is out of %s range; assuming two's complement"),
778 (int) (where - where1), where1, type));
779 negative = true;
780 }
781 }
782
783 if (overflow)
784 {
785 if (type && !silent)
786 ERROR ((0, 0,
787 /* TRANSLATORS: Second %s is a type name (gid_t,uid_t,etc.) */
788 _("Archive octal value %.*s is out of %s range"),
789 (int) (where - where1), where1, type));
790 return -1;
791 }
792 }
793 else if (octal_only)
794 {
795 /* Suppress the following extensions. */
796 }
797 else if (*where == '-' || *where == '+')
798 {
799 /* Parse base-64 output produced only by tar test versions
800 1.13.6 (1999-08-11) through 1.13.11 (1999-08-23).
801 Support for this will be withdrawn in future releases. */
802 int dig;
803 if (!silent)
804 {
805 static bool warned_once;
806 if (! warned_once)
807 {
808 warned_once = true;
809 WARN ((0, 0, _("Archive contains obsolescent base-64 headers")));
810 }
811 }
812 negative = *where++ == '-';
813 while (where != lim
814 && (dig = base64_map[(unsigned char) *where]) < 64)
815 {
816 if (value << LG_64 >> LG_64 != value)
817 {
818 char *string = alloca (digs + 1);
819 memcpy (string, where0, digs);
820 string[digs] = '\0';
821 if (type && !silent)
822 ERROR ((0, 0,
823 _("Archive signed base-64 string %s is out of %s range"),
824 quote (string), type));
825 return -1;
826 }
827 value = (value << LG_64) | dig;
828 where++;
829 }
830 }
831 else if (*where == '\200' /* positive base-256 */
832 || *where == '\377' /* negative base-256 */)
833 {
834 /* Parse base-256 output. A nonnegative number N is
835 represented as (256**DIGS)/2 + N; a negative number -N is
836 represented as (256**DIGS) - N, i.e. as two's complement.
837 The representation guarantees that the leading bit is
838 always on, so that we don't confuse this format with the
839 others (assuming ASCII bytes of 8 bits or more). */
840 int signbit = *where & (1 << (LG_256 - 2));
841 uintmax_t topbits = (((uintmax_t) - signbit)
842 << (CHAR_BIT * sizeof (uintmax_t)
843 - LG_256 - (LG_256 - 2)));
844 value = (*where++ & ((1 << (LG_256 - 2)) - 1)) - signbit;
845 for (;;)
846 {
847 value = (value << LG_256) + (unsigned char) *where++;
848 if (where == lim)
849 break;
850 if (((value << LG_256 >> LG_256) | topbits) != value)
851 {
852 if (type && !silent)
853 ERROR ((0, 0,
854 _("Archive base-256 value is out of %s range"),
855 type));
856 return -1;
857 }
858 }
859 negative = signbit != 0;
860 if (negative)
861 value = -value;
862 }
863
864 if (where != lim && *where && !ISSPACE ((unsigned char) *where))
865 {
866 if (type)
867 {
868 char buf[1000]; /* Big enough to represent any header. */
869 static struct quoting_options *o;
870
871 if (!o)
872 {
873 o = clone_quoting_options (0);
874 set_quoting_style (o, locale_quoting_style);
875 }
876
877 while (where0 != lim && ! lim[-1])
878 lim--;
879 quotearg_buffer (buf, sizeof buf, where0, lim - where0, o);
880 if (!silent)
881 ERROR ((0, 0,
882 /* TRANSLATORS: Second %s is a type name (gid_t,uid_t,etc.) */
883 _("Archive contains %.*s where numeric %s value expected"),
884 (int) sizeof buf, buf, type));
885 }
886
887 return -1;
888 }
889
890 if (value <= (negative ? minus_minval : maxval))
891 return represent_uintmax (negative ? -value : value);
892
893 if (type && !silent)
894 {
895 char minval_buf[UINTMAX_STRSIZE_BOUND + 1];
896 char maxval_buf[UINTMAX_STRSIZE_BOUND];
897 char value_buf[UINTMAX_STRSIZE_BOUND + 1];
898 char *minval_string = STRINGIFY_BIGINT (minus_minval, minval_buf + 1);
899 char *value_string = STRINGIFY_BIGINT (value, value_buf + 1);
900 if (negative)
901 *--value_string = '-';
902 if (minus_minval)
903 *--minval_string = '-';
904 /* TRANSLATORS: Second %s is type name (gid_t,uid_t,etc.) */
905 ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"),
906 value_string, type,
907 minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));
908 }
909
910 return -1;
911 }
912
913 static gid_t
914 gid_from_header (const char *p, size_t s)
915 {
916 return from_header (p, s, "gid_t",
917 TYPE_MINIMUM (gid_t), TYPE_MAXIMUM (gid_t),
918 false, false);
919 }
920
921 static major_t
922 major_from_header (const char *p, size_t s)
923 {
924 return from_header (p, s, "major_t",
925 TYPE_MINIMUM (major_t), TYPE_MAXIMUM (major_t),
926 false, false);
927 }
928
929 static minor_t
930 minor_from_header (const char *p, size_t s)
931 {
932 return from_header (p, s, "minor_t",
933 TYPE_MINIMUM (minor_t), TYPE_MAXIMUM (minor_t),
934 false, false);
935 }
936
937 /* Convert P to the file mode, as understood by tar.
938 Set *HBITS if there are any unrecognized bits. */
939 static mode_t
940 mode_from_header (const char *p, size_t s, bool *hbits)
941 {
942 intmax_t u = from_header (p, s, "mode_t",
943 INTMAX_MIN, UINTMAX_MAX,
944 false, false);
945 mode_t mode = ((u & TSUID ? S_ISUID : 0)
946 | (u & TSGID ? S_ISGID : 0)
947 | (u & TSVTX ? S_ISVTX : 0)
948 | (u & TUREAD ? S_IRUSR : 0)
949 | (u & TUWRITE ? S_IWUSR : 0)
950 | (u & TUEXEC ? S_IXUSR : 0)
951 | (u & TGREAD ? S_IRGRP : 0)
952 | (u & TGWRITE ? S_IWGRP : 0)
953 | (u & TGEXEC ? S_IXGRP : 0)
954 | (u & TOREAD ? S_IROTH : 0)
955 | (u & TOWRITE ? S_IWOTH : 0)
956 | (u & TOEXEC ? S_IXOTH : 0));
957 *hbits = (u & ~07777) != 0;
958 return mode;
959 }
960
961 off_t
962 off_from_header (const char *p, size_t s)
963 {
964 /* Negative offsets are not allowed in tar files, so invoke
965 from_header with minimum value 0, not TYPE_MINIMUM (off_t). */
966 return from_header (p, s, "off_t",
967 0, TYPE_MAXIMUM (off_t),
968 false, false);
969 }
970
971 static time_t
972 time_from_header (const char *p, size_t s)
973 {
974 return from_header (p, s, "time_t",
975 TYPE_MINIMUM (time_t), TYPE_MAXIMUM (time_t),
976 false, false);
977 }
978
979 static uid_t
980 uid_from_header (const char *p, size_t s)
981 {
982 return from_header (p, s, "uid_t",
983 TYPE_MINIMUM (uid_t), TYPE_MAXIMUM (uid_t),
984 false, false);
985 }
986
987 uintmax_t
988 uintmax_from_header (const char *p, size_t s)
989 {
990 return from_header (p, s, "uintmax_t", 0, UINTMAX_MAX, false, false);
991 }
992
993
994 /* Return a printable representation of T. The result points to
995 static storage that can be reused in the next call to this
996 function, to ctime, or to asctime. If FULL_TIME, then output the
997 time stamp to its full resolution; otherwise, just output it to
998 1-minute resolution. */
999 char const *
1000 tartime (struct timespec t, bool full_time)
1001 {
1002 enum { fraclen = sizeof ".FFFFFFFFF" - 1 };
1003 static char buffer[max (UINTMAX_STRSIZE_BOUND + 1,
1004 INT_STRLEN_BOUND (int) + 16)
1005 + fraclen];
1006 struct tm *tm;
1007 time_t s = t.tv_sec;
1008 int ns = t.tv_nsec;
1009 bool negative = s < 0;
1010 char *p;
1011
1012 if (negative && ns != 0)
1013 {
1014 s++;
1015 ns = 1000000000 - ns;
1016 }
1017
1018 tm = utc_option ? gmtime (&s) : localtime (&s);
1019 if (tm)
1020 {
1021 if (full_time)
1022 {
1023 sprintf (buffer, "%04ld-%02d-%02d %02d:%02d:%02d",
1024 tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,
1025 tm->tm_hour, tm->tm_min, tm->tm_sec);
1026 code_ns_fraction (ns, buffer + strlen (buffer));
1027 }
1028 else
1029 sprintf (buffer, "%04ld-%02d-%02d %02d:%02d",
1030 tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,
1031 tm->tm_hour, tm->tm_min);
1032 return buffer;
1033 }
1034
1035 /* The time stamp cannot be broken down, most likely because it
1036 is out of range. Convert it as an integer,
1037 right-adjusted in a field with the same width as the usual
1038 4-year ISO time format. */
1039 p = umaxtostr (negative ? - (uintmax_t) s : s,
1040 buffer + sizeof buffer - UINTMAX_STRSIZE_BOUND - fraclen);
1041 if (negative)
1042 *--p = '-';
1043 while ((buffer + sizeof buffer - sizeof "YYYY-MM-DD HH:MM"
1044 + (full_time ? sizeof ":SS.FFFFFFFFF" - 1 : 0))
1045 < p)
1046 *--p = ' ';
1047 if (full_time)
1048 code_ns_fraction (ns, buffer + sizeof buffer - 1 - fraclen);
1049 return p;
1050 }
1051
1052 /* Actually print it.
1053
1054 Plain and fancy file header block logging. Non-verbose just prints
1055 the name, e.g. for "tar t" or "tar x". This should just contain
1056 file names, so it can be fed back into tar with xargs or the "-T"
1057 option. The verbose option can give a bunch of info, one line per
1058 file. I doubt anybody tries to parse its format, or if they do,
1059 they shouldn't. Unix tar is pretty random here anyway. */
1060
1061
1062 /* Width of "user/group size", with initial value chosen
1063 heuristically. This grows as needed, though this may cause some
1064 stairstepping in the output. Make it too small and the output will
1065 almost always look ragged. Make it too large and the output will
1066 be spaced out too far. */
1067 static int ugswidth = 19;
1068
1069 /* Width of printed time stamps. It grows if longer time stamps are
1070 found (typically, those with nanosecond resolution). Like
1071 USGWIDTH, some stairstepping may occur. */
1072 static int datewidth = sizeof "YYYY-MM-DD HH:MM" - 1;
1073
1074 static bool volume_label_printed = false;
1075
1076 static void
1077 simple_print_header (struct tar_stat_info *st, union block *blk,
1078 off_t block_ordinal)
1079 {
1080 char modes[12];
1081 char const *time_stamp;
1082 int time_stamp_len;
1083 char *temp_name;
1084
1085 /* These hold formatted ints. */
1086 char uform[max (INT_BUFSIZE_BOUND (intmax_t), UINTMAX_STRSIZE_BOUND)];
1087 char gform[sizeof uform];
1088 char *user, *group;
1089 char size[2 * UINTMAX_STRSIZE_BOUND];
1090 /* holds formatted size or major,minor */
1091 char uintbuf[UINTMAX_STRSIZE_BOUND];
1092 int pad;
1093 int sizelen;
1094
1095 if (show_transformed_names_option)
1096 temp_name = st->file_name ? st->file_name : st->orig_file_name;
1097 else
1098 temp_name = st->orig_file_name ? st->orig_file_name : st->file_name;
1099
1100 if (block_number_option)
1101 {
1102 char buf[UINTMAX_STRSIZE_BOUND];
1103 if (block_ordinal < 0)
1104 block_ordinal = current_block_ordinal ();
1105 block_ordinal -= recent_long_name_blocks;
1106 block_ordinal -= recent_long_link_blocks;
1107 fprintf (stdlis, _("block %s: "),
1108 STRINGIFY_BIGINT (block_ordinal, buf));
1109 }
1110
1111 if (verbose_option <= 1)
1112 {
1113 /* Just the fax, mam. */
1114 fprintf (stdlis, "%s\n", quotearg (temp_name));
1115 }
1116 else
1117 {
1118 /* File type and modes. */
1119
1120 modes[0] = '?';
1121 switch (blk->header.typeflag)
1122 {
1123 case GNUTYPE_VOLHDR:
1124 volume_label_printed = true;
1125 modes[0] = 'V';
1126 break;
1127
1128 case GNUTYPE_MULTIVOL:
1129 modes[0] = 'M';
1130 break;
1131
1132 case GNUTYPE_LONGNAME:
1133 case GNUTYPE_LONGLINK:
1134 modes[0] = 'L';
1135 ERROR ((0, 0, _("Unexpected long name header")));
1136 break;
1137
1138 case GNUTYPE_SPARSE:
1139 case REGTYPE:
1140 case AREGTYPE:
1141 modes[0] = '-';
1142 if (temp_name[strlen (temp_name) - 1] == '/')
1143 modes[0] = 'd';
1144 break;
1145 case LNKTYPE:
1146 modes[0] = 'h';
1147 break;
1148 case GNUTYPE_DUMPDIR:
1149 modes[0] = 'd';
1150 break;
1151 case DIRTYPE:
1152 modes[0] = 'd';
1153 break;
1154 case SYMTYPE:
1155 modes[0] = 'l';
1156 break;
1157 case BLKTYPE:
1158 modes[0] = 'b';
1159 break;
1160 case CHRTYPE:
1161 modes[0] = 'c';
1162 break;
1163 case FIFOTYPE:
1164 modes[0] = 'p';
1165 break;
1166 case CONTTYPE:
1167 modes[0] = 'C';
1168 break;
1169 }
1170
1171 pax_decode_mode (st->stat.st_mode, modes + 1);
1172
1173 /* extended attributes: GNU `ls -l'-like preview */
1174 xattrs_print_char (st, modes + 10);
1175
1176 /* Time stamp. */
1177
1178 time_stamp = tartime (st->mtime, full_time_option);
1179 time_stamp_len = strlen (time_stamp);
1180 if (datewidth < time_stamp_len)
1181 datewidth = time_stamp_len;
1182
1183 /* User and group names. */
1184
1185 if (st->uname
1186 && st->uname[0]
1187 && current_format != V7_FORMAT
1188 && !numeric_owner_option)
1189 user = st->uname;
1190 else
1191 {
1192 /* Try parsing it as an unsigned integer first, and as a
1193 uid_t if that fails. This method can list positive user
1194 ids that are too large to fit in a uid_t. */
1195 uintmax_t u = from_header (blk->header.uid,
1196 sizeof blk->header.uid, 0,
1197 0, UINTMAX_MAX,
1198 false, false);
1199 user = (u != -1
1200 ? STRINGIFY_BIGINT (u, uform)
1201 : imaxtostr (UID_FROM_HEADER (blk->header.uid), uform));
1202 }
1203
1204 if (st->gname
1205 && st->gname[0]
1206 && current_format != V7_FORMAT
1207 && !numeric_owner_option)
1208 group = st->gname;
1209 else
1210 {
1211 /* Try parsing it as an unsigned integer first, and as a
1212 gid_t if that fails. This method can list positive group
1213 ids that are too large to fit in a gid_t. */
1214 uintmax_t g = from_header (blk->header.gid,
1215 sizeof blk->header.gid, 0,
1216 0, UINTMAX_MAX,
1217 false, false);
1218 group = (g != -1
1219 ? STRINGIFY_BIGINT (g, gform)
1220 : imaxtostr (GID_FROM_HEADER (blk->header.gid), gform));
1221 }
1222
1223 /* Format the file size or major/minor device numbers. */
1224
1225 switch (blk->header.typeflag)
1226 {
1227 case CHRTYPE:
1228 case BLKTYPE:
1229 strcpy (size,
1230 STRINGIFY_BIGINT (major (st->stat.st_rdev), uintbuf));
1231 strcat (size, ",");
1232 strcat (size,
1233 STRINGIFY_BIGINT (minor (st->stat.st_rdev), uintbuf));
1234 break;
1235
1236 default:
1237 /* st->stat.st_size keeps stored file size */
1238 strcpy (size, STRINGIFY_BIGINT (st->stat.st_size, uintbuf));
1239 break;
1240 }
1241
1242 /* Figure out padding and print the whole line. */
1243
1244 sizelen = strlen (size);
1245 pad = strlen (user) + 1 + strlen (group) + 1 + sizelen;
1246 if (pad > ugswidth)
1247 ugswidth = pad;
1248
1249 fprintf (stdlis, "%s %s/%s %*s %-*s",
1250 modes, user, group, ugswidth - pad + sizelen, size,
1251 datewidth, time_stamp);
1252
1253 fprintf (stdlis, " %s", quotearg (temp_name));
1254
1255 switch (blk->header.typeflag)
1256 {
1257 case SYMTYPE:
1258 fprintf (stdlis, " -> %s\n", quotearg (st->link_name));
1259 break;
1260
1261 case LNKTYPE:
1262 fprintf (stdlis, _(" link to %s\n"), quotearg (st->link_name));
1263 break;
1264
1265 default:
1266 {
1267 char type_string[2];
1268 type_string[0] = blk->header.typeflag;
1269 type_string[1] = '\0';
1270 fprintf (stdlis, _(" unknown file type %s\n"),
1271 quote (type_string));
1272 }
1273 break;
1274
1275 case AREGTYPE:
1276 case REGTYPE:
1277 case GNUTYPE_SPARSE:
1278 case CHRTYPE:
1279 case BLKTYPE:
1280 case DIRTYPE:
1281 case FIFOTYPE:
1282 case CONTTYPE:
1283 case GNUTYPE_DUMPDIR:
1284 putc ('\n', stdlis);
1285 break;
1286
1287 case GNUTYPE_LONGLINK:
1288 fprintf (stdlis, _("--Long Link--\n"));
1289 break;
1290
1291 case GNUTYPE_LONGNAME:
1292 fprintf (stdlis, _("--Long Name--\n"));
1293 break;
1294
1295 case GNUTYPE_VOLHDR:
1296 fprintf (stdlis, _("--Volume Header--\n"));
1297 break;
1298
1299 case GNUTYPE_MULTIVOL:
1300 strcpy (size,
1301 STRINGIFY_BIGINT
1302 (UINTMAX_FROM_HEADER (blk->oldgnu_header.offset),
1303 uintbuf));
1304 fprintf (stdlis, _("--Continued at byte %s--\n"), size);
1305 break;
1306 }
1307 }
1308 fflush (stdlis);
1309 xattrs_print (st);
1310 }
1311
1312
1313 static void
1314 print_volume_label (void)
1315 {
1316 struct tar_stat_info vstat;
1317 union block vblk;
1318 enum archive_format dummy;
1319
1320 memset (&vblk, 0, sizeof (vblk));
1321 vblk.header.typeflag = GNUTYPE_VOLHDR;
1322 if (recent_global_header)
1323 memcpy (vblk.header.mtime, recent_global_header->header.mtime,
1324 sizeof vblk.header.mtime);
1325 tar_stat_init (&vstat);
1326 assign_string (&vstat.file_name, ".");
1327 decode_header (&vblk, &vstat, &dummy, 0);
1328 assign_string (&vstat.file_name, volume_label);
1329 simple_print_header (&vstat, &vblk, 0);
1330 tar_stat_destroy (&vstat);
1331 }
1332
1333 void
1334 print_header (struct tar_stat_info *st, union block *blk,
1335 off_t block_ordinal)
1336 {
1337 if (current_format == POSIX_FORMAT && !volume_label_printed && volume_label)
1338 {
1339 print_volume_label ();
1340 volume_label_printed = true;
1341 }
1342
1343 simple_print_header (st, blk, block_ordinal);
1344 }
1345
1346 /* Print a similar line when we make a directory automatically. */
1347 void
1348 print_for_mkdir (char *dirname, int length, mode_t mode)
1349 {
1350 char modes[11];
1351
1352 if (verbose_option > 1)
1353 {
1354 /* File type and modes. */
1355
1356 modes[0] = 'd';
1357 pax_decode_mode (mode, modes + 1);
1358
1359 if (block_number_option)
1360 {
1361 char buf[UINTMAX_STRSIZE_BOUND];
1362 fprintf (stdlis, _("block %s: "),
1363 STRINGIFY_BIGINT (current_block_ordinal (), buf));
1364 }
1365
1366 fprintf (stdlis, "%s %*s %s\n", modes, ugswidth + 1 + datewidth,
1367 _("Creating directory:"), quotearg (dirname));
1368 }
1369 }
1370
1371 /* Skip over SIZE bytes of data in blocks in the archive. */
1372 void
1373 skip_file (off_t size)
1374 {
1375 union block *x;
1376
1377 /* FIXME: Make sure mv_begin_read is always called before it */
1378
1379 if (seekable_archive)
1380 {
1381 off_t nblk = seek_archive (size);
1382 if (nblk >= 0)
1383 size -= nblk * BLOCKSIZE;
1384 else
1385 seekable_archive = false;
1386 }
1387
1388 mv_size_left (size);
1389
1390 while (size > 0)
1391 {
1392 x = find_next_block ();
1393 if (! x)
1394 FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
1395
1396 set_next_block_after (x);
1397 size -= BLOCKSIZE;
1398 mv_size_left (size);
1399 }
1400 }
1401
1402 /* Skip the current member in the archive.
1403 NOTE: Current header must be decoded before calling this function. */
1404 void
1405 skip_member (void)
1406 {
1407 if (!current_stat_info.skipped)
1408 {
1409 char save_typeflag = current_header->header.typeflag;
1410 set_next_block_after (current_header);
1411
1412 mv_begin_read (&current_stat_info);
1413
1414 if (current_stat_info.is_sparse)
1415 sparse_skip_file (&current_stat_info);
1416 else if (save_typeflag != DIRTYPE)
1417 skip_file (current_stat_info.stat.st_size);
1418
1419 mv_end ();
1420 }
1421 }
1422
1423 void
1424 test_archive_label (void)
1425 {
1426 base64_init ();
1427 name_gather ();
1428
1429 open_archive (ACCESS_READ);
1430 if (read_header (&current_header, &current_stat_info, read_header_auto)
1431 == HEADER_SUCCESS)
1432 {
1433 decode_header (current_header,
1434 &current_stat_info, &current_format, 0);
1435 if (current_header->header.typeflag == GNUTYPE_VOLHDR)
1436 assign_string (&volume_label, current_header->header.name);
1437
1438 if (volume_label)
1439 {
1440 if (verbose_option)
1441 print_volume_label ();
1442 if (!name_match (volume_label) && multi_volume_option)
1443 {
1444 char *s = drop_volume_label_suffix (volume_label);
1445 name_match (s);
1446 free (s);
1447 }
1448 }
1449 }
1450 close_archive ();
1451 label_notfound ();
1452 }
This page took 0.096487 seconds and 3 git commands to generate.