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