Remove leading '/' from hardlink name when removing them from the

regular file name. This fixes the problem, when bsdtar can not create
hardlinks to extracted files.

Silence from:	kientzle@
MFC after:	1 week
Sponsored by:	Yandex LLC
This commit is contained in:
Andrey V. Elsukov 2014-08-26 13:11:38 +00:00
parent 9d365a16df
commit 44418c8be9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=270661

View File

@ -372,6 +372,21 @@ strip_components(const char *p, int elements)
}
}
static const char*
strip_leading_slashes(const char *p)
{
/* Remove leading "/../", "//", etc. */
while (p[0] == '/' || p[0] == '\\') {
if (p[1] == '.' && p[2] == '.' && (
p[3] == '/' || p[3] == '\\')) {
p += 3; /* Remove "/..", leave "/" for next pass. */
} else
p += 1; /* Remove "/". */
}
return (p);
}
/*
* Handle --strip-components and any future path-rewriting options.
* Returns non-zero if the pathname should not be extracted.
@ -474,16 +489,7 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
p += 2;
slashonly = 0;
}
/* Remove leading "/../", "//", etc. */
while (p[0] == '/' || p[0] == '\\') {
if (p[1] == '.' && p[2] == '.' &&
(p[3] == '/' || p[3] == '\\')) {
p += 3; /* Remove "/..", leave "/"
* for next pass. */
slashonly = 0;
} else
p += 1; /* Remove "/". */
}
p = strip_leading_slashes(p);
} while (rp != p);
if (p != name && !bsdtar->warned_lead_slash) {
@ -504,6 +510,19 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
name = ".";
else
name = p;
p = archive_entry_hardlink(entry);
if (p != NULL) {
rp = strip_leading_slashes(p);
if (rp == '\0')
return (1);
if (rp != p) {
char *linkname = strdup(rp);
archive_entry_copy_hardlink(entry, linkname);
free(linkname);
}
}
} else {
/* Strip redundant leading '/' characters. */
while (name[0] == '/' && name[1] == '/')