Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Sep 2014 11:17:12 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r271015 - stable/9/contrib/libarchive/tar
Message-ID:  <201409031117.s83BHCoh070081@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Sep  3 11:17:11 2014
New Revision: 271015
URL: http://svnweb.freebsd.org/changeset/base/271015

Log:
  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.

Modified:
  stable/9/contrib/libarchive/tar/util.c
Directory Properties:
  stable/9/contrib/libarchive/tar/   (props changed)

Modified: stable/9/contrib/libarchive/tar/util.c
==============================================================================
--- stable/9/contrib/libarchive/tar/util.c	Wed Sep  3 11:07:49 2014	(r271014)
+++ stable/9/contrib/libarchive/tar/util.c	Wed Sep  3 11:17:11 2014	(r271015)
@@ -349,6 +349,21 @@ strip_components(const char *p, int elem
 	}
 }
 
+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.
@@ -453,16 +468,7 @@ edit_pathname(struct bsdtar *bsdtar, str
 				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) {
@@ -483,6 +489,19 @@ edit_pathname(struct bsdtar *bsdtar, str
 			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] == '/')



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409031117.s83BHCoh070081>