Merge pull request #875 from tpgxyz/master

fix liblzma.h detect
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 048847b..dbbf797 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -572,6 +572,11 @@
 LA_CHECK_INCLUDE_FILE("linux/types.h" HAVE_LINUX_TYPES_H)
 LA_CHECK_INCLUDE_FILE("linux/fiemap.h" HAVE_LINUX_FIEMAP_H)
 LA_CHECK_INCLUDE_FILE("linux/fs.h" HAVE_LINUX_FS_H)
+
+CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
+#include <linux/fs.h>
+int main(void) { return FS_IOC_GETFLAGS; }" HAVE_WORKING_FS_IOC_GETFLAGS)
+
 LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H)
 LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H)
 LA_CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H)
diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in
index ec64d99..923a78e 100644
--- a/build/cmake/config.h.in
+++ b/build/cmake/config.h.in
@@ -1099,6 +1099,9 @@
 /* Define to 1 if you have a working EXT2_IOC_GETFLAGS */
 #cmakedefine HAVE_WORKING_EXT2_IOC_GETFLAGS 1
 
+/* Define to 1 if you have a working FS_IOC_GETFLAGS */
+#cmakedefine HAVE_WORKING_FS_IOC_GETFLAGS 1
+
 /* Define to 1 if you have the <zlib.h> header file. */
 #cmakedefine HAVE_ZLIB_H 1
 
diff --git a/configure.ac b/configure.ac
index 0c054cc..b29917e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -270,6 +270,19 @@
 
 AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h])
 AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h linux/types.h])
+
+AC_CACHE_CHECK([whether FS_IOC_GETFLAGS is usable],
+    [ac_cv_have_decl_FS_IOC_GETFLAGS],
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <sys/ioctl.h>
+@%:@include <linux/fs.h>],
+                                   [int x = FS_IOC_GETFLAGS])],
+                  [AS_VAR_SET([ac_cv_have_decl_FS_IOC_GETFLAGS], [yes])],
+                  [AS_VAR_SET([ac_cv_have_decl_FS_IOC_GETFLAGS], [no])])])
+
+AS_VAR_IF([ac_cv_have_decl_FS_IOC_GETFLAGS], [yes],
+    [AC_DEFINE_UNQUOTED([HAVE_WORKING_FS_IOC_GETFLAGS], [1],
+                    [Define to 1 if you have a working FS_IOC_GETFLAGS])])
+
 AC_CHECK_HEADERS([locale.h paths.h poll.h pthread.h pwd.h])
 AC_CHECK_HEADERS([readpassphrase.h signal.h spawn.h])
 AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h])
diff --git a/libarchive/archive.h b/libarchive/archive.h
index 20fa09b..e74be4d 100644
--- a/libarchive/archive.h
+++ b/libarchive/archive.h
@@ -1003,6 +1003,8 @@
 #define	ARCHIVE_READDISK_NO_XATTR		(0x0010)
 /* Default: ACLs are read from disk. */
 #define	ARCHIVE_READDISK_NO_ACL			(0x0020)
+/* Default: File flags are read from disk. */
+#define	ARCHIVE_READDISK_NO_FFLAGS		(0x0040)
 
 __LA_DECL int  archive_read_disk_set_behavior(struct archive *,
 		    int flags);
diff --git a/libarchive/archive_entry.c b/libarchive/archive_entry.c
index d4f061b..10eff11 100644
--- a/libarchive/archive_entry.c
+++ b/libarchive/archive_entry.c
@@ -1649,7 +1649,10 @@
 	{ "nosappnd",	L"nosappnd",		SF_APPEND,	0 },
 	{ "nosappend",	L"nosappend",		SF_APPEND,	0 },
 #endif
-#ifdef  EXT2_APPEND_FL				/* 'a' */
+#if defined(FS_APPEND_FL)			/* 'a' */
+	{ "nosappnd",	L"nosappnd",		FS_APPEND_FL,	0 },
+	{ "nosappend",	L"nosappend",		FS_APPEND_FL,	0 },
+#elif defined(EXT2_APPEND_FL)			/* 'a' */
 	{ "nosappnd",	L"nosappnd",		EXT2_APPEND_FL,	0 },
 	{ "nosappend",	L"nosappend",		EXT2_APPEND_FL,	0 },
 #endif
@@ -1662,7 +1665,11 @@
 	{ "noschange",	L"noschange",		SF_IMMUTABLE,	0 },
 	{ "nosimmutable",	L"nosimmutable",	SF_IMMUTABLE,	0 },
 #endif
-#ifdef EXT2_IMMUTABLE_FL			/* 'i' */
+#if defined(FS_IMMUTABLE_FL)			/* 'i' */
+	{ "noschg",	L"noschg",		FS_IMMUTABLE_FL,	0 },
+	{ "noschange",	L"noschange",		FS_IMMUTABLE_FL,	0 },
+	{ "nosimmutable",	L"nosimmutable",	FS_IMMUTABLE_FL,	0 },
+#elif defined(EXT2_IMMUTABLE_FL)		/* 'i' */
 	{ "noschg",	L"noschg",		EXT2_IMMUTABLE_FL,	0 },
 	{ "noschange",	L"noschange",		EXT2_IMMUTABLE_FL,	0 },
 	{ "nosimmutable",	L"nosimmutable",	EXT2_IMMUTABLE_FL,	0 },
@@ -1686,7 +1693,9 @@
 #ifdef UF_NODUMP
 	{ "nodump",	L"nodump",		0,		UF_NODUMP},
 #endif
-#ifdef EXT2_NODUMP_FL				/* 'd' */
+#if defined(FS_NODUMP_FL)	/* 'd' */
+	{ "nodump",	L"nodump",		0,		FS_NODUMP_FL},
+#elif defined(EXT2_NODUMP_FL) 	/* 'd' */
 	{ "nodump",	L"nodump",		0,		EXT2_NODUMP_FL},
 #endif
 #ifdef UF_OPAQUE
@@ -1699,65 +1708,124 @@
 #ifdef UF_COMPRESSED
 	{ "nocompressed",L"nocompressed",	UF_COMPRESSED,	0 },
 #endif
-#ifdef EXT2_UNRM_FL
+#if defined(FS_UNRM_FL)
+        { "nouunlink",	L"nouunlink",		FS_UNRM_FL,	0},
+#elif defined(EXT2_UNRM_FL)
         { "nouunlink",	L"nouunlink",		EXT2_UNRM_FL,	0},
 #endif
 
-#ifdef EXT2_BTREE_FL
+#if defined(FS_BTREE_FL)
+        { "nobtree",	L"nobtree",       	FS_BTREE_FL,	0 },
+#elif defined(EXT2_BTREE_FL)
         { "nobtree",	L"nobtree",       	EXT2_BTREE_FL,	0 },
 #endif
 
-#ifdef EXT2_ECOMPR_FL
+#if defined(FS_ECOMPR_FL)
+        { "nocomperr",	L"nocomperr",       	FS_ECOMPR_FL,	0 },
+#elif defined(EXT2_ECOMPR_FL)
         { "nocomperr",	L"nocomperr",       	EXT2_ECOMPR_FL,	0 },
 #endif
 
-#ifdef EXT2_COMPR_FL				/* 'c' */
+#if defined(FS_COMPR_FL)			/* 'c' */
+        { "nocompress",	L"nocompress",       	FS_COMPR_FL,	0 },
+#elif defined(EXT2_COMPR_FL)			/* 'c' */
         { "nocompress",	L"nocompress",       	EXT2_COMPR_FL,	0 },
 #endif
 
-#ifdef EXT2_NOATIME_FL				/* 'A' */
+#if defined(FS_NOATIME_FL)			/* 'A' */
+        { "noatime",	L"noatime",		0,		FS_NOATIME_FL},
+#elif defined(EXT2_NOATIME_FL)			/* 'A' */
         { "noatime",	L"noatime",		0,		EXT2_NOATIME_FL},
 #endif
 
-#ifdef EXT2_DIRTY_FL
+#if defined(FS_DIRTY_FL)
+        { "nocompdirty",L"nocompdirty",		FS_DIRTY_FL,		0},
+#elif defined(EXT2_DIRTY_FL)
         { "nocompdirty",L"nocompdirty",		EXT2_DIRTY_FL,		0},
 #endif
 
-#ifdef EXT2_COMPRBLK_FL
-#ifdef EXT2_NOCOMPR_FL
+#if defined(FS_COMPRBLK_FL)
+#if defined(FS_NOCOMPR_FL)
+        { "nocomprblk",	L"nocomprblk",		FS_COMPRBLK_FL, FS_NOCOMPR_FL},
+#else
+        { "nocomprblk",	L"nocomprblk",		FS_COMPRBLK_FL,	0},
+#endif
+#elif defined(EXT2_COMPRBLK_FL)
+#if defined(EXT2_NOCOMPR_FL)
         { "nocomprblk",	L"nocomprblk",		EXT2_COMPRBLK_FL, EXT2_NOCOMPR_FL},
 #else
         { "nocomprblk",	L"nocomprblk",		EXT2_COMPRBLK_FL,	0},
 #endif
 #endif
-#ifdef EXT2_DIRSYNC_FL
+#if defined(FS_DIRSYNC_FL)
+        { "nodirsync",	L"nodirsync",		FS_DIRSYNC_FL,	0},
+#elif defined(EXT2_DIRSYNC_FL)
         { "nodirsync",	L"nodirsync",		EXT2_DIRSYNC_FL,	0},
 #endif
-#ifdef EXT2_INDEX_FL
+#if defined(FS_INDEX_FL)
+        { "nohashidx",	L"nohashidx",		FS_INDEX_FL,		0},
+#elif defined(EXT2_INDEX_FL)
         { "nohashidx",	L"nohashidx",		EXT2_INDEX_FL,		0},
 #endif
-#ifdef EXT2_IMAGIC_FL
+#if defined(FS_IMAGIC_FL)
+        { "noimagic",	L"noimagic",		FS_IMAGIC_FL,		0},
+#elif defined(EXT2_IMAGIC_FL)
         { "noimagic",	L"noimagic",		EXT2_IMAGIC_FL,		0},
 #endif
-#ifdef EXT3_JOURNAL_DATA_FL
+#if defined(FS_JOURNAL_DATA_FL)
+        { "nojournal",	L"nojournal",		FS_JOURNAL_DATA_FL,	0},
+#elif defined(EXT3_JOURNAL_DATA_FL)
         { "nojournal",	L"nojournal",		EXT3_JOURNAL_DATA_FL,	0},
 #endif
-#ifdef EXT2_SECRM_FL
+#if defined(FS_SECRM_FL)
+        { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL,		0},
+#elif defined(EXT2_SECRM_FL)
         { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL,		0},
 #endif
-#ifdef EXT2_SYNC_FL
+#if defined(FS_SYNC_FL)
+        { "nosync",	L"nosync",		FS_SYNC_FL,		0},
+#elif defined(EXT2_SYNC_FL)
         { "nosync",	L"nosync",		EXT2_SYNC_FL,		0},
 #endif
-#ifdef EXT2_NOTAIL_FL
+#if defined(FS_NOTAIL_FL)
+        { "notail",	L"notail",		0,		FS_NOTAIL_FL},
+#elif defined(EXT2_NOTAIL_FL)
         { "notail",	L"notail",		0,		EXT2_NOTAIL_FL},
 #endif
-#ifdef EXT2_TOPDIR_FL
+#if defined(FS_TOPDIR_FL)
+        { "notopdir",	L"notopdir",		FS_TOPDIR_FL,		0},
+#elif defined(EXT2_TOPDIR_FL)
         { "notopdir",	L"notopdir",		EXT2_TOPDIR_FL,		0},
 #endif
-#ifdef EXT2_RESERVED_FL
+#ifdef FS_ENCRYPT_FL
+        { "noencrypt",	L"noencrypt",		FS_ENCRYPT_FL,	0},
+#endif
+#ifdef FS_HUGE_FILE_FL
+        { "nohugefile",	L"nohugefile",		FS_HUGE_FILE_FL,	0},
+#endif
+#ifdef FS_EXTENT_FL
+        { "noextent",	L"noextent",		FS_EXTENT_FL,	0},
+#endif
+#ifdef FS_EA_INODE_FL
+        { "noeainode",	L"noeainode",		FS_EA_INODE_FL,	0},
+#endif
+#ifdef FS_EOFBLOCKS_FL
+        { "noeofblocks",L"noeofblocks",		FS_EOFBLOCKS_FL,	0},
+#endif
+#ifdef FS_NOCOW_FL
+        { "nocow",	L"nocow",		FS_NOCOW_FL,	0},
+#endif
+#ifdef FS_INLINE_DATA_FL
+        { "noinlinedata",L"noinlinedata",	FS_INLINE_DATA_FL,	0},
+#endif
+#ifdef FS_PROJINHERIT_FL
+        { "noprojinherit",L"noprojinherit",	FS_PROJINHERIT_FL,	0},
+#endif
+#if defined(FS_RESERVED_FL)
+        { "noreserved",	L"noreserved",		FS_RESERVED_FL,	0},
+#elif defined(EXT2_RESERVED_FL)
         { "noreserved",	L"noreserved",		EXT2_RESERVED_FL,	0},
 #endif
-
 	{ NULL,		NULL,			0,		0 }
 };
 
diff --git a/libarchive/archive_hmac.c b/libarchive/archive_hmac.c
index 1e0ae28..f299655 100644
--- a/libarchive/archive_hmac.c
+++ b/libarchive/archive_hmac.c
@@ -76,6 +76,10 @@
 
 #elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
 
+#ifndef BCRYPT_HASH_REUSABLE_FLAG
+# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020
+#endif
+
 static int
 __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
 {
diff --git a/libarchive/archive_read_disk_entry_from_file.c b/libarchive/archive_read_disk_entry_from_file.c
index 1e20bea..b2f1d17 100644
--- a/libarchive/archive_read_disk_entry_from_file.c
+++ b/libarchive/archive_read_disk_entry_from_file.c
@@ -203,15 +203,17 @@
 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
 	/* On FreeBSD, we get flags for free with the stat. */
 	/* TODO: Does this belong in copy_stat()? */
-	if (st->st_flags != 0)
+	if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 && st->st_flags != 0)
 		archive_entry_set_fflags(entry, st->st_flags, 0);
 #endif
 
-#if defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+#if (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+    (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
 	/* Linux requires an extra ioctl to pull the flags.  Although
 	 * this is an extra step, it has a nice side-effect: We get an
 	 * open file descriptor which we can use in the subsequent lookups. */
-	if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
+	if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 &&
+	    (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
 		if (fd < 0) {
 			if (a->tree != NULL)
 				fd = a->open_on_current_dir(a->tree, path,
@@ -223,7 +225,13 @@
 		}
 		if (fd >= 0) {
 			int stflags;
-			r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
+			r = ioctl(fd,
+#if defined(FS_IOC_GETFLAGS)
+			    FS_IOC_GETFLAGS,
+#else
+			    EXT2_IOC_GETFLAGS,
+#endif
+			    &stflags);
 			if (r == 0 && stflags != 0)
 				archive_entry_set_fflags(entry, stflags, 0);
 		}
diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c
index 7f7823a..6961ae6 100644
--- a/libarchive/archive_read_disk_posix.c
+++ b/libarchive/archive_read_disk_posix.c
@@ -981,8 +981,10 @@
 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
 		if (st->st_flags & UF_NODUMP)
 			return (ARCHIVE_RETRY);
-#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) &&\
-      defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+#elif (defined(FS_IOC_GETFLAGS) && defined(FS_NODUMP_FL) && \
+       defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+      (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) && \
+       defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
 		if (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) {
 			int stflags;
 
@@ -991,9 +993,18 @@
 			    O_RDONLY | O_NONBLOCK | O_CLOEXEC);
 			__archive_ensure_cloexec_flag(t->entry_fd);
 			if (t->entry_fd >= 0) {
-				r = ioctl(t->entry_fd, EXT2_IOC_GETFLAGS,
+				r = ioctl(t->entry_fd,
+#ifdef FS_IOC_GETFLAGS
+				FS_IOC_GETFLAGS,
+#else
+				EXT2_IOC_GETFLAGS,
+#endif
 					&stflags);
+#ifdef FS_NODUMP_FL
+				if (r == 0 && (stflags & FS_NODUMP_FL) != 0)
+#else
 				if (r == 0 && (stflags & EXT2_NODUMP_FL) != 0)
+#endif
 					return (ARCHIVE_RETRY);
 			}
 		}
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
index 20450ba..5a01e84 100644
--- a/libarchive/archive_write_disk_posix.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -1712,7 +1712,8 @@
 		const void *metadata;
 		size_t metadata_size;
 		metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
-		if (metadata == NULL || metadata_size == 0) {
+		if ((a->todo & TODO_MAC_METADATA) == 0 ||
+		    metadata == NULL || metadata_size == 0) {
 #endif
 		r2 = archive_write_disk_set_acls(&a->archive, a->fd,
 		    archive_entry_pathname(a->entry),
@@ -2293,7 +2294,8 @@
 			chmod(p->name, p->mode);
 		if (p->fixup & TODO_ACLS)
 #ifdef HAVE_DARWIN_ACL
-			if (p->mac_metadata == NULL ||
+			if ((p->fixup & TODO_MAC_METADATA) == 0 ||
+			    p->mac_metadata == NULL ||
 			    p->mac_metadata_size == 0)
 #endif
 				archive_write_disk_set_acls(&a->archive,
@@ -3465,12 +3467,19 @@
 #ifdef UF_APPEND
 	critical_flags |= UF_APPEND;
 #endif
-#ifdef EXT2_APPEND_FL
+#if defined(FS_APPEND_FL)
+	critical_flags |= FS_APPEND_FL;
+#elif defined(EXT2_APPEND_FL)
 	critical_flags |= EXT2_APPEND_FL;
 #endif
-#ifdef EXT2_IMMUTABLE_FL
+#if defined(FS_IMMUTABLE_FL)
+	critical_flags |= FS_IMMUTABLE_FL;
+#elif defined(EXT2_IMMUTABLE_FL)
 	critical_flags |= EXT2_IMMUTABLE_FL;
 #endif
+#ifdef FS_JOURNAL_DATA_FL
+	critical_flags |= FS_JOURNAL_DATA_FL;
+#endif
 
 	if (a->todo & TODO_FFLAGS) {
 		archive_entry_fflags(a->entry, &set, &clear);
@@ -3582,7 +3591,10 @@
 	return (ARCHIVE_WARN);
 }
 
-#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+#elif (defined(FS_IOC_GETFLAGS) && defined(FS_IOC_SETFLAGS) && \
+       defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+      (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && \
+       defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
 /*
  * Linux uses ioctl() to read and write file flags.
  */
@@ -3595,7 +3607,7 @@
 	int newflags, oldflags;
 	int sf_mask = 0;
 
-	if (set == 0  && clear == 0)
+	if (set == 0 && clear == 0)
 		return (ARCHIVE_OK);
 	/* Only regular files and dirs can have flags. */
 	if (!S_ISREG(mode) && !S_ISDIR(mode))
@@ -3616,12 +3628,19 @@
 	 * defines. (?)  The code below degrades reasonably gracefully
 	 * if sf_mask is incomplete.
 	 */
-#ifdef EXT2_IMMUTABLE_FL
+#if defined(FS_IMMUTABLE_FL)
+	sf_mask |= FS_IMMUTABLE_FL;
+#elif defined(EXT2_IMMUTABLE_FL)
 	sf_mask |= EXT2_IMMUTABLE_FL;
 #endif
-#ifdef EXT2_APPEND_FL
+#if defined(FS_APPEND_FL)
+	sf_mask |= FS_APPEND_FL;
+#elif defined(EXT2_APPEND_FL)
 	sf_mask |= EXT2_APPEND_FL;
 #endif
+#if defined(FS_JOURNAL_DATA_FL)
+	sf_mask |= FS_JOURNAL_DATA_FL;
+#endif
 	/*
 	 * XXX As above, this would be way simpler if we didn't have
 	 * to read the current flags from disk. XXX
@@ -3629,12 +3648,24 @@
 	ret = ARCHIVE_OK;
 
 	/* Read the current file flags. */
-	if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) < 0)
+	if (ioctl(myfd,
+#ifdef FS_IOC_GETFLAGS
+	    FS_IOC_GETFLAGS,
+#else
+	    EXT2_IOC_GETFLAGS,
+#endif
+	    &oldflags) < 0)
 		goto fail;
 
 	/* Try setting the flags as given. */
 	newflags = (oldflags & ~clear) | set;
-	if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+	if (ioctl(myfd,
+#ifdef FS_IOC_SETFLAGS
+	    FS_IOC_SETFLAGS,
+#else
+	    EXT2_IOC_SETFLAGS,
+#endif
+	    &newflags) >= 0)
 		goto cleanup;
 	if (errno != EPERM)
 		goto fail;
@@ -3643,7 +3674,13 @@
 	newflags &= ~sf_mask;
 	oldflags &= sf_mask;
 	newflags |= oldflags;
-	if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+	if (ioctl(myfd,
+#ifdef FS_IOC_SETFLAGS
+	    FS_IOC_SETFLAGS,
+#else
+	    EXT2_IOC_SETFLAGS,
+#endif
+	    &newflags) >= 0)
 		goto cleanup;
 
 	/* We couldn't set the flags, so report the failure. */
diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c
index 4e91097..c0ca435 100644
--- a/libarchive/archive_write_set_format_iso9660.c
+++ b/libarchive/archive_write_set_format_iso9660.c
@@ -4074,8 +4074,10 @@
 	memset(info.s, 0, info_size);
 	opt = 0;
 #if defined(HAVE__CTIME64_S)
-	__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
-	_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
+	{
+		__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
+		_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
+	}
 #elif defined(HAVE_CTIME_R)
 	ctime_r(&(iso9660->birth_time), buf);
 #else
diff --git a/libarchive/test/test_fuzz.c b/libarchive/test/test_fuzz.c
index 71bf3ff..ce7b866 100644
--- a/libarchive/test/test_fuzz.c
+++ b/libarchive/test/test_fuzz.c
@@ -110,8 +110,9 @@
 		} else {
 			for (i = 0; filesets[n].names[i] != NULL; ++i)
 			{
+				char *newraw;
 				tmp = slurpfile(&size, filesets[n].names[i]);
-				char *newraw = realloc(rawimage, oldsize + size);
+				newraw = realloc(rawimage, oldsize + size);
 				if (!assert(newraw != NULL))
 				{
 					free(rawimage);
diff --git a/tar/bsdtar.1 b/tar/bsdtar.1
index 9eadaaf..b60f09c 100644
--- a/tar/bsdtar.1
+++ b/tar/bsdtar.1
@@ -1,4 +1,5 @@
 .\" Copyright (c) 2003-2007 Tim Kientzle
+.\" Copyright (c) 2017 Martin Matuska
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -24,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 16, 2014
+.Dd February 24, 2017
 .Dt TAR 1
 .Os
 .Sh NAME
@@ -124,7 +125,7 @@
 all operating modes.
 .Bl -tag -width indent
 .It Cm @ Ns Pa archive
-(c and r mode only)
+(c and r modes only)
 The specified archive is opened and the entries
 in it will be appended to the current archive.
 As a simple example,
@@ -164,6 +165,16 @@
 .Dl Nm Fl a Fl jcf Pa archive.xxx source.c source.h
 if it is unknown suffix or no suffix, creates a new archive with
 restricted pax format and bzip2 compression.
+.It Fl Fl acls
+(c, r, u, x modes only)
+Archive or extract POSIX.1e or NFSv4 ACLs. This is the reverse of
+.Fl Fl no-acls
+and the default behavior in c, r, and u modes (except Mac OS X) or if
+.Nm
+is run in x mode as root. On Mac OS X this option translates extended ACLs
+to NFSv4 ACLs. To store extended ACLs the
+.Fl Fl mac-metadata
+option is preferred.
 .It Fl B , Fl Fl read-full-blocks
 Ignored for compatibility with other
 .Xr tar 1
@@ -188,15 +199,18 @@
 (x mode only)
 Before removing file system objects to replace them, clear platform-specific
 file flags that might prevent removal.
-.It Fl Fl disable-copyfile
-Mac OS X specific.
-Disable the use of
-.Xr copyfile 3 .
 .It Fl Fl exclude Ar pattern
 Do not process files or directories that match the
 specified pattern.
 Note that exclusions take precedence over patterns or filenames
 specified on the command line.
+.It Fl Fl fflags
+(c, r, u, x modes only)
+Archive or extract file flags. This is the reverse of
+.Fl Fl no-fflags
+and the default behavior in c, r, and u modes or if
+.Nm
+is run in x mode as root.
 .It Fl Fl format Ar format
 (c, r, u mode only)
 Use the specified format for the created archive.
@@ -245,11 +259,11 @@
 in the archive;
 the name will not be verified against the system group database.
 .It Fl H
-(c and r mode only)
+(c and r modes only)
 Symbolic links named on the command line will be followed; the
 target of the link will be archived, not the link itself.
 .It Fl h
-(c and r mode only)
+(c and r modes only)
 Synonym for
 .Fl L .
 .It Fl I
@@ -259,7 +273,8 @@
 Show usage.
 .It Fl Fl hfsCompression
 (x mode only)
-Mac OS X specific(v10.6 or later). Compress extracted regular files with HFS+ compression.
+Mac OS X specific (v10.6 or later). Compress extracted regular files with HFS+
+compression.
 .It Fl Fl ignore-zeros
 An alias of
 .Fl Fl options Cm read_concatenated_archives
@@ -310,7 +325,7 @@
 Do not overwrite existing files that are newer than the
 versions appearing in the archive being extracted.
 .It Fl L , Fl Fl dereference
-(c and r mode only)
+(c and r modes only)
 All symbolic links will be followed.
 Normally, symbolic links are archived as such.
 With this option, the target of the link will be archived instead.
@@ -345,6 +360,16 @@
 (x mode only)
 Do not extract modification time.
 By default, the modification time is set to the time stored in the archive.
+.It Fl Fl mac-metadata
+(c, r, u and x mode only)
+Mac OS X specific. Archive or extract extended ACLs and extended attributes
+using
+.Xr copyfile 3
+in AppleDouble format. This is the reverse of
+.Fl Fl no-mac-metadata .
+and the default behavior in c, r, and u modes or if
+.Nm
+is run in x mode as root.
 .It Fl n , Fl Fl norecurse , Fl Fl no-recursion
 (c, r, u modes only)
 Do not recursively archive the contents of directories.
@@ -385,6 +410,30 @@
 .Fl print0
 option to
 .Xr find 1 .
+.It Fl Fl no-acls
+(c, r, u, x modes only)
+Do not archive or extract POSIX.1e or NFSv4 ACLs. This is the reverse of
+.Fl Fl acls
+and the default behavior if
+.Nm
+is run as non-root in x mode (on Mac OS X also in c, r and u modes).
+.It Fl Fl no-fflags
+(c, r, u, x modes only)
+Do not archive or extract file flags. This is the reverse of
+.Fl Fl fflags
+and the default behavior if
+.Nm
+is run as non-root in x mode.
+.It Fl Fl no-mac-metadata
+(x mode only)
+Mac OS X specific. Do not archive or extract ACLs and extended attributes using
+.Xr copyfile 3
+in AppleDouble format. This is the reverse of
+.Fl Fl mac-metadata .
+and the default behavior if
+.Nm
+is run as non-root in x mode.
+.It Fl n , Fl Fl norecurse , Fl Fl no-recursion
 .It Fl Fl no-same-owner
 (x mode only)
 Do not extract owner and group IDs.
@@ -401,7 +450,21 @@
 .Fl p
 and the default behavior if
 .Nm
-is run as non-root.
+is run as non-root and can be overridden by also specifying
+.Fl Fl acls ,
+.Fl Fl fflags ,
+.Fl Fl mac-metadata,
+.Fl Fl same-owner ,
+.Fl Fl same-permissions
+and
+.Fl Fl xattrs .
+.It Fl Fl no-xattrs
+(c, r, u, x modes only)
+Do not archive or extract extended attributes. This is the reverse of
+.Fl Fl xattrs
+and the default behavior if
+.Nm
+is run as non-root in x mode.
 .It Fl Fl numeric-owner
 This is equivalent to
 .Fl Fl uname
@@ -583,14 +646,18 @@
 .It Fl p , Fl Fl insecure , Fl Fl preserve-permissions
 (x mode only)
 Preserve file permissions.
-Attempt to restore the full permissions, including owner, file modes, file
-flags and ACLs, if available, for each item extracted from the archive.
-This is the default, if
+Attempt to restore the full permissions, including owner, file modes, ACLs,
+extended atributes and extended file flags, if available, for each item
+extracted from the archive. This is the default, if
 .Nm
 is being run by root and can be overridden by also specifying
-.Fl Fl no-same-owner
+.Fl Fl no-acls ,
+.Fl Fl no-fflags ,
+.Fl Fl no-mac-metadata,
+.Fl Fl no-same-owner ,
+.Fl Fl no-same-permissions
 and
-.Fl Fl no-same-permissions .
+.Fl Fl no-xattrs .
 .It Fl Fl passphrase Ar passphrase
 The
 .Pa passphrase
@@ -692,7 +759,7 @@
 .Fl n
 as well.
 .It Fl Fl totals
-(c, r, u mode only)
+(c, r, u modes only)
 After archiving all files, print a summary to stderr.
 .It Fl U , Fl Fl unlink , Fl Fl unlink-first
 (x mode only)
@@ -754,6 +821,13 @@
 See
 .Fl Fl exclude
 for more information about the handling of exclusions.
+.It Fl Fl xattrs
+(c, r, u, x modes only)
+Archive or extract extended attributes. This is the reverse of
+.Fl Fl no-xattrs
+and the default behavior in c, r, and u modes or if
+.Nm
+is run in x mode as root.
 .It Fl y
 (c mode only)
 Compress the resulting archive with
diff --git a/tar/bsdtar.c b/tar/bsdtar.c
index 8c7ffe8..a9252a5 100644
--- a/tar/bsdtar.c
+++ b/tar/bsdtar.c
@@ -232,6 +232,14 @@
 	if (getenv(COPYFILE_DISABLE_VAR))
 		bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_MAC_COPYFILE;
 #endif
+#if defined(__APPLE__)
+	/*
+	 * On Mac OS ACLs are archived with copyfile() (--mac-metadata)
+	 * Translation to NFSv4 ACLs has to be requested explicitly with --acls
+	 */
+	bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_ACL;
+#endif
+
 	bsdtar->matching = archive_match_new();
 	if (bsdtar->matching == NULL)
 		lafe_errc(1, errno, "Out of memory");
@@ -253,6 +261,11 @@
 		case 'a': /* GNU tar */
 			bsdtar->flags |= OPTFLAG_AUTO_COMPRESS;
 			break;
+		case OPTION_ACLS: /* GNU tar */
+			bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL;
+			bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_ACL;
+			bsdtar->flags |= OPTFLAG_ACLS;
+			break;
 		case 'B': /* GNU tar */
 			/* libarchive doesn't need this; just ignore it. */
 			break;
@@ -293,15 +306,17 @@
 			bsdtar->extract_flags |=
 			    ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS;
 			break;
-		case OPTION_DISABLE_COPYFILE: /* Mac OS X */
-			bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_MAC_COPYFILE;
-			break;
 		case OPTION_EXCLUDE: /* GNU tar */
 			if (archive_match_exclude_pattern(
 			    bsdtar->matching, bsdtar->argument) != ARCHIVE_OK)
 				lafe_errc(1, 0,
 				    "Couldn't exclude %s\n", bsdtar->argument);
 			break;
+		case OPTION_FFLAGS:
+			bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
+			bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_FFLAGS;
+			bsdtar->flags |= OPTFLAG_FFLAGS;
+			break;
 		case OPTION_FORMAT: /* GNU tar, others */
 			cset_set_format(bsdtar->cset, bsdtar->argument);
 			break;
@@ -420,6 +435,11 @@
 		case 'm': /* SUSv2 */
 			bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_TIME;
 			break;
+		case OPTION_MAC_METADATA: /* Mac OS X */
+			bsdtar->readdisk_flags |= ARCHIVE_READDISK_MAC_COPYFILE;
+			bsdtar->extract_flags |= ARCHIVE_EXTRACT_MAC_METADATA;
+			bsdtar->flags |= OPTFLAG_MAC_METADATA;
+			break;
 		case 'n': /* GNU tar */
 			bsdtar->flags |= OPTFLAG_NO_SUBDIRS;
 			break;
@@ -465,6 +485,21 @@
 			bsdtar->extract_flags |=
 			    ARCHIVE_EXTRACT_NO_HFS_COMPRESSION;
 			break;
+		case OPTION_NO_ACLS: /* GNU tar */
+			bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_ACL;
+			bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_ACL;
+			bsdtar->flags |= OPTFLAG_NO_ACLS;
+			break;
+		case OPTION_NO_FFLAGS:
+			bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_FFLAGS;
+			bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_FFLAGS;
+			bsdtar->flags |= OPTFLAG_NO_FFLAGS;
+			break;
+		case OPTION_NO_MAC_METADATA: /* Mac OS X */
+			bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_MAC_COPYFILE;
+			bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_MAC_METADATA;
+			bsdtar->flags |= OPTFLAG_NO_MAC_METADATA;
+			break;
 		case OPTION_NO_SAME_OWNER: /* GNU tar */
 			bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
 			break;
@@ -475,10 +510,10 @@
 			bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_FFLAGS;
 			bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_MAC_METADATA;
 			break;
-		case OPTION_NO_XATTR: /* Issue #131 */
+		case OPTION_NO_XATTRS: /* GNU tar */
 			bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_XATTR;
 			bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_XATTR;
-			bsdtar->flags |= OPTFLAG_NO_XATTR;
+			bsdtar->flags |= OPTFLAG_NO_XATTRS;
 			break;
 		case OPTION_NULL: /* GNU tar */
 			bsdtar->flags |= OPTFLAG_NULL;
@@ -655,6 +690,11 @@
 		case 'x': /* SUSv2 */
 			set_mode(bsdtar, opt);
 			break;
+		case OPTION_XATTRS: /* GNU tar */
+			bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR;
+			bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_XATTR;
+			bsdtar->flags |= OPTFLAG_XATTRS;
+			break;
 		case 'y': /* FreeBSD version of GNU tar */
 			if (compression != '\0')
 				lafe_errc(1, 0,
@@ -715,8 +755,22 @@
 		only_mode(bsdtar, "--nopreserveHFSCompression", "x");
 	if (bsdtar->readdisk_flags & ARCHIVE_READDISK_HONOR_NODUMP)
 		only_mode(bsdtar, "--nodump", "cru");
-	if (bsdtar->flags & OPTFLAG_NO_XATTR)
-		only_mode(bsdtar, "--no-xattr", "crux");
+	if (bsdtar->flags & OPTFLAG_ACLS)
+		only_mode(bsdtar, "--acls", "crux");
+	if (bsdtar->flags & OPTFLAG_NO_ACLS)
+		only_mode(bsdtar, "--no-acls", "crux");
+	if (bsdtar->flags & OPTFLAG_XATTRS)
+		only_mode(bsdtar, "--xattrs", "crux");
+	if (bsdtar->flags & OPTFLAG_NO_XATTRS)
+		only_mode(bsdtar, "--no-xattrs", "crux");
+	if (bsdtar->flags & OPTFLAG_FFLAGS)
+		only_mode(bsdtar, "--fflags", "crux");
+	if (bsdtar->flags & OPTFLAG_NO_FFLAGS)
+		only_mode(bsdtar, "--no-fflags", "crux");
+	if (bsdtar->flags & OPTFLAG_MAC_METADATA)
+		only_mode(bsdtar, "--mac-metadata", "crux");
+	if (bsdtar->flags & OPTFLAG_NO_MAC_METADATA)
+		only_mode(bsdtar, "--no-mac-metadata", "crux");
 	if (bsdtar->flags & OPTFLAG_O) {
 		switch (bsdtar->mode) {
 		case 'c':
diff --git a/tar/bsdtar.h b/tar/bsdtar.h
index 89cf2f9..ee9c648 100644
--- a/tar/bsdtar.h
+++ b/tar/bsdtar.h
@@ -50,7 +50,7 @@
 	int		  bytes_per_block; /* -b block_size */
 	int		  bytes_in_last_block; /* See -b handling. */
 	int		  verbose;   /* -v */
-	int		  flags; /* Bitfield of boolean options */
+	unsigned int	  flags; /* Bitfield of boolean options */
 	int		  extract_flags; /* Flags for extract operation */
 	int		  readdisk_flags; /* Flags for read disk operation */
 	int		  strip_components; /* Remove this many leading dirs */
@@ -118,16 +118,24 @@
 #define	OPTFLAG_TOTALS		(0x00001000)	/* --totals */
 #define	OPTFLAG_UNLINK_FIRST	(0x00002000)	/* -U */
 #define	OPTFLAG_WARN_LINKS	(0x00004000)	/* --check-links */
-#define	OPTFLAG_NO_XATTR	(0x00008000)	/* --no-xattr */
+#define	OPTFLAG_NO_XATTRS	(0x00008000)	/* --no-xattrs */
+#define	OPTFLAG_XATTRS		(0x00010000)	/* --xattrs */
+#define	OPTFLAG_NO_ACLS		(0x00020000)	/* --no-acls */
+#define	OPTFLAG_ACLS		(0x00040000)	/* --acls */
+#define	OPTFLAG_NO_FFLAGS	(0x00080000)	/* --no-fflags */
+#define	OPTFLAG_FFLAGS		(0x00100000)	/* --fflags */
+#define	OPTFLAG_NO_MAC_METADATA	(0x00200000)	/* --no-mac-metadata */
+#define	OPTFLAG_MAC_METADATA	(0x00400000)	/* --mac-metadata */
 
 /* Fake short equivalents for long options that otherwise lack them. */
 enum {
-	OPTION_B64ENCODE = 1,
+	OPTION_ACLS = 1,
+	OPTION_B64ENCODE,
 	OPTION_CHECK_LINKS,
 	OPTION_CHROOT,
 	OPTION_CLEAR_NOCHANGE_FFLAGS,
-	OPTION_DISABLE_COPYFILE,
 	OPTION_EXCLUDE,
+	OPTION_FFLAGS,
 	OPTION_FORMAT,
 	OPTION_GID,
 	OPTION_GNAME,
@@ -142,15 +150,19 @@
 	OPTION_LZIP,
 	OPTION_LZMA,
 	OPTION_LZOP,
+	OPTION_MAC_METADATA,
 	OPTION_NEWER_CTIME,
 	OPTION_NEWER_CTIME_THAN,
 	OPTION_NEWER_MTIME,
 	OPTION_NEWER_MTIME_THAN,
 	OPTION_NODUMP,
 	OPTION_NOPRESERVE_HFS_COMPRESSION,
+	OPTION_NO_ACLS,
+	OPTION_NO_FFLAGS,
+	OPTION_NO_MAC_METADATA,
 	OPTION_NO_SAME_OWNER,
 	OPTION_NO_SAME_PERMISSIONS,
-	OPTION_NO_XATTR,
+	OPTION_NO_XATTRS,
 	OPTION_NULL,
 	OPTION_NUMERIC_OWNER,
 	OPTION_OLDER_CTIME,
@@ -168,7 +180,8 @@
 	OPTION_UNAME,
 	OPTION_USE_COMPRESS_PROGRAM,
 	OPTION_UUENCODE,
-	OPTION_VERSION
+	OPTION_VERSION,
+	OPTION_XATTRS
 };
 
 int	bsdtar_getopt(struct bsdtar *);
diff --git a/tar/cmdline.c b/tar/cmdline.c
index c87741c..e36c545 100644
--- a/tar/cmdline.c
+++ b/tar/cmdline.c
@@ -65,6 +65,7 @@
 } tar_longopts[] = {
 	{ "absolute-paths",       0, 'P' },
 	{ "append",               0, 'r' },
+	{ "acls",                 0, OPTION_ACLS },
 	{ "auto-compress",        0, 'a' },
 	{ "b64encode",            0, OPTION_B64ENCODE },
 	{ "block-size",           1, 'b' },
@@ -81,11 +82,12 @@
 	{ "create",               0, 'c' },
 	{ "dereference",	  0, 'L' },
 	{ "directory",            1, 'C' },
-	{ "disable-copyfile",	  0, OPTION_DISABLE_COPYFILE },
+	{ "disable-copyfile",	  0, OPTION_NO_MAC_METADATA },
 	{ "exclude",              1, OPTION_EXCLUDE },
 	{ "exclude-from",         1, 'X' },
 	{ "extract",              0, 'x' },
 	{ "fast-read",            0, 'q' },
+	{ "fflags",               0, OPTION_FFLAGS },
 	{ "file",                 1, 'f' },
 	{ "files-from",           1, 'T' },
 	{ "format",               1, OPTION_FORMAT },
@@ -108,6 +110,7 @@
 	{ "lzip",                 0, OPTION_LZIP },
 	{ "lzma",                 0, OPTION_LZMA },
 	{ "lzop",                 0, OPTION_LZOP },
+	{ "mac-metadata",         0, OPTION_MAC_METADATA },
 	{ "modification-time",    0, 'm' },
 	{ "newer",		  1, OPTION_NEWER_CTIME },
 	{ "newer-ctime",	  1, OPTION_NEWER_CTIME },
@@ -115,10 +118,14 @@
 	{ "newer-mtime",	  1, OPTION_NEWER_MTIME },
 	{ "newer-mtime-than",	  1, OPTION_NEWER_MTIME_THAN },
 	{ "newer-than",		  1, OPTION_NEWER_CTIME_THAN },
+	{ "no-acls",              0, OPTION_NO_ACLS },
+	{ "no-fflags",            0, OPTION_NO_FFLAGS },
+	{ "no-mac-metadata",      0, OPTION_NO_MAC_METADATA },
 	{ "no-recursion",         0, 'n' },
 	{ "no-same-owner",	  0, OPTION_NO_SAME_OWNER },
 	{ "no-same-permissions",  0, OPTION_NO_SAME_PERMISSIONS },
-	{ "no-xattr",             0, OPTION_NO_XATTR },
+	{ "no-xattr",             0, OPTION_NO_XATTRS },
+	{ "no-xattrs",            0, OPTION_NO_XATTRS },
 	{ "nodump",               0, OPTION_NODUMP },
 	{ "nopreserveHFSCompression",0, OPTION_NOPRESERVE_HFS_COMPRESSION },
 	{ "norecurse",            0, 'n' },
@@ -151,6 +158,7 @@
 	{ "uuencode",             0, OPTION_UUENCODE },
 	{ "verbose",              0, 'v' },
 	{ "version",              0, OPTION_VERSION },
+	{ "xattrs",               0, OPTION_XATTRS },
 	{ "xz",                   0, 'J' },
 	{ NULL, 0, 0 }
 };
diff --git a/test_utils/test_main.c b/test_utils/test_main.c
index b0b6c2b..2ae6b38 100644
--- a/test_utils/test_main.c
+++ b/test_utils/test_main.c
@@ -45,6 +45,9 @@
 #if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
 #include <ext2fs/ext2_fs.h>     /* Linux file flags, broken on Cygwin */
 #endif
+#ifdef HAVE_LINUX_FS_H
+#include <linux/fs.h>
+#endif
 #include <limits.h>
 #include <locale.h>
 #ifdef HAVE_SIGNAL_H
@@ -1894,8 +1897,10 @@
 		failure_finish(NULL);
 		return (0);
 	}
-#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
-	 && defined(EXT2_NODUMP_FL)
+#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) && \
+       defined(FS_NODUMP_FL)) || \
+      (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
+	 && defined(EXT2_NODUMP_FL))
 	int fd, r, flags;
 
 	assertion_count(file, line);
@@ -1905,14 +1910,31 @@
 		failure_finish(NULL);
 		return (0);
 	}
-	r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+	    FS_IOC_GETFLAGS,
+#else
+	    EXT2_IOC_GETFLAGS,
+#endif
+	    &flags);
 	if (r < 0) {
 		failure_start(file, line, "Can't get flags %s\n", pathname);
 		failure_finish(NULL);
 		return (0);
 	}
+#ifdef FS_NODUMP_FL
+	flags |= FS_NODUMP_FL;
+#else
 	flags |= EXT2_NODUMP_FL;
-	r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+#endif
+
+	 r = ioctl(fd,
+#ifdef FS_IOC_SETFLAGS
+	    FS_IOC_SETFLAGS,
+#else
+	    EXT2_IOC_SETFLAGS,
+#endif
+	    &flags);
 	if (r < 0) {
 		failure_start(file, line, "Can't set nodump %s\n", pathname);
 		failure_finish(NULL);
@@ -2252,9 +2274,10 @@
 	return (0);
 }
 
-#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
-	 && defined(EXT2_NODUMP_FL)
-
+#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) \
+	 && defined(FS_NODUMP_FL)) || \
+      (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
+	 && defined(EXT2_NODUMP_FL))
 int
 canNodump(void)
 {
@@ -2265,22 +2288,48 @@
 	fd = open(path, O_RDONLY | O_NONBLOCK);
 	if (fd < 0)
 		return (0);
-	r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+	    FS_IOC_GETFLAGS,
+#else
+	    EXT2_IOC_GETFLAGS,
+#endif
+	    &flags);
 	if (r < 0)
 		return (0);
+#ifdef FS_NODUMP_FL
+	flags |= FS_NODUMP_FL;
+#else
 	flags |= EXT2_NODUMP_FL;
-	r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+#endif
+	r = ioctl(fd,
+#ifdef FS_IOC_SETFLAGS
+	    FS_IOC_SETFLAGS,
+#else
+	    EXT2_IOC_SETFLAGS,
+#endif
+	   &flags);
 	if (r < 0)
 		return (0);
 	close(fd);
 	fd = open(path, O_RDONLY | O_NONBLOCK);
 	if (fd < 0)
 		return (0);
-	r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+	    FS_IOC_GETFLAGS,
+#else
+	    EXT2_IOC_GETFLAGS,
+#endif
+	    &flags);
 	if (r < 0)
 		return (0);
 	close(fd);
+#ifdef FS_NODUMP_FL
+	if (flags & FS_NODUMP_FL)
+#else
 	if (flags & EXT2_NODUMP_FL)
+#endif
 		return (1);
 	return (0);
 }