216 |
|
|
217 |
static struct tar_sparse_optab oldgnu_optab; |
static struct tar_sparse_optab oldgnu_optab; |
218 |
static struct tar_sparse_optab star_optab; |
static struct tar_sparse_optab star_optab; |
219 |
|
static struct tar_sparse_optab pax_optab; |
220 |
|
|
221 |
static bool |
static bool |
222 |
sparse_select_optab (struct tar_sparse_file *file) |
sparse_select_optab (struct tar_sparse_file *file) |
233 |
break; |
break; |
234 |
|
|
235 |
case POSIX_FORMAT: |
case POSIX_FORMAT: |
236 |
/* FIXME: Add method */ |
file->optab = &pax_optab; |
237 |
return false; |
break; |
238 |
|
|
239 |
case STAR_FORMAT: |
case STAR_FORMAT: |
240 |
file->optab = &star_optab; |
file->optab = &star_optab; |
714 |
NULL, /* No dump region function */ |
NULL, /* No dump region function */ |
715 |
sparse_extract_region, |
sparse_extract_region, |
716 |
}; |
}; |
717 |
|
|
718 |
|
|
719 |
|
/* GNU PAX sparse file format. The sparse file map is stored in |
720 |
|
x header: |
721 |
|
|
722 |
|
GNU.sparse.size Real size of the stored file |
723 |
|
GNU.sparse.numblocks Number of blocks in the sparse map |
724 |
|
repeat numblocks time |
725 |
|
GNU.sparse.offset Offset of the next data block |
726 |
|
GNU.sparse.numbytes Size of the next data block |
727 |
|
end repeat |
728 |
|
*/ |
729 |
|
|
730 |
|
static bool |
731 |
|
pax_dump_header (struct tar_sparse_file *file) |
732 |
|
{ |
733 |
|
off_t block_ordinal = current_block_ordinal (); |
734 |
|
union block *blk; |
735 |
|
size_t i; |
736 |
|
|
737 |
|
/* Store the real file size */ |
738 |
|
xheader_store ("GNU.sparse.size", file->stat_info, NULL); |
739 |
|
xheader_store ("GNU.sparse.numblocks", file->stat_info, NULL); |
740 |
|
for (i = 0; i < file->stat_info->sparse_map_avail; i++) |
741 |
|
{ |
742 |
|
xheader_store ("GNU.sparse.offset", file->stat_info, &i); |
743 |
|
xheader_store ("GNU.sparse.numbytes", file->stat_info, &i); |
744 |
|
} |
745 |
|
|
746 |
|
blk = start_header (file->stat_info); |
747 |
|
/* Store the effective (shrunken) file size */ |
748 |
|
OFF_TO_CHARS (file->stat_info->archive_file_size, blk->header.size); |
749 |
|
finish_header (file->stat_info, blk, block_ordinal); |
750 |
|
return true; |
751 |
|
} |
752 |
|
|
753 |
|
static bool |
754 |
|
pax_decode_header (struct tar_sparse_file *file) |
755 |
|
{ |
756 |
|
/* Restore actual size */ |
757 |
|
size_t s = file->stat_info->archive_file_size; |
758 |
|
file->stat_info->archive_file_size = file->stat_info->stat.st_size; |
759 |
|
file->stat_info->stat.st_size = s; |
760 |
|
return true; |
761 |
|
} |
762 |
|
|
763 |
|
static struct tar_sparse_optab pax_optab = { |
764 |
|
NULL, /* No init function */ |
765 |
|
NULL, /* No done function */ |
766 |
|
pax_dump_header, |
767 |
|
pax_decode_header, |
768 |
|
NULL, /* No scan_block function */ |
769 |
|
sparse_dump_region, |
770 |
|
sparse_extract_region, |
771 |
|
}; |
772 |
|
|