bool sparse_diff_file (int fd, struct tar_stat_info *st) { bool rc = true; struct tar_sparse_file file; size_t i; off_t offset = 0; 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 compare to work */ rc = tar_sparse_decode_header (&file); mv_begin (st); for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++) { rc = check_sparse_region (&file, offset, file.stat_info->sparse_map[i].offset) && check_data_region (&file, i); offset = file.stat_info->sparse_map[i].offset + file.stat_info->sparse_map[i].numbytes; } if (!rc) skip_file (file.stat_info->archive_file_size - file.dumped_size); mv_end (); tar_sparse_done (&file); return rc; }
bool sparse_diff_file (int fd, struct tar_stat_info *st) { bool rc = true; struct tar_sparse_file file; size_t i; off_t offset = 0; 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++) { rc = check_sparse_region (&file, offset, file.stat_info->sparse_map[i].offset) && check_data_region (&file, i); offset = file.stat_info->sparse_map[i].offset + file.stat_info->sparse_map[i].numbytes; } if (!rc) skip_file (file.stat_info->archive_file_size - file.dumped_size); tar_sparse_done (&file); return rc; }
enum dump_status 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; rc = tar_sparse_decode_header (&file); skip_file (file.stat_info->archive_file_size - file.dumped_size); return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short; }
enum dump_status sparse_extract_file (int fd, struct tar_stat_info *st, off_t *size) { bool rc = true; struct tar_sparse_file file; size_t i; 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++) rc = tar_sparse_extract_region (&file, i); *size = file.stat_info->archive_file_size - file.dumped_size; return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short; }