From: Sergey Poznyakoff Date: Mon, 17 Nov 2003 07:37:03 +0000 (+0000) Subject: Use new sparse file interface. X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=87fa28ed2abd92693a08e58523d7ab7f7c4563f0;p=chaz%2Ftar Use new sparse file interface. --- diff --git a/src/extract.c b/src/extract.c index 9d00c80..1731b3a 100644 --- a/src/extract.c +++ b/src/extract.c @@ -486,148 +486,6 @@ maybe_recoverable (char *file_name, int *interdir_made) } } -/* Translate the sparse information on the header, and in any - subsequent extended headers, into an array of structures with true - numbers, as opposed to character strings. Return nonzero if - successful. - - This function invalidates current_header. */ - -bool -fill_in_sparse_array (void) -{ - off_t sparse_data_size = current_stat_info.stat.st_size; - off_t file_size = OFF_FROM_HEADER (current_header->oldgnu_header.realsize); - int sparses; - int counter; - union block *h = current_header; - - init_sparsearray (); - - for (sparses = 0; sparses < SPARSES_IN_OLDGNU_HEADER; sparses++) - { - struct sparse const *s = &h->oldgnu_header.sp[sparses]; - off_t offset; - size_t numbytes; - if (s->numbytes[0] == '\0') - break; - sparsearray[sparses].offset = offset = OFF_FROM_HEADER (s->offset); - sparsearray[sparses].numbytes = numbytes = - SIZE_FROM_HEADER (s->numbytes); - sparse_data_size -= numbytes; - if (offset < 0 || file_size < offset + numbytes || sparse_data_size < 0) - goto invalid_member; - } - - if (h->oldgnu_header.isextended) - do - { - h = find_next_block (); - if (! h) - { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - return 0; - } - - for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++) - { - struct sparse const *s = &h->sparse_header.sp[counter]; - off_t offset; - size_t numbytes; - if (s->numbytes[0] == '\0') - break; - - if (sparses == sp_array_size) - { - sp_array_size *= 2; - sparsearray = - xrealloc (sparsearray, - sp_array_size * sizeof *sparsearray); - } - - sparsearray[sparses].offset = offset = - OFF_FROM_HEADER (s->offset); - sparsearray[sparses].numbytes = numbytes = - SIZE_FROM_HEADER (s->numbytes); - sparse_data_size -= numbytes; - if (offset < 0 || file_size < offset + numbytes - || sparse_data_size < 0) - goto invalid_member; - sparses++; - } - - set_next_block_after (h); - - } while (h->sparse_header.isextended); - - return 1; - - invalid_member: - ERROR ((0, 0, _("%s: invalid sparse archive member"), - current_stat_info.file_name)); - return 0; -} - - -static off_t -extract_sparse_file (int fd, char const *name, - off_t sizeleft, off_t file_size) -{ - int sparse_ind = 0; - - while (sizeleft != 0) - { - size_t written; - size_t count; - union block *data_block = find_next_block (); - if (! data_block) - { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - return sizeleft; - } - if (lseek (fd, sparsearray[sparse_ind].offset, SEEK_SET) < 0) - { - seek_error_details (name, sparsearray[sparse_ind].offset); - return sizeleft; - } - written = sparsearray[sparse_ind++].numbytes; - while (written > BLOCKSIZE) - { - count = full_write (fd, data_block->buffer, BLOCKSIZE); - written -= count; - sizeleft -= count; - if (count != BLOCKSIZE) - { - write_error_details (name, count, BLOCKSIZE); - return sizeleft; - } - set_next_block_after (data_block); - data_block = find_next_block (); - if (! data_block) - { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - return sizeleft; - } - } - - count = full_write (fd, data_block->buffer, written); - sizeleft -= count; - - if (count != written) - { - write_error_details (name, count, written); - return sizeleft; - } - - set_next_block_after (data_block); - } - - if (ftruncate (fd, file_size) != 0) - truncate_error (name); - - return 0; -} - /* Fix the statuses of all directories whose statuses need fixing, and which are not ancestors of FILE_NAME. If AFTER_SYMLINKS is nonzero, do this for all such directories; otherwise, stop at the @@ -712,7 +570,7 @@ extract_archive (void) /* Print the block from current_header and current_stat. */ if (verbose_option) - print_header (-1); + print_header (¤t_stat_info, -1); file_name = safer_name_suffix (current_stat_info.file_name, 0); if (strip_path_elements) @@ -746,9 +604,6 @@ extract_archive (void) switch (typeflag) { case GNUTYPE_SPARSE: - file_size = OFF_FROM_HEADER (current_header->oldgnu_header.realsize); - if (! fill_in_sparse_array ()) - return; /* Fall through. */ case AREGTYPE: @@ -823,21 +678,7 @@ extract_archive (void) extract_file: if (typeflag == GNUTYPE_SPARSE) { - char *name; - size_t name_length_bis; - - /* Kludge alert. NAME is assigned to header.name because - during the extraction, the space that contains the header - will get scribbled on, and the name will get munged, so any - error messages that happen to contain the filename will look - REAL interesting unless we do this. */ - - name_length_bis = strlen (file_name) + 1; - name = xmalloc (name_length_bis); - memcpy (name, file_name, name_length_bis); - size = extract_sparse_file (fd, name, - current_stat_info.stat.st_size, file_size); - free (sparsearray); + sparse_extract_file (fd, ¤t_stat_info, &size); } else for (size = current_stat_info.stat.st_size; size > 0; )