/* Miscellaneous functions, not really specific to GNU tar.
Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
- 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2009, 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
return name;
}
-/* Normalize NAME by resolving any relative references and
- removing trailing slashes. Destructive version: modifies its argument. */
-static int
-normalize_filename_x (char *name)
-{
- char *p, *q;
-
- p = name;
- if (DOUBLE_SLASH_IS_DISTINCT_ROOT && ISSLASH (*p))
- p++;
-
- /* Remove /./, resolve /../ and compress sequences of slashes */
- for (q = p; *q; )
+/* Normalize FILE_NAME by removing redundant slashes and "."
+ components, including redundant trailing slashes. Leave ".."
+ alone, as it may be significant in the presence of symlinks and on
+ platforms where "/.." != "/". Destructive version: modifies its
+ argument. */
+static void
+normalize_filename_x (char *file_name)
+{
+ char *name = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
+ char *p;
+ char const *q;
+ char c;
+
+ /* Don't squeeze leading "//" to "/", on hosts where they're distinct. */
+ name += (DOUBLE_SLASH_IS_DISTINCT_ROOT
+ && ISSLASH (*name) && ISSLASH (name[1]) && ! ISSLASH (name[2]));
+
+ /* Omit redundant leading "." components. */
+ for (q = p = name; (*p = *q) == '.' && ISSLASH (q[1]); p += !*q)
+ for (q += 2; ISSLASH (*q); q++)
+ continue;
+
+ /* Copy components from Q to P, omitting redundant slashes and
+ internal "." components. */
+ while ((*p++ = c = *q++) != '\0')
+ if (ISSLASH (c))
+ while (ISSLASH (q[*q == '.']))
+ q += (*q == '.') + 1;
+
+ /* Omit redundant trailing "." component and slash. */
+ if (2 < p - name)
{
- if (ISSLASH (*q))
- {
- *p++ = *q++;
- while (ISSLASH (*q))
- q++;
- continue;
- }
- else if (p == name)
- {
- if (*q == '.')
- {
- if (ISSLASH (q[1]))
- {
- q += 2;
- continue;
- }
- if (q[1] == '.' && ISSLASH (q[2]))
- return 1;
- }
- }
- else
- {
- if (*q == '.' && ISSLASH (p[-1]))
- {
- if (ISSLASH (q[1]))
- {
- q += 2;
- while (ISSLASH (*q))
- q++;
- continue;
- }
- else if (q[1] == '.' && ISSLASH (q[2]))
- {
- do
- {
- --p;
- }
- while (p > name && !ISSLASH (p[-1]));
- q += 3;
- continue;
- }
- }
- }
- *p++ = *q++;
+ p -= p[-2] == '.' && ISSLASH (p[-3]);
+ p -= 2 < p - name && ISSLASH (p[-2]);
+ p[-1] = '\0';
}
-
- /* Remove trailing slashes */
- while (p - 1 > name && ISSLASH (p[-1]))
- p--;
-
- *p = 0;
- return 0;
}
-/* Normalize NAME by resolving any relative references, removing trailing
- slashes, and converting it to absolute file name. Return the normalized
- name, or NULL in case of error. */
+/* Normalize NAME by removing redundant slashes and "." components,
+ including redundant trailing slashes. Return a normalized
+ newly-allocated copy. */
char *
normalize_filename (const char *name)
{
- char *copy;
-
- if (name[0] != '/')
- {
- copy = xgetcwd ();
- copy = xrealloc (copy, strlen (copy) + strlen (name) + 2);
-
- strcat (copy, "/");
- strcat (copy, name);
- }
- else
- copy = xstrdup (name);
- if (normalize_filename_x (copy))
- {
- free (copy);
- return NULL;
- }
- return xrealloc (copy, strlen (copy) + 1);
+ char *copy = xstrdup (name);
+ normalize_filename_x (copy);
+ return copy;
}
\f
close (fd1);
prev->saved_cwd.desc = -1;
prev->saved_cwd.name = xgetcwd ();
+ if (! prev->saved_cwd.name)
+ err = errno;
}
else
err = errno;
# Makefile for GNU tar regression tests.
-# Copyright (C) 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2005,
+# Copyright (C) 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2005,
# 2006, 2007, 2009 Free Software Foundation, Inc.
# François Pinard <pinard@iro.umontreal.ca>, 1988.
link03.at\
listed01.at\
listed02.at\
+ listed03.at\
long01.at\
longv7.at\
lustar01.at\
--- /dev/null
+# 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/>.
+
+# This checks for the --listed-incremental bug reported by J Chapman Flack at
+# http://lists.gnu.org/archive/html/bug-tar/2010-06/msg00000.html
+
+AT_SETUP([incremental dump when the parent directory is unreadable])
+AT_KEYWORDS([listed incremental listed03])
+
+AT_TAR_CHECK([
+mkdir dir
+mkdir dir/sub
+mkdir dir/sub/a
+genfile --file dir/sub/a/file
+cd dir/sub
+
+chmod a-r ..
+tar -c -f archive.tar --listed-incremental=db.1 -v a
+status=$?
+chmod a+r ..
+exit $status
+],
+[0],
+[a/
+a/file
+],
+[tar: a: Directory is new
+],[],[],[gnu])
+
+AT_CLEANUP