bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-tar] [PATCH] tar: extract permissions for . last


From: Paul Eggert
Subject: [Bug-tar] [PATCH] tar: extract permissions for . last
Date: Fri, 17 Sep 2010 12:31:18 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.12) Gecko/20100915 Thunderbird/3.0.8

* src/common.h (must_be_dot_or_slash): New decl.
* src/extract.c (mark_after_links): New function, taking code
that used to be in create_placeholder_file.
(create_placeholder_file): Use it.
(delay_set_stat): Always delay setting status for . and /.
* src/misc.c (must_be_dot_or_slash): Now extern.
* tests/extrac12.at: New file.
* tests/Makefile.am (TESTSUITE_AT): Add it.
* tests/testsuite.at: Likewise.
---
 src/common.h       |    2 ++
 src/extract.c      |   42 +++++++++++++++++++++++++++---------------
 src/misc.c         |    2 +-
 tests/Makefile.am  |    1 +
 tests/extrac12.at  |   39 +++++++++++++++++++++++++++++++++++++++
 tests/testsuite.at |    1 +
 6 files changed, 71 insertions(+), 16 deletions(-)
 create mode 100644 tests/extrac12.at

diff --git a/src/common.h b/src/common.h
index e0d8eb7..d0e3484 100644
--- a/src/common.h
+++ b/src/common.h
@@ -591,6 +591,8 @@ enum { BILLION = 1000000000, LOG10_BILLION = 9 };
 enum { TIMESPEC_STRSIZE_BOUND =
          UINTMAX_STRSIZE_BOUND + LOG10_BILLION + sizeof "-." - 1 };
 
+bool must_be_dot_or_slash (char const *);
+
 enum remove_option
 {
   ORDINARY_REMOVE_OPTION,
diff --git a/src/extract.c b/src/extract.c
index 1f45593..46ee678 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -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;
     }
diff --git a/src/misc.c b/src/misc.c
index 64b1b2b..f1ebdd4 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -390,7 +390,7 @@ static char *before_backup_name;
 static char *after_backup_name;
 
 /* Return 1 if FILE_NAME is obviously "." or "/".  */
-static bool
+bool
 must_be_dot_or_slash (char const *file_name)
 {
   file_name += FILE_SYSTEM_PREFIX_LEN (file_name);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ea1c6ae..5cfd847 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -78,6 +78,7 @@ TESTSUITE_AT = \
  extrac09.at\
  extrac10.at\
  extrac11.at\
+ extrac12.at\
  filerem01.at\
  filerem02.at\
  gzip.at\
diff --git a/tests/extrac12.at b/tests/extrac12.at
new file mode 100644
index 0000000..4c5962e
--- /dev/null
+++ b/tests/extrac12.at
@@ -0,0 +1,39 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+
+# Test suite for GNU tar.
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# written by Paul Eggert
+
+# Check that 'tar' extracts permissions on the working directory last.
+
+AT_SETUP([extract dot permissions])
+AT_KEYWORDS([extract extrac12])
+
+AT_TAR_CHECK([
+mkdir src dst
+echo file1 >src/file1
+echo file2 >src/file2
+chmod a-w src
+
+tar --no-recursion -cf archive.tar -C src . ./file1 file2 &&
+tar -xf archive.tar -C dst &&
+cmp src/file1 dst/file1 &&
+cmp src/file2 dst/file2
+],
+[0],[],[],[],[],[gnu])
+
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 2b2bd6b..dc7a603 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -150,6 +150,7 @@ m4_include([extrac08.at])
 m4_include([extrac09.at])
 m4_include([extrac10.at])
 m4_include([extrac11.at])
+m4_include([extrac12.at])
 
 m4_include([label01.at])
 m4_include([label02.at])
-- 
1.7.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]