/* Scan the sparse file and create its map */ static bool sparse_scan_file (struct tar_sparse_file *file) { struct tar_stat_info *st = file->stat_info; int fd = file->fd; char buffer[BLOCKSIZE]; size_t count = 0; off_t offset = 0; struct sp_array sp = {0, 0}; st->archive_file_size = 0; if (ST_NBLOCKS (st->stat) == 0) offset = st->stat.st_size; else { if (!tar_sparse_scan (file, scan_begin, NULL)) return false; while ((count = blocking_read (fd, buffer, sizeof buffer)) != 0 && count != SAFE_READ_ERROR) { /* Analyze the block. */ if (zero_block_p (buffer, count)) { if (sp.numbytes) { sparse_add_map (st, &sp); sp.numbytes = 0; if (!tar_sparse_scan (file, scan_block, NULL)) return false; } } else { if (sp.numbytes == 0) sp.offset = offset; sp.numbytes += count; st->archive_file_size += count; if (!tar_sparse_scan (file, scan_block, buffer)) return false; } offset += count; } } if (sp.numbytes == 0) sp.offset = offset; sparse_add_map (st, &sp); st->archive_file_size += count; return tar_sparse_scan (file, scan_end, NULL); }
/* Scan the sparse file and create its map */ static bool sparse_scan_file (struct tar_sparse_file *file) { static char buffer[BLOCKSIZE]; size_t count; size_t offset = 0; struct sp_array sp = {0, 0}; if (!lseek_or_error (file, 0, SEEK_SET)) return false; clear_block (buffer); file->stat_info->sparse_map_avail = 0; file->stat_info->archive_file_size = 0; if (!tar_sparse_scan (file, scan_begin, NULL)) return false; while ((count = safe_read (file->fd, buffer, sizeof buffer)) != 0 && count != SAFE_READ_ERROR) { /* Analize the block */ if (zero_block_p (buffer, count)) { if (sp.numbytes) { sparse_add_map (file, &sp); sp.numbytes = 0; if (!tar_sparse_scan (file, scan_block, NULL)) return false; } } else { if (sp.numbytes == 0) sp.offset = offset; sp.numbytes += count; file->stat_info->archive_file_size += count; if (!tar_sparse_scan (file, scan_block, buffer)) return false; } offset += count; clear_block (buffer); } if (sp.numbytes == 0) sp.offset = offset; sparse_add_map (file, &sp); file->stat_info->archive_file_size += count; return tar_sparse_scan (file, scan_end, NULL); }