X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Fsparse.c;h=d16efc79ef170ea9d178ee2c2dfe72604d4849bb;hb=f6458a827ae7a2c41616490f653714068072b257;hp=d3f716492b894cd0134711e2de3b8b540d0f1550;hpb=37d2462d7c5da33a2bdfd4f12e8f2e047837f72e;p=chaz%2Ftar diff --git a/src/sparse.c b/src/sparse.c index d3f7164..d16efc7 100644 --- a/src/sparse.c +++ b/src/sparse.c @@ -22,6 +22,7 @@ #include "common.h" struct tar_sparse_file; +static bool sparse_select_optab (struct tar_sparse_file *file); enum sparse_scan_state { @@ -102,9 +103,14 @@ tar_sparse_member_p (struct tar_sparse_file *file) static bool tar_sparse_init (struct tar_sparse_file *file) { - file->dumped_size = 0; + memset (file, 0, sizeof *file); + + if (!sparse_select_optab (file)) + return false; + if (file->optab->init) return file->optab->init (file); + return true; } @@ -217,6 +223,8 @@ sparse_scan_file (struct tar_sparse_file *file) if (!lseek_or_error (file, 0)) return false; + st->archive_file_size = 0; + if (!tar_sparse_scan (file, scan_begin, NULL)) return false; @@ -370,16 +378,15 @@ enum dump_status sparse_dump_file (int fd, struct tar_stat_info *st) { bool rc; - struct tar_sparse_file file = { 0, }; + struct tar_sparse_file file; + + if (!tar_sparse_init (&file)) + return dump_status_not_implemented; file.stat_info = st; file.fd = fd; file.seekable = true; /* File *must* be seekable for dump to work */ - if (!sparse_select_optab (&file) - || !tar_sparse_init (&file)) - return dump_status_not_implemented; - rc = sparse_scan_file (&file); if (rc && file.optab->dump_region) { @@ -412,7 +419,7 @@ sparse_member_p (struct tar_stat_info *st) { struct tar_sparse_file file; - if (!sparse_select_optab (&file)) + if (!tar_sparse_init (&file)) return false; file.stat_info = st; return tar_sparse_member_p (&file); @@ -423,7 +430,7 @@ sparse_fixup_header (struct tar_stat_info *st) { struct tar_sparse_file file; - if (!sparse_select_optab (&file)) + if (!tar_sparse_init (&file)) return false; file.stat_info = st; return tar_sparse_fixup_header (&file); @@ -436,15 +443,14 @@ sparse_extract_file (int fd, struct tar_stat_info *st, off_t *size) struct tar_sparse_file file; size_t i; + if (!tar_sparse_init (&file)) + return dump_status_not_implemented; + file.stat_info = st; file.fd = fd; file.seekable = lseek (fd, 0, SEEK_SET) == 0; file.offset = 0; - if (!sparse_select_optab (&file) - || !tar_sparse_init (&file)) - return dump_status_not_implemented; - rc = tar_sparse_decode_header (&file); for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++) rc = tar_sparse_extract_region (&file, i); @@ -458,13 +464,12 @@ sparse_skip_file (struct tar_stat_info *st) bool rc = true; struct tar_sparse_file file; + if (!tar_sparse_init (&file)) + return dump_status_not_implemented; + file.stat_info = st; file.fd = -1; - if (!sparse_select_optab (&file) - || !tar_sparse_init (&file)) - return dump_status_not_implemented; - rc = tar_sparse_decode_header (&file); skip_file (file.stat_info->archive_file_size); return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short; @@ -555,13 +560,12 @@ sparse_diff_file (int fd, struct tar_stat_info *st) size_t i; off_t offset = 0; + if (!tar_sparse_init (&file)) + return dump_status_not_implemented; + file.stat_info = st; file.fd = fd; - if (!sparse_select_optab (&file) - || !tar_sparse_init (&file)) - return dump_status_not_implemented; - rc = tar_sparse_decode_header (&file); for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++) { @@ -843,7 +847,7 @@ static struct tar_sparse_optab const star_optab = { static bool pax_sparse_member_p (struct tar_sparse_file *file) { - return file->stat_info->archive_file_size != file->stat_info->stat.st_size; + return file->stat_info->sparse_map_avail > 0; } static bool