]> Dogcows Code - chaz/tar/blobdiff - src/list.c
Keep a detailed map of archive members stored in the record buffer.
[chaz/tar] / src / list.c
index 5a341aad2c81d5deb1505ff7f48cf2d515443749..9184beab739f70631c371a517b0c119af001e781 100644 (file)
@@ -78,7 +78,8 @@ read_and (void (*do_something) (void))
       prev_status = status;
       tar_stat_destroy (&current_stat_info);
 
-      status = read_header (&current_header, &current_stat_info, false);
+      status = read_header (&current_header, &current_stat_info,
+                            read_header_auto);
       switch (status)
        {
        case HEADER_STILL_UNREAD:
@@ -89,7 +90,8 @@ read_and (void (*do_something) (void))
 
          /* Valid header.  We should decode next field (mode) first.
             Ensure incoming names are null terminated.  */
-
+         decode_header (current_header, &current_stat_info,
+                        &current_format, 1);
          if (! name_match (current_stat_info.file_name)
              || (NEWER_OPTION_INITIALIZED (newer_mtime_option)
                  /* FIXME: We get mtime now, and again later; this causes
@@ -115,8 +117,6 @@ read_and (void (*do_something) (void))
                           quotearg_colon (current_stat_info.file_name)));
                  /* Fall through.  */
                default:
-                 decode_header (current_header,
-                                &current_stat_info, &current_format, 0);
                  skip_member ();
                  continue;
                }
@@ -139,7 +139,8 @@ read_and (void (*do_something) (void))
            {
              char buf[UINTMAX_STRSIZE_BOUND];
 
-             status = read_header (&current_header, &current_stat_info, false);
+             status = read_header (&current_header, &current_stat_info,
+                                   read_header_auto);
              if (status == HEADER_ZERO_BLOCK)
                break;
              WARNOPT (WARN_ALONE_ZERO_BLOCK,
@@ -208,8 +209,6 @@ list_archive (void)
   off_t block_ordinal = current_block_ordinal ();
 
   /* Print the header block.  */
-  
-  decode_header (current_header, &current_stat_info, &current_format, 0);
   if (verbose_option)
     print_header (&current_stat_info, current_header, block_ordinal);
 
@@ -282,21 +281,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 one of enum read_header describing the status of the
+   operation.
 
-   Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a
-   block full of zeros (EOF marker).
+   The MODE parameter instructs read_header what to do with special
+   header blocks, i.e.: extended POSIX, GNU long name or long link,
+   etc.:
 
-   If RAW_EXTENDED_HEADERS is nonzero, do not automagically fold the
-   GNU long name and link headers into later headers.
+     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(current_header) to skip past
+   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 +340,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 +412,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!  */
@@ -484,18 +493,18 @@ decode_xform (char *file_name, void *data)
         links subject to filename transformation.  In the absence of another
         solution, symbolic links are exempt from component stripping and
         name suffix normalization, but subject to filename transformation
-        proper. */ 
+        proper. */
       return file_name;
-      
+
     case XFORM_LINK:
       file_name = safer_name_suffix (file_name, true, absolute_names_option);
       break;
-      
+
     case XFORM_REGFILE:
       file_name = safer_name_suffix (file_name, false, absolute_names_option);
       break;
     }
-  
+
   if (strip_name_components)
     {
       size_t prefix_len = stripped_prefix_len (file_name,
@@ -535,7 +544,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
   enum archive_format format;
   unsigned hbits; /* high bits of the file mode. */
   mode_t mode = MODE_FROM_HEADER (header->header.mode, &hbits);
-  
+
   if (strcmp (header->header.magic, TMAGIC) == 0)
     {
       if (header->star_header.prefix[130] == 0
@@ -639,7 +648,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
     case SYMTYPE:
       transform_member_name (&stat_info->link_name, XFORM_SYMLINK);
       break;
-      
+
     case LNKTYPE:
       transform_member_name (&stat_info->link_name, XFORM_LINK);
     }
@@ -1134,7 +1143,7 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
 
       /* Time stamp.  */
 
-      time_stamp = tartime (st->mtime, false);
+      time_stamp = tartime (st->mtime, full_time_option);
       time_stamp_len = strlen (time_stamp);
       if (datewidth < time_stamp_len)
        datewidth = time_stamp_len;
@@ -1280,8 +1289,8 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
 }
 
 
-void
-print_volume_label ()
+static void
+print_volume_label (void)
 {
   struct tar_stat_info vstat;
   union block vblk;
@@ -1344,7 +1353,7 @@ skip_file (off_t size)
 {
   union block *x;
 
-  /* FIXME: Make sure mv_begin is always called before it */
+  /* FIXME: Make sure mv_begin_read is always called before it */
 
   if (seekable_archive)
     {
@@ -1379,7 +1388,7 @@ skip_member (void)
       char save_typeflag = current_header->header.typeflag;
       set_next_block_after (current_header);
 
-      mv_begin (&current_stat_info);
+      mv_begin_read (&current_stat_info);
 
       if (current_stat_info.is_sparse)
        sparse_skip_file (&current_stat_info);
@@ -1397,25 +1406,26 @@ test_archive_label ()
   name_gather ();
 
   open_archive (ACCESS_READ);
-  if (read_header (&current_header, &current_stat_info, false)
+  if (read_header (&current_header, &current_stat_info, read_header_auto)
       == HEADER_SUCCESS)
     {
-      char *s = NULL;
-       
       decode_header (current_header,
                     &current_stat_info, &current_format, 0);
       if (current_header->header.typeflag == GNUTYPE_VOLHDR)
        assign_string (&volume_label, current_header->header.name);
 
-      if (volume_label
-         && (name_match (volume_label)
-             || (multi_volume_option
-                 && (s = drop_volume_label_suffix (volume_label))
-                 && name_match (s))))
-       if (verbose_option)
-         print_volume_label ();
-      free (s);
+      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 ();
-  names_notfound ();
+  label_notfound ();
 }
This page took 0.028884 seconds and 4 git commands to generate.