Fix normalize_filename.

The function did not take into account eventual -C options, which
in particular led to various problems when using -C and --remove-files
together.

* src/common.h (namebuf_add_dir,namebuf_finish)
(tar_getcwd): New prototypes.
* src/misc.c (namebuf_add_dir,namebuf_finish)
(tar_getcwd): New functions.
(normalize_filename): Use tar_getcwd.
This commit is contained in:
Sergey Poznyakoff
2013-09-24 14:01:13 +03:00
parent 2c06a80918
commit e3d28d84bd
2 changed files with 44 additions and 1 deletions

View File

@@ -605,6 +605,10 @@ typedef struct namebuf *namebuf_t;
namebuf_t namebuf_create (const char *dir);
void namebuf_free (namebuf_t buf);
char *namebuf_name (namebuf_t buf, const char *name);
void namebuf_add_dir (namebuf_t buf, const char *name);
char *namebuf_finish (namebuf_t buf);
char *tar_getcwd (void);
/* Represent N using a signed integer I such that (uintmax_t) I == N.
With a good optimizing compiler, this is equivalent to (intmax_t) i

View File

@@ -283,7 +283,7 @@ normalize_filename (const char *name)
getcwd is slow, it might fail, and it does not necessarily
return a canonical name even when it succeeds. Perhaps we
can use dev+ino pairs instead of names? */
copy = xgetcwd ();
copy = tar_getcwd ();
if (copy)
{
size_t copylen = strlen (copy);
@@ -976,6 +976,21 @@ chdir_do (int i)
}
}
char *
tar_getcwd (void)
{
static char *cwd;
namebuf_t nbuf;
int i;
if (!cwd)
cwd = xgetcwd ();
nbuf = namebuf_create (cwd);
for (i = 1; i <= chdir_current; i++)
namebuf_add_dir (nbuf, wd[i].name);
return namebuf_finish (nbuf);
}
void
close_diag (char const *name)
{
@@ -1145,6 +1160,30 @@ namebuf_name (namebuf_t buf, const char *name)
return buf->buffer;
}
void
namebuf_add_dir (namebuf_t buf, const char *name)
{
static char dirsep[] = { DIRECTORY_SEPARATOR, 0 };
if (!ISSLASH (buf->buffer[buf->dir_length - 1]))
{
namebuf_name (buf, dirsep);
buf->dir_length++;
}
namebuf_name (buf, name);
buf->dir_length += strlen (name);
}
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);
return res;
}
/* Return the filenames in directory NAME, relative to the chdir_fd.
If the directory does not exist, report error if MUST_EXIST is
true.