Browse Source

Use new sparse file interface.

Sergey Poznyakoff 21 years ago
parent
commit
87fa28ed2a
1 changed files with 2 additions and 161 deletions
  1. 2 161
      src/extract.c

+ 2 - 161
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 (&current_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, &current_stat_info, &size);
 	}
       else
 	for (size = current_stat_info.stat.st_size; size > 0; )