mirror of
https://git.savannah.gnu.org/git/tar.git
synced 2026-04-24 10:30:48 +00:00
tar: extract permissions for . last
* 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.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -78,6 +78,7 @@ TESTSUITE_AT = \
|
||||
extrac09.at\
|
||||
extrac10.at\
|
||||
extrac11.at\
|
||||
extrac12.at\
|
||||
filerem01.at\
|
||||
filerem02.at\
|
||||
gzip.at\
|
||||
|
||||
39
tests/extrac12.at
Normal file
39
tests/extrac12.at
Normal file
@@ -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
|
||||
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user