|
@@ -29,6 +29,8 @@
|
|
|
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
|
|
|
#endif
|
|
|
|
|
|
+static const char *tar_getcdpath (int);
|
|
|
+
|
|
|
|
|
|
/* Handling strings. */
|
|
|
|
|
@@ -230,7 +232,7 @@ zap_slashes (char *name)
|
|
|
|
|
|
/* Normalize FILE_NAME by removing redundant slashes and "."
|
|
|
components, including redundant trailing slashes.
|
|
|
- Leave ".." alone, as it may be significant in the presence
|
|
|
+ Leave ".." alone, as it may be significant in the presence
|
|
|
of symlinks and on platforms where "/.." != "/".
|
|
|
|
|
|
Destructive version: modifies its argument. */
|
|
@@ -290,7 +292,9 @@ normalize_filename (int cdidx, const char *name)
|
|
|
const char *cdpath = tar_getcdpath (cdidx);
|
|
|
size_t copylen;
|
|
|
bool need_separator;
|
|
|
-
|
|
|
+
|
|
|
+ if (!cdpath)
|
|
|
+ call_arg_fatal ("getcwd", ".");
|
|
|
copylen = strlen (cdpath);
|
|
|
need_separator = ! (DOUBLE_SLASH_IS_DISTINCT_ROOT
|
|
|
&& copylen == 2 && ISSLASH (cdpath[1]));
|
|
@@ -834,10 +838,11 @@ struct wd
|
|
|
{
|
|
|
/* The directory's name. */
|
|
|
char const *name;
|
|
|
- /* "absolute" path representing this directory; in the contrast to
|
|
|
+ /* "Absolute" path representing this directory; in the contrast to
|
|
|
the real absolute pathname, it can contain /../ components (see
|
|
|
- normalize_filename_x for the reason of it). */
|
|
|
- char *abspath;
|
|
|
+ normalize_filename_x for the reason of it). It is NULL if the
|
|
|
+ absolute path could not be determined. */
|
|
|
+ char *abspath;
|
|
|
/* If nonzero, the file descriptor of the directory, or AT_FDCWD if
|
|
|
the working directory. If zero, the directory needs to be opened
|
|
|
to be used. */
|
|
@@ -879,15 +884,13 @@ chdir_count (void)
|
|
|
int
|
|
|
chdir_arg (char const *dir)
|
|
|
{
|
|
|
+ char *absdir;
|
|
|
+
|
|
|
if (wd_count == wd_alloc)
|
|
|
{
|
|
|
if (wd_alloc == 0)
|
|
|
- {
|
|
|
- wd_alloc = 2;
|
|
|
- wd = xmalloc (sizeof *wd * wd_alloc);
|
|
|
- }
|
|
|
- else
|
|
|
- wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
|
|
|
+ wd_alloc = 2;
|
|
|
+ wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
|
|
|
|
|
|
if (! wd_count)
|
|
|
{
|
|
@@ -909,18 +912,22 @@ chdir_arg (char const *dir)
|
|
|
return wd_count - 1;
|
|
|
}
|
|
|
|
|
|
- wd[wd_count].name = dir;
|
|
|
- /* if the given name is an absolute path, then use that path
|
|
|
- to represent this working directory; otherwise, construct
|
|
|
- a path based on the previous -C option's absolute path */
|
|
|
- if (IS_ABSOLUTE_FILE_NAME (wd[wd_count].name))
|
|
|
- wd[wd_count].abspath = xstrdup (wd[wd_count].name);
|
|
|
- else
|
|
|
+
|
|
|
+ /* If the given name is absolute, use it to represent this directory;
|
|
|
+ otherwise, construct a name based on the previous -C option. */
|
|
|
+ if (IS_ABSOLUTE_FILE_NAME (dir))
|
|
|
+ absdir = xstrdup (dir);
|
|
|
+ else if (wd[wd_count - 1].abspath)
|
|
|
{
|
|
|
namebuf_t nbuf = namebuf_create (wd[wd_count - 1].abspath);
|
|
|
- namebuf_add_dir (nbuf, wd[wd_count].name);
|
|
|
- wd[wd_count].abspath = namebuf_finish (nbuf);
|
|
|
+ namebuf_add_dir (nbuf, dir);
|
|
|
+ absdir = namebuf_finish (nbuf);
|
|
|
}
|
|
|
+ else
|
|
|
+ absdir = 0;
|
|
|
+
|
|
|
+ wd[wd_count].name = dir;
|
|
|
+ wd[wd_count].abspath = absdir;
|
|
|
wd[wd_count].fd = 0;
|
|
|
return wd_count++;
|
|
|
}
|
|
@@ -1007,7 +1014,7 @@ tar_dirname (void)
|
|
|
chdir_args() has never been called, so we simply return the
|
|
|
process's actual cwd. (Note that in this case IDX is ignored,
|
|
|
since it should always be 0.) */
|
|
|
-const char *
|
|
|
+static const char *
|
|
|
tar_getcdpath (int idx)
|
|
|
{
|
|
|
if (!wd)
|
|
@@ -1206,7 +1213,7 @@ char *
|
|
|
namebuf_finish (namebuf_t buf)
|
|
|
{
|
|
|
char *res = buf->buffer;
|
|
|
-
|
|
|
+
|
|
|
if (ISSLASH (buf->buffer[buf->dir_length - 1]))
|
|
|
buf->buffer[buf->dir_length] = 0;
|
|
|
free (buf);
|