svn commit: r224153 - in head/usr.bin/tar: . test

Martin Matuska mm at FreeBSD.org
Sun Jul 17 21:33:16 UTC 2011


Author: mm
Date: Sun Jul 17 21:33:15 2011
New Revision: 224153
URL: http://svn.freebsd.org/changeset/base/224153

Log:
  Update bsdtar to 2.8.4
  Use common code from lib/libarchive/libarchive_fe
  
  Approved by:	kientzle
  MFC after:	2 weeks

Added:
  head/usr.bin/tar/test/test_empty_mtree.c   (contents, props changed)
  head/usr.bin/tar/test/test_option_T_upper.c   (contents, props changed)
  head/usr.bin/tar/test/test_option_r.c   (contents, props changed)
Deleted:
  head/usr.bin/tar/err.c
  head/usr.bin/tar/err.h
  head/usr.bin/tar/line_reader.c
  head/usr.bin/tar/line_reader.h
  head/usr.bin/tar/matching.c
  head/usr.bin/tar/matching.h
  head/usr.bin/tar/pathmatch.c
  head/usr.bin/tar/pathmatch.h
  head/usr.bin/tar/test/test_option_T.c
Modified:
  head/usr.bin/tar/Makefile
  head/usr.bin/tar/bsdtar.1
  head/usr.bin/tar/bsdtar.c
  head/usr.bin/tar/cmdline.c
  head/usr.bin/tar/config_freebsd.h
  head/usr.bin/tar/read.c
  head/usr.bin/tar/subst.c
  head/usr.bin/tar/test/Makefile
  head/usr.bin/tar/test/main.c
  head/usr.bin/tar/test/test.h
  head/usr.bin/tar/test/test_0.c
  head/usr.bin/tar/test/test_basic.c
  head/usr.bin/tar/test/test_copy.c
  head/usr.bin/tar/test/test_help.c
  head/usr.bin/tar/test/test_option_q.c
  head/usr.bin/tar/test/test_option_s.c
  head/usr.bin/tar/test/test_patterns.c
  head/usr.bin/tar/test/test_patterns_2.tar.uu
  head/usr.bin/tar/test/test_patterns_3.tar.uu
  head/usr.bin/tar/test/test_patterns_4.tar.uu
  head/usr.bin/tar/test/test_stdio.c
  head/usr.bin/tar/test/test_strip_components.c
  head/usr.bin/tar/test/test_symlink_dir.c
  head/usr.bin/tar/test/test_version.c
  head/usr.bin/tar/util.c
  head/usr.bin/tar/write.c

Modified: head/usr.bin/tar/Makefile
==============================================================================
--- head/usr.bin/tar/Makefile	Sun Jul 17 21:27:38 2011	(r224152)
+++ head/usr.bin/tar/Makefile	Sun Jul 17 21:33:15 2011	(r224153)
@@ -2,21 +2,24 @@
 .include <bsd.own.mk>
 
 PROG=	bsdtar
-BSDTAR_VERSION_STRING=2.8.3
+BSDTAR_VERSION_STRING=2.8.4
 SRCS=	bsdtar.c	\
 	cmdline.c	\
-	err.c		\
 	getdate.c	\
-	line_reader.c	\
-	matching.c	\
-	pathmatch.c	\
 	read.c		\
 	subst.c		\
 	tree.c		\
 	util.c		\
 	write.c
-DPADD=	${LIBARCHIVE} ${LIBBZ2} ${LIBZ} ${LIBMD} ${LIBLZMA}
-LDADD=	-larchive -lbz2 -lz -lmd -llzma
+
+.PATH: ${.CURDIR}/../../lib/libarchive/libarchive_fe
+SRCS+=	err.c		\
+	line_reader.c	\
+	matching.c	\
+	pathmatch.c
+
+DPADD=	${LIBARCHIVE} ${LIBBZ2} ${LIBZ} ${LIBMD} ${LIBLZMA} ${LIBBSDXML}
+LDADD=	-larchive -lbz2 -lz -lmd -llzma -lbsdxml
 .if ${MK_OPENSSL} != "no"
 DPADD+=	${LIBCRYPTO}
 LDADD+= -lcrypto
@@ -24,6 +27,7 @@ LDADD+= -lcrypto
 CFLAGS+=	-DBSDTAR_VERSION_STRING=\"${BSDTAR_VERSION_STRING}\"
 CFLAGS+=	-DPLATFORM_CONFIG_H=\"config_freebsd.h\"
 CFLAGS+=	-I${.CURDIR} -I${.CURDIR}/../../lib/libarchive
+CFLAGS+=	-I${.CURDIR}/../../lib/libarchive/libarchive_fe
 SYMLINKS=	bsdtar ${BINDIR}/tar
 MLINKS=	bsdtar.1 tar.1
 DEBUG_FLAGS=-g

Modified: head/usr.bin/tar/bsdtar.1
==============================================================================
--- head/usr.bin/tar/bsdtar.1	Sun Jul 17 21:27:38 2011	(r224152)
+++ head/usr.bin/tar/bsdtar.1	Sun Jul 17 21:33:15 2011	(r224153)
@@ -50,8 +50,8 @@
 .Sh DESCRIPTION
 .Nm
 creates and manipulates streaming archive files.
-This implementation can extract from tar, pax, cpio, zip, jar, ar,
-xar, and ISO 9660 cdrom images and can create tar, pax, cpio, ar, zip,
+This implementation can extract from tar, pax, cpio, zip, jar, ar, xar,
+rpm and ISO 9660 cdrom images and can create tar, pax, cpio, ar, zip,
 and shar archives.
 .Pp
 The first synopsis form shows a

Modified: head/usr.bin/tar/bsdtar.c
==============================================================================
--- head/usr.bin/tar/bsdtar.c	Sun Jul 17 21:27:38 2011	(r224152)
+++ head/usr.bin/tar/bsdtar.c	Sun Jul 17 21:33:15 2011	(r224153)
@@ -63,6 +63,9 @@ __FBSDID("$FreeBSD$");
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#if HAVE_ZLIB_H
+#include <zlib.h>
+#endif
 
 #include "bsdtar.h"
 #include "err.h"
@@ -86,6 +89,8 @@ __FBSDID("$FreeBSD$");
 int _CRT_glob = 0; /* Disable broken CRT globbing. */
 #endif
 
+static struct bsdtar *_bsdtar;
+
 #if defined(HAVE_SIGACTION) && (defined(SIGINFO) || defined(SIGUSR1))
 static volatile int siginfo_occurred;
 
@@ -139,7 +144,7 @@ main(int argc, char **argv)
 	 * Use a pointer for consistency, but stack-allocated storage
 	 * for ease of cleanup.
 	 */
-	bsdtar = &bsdtar_storage;
+	_bsdtar = bsdtar = &bsdtar_storage;
 	memset(bsdtar, 0, sizeof(*bsdtar));
 	bsdtar->fd = -1; /* Mark as "unused" */
 	option_o = 0;
@@ -152,36 +157,36 @@ main(int argc, char **argv)
 		sa.sa_flags = 0;
 #ifdef SIGINFO
 		if (sigaction(SIGINFO, &sa, NULL))
-			bsdtar_errc(1, errno, "sigaction(SIGINFO) failed");
+			lafe_errc(1, errno, "sigaction(SIGINFO) failed");
 #endif
 #ifdef SIGUSR1
 		/* ... and treat SIGUSR1 the same way as SIGINFO. */
 		if (sigaction(SIGUSR1, &sa, NULL))
-			bsdtar_errc(1, errno, "sigaction(SIGUSR1) failed");
+			lafe_errc(1, errno, "sigaction(SIGUSR1) failed");
 #endif
 	}
 #endif
 
-	/* Need bsdtar_progname before calling bsdtar_warnc. */
+	/* Need lafe_progname before calling lafe_warnc. */
 	if (*argv == NULL)
-		bsdtar_progname = "bsdtar";
+		lafe_progname = "bsdtar";
 	else {
 #if defined(_WIN32) && !defined(__CYGWIN__)
-		bsdtar_progname = strrchr(*argv, '\\');
+		lafe_progname = strrchr(*argv, '\\');
 #else
-		bsdtar_progname = strrchr(*argv, '/');
+		lafe_progname = strrchr(*argv, '/');
 #endif
-		if (bsdtar_progname != NULL)
-			bsdtar_progname++;
+		if (lafe_progname != NULL)
+			lafe_progname++;
 		else
-			bsdtar_progname = *argv;
+			lafe_progname = *argv;
 	}
 
 	time(&now);
 
 #if HAVE_SETLOCALE
 	if (setlocale(LC_ALL, "") == NULL)
-		bsdtar_warnc(0, "Failed to set default locale");
+		lafe_warnc(0, "Failed to set default locale");
 #endif
 #if defined(HAVE_NL_LANGINFO) && defined(HAVE_D_MD_ORDER)
 	bsdtar->day_first = (*nl_langinfo(D_MD_ORDER) == 'd');
@@ -233,7 +238,7 @@ main(int argc, char **argv)
 		case 'b': /* SUSv2 */
 			t = atoi(bsdtar->optarg);
 			if (t <= 0 || t > 8192)
-				bsdtar_errc(1, 0,
+				lafe_errc(1, 0,
 				    "Argument to -b is out of range (1..8192)");
 			bsdtar->bytes_per_block = 512 * t;
 			break;
@@ -251,7 +256,7 @@ main(int argc, char **argv)
 			break;
 		case OPTION_EXCLUDE: /* GNU tar */
 			if (lafe_exclude(&bsdtar->matching, bsdtar->optarg))
-				bsdtar_errc(1, 0,
+				lafe_errc(1, 0,
 				    "Couldn't exclude %s\n", bsdtar->optarg);
 			break;
 		case OPTION_FORMAT: /* GNU tar, others */
@@ -297,20 +302,20 @@ main(int argc, char **argv)
 			 * when transforming archives.
 			 */
 			if (lafe_include(&bsdtar->matching, bsdtar->optarg))
-				bsdtar_errc(1, 0,
+				lafe_errc(1, 0,
 				    "Failed to add %s to inclusion list",
 				    bsdtar->optarg);
 			break;
 		case 'j': /* GNU tar */
 			if (bsdtar->create_compression != '\0')
-				bsdtar_errc(1, 0,
+				lafe_errc(1, 0,
 				    "Can't specify both -%c and -%c", opt,
 				    bsdtar->create_compression);
 			bsdtar->create_compression = opt;
 			break;
 		case 'J': /* GNU tar 1.21 and later */
 			if (bsdtar->create_compression != '\0')
-				bsdtar_errc(1, 0,
+				lafe_errc(1, 0,
 				    "Can't specify both -%c and -%c", opt,
 				    bsdtar->create_compression);
 			bsdtar->create_compression = opt;
@@ -330,7 +335,7 @@ main(int argc, char **argv)
 			break;
 		case OPTION_LZMA:
 			if (bsdtar->create_compression != '\0')
-				bsdtar_errc(1, 0,
+				lafe_errc(1, 0,
 				    "Can't specify both -%c and -%c", opt,
 				    bsdtar->create_compression);
 			bsdtar->create_compression = opt;
@@ -355,7 +360,7 @@ main(int argc, char **argv)
 			{
 				struct stat st;
 				if (stat(bsdtar->optarg, &st) != 0)
-					bsdtar_errc(1, 0,
+					lafe_errc(1, 0,
 					    "Can't open file %s", bsdtar->optarg);
 				bsdtar->newer_ctime_sec = st.st_ctime;
 				bsdtar->newer_ctime_nsec =
@@ -369,7 +374,7 @@ main(int argc, char **argv)
 			{
 				struct stat st;
 				if (stat(bsdtar->optarg, &st) != 0)
-					bsdtar_errc(1, 0,
+					lafe_errc(1, 0,
 					    "Can't open file %s", bsdtar->optarg);
 				bsdtar->newer_mtime_sec = st.st_mtime;
 				bsdtar->newer_mtime_nsec =
@@ -440,7 +445,7 @@ main(int argc, char **argv)
 #if HAVE_REGEX_H
 			add_substitution(bsdtar, bsdtar->optarg);
 #else
-			bsdtar_warnc(0,
+			lafe_warnc(0,
 			    "-s is not supported by this version of bsdtar");
 			usage();
 #endif
@@ -487,7 +492,7 @@ main(int argc, char **argv)
 			break;
 		case 'X': /* GNU tar */
 			if (lafe_exclude_from_file(&bsdtar->matching, bsdtar->optarg))
-				bsdtar_errc(1, 0,
+				lafe_errc(1, 0,
 				    "failed to process exclusions from file %s",
 				    bsdtar->optarg);
 			break;
@@ -496,21 +501,21 @@ main(int argc, char **argv)
 			break;
 		case 'y': /* FreeBSD version of GNU tar */
 			if (bsdtar->create_compression != '\0')
-				bsdtar_errc(1, 0,
+				lafe_errc(1, 0,
 				    "Can't specify both -%c and -%c", opt,
 				    bsdtar->create_compression);
 			bsdtar->create_compression = opt;
 			break;
 		case 'Z': /* GNU tar */
 			if (bsdtar->create_compression != '\0')
-				bsdtar_errc(1, 0,
+				lafe_errc(1, 0,
 				    "Can't specify both -%c and -%c", opt,
 				    bsdtar->create_compression);
 			bsdtar->create_compression = opt;
 			break;
 		case 'z': /* GNU tar, star, many others */
 			if (bsdtar->create_compression != '\0')
-				bsdtar_errc(1, 0,
+				lafe_errc(1, 0,
 				    "Can't specify both -%c and -%c", opt,
 				    bsdtar->create_compression);
 			bsdtar->create_compression = opt;
@@ -535,7 +540,7 @@ main(int argc, char **argv)
 
 	/* Otherwise, a mode is required. */
 	if (bsdtar->mode == '\0')
-		bsdtar_errc(1, 0,
+		lafe_errc(1, 0,
 		    "Must specify one of -c, -r, -t, -u, -x");
 
 	/* Check boolean options only permitted in certain modes. */
@@ -615,7 +620,7 @@ main(int argc, char **argv)
 #endif
 
 	if (bsdtar->return_value != 0)
-		bsdtar_warnc(0,
+		lafe_warnc(0,
 		    "Error exit delayed from previous errors.");
 	return (bsdtar->return_value);
 }
@@ -624,7 +629,7 @@ static void
 set_mode(struct bsdtar *bsdtar, char opt)
 {
 	if (bsdtar->mode != '\0' && bsdtar->mode != opt)
-		bsdtar_errc(1, 0,
+		lafe_errc(1, 0,
 		    "Can't specify both -%c and -%c", opt, bsdtar->mode);
 	bsdtar->mode = opt;
 }
@@ -636,7 +641,7 @@ static void
 only_mode(struct bsdtar *bsdtar, const char *opt, const char *valid_modes)
 {
 	if (strchr(valid_modes, bsdtar->mode) == NULL)
-		bsdtar_errc(1, 0,
+		lafe_errc(1, 0,
 		    "Option %s is not permitted in mode -%c",
 		    opt, bsdtar->mode);
 }
@@ -647,7 +652,7 @@ usage(void)
 {
 	const char	*p;
 
-	p = bsdtar_progname;
+	p = lafe_progname;
 
 	fprintf(stderr, "Usage:\n");
 	fprintf(stderr, "  List:    %s -tf <archive-filename>\n", p);
@@ -707,7 +712,7 @@ long_help(void)
 	const char	*prog;
 	const char	*p;
 
-	prog = bsdtar_progname;
+	prog = lafe_progname;
 
 	fflush(stderr);
 

Modified: head/usr.bin/tar/cmdline.c
==============================================================================
--- head/usr.bin/tar/cmdline.c	Sun Jul 17 21:27:38 2011	(r224152)
+++ head/usr.bin/tar/cmdline.c	Sun Jul 17 21:33:15 2011	(r224153)
@@ -221,7 +221,7 @@ bsdtar_getopt(struct bsdtar *bsdtar)
 			if (p[1] == ':') {
 				bsdtar->optarg = *bsdtar->argv;
 				if (bsdtar->optarg == NULL) {
-					bsdtar_warnc(0,
+					lafe_warnc(0,
 					    "Option %c requires an argument",
 					    opt);
 					return ('?');
@@ -288,7 +288,7 @@ bsdtar_getopt(struct bsdtar *bsdtar)
 				/* Otherwise, pick up the next word. */
 				opt_word = *bsdtar->argv;
 				if (opt_word == NULL) {
-					bsdtar_warnc(0,
+					lafe_warnc(0,
 					    "Option -%c requires an argument",
 					    opt);
 					return ('?');
@@ -339,13 +339,13 @@ bsdtar_getopt(struct bsdtar *bsdtar)
 
 		/* Fail if there wasn't a unique match. */
 		if (match == NULL) {
-			bsdtar_warnc(0,
+			lafe_warnc(0,
 			    "Option %s%s is not supported",
 			    long_prefix, opt_word);
 			return ('?');
 		}
 		if (match2 != NULL) {
-			bsdtar_warnc(0,
+			lafe_warnc(0,
 			    "Ambiguous option %s%s (matches --%s and --%s)",
 			    long_prefix, opt_word, match->name, match2->name);
 			return ('?');
@@ -357,7 +357,7 @@ bsdtar_getopt(struct bsdtar *bsdtar)
 			if (bsdtar->optarg == NULL) {
 				bsdtar->optarg = *bsdtar->argv;
 				if (bsdtar->optarg == NULL) {
-					bsdtar_warnc(0,
+					lafe_warnc(0,
 					    "Option %s%s requires an argument",
 					    long_prefix, match->name);
 					return ('?');
@@ -368,7 +368,7 @@ bsdtar_getopt(struct bsdtar *bsdtar)
 		} else {
 			/* Argument forbidden: fail if there is one. */
 			if (bsdtar->optarg != NULL) {
-				bsdtar_warnc(0,
+				lafe_warnc(0,
 				    "Option %s%s does not allow an argument",
 				    long_prefix, match->name);
 				return ('?');

Modified: head/usr.bin/tar/config_freebsd.h
==============================================================================
--- head/usr.bin/tar/config_freebsd.h	Sun Jul 17 21:27:38 2011	(r224152)
+++ head/usr.bin/tar/config_freebsd.h	Sun Jul 17 21:33:15 2011	(r224153)
@@ -44,6 +44,7 @@
 #undef	HAVE_LIBACL
 #define	HAVE_LIBARCHIVE 1
 #define	HAVE_LIMITS_H 1
+#define	HAVE_LINK 1
 #undef	HAVE_LINUX_EXT2_FS_H
 #undef	HAVE_LINUX_FS_H
 #define	HAVE_LOCALE_H 1
@@ -77,5 +78,5 @@
 #define	HAVE_TIME_H 1
 #define	HAVE_UNISTD_H 1
 #define	HAVE_WCTYPE_H 1
+#define	HAVE_WCSCMP 1
 #undef	HAVE_WINDOWS_H
-

Modified: head/usr.bin/tar/read.c
==============================================================================
--- head/usr.bin/tar/read.c	Sun Jul 17 21:27:38 2011	(r224152)
+++ head/usr.bin/tar/read.c	Sun Jul 17 21:33:15 2011	(r224153)
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "bsdtar_platform.h"
+#include "lafe_platform.h"
 __FBSDID("$FreeBSD$");
 
 #ifdef HAVE_SYS_TYPES_H
@@ -160,11 +160,11 @@ read_archive(struct bsdtar *bsdtar, char
 		archive_read_support_compression_all(a);
 	archive_read_support_format_all(a);
 	if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options))
-		bsdtar_errc(1, 0, "%s", archive_error_string(a));
+		lafe_errc(1, 0, "%s", archive_error_string(a));
 	if (archive_read_open_file(a, bsdtar->filename,
 	    bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block :
 	    DEFAULT_BYTES_PER_BLOCK))
-		bsdtar_errc(1, 0, "Error opening archive: %s",
+		lafe_errc(1, 0, "Error opening archive: %s",
 		    archive_error_string(a));
 
 	do_chdir(bsdtar);
@@ -180,9 +180,9 @@ read_archive(struct bsdtar *bsdtar, char
 	if (mode == 'x' && bsdtar->option_chroot) {
 #if HAVE_CHROOT
 		if (chroot(".") != 0)
-			bsdtar_errc(1, errno, "Can't chroot to \".\"");
+			lafe_errc(1, errno, "Can't chroot to \".\"");
 #else
-		bsdtar_errc(1, 0,
+		lafe_errc(1, 0,
 		    "chroot isn't supported on this platform");
 #endif
 	}
@@ -198,12 +198,12 @@ read_archive(struct bsdtar *bsdtar, char
 		if (r == ARCHIVE_EOF)
 			break;
 		if (r < ARCHIVE_OK)
-			bsdtar_warnc(0, "%s", archive_error_string(a));
+			lafe_warnc(0, "%s", archive_error_string(a));
 		if (r <= ARCHIVE_WARN)
 			bsdtar->return_value = 1;
 		if (r == ARCHIVE_RETRY) {
 			/* Retryable error: try again */
-			bsdtar_warnc(0, "Retrying...");
+			lafe_warnc(0, "Retrying...");
 			continue;
 		}
 		if (r == ARCHIVE_FATAL)
@@ -267,17 +267,17 @@ read_archive(struct bsdtar *bsdtar, char
 			r = archive_read_data_skip(a);
 			if (r == ARCHIVE_WARN) {
 				fprintf(out, "\n");
-				bsdtar_warnc(0, "%s",
+				lafe_warnc(0, "%s",
 				    archive_error_string(a));
 			}
 			if (r == ARCHIVE_RETRY) {
 				fprintf(out, "\n");
-				bsdtar_warnc(0, "%s",
+				lafe_warnc(0, "%s",
 				    archive_error_string(a));
 			}
 			if (r == ARCHIVE_FATAL) {
 				fprintf(out, "\n");
-				bsdtar_warnc(0, "%s",
+				lafe_warnc(0, "%s",
 				    archive_error_string(a));
 				bsdtar->return_value = 1;
 				break;
@@ -329,7 +329,7 @@ read_archive(struct bsdtar *bsdtar, char
 
 	r = archive_read_close(a);
 	if (r != ARCHIVE_OK)
-		bsdtar_warnc(0, "%s", archive_error_string(a));
+		lafe_warnc(0, "%s", archive_error_string(a));
 	if (r <= ARCHIVE_WARN)
 		bsdtar->return_value = 1;
 

Modified: head/usr.bin/tar/subst.c
==============================================================================
--- head/usr.bin/tar/subst.c	Sun Jul 17 21:27:38 2011	(r224152)
+++ head/usr.bin/tar/subst.c	Sun Jul 17 21:33:15 2011	(r224153)
@@ -58,7 +58,7 @@ init_substitution(struct bsdtar *bsdtar)
 
 	bsdtar->substitution = subst = malloc(sizeof(*subst));
 	if (subst == NULL)
-		bsdtar_errc(1, errno, "Out of memory");
+		lafe_errc(1, errno, "Out of memory");
 	subst->first_rule = subst->last_rule = NULL;
 }
 
@@ -78,7 +78,7 @@ add_substitution(struct bsdtar *bsdtar, 
 
 	rule = malloc(sizeof(*rule));
 	if (rule == NULL)
-		bsdtar_errc(1, errno, "Out of memory");
+		lafe_errc(1, errno, "Out of memory");
 	rule->next = NULL;
 
 	if (subst->last_rule == NULL)
@@ -88,32 +88,32 @@ add_substitution(struct bsdtar *bsdtar, 
 	subst->last_rule = rule;
 
 	if (*rule_text == '\0')
-		bsdtar_errc(1, 0, "Empty replacement string");
+		lafe_errc(1, 0, "Empty replacement string");
 	end_pattern = strchr(rule_text + 1, *rule_text);
 	if (end_pattern == NULL)
-		bsdtar_errc(1, 0, "Invalid replacement string");
+		lafe_errc(1, 0, "Invalid replacement string");
 
 	pattern = malloc(end_pattern - rule_text);
 	if (pattern == NULL)
-		bsdtar_errc(1, errno, "Out of memory");
+		lafe_errc(1, errno, "Out of memory");
 	memcpy(pattern, rule_text + 1, end_pattern - rule_text - 1);
 	pattern[end_pattern - rule_text - 1] = '\0';
 
 	if ((r = regcomp(&rule->re, pattern, REG_BASIC)) != 0) {
 		char buf[80];
 		regerror(r, &rule->re, buf, sizeof(buf));
-		bsdtar_errc(1, 0, "Invalid regular expression: %s", buf);
+		lafe_errc(1, 0, "Invalid regular expression: %s", buf);
 	}
 	free(pattern);
 
 	start_subst = end_pattern + 1;
 	end_pattern = strchr(start_subst, *rule_text);
 	if (end_pattern == NULL)
-		bsdtar_errc(1, 0, "Invalid replacement string");
+		lafe_errc(1, 0, "Invalid replacement string");
 
 	rule->result = malloc(end_pattern - start_subst + 1);
 	if (rule->result == NULL)
-		bsdtar_errc(1, errno, "Out of memory");
+		lafe_errc(1, errno, "Out of memory");
 	memcpy(rule->result, start_subst, end_pattern - start_subst);
 	rule->result[end_pattern - start_subst] = '\0';
 
@@ -136,7 +136,7 @@ add_substitution(struct bsdtar *bsdtar, 
 			rule->symlink = 1;
 			break;
 		default:
-			bsdtar_errc(1, 0, "Invalid replacement flag %c", *end_pattern);
+			lafe_errc(1, 0, "Invalid replacement flag %c", *end_pattern);
 		}
 	}
 }
@@ -154,7 +154,7 @@ realloc_strncat(char **str, const char *
 
 	new_str = malloc(old_len + len + 1);
 	if (new_str == NULL)
-		bsdtar_errc(1, errno, "Out of memory");
+		lafe_errc(1, errno, "Out of memory");
 	memcpy(new_str, *str, old_len);
 	memcpy(new_str + old_len, append, len);
 	new_str[old_len + len] = '\0';
@@ -175,7 +175,7 @@ realloc_strcat(char **str, const char *a
 
 	new_str = malloc(old_len + strlen(append) + 1);
 	if (new_str == NULL)
-		bsdtar_errc(1, errno, "Out of memory");
+		lafe_errc(1, errno, "Out of memory");
 	memcpy(new_str, *str, old_len);
 	strcpy(new_str + old_len, append);
 	free(*str);

Modified: head/usr.bin/tar/test/Makefile
==============================================================================
--- head/usr.bin/tar/test/Makefile	Sun Jul 17 21:27:38 2011	(r224152)
+++ head/usr.bin/tar/test/Makefile	Sun Jul 17 21:33:15 2011	(r224153)
@@ -6,16 +6,18 @@ TAR_SRCDIR=${.CURDIR}/..
 
 # Some tar sources are pulled in for white-box tests
 TAR_SRCS=					\
-	../getdate.c
+	getdate.c
 
 TESTS=	\
 	test_0.c				\
 	test_basic.c				\
 	test_copy.c				\
+	test_empty_mtree.c			\
 	test_getdate.c				\
 	test_help.c				\
-	test_option_T.c				\
+	test_option_T_upper.c			\
 	test_option_q.c				\
+	test_option_r.c				\
 	test_option_s.c				\
 	test_patterns.c				\
 	test_stdio.c				\

Modified: head/usr.bin/tar/test/main.c
==============================================================================
--- head/usr.bin/tar/test/main.c	Sun Jul 17 21:27:38 2011	(r224152)
+++ head/usr.bin/tar/test/main.c	Sun Jul 17 21:33:15 2011	(r224153)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2009 Tim Kientzle
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,12 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/*
- * Various utility routines useful for test programs.
- * Each test program is linked against this file.
- */
 #include "test.h"
-
 #include <errno.h>
 #include <locale.h>
 #include <stdarg.h>
@@ -38,148 +33,319 @@
  * This same file is used pretty much verbatim for all test harnesses.
  *
  * The next few lines are the only differences.
+ * TODO: Move this into a separate configuration header, have all test
+ * suites share one copy of this file.
  */
-#define	PROGRAM "bsdtar" /* Name of program being tested. */
-#define ENVBASE "BSDTAR" /* Prefix for environment variables. */
+__FBSDID("$FreeBSD$");
+#define KNOWNREF	"test_patterns_2.tar.uu"
+#define ENVBASE "BSDTAR"  /* Prefix for environment variables. */
+#define	PROGRAM "bsdtar"  /* Name of program being tested. */
+#undef LIBRARY		  /* Not testing a library. */
 #undef	EXTRA_DUMP	     /* How to dump extra data */
 /* How to generate extra version info. */
 #define	EXTRA_VERSION    (systemf("%s --version", testprog) ? "" : "")
-__FBSDID("$FreeBSD$");
 
 /*
- * "list.h" is simply created by "grep DEFINE_TEST"; it has
- * a line like
- *      DEFINE_TEST(test_function)
- * for each test.
- * Include it here with a suitable DEFINE_TEST to declare all of the
- * test functions.
+ *
+ * Windows support routines
+ *
+ * Note: Configuration is a tricky issue.  Using HAVE_* feature macros
+ * in the test harness is dangerous because they cover up
+ * configuration errors.  The classic example of this is omitting a
+ * configure check.  If libarchive and libarchive_test both look for
+ * the same feature macro, such errors are hard to detect.  Platform
+ * macros (e.g., _WIN32 or __GNUC__) are a little better, but can
+ * easily lead to very messy code.  It's best to limit yourself
+ * to only the most generic programming techniques in the test harness
+ * and thus avoid conditionals altogether.  Where that's not possible,
+ * try to minimize conditionals by grouping platform-specific tests in
+ * one place (e.g., test_acl_freebsd) or by adding new assert()
+ * functions (e.g., assertMakeHardlink()) to cover up platform
+ * differences.  Platform-specific coding in libarchive_test is often
+ * a symptom that some capability is missing from libarchive itself.
  */
-#undef DEFINE_TEST
-#define	DEFINE_TEST(name) void name(void);
-#include "list.h"
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <io.h>
+#include <windows.h>
+#ifndef F_OK
+#define F_OK (0)
+#endif
+#ifndef S_ISDIR
+#define S_ISDIR(m)  ((m) & _S_IFDIR)
+#endif
+#ifndef S_ISREG
+#define S_ISREG(m)  ((m) & _S_IFREG)
+#endif
+#if !defined(__BORLANDC__)
+#define access _access
+#undef chdir
+#define chdir _chdir
+#endif
+#ifndef fileno
+#define fileno _fileno
+#endif
+/*#define fstat _fstat64*/
+#if !defined(__BORLANDC__)
+#define getcwd _getcwd
+#endif
+#define lstat stat
+/*#define lstat _stat64*/
+/*#define stat _stat64*/
+#define rmdir _rmdir
+#if !defined(__BORLANDC__)
+#define strdup _strdup
+#define umask _umask
+#endif
+#define int64_t __int64
+#endif
+
+#if defined(HAVE__CrtSetReportMode)
+# include <crtdbg.h>
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+void *GetFunctionKernel32(const char *name)
+{
+	static HINSTANCE lib;
+	static int set;
+	if (!set) {
+		set = 1;
+		lib = LoadLibrary("kernel32.dll");
+	}
+	if (lib == NULL) {
+		fprintf(stderr, "Can't load kernel32.dll?!\n");
+		exit(1);
+	}
+	return (void *)GetProcAddress(lib, name);
+}
+
+static int
+my_CreateSymbolicLinkA(const char *linkname, const char *target, int flags)
+{
+	static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, DWORD);
+	static int set;
+	if (!set) {
+		set = 1;
+		f = GetFunctionKernel32("CreateSymbolicLinkA");
+	}
+	return f == NULL ? 0 : (*f)(linkname, target, flags);
+}
+
+static int
+my_CreateHardLinkA(const char *linkname, const char *target)
+{
+	static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES);
+	static int set;
+	if (!set) {
+		set = 1;
+		f = GetFunctionKernel32("CreateHardLinkA");
+	}
+	return f == NULL ? 0 : (*f)(linkname, target, NULL);
+}
+
+int
+my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+	HANDLE h;
+	int r;
+
+	memset(bhfi, 0, sizeof(*bhfi));
+	h = CreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
+		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	if (h == INVALID_HANDLE_VALUE)
+		return (0);
+	r = GetFileInformationByHandle(h, bhfi);
+	CloseHandle(h);
+	return (r);
+}
+#endif
 
-/* Interix doesn't define these in a standard header. */
-#if __INTERIX__
-extern char *optarg;
-extern int optind;
+#if defined(HAVE__CrtSetReportMode)
+static void
+invalid_parameter_handler(const wchar_t * expression,
+    const wchar_t * function, const wchar_t * file,
+    unsigned int line, uintptr_t pReserved)
+{
+	/* nop */
+}
 #endif
 
+/*
+ *
+ * OPTIONS FLAGS
+ *
+ */
+
 /* Enable core dump on failure. */
 static int dump_on_failure = 0;
-/* Default is to remove temp dirs for successful tests. */
+/* Default is to remove temp dirs and log data for successful tests. */
 static int keep_temp_files = 0;
-/* Default is to print some basic information about each test. */
-static int quiet_flag = 0;
-/* Default is to summarize repeated failures. */
-static int verbose = 0;
-/* Cumulative count of component failures. */
+/* Default is to just report pass/fail for each test. */
+static int verbosity = 0;
+#define	VERBOSITY_SUMMARY_ONLY -1 /* -q */
+#define VERBOSITY_PASSFAIL 0   /* Default */
+#define VERBOSITY_LIGHT_REPORT 1 /* -v */
+#define VERBOSITY_FULL 2 /* -vv */
+/* A few places generate even more output for verbosity > VERBOSITY_FULL,
+ * mostly for debugging the test harness itself. */
+/* Cumulative count of assertion failures. */
 static int failures = 0;
-/* Cumulative count of skipped component tests. */
+/* Cumulative count of reported skips. */
 static int skips = 0;
-/* Cumulative count of assertions. */
+/* Cumulative count of assertions checked. */
 static int assertions = 0;
 
 /* Directory where uuencoded reference files can be found. */
 static const char *refdir;
 
 /*
- * My own implementation of the standard assert() macro emits the
- * message in the same format as GCC (file:line: message).
- * It also includes some additional useful information.
- * This makes it a lot easier to skim through test failures in
- * Emacs.  ;-)
- *
- * It also supports a few special features specifically to simplify
- * test harnesses:
- *    failure(fmt, args) -- Stores a text string that gets
- *          printed if the following assertion fails, good for
- *          explaining subtle tests.
- */
-static char msg[4096];
-
-/*
- * For each test source file, we remember how many times each
- * failure was reported.
- */
-static const char *failed_filename = NULL;
-static struct line {
-	int line;
-	int count;
-}  failed_lines[1000];
-
-/*
- * Count this failure; return the number of previous failures.
+ * Report log information selectively to console and/or disk log.
  */
-static int
-previous_failures(const char *filename, int line)
+static int log_console = 0;
+static FILE *logfile;
+static void
+vlogprintf(const char *fmt, va_list ap)
 {
-	unsigned int i;
-	int count;
+#ifdef va_copy
+	va_list lfap;
+	va_copy(lfap, ap);
+#endif
+	if (log_console)
+		vfprintf(stdout, fmt, ap);
+	if (logfile != NULL)
+#ifdef va_copy
+		vfprintf(logfile, fmt, lfap);
+	va_end(lfap);
+#else
+		vfprintf(logfile, fmt, ap);
+#endif
+}
 
-	if (failed_filename == NULL || strcmp(failed_filename, filename) != 0)
-		memset(failed_lines, 0, sizeof(failed_lines));
-	failed_filename = filename;
+static void
+logprintf(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	vlogprintf(fmt, ap);
+	va_end(ap);
+}
 
-	for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
-		if (failed_lines[i].line == line) {
-			count = failed_lines[i].count;
-			failed_lines[i].count++;
-			return (count);
-		}
-		if (failed_lines[i].line == 0) {
-			failed_lines[i].line = line;
-			failed_lines[i].count = 1;
-			return (0);
-		}
-	}
-	return (0);
+/* Set up a message to display only if next assertion fails. */
+static char msgbuff[4096];
+static const char *msg, *nextmsg;
+void
+failure(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	vsprintf(msgbuff, fmt, ap);
+	va_end(ap);
+	nextmsg = msgbuff;
 }
 
 /*
  * Copy arguments into file-local variables.
+ * This was added to permit vararg assert() functions without needing
+ * variadic wrapper macros.  Turns out that the vararg capability is almost
+ * never used, so almost all of the vararg assertions can be simplified
+ * by removing the vararg capability and reworking the wrapper macro to
+ * pass __FILE__, __LINE__ directly into the function instead of using
+ * this hook.  I suspect this machinery is used so rarely that we
+ * would be better off just removing it entirely.  That would simplify
+ * the code here noticably.
  */
 static const char *test_filename;
 static int test_line;
 static void *test_extra;
-void test_setup(const char *filename, int line)
+void assertion_setup(const char *filename, int line)
 {
 	test_filename = filename;
 	test_line = line;
 }
 
+/* Called at the beginning of each assert() function. */
+static void
+assertion_count(const char *file, int line)
+{
+	(void)file; /* UNUSED */
+	(void)line; /* UNUSED */
+	++assertions;
+	/* Proper handling of "failure()" message. */
+	msg = nextmsg;
+	nextmsg = NULL;
+	/* Uncomment to print file:line after every assertion.
+	 * Verbose, but occasionally useful in tracking down crashes. */
+	/* printf("Checked %s:%d\n", file, line); */
+}
+
 /*
- * Inform user that we're skipping a test.
+ * For each test source file, we remember how many times each
+ * assertion was reported.  Cleared before each new test,
+ * used by test_summarize().
  */
-void
-test_skipping(const char *fmt, ...)
+static struct line {
+	int count;
+	int skip;
+}  failed_lines[10000];
+
+/* Count this failure, setup up log destination and handle initial report. */
+static void
+failure_start(const char *filename, int line, const char *fmt, ...)
 {
 	va_list ap;
 
-	if (previous_failures(test_filename, test_line))
-		return;
+	/* Record another failure for this line. */
+	++failures;
+	/* test_filename = filename; */
+	failed_lines[line].count++;
+
+	/* Determine whether to log header to console. */
+	switch (verbosity) {
+	case VERBOSITY_FULL:
+		log_console = 1;
+		break;
+	case VERBOSITY_LIGHT_REPORT:
+		log_console = (failed_lines[line].count < 2);
+		break;
+	default:
+		log_console = 0;
+	}
 
+	/* Log file:line header for this failure */
 	va_start(ap, fmt);
-	fprintf(stderr, " *** SKIPPING: ");
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, "\n");
+#if _MSC_VER
+	logprintf("%s(%d): ", filename, line);
+#else
+	logprintf("%s:%d: ", filename, line);
+#endif
+	vlogprintf(fmt, ap);
 	va_end(ap);
-	++skips;
+	logprintf("\n");
+
+	if (msg != NULL && msg[0] != '\0') {
+		logprintf("   Description: %s\n", msg);
+		msg = NULL;
+	}
+
+	/* Determine whether to log details to console. */
+	if (verbosity == VERBOSITY_LIGHT_REPORT)
+		log_console = 0;
 }
 
-/* Common handling of failed tests. */
+/* Complete reporting of failed tests. */
+/*
+ * The 'extra' hook here is used by libarchive to include libarchive
+ * error messages with assertion failures.  It could also be used
+ * to add strerror() output, for example.  Just define the EXTRA_DUMP()
+ * macro appropriately.
+ */
 static void
-report_failure(void *extra)
+failure_finish(void *extra)
 {
-	if (msg[0] != '\0') {
-		fprintf(stderr, "   Description: %s\n", msg);
-		msg[0] = '\0';
-	}
-
+	(void)extra; /* UNUSED (maybe) */
 #ifdef EXTRA_DUMP
 	if (extra != NULL)
-		fprintf(stderr, "   detail: %s\n", EXTRA_DUMP(extra));
-#else
-	(void)extra; /* UNUSED */
+		logprintf("   detail: %s\n", EXTRA_DUMP(extra));
 #endif
 
 	if (dump_on_failure) {
@@ -190,203 +356,170 @@ report_failure(void *extra)
 	}
 }
 
-/*
- * Summarize repeated failures in the just-completed test file.
- * The reports above suppress multiple failures from the same source
- * line; this reports on any tests that did fail multiple times.

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list