From cf2dade6c2a196668e54103922599c08a7450a72 Mon Sep 17 00:00:00 2001
From: Britney Fransen <brfransen@gmail.com>
Date: Sun, 24 May 2020 05:51:14 +0000
Subject: libarchive: update to 3.4.3

---
 ...1-Limit-write-requests-to-at-most-INT_MAX.patch |  32 --
 ...tree-fix-line-filename-length-calculation.patch |  29 --
 abs/core/libarchive/PKGBUILD                       |  62 +--
 abs/core/libarchive/libarchive-3.1.2-acl.patch     | 219 ----------
 .../libarchive/libarchive-3.1.2-sparce-mtree.patch | 478 ---------------------
 5 files changed, 21 insertions(+), 799 deletions(-)
 delete mode 100644 abs/core/libarchive/0001-Limit-write-requests-to-at-most-INT_MAX.patch
 delete mode 100644 abs/core/libarchive/0001-mtree-fix-line-filename-length-calculation.patch
 delete mode 100644 abs/core/libarchive/libarchive-3.1.2-acl.patch
 delete mode 100644 abs/core/libarchive/libarchive-3.1.2-sparce-mtree.patch

diff --git a/abs/core/libarchive/0001-Limit-write-requests-to-at-most-INT_MAX.patch b/abs/core/libarchive/0001-Limit-write-requests-to-at-most-INT_MAX.patch
deleted file mode 100644
index c805ce1..0000000
--- a/abs/core/libarchive/0001-Limit-write-requests-to-at-most-INT_MAX.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 22531545514043e04633e1c015c7540b9de9dbe4 Mon Sep 17 00:00:00 2001
-From: Tim Kientzle <kientzle@acm.org>
-Date: Fri, 22 Mar 2013 23:48:41 -0700
-Subject: [PATCH] Limit write requests to at most INT_MAX. This prevents a
- certain common programming error (passing -1 to write) from leading to other
- problems deeper in the library.
-
----
- libarchive/archive_write.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
-index eede5e0..be85621 100644
---- a/libarchive/archive_write.c
-+++ b/libarchive/archive_write.c
-@@ -673,8 +673,13 @@ static ssize_t
- _archive_write_data(struct archive *_a, const void *buff, size_t s)
- {
- 	struct archive_write *a = (struct archive_write *)_a;
-+	const size_t max_write = INT_MAX;
-+
- 	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- 	    ARCHIVE_STATE_DATA, "archive_write_data");
-+	/* In particular, this catches attempts to pass negative values. */
-+	if (s > max_write)
-+		s = max_write;
- 	archive_clear_error(&a->archive);
- 	return ((a->format_write_data)(a, buff, s));
- }
--- 
-1.9.0
-
diff --git a/abs/core/libarchive/0001-mtree-fix-line-filename-length-calculation.patch b/abs/core/libarchive/0001-mtree-fix-line-filename-length-calculation.patch
deleted file mode 100644
index a255f2c..0000000
--- a/abs/core/libarchive/0001-mtree-fix-line-filename-length-calculation.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From e65bf287f0133426b26611fe3e80b51267987106 Mon Sep 17 00:00:00 2001
-From: Dave Reisner <dreisner@archlinux.org>
-Date: Thu, 21 Feb 2013 19:01:06 -0500
-Subject: [PATCH] mtree: fix line filename length calculation. Fixes #301.
- Signed-off-by: Andres Mejia <amejia004@gmail.com>
-
----
- libarchive/archive_write_set_format_mtree.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/libarchive/archive_write_set_format_mtree.c b/libarchive/archive_write_set_format_mtree.c
-index 9c0613c..f37f723 100644
---- a/libarchive/archive_write_set_format_mtree.c
-+++ b/libarchive/archive_write_set_format_mtree.c
-@@ -1855,9 +1855,9 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
- 		return (ret);
- 	}
- 
--	/* Make a basename from dirname and slash */
-+	/* Make a basename from file->parentdir.s and slash */
- 	*slash  = '\0';
--	file->parentdir.length = slash - dirname;
-+	file->parentdir.length = slash - file->parentdir.s;
- 	archive_strcpy(&(file->basename),  slash + 1);
- 	return (ret);
- }
--- 
-1.8.1.4
-
diff --git a/abs/core/libarchive/PKGBUILD b/abs/core/libarchive/PKGBUILD
index 4bb4c70..5893a0e 100644
--- a/abs/core/libarchive/PKGBUILD
+++ b/abs/core/libarchive/PKGBUILD
@@ -1,59 +1,39 @@
-# $Id$
+# Maintainer: Bartłomiej Piotrowski <bpiotrowski@archlinux.org>
 # Maintainer: Dan McGee <dan@archlinux.org>
 
 pkgname=libarchive
-pkgver=3.1.2
-pkgrel=10
-pkgdesc="library that can create and read several streaming archive formats"
-arch=('i686' 'x86_64')
-url="http://libarchive.org/"
+pkgver=3.4.3
+pkgrel=1
+pkgdesc='Multi-format archive and compression library'
+arch=('x86_64')
+url='https://libarchive.org/'
 license=('BSD')
-depends=('acl' 'attr' 'bzip2' 'expat' 'lzo' 'nettle>=3.2-1' 'openssl' 'xz' 'zlib')
-options=('strip' 'debug' 'libtool')
+depends=('acl' 'libacl.so' 'bzip2' 'expat' 'lz4' 'openssl' 'xz' 'zlib' 'zstd')
 provides=('libarchive.so')
-source=("http://libarchive.org/downloads/$pkgname-$pkgver.tar.gz"
-        '0001-mtree-fix-line-filename-length-calculation.patch'
-        '0001-Limit-write-requests-to-at-most-INT_MAX.patch'
-        'libarchive-3.1.2-acl.patch'
-        'libarchive-3.1.2-sparce-mtree.patch')
-md5sums=('efad5a503f66329bb9d2f4308b5de98a'
-         'fda89c145bbcd793a96b06b463ef6a72'
-         '9bf80940bd3ce861137a0a8dcacf5705'
-         'a5c995661c62429ceff2c23ea322393b'
-         'cb344a879b3c4550fe3faf86c3826f23')
+validpgpkeys=('A5A45B12AD92D964B89EEE2DEC560C81CEC2276E') # Martin Matuska <mm@FreeBSD.org>
+source=("https://github.com/${pkgname}/${pkgname}/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.xz"{,.asc})
+sha256sums=('0bfc3fd40491768a88af8d9b86bf04a9e95b6d41a94f9292dbc0ec342288c05f'
+            'SKIP')
 
-prepare() {
-  cd "$pkgname-$pkgver"
-
-  # https://code.google.com/p/libarchive/issues/detail?id=301
-  # upstream commit e65bf287f0133426b26611fe3e80b51267987106
-  patch -Np1 -i "$srcdir/0001-mtree-fix-line-filename-length-calculation.patch"
-
-  # https://code.google.com/p/libarchive/issues/detail?id=329
-  patch -Np1 -i "$srcdir/libarchive-3.1.2-acl.patch"
-
-  # CVE-2013-0211
-  patch -Np1 -i "$srcdir/0001-Limit-write-requests-to-at-most-INT_MAX.patch"
+build() {
+  cd $pkgname-$pkgver 
 
-  # upstream commit 977bf2a4 - improved mtree support
-  patch -p1 -i $srcdir/libarchive-3.1.2-sparce-mtree.patch
-}
+  ./configure \
+      --prefix=/usr \
+      --without-xml2 \
+      --without-nettle \
+      --disable-static
 
-build() {
-  cd "$pkgname-$pkgver"
-  ./configure --prefix=/usr --without-xml2
   make
 }
 
 check() {
-  cd "$pkgname-$pkgver"
-
+  cd $pkgname-$pkgver
   make check
 }
 
 package() {
-  cd "$pkgname-$pkgver"
+  cd $pkgname-$pkgver
   make DESTDIR="$pkgdir" install
-
-  install -D -m644 COPYING "$pkgdir"/usr/share/licenses/libarchive/COPYING
+  install -Dm644 COPYING "$pkgdir/usr/share/licenses/libarchive/COPYING"
 }
diff --git a/abs/core/libarchive/libarchive-3.1.2-acl.patch b/abs/core/libarchive/libarchive-3.1.2-acl.patch
deleted file mode 100644
index ce563b0..0000000
--- a/abs/core/libarchive/libarchive-3.1.2-acl.patch
+++ /dev/null
@@ -1,219 +0,0 @@
-diff -ruN libarchive-3.1.2/libarchive/archive_read_disk_entry_from_file.c libarchive-3.1.2.fixed/libarchive/archive_read_disk_entry_from_file.c
---- libarchive-3.1.2/libarchive/archive_read_disk_entry_from_file.c	2013-02-08 01:52:07.000000000 +0100
-+++ libarchive-3.1.2.fixed/libarchive/archive_read_disk_entry_from_file.c	2013-08-08 10:47:41.000000000 +0200
-@@ -399,7 +399,7 @@
- #endif
- 
- 
--#if defined(HAVE_POSIX_ACL) && defined(ACL_TYPE_NFS4)
-+#ifdef HAVE_POSIX_ACL
- static int translate_acl(struct archive_read_disk *a,
-     struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
- 
-@@ -419,6 +419,7 @@
- 
- 	archive_entry_acl_clear(entry);
- 
-+#ifdef ACL_TYPE_NFS4
- 	/* Try NFS4 ACL first. */
- 	if (*fd >= 0)
- 		acl = acl_get_fd(*fd);
-@@ -447,6 +448,7 @@
- 		acl_free(acl);
- 		return (ARCHIVE_OK);
- 	}
-+#endif
- 
- 	/* Retrieve access ACL from file. */
- 	if (*fd >= 0)
-@@ -492,6 +494,7 @@
-         {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
-         {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
-         {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
-+#ifdef ACL_TYPE_NFS4
-         {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
-         {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
-         {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
-@@ -508,8 +511,10 @@
-         {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
-         {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
-         {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
-+#endif
- };
- 
-+#ifdef ACL_TYPE_NFS4
- static struct {
-         int archive_inherit;
-         int platform_inherit;
-@@ -519,21 +524,25 @@
- 	{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
- 	{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
- };
--
-+#endif
- static int
- translate_acl(struct archive_read_disk *a,
-     struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
- {
- 	acl_tag_t	 acl_tag;
-+#ifdef ACL_TYPE_NFS4
- 	acl_entry_type_t acl_type;
- 	acl_flagset_t	 acl_flagset;
-+	int brand, r;
-+#endif
- 	acl_entry_t	 acl_entry;
- 	acl_permset_t	 acl_permset;
--	int		 brand, i, r, entry_acl_type;
-+	int		 i, entry_acl_type;
- 	int		 s, ae_id, ae_tag, ae_perm;
- 	const char	*ae_name;
- 
- 
-+#ifdef ACL_TYPE_NFS4
- 	// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
- 	// Make sure the "brand" on this ACL is consistent
- 	// with the default_entry_acl_type bits provided.
-@@ -560,6 +569,7 @@
- 		return ARCHIVE_FAILED;
- 		break;
- 	}
-+#endif
- 
- 
- 	s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
-@@ -592,9 +602,11 @@
- 		case ACL_OTHER:
- 			ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
- 			break;
-+#ifdef ACL_TYPE_NFS4
- 		case ACL_EVERYONE:
- 			ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
- 			break;
-+#endif
- 		default:
- 			/* Skip types that libarchive can't support. */
- 			s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
-@@ -605,6 +617,7 @@
- 		// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
- 		// non-NFSv4 ACLs
- 		entry_acl_type = default_entry_acl_type;
-+#ifdef ACL_TYPE_NFS4
- 		r = acl_get_entry_type_np(acl_entry, &acl_type);
- 		if (r == 0) {
- 			switch (acl_type) {
-@@ -634,9 +647,10 @@
- 				ae_perm |= acl_inherit_map[i].archive_inherit;
- 
-                 }
-+#endif
- 
- 		acl_get_permset(acl_entry, &acl_permset);
--                for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
-+		for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
- 			/*
- 			 * acl_get_perm() is spelled differently on different
- 			 * platforms; see above.
-diff -ruN libarchive-3.1.2/libarchive/archive_write_disk_acl.c libarchive-3.1.2.fixed/libarchive/archive_write_disk_acl.c
---- libarchive-3.1.2/libarchive/archive_write_disk_acl.c	2013-01-14 02:43:45.000000000 +0100
-+++ libarchive-3.1.2.fixed/libarchive/archive_write_disk_acl.c	2013-08-08 10:31:35.000000000 +0200
-@@ -43,7 +43,7 @@
- #include "archive_acl_private.h"
- #include "archive_write_disk_private.h"
- 
--#if !defined(HAVE_POSIX_ACL) || !defined(ACL_TYPE_NFS4)
-+#ifndef HAVE_POSIX_ACL
- /* Default empty function body to satisfy mainline code. */
- int
- archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
-@@ -79,10 +79,12 @@
- 		ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
- 		    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
- 		return (ret);
-+#ifdef ACL_TYPE_NFS4
- 	} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0) {
- 		ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
- 		    ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
- 		return (ret);
-+#endif
- 	} else
- 		return ARCHIVE_OK;
- }
-@@ -94,6 +96,7 @@
- 	{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
- 	{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
- 	{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
-+#ifdef ACL_TYPE_NFS4
- 	{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
- 	{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
- 	{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
-@@ -110,8 +113,10 @@
- 	{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
- 	{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
- 	{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
-+#endif
- };
- 
-+#ifdef ACL_TYPE_NFS4
- static struct {
- 	int archive_inherit;
- 	int platform_inherit;
-@@ -121,6 +126,7 @@
- 	{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
- 	{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
- };
-+#endif
- 
- static int
- set_acl(struct archive *a, int fd, const char *name,
-@@ -130,7 +136,9 @@
- 	acl_t		 acl;
- 	acl_entry_t	 acl_entry;
- 	acl_permset_t	 acl_permset;
-+#ifdef ACL_TYPE_NFS4
- 	acl_flagset_t	 acl_flagset;
-+#endif
- 	int		 ret;
- 	int		 ae_type, ae_permset, ae_tag, ae_id;
- 	uid_t		 ae_uid;
-@@ -171,14 +179,17 @@
- 		case ARCHIVE_ENTRY_ACL_OTHER:
- 			acl_set_tag_type(acl_entry, ACL_OTHER);
- 			break;
-+#ifdef ACL_TYPE_NFS4
- 		case ARCHIVE_ENTRY_ACL_EVERYONE:
- 			acl_set_tag_type(acl_entry, ACL_EVERYONE);
- 			break;
-+#endif
- 		default:
- 			/* XXX */
- 			break;
- 		}
- 
-+#ifdef ACL_TYPE_NFS4
- 		switch (ae_type) {
- 		case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
- 			acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
-@@ -200,6 +211,7 @@
- 			// XXX error handling here.
- 			break;
- 		}
-+#endif
- 
- 		acl_get_permset(acl_entry, &acl_permset);
- 		acl_clear_perms(acl_permset);
-@@ -210,6 +222,7 @@
- 					     acl_perm_map[i].platform_perm);
- 		}
- 
-+#ifdef ACL_TYPE_NFS4
- 		acl_get_flagset_np(acl_entry, &acl_flagset);
- 		acl_clear_flags_np(acl_flagset);
- 		for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
-@@ -217,6 +230,7 @@
- 				acl_add_flag_np(acl_flagset,
- 						acl_inherit_map[i].platform_inherit);
- 		}
-+#endif
- 	}
- 
- 	/* Try restoring the ACL through 'fd' if we can. */
diff --git a/abs/core/libarchive/libarchive-3.1.2-sparce-mtree.patch b/abs/core/libarchive/libarchive-3.1.2-sparce-mtree.patch
deleted file mode 100644
index 7b40277..0000000
--- a/abs/core/libarchive/libarchive-3.1.2-sparce-mtree.patch
+++ /dev/null
@@ -1,478 +0,0 @@
-From 977bf2a49484239f7a7b6ce08bfa9da413a27ead Mon Sep 17 00:00:00 2001
-From: Florian Pritz <bluewind@xinu.at>
-Date: Sat, 1 Mar 2014 17:21:47 +0100
-Subject: [PATCH] mtree: Make reading additional information from the fs
- optional
-
-This feature is not needed if users just want to read in the content of
-an mtree file and do validation against the file system themselves.
-
-It is needed for `bsdtar cvf out.tar @input.mtree` which is why the
-option is enabled in bsdtar.
-
-Since the mtree tests rely on this feature, this patch also enables it
-there.
-
-Signed-off-by: Florian Pritz <bluewind@xinu.at>
----
- libarchive/archive_read_support_format_mtree.c | 290 ++++++++++++++-----------
- libarchive/test/test_read_format_mtree.c       |  20 ++
- tar/write.c                                    |   1 +
- 3 files changed, 179 insertions(+), 132 deletions(-)
-
-diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c
-index 44799df..d82d4c1 100644
---- a/libarchive/archive_read_support_format_mtree.c
-+++ b/libarchive/archive_read_support_format_mtree.c
-@@ -104,6 +104,7 @@ struct mtree {
- 	struct archive_entry_linkresolver *resolver;
- 
- 	int64_t			 cur_size;
-+	char checkfs;
- };
- 
- static int	bid_keycmp(const char *, const char *, ssize_t);
-@@ -174,6 +175,29 @@ static int	read_header(struct archive_read *,
- #endif
- }
- 
-+static int
-+archive_read_format_mtree_options(struct archive_read *a,
-+    const char *key, const char *val)
-+{
-+	struct mtree *mtree;
-+
-+	mtree = (struct mtree *)(a->format->data);
-+	if (strcmp(key, "checkfs")  == 0) {
-+		/* Allows to read information missing from the mtree from the file system */
-+		if (val == NULL || val[0] == 0) {
-+			mtree->checkfs = 0;
-+		} else {
-+			mtree->checkfs = 1;
-+		}
-+		return (ARCHIVE_OK);
-+	}
-+
-+	/* Note: The "warn" return is just to inform the options
-+	 * supervisor that we didn't handle it.  It will generate
-+	 * a suitable error if no one used this option. */
-+	return (ARCHIVE_WARN);
-+}
-+
- static void
- free_options(struct mtree_option *head)
- {
-@@ -206,7 +230,7 @@ static int	read_header(struct archive_read *,
- 	mtree->fd = -1;
- 
- 	r = __archive_read_register_format(a, mtree, "mtree",
--	    mtree_bid, NULL, read_header, read_data, skip, NULL, cleanup);
-+           mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup);
- 
- 	if (r != ARCHIVE_OK)
- 		free(mtree);
-@@ -1104,162 +1128,164 @@ static int	read_header(struct archive_read *,
- 			mtree->current_dir.length = n;
- 	}
- 
--	/*
--	 * Try to open and stat the file to get the real size
--	 * and other file info.  It would be nice to avoid
--	 * this here so that getting a listing of an mtree
--	 * wouldn't require opening every referenced contents
--	 * file.  But then we wouldn't know the actual
--	 * contents size, so I don't see a really viable way
--	 * around this.  (Also, we may want to someday pull
--	 * other unspecified info from the contents file on
--	 * disk.)
--	 */
--	mtree->fd = -1;
--	if (archive_strlen(&mtree->contents_name) > 0)
--		path = mtree->contents_name.s;
--	else
--		path = archive_entry_pathname(entry);
--
--	if (archive_entry_filetype(entry) == AE_IFREG ||
--	    archive_entry_filetype(entry) == AE_IFDIR) {
--		mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
--		__archive_ensure_cloexec_flag(mtree->fd);
--		if (mtree->fd == -1 &&
--		    (errno != ENOENT ||
--		     archive_strlen(&mtree->contents_name) > 0)) {
--			archive_set_error(&a->archive, errno,
--			    "Can't open %s", path);
--			r = ARCHIVE_WARN;
-+	if (mtree->checkfs) {
-+		/*
-+		 * Try to open and stat the file to get the real size
-+		 * and other file info.  It would be nice to avoid
-+		 * this here so that getting a listing of an mtree
-+		 * wouldn't require opening every referenced contents
-+		 * file.  But then we wouldn't know the actual
-+		 * contents size, so I don't see a really viable way
-+		 * around this.  (Also, we may want to someday pull
-+		 * other unspecified info from the contents file on
-+		 * disk.)
-+		 */
-+		mtree->fd = -1;
-+		if (archive_strlen(&mtree->contents_name) > 0)
-+			path = mtree->contents_name.s;
-+		else
-+			path = archive_entry_pathname(entry);
-+
-+		if (archive_entry_filetype(entry) == AE_IFREG ||
-+				archive_entry_filetype(entry) == AE_IFDIR) {
-+			mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
-+			__archive_ensure_cloexec_flag(mtree->fd);
-+			if (mtree->fd == -1 &&
-+					(errno != ENOENT ||
-+					 archive_strlen(&mtree->contents_name) > 0)) {
-+				archive_set_error(&a->archive, errno,
-+						"Can't open %s", path);
-+				r = ARCHIVE_WARN;
-+			}
- 		}
--	}
- 
--	st = &st_storage;
--	if (mtree->fd >= 0) {
--		if (fstat(mtree->fd, st) == -1) {
--			archive_set_error(&a->archive, errno,
--			    "Could not fstat %s", path);
--			r = ARCHIVE_WARN;
--			/* If we can't stat it, don't keep it open. */
--			close(mtree->fd);
--			mtree->fd = -1;
-+		st = &st_storage;
-+		if (mtree->fd >= 0) {
-+			if (fstat(mtree->fd, st) == -1) {
-+				archive_set_error(&a->archive, errno,
-+						"Could not fstat %s", path);
-+				r = ARCHIVE_WARN;
-+				/* If we can't stat it, don't keep it open. */
-+				close(mtree->fd);
-+				mtree->fd = -1;
-+				st = NULL;
-+			}
-+		} else if (lstat(path, st) == -1) {
- 			st = NULL;
- 		}
--	} else if (lstat(path, st) == -1) {
--		st = NULL;
--	}
- 
--	/*
--	 * Check for a mismatch between the type in the specification and
--	 * the type of the contents object on disk.
--	 */
--	if (st != NULL) {
--		if (
--		    ((st->st_mode & S_IFMT) == S_IFREG &&
--		     archive_entry_filetype(entry) == AE_IFREG)
-+		/*
-+		 * Check for a mismatch between the type in the specification and
-+		 * the type of the contents object on disk.
-+		 */
-+		if (st != NULL) {
-+			if (
-+					((st->st_mode & S_IFMT) == S_IFREG &&
-+					 archive_entry_filetype(entry) == AE_IFREG)
- #ifdef S_IFLNK
--		    || ((st->st_mode & S_IFMT) == S_IFLNK &&
--			archive_entry_filetype(entry) == AE_IFLNK)
-+					|| ((st->st_mode & S_IFMT) == S_IFLNK &&
-+						archive_entry_filetype(entry) == AE_IFLNK)
- #endif
- #ifdef S_IFSOCK
--		    || ((st->st_mode & S_IFSOCK) == S_IFSOCK &&
--			archive_entry_filetype(entry) == AE_IFSOCK)
-+					|| ((st->st_mode & S_IFSOCK) == S_IFSOCK &&
-+						archive_entry_filetype(entry) == AE_IFSOCK)
- #endif
- #ifdef S_IFCHR
--		    || ((st->st_mode & S_IFMT) == S_IFCHR &&
--			archive_entry_filetype(entry) == AE_IFCHR)
-+					|| ((st->st_mode & S_IFMT) == S_IFCHR &&
-+						archive_entry_filetype(entry) == AE_IFCHR)
- #endif
- #ifdef S_IFBLK
--		    || ((st->st_mode & S_IFMT) == S_IFBLK &&
--			archive_entry_filetype(entry) == AE_IFBLK)
-+					|| ((st->st_mode & S_IFMT) == S_IFBLK &&
-+						archive_entry_filetype(entry) == AE_IFBLK)
- #endif
--		    || ((st->st_mode & S_IFMT) == S_IFDIR &&
--			archive_entry_filetype(entry) == AE_IFDIR)
-+					|| ((st->st_mode & S_IFMT) == S_IFDIR &&
-+						archive_entry_filetype(entry) == AE_IFDIR)
- #ifdef S_IFIFO
--		    || ((st->st_mode & S_IFMT) == S_IFIFO &&
--			archive_entry_filetype(entry) == AE_IFIFO)
-+					|| ((st->st_mode & S_IFMT) == S_IFIFO &&
-+							archive_entry_filetype(entry) == AE_IFIFO)
- #endif
--		    ) {
--			/* Types match. */
--		} else {
--			/* Types don't match; bail out gracefully. */
--			if (mtree->fd >= 0)
--				close(mtree->fd);
--			mtree->fd = -1;
--			if (parsed_kws & MTREE_HAS_OPTIONAL) {
--				/* It's not an error for an optional entry
--				   to not match disk. */
--				*use_next = 1;
--			} else if (r == ARCHIVE_OK) {
--				archive_set_error(&a->archive,
--				    ARCHIVE_ERRNO_MISC,
--				    "mtree specification has different type for %s",
--				    archive_entry_pathname(entry));
--				r = ARCHIVE_WARN;
--			}
--			return r;
-+					) {
-+						/* Types match. */
-+					} else {
-+						/* Types don't match; bail out gracefully. */
-+						if (mtree->fd >= 0)
-+							close(mtree->fd);
-+						mtree->fd = -1;
-+						if (parsed_kws & MTREE_HAS_OPTIONAL) {
-+							/* It's not an error for an optional entry
-+							   to not match disk. */
-+							*use_next = 1;
-+						} else if (r == ARCHIVE_OK) {
-+							archive_set_error(&a->archive,
-+									ARCHIVE_ERRNO_MISC,
-+									"mtree specification has different type for %s",
-+									archive_entry_pathname(entry));
-+							r = ARCHIVE_WARN;
-+						}
-+						return r;
-+					}
- 		}
--	}
- 
--	/*
--	 * If there is a contents file on disk, pick some of the metadata
--	 * from that file.  For most of these, we only set it from the contents
--	 * if it wasn't already parsed from the specification.
--	 */
--	if (st != NULL) {
--		if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
--		     (parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
--		    (archive_entry_filetype(entry) == AE_IFCHR ||
--		     archive_entry_filetype(entry) == AE_IFBLK))
--			archive_entry_set_rdev(entry, st->st_rdev);
--		if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME)) == 0 ||
--		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
--			archive_entry_set_gid(entry, st->st_gid);
--		if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME)) == 0 ||
--		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
--			archive_entry_set_uid(entry, st->st_uid);
--		if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
--		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
-+		/*
-+		 * If there is a contents file on disk, pick some of the metadata
-+		 * from that file.  For most of these, we only set it from the contents
-+		 * if it wasn't already parsed from the specification.
-+		 */
-+		if (st != NULL) {
-+			if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
-+						(parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
-+					(archive_entry_filetype(entry) == AE_IFCHR ||
-+					 archive_entry_filetype(entry) == AE_IFBLK))
-+				archive_entry_set_rdev(entry, st->st_rdev);
-+			if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME)) == 0 ||
-+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
-+				archive_entry_set_gid(entry, st->st_gid);
-+			if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME)) == 0 ||
-+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
-+				archive_entry_set_uid(entry, st->st_uid);
-+			if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
-+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
- #if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
--			archive_entry_set_mtime(entry, st->st_mtime,
--			    st->st_mtimespec.tv_nsec);
-+				archive_entry_set_mtime(entry, st->st_mtime,
-+						st->st_mtimespec.tv_nsec);
- #elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
--			archive_entry_set_mtime(entry, st->st_mtime,
--			    st->st_mtim.tv_nsec);
-+				archive_entry_set_mtime(entry, st->st_mtime,
-+						st->st_mtim.tv_nsec);
- #elif HAVE_STRUCT_STAT_ST_MTIME_N
--			archive_entry_set_mtime(entry, st->st_mtime,
--			    st->st_mtime_n);
-+				archive_entry_set_mtime(entry, st->st_mtime,
-+						st->st_mtime_n);
- #elif HAVE_STRUCT_STAT_ST_UMTIME
--			archive_entry_set_mtime(entry, st->st_mtime,
--			    st->st_umtime*1000);
-+				archive_entry_set_mtime(entry, st->st_mtime,
-+						st->st_umtime*1000);
- #elif HAVE_STRUCT_STAT_ST_MTIME_USEC
--			archive_entry_set_mtime(entry, st->st_mtime,
--			    st->st_mtime_usec*1000);
-+				archive_entry_set_mtime(entry, st->st_mtime,
-+						st->st_mtime_usec*1000);
- #else
--			archive_entry_set_mtime(entry, st->st_mtime, 0);
-+				archive_entry_set_mtime(entry, st->st_mtime, 0);
- #endif
-+			}
-+			if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
-+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
-+				archive_entry_set_nlink(entry, st->st_nlink);
-+			if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
-+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
-+				archive_entry_set_perm(entry, st->st_mode);
-+			if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
-+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
-+				archive_entry_set_size(entry, st->st_size);
-+			archive_entry_set_ino(entry, st->st_ino);
-+			archive_entry_set_dev(entry, st->st_dev);
-+
-+			archive_entry_linkify(mtree->resolver, &entry, &sparse_entry);
-+		} else if (parsed_kws & MTREE_HAS_OPTIONAL) {
-+			/*
-+			 * Couldn't open the entry, stat it or the on-disk type
-+			 * didn't match.  If this entry is optional, just ignore it
-+			 * and read the next header entry.
-+			 */
-+			*use_next = 1;
-+			return ARCHIVE_OK;
- 		}
--		if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
--		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
--			archive_entry_set_nlink(entry, st->st_nlink);
--		if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
--		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
--			archive_entry_set_perm(entry, st->st_mode);
--		if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
--		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
--			archive_entry_set_size(entry, st->st_size);
--		archive_entry_set_ino(entry, st->st_ino);
--		archive_entry_set_dev(entry, st->st_dev);
--
--		archive_entry_linkify(mtree->resolver, &entry, &sparse_entry);
--	} else if (parsed_kws & MTREE_HAS_OPTIONAL) {
--		/*
--		 * Couldn't open the entry, stat it or the on-disk type
--		 * didn't match.  If this entry is optional, just ignore it
--		 * and read the next header entry.
--		 */
--		*use_next = 1;
--		return ARCHIVE_OK;
- 	}
- 
- 	mtree->cur_size = archive_entry_size(entry);
-diff --git a/libarchive/test/test_read_format_mtree.c b/libarchive/test/test_read_format_mtree.c
-index 830fa0a..f96529d 100644
---- a/libarchive/test/test_read_format_mtree.c
-+++ b/libarchive/test/test_read_format_mtree.c
-@@ -58,6 +58,8 @@
- 	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_support_format_all(a));
- 	assertEqualIntA(a, ARCHIVE_OK,
-+	    archive_read_set_options(a, "mtree:checkfs"));
-+	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_open_filename(a, reffile, 11));
- 
- 	/*
-@@ -209,6 +211,8 @@
- 	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_support_format_all(a));
- 	assertEqualIntA(a, ARCHIVE_OK,
-+	    archive_read_set_options(a, "mtree:checkfs"));
-+	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_open_memory(a, archive, sizeof(archive)));
- 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
- 	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
-@@ -246,6 +250,8 @@
- 	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_support_format_all(a));
- 	assertEqualIntA(a, ARCHIVE_OK,
-+	    archive_read_set_options(a, "mtree:checkfs"));
-+	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_open_memory(a, archive, sizeof(archive)));
- 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
- 	assertEqualString(archive_entry_pathname(ae), "a");
-@@ -299,6 +305,8 @@
- 	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_support_format_all(a));
- 	assertEqualIntA(a, ARCHIVE_OK,
-+	    archive_read_set_options(a, "mtree:checkfs"));
-+	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_open_memory(a, archive, sizeof(archive)));
- 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
- 	assertEqualString(archive_entry_pathname(ae), "./a");	
-@@ -365,6 +373,8 @@
- 	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_support_format_all(a));
- 	assertEqualIntA(a, ARCHIVE_OK,
-+	    archive_read_set_options(a, "mtree:checkfs"));
-+	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_open_memory(a, archive, sizeof(archive)));
- 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
- 	assertEqualString(archive_entry_pathname(ae), "./a");
-@@ -402,6 +412,8 @@
- 	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_support_format_all(a));
- 	assertEqualIntA(a, ARCHIVE_OK,
-+	    archive_read_set_options(a, "mtree:checkfs"));
-+	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_open_memory(a, archive2, sizeof(archive2)));
- 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
- 	assertEqualString(archive_entry_pathname(ae), "./a");
-@@ -449,6 +461,8 @@
- 	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_support_format_all(a));
- 	assertEqualIntA(a, ARCHIVE_OK,
-+	    archive_read_set_options(a, "mtree:checkfs"));
-+	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_open_filename(a, reffile, 11));
- 
- 	/*
-@@ -552,6 +566,8 @@
- 	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_support_format_all(a));
- 	assertEqualIntA(a, ARCHIVE_OK,
-+	    archive_read_set_options(a, "mtree:checkfs"));
-+	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_open_filename(a, reffile, 11));
- 
- 	/*
-@@ -617,6 +633,8 @@
- 	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_support_format_all(a));
- 	assertEqualIntA(a, ARCHIVE_OK,
-+	    archive_read_set_options(a, "mtree:checkfs"));
-+	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_open_filename(a, reffile, 11));
- 
- 	/*
-@@ -680,6 +698,8 @@
- 	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_support_format_all(a));
- 	assertEqualIntA(a, ARCHIVE_OK,
-+	    archive_read_set_options(a, "mtree:checkfs"));
-+	assertEqualIntA(a, ARCHIVE_OK,
- 	    archive_read_open_memory(a, archive, sizeof(archive)));
- 	assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
- 	assert(strlen(archive_error_string(a)) > 0);
-diff --git a/tar/write.c b/tar/write.c
-index 40d2fb0..7e8cb13 100644
---- a/tar/write.c
-+++ b/tar/write.c
-@@ -648,6 +648,7 @@ static void		 write_hierarchy(struct bsdtar *, struct archive *,
- 	archive_read_support_format_all(ina);
- 	archive_read_support_filter_all(ina);
- 	set_reader_options(bsdtar, a);
-+	archive_read_set_options(ina, "mtree:checkfs");
- 	if (archive_read_open_filename(ina, filename,
- 					bsdtar->bytes_per_block)) {
- 		lafe_warnc(0, "%s", archive_error_string(ina));
--- 
-1.8.5.5
-
-- 
cgit v0.12

