]> Dogcows Code - chaz/tar/blobdiff - src/extract.c
(total_written): Remove; replaced with prev_written + bytes_written.
[chaz/tar] / src / extract.c
index ccaf5fe6f1ee22c1ef842ea5654308d23b6357af..ffb4c33311c097728739cddef7c8bc425d28e305 100644 (file)
@@ -1,5 +1,5 @@
 /* Extract files from a tar archive.
-   Copyright (C) 1988, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
+   Copyright (C) 1988, 92,93,94,96,97,98, 1999 Free Software Foundation, Inc.
    Written by John Gilmore, on 1985-11-19.
 
    This program is free software; you can redistribute it and/or modify it
@@ -14,7 +14,7 @@
 
    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
-   59 Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "system.h"
 
@@ -81,7 +81,7 @@ extr_init (void)
 
   /* FIXME: Just make sure we can add files in directories we create.  Maybe
      should we later remove permissions we are adding, here?  */
-  newdir_umask &= ~0300;
+  newdir_umask &= ~ MODE_WXUSR;
 }
 
 /*------------------------------------------------------------------.
@@ -104,7 +104,7 @@ set_mode (char *file_name, struct stat *stat_info)
   if (!keep_old_files_option
       || (stat_info->st_mode & (S_ISUID | S_ISGID | S_ISVTX)))
     if (chmod (file_name, ~current_umask & stat_info->st_mode) < 0)
-      ERROR ((0, errno, _("%s: Cannot change mode to %0.4lo"),
+      ERROR ((0, errno, _("%s: Cannot change mode to %04lo"),
              file_name,
              (unsigned long) (~current_umask & stat_info->st_mode)));
 }
@@ -240,7 +240,7 @@ make_directories (char *file_name)
        continue;
 
       *cursor = '\0';          /* truncate the path there */
-      status = mkdir (file_name, ~newdir_umask & 0777);
+      status = mkdir (file_name, ~newdir_umask & MODE_RWX);
 
       if (status == 0)
        {
@@ -255,7 +255,7 @@ make_directories (char *file_name)
                      (unsigned long) current_stat.st_gid));
 
          print_for_mkdir (file_name, cursor - file_name,
-                          ~newdir_umask & 0777);
+                          ~newdir_umask & MODE_RWX);
          did_something = 1;
 
          *cursor = '/';
@@ -321,29 +321,32 @@ maybe_recoverable (char *file_name)
 static void
 extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
 {
-  union block *data_block;
   int sparse_ind = 0;
   size_t written;
   ssize_t count;
 
-  /* FIXME: `data_block' might be used uninitialized in this function.
-     Reported by Bruno Haible.  */
-
   /* assuming sizeleft is initially totalsize */
 
   while (*sizeleft > 0)
     {
-      data_block = find_next_block ();
+      union block *data_block = find_next_block ();
       if (data_block == NULL)
        {
          ERROR ((0, 0, _("Unexpected EOF on archive file")));
          return;
        }
-      lseek (fd, sparsearray[sparse_ind].offset, 0);
+      if (lseek (fd, sparsearray[sparse_ind].offset, SEEK_SET) < 0)
+       {
+         char buf[UINTMAX_STRSIZE_BOUND];
+         ERROR ((0, errno, _("%s: lseek error at byte %s"),
+                 STRINGIFY_BIGINT (sparsearray[sparse_ind].offset, buf),
+                 name));
+         return;
+       }
       written = sparsearray[sparse_ind++].numbytes;
       while (written > BLOCKSIZE)
        {
-         count = write (fd, data_block->buffer, BLOCKSIZE);
+         count = full_write (fd, data_block->buffer, BLOCKSIZE);
          if (count < 0)
            ERROR ((0, errno, _("%s: Could not write to file"), name));
          written -= count;
@@ -352,7 +355,7 @@ extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
          data_block = find_next_block ();
        }
 
-      count = write (fd, data_block->buffer, written);
+      count = full_write (fd, data_block->buffer, written);
 
       if (count < 0)
        ERROR ((0, errno, _("%s: Could not write to file"), name));
@@ -371,8 +374,8 @@ extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
       *sizeleft -= count;
       set_next_block_after (data_block);
     }
+
   free (sparsearray);
-  set_next_block_after (data_block);
 }
 
 /*----------------------------------.
@@ -392,6 +395,7 @@ extract_archive (void)
   off_t size;
   int skipcrud;
   int counter;
+  char typeflag;
 #if 0
   int sparse_ind = 0;
 #endif
@@ -447,7 +451,8 @@ Removing leading `/' from absolute path names in the archive")));
 
   /* Extract the archive entry according to its type.  */
 
-  switch (current_header->header.typeflag)
+  typeflag = current_header->header.typeflag;
+  switch (typeflag)
     {
       /* JK - What we want to do if the file is sparse is loop through
         the array of sparse structures in the header and read in and
@@ -480,8 +485,9 @@ Removing leading `/' from absolute path names in the archive")));
 
       if (current_header->oldgnu_header.isextended)
        {
-         /* Read in the list of extended headers and translate them into
-            the sparsearray as before.  */
+         /* Read in the list of extended headers and translate them
+            into the sparsearray as before.  Note that this
+            invalidates current_header.  */
 
          /* static */ int ind = SPARSES_IN_OLDGNU_HEADER;
 
@@ -538,7 +544,7 @@ Removing leading `/' from absolute path names in the archive")));
       openflag = (keep_old_files_option ?
                  O_BINARY | O_NDELAY | O_WRONLY | O_CREAT | O_EXCL :
                  O_BINARY | O_NDELAY | O_WRONLY | O_CREAT | O_TRUNC)
-       | ((current_header->header.typeflag == GNUTYPE_SPARSE) ? 0 : O_APPEND);
+       | ((typeflag == GNUTYPE_SPARSE) ? 0 : O_APPEND);
 
       /* JK - The last | is a kludge to solve the problem the O_APPEND
         flag causes with files we are trying to make sparse: when a file
@@ -562,14 +568,14 @@ Removing leading `/' from absolute path names in the archive")));
       /* Contiguous files (on the Masscomp) have to specify the size in
         the open call that creates them.  */
 
-      if (current_header->header.typeflag == CONTTYPE)
+      if (typeflag == CONTTYPE)
        fd = open (CURRENT_FILE_NAME, openflag | O_CTG,
                   current_stat.st_mode, current_stat.st_size);
       else
        fd = open (CURRENT_FILE_NAME, openflag, current_stat.st_mode);
 
 #else /* not O_CTG */
-      if (current_header->header.typeflag == CONTTYPE)
+      if (typeflag == CONTTYPE)
        {
          static int conttype_diagnosed = 0;
 
@@ -599,7 +605,7 @@ Removing leading `/' from absolute path names in the archive")));
        }
 
     extract_file:
-      if (current_header->header.typeflag == GNUTYPE_SPARSE)
+      if (typeflag == GNUTYPE_SPARSE)
        {
          char *name;
          size_t name_length_bis;
@@ -639,24 +645,12 @@ Removing leading `/' from absolute path names in the archive")));
                break;          /* FIXME: What happens, then?  */
              }
 
-           /* If the file is sparse, use the sparsearray that we created
-              before to lseek into the new file the proper amount, and to
-              see how many bytes we want to write at that position.  */
-
-#if 0
-           if (current_header->header.typeflag == GNUTYPE_SPARSE)
-             {
-               lseek (fd, sparsearray[sparse_ind].offset, 0);
-               written = sparsearray[sparse_ind++].numbytes;
-             }
-           else
-#endif
-             written = available_space_after (data_block);
+           written = available_space_after (data_block);
 
            if (written > size)
              written = size;
            errno = 0;          /* FIXME: errno should be read-only */
-           sstatus = write (fd, data_block->buffer, written);
+           sstatus = full_write (fd, data_block->buffer, written);
 
            set_next_block_after ((union block *)
                                  (data_block->buffer + written - 1));
@@ -687,28 +681,6 @@ Removing leading `/' from absolute path names in the archive")));
       if (to_stdout_option)
        break;
 
-#if 0
-      if (current_header->header.isextended)
-       {
-         union block *exhdr;
-         int counter;
-
-         for (counter = 0; counter < 21; counter++)
-           {
-             off_t offset;
-
-             if (!exhdr->sparse_header.sp[counter].numbytes)
-               break;
-             offset = OFF_FROM_OCT (exhdr->sparse_header.sp[counter].offset);
-             written
-               = SIZE_FROM_OCT (exhdr->sparse_header.sp[counter].numbytes);
-             lseek (fd, offset, 0);
-             sstatus = write (fd, data_block->buffer, written);
-             if (sstatus == written)
-               continue;
-           }
-       }
-#endif
       status = close (fd);
       if (status < 0)
        {
@@ -812,7 +784,7 @@ Attempting extraction of symbolic links as hard links")));
       current_stat.st_mode |= S_IFBLK;
 #endif
 
-#if defined(S_IFCHR) || defined(S_IFBLK)
+#if S_IFCHR || S_IFBLK
     make_node:
       if (to_stdout_option)
        break;
@@ -876,7 +848,7 @@ Attempting extraction of symbolic links as hard links")));
 
          gnu_restore (skipcrud);
        }
-      else if (current_header->header.typeflag == GNUTYPE_DUMPDIR)
+      else if (typeflag == GNUTYPE_DUMPDIR)
        skip_file (current_stat.st_size);
 
       if (to_stdout_option)
@@ -884,7 +856,8 @@ Attempting extraction of symbolic links as hard links")));
 
     again_dir:
       status = mkdir (CURRENT_FILE_NAME,
-                    (we_are_root ? 0 : 0300) | current_stat.st_mode);
+                     ((we_are_root ? 0 : MODE_WXUSR)
+                      | current_stat.st_mode));
       if (status != 0)
        {
          /* If the directory creation fails, let's consider immediately the
@@ -937,9 +910,9 @@ Attempting extraction of symbolic links as hard links")));
        }
 
     check_perms:
-      if (!we_are_root && 0300 != (0300 & current_stat.st_mode))
+      if (!we_are_root && MODE_WXUSR != (MODE_WXUSR & current_stat.st_mode))
        {
-         current_stat.st_mode |= 0300;
+         current_stat.st_mode |= MODE_WXUSR;
          WARN ((0, 0, _("Added write and execute permission to directory %s"),
                 CURRENT_FILE_NAME));
        }
@@ -997,7 +970,7 @@ Cannot extract `%s' -- file is continued from another volume"),
     default:
       WARN ((0, 0,
             _("Unknown file type '%c' for %s, extracted as normal file"),
-            current_header->header.typeflag, CURRENT_FILE_NAME));
+            typeflag, CURRENT_FILE_NAME));
       goto again_file;
     }
 
This page took 0.027389 seconds and 4 git commands to generate.