X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Flist.c;h=fdc8fa9975b14cb7b81e4d0e72fa9323f4076d18;hb=d46025b23c5bbe31902ba4e902312ce8fe05ed63;hp=13140eb5873472734d80e134f86b81157fd112ac;hpb=096bc2bffd857a690a9364043c33109eee0a53b4;p=chaz%2Ftar diff --git a/src/list.c b/src/list.c index 13140eb..fdc8fa9 100644 --- a/src/list.c +++ b/src/list.c @@ -73,13 +73,17 @@ read_and (void (*do_something) (void)) name_gather (); open_archive (ACCESS_READ); - while (1) + do { prev_status = status; - status = read_header (0); + tar_stat_destroy (¤t_stat_info); + xheader_destroy (&extended_header); + + status = read_header (false); switch (status) { case HEADER_STILL_UNREAD: + case HEADER_SUCCESS_EXTENDED: abort (); case HEADER_SUCCESS: @@ -112,7 +116,7 @@ read_and (void (*do_something) (void)) skip_member (); continue; } - } + } (*do_something) (); continue; @@ -126,10 +130,19 @@ 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))); + } status = prev_status; - if (ignore_zeros_option) - continue; - break; + continue; case HEADER_END_OF_FILE: if (block_number_option) @@ -159,11 +172,15 @@ read_and (void (*do_something) (void)) case HEADER_FAILURE: /* We are in the middle of a cascade of errors. */ break; + + case HEADER_SUCCESS_EXTENDED: + abort (); } continue; } break; } + while (!all_names_found (¤t_stat_info)); close_archive (); names_notfound (); /* print names not found */ @@ -175,12 +192,9 @@ list_archive (void) { /* Print the header block. */ + decode_header (current_header, ¤t_stat_info, ¤t_format, 0); if (verbose_option) - { - if (verbose_option > 1) - decode_header (current_header, ¤t_stat_info, ¤t_format, 0); - print_header (-1); - } + print_header (¤t_stat_info, -1); if (incremental_option && current_header->header.typeflag == GNUTYPE_DUMPDIR) { @@ -319,72 +333,72 @@ read_header (bool raw_extended_headers) /* Good block. Decode file size and return. */ - if (header->header.typeflag == XHDTYPE - || header->header.typeflag == XGLTYPE) - { - xheader_read (header, OFF_FROM_HEADER (header->header.size)); - continue; - } - if (header->header.typeflag == LNKTYPE) current_stat_info.stat.st_size = 0; /* links 0 size on tape */ else current_stat_info.stat.st_size = OFF_FROM_HEADER (header->header.size); if (header->header.typeflag == GNUTYPE_LONGNAME - || header->header.typeflag == GNUTYPE_LONGLINK) + || header->header.typeflag == GNUTYPE_LONGLINK + || header->header.typeflag == XHDTYPE + || header->header.typeflag == XGLTYPE) { if (raw_extended_headers) return HEADER_SUCCESS_EXTENDED; - else + else if (header->header.typeflag == GNUTYPE_LONGNAME + || header->header.typeflag == GNUTYPE_LONGLINK) { size_t name_size = current_stat_info.stat.st_size; size = name_size - name_size % BLOCKSIZE + 2 * BLOCKSIZE; - if (name_size != current_stat_info.stat.st_size || size < name_size) + if (name_size != current_stat_info.stat.st_size + || size < name_size) xalloc_die (); - } - - header_copy = xmalloc (size + 1); - if (header->header.typeflag == GNUTYPE_LONGNAME) - { - if (next_long_name) - free (next_long_name); - next_long_name = header_copy; - next_long_name_blocks = size / BLOCKSIZE; - } - else - { - if (next_long_link) - free (next_long_link); - next_long_link = header_copy; - next_long_link_blocks = size / BLOCKSIZE; - } - - set_next_block_after (header); - *header_copy = *header; - bp = header_copy->buffer + BLOCKSIZE; - - for (size -= BLOCKSIZE; size > 0; size -= written) - { - data_block = find_next_block (); - if (! data_block) + header_copy = xmalloc (size + 1); + + if (header->header.typeflag == GNUTYPE_LONGNAME) { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - break; + if (next_long_name) + free (next_long_name); + next_long_name = header_copy; + next_long_name_blocks = size / BLOCKSIZE; } - written = available_space_after (data_block); - if (written > size) - written = size; - - memcpy (bp, data_block->buffer, written); - bp += written; - set_next_block_after ((union block *) - (data_block->buffer + written - 1)); - } + else + { + if (next_long_link) + free (next_long_link); + next_long_link = header_copy; + next_long_link_blocks = size / BLOCKSIZE; + } + + set_next_block_after (header); + *header_copy = *header; + bp = header_copy->buffer + BLOCKSIZE; - *bp = '\0'; + for (size -= BLOCKSIZE; size > 0; size -= written) + { + data_block = find_next_block (); + if (! data_block) + { + ERROR ((0, 0, _("Unexpected EOF in archive"))); + break; + } + written = available_space_after (data_block); + if (written > size) + written = size; + + memcpy (bp, data_block->buffer, written); + bp += written; + set_next_block_after ((union block *) + (data_block->buffer + written - 1)); + } + *bp = '\0'; + } + else if (header->header.typeflag == XHDTYPE + || header->header.typeflag == XGLTYPE) + xheader_read (header, OFF_FROM_HEADER (header->header.size)); + /* Loop! */ } @@ -484,8 +498,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; @@ -500,6 +516,9 @@ decode_header (union block *header, struct tar_stat_info *stat_info, stat_info->devmajor = MAJOR_FROM_HEADER (header->header.devmajor); stat_info->devminor = MINOR_FROM_HEADER (header->header.devminor); + stat_info->stat.st_atime = start_time; + stat_info->stat.st_ctime = start_time; + if (format == OLDGNU_FORMAT && incremental_option) { stat_info->stat.st_atime = TIME_FROM_HEADER (header->oldgnu_header.atime); @@ -548,8 +567,8 @@ decode_header (union block *header, struct tar_stat_info *stat_info, } } - if (extended_header.nblocks) - xheader_decode (stat_info); + current_stat_info.archive_file_size = current_stat_info.stat.st_size; + xheader_decode (stat_info); } /* Convert buffer at WHERE0 of size DIGS from external format to @@ -925,11 +944,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]; @@ -1013,17 +1032,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_header->header.uname && current_format != V7_FORMAT + if (st->uname && current_format != V7_FORMAT && !numeric_owner_option) - user = current_header->header.uname; + user = st->uname; else { /* Try parsing it as an unsigned integer first, and as a @@ -1043,9 +1062,9 @@ print_header (off_t block_ordinal) } } - if (*current_header->header.gname && current_format != V7_FORMAT + if (st->gname && current_format != V7_FORMAT && !numeric_owner_option) - group = current_header->header.gname; + group = st->gname; else { /* Try parsing it as an unsigned integer first, and as a @@ -1072,10 +1091,10 @@ 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)); + STRINGIFY_BIGINT (minor (st->stat.st_rdev), uintbuf)); break; case GNUTYPE_SPARSE: strcpy (size, @@ -1085,7 +1104,8 @@ print_header (off_t block_ordinal) 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->archive_file_size, uintbuf)); break; } @@ -1103,11 +1123,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: