]> Dogcows Code - chaz/tar/blobdiff - src/extract.c
(to_chars): Fix base-256 output.
[chaz/tar] / src / extract.c
index b3f06dc4db6744381c17f016222723c5a16f3b69..aa699805eee3d0e68d0dd698bba4038b267df452 100644 (file)
@@ -1,5 +1,5 @@
 /* Extract files from a tar archive.
-   Copyright (C) 1988, 92,93,94,96,97,98, 1999 Free Software Foundation, Inc.
+   Copyright 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
@@ -18,9 +18,6 @@
 
 #include "system.h"
 
-#include <time.h>
-time_t time ();
-
 #if HAVE_UTIME_H
 # include <utime.h>
 #else
@@ -33,20 +30,10 @@ struct utimbuf
 
 #include "common.h"
 
-static time_t now;             /* current time */
 static int we_are_root;                /* true if our effective uid == 0 */
 static mode_t newdir_umask;    /* umask when creating new directories */
 static mode_t current_umask;   /* current umask (which is set to 0 if -p) */
 
-#if 0
-/* "Scratch" space to store the information about a sparse file before
-   writing the info into the header or extended header.  */
-struct sp_array *sparsearray;
-
-/* Number of elts storable in the sparsearray.  */
-int   sp_array_size = 10;
-#endif
-
 struct delayed_set_stat
   {
     struct delayed_set_stat *next;
@@ -63,15 +50,16 @@ static struct delayed_set_stat *delayed_set_stat_head;
 void
 extr_init (void)
 {
-  now = time ((time_t *) 0);
   we_are_root = geteuid () == 0;
+  same_permissions_option += we_are_root;
+  same_owner_option += we_are_root;
 
   /* Option -p clears the kernel umask, so it does not affect proper
      restoration of file permissions.  New intermediate directories will
      comply with umask at start of program.  */
 
   newdir_umask = umask (0);
-  if (same_permissions_option)
+  if (0 < same_permissions_option)
     current_umask = 0;
   else
     {
@@ -103,7 +91,7 @@ set_mode (char *file_name, struct stat *stat_info)
      normal, we merely skip the chmod.  This works because we did umask (0)
      when -p, so umask will have left the specified mode alone.  */
 
-  if ((we_are_root || same_permissions_option)
+  if (0 < same_permissions_option
       && ((!keep_old_files_option && !unlink_first_option)
          || (stat_info->st_mode & (S_ISUID | S_ISGID | S_ISVTX))))
     if (chmod (file_name, ~current_umask & stat_info->st_mode) < 0)
@@ -144,7 +132,7 @@ set_stat (char *file_name, struct stat *stat_info, int symlink_flag)
          if (incremental_option)
            utimbuf.actime = stat_info->st_atime;
          else
-           utimbuf.actime = now;
+           utimbuf.actime = start_time;
 
          utimbuf.modtime = stat_info->st_mtime;
 
@@ -165,7 +153,7 @@ set_stat (char *file_name, struct stat *stat_info, int symlink_flag)
      extract as the original owner.  Or else, if we are running as a user,
      leave the owner and group as they are, so we extract as that user.  */
 
-  if (we_are_root || same_owner_option)
+  if (0 < same_owner_option)
     {
 #if HAVE_LCHOWN
 
@@ -229,7 +217,7 @@ make_directories (char *file_name)
   int status;
 
   for (cursor = strchr (file_name, '/');
-       cursor != NULL;
+       cursor;
        cursor = strchr (cursor + 1, '/'))
     {
       /* Avoid mkdir of empty string, if leading or double '/'.  */
@@ -247,16 +235,6 @@ make_directories (char *file_name)
 
       if (status == 0)
        {
-         /* Fix ownership.  */
-
-         if (we_are_root)
-           if (chown (file_name, current_stat.st_uid, current_stat.st_gid) < 0)
-             ERROR ((0, errno,
-                     _("%s: Cannot change owner to uid %lu, gid %lu"),
-                     file_name,
-                     (unsigned long) current_stat.st_uid,
-                     (unsigned long) current_stat.st_gid));
-
          print_for_mkdir (file_name, cursor - file_name,
                           ~newdir_umask & MODE_RWX);
          did_something = 1;
@@ -352,7 +330,7 @@ extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
   while (*sizeleft > 0)
     {
       union block *data_block = find_next_block ();
-      if (data_block == NULL)
+      if (! data_block)
        {
          ERROR ((0, 0, _("Unexpected EOF on archive file")));
          return;
@@ -375,6 +353,11 @@ extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
          *sizeleft -= count;
          set_next_block_after (data_block);
          data_block = find_next_block ();
+         if (! data_block)
+           {
+             ERROR ((0, 0, _("Unexpected EOF on archive file")));
+             return;
+           }
        }
 
       count = full_write (fd, data_block->buffer, written);
@@ -447,15 +430,14 @@ extract_archive (void)
   skipcrud = 0;
   while (!absolute_names_option && CURRENT_FILE_NAME[0] == '/')
     {
-      static int warned_once = 0;
+      static int warned_once;
 
-      skipcrud++;              /* force relative path */
       if (!warned_once)
        {
          warned_once = 1;
-         WARN ((0, 0, _("\
-Removing leading `/' from absolute path names in the archive")));
+         WARN ((0, 0, _("Removing leading `/' from archive names")));
        }
+      skipcrud++;              /* force relative path */
     }
 
   /* Take a safety backup of a previously existing file.  */
@@ -492,15 +474,14 @@ Removing leading `/' from absolute path names in the archive")));
 
     case GNUTYPE_SPARSE:
       sp_array_size = 10;
-      sparsearray = (struct sp_array *)
+      sparsearray =
        xmalloc (sp_array_size * sizeof (struct sp_array));
 
       for (counter = 0; counter < SPARSES_IN_OLDGNU_HEADER; counter++)
        {
-         sparsearray[counter].offset =
-           OFF_FROM_CHARS (current_header->oldgnu_header.sp[counter].offset);
-         sparsearray[counter].numbytes =
-           SIZE_FROM_CHARS (current_header->oldgnu_header.sp[counter].numbytes);
+         struct sparse const *s = &current_header->oldgnu_header.sp[counter];
+         sparsearray[counter].offset = OFF_FROM_HEADER (s->offset);
+         sparsearray[counter].numbytes = SIZE_FROM_HEADER (s->numbytes);
          if (!sparsearray[counter].numbytes)
            break;
        }
@@ -516,26 +497,30 @@ Removing leading `/' from absolute path names in the archive")));
          while (1)
            {
              exhdr = find_next_block ();
+             if (! exhdr)
+               {
+                 ERROR ((0, 0, _("Unexpected EOF on archive file")));
+                 return;
+               }
              for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++)
                {
+                 struct sparse const *s = &exhdr->sparse_header.sp[counter];
                  if (counter + ind > sp_array_size - 1)
                    {
                      /* Realloc the scratch area since we've run out of
                         room.  */
 
                      sp_array_size *= 2;
-                     sparsearray = (struct sp_array *)
+                     sparsearray =
                        xrealloc (sparsearray,
-                                 sp_array_size * (sizeof (struct sp_array)));
+                                 sp_array_size * sizeof (struct sp_array));
                    }
-                 /* Compare to 0, or use !(int)..., for Pyramid's dumb
-                    compiler.  */
-                 if (exhdr->sparse_header.sp[counter].numbytes == 0)
+                 if (s->numbytes[0] == 0)
                    break;
                  sparsearray[counter + ind].offset =
-                   OFF_FROM_CHARS (exhdr->sparse_header.sp[counter].offset);
+                   OFF_FROM_HEADER (s->offset);
                  sparsearray[counter + ind].numbytes =
-                   SIZE_FROM_CHARS (exhdr->sparse_header.sp[counter].numbytes);
+                   SIZE_FROM_HEADER (s->numbytes);
                }
              if (!exhdr->sparse_header.isextended)
                break;
@@ -606,7 +591,7 @@ Removing leading `/' from absolute path names in the archive")));
 #else /* not O_CTG */
       if (typeflag == CONTTYPE)
        {
-         static int conttype_diagnosed = 0;
+         static int conttype_diagnosed;
 
          if (!conttype_diagnosed)
            {
@@ -646,7 +631,7 @@ Removing leading `/' from absolute path names in the archive")));
             REAL interesting unless we do this.  */
 
          name_length_bis = strlen (CURRENT_FILE_NAME) + 1;
-         name = (char *) xmalloc (name_length_bis);
+         name = xmalloc (name_length_bis);
          memcpy (name, CURRENT_FILE_NAME, name_length_bis);
          size = current_stat.st_size;
          extract_sparse_file (fd, &size, current_stat.st_size, name);
@@ -668,7 +653,7 @@ Removing leading `/' from absolute path names in the archive")));
               worked.  */
 
            data_block = find_next_block ();
-           if (data_block == NULL)
+           if (! data_block)
              {
                ERROR ((0, 0, _("Unexpected EOF on archive file")));
                break;          /* FIXME: What happens, then?  */
@@ -702,7 +687,7 @@ Removing leading `/' from absolute path names in the archive")));
          }
 
       if (multi_volume_option)
-       assign_string (&save_name, NULL);
+       assign_string (&save_name, 0);
 
       /* If writing to stdout, don't try to do anything to the filename;
         it doesn't exist, or we don't want to touch it anyway.  */
@@ -754,13 +739,13 @@ Removing leading `/' from absolute path names in the archive")));
 
 #else
       {
-       static int warned_once = 0;
+       static int warned_once;
 
        if (!warned_once)
          {
            warned_once = 1;
-           WARN ((0, 0, _("\
-Attempting extraction of symbolic links as hard links")));
+           WARN ((0, 0,
+                  _("Attempting extraction of symbolic links as hard links")));
          }
       }
       /* Fall through.  */
@@ -947,7 +932,7 @@ Attempting extraction of symbolic links as hard links")));
        }
 
 #if !MSDOS
-      /* MSDOS does not associate timestamps with directories.   In this
+      /* MSDOS does not associate time stamps with directories.   In this
         case, no need to try delaying their restoration.  */
 
       if (touch_option)
@@ -960,8 +945,7 @@ Attempting extraction of symbolic links as hard links")));
 
       else
        {
-         data = ((struct delayed_set_stat *)
-                     xmalloc (sizeof (struct delayed_set_stat)));
+         data = xmalloc (sizeof (struct delayed_set_stat));
          data->file_name = xstrdup (CURRENT_FILE_NAME);
          data->stat_info = current_stat;
          data->next = delayed_set_stat_head;
@@ -980,8 +964,8 @@ Attempting extraction of symbolic links as hard links")));
       break;
 
     case GNUTYPE_MULTIVOL:
-      ERROR ((0, 0, _("\
-Cannot extract `%s' -- file is continued from another volume"),
+      ERROR ((0, 0,
+             _("Cannot extract `%s' -- file is continued from another volume"),
              current_file_name));
       skip_file (current_stat.st_size);
       if (backup_option)
@@ -1015,7 +999,7 @@ apply_delayed_set_stat (void)
 {
   struct delayed_set_stat *data;
 
-  while (delayed_set_stat_head != NULL)
+  while (delayed_set_stat_head)
     {
       data = delayed_set_stat_head;
       delayed_set_stat_head = delayed_set_stat_head->next;
This page took 0.031889 seconds and 4 git commands to generate.