bsdtar tests: add test_option_fflags
diff --git a/Makefile.am b/Makefile.am
index a699dc5..600e1ff 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -955,6 +955,7 @@
 	tar/test/test_option_b.c \
 	tar/test/test_option_b64encode.c \
 	tar/test/test_option_exclude.c \
+	tar/test/test_option_fflags.c \
 	tar/test/test_option_gid_gname.c \
 	tar/test/test_option_grzip.c \
 	tar/test/test_option_j.c \
diff --git a/libarchive/test/test_read_disk_directory_traversals.c b/libarchive/test/test_read_disk_directory_traversals.c
index fdbfbec..705b3d9 100644
--- a/libarchive/test/test_read_disk_directory_traversals.c
+++ b/libarchive/test/test_read_disk_directory_traversals.c
@@ -1231,8 +1231,8 @@
 	 * Test4: Traversals with ARCHIVE_READDISK_RESTORE_ATIME and
 	 * ARCHIVE_READDISK_HONOR_NODUMP
 	 */
-	assertNodump("at/f1");
-	assertNodump("at/f2");
+	assertSetNodump("at/f1");
+	assertSetNodump("at/f2");
 	assertUtimes("at/f1", 886600, 0, 886600, 0);
 	assertUtimes("at/f2", 886611, 0, 886611, 0);
 	assertUtimes("at/fe", 886611, 0, 886611, 0);
@@ -1450,7 +1450,7 @@
 	assertMakeFile("nd/f1", 0644, "0123456789");
 	assertMakeFile("nd/f2", 0644, "hello world");
 	assertMakeFile("nd/fe", 0644, NULL);
-	assertNodump("nd/f2");
+	assertSetNodump("nd/f2");
 	assertUtimes("nd/f1", 886600, 0, 886600, 0);
 	assertUtimes("nd/f2", 886611, 0, 886611, 0);
 	assertUtimes("nd/fe", 886611, 0, 886611, 0);
diff --git a/tar/test/CMakeLists.txt b/tar/test/CMakeLists.txt
index 3dd3601..9115d6f 100644
--- a/tar/test/CMakeLists.txt
+++ b/tar/test/CMakeLists.txt
@@ -37,6 +37,7 @@
     test_option_b.c
     test_option_b64encode.c
     test_option_exclude.c
+    test_option_fflags.c
     test_option_gid_gname.c
     test_option_grzip.c
     test_option_j.c
diff --git a/tar/test/test_option_fflags.c b/tar/test/test_option_fflags.c
new file mode 100644
index 0000000..ab62186
--- /dev/null
+++ b/tar/test/test_option_fflags.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2017 Martin Matuska
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_fflags)
+{
+	int r;
+
+	if (!canNodump()) {
+		skipping("Can't test nodump flag on this filesystem");
+		return;
+	}
+
+	/* Create a file. */
+	assertMakeFile("f", 0644, "a");
+
+	/* Set nodump flag on the file */
+	assertSetNodump("f");
+
+	/* Archive it with fflags */
+	r = systemf("%s -c --fflags -f fflags.tar f >fflags.out 2>fflags.err", testprog);
+	assertEqualInt(r, 0);
+
+	/* Archive it without fflags */
+	r = systemf("%s -c --no-fflags -f nofflags.tar f >nofflags.out 2>nofflags.err", testprog);
+	assertEqualInt(r, 0);
+
+	/* Extract fflags with fflags */
+	assertMakeDir("fflags_fflags", 0755);
+	r = systemf("%s -x -C fflags_fflags --no-same-permissions --fflags -f fflags.tar >fflags_fflags.out 2>fflags_fflags.err", testprog);
+	assertEqualInt(r, 0);
+	assertHasNodump("fflags_fflags/f", 1);
+
+	/* Extract fflags without fflags */
+	assertMakeDir("fflags_nofflags", 0755);
+	r = systemf("%s -x -C fflags_nofflags -p --no-fflags -f fflags.tar >fflags_nofflags.out 2>fflags_nofflags.err", testprog);
+	assertEqualInt(r, 0);
+	assertHasNodump("fflags_nofflags/f", 0);
+
+	/* Extract nofflags with fflags */
+	assertMakeDir("nofflags_fflags", 0755);
+	r = systemf("%s -x -C nofflags_fflags --no-same-permissions --fflags -f nofflags.tar >nofflags_fflags.out 2>nofflags_fflags.err", testprog);
+	assertEqualInt(r, 0);	
+	assertHasNodump("nofflags_fflags/f", 0);
+
+	/* Extract nofflags with nofflags */
+	assertMakeDir("nofflags_nofflags", 0755);
+	r = systemf("%s -x -C nofflags_nofflags -p --no-fflags -f nofflags.tar >nofflags_nofflags.out 2>nofflags_nofflags.err", testprog);
+	assertEqualInt(r, 0);
+	assertHasNodump("nofflags_nofflags/f", 0);
+}
diff --git a/tar/test/test_option_nodump.c b/tar/test/test_option_nodump.c
index 768f64a..815b08e 100644
--- a/tar/test/test_option_nodump.c
+++ b/tar/test/test_option_nodump.c
@@ -36,7 +36,7 @@
 	assertMakeFile("file1", 0644, "file1");
 	assertMakeFile("file2", 0644, "file2");
 	assertMakeFile("file3", 0644, "file3");
-	assertNodump("file2");
+	assertSetNodump("file2");
 
 	/* Test 1: Without --nodump */
 	assertEqualInt(0, systemf("%s -cf test1.tar file1 file2 file3",
diff --git a/test_utils/test_common.h b/test_utils/test_common.h
index 82e8483..ce06f4e 100644
--- a/test_utils/test_common.h
+++ b/test_utils/test_common.h
@@ -239,8 +239,10 @@
   assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
 #define assertMakeSymlink(newfile, linkto)	\
   assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
-#define assertNodump(path)      \
-  assertion_nodump(__FILE__, __LINE__, path)
+#define assertHasNodump(path, isset)	\
+  assertion_has_nodump(__FILE__, __LINE__, path, isset)
+#define assertSetNodump(path)	\
+  assertion_set_nodump(__FILE__, __LINE__, path)
 #define assertUmask(mask)	\
   assertion_umask(__FILE__, __LINE__, mask)
 #define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec)	\
@@ -286,6 +288,7 @@
 int assertion_file_nlinks(const char *, int, const char *, int);
 int assertion_file_not_exists(const char *, int, const char *);
 int assertion_file_size(const char *, int, const char *, long);
+int assertion_has_nodump(const char *, int, const char *, int);
 int assertion_is_dir(const char *, int, const char *, int);
 int assertion_is_hardlink(const char *, int, const char *, const char *);
 int assertion_is_not_hardlink(const char *, int, const char *, const char *);
@@ -295,8 +298,8 @@
 int assertion_make_file(const char *, int, const char *, int, int, const void *);
 int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
 int assertion_make_symlink(const char *, int, const char *newpath, const char *);
-int assertion_nodump(const char *, int, const char *);
 int assertion_non_empty_file(const char *, int, const char *);
+int assertion_set_nodump(const char *, int, const char *);
 int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
 int assertion_umask(const char *, int, int);
 int assertion_utimes(const char *, int, const char *, long, long, long, long );
diff --git a/test_utils/test_main.c b/test_utils/test_main.c
index 2ae6b38..a50ed23 100644
--- a/test_utils/test_main.c
+++ b/test_utils/test_main.c
@@ -1882,10 +1882,80 @@
 	return (1);
 #endif /* defined(_WIN32) && !defined(__CYGWIN__) */
 }
+/* Get nodump. */
+int
+assertion_has_nodump(const char *file, int line, const char *pathname, int isset)
+{
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
+	struct stat sb;
+
+	assertion_count(file, line);
+
+	if (stat(pathname, &sb) < 0)
+		return (0);
+	if (sb.st_flags & UF_NODUMP) {
+		if (isset)
+			return (1);
+	} else {
+		if (!isset)
+			return (1);
+	}
+#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);
+	fd = open(pathname, O_RDONLY | O_NONBLOCK);
+	if (fd < 0) {
+		failure_start(file, line, "Can't open %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+	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
+	if (flags & FS_NODUMP_FL)
+#else
+	if (flags & EXT2_NODUMP_FL)
+#endif
+	{
+		if (!isset) {
+			failure_start(file, line,
+			    "Nodump flag should not be set on %s\n", pathname);
+			failure_finish(NULL);
+			return (0);
+		}
+	} else {
+		if (isset) {
+			failure_start(file, line,
+			    "Nodump flag should be set on %s\n", pathname);
+			failure_finish(NULL);
+			return (0);
+		}
+	}
+#else
+	(void)pathname; /* UNUSED */
+	(void)isset; /* UNUSED */
+	assertion_count(file, line);
+#endif
+	return (1);
+}
 
 /* Set nodump, report failures. */
 int
-assertion_nodump(const char *file, int line, const char *pathname)
+assertion_set_nodump(const char *file, int line, const char *pathname)
 {
 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
 	int r;