X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Flist.c;h=cd63064df05b23c44b8d9c17319271cce1b6005e;hb=15a607fc11d8563fe471924fb6e718ceb9adfce4;hp=d23002beaa64cf6c49badb1bd87c9ba389980b93;hpb=cc8628df0c1b0e6e4acb1b1e797bde9bfb38094e;p=chaz%2Ftar diff --git a/src/list.c b/src/list.c index d23002b..cd63064 100644 --- a/src/list.c +++ b/src/list.c @@ -20,7 +20,7 @@ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Define to non-zero for forcing old ctime format instead of ISO format. */ -#undef USE_OLD_CTIME +#undef USE_OLD_CTIME #include "system.h" #include @@ -76,7 +76,7 @@ read_and (void (*do_something) (void)) do { prev_status = status; - destroy_stat (¤t_stat_info); + tar_stat_destroy (¤t_stat_info); xheader_destroy (&extended_header); status = read_header (false); @@ -130,10 +130,20 @@ read_and (void (*do_something) (void)) } set_next_block_after (current_header); + + if (!ignore_zeros_option) + { + char buf[UINTMAX_STRSIZE_BOUND]; + + status = read_header (false); + if (status == HEADER_ZERO_BLOCK) + break; + WARN ((0, 0, _("A lone zero block at %s"), + STRINGIFY_BIGINT (current_block_ordinal (), buf))); + break; + } status = prev_status; - if (ignore_zeros_option) - continue; - break; + continue; case HEADER_END_OF_FILE: if (block_number_option) @@ -185,7 +195,7 @@ list_archive (void) decode_header (current_header, ¤t_stat_info, ¤t_format, 0); if (verbose_option) - print_header (-1); + print_header (¤t_stat_info, -1); if (incremental_option && current_header->header.typeflag == GNUTYPE_DUMPDIR) { @@ -386,9 +396,13 @@ read_header (bool raw_extended_headers) *bp = '\0'; } - else if (header->header.typeflag == XHDTYPE - || header->header.typeflag == XGLTYPE) + else if (header->header.typeflag == XHDTYPE) xheader_read (header, OFF_FROM_HEADER (header->header.size)); + else if (header->header.typeflag == XGLTYPE) + { + xheader_read (header, OFF_FROM_HEADER (header->header.size)); + xheader_decode_global (); + } /* Loop! */ @@ -489,8 +503,10 @@ decode_header (union block *header, struct tar_stat_info *stat_info, && ISOCTAL (header->star_header.ctime[0]) && header->star_header.ctime[11] == ' ') format = STAR_FORMAT; - else + else if (extended_header.size) format = POSIX_FORMAT; + else + format = USTAR_FORMAT; } else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0) format = OLDGNU_FORMAT; @@ -548,7 +564,8 @@ decode_header (union block *header, struct tar_stat_info *stat_info, { case BLKTYPE: case CHRTYPE: - stat_info->stat.st_rdev = makedev (stat_info->devmajor, stat_info->devminor); + stat_info->stat.st_rdev = makedev (stat_info->devmajor, + stat_info->devminor); break; default: @@ -556,8 +573,14 @@ decode_header (union block *header, struct tar_stat_info *stat_info, } } - if (extended_header.size) - xheader_decode (stat_info); + stat_info->archive_file_size = stat_info->stat.st_size; + xheader_decode (stat_info); + + if (sparse_member_p (stat_info)) + { + sparse_fixup_header (stat_info); + stat_info->is_sparse = true; + } } /* Convert buffer at WHERE0 of size DIGS from external format to @@ -884,7 +907,7 @@ tartime (time_t t) #else /* Use ISO 8610 format. See: http://www.cl.cam.ac.uk/~mgk25/iso-time.html */ - struct tm *tm = localtime (&t); + struct tm *tm = utc_option ? gmtime (&t) : localtime (&t); if (tm) { sprintf (buffer, "%04ld-%02d-%02d %02d:%02d:%02d", @@ -933,11 +956,11 @@ static int ugswidth = UGSWIDTH; /* maximum width encountered so far */ #endif void -print_header (off_t block_ordinal) +print_header (struct tar_stat_info *st, off_t block_ordinal) { char modes[11]; char const *time_stamp; - char *temp_name = current_stat_info.orig_file_name ? current_stat_info.orig_file_name : current_stat_info.file_name; + char *temp_name = st->orig_file_name ? st->orig_file_name : st->file_name; /* These hold formatted ints. */ char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND]; @@ -1021,17 +1044,17 @@ print_header (off_t block_ordinal) break; } - decode_mode (current_stat_info.stat.st_mode, modes + 1); + decode_mode (st->stat.st_mode, modes + 1); /* Time stamp. */ - time_stamp = tartime (current_stat_info.stat.st_mtime); + time_stamp = tartime (st->stat.st_mtime); /* User and group names. */ - if (current_stat_info.uname && current_format != V7_FORMAT + if (st->uname && current_format != V7_FORMAT && !numeric_owner_option) - user = current_stat_info.uname; + user = st->uname; else { /* Try parsing it as an unsigned integer first, and as a @@ -1051,9 +1074,9 @@ print_header (off_t block_ordinal) } } - if (current_stat_info.gname && current_format != V7_FORMAT + if (st->gname && current_format != V7_FORMAT && !numeric_owner_option) - group = current_stat_info.gname; + group = st->gname; else { /* Try parsing it as an unsigned integer first, and as a @@ -1080,20 +1103,15 @@ print_header (off_t block_ordinal) case CHRTYPE: case BLKTYPE: strcpy (size, - STRINGIFY_BIGINT (major (current_stat_info.stat.st_rdev), uintbuf)); + STRINGIFY_BIGINT (major (st->stat.st_rdev), uintbuf)); strcat (size, ","); strcat (size, - STRINGIFY_BIGINT (minor (current_stat_info.stat.st_rdev), uintbuf)); - break; - case GNUTYPE_SPARSE: - strcpy (size, - STRINGIFY_BIGINT - (UINTMAX_FROM_HEADER (current_header - ->oldgnu_header.realsize), - uintbuf)); + STRINGIFY_BIGINT (minor (st->stat.st_rdev), uintbuf)); break; + default: - strcpy (size, STRINGIFY_BIGINT (current_stat_info.stat.st_size, uintbuf)); + /* st->stat.st_size keeps stored file size */ + strcpy (size, STRINGIFY_BIGINT (st->stat.st_size, uintbuf)); break; } @@ -1111,11 +1129,11 @@ print_header (off_t block_ordinal) switch (current_header->header.typeflag) { case SYMTYPE: - fprintf (stdlis, " -> %s\n", quotearg (current_stat_info.link_name)); + fprintf (stdlis, " -> %s\n", quotearg (st->link_name)); break; case LNKTYPE: - fprintf (stdlis, _(" link to %s\n"), quotearg (current_stat_info.link_name)); + fprintf (stdlis, _(" link to %s\n"), quotearg (st->link_name)); break; default: @@ -1225,20 +1243,10 @@ skip_member (void) char save_typeflag = current_header->header.typeflag; set_next_block_after (current_header); - if (current_format == OLDGNU_FORMAT - && current_header->oldgnu_header.isextended) - { - union block *exhdr; - do - { - exhdr = find_next_block (); - if (!exhdr) - FATAL_ERROR ((0, 0, _("Unexpected EOF in archive"))); - set_next_block_after (exhdr); - } - while (exhdr->sparse_header.isextended); - } + assign_string (&save_name, current_stat_info.file_name); - if (save_typeflag != DIRTYPE) + if (sparse_member_p (¤t_stat_info)) + sparse_skip_file (¤t_stat_info); + else if (save_typeflag != DIRTYPE) skip_file (current_stat_info.stat.st_size); }