X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Flist.c;h=0474fb1e5ad40a02cab4f5c76f076ed7e1e9ffc3;hb=340dbf5aabfee4e1e657f8ebf202a2fee1750a63;hp=3394e90d30d8896f7544e233c7a9455aaacccd76;hpb=166b7c7d028c3dbcfded5c834b9bf752d2fb41f0;p=chaz%2Ftar diff --git a/src/list.c b/src/list.c index 3394e90..0474fb1 100644 --- a/src/list.c +++ b/src/list.c @@ -78,7 +78,8 @@ read_and (void (*do_something) (void)) prev_status = status; tar_stat_destroy (¤t_stat_info); - status = read_header (¤t_header, ¤t_stat_info, false); + status = read_header (¤t_header, ¤t_stat_info, + read_header_auto); switch (status) { case HEADER_STILL_UNREAD: @@ -139,7 +140,8 @@ read_and (void (*do_something) (void)) { char buf[UINTMAX_STRSIZE_BOUND]; - status = read_header (¤t_header, ¤t_stat_info, false); + status = read_header (¤t_header, ¤t_stat_info, + read_header_auto); if (status == HEADER_ZERO_BLOCK) break; WARNOPT (WARN_ALONE_ZERO_BLOCK, @@ -282,21 +284,29 @@ tar_checksum (union block *header, bool silent) } /* Read a block that's supposed to be a header block. Return its - address in "current_header", and if it is good, the file's size - and names (file name, link name) in *info. + address in *RETURN_BLOCK, and if it is good, the file's size + and names (file name, link name) in *INFO. - Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a - block full of zeros (EOF marker). + Return one of enum read_header describing the status of the + operation. - If RAW_EXTENDED_HEADERS is nonzero, do not automagically fold the - GNU long name and link headers into later headers. + The MODE parameter instructs read_header what to do with special + header blocks, i.e.: extended POSIX, GNU long name or long link, + etc.: - You must always set_next_block_after(current_header) to skip past + read_header_auto process them automatically, + read_header_x_raw when a special header is read, return + HEADER_SUCCESS_EXTENDED without actually + processing the header, + read_header_x_global when a POSIX global header is read, + decode it and return HEADER_SUCCESS_EXTENDED. + + You must always set_next_block_after(*return_block) to skip past the header which this routine reads. */ enum read_header read_header (union block **return_block, struct tar_stat_info *info, - bool raw_extended_headers) + enum read_header_mode mode) { union block *header; union block *header_copy; @@ -333,7 +343,7 @@ read_header (union block **return_block, struct tar_stat_info *info, || header->header.typeflag == XGLTYPE || header->header.typeflag == SOLARIS_XHDTYPE) { - if (raw_extended_headers) + if (mode == read_header_x_raw) return HEADER_SUCCESS_EXTENDED; else if (header->header.typeflag == GNUTYPE_LONGNAME || header->header.typeflag == GNUTYPE_LONGLINK) @@ -405,6 +415,8 @@ read_header (union block **return_block, struct tar_stat_info *info, OFF_FROM_HEADER (header->header.size)); xheader_decode_global (&xhdr); xheader_destroy (&xhdr); + if (mode == read_header_x_global) + return HEADER_SUCCESS_EXTENDED; } /* Loop! */ @@ -672,7 +684,8 @@ from_header (char const *where0, size_t digs, char const *type, { if (type && !silent) ERROR ((0, 0, - /* TRANSLATORS: %s is type of the value (gid_t, uid_t, etc.) */ + /* TRANSLATORS: %s is type of the value (gid_t, uid_t, + etc.) */ _("Blanks in header where numeric %s value expected"), type)); return -1; @@ -1053,9 +1066,6 @@ simple_print_header (struct tar_stat_info *st, union block *blk, int pad; int sizelen; - if (test_label_option && blk->header.typeflag != GNUTYPE_VOLHDR) - return; - if (show_transformed_names_option) temp_name = st->file_name ? st->file_name : st->orig_file_name; else @@ -1282,30 +1292,36 @@ simple_print_header (struct tar_stat_info *st, union block *blk, } +void +print_volume_label () +{ + struct tar_stat_info vstat; + union block vblk; + enum archive_format dummy; + + memset (&vblk, 0, sizeof (vblk)); + vblk.header.typeflag = GNUTYPE_VOLHDR; + if (recent_global_header) + memcpy (vblk.header.mtime, recent_global_header->header.mtime, + sizeof vblk.header.mtime); + tar_stat_init (&vstat); + assign_string (&vstat.file_name, "."); + decode_header (&vblk, &vstat, &dummy, 0); + assign_string (&vstat.file_name, volume_label); + simple_print_header (&vstat, &vblk, 0); + tar_stat_destroy (&vstat); +} + void print_header (struct tar_stat_info *st, union block *blk, off_t block_ordinal) { if (current_format == POSIX_FORMAT && !volume_label_printed && volume_label) { - struct tar_stat_info vstat; - union block vblk; - enum archive_format dummy; - + print_volume_label (); volume_label_printed = true; - - memset (&vblk, 0, sizeof (vblk)); - vblk.header.typeflag = GNUTYPE_VOLHDR; - if (recent_global_header) - memcpy (vblk.header.mtime, recent_global_header->header.mtime, - sizeof vblk.header.mtime); - tar_stat_init (&vstat); - assign_string (&vstat.file_name, "."); - decode_header (&vblk, &vstat, &dummy, 0); - assign_string (&vstat.file_name, volume_label); - simple_print_header (&vstat, &vblk, block_ordinal); - tar_stat_destroy (&vstat); } + simple_print_header (st, blk, block_ordinal); } @@ -1385,3 +1401,34 @@ skip_member (void) mv_end (); } } + +void +test_archive_label () +{ + base64_init (); + name_gather (); + + open_archive (ACCESS_READ); + if (read_header (¤t_header, ¤t_stat_info, read_header_auto) + == HEADER_SUCCESS) + { + decode_header (current_header, + ¤t_stat_info, ¤t_format, 0); + if (current_header->header.typeflag == GNUTYPE_VOLHDR) + assign_string (&volume_label, current_header->header.name); + + if (volume_label) + { + if (verbose_option) + print_volume_label (); + if (!name_match (volume_label) && multi_volume_option) + { + char *s = drop_volume_label_suffix (volume_label); + name_match (s); + free (s); + } + } + } + close_archive (); + label_notfound (); +}