]> Dogcows Code - chaz/tar/commitdiff
Fix bug in sparse file listing
authorPavel Raiskup <praiskup@redhat.com>
Tue, 29 Jan 2013 09:39:30 +0000 (10:39 +0100)
committerSergey Poznyakoff <gray@gnu.org>
Fri, 7 Nov 2014 08:21:41 +0000 (10:21 +0200)
List posix archives containing sparse files >8GB correctly and do not fail.
This fixes also bug in format of listing for sparse files >8GB - now the
real size is printed instead of the effective one (this is not strictly
posix format related).

* src/list.c: Remove redundant assignment.
* src/tar.h: Add new 'real_size' and 'real_size_set' fields in
  tar_stat_info struct.
* src/xheader.c: Correctly handle (especially sparse) file sizes directly in
  xheader_decode().

src/list.c
src/tar.h
src/xheader.c

index b4277e028e59f9672fbb5b247574fcad5c8e41c9..22bec010e475516f8a19e89d10519627c756db69 100644 (file)
@@ -689,7 +689,6 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
        }
     }
 
-  stat_info->archive_file_size = stat_info->stat.st_size;
   xheader_decode (stat_info);
 
   if (sparse_member_p (stat_info))
index 3d6939948ba5ae10b10816a53d72b652d1ef6fad..73cd11e6d635f00efb47e0eecc67d462fc1355e3 100644 (file)
--- a/src/tar.h
+++ b/src/tar.h
@@ -327,6 +327,10 @@ struct tar_stat_info
   size_t sparse_map_size;   /* Size of the sparse map */
   struct sp_array *sparse_map;
 
+  off_t real_size;          /* The real size of sparse file */
+  int   real_size_set;      /* True when GNU.sparse.realsize is set in
+                              archived file */
+
   size_t xattr_map_size;   /* Size of the xattr map */
   struct xattr_array *xattr_map;
 
index c94c6d39f1e2437a3caa8ea577d436cd77275143..361f684751806c5482d44f9c1fa1ed1f397c6ac7 100644 (file)
@@ -755,6 +755,16 @@ xheader_decode (struct tar_stat_info *st)
        continue;
     }
   run_override_list (keyword_override_list, st);
+
+  /* The archived (effective) file size is always set directly in tar header
+     field, possibly overridden by "size" extended header - in both cases,
+     result is now decoded in st->stat.st_size */
+  st->archive_file_size = st->stat.st_size;
+
+  /* The real file size (given by stat()) may be redefined for sparse
+     files in "GNU.sparse.realsize" extended header */
+  if (st->real_size_set)
+    st->stat.st_size = st->real_size;
 }
 
 static void
@@ -1360,7 +1370,10 @@ sparse_size_decoder (struct tar_stat_info *st,
 {
   uintmax_t u;
   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
-    st->stat.st_size = u;
+    {
+      st->real_size_set = 1;
+      st->real_size = u;
+    }
 }
 
 static void
This page took 0.025371 seconds and 4 git commands to generate.