From: Pavel Raiskup Date: Tue, 29 Jan 2013 09:39:30 +0000 (+0100) Subject: Fix bug in sparse file listing X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Ftar;a=commitdiff_plain;h=ec94fbdf458adb2af803eefdd1a9c9bbb432bb21 Fix bug in sparse file listing 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(). --- diff --git a/src/list.c b/src/list.c index b4277e0..22bec01 100644 --- a/src/list.c +++ b/src/list.c @@ -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)) diff --git a/src/tar.h b/src/tar.h index 3d69399..73cd11e 100644 --- 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; diff --git a/src/xheader.c b/src/xheader.c index c94c6d3..361f684 100644 --- a/src/xheader.c +++ b/src/xheader.c @@ -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