From: Sergey Poznyakoff Date: Sun, 4 Apr 2004 09:33:25 +0000 (+0000) Subject: (struct tar_sparse_optab.sparse_member_p) X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Ftar;a=commitdiff_plain;h=15a607fc11d8563fe471924fb6e718ceb9adfce4 (struct tar_sparse_optab.sparse_member_p) (struct tar_sparse_optab.fixup_header): New member (tar_sparse_member_p): New function. (tar_sparse_init): Return true if decode_header is not provided (tar_sparse_fixup_header) (sparse_member_p,sparse_fixup_header) (sparse_skip_file) (oldgnu_sparse_member_p,oldgnu_fixup_header,star_sparse_member_p) (star_fixup_header, pax_sparse_member_p): New function (pax_decode_header): Remove --- diff --git a/src/sparse.c b/src/sparse.c index a661ab1..2f5330d 100644 --- a/src/sparse.c +++ b/src/sparse.c @@ -33,7 +33,9 @@ struct tar_sparse_optab { bool (*init) (struct tar_sparse_file *); bool (*done) (struct tar_sparse_file *); + bool (*sparse_member_p) (struct tar_sparse_file *); bool (*dump_header) (struct tar_sparse_file *); + bool (*fixup_header) (struct tar_sparse_file *); bool (*decode_header) (struct tar_sparse_file *); bool (*scan_block) (struct tar_sparse_file *, enum sparse_scan_state, void *); @@ -52,6 +54,14 @@ struct tar_sparse_file reqiure */ }; +static bool +tar_sparse_member_p (struct tar_sparse_file *file) +{ + if (file->optab->sparse_member_p) + return file->optab->sparse_member_p (file); + return false; +} + static bool tar_sparse_init (struct tar_sparse_file *file) { @@ -107,7 +117,15 @@ tar_sparse_decode_header (struct tar_sparse_file *file) { if (file->optab->decode_header) return file->optab->decode_header (file); - return false; + return true; +} + +static bool +tar_sparse_fixup_header (struct tar_sparse_file *file) +{ + if (file->optab->fixup_header) + return file->optab->fixup_header (file); + return true; } @@ -364,6 +382,28 @@ sparse_file_p (struct tar_stat_info *stat) + (stat->stat.st_size % ST_NBLOCKSIZE != 0))); } +bool +sparse_member_p (struct tar_stat_info *stat) +{ + struct tar_sparse_file file; + + if (!sparse_select_optab (&file)) + return false; + file.stat_info = stat; + return tar_sparse_member_p (&file); +} + +bool +sparse_fixup_header (struct tar_stat_info *stat) +{ + struct tar_sparse_file file; + + if (!sparse_select_optab (&file)) + return false; + file.stat_info = stat; + return tar_sparse_fixup_header (&file); +} + enum dump_status sparse_extract_file (int fd, struct tar_stat_info *stat, off_t *size) { @@ -385,6 +425,24 @@ sparse_extract_file (int fd, struct tar_stat_info *stat, off_t *size) return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short; } +enum dump_status +sparse_skip_file (struct tar_stat_info *stat) +{ + bool rc = true; + struct tar_sparse_file file; + + file.stat_info = stat; + 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; +} + static char diff_buffer[BLOCKSIZE]; @@ -522,6 +580,12 @@ enum oldgnu_add_status add_fail }; +static bool +oldgnu_sparse_member_p (struct tar_sparse_file *file_unused) +{ + return current_header->header.typeflag == GNUTYPE_SPARSE; +} + /* Add a sparse item to the sparse file and its obstack */ static enum oldgnu_add_status oldgnu_add_sparse (struct tar_sparse_file *file, struct sparse *s) @@ -541,8 +605,18 @@ oldgnu_add_sparse (struct tar_sparse_file *file, struct sparse *s) return add_ok; } -/* Convert old GNU format sparse data to internal representation - FIXME: Clubbers current_header! */ +static bool +oldgnu_fixup_header (struct tar_sparse_file *file) +{ + /* NOTE! st_size was initialized from the header + which actually contains archived size. The following fixes it */ + file->stat_info->archive_file_size = file->stat_info->stat.st_size; + file->stat_info->stat.st_size = + OFF_FROM_HEADER (current_header->oldgnu_header.realsize); + return true; +} + +/* Convert old GNU format sparse data to internal representation */ static bool oldgnu_get_sparse_info (struct tar_sparse_file *file) { @@ -551,12 +625,6 @@ oldgnu_get_sparse_info (struct tar_sparse_file *file) int ext_p; static enum oldgnu_add_status rc; - /* FIXME: note this! st_size was initialized from the header - which actually contains archived size. The following fixes it */ - file->stat_info->archive_file_size = file->stat_info->stat.st_size; - file->stat_info->stat.st_size = - OFF_FROM_HEADER (current_header->oldgnu_header.realsize); - file->stat_info->sparse_map_size = 0; for (i = 0; i < SPARSES_IN_OLDGNU_HEADER; i++) { @@ -645,7 +713,9 @@ oldgnu_dump_header (struct tar_sparse_file *file) static struct tar_sparse_optab oldgnu_optab = { NULL, /* No init function */ NULL, /* No done function */ + oldgnu_sparse_member_p, oldgnu_dump_header, + oldgnu_fixup_header, oldgnu_get_sparse_info, NULL, /* No scan_block function */ sparse_dump_region, @@ -655,8 +725,24 @@ static struct tar_sparse_optab oldgnu_optab = { /* Star */ -/* Convert STAR format sparse data to internal representation - FIXME: Clubbers current_header! */ +static bool +star_sparse_member_p (struct tar_sparse_file *file_unused) +{ + return current_header->header.typeflag == GNUTYPE_SPARSE; +} + +static bool +star_fixup_header (struct tar_sparse_file *file) +{ + /* NOTE! st_size was initialized from the header + which actually contains archived size. The following fixes it */ + file->stat_info->archive_file_size = file->stat_info->stat.st_size; + file->stat_info->stat.st_size = + OFF_FROM_HEADER (current_header->star_in_header.realsize); + return true; +} + +/* Convert STAR format sparse data to internal representation */ static bool star_get_sparse_info (struct tar_sparse_file *file) { @@ -665,12 +751,6 @@ star_get_sparse_info (struct tar_sparse_file *file) int ext_p; static enum oldgnu_add_status rc; - /* FIXME: note this! st_size was initialized from the header - which actually contains archived size. The following fixes it */ - file->stat_info->archive_file_size = file->stat_info->stat.st_size; - file->stat_info->stat.st_size = - OFF_FROM_HEADER (current_header->star_in_header.realsize); - file->stat_info->sparse_map_size = 0; if (h->star_in_header.prefix[0] == '\0' @@ -714,7 +794,9 @@ star_get_sparse_info (struct tar_sparse_file *file) static struct tar_sparse_optab star_optab = { NULL, /* No init function */ NULL, /* No done function */ + star_sparse_member_p, NULL, + star_fixup_header, star_get_sparse_info, NULL, /* No scan_block function */ NULL, /* No dump region function */ @@ -733,6 +815,12 @@ static struct tar_sparse_optab star_optab = { end repeat */ +static bool +pax_sparse_member_p (struct tar_sparse_file *file) +{ + return file->stat_info->archive_file_size != file->stat_info->stat.st_size; +} + static bool pax_dump_header (struct tar_sparse_file *file) { @@ -756,21 +844,13 @@ pax_dump_header (struct tar_sparse_file *file) return true; } -static bool -pax_decode_header (struct tar_sparse_file *file) -{ - /* Restore actual size */ - size_t s = file->stat_info->archive_file_size; - file->stat_info->archive_file_size = file->stat_info->stat.st_size; - file->stat_info->stat.st_size = s; - return true; -} - static struct tar_sparse_optab pax_optab = { NULL, /* No init function */ NULL, /* No done function */ + pax_sparse_member_p, pax_dump_header, - pax_decode_header, + NULL, /* No decode_header function */ + NULL, /* No fixup_header function */ NULL, /* No scan_block function */ sparse_dump_region, sparse_extract_region,