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.
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
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.
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. */
19 /* Define to non-zero for forcing old ctime() instead of isotime(). */
29 union block
*current_header
; /* points to current archive header */
30 struct stat current_stat
; /* stat struct corresponding */
31 enum archive_format current_format
; /* recognized format */
33 static uintmax_t from_chars
PARAMS ((const char *, size_t, const char *,
34 uintmax_t, uintmax_t));
36 /* Table of base 64 digit values indexed by unsigned chars.
37 The value is 64 for unsigned chars that are not base 64 digits. */
38 static char base64_map
[1 + (unsigned char) -1];
44 memset (base64_map
, 64, sizeof base64_map
);
45 for (i
= 0; i
< 64; i
++)
46 base64_map
[(int) base_64_digits
[i
]] = i
;
49 /*-----------------------------------.
50 | Main loop for reading an archive. |
51 `-----------------------------------*/
54 read_and (void (*do_something
) ())
56 enum read_header status
= HEADER_STILL_UNREAD
;
57 enum read_header prev_status
;
61 open_archive (ACCESS_READ
);
66 status
= read_header ();
69 case HEADER_STILL_UNREAD
:
74 /* Valid header. We should decode next field (mode) first.
75 Ensure incoming names are null terminated. */
77 /* FIXME: This is a quick kludge before 1.12 goes out. */
79 = TIME_FROM_CHARS (current_header
->header
.mtime
);
81 if (!name_match (current_file_name
)
82 || current_stat
.st_mtime
< newer_mtime_option
83 || excluded_name (current_file_name
))
87 if (current_header
->header
.typeflag
== GNUTYPE_VOLHDR
88 || current_header
->header
.typeflag
== GNUTYPE_MULTIVOL
89 || current_header
->header
.typeflag
== GNUTYPE_NAMES
)
94 if (show_omitted_dirs_option
95 && current_header
->header
.typeflag
== DIRTYPE
)
96 WARN ((0, 0, _("Omitting %s"), current_file_name
));
98 /* Skip past it in the archive. */
100 save_typeflag
= current_header
->header
.typeflag
;
101 set_next_block_after (current_header
);
102 if (current_header
->oldgnu_header
.isextended
)
103 skip_extended_headers ();
105 /* Skip to the next header on the archive. */
107 if (save_typeflag
!= DIRTYPE
)
108 skip_file (current_stat
.st_size
);
115 case HEADER_ZERO_BLOCK
:
116 if (block_number_option
)
118 char buf
[UINTMAX_STRSIZE_BOUND
];
119 fprintf (stdlis
, _("block %s: ** Block of NULs **\n"),
120 STRINGIFY_BIGINT (current_block_ordinal (), buf
));
123 set_next_block_after (current_header
);
124 status
= prev_status
;
125 if (ignore_zeros_option
)
129 case HEADER_END_OF_FILE
:
130 if (block_number_option
)
132 char buf
[UINTMAX_STRSIZE_BOUND
];
133 fprintf (stdlis
, _("block %s: ** End of File **\n"),
134 STRINGIFY_BIGINT (current_block_ordinal (), buf
));
139 /* If the previous header was good, tell them that we are
140 skipping bad ones. */
141 set_next_block_after (current_header
);
144 case HEADER_STILL_UNREAD
:
145 WARN ((0, 0, _("Hmm, this doesn't look like a tar archive")));
148 case HEADER_ZERO_BLOCK
:
150 WARN ((0, 0, _("Skipping to next file header")));
153 case HEADER_END_OF_FILE
:
155 /* We are in the middle of a cascade of errors. */
163 apply_delayed_set_stat ();
165 names_notfound (); /* print names not found */
168 /*---------------------------------------------.
169 | Print a header block, based on tar options. |
170 `---------------------------------------------*/
175 /* Print the header block. */
179 if (verbose_option
> 1)
180 decode_header (current_header
, ¤t_stat
, ¤t_format
, 0);
184 if (incremental_option
&& current_header
->header
.typeflag
== GNUTYPE_DUMPDIR
)
187 size_t written
, check
;
188 union block
*data_block
;
190 set_next_block_after (current_header
);
191 if (multi_volume_option
)
193 assign_string (&save_name
, current_file_name
);
194 save_totsize
= current_stat
.st_size
;
196 for (size
= current_stat
.st_size
; size
> 0; size
-= written
)
198 if (multi_volume_option
)
199 save_sizeleft
= size
;
200 data_block
= find_next_block ();
203 ERROR ((0, 0, _("EOF in archive file")));
204 break; /* FIXME: What happens, then? */
206 written
= available_space_after (data_block
);
209 errno
= 0; /* FIXME: errno should be read-only */
210 check
= fwrite (data_block
->buffer
, sizeof (char), written
, stdlis
);
211 set_next_block_after ((union block
*)
212 (data_block
->buffer
+ written
- 1));
213 if (check
!= written
)
215 ERROR ((0, errno
, _("Only wrote %lu of %lu bytes to file %s"),
216 (unsigned long) check
,
217 (unsigned long) written
, current_file_name
));
218 skip_file (size
- written
);
222 if (multi_volume_option
)
223 assign_string (&save_name
, NULL
);
224 fputc ('\n', stdlis
);
230 /* Skip past the header in the archive, and past any extended headers. */
232 set_next_block_after (current_header
);
233 if (current_header
->oldgnu_header
.isextended
)
234 skip_extended_headers ();
236 if (multi_volume_option
)
237 assign_string (&save_name
, current_file_name
);
239 /* Skip to the next header on the archive. */
241 skip_file (current_stat
.st_size
);
243 if (multi_volume_option
)
244 assign_string (&save_name
, NULL
);
247 /*-----------------------------------------------------------------------.
248 | Read a block that's supposed to be a header block. Return its address |
249 | in "current_header", and if it is good, the file's size in |
250 | current_stat.st_size. |
252 | Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a |
253 | block full of zeros (EOF marker). |
255 | You must always set_next_block_after(current_header) to skip past the |
256 | header which this routine reads. |
257 `-----------------------------------------------------------------------*/
259 /* The standard BSD tar sources create the checksum by adding up the
260 bytes in the header as type char. I think the type char was unsigned
261 on the PDP-11, but it's signed on the Next and Sun. It looks like the
262 sources to BSD tar were never changed to compute the checksum
263 currectly, so both the Sun and Next add the bytes of the header as
264 signed chars. This doesn't cause a problem until you get a file with
265 a name containing characters with the high bit set. So read_header
266 computes two checksums -- signed and unsigned. */
272 int unsigned_sum
; /* the POSIX one :-) */
273 int signed_sum
; /* the Sun one :-( */
275 uintmax_t parsed_sum
;
280 union block
*data_block
;
281 size_t size
, written
;
282 static char *next_long_name
, *next_long_link
;
286 header
= find_next_block ();
287 current_header
= header
;
289 return HEADER_END_OF_FILE
;
294 for (i
= sizeof (*header
); i
-- != 0;)
296 unsigned_sum
+= (unsigned char) *p
;
297 signed_sum
+= signed_char (*p
++);
300 if (unsigned_sum
== 0)
301 return HEADER_ZERO_BLOCK
;
303 /* Adjust checksum to count the "chksum" field as blanks. */
305 for (i
= sizeof (header
->header
.chksum
); i
-- != 0;)
307 unsigned_sum
-= (unsigned char) header
->header
.chksum
[i
];
308 signed_sum
-= signed_char (header
->header
.chksum
[i
]);
310 unsigned_sum
+= ' ' * sizeof header
->header
.chksum
;
311 signed_sum
+= ' ' * sizeof header
->header
.chksum
;
313 parsed_sum
= from_chars (header
->header
.chksum
,
314 sizeof header
->header
.chksum
,
315 (char *) 0, (uintmax_t) 0,
316 (uintmax_t) TYPE_MAXIMUM (int));
317 if (parsed_sum
== (uintmax_t) -1)
318 return HEADER_FAILURE
;
320 recorded_sum
= parsed_sum
;
322 if (unsigned_sum
!= recorded_sum
&& signed_sum
!= recorded_sum
)
323 return HEADER_FAILURE
;
325 /* Good block. Decode file size and return. */
327 if (header
->header
.typeflag
== LNKTYPE
)
328 current_stat
.st_size
= 0; /* links 0 size on tape */
330 current_stat
.st_size
= OFF_FROM_CHARS (header
->header
.size
);
332 if (header
->header
.typeflag
== GNUTYPE_LONGNAME
333 || header
->header
.typeflag
== GNUTYPE_LONGLINK
)
335 longp
= ((header
->header
.typeflag
== GNUTYPE_LONGNAME
)
339 set_next_block_after (header
);
342 size
= current_stat
.st_size
;
343 if (size
!= current_stat
.st_size
)
344 FATAL_ERROR ((0, 0, _("Memory exhausted")));
345 bp
= *longp
= (char *) xmalloc (size
);
347 for (; size
> 0; size
-= written
)
349 data_block
= find_next_block ();
350 if (data_block
== NULL
)
352 ERROR ((0, 0, _("Unexpected EOF on archive file")));
355 written
= available_space_after (data_block
);
359 memcpy (bp
, data_block
->buffer
, written
);
361 set_next_block_after ((union block
*)
362 (data_block
->buffer
+ written
- 1));
371 struct posix_header
*h
= ¤t_header
->header
;
372 char namebuf
[sizeof h
->prefix
+ 1 + NAME_FIELD_SIZE
+ 1];
374 name
= next_long_name
;
377 /* Accept file names as specified by POSIX.1-1996
379 int posix_header
= strcmp (h
->magic
, TMAGIC
) == 0;
382 if (posix_header
&& h
->prefix
[0])
384 memcpy (np
, h
->prefix
, sizeof h
->prefix
);
385 np
[sizeof h
->prefix
] = '\0';
389 memcpy (np
, h
->name
, sizeof h
->name
);
390 np
[sizeof h
->name
] = '\0';
393 assign_string (¤t_file_name
, name
);
396 free (next_long_name
);
400 name
= next_long_link
;
403 memcpy (namebuf
, h
->linkname
, sizeof h
->linkname
);
404 namebuf
[sizeof h
->linkname
] = '\0';
407 assign_string (¤t_link_name
, name
);
410 free (next_long_link
);
414 return HEADER_SUCCESS
;
419 /*-------------------------------------------------------------------------.
420 | Decode things from a file HEADER block into STAT_INFO, also setting |
421 | *FORMAT_POINTER depending on the header block format. If DO_USER_GROUP, |
422 | decode the user/group information (this is useful for extraction, but |
423 | waste time when merely listing). |
425 | read_header() has already decoded the checksum and length, so we don't. |
427 | This routine should *not* be called twice for the same block, since the |
428 | two calls might use different DO_USER_GROUP values and thus might end up |
429 | with different uid/gid for the two calls. If anybody wants the uid/gid |
430 | they should decode it first, and other callers should decode it without |
431 | uid/gid before calling a routine, e.g. print_header, that assumes |
433 `-------------------------------------------------------------------------*/
436 decode_header (union block
*header
, struct stat
*stat_info
,
437 enum archive_format
*format_pointer
, int do_user_group
)
439 enum archive_format format
;
441 if (strcmp (header
->header
.magic
, TMAGIC
) == 0)
442 format
= POSIX_FORMAT
;
443 else if (strcmp (header
->header
.magic
, OLDGNU_MAGIC
) == 0)
444 format
= OLDGNU_FORMAT
;
447 *format_pointer
= format
;
449 stat_info
->st_mode
= MODE_FROM_CHARS (header
->header
.mode
);
450 stat_info
->st_mtime
= TIME_FROM_CHARS (header
->header
.mtime
);
452 if (format
== OLDGNU_FORMAT
&& incremental_option
)
454 stat_info
->st_atime
= TIME_FROM_CHARS (header
->oldgnu_header
.atime
);
455 stat_info
->st_ctime
= TIME_FROM_CHARS (header
->oldgnu_header
.ctime
);
458 if (format
== V7_FORMAT
)
460 stat_info
->st_uid
= UID_FROM_CHARS (header
->header
.uid
);
461 stat_info
->st_gid
= GID_FROM_CHARS (header
->header
.gid
);
462 stat_info
->st_rdev
= 0;
468 /* FIXME: Decide if this should somewhat depend on -p. */
470 if (numeric_owner_option
471 || !*header
->header
.uname
472 || !uname_to_uid (header
->header
.uname
, &stat_info
->st_uid
))
473 stat_info
->st_uid
= UID_FROM_CHARS (header
->header
.uid
);
475 if (numeric_owner_option
476 || !*header
->header
.gname
477 || !gname_to_gid (header
->header
.gname
, &stat_info
->st_gid
))
478 stat_info
->st_gid
= GID_FROM_CHARS (header
->header
.gid
);
480 switch (header
->header
.typeflag
)
484 = makedev (MAJOR_FROM_CHARS (header
->header
.devmajor
),
485 MINOR_FROM_CHARS (header
->header
.devminor
));
490 = makedev (MAJOR_FROM_CHARS (header
->header
.devmajor
),
491 MINOR_FROM_CHARS (header
->header
.devminor
));
495 stat_info
->st_rdev
= 0;
500 /*------------------------------------------------------------------------.
501 | Convert buffer at WHERE0 of size DIGS from external format to uintmax_t.|
502 | The data is of type TYPE. The buffer must represent a value in the |
503 | range -MINUS_MINVAL through MAXVAL. |
504 `------------------------------------------------------------------------*/
507 from_chars (char const *where0
, size_t digs
, char const *type
,
508 uintmax_t minus_minval
, uintmax_t maxval
)
511 char const *where
= where0
;
512 char const *lim
= where
+ digs
;
515 /* Accommodate buggy tar of unknown vintage, which outputs leading
516 NUL if the previous field overflows. */
519 /* Accommodate older tars, which output leading spaces. */
526 _("Blanks in header where numeric %s value expected"),
530 if (!ISSPACE ((unsigned char) *where
))
536 if (ISODIGIT (*where
))
540 if (value
<< LG_8
>> LG_8
!= value
)
542 value
= (value
<< LG_8
) | (*where
++ - '0');
544 while (where
!= lim
&& ISODIGIT (*where
));
546 /* Parse the output of older tars, which output negative values
547 in two's complement octal. This method works only if the
548 type has the same number of bits as it did on the host that
549 created the tar file, but that's the best we can do. */
550 if (maxval
< value
&& value
- maxval
<= minus_minval
)
552 value
= minus_minval
- (value
- maxval
);
556 else if (*where
== '-' || *where
== '+')
559 negative
= *where
++ == '-';
561 && (dig
= base64_map
[(unsigned char) *where
]) < 64)
563 if (value
<< LG_64
>> LG_64
!= value
)
565 value
= (value
<< LG_64
) | dig
;
570 if (where
!= lim
&& *where
&& !ISSPACE ((unsigned char) *where
))
574 char buf
[1000]; /* Big enough to represent any header. */
575 static struct quoting_options
*o
;
579 o
= clone_quoting_options ((struct quoting_options
*) 0);
580 set_quoting_style (o
, c_quoting_style
);
583 while (where0
!= lim
&& ! lim
[-1])
585 quotearg_buffer (buf
, sizeof buf
, where0
, lim
- where
, o
);
587 _("Header contains `%.*s' where numeric %s value expected"),
588 (int) sizeof buf
, buf
, type
));
594 if (value
<= (negative
? minus_minval
: maxval
))
595 return negative
? -value
: value
;
599 ERROR ((0, 0, _("Numeric value `%.*s' is out of range for %s"),
600 (int) digs
, where0
, type
));
605 gid_from_chars (const char *p
, size_t s
)
607 return from_chars (p
, s
, "gid_t",
608 - (uintmax_t) TYPE_MINIMUM (gid_t
),
609 (uintmax_t) TYPE_MAXIMUM (gid_t
));
613 major_from_chars (const char *p
, size_t s
)
615 return from_chars (p
, s
, "major_t",
616 - (uintmax_t) TYPE_MINIMUM (major_t
),
617 (uintmax_t) TYPE_MAXIMUM (major_t
));
621 minor_from_chars (const char *p
, size_t s
)
623 return from_chars (p
, s
, "minor_t",
624 - (uintmax_t) TYPE_MINIMUM (minor_t
),
625 (uintmax_t) TYPE_MAXIMUM (minor_t
));
629 mode_from_chars (const char *p
, size_t s
)
631 /* Do not complain about unrecognized mode bits. */
632 unsigned u
= from_chars (p
, s
, "mode_t",
633 - (uintmax_t) TYPE_MINIMUM (mode_t
),
634 TYPE_MAXIMUM (uintmax_t));
635 return ((u
& TSUID
? S_ISUID
: 0)
636 | (u
& TSGID
? S_ISGID
: 0)
637 | (u
& TSVTX
? S_ISVTX
: 0)
638 | (u
& TUREAD
? S_IRUSR
: 0)
639 | (u
& TUWRITE
? S_IWUSR
: 0)
640 | (u
& TUEXEC
? S_IXUSR
: 0)
641 | (u
& TGREAD
? S_IRGRP
: 0)
642 | (u
& TGWRITE
? S_IWGRP
: 0)
643 | (u
& TGEXEC
? S_IXGRP
: 0)
644 | (u
& TOREAD
? S_IROTH
: 0)
645 | (u
& TOWRITE
? S_IWOTH
: 0)
646 | (u
& TOEXEC
? S_IXOTH
: 0));
650 off_from_chars (const char *p
, size_t s
)
652 return from_chars (p
, s
, "off_t",
653 - (uintmax_t) TYPE_MINIMUM (off_t
),
654 (uintmax_t) TYPE_MAXIMUM (off_t
));
658 size_from_chars (const char *p
, size_t s
)
660 return from_chars (p
, s
, "size_t", (uintmax_t) 0,
661 (uintmax_t) TYPE_MAXIMUM (size_t));
665 time_from_chars (const char *p
, size_t s
)
667 return from_chars (p
, s
, "time_t",
668 - (uintmax_t) TYPE_MINIMUM (time_t),
669 (uintmax_t) TYPE_MAXIMUM (time_t));
673 uid_from_chars (const char *p
, size_t s
)
675 return from_chars (p
, s
, "uid_t", (uintmax_t) 0,
676 (uintmax_t) TYPE_MAXIMUM (uid_t
));
680 uintmax_from_chars (const char *p
, size_t s
)
682 return from_chars (p
, s
, "uintmax_t", (uintmax_t) 0,
683 TYPE_MAXIMUM (uintmax_t));
687 /*----------------------------------------------------------------------.
688 | Format O as a null-terminated decimal string into BUF _backwards_; |
689 | return pointer to start of result. |
690 `----------------------------------------------------------------------*/
692 stringify_uintmax_t_backwards (uintmax_t o
, char *buf
)
696 *--buf
= '0' + (int) (o
% 10);
697 while ((o
/= 10) != 0);
703 /*-------------------------------------------.
704 | Return the time formatted along ISO 8601. |
705 `-------------------------------------------*/
707 /* Also, see http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html. */
710 isotime (const time_t *time
)
712 static char buffer
[INT_STRLEN_BOUND (int) + 16];
713 struct tm
*tm
= localtime (time
);
715 sprintf (buffer
, "%04d-%02d-%02d %02d:%02d:%02d",
716 tm
->tm_year
+ 1900, tm
->tm_mon
+ 1, tm
->tm_mday
,
717 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
719 /* Interpose %s between ?? and - to avoid ANSI C trigraph brain damage. */
720 sprintf (buffer
, "????%s-??%s-?? ??:??:??", "", "");
725 #endif /* not USE_OLD_CTIME */
727 /*-------------------------------------------------------------------------.
728 | Decode MODE from its binary form in a stat structure, and encode it into |
729 | a 9 characters string STRING, terminated with a NUL. |
730 `-------------------------------------------------------------------------*/
733 decode_mode (mode_t mode
, char *string
)
735 *string
++ = mode
& S_IRUSR
? 'r' : '-';
736 *string
++ = mode
& S_IWUSR
? 'w' : '-';
737 *string
++ = (mode
& S_ISUID
738 ? (mode
& S_IXUSR
? 's' : 'S')
739 : (mode
& S_IXUSR
? 'x' : '-'));
740 *string
++ = mode
& S_IRGRP
? 'r' : '-';
741 *string
++ = mode
& S_IWGRP
? 'w' : '-';
742 *string
++ = (mode
& S_ISGID
743 ? (mode
& S_IXGRP
? 's' : 'S')
744 : (mode
& S_IXGRP
? 'x' : '-'));
745 *string
++ = mode
& S_IROTH
? 'r' : '-';
746 *string
++ = mode
& S_IWOTH
? 'w' : '-';
747 *string
++ = (mode
& S_ISVTX
748 ? (mode
& S_IXOTH
? 't' : 'T')
749 : (mode
& S_IXOTH
? 'x' : '-'));
753 /*-------------------------------------------------------------------------.
754 | Actually print it. |
756 | Plain and fancy file header block logging. Non-verbose just prints the |
757 | name, e.g. for "tar t" or "tar x". This should just contain file names, |
758 | so it can be fed back into tar with xargs or the "-T" option. The |
759 | verbose option can give a bunch of info, one line per file. I doubt |
760 | anybody tries to parse its format, or if they do, they shouldn't. Unix |
761 | tar is pretty random here anyway. |
762 `-------------------------------------------------------------------------*/
764 /* FIXME: Note that print_header uses the globals HEAD, HSTAT, and
765 HEAD_STANDARD, which must be set up in advance. Not very clean... */
767 /* UGSWIDTH starts with 18, so with user and group names <= 8 chars, the
768 columns never shift during the listing. */
770 static int ugswidth
= UGSWIDTH
; /* maximum width encountered so far */
772 /* DATEWIDTH is the number of columns taken by the date and time fields. */
774 # define DATEWIDTH 19
776 # define DATEWIDTH 18
783 char const *timestamp
;
784 /* These hold formatted ints. */
785 char uform
[UINTMAX_STRSIZE_BOUND
], gform
[UINTMAX_STRSIZE_BOUND
];
787 char size
[2 * UINTMAX_STRSIZE_BOUND
];
788 /* holds formatted size or major,minor */
789 char uintbuf
[UINTMAX_STRSIZE_BOUND
];
790 time_t longie
; /* to make ctime() call portable */
794 if (block_number_option
)
796 char buf
[UINTMAX_STRSIZE_BOUND
];
797 fprintf (stdlis
, _("block %s: "),
798 STRINGIFY_BIGINT (current_block_ordinal (), buf
));
801 if (verbose_option
<= 1)
803 /* Just the fax, mam. */
805 char *quoted_name
= quote_copy_string (current_file_name
);
809 fprintf (stdlis
, "%s\n", quoted_name
);
813 fprintf (stdlis
, "%s\n", current_file_name
);
817 /* File type and modes. */
820 switch (current_header
->header
.typeflag
)
826 case GNUTYPE_MULTIVOL
:
834 case GNUTYPE_LONGNAME
:
835 case GNUTYPE_LONGLINK
:
836 ERROR ((0, 0, _("Visible longname error")));
844 if (current_file_name
[strlen (current_file_name
) - 1] == '/')
847 case GNUTYPE_DUMPDIR
:
870 decode_mode (current_stat
.st_mode
, modes
+ 1);
874 longie
= current_stat
.st_mtime
;
877 char *ct
= ctime (&longie
);
881 for (ct
+= 16; ct
[4] != '\n'; ct
++)
886 timestamp
= "??? ?? ??:?? ????";
889 timestamp
= isotime (&longie
);
892 /* User and group names. */
894 if (*current_header
->header
.uname
&& current_format
!= V7_FORMAT
895 && !numeric_owner_option
)
896 user
= current_header
->header
.uname
;
898 user
= STRINGIFY_BIGINT (UINTMAX_FROM_CHARS
899 (current_header
->header
.uid
),
902 if (*current_header
->header
.gname
&& current_format
!= V7_FORMAT
903 && !numeric_owner_option
)
904 group
= current_header
->header
.gname
;
906 group
= STRINGIFY_BIGINT (UINTMAX_FROM_CHARS
907 (current_header
->header
.gid
),
910 /* Format the file size or major/minor device numbers. */
912 switch (current_header
->header
.typeflag
)
916 sprintf (size
, "%lu,%lu",
917 (unsigned long) major (current_stat
.st_rdev
),
918 (unsigned long) minor (current_stat
.st_rdev
));
923 (UINTMAX_FROM_CHARS (current_header
->oldgnu_header
.realsize
),
927 strcpy (size
, STRINGIFY_BIGINT (current_stat
.st_size
, uintbuf
));
931 /* Figure out padding and print the whole line. */
933 pad
= strlen (user
) + strlen (group
) + strlen (size
) + 1;
937 fprintf (stdlis
, "%s %s/%s %*s%s %s",
938 modes
, user
, group
, ugswidth
- pad
, "", size
, timestamp
);
940 name
= quote_copy_string (current_file_name
);
943 fprintf (stdlis
, " %s", name
);
947 fprintf (stdlis
, " %s", current_file_name
);
949 switch (current_header
->header
.typeflag
)
952 name
= quote_copy_string (current_link_name
);
955 fprintf (stdlis
, " -> %s\n", name
);
959 fprintf (stdlis
, " -> %s\n", current_link_name
);
963 name
= quote_copy_string (current_link_name
);
966 fprintf (stdlis
, _(" link to %s\n"), name
);
970 fprintf (stdlis
, _(" link to %s\n"), current_link_name
);
974 fprintf (stdlis
, _(" unknown file type `%c'\n"),
975 current_header
->header
.typeflag
);
986 case GNUTYPE_DUMPDIR
:
991 fprintf (stdlis
, _("--Volume Header--\n"));
994 case GNUTYPE_MULTIVOL
:
997 (UINTMAX_FROM_CHARS (current_header
->oldgnu_header
.offset
),
999 fprintf (stdlis
, _("--Continued at byte %s--\n"), size
);
1003 fprintf (stdlis
, _("--Mangled file names--\n"));
1010 /*--------------------------------------------------------------.
1011 | Print a similar line when we make a directory automatically. |
1012 `--------------------------------------------------------------*/
1015 print_for_mkdir (char *pathname
, int length
, mode_t mode
)
1020 if (verbose_option
> 1)
1022 /* File type and modes. */
1025 decode_mode (mode
, modes
+ 1);
1027 if (block_number_option
)
1029 char buf
[UINTMAX_STRSIZE_BOUND
];
1030 fprintf (stdlis
, _("block %s: "),
1031 STRINGIFY_BIGINT (current_block_ordinal (), buf
));
1033 name
= quote_copy_string (pathname
);
1036 fprintf (stdlis
, "%s %*s %.*s\n", modes
, ugswidth
+ DATEWIDTH
,
1037 _("Creating directory:"), length
, name
);
1041 fprintf (stdlis
, "%s %*s %.*s\n", modes
, ugswidth
+ DATEWIDTH
,
1042 _("Creating directory:"), length
, pathname
);
1046 /*--------------------------------------------------------.
1047 | Skip over SIZE bytes of data in blocks in the archive. |
1048 `--------------------------------------------------------*/
1051 skip_file (off_t size
)
1055 if (multi_volume_option
)
1057 save_totsize
= size
;
1058 save_sizeleft
= size
;
1063 x
= find_next_block ();
1065 FATAL_ERROR ((0, 0, _("Unexpected EOF on archive file")));
1067 set_next_block_after (x
);
1069 if (multi_volume_option
)
1070 save_sizeleft
-= BLOCKSIZE
;
1079 skip_extended_headers (void)
1085 exhdr
= find_next_block ();
1087 FATAL_ERROR ((0, 0, _("Unexpected EOF on archive file")));
1088 set_next_block_after (exhdr
);
1090 while (exhdr
->sparse_header
.isextended
);