summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2014-09-03 08:27:05 +0000
committerae <ae@FreeBSD.org>2014-09-03 08:27:05 +0000
commit36aab21b56eda2d5b672607f2026f9cf4ba60510 (patch)
treea6e8b3d36affff5838f98ad9c169dedf0ba8f2c6
parent4910deb0fcf65a3546947b9f267113a4032d466b (diff)
downloadFreeBSD-src-36aab21b56eda2d5b672607f2026f9cf4ba60510.zip
FreeBSD-src-36aab21b56eda2d5b672607f2026f9cf4ba60510.tar.gz
MFC r270661:
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.
-rw-r--r--contrib/libarchive/tar/util.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/contrib/libarchive/tar/util.c b/contrib/libarchive/tar/util.c
index a6f3189..688e1f8 100644
--- a/contrib/libarchive/tar/util.c
+++ b/contrib/libarchive/tar/util.c
@@ -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] == '/')
OpenPOWER on IntegriCloud