]> Dogcows Code - chaz/tar/blobdiff - src/extract.c
tar: extract permissions for . last
[chaz/tar] / src / extract.c
index 1f455932291db1a2d4e9dad187a73b6e63631427..46ee6781fc8a8e96b0742d07b15c9e5326e52c6d 100644 (file)
@@ -361,6 +361,30 @@ set_stat (char const *file_name,
            fd, current_mode, current_mode_mask, typeflag, atflag);
 }
 
+/* For each entry H in the leading prefix of entries in HEAD that do
+   not have after_links marked, mark H and fill in its dev and ino
+   members.  Assume HEAD && ! HEAD->after_links.  */
+static void
+mark_after_links (struct delayed_set_stat *head)
+{
+  struct delayed_set_stat *h = head;
+
+  do
+    {
+      struct stat st;
+      h->after_links = 1;
+
+      if (stat (h->file_name, &st) != 0)
+       stat_error (h->file_name);
+      else
+       {
+         h->dev = st.st_dev;
+         h->ino = st.st_ino;
+       }
+    }
+  while ((h = h->next) && ! h->after_links);
+}
+
 /* Remember to restore stat attributes (owner, group, mode and times)
    for the directory FILE_NAME, using information given in *ST,
    once we stop extracting files into that directory.
@@ -408,6 +432,8 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
   data->change_dir = chdir_current;
   strcpy (data->file_name, file_name);
   delayed_set_stat_head = data;
+  if (must_be_dot_or_slash (file_name))
+    mark_after_links (data);
 }
 
 /* Update the delayed_set_stat info for an intermediate directory
@@ -1033,21 +1059,7 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
          && strncmp (file_name, h->file_name, h->file_name_len) == 0
          && ISSLASH (file_name[h->file_name_len])
          && (last_component (file_name) == file_name + h->file_name_len + 1))
-       {
-         do
-           {
-             h->after_links = 1;
-
-             if (stat (h->file_name, &st) != 0)
-               stat_error (h->file_name);
-             else
-               {
-                 h->dev = st.st_dev;
-                 h->ino = st.st_ino;
-               }
-           }
-         while ((h = h->next) && ! h->after_links);
-       }
+       mark_after_links (h);
 
       return 0;
     }
This page took 0.023391 seconds and 4 git commands to generate.