aboutsummaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2012-01-05 12:57:14 +0000
committerMartin Matuska <mm@FreeBSD.org>2012-01-05 12:57:14 +0000
commite42eef304bbcb48da12511ffedda93732847a7c3 (patch)
tree0e6529b31367e752d2dfd1343511ba2a644c6c90 /usr.bin
parent3a86a50b49e3b1a7cc76f7a1db61c8fd302c1c7e (diff)
downloadsrc-e42eef304bbcb48da12511ffedda93732847a7c3.tar.gz
src-e42eef304bbcb48da12511ffedda93732847a7c3.zip
MFC r228797:
Use contrib sources for building libarchive, tar and cpio. Make "make test" fully operational.
Notes
Notes: svn path=/stable/8/; revision=229596
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/cpio/Makefile16
-rw-r--r--usr.bin/cpio/bsdcpio.1405
-rw-r--r--usr.bin/cpio/cmdline.c371
-rw-r--r--usr.bin/cpio/cpio.c1277
-rw-r--r--usr.bin/cpio/cpio.h111
-rw-r--r--usr.bin/cpio/cpio_platform.h77
-rw-r--r--usr.bin/cpio/test/Makefile23
-rw-r--r--usr.bin/cpio/test/main.c2140
-rw-r--r--usr.bin/cpio/test/test.h285
-rw-r--r--usr.bin/cpio/test/test_0.c67
-rw-r--r--usr.bin/cpio/test/test_basic.c173
-rw-r--r--usr.bin/cpio/test/test_cmdline.c107
-rw-r--r--usr.bin/cpio/test/test_format_newc.c294
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat.c108
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref.bin.uu16
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref.crc.uu27
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref.newc.uu27
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref.ustar.uu84
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu17
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu17
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu17
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu74
-rw-r--r--usr.bin/cpio/test/test_option_B_upper.c52
-rw-r--r--usr.bin/cpio/test/test_option_C_upper.c62
-rw-r--r--usr.bin/cpio/test/test_option_J_upper.c56
-rw-r--r--usr.bin/cpio/test/test_option_L_upper.c101
-rw-r--r--usr.bin/cpio/test/test_option_Z_upper.c56
-rw-r--r--usr.bin/cpio/test/test_option_a.c154
-rw-r--r--usr.bin/cpio/test/test_option_c.c221
-rw-r--r--usr.bin/cpio/test/test_option_d.c64
-rw-r--r--usr.bin/cpio/test/test_option_f.c76
-rw-r--r--usr.bin/cpio/test/test_option_f.cpio.uu16
-rw-r--r--usr.bin/cpio/test/test_option_help.c84
-rw-r--r--usr.bin/cpio/test/test_option_l.c50
-rw-r--r--usr.bin/cpio/test/test_option_lzma.c56
-rw-r--r--usr.bin/cpio/test/test_option_m.c63
-rw-r--r--usr.bin/cpio/test/test_option_m.cpio.uu16
-rw-r--r--usr.bin/cpio/test/test_option_t.c95
-rw-r--r--usr.bin/cpio/test/test_option_t.cpio.uu16
-rw-r--r--usr.bin/cpio/test/test_option_t.stdout.uu5
-rw-r--r--usr.bin/cpio/test/test_option_tv.stdout.uu6
-rw-r--r--usr.bin/cpio/test/test_option_u.c81
-rw-r--r--usr.bin/cpio/test/test_option_version.c109
-rw-r--r--usr.bin/cpio/test/test_option_y.c57
-rw-r--r--usr.bin/cpio/test/test_option_z.c56
-rw-r--r--usr.bin/cpio/test/test_owner_parse.c122
-rw-r--r--usr.bin/cpio/test/test_passthrough_dotdot.c76
-rw-r--r--usr.bin/cpio/test/test_passthrough_reverse.c85
-rw-r--r--usr.bin/cpio/test/test_pathmatch.c243
-rw-r--r--usr.bin/tar/COPYING62
-rw-r--r--usr.bin/tar/Makefile19
-rw-r--r--usr.bin/tar/bsdtar.11029
-rw-r--r--usr.bin/tar/bsdtar.c733
-rw-r--r--usr.bin/tar/bsdtar.h157
-rw-r--r--usr.bin/tar/bsdtar_platform.h132
-rw-r--r--usr.bin/tar/cmdline.c381
-rw-r--r--usr.bin/tar/getdate.c1037
-rw-r--r--usr.bin/tar/read.c442
-rw-r--r--usr.bin/tar/subst.c289
-rw-r--r--usr.bin/tar/test/Makefile23
-rw-r--r--usr.bin/tar/test/main.c2242
-rw-r--r--usr.bin/tar/test/test.h288
-rw-r--r--usr.bin/tar/test/test_0.c67
-rw-r--r--usr.bin/tar/test/test_basic.c115
-rw-r--r--usr.bin/tar/test/test_copy.c372
-rw-r--r--usr.bin/tar/test/test_empty_mtree.c45
-rw-r--r--usr.bin/tar/test/test_getdate.c80
-rw-r--r--usr.bin/tar/test/test_help.c84
-rw-r--r--usr.bin/tar/test/test_option_T_upper.c188
-rw-r--r--usr.bin/tar/test/test_option_q.c129
-rw-r--r--usr.bin/tar/test/test_option_r.c117
-rw-r--r--usr.bin/tar/test/test_option_s.c107
-rw-r--r--usr.bin/tar/test/test_patterns.c184
-rw-r--r--usr.bin/tar/test/test_patterns_2.tar.uu233
-rw-r--r--usr.bin/tar/test/test_patterns_3.tar.uu233
-rw-r--r--usr.bin/tar/test/test_patterns_4.tar.uu643
-rw-r--r--usr.bin/tar/test/test_stdio.c125
-rw-r--r--usr.bin/tar/test/test_strip_components.c109
-rw-r--r--usr.bin/tar/test/test_symlink_dir.c160
-rw-r--r--usr.bin/tar/test/test_version.c97
-rw-r--r--usr.bin/tar/tree.c820
-rw-r--r--usr.bin/tar/tree.h141
-rw-r--r--usr.bin/tar/util.c563
-rw-r--r--usr.bin/tar/write.c1159
84 files changed, 48 insertions, 20368 deletions
diff --git a/usr.bin/cpio/Makefile b/usr.bin/cpio/Makefile
index 19653f3abc53..fb6c967741a3 100644
--- a/usr.bin/cpio/Makefile
+++ b/usr.bin/cpio/Makefile
@@ -2,19 +2,22 @@
.include <bsd.own.mk>
+LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive
+
PROG= bsdcpio
BSDCPIO_VERSION_STRING=2.8.5
+.PATH: ${LIBARCHIVEDIR}/cpio
SRCS= cpio.c cmdline.c
-.PATH: ${.CURDIR}/../../lib/libarchive/libarchive_fe
+.PATH: ${LIBARCHIVEDIR}/libarchive_fe
SRCS+= err.c line_reader.c matching.c pathmatch.c
WARNS?= 6
DPADD= ${LIBARCHIVE} ${LIBZ} ${LIBBZ2}
CFLAGS+= -DBSDCPIO_VERSION_STRING=\"${BSDCPIO_VERSION_STRING}\"
-CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
-CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../../lib/libarchive/libarchive_fe
+CFLAGS+= -DPLATFORM_CONFIG_H=\"${.CURDIR}/config_freebsd.h\"
+CFLAGS+= -I${LIBARCHIVEDIR}/cpio -I${LIBARCHIVEDIR}/libarchive_fe
.ifdef RELEASE_CRUNCH
# FreeBSD's installer uses cpio in crunched binaries that are
@@ -34,9 +37,12 @@ LDADD+= -lmd
SYMLINKS=bsdcpio ${BINDIR}/cpio
MLINKS= bsdcpio.1 cpio.1
-.PHONY: check test
+.PHONY: check test clean-test
check test: $(PROG) bsdcpio.1.gz
- cd ${.CURDIR}/test && make clean test
+ cd ${.CURDIR}/test && make obj && make test
+
+clean-test:
+ cd ${.CURDIR}/test && make clean
.include <bsd.prog.mk>
diff --git a/usr.bin/cpio/bsdcpio.1 b/usr.bin/cpio/bsdcpio.1
deleted file mode 100644
index 789ce74e1c48..000000000000
--- a/usr.bin/cpio/bsdcpio.1
+++ /dev/null
@@ -1,405 +0,0 @@
-.\" Copyright (c) 2003-2007 Tim Kientzle
-.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd September 5, 2010
-.Dt BSDCPIO 1
-.Os
-.Sh NAME
-.Nm cpio
-.Nd copy files to and from archives
-.Sh SYNOPSIS
-.Nm
-.Brq Fl i
-.Op Ar options
-.Op Ar pattern ...
-.Op Ar < archive
-.Nm
-.Brq Fl o
-.Op Ar options
-.Ar < name-list
-.Op Ar > archive
-.Nm
-.Brq Fl p
-.Op Ar options
-.Ar dest-dir
-.Ar < name-list
-.Sh DESCRIPTION
-.Nm
-copies files between archives and directories.
-This implementation can extract from tar, pax, cpio, zip, jar, ar,
-and ISO 9660 cdrom images and can create tar, pax, cpio, ar,
-and shar archives.
-.Pp
-The first option to
-.Nm
-is a mode indicator from the following list:
-.Bl -tag -compact -width indent
-.It Fl i
-Input.
-Read an archive from standard input (unless overriden) and extract the
-contents to disk or (if the
-.Fl t
-option is specified)
-list the contents to standard output.
-If one or more file patterns are specified, only files matching
-one of the patterns will be extracted.
-.It Fl o
-Output.
-Read a list of filenames from standard input and produce a new archive
-on standard output (unless overriden) containing the specified items.
-.It Fl p
-Pass-through.
-Read a list of filenames from standard input and copy the files to the
-specified directory.
-.El
-.Pp
-.Sh OPTIONS
-Unless specifically stated otherwise, options are applicable in
-all operating modes.
-.Bl -tag -width indent
-.It Fl 0
-Read filenames separated by NUL characters instead of newlines.
-This is necessary if any of the filenames being read might contain newlines.
-.It Fl A
-(o mode only)
-Append to the specified archive.
-(Not yet implemented.)
-.It Fl a
-(o and p modes)
-Reset access times on files after they are read.
-.It Fl B
-(o mode only)
-Block output to records of 5120 bytes.
-.It Fl C Ar size
-(o mode only)
-Block output to records of
-.Ar size
-bytes.
-.It Fl c
-(o mode only)
-Use the old POSIX portable character format.
-Equivalent to
-.Fl -format Ar odc .
-.It Fl d
-(i and p modes)
-Create directories as necessary.
-.It Fl E Ar file
-(i mode only)
-Read list of file name patterns from
-.Ar file
-to list and extract.
-.It Fl F Ar file
-Read archive from or write archive to
-.Ar file .
-.It Fl f Ar pattern
-(i mode only)
-Ignore files that match
-.Ar pattern .
-.It Fl -format Ar format
-(o mode only)
-Produce the output archive in the specified format.
-Supported formats include:
-.Pp
-.Bl -tag -width "iso9660" -compact
-.It Ar cpio
-Synonym for
-.Ar odc .
-.It Ar newc
-The SVR4 portable cpio format.
-.It Ar odc
-The old POSIX.1 portable octet-oriented cpio format.
-.It Ar pax
-The POSIX.1 pax format, an extension of the ustar format.
-.It Ar ustar
-The POSIX.1 tar format.
-.El
-.Pp
-The default format is
-.Ar odc .
-See
-.Xr libarchive-formats 5
-for more complete information about the
-formats currently supported by the underlying
-.Xr libarchive 3
-library.
-.It Fl H Ar format
-Synonym for
-.Fl -format .
-.It Fl h , Fl -help
-Print usage information.
-.It Fl I Ar file
-Read archive from
-.Ar file .
-.It Fl i
-Input mode.
-See above for description.
-.It Fl -insecure
-(i and p mode only)
-Disable security checks during extraction or copying.
-This allows extraction via symbolic links and path names containing
-.Sq ..
-in the name.
-.It Fl J
-(o mode only)
-Compress the file with xz-compatible compression before writing it.
-In input mode, this option is ignored; xz compression is recognized
-automatically on input.
-.It Fl j
-Synonym for
-.Fl y .
-.It Fl L
-(o and p modes)
-All symbolic links will be followed.
-Normally, symbolic links are archived and copied as symbolic links.
-With this option, the target of the link will be archived or copied instead.
-.It Fl l
-(p mode only)
-Create links from the target directory to the original files,
-instead of copying.
-.It Fl lzma
-(o mode only)
-Compress the file with lzma-compatible compression before writing it.
-In input mode, this option is ignored; lzma compression is recognized
-automatically on input.
-.It Fl m
-(i and p modes)
-Set file modification time on created files to match
-those in the source.
-.It Fl n
-(i mode, only with
-.Fl t )
-Display numeric uid and gid.
-By default,
-.Nm
-displays the user and group names when they are provided in the
-archive, or looks up the user and group names in the system
-password database.
-.It Fl no-preserve-owner
-(i mode only)
-Do not attempt to restore file ownership.
-This is the default when run by non-root users.
-.It Fl O Ar file
-Write archive to
-.Ar file .
-.It Fl o
-Output mode.
-See above for description.
-.It Fl p
-Pass-through mode.
-See above for description.
-.It Fl preserve-owner
-(i mode only)
-Restore file ownership.
-This is the default when run by the root user.
-.It Fl -quiet
-Suppress unnecessary messages.
-.It Fl R Oo user Oc Ns Oo : Oc Ns Oo group Oc
-Set the owner and/or group on files in the output.
-If group is specified with no user
-(for example,
-.Fl R Ar :wheel )
-then the group will be set but not the user.
-If the user is specified with a trailing colon and no group
-(for example,
-.Fl R Ar root: )
-then the group will be set to the user's default group.
-If the user is specified with no trailing colon, then
-the user will be set but not the group.
-In
-.Fl i
-and
-.Fl p
-modes, this option can only be used by the super-user.
-(For compatibility, a period can be used in place of the colon.)
-.It Fl r
-(All modes.)
-Rename files interactively.
-For each file, a prompt is written to
-.Pa /dev/tty
-containing the name of the file and a line is read from
-.Pa /dev/tty .
-If the line read is blank, the file is skipped.
-If the line contains a single period, the file is processed normally.
-Otherwise, the line is taken to be the new name of the file.
-.It Fl t
-(i mode only)
-List the contents of the archive to stdout;
-do not restore the contents to disk.
-.It Fl u
-(i and p modes)
-Unconditionally overwrite existing files.
-Ordinarily, an older file will not overwrite a newer file on disk.
-.It Fl v
-Print the name of each file to stderr as it is processed.
-With
-.Fl t ,
-provide a detailed listing of each file.
-.It Fl -version
-Print the program version information and exit.
-.It Fl y
-(o mode only)
-Compress the archive with bzip2-compatible compression before writing it.
-In input mode, this option is ignored;
-bzip2 compression is recognized automatically on input.
-.It Fl Z
-(o mode only)
-Compress the archive with compress-compatible compression before writing it.
-In input mode, this option is ignored;
-compression is recognized automatically on input.
-.It Fl z
-(o mode only)
-Compress the archive with gzip-compatible compression before writing it.
-In input mode, this option is ignored;
-gzip compression is recognized automatically on input.
-.El
-.Sh ENVIRONMENT
-The following environment variables affect the execution of
-.Nm :
-.Bl -tag -width ".Ev BLOCKSIZE"
-.It Ev LANG
-The locale to use.
-See
-.Xr environ 7
-for more information.
-.It Ev TZ
-The timezone to use when displaying dates.
-See
-.Xr environ 7
-for more information.
-.El
-.Sh EXIT STATUS
-.Ex -std
-.Sh EXAMPLES
-The
-.Nm
-command is traditionally used to copy file hierarchies in conjunction
-with the
-.Xr find 1
-command.
-The first example here simply copies all files from
-.Pa src
-to
-.Pa dest :
-.Dl Nm find Pa src | Nm Fl pmud Pa dest
-.Pp
-By carefully selecting options to the
-.Xr find 1
-command and combining it with other standard utilities,
-it is possible to exercise very fine control over which files are copied.
-This next example copies files from
-.Pa src
-to
-.Pa dest
-that are more than 2 days old and whose names match a particular pattern:
-.Dl Nm find Pa src Fl mtime Ar +2 | Nm grep foo[bar] | Nm Fl pdmu Pa dest
-.Pp
-This example copies files from
-.Pa src
-to
-.Pa dest
-that are more than 2 days old and which contain the word
-.Do foobar Dc :
-.Dl Nm find Pa src Fl mtime Ar +2 | Nm xargs Nm grep -l foobar | Nm Fl pdmu Pa dest
-.Sh COMPATIBILITY
-The mode options i, o, and p and the options
-a, B, c, d, f, l, m, r, t, u, and v comply with SUSv2.
-.Pp
-The old POSIX.1 standard specified that only
-.Fl i ,
-.Fl o ,
-and
-.Fl p
-were interpreted as command-line options.
-Each took a single argument of a list of modifier
-characters.
-For example, the standard syntax allows
-.Fl imu
-but does not support
-.Fl miu
-or
-.Fl i Fl m Fl u ,
-since
-.Ar m
-and
-.Ar u
-are only modifiers to
-.Fl i ,
-they are not command-line options in their own right.
-The syntax supported by this implementation is backwards-compatible
-with the standard.
-For best compatibility, scripts should limit themselves to the
-standard syntax.
-.Sh SEE ALSO
-.Xr bzip2 1 ,
-.Xr tar 1 ,
-.Xr gzip 1 ,
-.Xr mt 1 ,
-.Xr pax 1 ,
-.Xr libarchive 3 ,
-.Xr cpio 5 ,
-.Xr libarchive-formats 5 ,
-.Xr tar 5
-.Sh STANDARDS
-There is no current POSIX standard for the cpio command; it appeared
-in
-.St -p1003.1-96
-but was dropped from
-.St -p1003.1-2001 .
-.Pp
-The cpio, ustar, and pax interchange file formats are defined by
-.St -p1003.1-2001
-for the pax command.
-.Sh HISTORY
-The original
-.Nm cpio
-and
-.Nm find
-utilities were written by Dick Haight
-while working in AT&T's Unix Support Group.
-They first appeared in 1977 in PWB/UNIX 1.0, the
-.Dq Programmer's Work Bench
-system developed for use within AT&T.
-They were first released outside of AT&T as part of System III Unix in 1981.
-As a result,
-.Nm cpio
-actually predates
-.Nm tar ,
-even though it was not well-known outside of AT&T until some time later.
-.Pp
-This is a complete re-implementation based on the
-.Xr libarchive 3
-library.
-.Sh BUGS
-The cpio archive format has several basic limitations:
-It does not store user and group names, only numbers.
-As a result, it cannot be reliably used to transfer
-files between systems with dissimilar user and group numbering.
-Older cpio formats limit the user and group numbers to
-16 or 18 bits, which is insufficient for modern systems.
-The cpio archive formats cannot support files over 4 gigabytes,
-except for the
-.Dq odc
-variant, which can support files up to 8 gigabytes.
diff --git a/usr.bin/cpio/cmdline.c b/usr.bin/cpio/cmdline.c
deleted file mode 100644
index 687fa62cb6d7..000000000000
--- a/usr.bin/cpio/cmdline.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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 "cpio_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "cpio.h"
-#include "err.h"
-
-/*
- * Short options for cpio. Please keep this sorted.
- */
-static const char *short_options = "0AaBC:cdE:F:f:H:hI:iJjLlmnO:opR:rtuvW:yZz";
-
-/*
- * Long options for cpio. Please keep this sorted.
- */
-static const struct option {
- const char *name;
- int required; /* 1 if this option requires an argument */
- int equivalent; /* Equivalent short option. */
-} cpio_longopts[] = {
- { "create", 0, 'o' },
- { "extract", 0, 'i' },
- { "file", 1, 'F' },
- { "format", 1, 'H' },
- { "help", 0, 'h' },
- { "insecure", 0, OPTION_INSECURE },
- { "link", 0, 'l' },
- { "list", 0, 't' },
- { "lzma", 0, OPTION_LZMA },
- { "make-directories", 0, 'd' },
- { "no-preserve-owner", 0, OPTION_NO_PRESERVE_OWNER },
- { "null", 0, '0' },
- { "numeric-uid-gid", 0, 'n' },
- { "owner", 1, 'R' },
- { "pass-through", 0, 'p' },
- { "preserve-modification-time", 0, 'm' },
- { "preserve-owner", 0, OPTION_PRESERVE_OWNER },
- { "quiet", 0, OPTION_QUIET },
- { "unconditional", 0, 'u' },
- { "verbose", 0, 'v' },
- { "version", 0, OPTION_VERSION },
- { "xz", 0, 'J' },
- { NULL, 0, 0 }
-};
-
-/*
- * I used to try to select platform-provided getopt() or
- * getopt_long(), but that caused a lot of headaches. In particular,
- * I couldn't consistently use long options in the test harness
- * because not all platforms have getopt_long(). That in turn led to
- * overuse of the -W hack in the test harness, which made it rough to
- * run the test harness against GNU cpio. (I periodically run the
- * test harness here against GNU cpio as a sanity-check. Yes,
- * I've found a couple of bugs in GNU cpio that way.)
- */
-int
-cpio_getopt(struct cpio *cpio)
-{
- enum { state_start = 0, state_next_word, state_short, state_long };
- static int state = state_start;
- static char *opt_word;
-
- const struct option *popt, *match = NULL, *match2 = NULL;
- const char *p, *long_prefix = "--";
- size_t optlength;
- int opt = '?';
- int required = 0;
-
- cpio->optarg = NULL;
-
- /* First time through, initialize everything. */
- if (state == state_start) {
- /* Skip program name. */
- ++cpio->argv;
- --cpio->argc;
- state = state_next_word;
- }
-
- /*
- * We're ready to look at the next word in argv.
- */
- if (state == state_next_word) {
- /* No more arguments, so no more options. */
- if (cpio->argv[0] == NULL)
- return (-1);
- /* Doesn't start with '-', so no more options. */
- if (cpio->argv[0][0] != '-')
- return (-1);
- /* "--" marks end of options; consume it and return. */
- if (strcmp(cpio->argv[0], "--") == 0) {
- ++cpio->argv;
- --cpio->argc;
- return (-1);
- }
- /* Get next word for parsing. */
- opt_word = *cpio->argv++;
- --cpio->argc;
- if (opt_word[1] == '-') {
- /* Set up long option parser. */
- state = state_long;
- opt_word += 2; /* Skip leading '--' */
- } else {
- /* Set up short option parser. */
- state = state_short;
- ++opt_word; /* Skip leading '-' */
- }
- }
-
- /*
- * We're parsing a group of POSIX-style single-character options.
- */
- if (state == state_short) {
- /* Peel next option off of a group of short options. */
- opt = *opt_word++;
- if (opt == '\0') {
- /* End of this group; recurse to get next option. */
- state = state_next_word;
- return cpio_getopt(cpio);
- }
-
- /* Does this option take an argument? */
- p = strchr(short_options, opt);
- if (p == NULL)
- return ('?');
- if (p[1] == ':')
- required = 1;
-
- /* If it takes an argument, parse that. */
- if (required) {
- /* If arg is run-in, opt_word already points to it. */
- if (opt_word[0] == '\0') {
- /* Otherwise, pick up the next word. */
- opt_word = *cpio->argv;
- if (opt_word == NULL) {
- lafe_warnc(0,
- "Option -%c requires an argument",
- opt);
- return ('?');
- }
- ++cpio->argv;
- --cpio->argc;
- }
- if (opt == 'W') {
- state = state_long;
- long_prefix = "-W "; /* For clearer errors. */
- } else {
- state = state_next_word;
- cpio->optarg = opt_word;
- }
- }
- }
-
- /* We're reading a long option, including -W long=arg convention. */
- if (state == state_long) {
- /* After this long option, we'll be starting a new word. */
- state = state_next_word;
-
- /* Option name ends at '=' if there is one. */
- p = strchr(opt_word, '=');
- if (p != NULL) {
- optlength = (size_t)(p - opt_word);
- cpio->optarg = (char *)(uintptr_t)(p + 1);
- } else {
- optlength = strlen(opt_word);
- }
-
- /* Search the table for an unambiguous match. */
- for (popt = cpio_longopts; popt->name != NULL; popt++) {
- /* Short-circuit if first chars don't match. */
- if (popt->name[0] != opt_word[0])
- continue;
- /* If option is a prefix of name in table, record it.*/
- if (strncmp(opt_word, popt->name, optlength) == 0) {
- match2 = match; /* Record up to two matches. */
- match = popt;
- /* If it's an exact match, we're done. */
- if (strlen(popt->name) == optlength) {
- match2 = NULL; /* Forget the others. */
- break;
- }
- }
- }
-
- /* Fail if there wasn't a unique match. */
- if (match == NULL) {
- lafe_warnc(0,
- "Option %s%s is not supported",
- long_prefix, opt_word);
- return ('?');
- }
- if (match2 != NULL) {
- lafe_warnc(0,
- "Ambiguous option %s%s (matches --%s and --%s)",
- long_prefix, opt_word, match->name, match2->name);
- return ('?');
- }
-
- /* We've found a unique match; does it need an argument? */
- if (match->required) {
- /* Argument required: get next word if necessary. */
- if (cpio->optarg == NULL) {
- cpio->optarg = *cpio->argv;
- if (cpio->optarg == NULL) {
- lafe_warnc(0,
- "Option %s%s requires an argument",
- long_prefix, match->name);
- return ('?');
- }
- ++cpio->argv;
- --cpio->argc;
- }
- } else {
- /* Argument forbidden: fail if there is one. */
- if (cpio->optarg != NULL) {
- lafe_warnc(0,
- "Option %s%s does not allow an argument",
- long_prefix, match->name);
- return ('?');
- }
- }
- return (match->equivalent);
- }
-
- return (opt);
-}
-
-
-/*
- * Parse the argument to the -R or --owner flag.
- *
- * The format is one of the following:
- * <username|uid> - Override user but not group
- * <username>: - Override both, group is user's default group
- * <uid>: - Override user but not group
- * <username|uid>:<groupname|gid> - Override both
- * :<groupname|gid> - Override group but not user
- *
- * Where uid/gid are decimal representations and groupname/username
- * are names to be looked up in system database. Note that we try
- * to look up an argument as a name first, then try numeric parsing.
- *
- * A period can be used instead of the colon.
- *
- * Sets uid/gid return as appropriate, -1 indicates uid/gid not specified.
- * TODO: If the spec uses uname/gname, then return those to the caller
- * as well. If the spec provides uid/gid, just return names as NULL.
- *
- * Returns NULL if no error, otherwise returns error string for display.
- *
- */
-const char *
-owner_parse(const char *spec, int *uid, int *gid)
-{
- static char errbuff[128];
- const char *u, *ue, *g;
-
- *uid = -1;
- *gid = -1;
-
- if (spec[0] == '\0')
- return ("Invalid empty user/group spec");
-
- /*
- * Split spec into [user][:.][group]
- * u -> first char of username, NULL if no username
- * ue -> first char after username (colon, period, or \0)
- * g -> first char of group name
- */
- if (*spec == ':' || *spec == '.') {
- /* If spec starts with ':' or '.', then just group. */
- ue = u = NULL;
- g = spec + 1;
- } else {
- /* Otherwise, [user] or [user][:] or [user][:][group] */
- ue = u = spec;
- while (*ue != ':' && *ue != '.' && *ue != '\0')
- ++ue;
- g = ue;
- if (*g != '\0') /* Skip : or . to find first char of group. */
- ++g;
- }
-
- if (u != NULL) {
- /* Look up user: ue is first char after end of user. */
- char *user;
- struct passwd *pwent;
-
- user = (char *)malloc(ue - u + 1);
- if (user == NULL)
- return ("Couldn't allocate memory");
- memcpy(user, u, ue - u);
- user[ue - u] = '\0';
- if ((pwent = getpwnam(user)) != NULL) {
- *uid = pwent->pw_uid;
- if (*ue != '\0')
- *gid = pwent->pw_gid;
- } else {
- char *end;
- errno = 0;
- *uid = strtoul(user, &end, 10);
- if (errno || *end != '\0') {
- snprintf(errbuff, sizeof(errbuff),
- "Couldn't lookup user ``%s''", user);
- errbuff[sizeof(errbuff) - 1] = '\0';
- return (errbuff);
- }
- }
- free(user);
- }
-
- if (*g != '\0') {
- struct group *grp;
- if ((grp = getgrnam(g)) != NULL) {
- *gid = grp->gr_gid;
- } else {
- char *end;
- errno = 0;
- *gid = strtoul(g, &end, 10);
- if (errno || *end != '\0') {
- snprintf(errbuff, sizeof(errbuff),
- "Couldn't lookup group ``%s''", g);
- errbuff[sizeof(errbuff) - 1] = '\0';
- return (errbuff);
- }
- }
- }
- return (NULL);
-}
diff --git a/usr.bin/cpio/cpio.c b/usr.bin/cpio/cpio.c
deleted file mode 100644
index cd81050e1531..000000000000
--- a/usr.bin/cpio/cpio.c
+++ /dev/null
@@ -1,1277 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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 "cpio_platform.h"
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <archive.h>
-#include <archive_entry.h>
-
-#ifdef HAVE_SYS_MKDEV_H
-#include <sys/mkdev.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#ifdef HAVE_STDARG_H
-#include <stdarg.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-
-#include "cpio.h"
-#include "err.h"
-#include "line_reader.h"
-#include "matching.h"
-
-/* Fixed size of uname/gname caches. */
-#define name_cache_size 101
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-struct name_cache {
- int probes;
- int hits;
- size_t size;
- struct {
- id_t id;
- char *name;
- } cache[name_cache_size];
-};
-
-static int extract_data(struct archive *, struct archive *);
-const char * cpio_i64toa(int64_t);
-static const char *cpio_rename(const char *name);
-static int entry_to_archive(struct cpio *, struct archive_entry *);
-static int file_to_archive(struct cpio *, const char *);
-static void free_cache(struct name_cache *cache);
-static void list_item_verbose(struct cpio *, struct archive_entry *);
-static void long_help(void);
-static const char *lookup_gname(struct cpio *, gid_t gid);
-static int lookup_gname_helper(struct cpio *,
- const char **name, id_t gid);
-static const char *lookup_uname(struct cpio *, uid_t uid);
-static int lookup_uname_helper(struct cpio *,
- const char **name, id_t uid);
-static void mode_in(struct cpio *);
-static void mode_list(struct cpio *);
-static void mode_out(struct cpio *);
-static void mode_pass(struct cpio *, const char *);
-static int restore_time(struct cpio *, struct archive_entry *,
- const char *, int fd);
-static void usage(void);
-static void version(void);
-
-int
-main(int argc, char *argv[])
-{
- static char buff[16384];
- struct cpio _cpio; /* Allocated on stack. */
- struct cpio *cpio;
- const char *errmsg;
- int uid, gid;
- int opt;
-
- cpio = &_cpio;
- memset(cpio, 0, sizeof(*cpio));
- cpio->buff = buff;
- cpio->buff_size = sizeof(buff);
-
- /* Need lafe_progname before calling lafe_warnc. */
- if (*argv == NULL)
- lafe_progname = "bsdcpio";
- else {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- lafe_progname = strrchr(*argv, '\\');
-#else
- lafe_progname = strrchr(*argv, '/');
-#endif
- if (lafe_progname != NULL)
- lafe_progname++;
- else
- lafe_progname = *argv;
- }
-
- cpio->uid_override = -1;
- cpio->gid_override = -1;
- cpio->argv = argv;
- cpio->argc = argc;
- cpio->mode = '\0';
- cpio->verbose = 0;
- cpio->compress = '\0';
- cpio->extract_flags = ARCHIVE_EXTRACT_NO_AUTODIR;
- cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
- cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS;
- cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT;
- cpio->extract_flags |= ARCHIVE_EXTRACT_PERM;
- cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
- cpio->extract_flags |= ARCHIVE_EXTRACT_ACL;
-#if !defined(_WIN32) && !defined(__CYGWIN__)
- if (geteuid() == 0)
- cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER;
-#endif
- cpio->bytes_per_block = 512;
- cpio->filename = NULL;
-
- while ((opt = cpio_getopt(cpio)) != -1) {
- switch (opt) {
- case '0': /* GNU convention: --null, -0 */
- cpio->option_null = 1;
- break;
- case 'A': /* NetBSD/OpenBSD */
- cpio->option_append = 1;
- break;
- case 'a': /* POSIX 1997 */
- cpio->option_atime_restore = 1;
- break;
- case 'B': /* POSIX 1997 */
- cpio->bytes_per_block = 5120;
- break;
- case 'C': /* NetBSD/OpenBSD */
- cpio->bytes_per_block = atoi(cpio->optarg);
- if (cpio->bytes_per_block <= 0)
- lafe_errc(1, 0, "Invalid blocksize %s", cpio->optarg);
- break;
- case 'c': /* POSIX 1997 */
- cpio->format = "odc";
- break;
- case 'd': /* POSIX 1997 */
- cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR;
- break;
- case 'E': /* NetBSD/OpenBSD */
- lafe_include_from_file(&cpio->matching,
- cpio->optarg, cpio->option_null);
- break;
- case 'F': /* NetBSD/OpenBSD/GNU cpio */
- cpio->filename = cpio->optarg;
- break;
- case 'f': /* POSIX 1997 */
- lafe_exclude(&cpio->matching, cpio->optarg);
- break;
- case 'H': /* GNU cpio (also --format) */
- cpio->format = cpio->optarg;
- break;
- case 'h':
- long_help();
- break;
- case 'I': /* NetBSD/OpenBSD */
- cpio->filename = cpio->optarg;
- break;
- case 'i': /* POSIX 1997 */
- if (cpio->mode != '\0')
- lafe_errc(1, 0,
- "Cannot use both -i and -%c", cpio->mode);
- cpio->mode = opt;
- break;
- case 'J': /* GNU tar, others */
- cpio->compress = opt;
- break;
- case 'j': /* GNU tar, others */
- cpio->compress = opt;
- break;
- case OPTION_INSECURE:
- cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS;
- cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
- break;
- case 'L': /* GNU cpio */
- cpio->option_follow_links = 1;
- break;
- case 'l': /* POSIX 1997 */
- cpio->option_link = 1;
- break;
- case OPTION_LZMA: /* GNU tar, others */
- cpio->compress = opt;
- break;
- case 'm': /* POSIX 1997 */
- cpio->extract_flags |= ARCHIVE_EXTRACT_TIME;
- break;
- case 'n': /* GNU cpio */
- cpio->option_numeric_uid_gid = 1;
- break;
- case OPTION_NO_PRESERVE_OWNER: /* GNU cpio */
- cpio->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
- break;
- case 'O': /* GNU cpio */
- cpio->filename = cpio->optarg;
- break;
- case 'o': /* POSIX 1997 */
- if (cpio->mode != '\0')
- lafe_errc(1, 0,
- "Cannot use both -o and -%c", cpio->mode);
- cpio->mode = opt;
- break;
- case 'p': /* POSIX 1997 */
- if (cpio->mode != '\0')
- lafe_errc(1, 0,
- "Cannot use both -p and -%c", cpio->mode);
- cpio->mode = opt;
- cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
- break;
- case OPTION_PRESERVE_OWNER:
- cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER;
- break;
- case OPTION_QUIET: /* GNU cpio */
- cpio->quiet = 1;
- break;
- case 'R': /* GNU cpio, also --owner */
- /* TODO: owner_parse should return uname/gname
- * also; use that to set [ug]name_override. */
- errmsg = owner_parse(cpio->optarg, &uid, &gid);
- if (errmsg) {
- lafe_warnc(-1, "%s", errmsg);
- usage();
- }
- if (uid != -1) {
- cpio->uid_override = uid;
- cpio->uname_override = NULL;
- }
- if (gid != -1) {
- cpio->gid_override = gid;
- cpio->gname_override = NULL;
- }
- break;
- case 'r': /* POSIX 1997 */
- cpio->option_rename = 1;
- break;
- case 't': /* POSIX 1997 */
- cpio->option_list = 1;
- break;
- case 'u': /* POSIX 1997 */
- cpio->extract_flags
- &= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
- break;
- case 'v': /* POSIX 1997 */
- cpio->verbose++;
- break;
- case OPTION_VERSION: /* GNU convention */
- version();
- break;
-#if 0
- /*
- * cpio_getopt() handles -W specially, so it's not
- * available here.
- */
- case 'W': /* Obscure, but useful GNU convention. */
- break;
-#endif
- case 'y': /* tar convention */
- cpio->compress = opt;
- break;
- case 'Z': /* tar convention */
- cpio->compress = opt;
- break;
- case 'z': /* tar convention */
- cpio->compress = opt;
- break;
- default:
- usage();
- }
- }
-
- /*
- * Sanity-check args, error out on nonsensical combinations.
- */
- /* -t implies -i if no mode was specified. */
- if (cpio->option_list && cpio->mode == '\0')
- cpio->mode = 'i';
- /* -t requires -i */
- if (cpio->option_list && cpio->mode != 'i')
- lafe_errc(1, 0, "Option -t requires -i");
- /* -n requires -it */
- if (cpio->option_numeric_uid_gid && !cpio->option_list)
- lafe_errc(1, 0, "Option -n requires -it");
- /* Can only specify format when writing */
- if (cpio->format != NULL && cpio->mode != 'o')
- lafe_errc(1, 0, "Option --format requires -o");
- /* -l requires -p */
- if (cpio->option_link && cpio->mode != 'p')
- lafe_errc(1, 0, "Option -l requires -p");
- /* TODO: Flag other nonsensical combinations. */
-
- switch (cpio->mode) {
- case 'o':
- /* TODO: Implement old binary format in libarchive,
- use that here. */
- if (cpio->format == NULL)
- cpio->format = "odc"; /* Default format */
-
- mode_out(cpio);
- break;
- case 'i':
- while (*cpio->argv != NULL) {
- lafe_include(&cpio->matching, *cpio->argv);
- --cpio->argc;
- ++cpio->argv;
- }
- if (cpio->option_list)
- mode_list(cpio);
- else
- mode_in(cpio);
- break;
- case 'p':
- if (*cpio->argv == NULL || **cpio->argv == '\0')
- lafe_errc(1, 0,
- "-p mode requires a target directory");
- mode_pass(cpio, *cpio->argv);
- break;
- default:
- lafe_errc(1, 0,
- "Must specify at least one of -i, -o, or -p");
- }
-
- free_cache(cpio->gname_cache);
- free_cache(cpio->uname_cache);
- return (cpio->return_value);
-}
-
-static void
-usage(void)
-{
- const char *p;
-
- p = lafe_progname;
-
- fprintf(stderr, "Brief Usage:\n");
- fprintf(stderr, " List: %s -it < archive\n", p);
- fprintf(stderr, " Extract: %s -i < archive\n", p);
- fprintf(stderr, " Create: %s -o < filenames > archive\n", p);
- fprintf(stderr, " Help: %s --help\n", p);
- exit(1);
-}
-
-static const char *long_help_msg =
- "First option must be a mode specifier:\n"
- " -i Input -o Output -p Pass\n"
- "Common Options:\n"
- " -v Verbose\n"
- "Create: %p -o [options] < [list of files] > [archive]\n"
- " -J,-y,-z,--lzma Compress archive with xz/bzip2/gzip/lzma\n"
- " --format {odc|newc|ustar} Select archive format\n"
- "List: %p -it < [archive]\n"
- "Extract: %p -i [options] < [archive]\n";
-
-
-/*
- * Note that the word 'bsdcpio' will always appear in the first line
- * of output.
- *
- * In particular, /bin/sh scripts that need to test for the presence
- * of bsdcpio can use the following template:
- *
- * if (cpio --help 2>&1 | grep bsdcpio >/dev/null 2>&1 ) then \
- * echo bsdcpio; else echo not bsdcpio; fi
- */
-static void
-long_help(void)
-{
- const char *prog;
- const char *p;
-
- prog = lafe_progname;
-
- fflush(stderr);
-
- p = (strcmp(prog,"bsdcpio") != 0) ? "(bsdcpio)" : "";
- printf("%s%s: manipulate archive files\n", prog, p);
-
- for (p = long_help_msg; *p != '\0'; p++) {
- if (*p == '%') {
- if (p[1] == 'p') {
- fputs(prog, stdout);
- p++;
- } else
- putchar('%');
- } else
- putchar(*p);
- }
- version();
-}
-
-static void
-version(void)
-{
- fprintf(stdout,"bsdcpio %s -- %s\n",
- BSDCPIO_VERSION_STRING,
- archive_version());
- exit(0);
-}
-
-static void
-mode_out(struct cpio *cpio)
-{
- struct archive_entry *entry, *spare;
- struct lafe_line_reader *lr;
- const char *p;
- int r;
-
- if (cpio->option_append)
- lafe_errc(1, 0, "Append mode not yet supported.");
-
- cpio->archive_read_disk = archive_read_disk_new();
- if (cpio->archive_read_disk == NULL)
- lafe_errc(1, 0, "Failed to allocate archive object");
- if (cpio->option_follow_links)
- archive_read_disk_set_symlink_logical(cpio->archive_read_disk);
- else
- archive_read_disk_set_symlink_physical(cpio->archive_read_disk);
- archive_read_disk_set_standard_lookup(cpio->archive_read_disk);
-
- cpio->archive = archive_write_new();
- if (cpio->archive == NULL)
- lafe_errc(1, 0, "Failed to allocate archive object");
- switch (cpio->compress) {
- case 'J':
- r = archive_write_set_compression_xz(cpio->archive);
- break;
- case OPTION_LZMA:
- r = archive_write_set_compression_lzma(cpio->archive);
- break;
- case 'j': case 'y':
- r = archive_write_set_compression_bzip2(cpio->archive);
- break;
- case 'z':
- r = archive_write_set_compression_gzip(cpio->archive);
- break;
- case 'Z':
- r = archive_write_set_compression_compress(cpio->archive);
- break;
- default:
- r = archive_write_set_compression_none(cpio->archive);
- break;
- }
- if (r < ARCHIVE_WARN)
- lafe_errc(1, 0, "Requested compression not available");
- r = archive_write_set_format_by_name(cpio->archive, cpio->format);
- if (r != ARCHIVE_OK)
- lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
- archive_write_set_bytes_per_block(cpio->archive, cpio->bytes_per_block);
- cpio->linkresolver = archive_entry_linkresolver_new();
- archive_entry_linkresolver_set_strategy(cpio->linkresolver,
- archive_format(cpio->archive));
-
- /*
- * The main loop: Copy each file into the output archive.
- */
- r = archive_write_open_file(cpio->archive, cpio->filename);
- if (r != ARCHIVE_OK)
- lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
- lr = lafe_line_reader("-", cpio->option_null);
- while ((p = lafe_line_reader_next(lr)) != NULL)
- file_to_archive(cpio, p);
- lafe_line_reader_free(lr);
-
- /*
- * The hardlink detection may have queued up a couple of entries
- * that can now be flushed.
- */
- entry = NULL;
- archive_entry_linkify(cpio->linkresolver, &entry, &spare);
- while (entry != NULL) {
- entry_to_archive(cpio, entry);
- archive_entry_free(entry);
- entry = NULL;
- archive_entry_linkify(cpio->linkresolver, &entry, &spare);
- }
-
- r = archive_write_close(cpio->archive);
- if (r != ARCHIVE_OK)
- lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
-
- if (!cpio->quiet) {
- int64_t blocks =
- (archive_position_uncompressed(cpio->archive) + 511)
- / 512;
- fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
- blocks == 1 ? "block" : "blocks");
- }
- archive_write_finish(cpio->archive);
-}
-
-/*
- * This is used by both out mode (to copy objects from disk into
- * an archive) and pass mode (to copy objects from disk to
- * an archive_write_disk "archive").
- */
-static int
-file_to_archive(struct cpio *cpio, const char *srcpath)
-{
- const char *destpath;
- struct archive_entry *entry, *spare;
- size_t len;
- const char *p;
- int r;
-
- /*
- * Create an archive_entry describing the source file.
- *
- */
- entry = archive_entry_new();
- if (entry == NULL)
- lafe_errc(1, 0, "Couldn't allocate entry");
- archive_entry_copy_sourcepath(entry, srcpath);
- r = archive_read_disk_entry_from_file(cpio->archive_read_disk,
- entry, -1, NULL);
- if (r < ARCHIVE_FAILED)
- lafe_errc(1, 0, "%s",
- archive_error_string(cpio->archive_read_disk));
- if (r < ARCHIVE_OK)
- lafe_warnc(0, "%s",
- archive_error_string(cpio->archive_read_disk));
- if (r <= ARCHIVE_FAILED) {
- cpio->return_value = 1;
- return (r);
- }
-
- if (cpio->uid_override >= 0) {
- archive_entry_set_uid(entry, cpio->uid_override);
- archive_entry_set_uname(entry, cpio->uname_override);
- }
- if (cpio->gid_override >= 0) {
- archive_entry_set_gid(entry, cpio->gid_override);
- archive_entry_set_gname(entry, cpio->gname_override);
- }
-
- /*
- * Generate a destination path for this entry.
- * "destination path" is the name to which it will be copied in
- * pass mode or the name that will go into the archive in
- * output mode.
- */
- destpath = srcpath;
- if (cpio->destdir) {
- len = strlen(cpio->destdir) + strlen(srcpath) + 8;
- if (len >= cpio->pass_destpath_alloc) {
- while (len >= cpio->pass_destpath_alloc) {
- cpio->pass_destpath_alloc += 512;
- cpio->pass_destpath_alloc *= 2;
- }
- free(cpio->pass_destpath);
- cpio->pass_destpath = malloc(cpio->pass_destpath_alloc);
- if (cpio->pass_destpath == NULL)
- lafe_errc(1, ENOMEM,
- "Can't allocate path buffer");
- }
- strcpy(cpio->pass_destpath, cpio->destdir);
- p = srcpath;
- while (p[0] == '/')
- ++p;
- strcat(cpio->pass_destpath, p);
- destpath = cpio->pass_destpath;
- }
- if (cpio->option_rename)
- destpath = cpio_rename(destpath);
- if (destpath == NULL)
- return (0);
- archive_entry_copy_pathname(entry, destpath);
-
- /*
- * If we're trying to preserve hardlinks, match them here.
- */
- spare = NULL;
- if (cpio->linkresolver != NULL
- && archive_entry_filetype(entry) != AE_IFDIR) {
- archive_entry_linkify(cpio->linkresolver, &entry, &spare);
- }
-
- if (entry != NULL) {
- r = entry_to_archive(cpio, entry);
- archive_entry_free(entry);
- if (spare != NULL) {
- if (r == 0)
- r = entry_to_archive(cpio, spare);
- archive_entry_free(spare);
- }
- }
- return (r);
-}
-
-static int
-entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
-{
- const char *destpath = archive_entry_pathname(entry);
- const char *srcpath = archive_entry_sourcepath(entry);
- int fd = -1;
- ssize_t bytes_read;
- int r;
-
- /* Print out the destination name to the user. */
- if (cpio->verbose)
- fprintf(stderr,"%s", destpath);
-
- /*
- * Option_link only makes sense in pass mode and for
- * regular files. Also note: if a link operation fails
- * because of cross-device restrictions, we'll fall back
- * to copy mode for that entry.
- *
- * TODO: Test other cpio implementations to see if they
- * hard-link anything other than regular files here.
- */
- if (cpio->option_link
- && archive_entry_filetype(entry) == AE_IFREG)
- {
- struct archive_entry *t;
- /* Save the original entry in case we need it later. */
- t = archive_entry_clone(entry);
- if (t == NULL)
- lafe_errc(1, ENOMEM, "Can't create link");
- /* Note: link(2) doesn't create parent directories,
- * so we use archive_write_header() instead as a
- * convenience. */
- archive_entry_set_hardlink(t, srcpath);
- /* This is a straight link that carries no data. */
- archive_entry_set_size(t, 0);
- r = archive_write_header(cpio->archive, t);
- archive_entry_free(t);
- if (r != ARCHIVE_OK)
- lafe_warnc(archive_errno(cpio->archive),
- "%s", archive_error_string(cpio->archive));
- if (r == ARCHIVE_FATAL)
- exit(1);
-#ifdef EXDEV
- if (r != ARCHIVE_OK && archive_errno(cpio->archive) == EXDEV) {
- /* Cross-device link: Just fall through and use
- * the original entry to copy the file over. */
- lafe_warnc(0, "Copying file instead");
- } else
-#endif
- return (0);
- }
-
- /*
- * Make sure we can open the file (if necessary) before
- * trying to write the header.
- */
- if (archive_entry_filetype(entry) == AE_IFREG) {
- if (archive_entry_size(entry) > 0) {
- fd = open(srcpath, O_RDONLY | O_BINARY);
- if (fd < 0) {
- lafe_warnc(errno,
- "%s: could not open file", srcpath);
- goto cleanup;
- }
- }
- } else {
- archive_entry_set_size(entry, 0);
- }
-
- r = archive_write_header(cpio->archive, entry);
-
- if (r != ARCHIVE_OK)
- lafe_warnc(archive_errno(cpio->archive),
- "%s: %s",
- srcpath,
- archive_error_string(cpio->archive));
-
- if (r == ARCHIVE_FATAL)
- exit(1);
-
- if (r >= ARCHIVE_WARN && fd >= 0) {
- bytes_read = read(fd, cpio->buff, cpio->buff_size);
- while (bytes_read > 0) {
- r = archive_write_data(cpio->archive,
- cpio->buff, bytes_read);
- if (r < 0)
- lafe_errc(1, archive_errno(cpio->archive),
- "%s", archive_error_string(cpio->archive));
- if (r < bytes_read) {
- lafe_warnc(0,
- "Truncated write; file may have grown while being archived.");
- }
- bytes_read = read(fd, cpio->buff, cpio->buff_size);
- }
- }
-
- fd = restore_time(cpio, entry, srcpath, fd);
-
-cleanup:
- if (cpio->verbose)
- fprintf(stderr,"\n");
- if (fd >= 0)
- close(fd);
- return (0);
-}
-
-static int
-restore_time(struct cpio *cpio, struct archive_entry *entry,
- const char *name, int fd)
-{
-#ifndef HAVE_UTIMES
- static int warned = 0;
-
- (void)cpio; /* UNUSED */
- (void)entry; /* UNUSED */
- (void)name; /* UNUSED */
-
- if (!warned)
- lafe_warnc(0, "Can't restore access times on this platform");
- warned = 1;
- return (fd);
-#else
-#if defined(_WIN32) && !defined(__CYGWIN__)
- struct __timeval times[2];
-#else
- struct timeval times[2];
-#endif
-
- if (!cpio->option_atime_restore)
- return (fd);
-
- times[1].tv_sec = archive_entry_mtime(entry);
- times[1].tv_usec = archive_entry_mtime_nsec(entry) / 1000;
-
- times[0].tv_sec = archive_entry_atime(entry);
- times[0].tv_usec = archive_entry_atime_nsec(entry) / 1000;
-
-#if defined(HAVE_FUTIMES) && !defined(__CYGWIN__)
- if (fd >= 0 && futimes(fd, times) == 0)
- return (fd);
-#endif
- /*
- * Some platform cannot restore access times if the file descriptor
- * is still opened.
- */
- if (fd >= 0) {
- close(fd);
- fd = -1;
- }
-
-#ifdef HAVE_LUTIMES
- if (lutimes(name, times) != 0)
-#else
- if ((AE_IFLNK != archive_entry_filetype(entry))
- && utimes(name, times) != 0)
-#endif
- lafe_warnc(errno, "Can't update time for %s", name);
-#endif
- return (fd);
-}
-
-
-static void
-mode_in(struct cpio *cpio)
-{
- struct archive *a;
- struct archive_entry *entry;
- struct archive *ext;
- const char *destpath;
- int r;
-
- ext = archive_write_disk_new();
- if (ext == NULL)
- lafe_errc(1, 0, "Couldn't allocate restore object");
- r = archive_write_disk_set_options(ext, cpio->extract_flags);
- if (r != ARCHIVE_OK)
- lafe_errc(1, 0, "%s", archive_error_string(ext));
- a = archive_read_new();
- if (a == NULL)
- lafe_errc(1, 0, "Couldn't allocate archive object");
- archive_read_support_compression_all(a);
- archive_read_support_format_all(a);
-
- if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
- lafe_errc(1, archive_errno(a),
- "%s", archive_error_string(a));
- for (;;) {
- r = archive_read_next_header(a, &entry);
- if (r == ARCHIVE_EOF)
- break;
- if (r != ARCHIVE_OK) {
- lafe_errc(1, archive_errno(a),
- "%s", archive_error_string(a));
- }
- if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
- continue;
- if (cpio->option_rename) {
- destpath = cpio_rename(archive_entry_pathname(entry));
- archive_entry_set_pathname(entry, destpath);
- } else
- destpath = archive_entry_pathname(entry);
- if (destpath == NULL)
- continue;
- if (cpio->verbose)
- fprintf(stdout, "%s\n", destpath);
- if (cpio->uid_override >= 0)
- archive_entry_set_uid(entry, cpio->uid_override);
- if (cpio->gid_override >= 0)
- archive_entry_set_gid(entry, cpio->gid_override);
- r = archive_write_header(ext, entry);
- if (r != ARCHIVE_OK) {
- fprintf(stderr, "%s: %s\n",
- archive_entry_pathname(entry),
- archive_error_string(ext));
- } else if (archive_entry_size(entry) > 0) {
- r = extract_data(a, ext);
- if (r != ARCHIVE_OK)
- cpio->return_value = 1;
- }
- }
- r = archive_read_close(a);
- if (r != ARCHIVE_OK)
- lafe_errc(1, 0, "%s", archive_error_string(a));
- r = archive_write_close(ext);
- if (r != ARCHIVE_OK)
- lafe_errc(1, 0, "%s", archive_error_string(ext));
- if (!cpio->quiet) {
- int64_t blocks = (archive_position_uncompressed(a) + 511)
- / 512;
- fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
- blocks == 1 ? "block" : "blocks");
- }
- archive_read_finish(a);
- archive_write_finish(ext);
- exit(cpio->return_value);
-}
-
-/*
- * Exits if there's a fatal error. Returns ARCHIVE_OK
- * if everything is kosher.
- */
-static int
-extract_data(struct archive *ar, struct archive *aw)
-{
- int r;
- size_t size;
- const void *block;
- off_t offset;
-
- for (;;) {
- r = archive_read_data_block(ar, &block, &size, &offset);
- if (r == ARCHIVE_EOF)
- return (ARCHIVE_OK);
- if (r != ARCHIVE_OK) {
- lafe_warnc(archive_errno(ar),
- "%s", archive_error_string(ar));
- exit(1);
- }
- r = archive_write_data_block(aw, block, size, offset);
- if (r != ARCHIVE_OK) {
- lafe_warnc(archive_errno(aw),
- "%s", archive_error_string(aw));
- return (r);
- }
- }
-}
-
-static void
-mode_list(struct cpio *cpio)
-{
- struct archive *a;
- struct archive_entry *entry;
- int r;
-
- a = archive_read_new();
- if (a == NULL)
- lafe_errc(1, 0, "Couldn't allocate archive object");
- archive_read_support_compression_all(a);
- archive_read_support_format_all(a);
-
- if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
- lafe_errc(1, archive_errno(a),
- "%s", archive_error_string(a));
- for (;;) {
- r = archive_read_next_header(a, &entry);
- if (r == ARCHIVE_EOF)
- break;
- if (r != ARCHIVE_OK) {
- lafe_errc(1, archive_errno(a),
- "%s", archive_error_string(a));
- }
- if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
- continue;
- if (cpio->verbose)
- list_item_verbose(cpio, entry);
- else
- fprintf(stdout, "%s\n", archive_entry_pathname(entry));
- }
- r = archive_read_close(a);
- if (r != ARCHIVE_OK)
- lafe_errc(1, 0, "%s", archive_error_string(a));
- if (!cpio->quiet) {
- int64_t blocks = (archive_position_uncompressed(a) + 511)
- / 512;
- fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
- blocks == 1 ? "block" : "blocks");
- }
- archive_read_finish(a);
- exit(0);
-}
-
-/*
- * Display information about the current file.
- *
- * The format here roughly duplicates the output of 'ls -l'.
- * This is based on SUSv2, where 'tar tv' is documented as
- * listing additional information in an "unspecified format,"
- * and 'pax -l' is documented as using the same format as 'ls -l'.
- */
-static void
-list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
-{
- char size[32];
- char date[32];
- char uids[16], gids[16];
- const char *uname, *gname;
- FILE *out = stdout;
- const char *fmt;
- time_t mtime;
- static time_t now;
-
- if (!now)
- time(&now);
-
- if (cpio->option_numeric_uid_gid) {
- /* Format numeric uid/gid for display. */
- strcpy(uids, cpio_i64toa(archive_entry_uid(entry)));
- uname = uids;
- strcpy(gids, cpio_i64toa(archive_entry_gid(entry)));
- gname = gids;
- } else {
- /* Use uname if it's present, else lookup name from uid. */
- uname = archive_entry_uname(entry);
- if (uname == NULL)
- uname = lookup_uname(cpio, archive_entry_uid(entry));
- /* Use gname if it's present, else lookup name from gid. */
- gname = archive_entry_gname(entry);
- if (gname == NULL)
- gname = lookup_gname(cpio, archive_entry_gid(entry));
- }
-
- /* Print device number or file size. */
- if (archive_entry_filetype(entry) == AE_IFCHR
- || archive_entry_filetype(entry) == AE_IFBLK) {
- snprintf(size, sizeof(size), "%lu,%lu",
- (unsigned long)archive_entry_rdevmajor(entry),
- (unsigned long)archive_entry_rdevminor(entry));
- } else {
- strcpy(size, cpio_i64toa(archive_entry_size(entry)));
- }
-
- /* Format the time using 'ls -l' conventions. */
- mtime = archive_entry_mtime(entry);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Windows' strftime function does not support %e format. */
- if (mtime - now > 365*86400/2
- || mtime - now < -365*86400/2)
- fmt = cpio->day_first ? "%d %b %Y" : "%b %d %Y";
- else
- fmt = cpio->day_first ? "%d %b %H:%M" : "%b %d %H:%M";
-#else
- if (abs(mtime - now) > (365/2)*86400)
- fmt = cpio->day_first ? "%e %b %Y" : "%b %e %Y";
- else
- fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M";
-#endif
- strftime(date, sizeof(date), fmt, localtime(&mtime));
-
- fprintf(out, "%s%3d %-8s %-8s %8s %12s %s",
- archive_entry_strmode(entry),
- archive_entry_nlink(entry),
- uname, gname, size, date,
- archive_entry_pathname(entry));
-
- /* Extra information for links. */
- if (archive_entry_hardlink(entry)) /* Hard link */
- fprintf(out, " link to %s", archive_entry_hardlink(entry));
- else if (archive_entry_symlink(entry)) /* Symbolic link */
- fprintf(out, " -> %s", archive_entry_symlink(entry));
- fprintf(out, "\n");
-}
-
-static void
-mode_pass(struct cpio *cpio, const char *destdir)
-{
- struct lafe_line_reader *lr;
- const char *p;
- int r;
-
- /* Ensure target dir has a trailing '/' to simplify path surgery. */
- cpio->destdir = malloc(strlen(destdir) + 8);
- strcpy(cpio->destdir, destdir);
- if (destdir[strlen(destdir) - 1] != '/')
- strcat(cpio->destdir, "/");
-
- cpio->archive = archive_write_disk_new();
- if (cpio->archive == NULL)
- lafe_errc(1, 0, "Failed to allocate archive object");
- r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags);
- if (r != ARCHIVE_OK)
- lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
- cpio->linkresolver = archive_entry_linkresolver_new();
- archive_write_disk_set_standard_lookup(cpio->archive);
-
- cpio->archive_read_disk = archive_read_disk_new();
- if (cpio->archive_read_disk == NULL)
- lafe_errc(1, 0, "Failed to allocate archive object");
- if (cpio->option_follow_links)
- archive_read_disk_set_symlink_logical(cpio->archive_read_disk);
- else
- archive_read_disk_set_symlink_physical(cpio->archive_read_disk);
- archive_read_disk_set_standard_lookup(cpio->archive_read_disk);
-
- lr = lafe_line_reader("-", cpio->option_null);
- while ((p = lafe_line_reader_next(lr)) != NULL)
- file_to_archive(cpio, p);
- lafe_line_reader_free(lr);
-
- archive_entry_linkresolver_free(cpio->linkresolver);
- r = archive_write_close(cpio->archive);
- if (r != ARCHIVE_OK)
- lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
-
- if (!cpio->quiet) {
- int64_t blocks =
- (archive_position_uncompressed(cpio->archive) + 511)
- / 512;
- fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
- blocks == 1 ? "block" : "blocks");
- }
-
- archive_write_finish(cpio->archive);
-}
-
-/*
- * Prompt for a new name for this entry. Returns a pointer to the
- * new name or NULL if the entry should not be copied. This
- * implements the semantics defined in POSIX.1-1996, which specifies
- * that an input of '.' means the name should be unchanged. GNU cpio
- * treats '.' as a literal new name.
- */
-static const char *
-cpio_rename(const char *name)
-{
- static char buff[1024];
- FILE *t;
- char *p, *ret;
-
- t = fopen("/dev/tty", "r+");
- if (t == NULL)
- return (name);
- fprintf(t, "%s (Enter/./(new name))? ", name);
- fflush(t);
-
- p = fgets(buff, sizeof(buff), t);
- fclose(t);
- if (p == NULL)
- /* End-of-file is a blank line. */
- return (NULL);
-
- while (*p == ' ' || *p == '\t')
- ++p;
- if (*p == '\n' || *p == '\0')
- /* Empty line. */
- return (NULL);
- if (*p == '.' && p[1] == '\n')
- /* Single period preserves original name. */
- return (name);
- ret = p;
- /* Trim the final newline. */
- while (*p != '\0' && *p != '\n')
- ++p;
- /* Overwrite the final \n with a null character. */
- *p = '\0';
- return (ret);
-}
-
-static void
-free_cache(struct name_cache *cache)
-{
- size_t i;
-
- if (cache != NULL) {
- for (i = 0; i < cache->size; i++)
- free(cache->cache[i].name);
- free(cache);
- }
-}
-
-/*
- * Lookup uname/gname from uid/gid, return NULL if no match.
- */
-static const char *
-lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable,
- int (*lookup_fn)(struct cpio *, const char **, id_t), id_t id)
-{
- char asnum[16];
- struct name_cache *cache;
- const char *name;
- int slot;
-
-
- if (*name_cache_variable == NULL) {
- *name_cache_variable = malloc(sizeof(struct name_cache));
- if (*name_cache_variable == NULL)
- lafe_errc(1, ENOMEM, "No more memory");
- memset(*name_cache_variable, 0, sizeof(struct name_cache));
- (*name_cache_variable)->size = name_cache_size;
- }
-
- cache = *name_cache_variable;
- cache->probes++;
-
- slot = id % cache->size;
- if (cache->cache[slot].name != NULL) {
- if (cache->cache[slot].id == id) {
- cache->hits++;
- return (cache->cache[slot].name);
- }
- free(cache->cache[slot].name);
- cache->cache[slot].name = NULL;
- }
-
- if (lookup_fn(cpio, &name, id) == 0) {
- if (name == NULL || name[0] == '\0') {
- /* If lookup failed, format it as a number. */
- snprintf(asnum, sizeof(asnum), "%u", (unsigned)id);
- name = asnum;
- }
- cache->cache[slot].name = strdup(name);
- if (cache->cache[slot].name != NULL) {
- cache->cache[slot].id = id;
- return (cache->cache[slot].name);
- }
- /*
- * Conveniently, NULL marks an empty slot, so
- * if the strdup() fails, we've just failed to
- * cache it. No recovery necessary.
- */
- }
- return (NULL);
-}
-
-static const char *
-lookup_uname(struct cpio *cpio, uid_t uid)
-{
- return (lookup_name(cpio, &cpio->uname_cache,
- &lookup_uname_helper, (id_t)uid));
-}
-
-static int
-lookup_uname_helper(struct cpio *cpio, const char **name, id_t id)
-{
- struct passwd *pwent;
-
- (void)cpio; /* UNUSED */
-
- errno = 0;
- pwent = getpwuid((uid_t)id);
- if (pwent == NULL) {
- *name = NULL;
- if (errno != 0 && errno != ENOENT)
- lafe_warnc(errno, "getpwuid(%d) failed", id);
- return (errno);
- }
-
- *name = pwent->pw_name;
- return (0);
-}
-
-static const char *
-lookup_gname(struct cpio *cpio, gid_t gid)
-{
- return (lookup_name(cpio, &cpio->gname_cache,
- &lookup_gname_helper, (id_t)gid));
-}
-
-static int
-lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
-{
- struct group *grent;
-
- (void)cpio; /* UNUSED */
-
- errno = 0;
- grent = getgrgid((gid_t)id);
- if (grent == NULL) {
- *name = NULL;
- if (errno != 0)
- lafe_warnc(errno, "getgrgid(%d) failed", id);
- return (errno);
- }
-
- *name = grent->gr_name;
- return (0);
-}
-
-/*
- * It would be nice to just use printf() for formatting large numbers,
- * but the compatibility problems are a big headache. Hence the
- * following simple utility function.
- */
-const char *
-cpio_i64toa(int64_t n0)
-{
- // 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice.
- // We also need 1 byte for '-' and 1 for '\0'.
- static char buff[22];
- int64_t n = n0 < 0 ? -n0 : n0;
- char *p = buff + sizeof(buff);
-
- *--p = '\0';
- do {
- *--p = '0' + (int)(n % 10);
- n /= 10;
- } while (n > 0);
- if (n0 < 0)
- *--p = '-';
- return p;
-}
diff --git a/usr.bin/cpio/cpio.h b/usr.bin/cpio/cpio.h
deleted file mode 100644
index 2d5b548f4ae3..000000000000
--- a/usr.bin/cpio/cpio.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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.
- *
- * $FreeBSD$
- */
-
-#ifndef CPIO_H_INCLUDED
-#define CPIO_H_INCLUDED
-
-#include "cpio_platform.h"
-#include <stdio.h>
-
-#include "matching.h"
-
-/*
- * The internal state for the "cpio" program.
- *
- * Keeping all of the state in a structure like this simplifies memory
- * leak testing (at exit, anything left on the heap is suspect). A
- * pointer to this structure is passed to most cpio internal
- * functions.
- */
-struct cpio {
- /* Option parsing */
- const char *optarg;
-
- /* Options */
- const char *filename;
- char mode; /* -i -o -p */
- char compress; /* -j, -y, or -z */
- const char *format; /* -H format */
- int bytes_per_block; /* -b block_size */
- int verbose; /* -v */
- int quiet; /* --quiet */
- int extract_flags; /* Flags for extract operation */
- char symlink_mode; /* H or L, per BSD conventions */
- const char *compress_program;
- int option_append; /* -A, only relevant for -o */
- int option_atime_restore; /* -a */
- int option_follow_links; /* -L */
- int option_link; /* -l */
- int option_list; /* -t */
- char option_null; /* --null */
- int option_numeric_uid_gid; /* -n */
- int option_rename; /* -r */
- char *destdir;
- size_t pass_destpath_alloc;
- char *pass_destpath;
- int uid_override;
- char *uname_override;
- int gid_override;
- char *gname_override;
- int day_first; /* true if locale prefers day/mon */
-
- /* If >= 0, then close this when done. */
- int fd;
-
- /* Miscellaneous state information */
- struct archive *archive;
- struct archive *archive_read_disk;
- int argc;
- char **argv;
- int return_value; /* Value returned by main() */
- struct archive_entry_linkresolver *linkresolver;
-
- struct name_cache *uname_cache;
- struct name_cache *gname_cache;
-
- /* Work data. */
- struct lafe_matching *matching;
- char *buff;
- size_t buff_size;
-};
-
-const char *owner_parse(const char *, int *, int *);
-
-
-/* Fake short equivalents for long options that otherwise lack them. */
-enum {
- OPTION_INSECURE = 1,
- OPTION_LZMA,
- OPTION_NO_PRESERVE_OWNER,
- OPTION_PRESERVE_OWNER,
- OPTION_QUIET,
- OPTION_VERSION
-};
-
-int cpio_getopt(struct cpio *cpio);
-
-#endif
diff --git a/usr.bin/cpio/cpio_platform.h b/usr.bin/cpio/cpio_platform.h
deleted file mode 100644
index 3043828db2af..000000000000
--- a/usr.bin/cpio/cpio_platform.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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.
- *
- * $FreeBSD$
- */
-
-/*
- * This header is the first thing included in any of the cpio
- * source files. As far as possible, platform-specific issues should
- * be dealt with here and not within individual source files.
- */
-
-#ifndef CPIO_PLATFORM_H_INCLUDED
-#define CPIO_PLATFORM_H_INCLUDED
-
-#if defined(PLATFORM_CONFIG_H)
-/* Use hand-built config.h in environments that need it. */
-#include PLATFORM_CONFIG_H
-#else
-/* Read config.h or die trying. */
-#include "config.h"
-#endif
-
-/* Get a real definition for __FBSDID if we can */
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
-/* If not, define it so as to avoid dangling semicolons. */
-#ifndef __FBSDID
-#define __FBSDID(a) struct _undefined_hack
-#endif
-
-#ifdef HAVE_LIBARCHIVE
-/* If we're using the platform libarchive, include system headers. */
-#include <archive.h>
-#include <archive_entry.h>
-#else
-/* Otherwise, include user headers. */
-#include "archive.h"
-#include "archive_entry.h"
-#endif
-
-/* How to mark functions that don't return. */
-#if defined(__GNUC__) && (__GNUC__ > 2 || \
- (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
-#define __LA_DEAD __attribute__((__noreturn__))
-#else
-#define __LA_DEAD
-#endif
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include "cpio_windows.h"
-#endif
-
-#endif /* !CPIO_PLATFORM_H_INCLUDED */
diff --git a/usr.bin/cpio/test/Makefile b/usr.bin/cpio/test/Makefile
index 642ec5f0de9f..0802ebca82e1 100644
--- a/usr.bin/cpio/test/Makefile
+++ b/usr.bin/cpio/test/Makefile
@@ -1,14 +1,14 @@
# $FreeBSD$
-# Where to find the cpio sources (for the internal unit tests)
-CPIO_SRCDIR=${.CURDIR}/..
+LIBARCHIVEDIR= ${.CURDIR}/../../../contrib/libarchive
-.PATH: ${CPIO_SRCDIR}
+.PATH: ${LIBARCHIVEDIR}/cpio
CPIO_SRCS= cmdline.c
-.PATH: ${.CURDIR}/../../../lib/libarchive/libarchive_fe
+.PATH: ${LIBARCHIVEDIR}/libarchive_fe
CPIO_SRCS+= err.c pathmatch.c
+.PATH: ${LIBARCHIVEDIR}/cpio/test
TESTS= \
test_0.c \
test_basic.c \
@@ -49,14 +49,13 @@ NO_MAN=yes
PROG=bsdcpio_test
DPADD=${LIBARCHIVE} ${LIBBZ2} ${LIBZ}
-CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
-CFLAGS+= -I..
+CFLAGS+= -DPLATFORM_CONFIG_H=\"${.CURDIR}/../config_freebsd.h\"
+CFLAGS+= -I${.CURDIR}/..
LDADD= -larchive -lz -lbz2
#CFLAGS+= -static -g -O2 -Wall
CFLAGS+= -g -O2 -Wall
CFLAGS+= -I${.OBJDIR}
-CFLAGS+= -I${CPIO_SRCDIR}
-CFLAGS+= -I${.CURDIR}/../../../lib/libarchive/libarchive_fe
+CFLAGS+= -I${LIBARCHIVEDIR}/cpio -I${LIBARCHIVEDIR}/libarchive_fe
# Uncomment to link against dmalloc
#LDADD+= -L/usr/local/lib -ldmalloc
@@ -64,15 +63,17 @@ CFLAGS+= -I${.CURDIR}/../../../lib/libarchive/libarchive_fe
WARNS=6
check test: bsdcpio_test
- ${.OBJDIR}/bsdcpio_test -p ${.OBJDIR}/../bsdcpio -r ${.CURDIR}
+ ${.OBJDIR}/bsdcpio_test -p ${.OBJDIR}/../bsdcpio \
+ -r ${LIBARCHIVEDIR}/cpio/test
${.OBJDIR}/list.h list.h: ${TESTS} Makefile
- (cd ${.CURDIR}; cat ${TESTS}) | grep DEFINE_TEST > list.h
+ (cd ${LIBARCHIVEDIR}/cpio/test; cat ${TESTS}) | \
+ grep DEFINE_TEST > ${.OBJDIR}/list.h
clean:
rm -f ${CLEANFILES}
rm -f *~
-chmod -R +w /tmp/bsdcpio_test.*
- rm -rf /tmp/bsdcpio_test.*
+ rm -rf /tmp/bsdcpio_test
.include <bsd.prog.mk>
diff --git a/usr.bin/cpio/test/main.c b/usr.bin/cpio/test/main.c
deleted file mode 100644
index bca4c963934f..000000000000
--- a/usr.bin/cpio/test/main.c
+++ /dev/null
@@ -1,2140 +0,0 @@
-/*
- * Copyright (c) 2003-2009 Tim Kientzle
- * 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"
-#include <errno.h>
-#include <locale.h>
-#include <stdarg.h>
-#include <time.h>
-
-/*
- * 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.
- */
-__FBSDID("$FreeBSD$");
-#define KNOWNREF "test_option_f.cpio.uu"
-#define ENVBASE "BSDCPIO" /* Prefix for environment variables. */
-#define PROGRAM "bsdcpio" /* 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) ? "" : "")
-
-/*
- *
- * 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.
- */
-#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
-#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
-
-#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 and log data for successful tests. */
-static int keep_temp_files = 0;
-/* 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 reported skips. */
-static int skips = 0;
-/* Cumulative count of assertions checked. */
-static int assertions = 0;
-
-/* Directory where uuencoded reference files can be found. */
-static const char *refdir;
-
-/*
- * Report log information selectively to console and/or disk log.
- */
-static int log_console = 0;
-static FILE *logfile;
-static void
-vlogprintf(const char *fmt, va_list ap)
-{
-#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
-}
-
-static void
-logprintf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vlogprintf(fmt, ap);
- va_end(ap);
-}
-
-/* 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 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); */
-}
-
-/*
- * For each test source file, we remember how many times each
- * assertion was reported. Cleared before each new test,
- * used by test_summarize().
- */
-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;
-
- /* 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);
-#if _MSC_VER
- logprintf("%s(%d): ", filename, line);
-#else
- logprintf("%s:%d: ", filename, line);
-#endif
- vlogprintf(fmt, ap);
- va_end(ap);
- 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;
-}
-
-/* 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
-failure_finish(void *extra)
-{
- (void)extra; /* UNUSED (maybe) */
-#ifdef EXTRA_DUMP
- if (extra != NULL)
- logprintf(" detail: %s\n", EXTRA_DUMP(extra));
-#endif
-
- if (dump_on_failure) {
- fprintf(stderr,
- " *** forcing core dump so failure can be debugged ***\n");
- *(char *)(NULL) = 0;
- exit(1);
- }
-}
-
-/* Inform user that we're skipping some checks. */
-void
-test_skipping(const char *fmt, ...)
-{
- char buff[1024];
- va_list ap;
-
- va_start(ap, fmt);
- vsprintf(buff, fmt, ap);
- va_end(ap);
- /* failure_start() isn't quite right, but is awfully convenient. */
- failure_start(test_filename, test_line, "SKIPPING: %s", buff);
- --failures; /* Undo failures++ in failure_start() */
- /* Don't failure_finish() here. */
- /* Mark as skip, so doesn't count as failed test. */
- failed_lines[test_line].skip = 1;
- ++skips;
-}
-
-/*
- *
- * ASSERTIONS
- *
- */
-
-/* Generic assert() just displays the failed condition. */
-int
-assertion_assert(const char *file, int line, int value,
- const char *condition, void *extra)
-{
- assertion_count(file, line);
- if (!value) {
- failure_start(file, line, "Assertion failed: %s", condition);
- failure_finish(extra);
- }
- return (value);
-}
-
-/* chdir() and report any errors */
-int
-assertion_chdir(const char *file, int line, const char *pathname)
-{
- assertion_count(file, line);
- if (chdir(pathname) == 0)
- return (1);
- failure_start(file, line, "chdir(\"%s\")", pathname);
- failure_finish(NULL);
- return (0);
-
-}
-
-/* Verify two integers are equal. */
-int
-assertion_equal_int(const char *file, int line,
- long long v1, const char *e1, long long v2, const char *e2, void *extra)
-{
- assertion_count(file, line);
- if (v1 == v2)
- return (1);
- failure_start(file, line, "%s != %s", e1, e2);
- logprintf(" %s=%lld (0x%llx, 0%llo)\n", e1, v1, v1, v1);
- logprintf(" %s=%lld (0x%llx, 0%llo)\n", e2, v2, v2, v2);
- failure_finish(extra);
- return (0);
-}
-
-static void strdump(const char *e, const char *p)
-{
- const char *q = p;
-
- logprintf(" %s = ", e);
- if (p == NULL) {
- logprintf("NULL");
- return;
- }
- logprintf("\"");
- while (*p != '\0') {
- unsigned int c = 0xff & *p++;
- switch (c) {
- case '\a': printf("\a"); break;
- case '\b': printf("\b"); break;
- case '\n': printf("\n"); break;
- case '\r': printf("\r"); break;
- default:
- if (c >= 32 && c < 127)
- logprintf("%c", c);
- else
- logprintf("\\x%02X", c);
- }
- }
- logprintf("\"");
- logprintf(" (length %d)\n", q == NULL ? -1 : (int)strlen(q));
-}
-
-/* Verify two strings are equal, dump them if not. */
-int
-assertion_equal_string(const char *file, int line,
- const char *v1, const char *e1,
- const char *v2, const char *e2,
- void *extra)
-{
- assertion_count(file, line);
- if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0))
- return (1);
- failure_start(file, line, "%s != %s", e1, e2);
- strdump(e1, v1);
- strdump(e2, v2);
- failure_finish(extra);
- return (0);
-}
-
-static void
-wcsdump(const char *e, const wchar_t *w)
-{
- logprintf(" %s = ", e);
- if (w == NULL) {
- logprintf("(null)");
- return;
- }
- logprintf("\"");
- while (*w != L'\0') {
- unsigned int c = *w++;
- if (c >= 32 && c < 127)
- logprintf("%c", c);
- else if (c < 256)
- logprintf("\\x%02X", c);
- else if (c < 0x10000)
- logprintf("\\u%04X", c);
- else
- logprintf("\\U%08X", c);
- }
- logprintf("\"\n");
-}
-
-#ifndef HAVE_WCSCMP
-static int
-wcscmp(const wchar_t *s1, const wchar_t *s2)
-{
-
- while (*s1 == *s2++) {
- if (*s1++ == L'\0')
- return 0;
- }
- if (*s1 > *--s2)
- return 1;
- else
- return -1;
-}
-#endif
-
-/* Verify that two wide strings are equal, dump them if not. */
-int
-assertion_equal_wstring(const char *file, int line,
- const wchar_t *v1, const char *e1,
- const wchar_t *v2, const char *e2,
- void *extra)
-{
- assertion_count(file, line);
- if (v1 == v2 || wcscmp(v1, v2) == 0)
- return (1);
- failure_start(file, line, "%s != %s", e1, e2);
- wcsdump(e1, v1);
- wcsdump(e2, v2);
- failure_finish(extra);
- return (0);
-}
-
-/*
- * Pretty standard hexdump routine. As a bonus, if ref != NULL, then
- * any bytes in p that differ from ref will be highlighted with '_'
- * before and after the hex value.
- */
-static void
-hexdump(const char *p, const char *ref, size_t l, size_t offset)
-{
- size_t i, j;
- char sep;
-
- if (p == NULL) {
- logprintf("(null)\n");
- return;
- }
- for(i=0; i < l; i+=16) {
- logprintf("%04x", (unsigned)(i + offset));
- sep = ' ';
- for (j = 0; j < 16 && i + j < l; j++) {
- if (ref != NULL && p[i + j] != ref[i + j])
- sep = '_';
- logprintf("%c%02x", sep, 0xff & (int)p[i+j]);
- if (ref != NULL && p[i + j] == ref[i + j])
- sep = ' ';
- }
- for (; j < 16; j++) {
- logprintf("%c ", sep);
- sep = ' ';
- }
- logprintf("%c", sep);
- for (j=0; j < 16 && i + j < l; j++) {
- int c = p[i + j];
- if (c >= ' ' && c <= 126)
- logprintf("%c", c);
- else
- logprintf(".");
- }
- logprintf("\n");
- }
-}
-
-/* Verify that two blocks of memory are the same, display the first
- * block of differences if they're not. */
-int
-assertion_equal_mem(const char *file, int line,
- const void *_v1, const char *e1,
- const void *_v2, const char *e2,
- size_t l, const char *ld, void *extra)
-{
- const char *v1 = (const char *)_v1;
- const char *v2 = (const char *)_v2;
- size_t offset;
-
- assertion_count(file, line);
- if (v1 == v2 || (v1 != NULL && v2 != NULL && memcmp(v1, v2, l) == 0))
- return (1);
-
- failure_start(file, line, "%s != %s", e1, e2);
- logprintf(" size %s = %d\n", ld, (int)l);
- /* Dump 48 bytes (3 lines) so that the first difference is
- * in the second line. */
- offset = 0;
- while (l > 64 && memcmp(v1, v2, 32) == 0) {
- /* Two lines agree, so step forward one line. */
- v1 += 16;
- v2 += 16;
- l -= 16;
- offset += 16;
- }
- logprintf(" Dump of %s\n", e1);
- hexdump(v1, v2, l < 64 ? l : 64, offset);
- logprintf(" Dump of %s\n", e2);
- hexdump(v2, v1, l < 64 ? l : 64, offset);
- logprintf("\n");
- failure_finish(extra);
- return (0);
-}
-
-/* Verify that the named file exists and is empty. */
-int
-assertion_empty_file(const char *f1fmt, ...)
-{
- char buff[1024];
- char f1[1024];
- struct stat st;
- va_list ap;
- ssize_t s;
- FILE *f;
-
- assertion_count(test_filename, test_line);
- va_start(ap, f1fmt);
- vsprintf(f1, f1fmt, ap);
- va_end(ap);
-
- if (stat(f1, &st) != 0) {
- failure_start(test_filename, test_line, "Stat failed: %s", f1);
- failure_finish(NULL);
- return (0);
- }
- if (st.st_size == 0)
- return (1);
-
- failure_start(test_filename, test_line, "File should be empty: %s", f1);
- logprintf(" File size: %d\n", (int)st.st_size);
- logprintf(" Contents:\n");
- f = fopen(f1, "rb");
- if (f == NULL) {
- logprintf(" Unable to open %s\n", f1);
- } else {
- s = ((off_t)sizeof(buff) < st.st_size) ?
- (ssize_t)sizeof(buff) : (ssize_t)st.st_size;
- s = fread(buff, 1, s, f);
- hexdump(buff, NULL, s, 0);
- fclose(f);
- }
- failure_finish(NULL);
- return (0);
-}
-
-/* Verify that the named file exists and is not empty. */
-int
-assertion_non_empty_file(const char *f1fmt, ...)
-{
- char f1[1024];
- struct stat st;
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, f1fmt);
- vsprintf(f1, f1fmt, ap);
- va_end(ap);
-
- if (stat(f1, &st) != 0) {
- failure_start(test_filename, test_line, "Stat failed: %s", f1);
- failure_finish(NULL);
- return (0);
- }
- if (st.st_size == 0) {
- failure_start(test_filename, test_line, "File empty: %s", f1);
- failure_finish(NULL);
- return (0);
- }
- return (1);
-}
-
-/* Verify that two files have the same contents. */
-/* TODO: hexdump the first bytes that actually differ. */
-int
-assertion_equal_file(const char *fn1, const char *f2pattern, ...)
-{
- char fn2[1024];
- va_list ap;
- char buff1[1024];
- char buff2[1024];
- FILE *f1, *f2;
- int n1, n2;
-
- assertion_count(test_filename, test_line);
- va_start(ap, f2pattern);
- vsprintf(fn2, f2pattern, ap);
- va_end(ap);
-
- f1 = fopen(fn1, "rb");
- f2 = fopen(fn2, "rb");
- for (;;) {
- n1 = fread(buff1, 1, sizeof(buff1), f1);
- n2 = fread(buff2, 1, sizeof(buff2), f2);
- if (n1 != n2)
- break;
- if (n1 == 0 && n2 == 0) {
- fclose(f1);
- fclose(f2);
- return (1);
- }
- if (memcmp(buff1, buff2, n1) != 0)
- break;
- }
- fclose(f1);
- fclose(f2);
- failure_start(test_filename, test_line, "Files not identical");
- logprintf(" file1=\"%s\"\n", fn1);
- logprintf(" file2=\"%s\"\n", fn2);
- failure_finish(test_extra);
- return (0);
-}
-
-/* Verify that the named file does exist. */
-int
-assertion_file_exists(const char *fpattern, ...)
-{
- char f[1024];
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
- va_end(ap);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (!_access(f, 0))
- return (1);
-#else
- if (!access(f, F_OK))
- return (1);
-#endif
- failure_start(test_filename, test_line, "File should exist: %s", f);
- failure_finish(test_extra);
- return (0);
-}
-
-/* Verify that the named file doesn't exist. */
-int
-assertion_file_not_exists(const char *fpattern, ...)
-{
- char f[1024];
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
- va_end(ap);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (_access(f, 0))
- return (1);
-#else
- if (access(f, F_OK))
- return (1);
-#endif
- failure_start(test_filename, test_line, "File should not exist: %s", f);
- failure_finish(test_extra);
- return (0);
-}
-
-/* Compare the contents of a file to a block of memory. */
-int
-assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
-{
- char fn[1024];
- va_list ap;
- char *contents;
- FILE *f;
- int n;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(fn, fpattern, ap);
- va_end(ap);
-
- f = fopen(fn, "rb");
- if (f == NULL) {
- failure_start(test_filename, test_line,
- "File should exist: %s", fn);
- failure_finish(test_extra);
- return (0);
- }
- contents = malloc(s * 2);
- n = fread(contents, 1, s * 2, f);
- fclose(f);
- if (n == s && memcmp(buff, contents, s) == 0) {
- free(contents);
- return (1);
- }
- failure_start(test_filename, test_line, "File contents don't match");
- logprintf(" file=\"%s\"\n", fn);
- if (n > 0)
- hexdump(contents, buff, n > 512 ? 512 : n, 0);
- else {
- logprintf(" File empty, contents should be:\n");
- hexdump(buff, NULL, s > 512 ? 512 : n, 0);
- }
- failure_finish(test_extra);
- free(contents);
- return (0);
-}
-
-/* Check the contents of a text file, being tolerant of line endings. */
-int
-assertion_text_file_contents(const char *buff, const char *fn)
-{
- char *contents;
- const char *btxt, *ftxt;
- FILE *f;
- int n, s;
-
- assertion_count(test_filename, test_line);
- f = fopen(fn, "r");
- if (f == NULL) {
- failure_start(test_filename, test_line,
- "File doesn't exist: %s", fn);
- failure_finish(test_extra);
- return (0);
- }
- s = strlen(buff);
- contents = malloc(s * 2 + 128);
- n = fread(contents, 1, s * 2 + 128 - 1, f);
- if (n >= 0)
- contents[n] = '\0';
- fclose(f);
- /* Compare texts. */
- btxt = buff;
- ftxt = (const char *)contents;
- while (*btxt != '\0' && *ftxt != '\0') {
- if (*btxt == *ftxt) {
- ++btxt;
- ++ftxt;
- continue;
- }
- if (btxt[0] == '\n' && ftxt[0] == '\r' && ftxt[1] == '\n') {
- /* Pass over different new line characters. */
- ++btxt;
- ftxt += 2;
- continue;
- }
- break;
- }
- if (*btxt == '\0' && *ftxt == '\0') {
- free(contents);
- return (1);
- }
- failure_start(test_filename, test_line, "Contents don't match");
- logprintf(" file=\"%s\"\n", fn);
- if (n > 0)
- hexdump(contents, buff, n, 0);
- else {
- logprintf(" File empty, contents should be:\n");
- hexdump(buff, NULL, s, 0);
- }
- failure_finish(test_extra);
- free(contents);
- return (0);
-}
-
-/* Test that two paths point to the same file. */
-/* As a side-effect, asserts that both files exist. */
-static int
-is_hardlink(const char *file, int line,
- const char *path1, const char *path2)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- BY_HANDLE_FILE_INFORMATION bhfi1, bhfi2;
- int r;
-
- assertion_count(file, line);
- r = my_GetFileInformationByName(path1, &bhfi1);
- if (r == 0) {
- failure_start(file, line, "File %s can't be inspected?", path1);
- failure_finish(NULL);
- return (0);
- }
- r = my_GetFileInformationByName(path2, &bhfi2);
- if (r == 0) {
- failure_start(file, line, "File %s can't be inspected?", path2);
- failure_finish(NULL);
- return (0);
- }
- return (bhfi1.dwVolumeSerialNumber == bhfi2.dwVolumeSerialNumber
- && bhfi1.nFileIndexHigh == bhfi2.nFileIndexHigh
- && bhfi1.nFileIndexLow == bhfi2.nFileIndexLow);
-#else
- struct stat st1, st2;
- int r;
-
- assertion_count(file, line);
- r = lstat(path1, &st1);
- if (r != 0) {
- failure_start(file, line, "File should exist: %s", path1);
- failure_finish(NULL);
- return (0);
- }
- r = lstat(path2, &st2);
- if (r != 0) {
- failure_start(file, line, "File should exist: %s", path2);
- failure_finish(NULL);
- return (0);
- }
- return (st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev);
-#endif
-}
-
-int
-assertion_is_hardlink(const char *file, int line,
- const char *path1, const char *path2)
-{
- if (is_hardlink(file, line, path1, path2))
- return (1);
- failure_start(file, line,
- "Files %s and %s are not hardlinked", path1, path2);
- failure_finish(NULL);
- return (0);
-}
-
-int
-assertion_is_not_hardlink(const char *file, int line,
- const char *path1, const char *path2)
-{
- if (!is_hardlink(file, line, path1, path2))
- return (1);
- failure_start(file, line,
- "Files %s and %s should not be hardlinked", path1, path2);
- failure_finish(NULL);
- return (0);
-}
-
-/* Verify a/b/mtime of 'pathname'. */
-/* If 'recent', verify that it's within last 10 seconds. */
-static int
-assertion_file_time(const char *file, int line,
- const char *pathname, long t, long nsec, char type, int recent)
-{
- long long filet, filet_nsec;
- int r;
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define EPOC_TIME (116444736000000000ULL)
- FILETIME ftime, fbirthtime, fatime, fmtime;
- ULARGE_INTEGER wintm;
- HANDLE h;
- ftime.dwLowDateTime = 0;
- ftime.dwHighDateTime = 0;
-
- assertion_count(file, line);
- h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE) {
- failure_start(file, line, "Can't access %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- r = GetFileTime(h, &fbirthtime, &fatime, &fmtime);
- switch (type) {
- case 'a': ftime = fatime; break;
- case 'b': ftime = fbirthtime; break;
- case 'm': ftime = fmtime; break;
- }
- CloseHandle(h);
- if (r == 0) {
- failure_start(file, line, "Can't GetFileTime %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- wintm.LowPart = ftime.dwLowDateTime;
- wintm.HighPart = ftime.dwHighDateTime;
- filet = (wintm.QuadPart - EPOC_TIME) / 10000000;
- filet_nsec = ((wintm.QuadPart - EPOC_TIME) % 10000000) * 100;
- nsec = (nsec / 100) * 100; /* Round the request */
-#else
- struct stat st;
-
- assertion_count(file, line);
- r = lstat(pathname, &st);
- if (r != 0) {
- failure_start(file, line, "Can't stat %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- switch (type) {
- case 'a': filet = st.st_atime; break;
- case 'm': filet = st.st_mtime; break;
- case 'b': filet = 0; break;
- default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type);
- exit(1);
- }
-#if defined(__FreeBSD__)
- switch (type) {
- case 'a': filet_nsec = st.st_atimespec.tv_nsec; break;
- case 'b': filet = st.st_birthtime;
- filet_nsec = st.st_birthtimespec.tv_nsec; break;
- case 'm': filet_nsec = st.st_mtimespec.tv_nsec; break;
- default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type);
- exit(1);
- }
- /* FreeBSD generally only stores to microsecond res, so round. */
- filet_nsec = (filet_nsec / 1000) * 1000;
- nsec = (nsec / 1000) * 1000;
-#else
- filet_nsec = nsec = 0; /* Generic POSIX only has whole seconds. */
- if (type == 'b') return (1); /* Generic POSIX doesn't have birthtime */
-#if defined(__HAIKU__)
- if (type == 'a') return (1); /* Haiku doesn't have atime. */
-#endif
-#endif
-#endif
- if (recent) {
- /* Check that requested time is up-to-date. */
- time_t now = time(NULL);
- if (filet < now - 10 || filet > now + 1) {
- failure_start(file, line,
- "File %s has %ctime %ld, %ld seconds ago\n",
- pathname, type, filet, now - filet);
- failure_finish(NULL);
- return (0);
- }
- } else if (filet != t || filet_nsec != nsec) {
- failure_start(file, line,
- "File %s has %ctime %ld.%09ld, expected %ld.%09ld",
- pathname, type, filet, filet_nsec, t, nsec);
- failure_finish(NULL);
- return (0);
- }
- return (1);
-}
-
-/* Verify atime of 'pathname'. */
-int
-assertion_file_atime(const char *file, int line,
- const char *pathname, long t, long nsec)
-{
- return assertion_file_time(file, line, pathname, t, nsec, 'a', 0);
-}
-
-/* Verify atime of 'pathname' is up-to-date. */
-int
-assertion_file_atime_recent(const char *file, int line, const char *pathname)
-{
- return assertion_file_time(file, line, pathname, 0, 0, 'a', 1);
-}
-
-/* Verify birthtime of 'pathname'. */
-int
-assertion_file_birthtime(const char *file, int line,
- const char *pathname, long t, long nsec)
-{
- return assertion_file_time(file, line, pathname, t, nsec, 'b', 0);
-}
-
-/* Verify birthtime of 'pathname' is up-to-date. */
-int
-assertion_file_birthtime_recent(const char *file, int line,
- const char *pathname)
-{
- return assertion_file_time(file, line, pathname, 0, 0, 'b', 1);
-}
-
-/* Verify mtime of 'pathname'. */
-int
-assertion_file_mtime(const char *file, int line,
- const char *pathname, long t, long nsec)
-{
- return assertion_file_time(file, line, pathname, t, nsec, 'm', 0);
-}
-
-/* Verify mtime of 'pathname' is up-to-date. */
-int
-assertion_file_mtime_recent(const char *file, int line, const char *pathname)
-{
- return assertion_file_time(file, line, pathname, 0, 0, 'm', 1);
-}
-
-/* Verify number of links to 'pathname'. */
-int
-assertion_file_nlinks(const char *file, int line,
- const char *pathname, int nlinks)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- BY_HANDLE_FILE_INFORMATION bhfi;
- int r;
-
- assertion_count(file, line);
- r = my_GetFileInformationByName(pathname, &bhfi);
- if (r != 0 && bhfi.nNumberOfLinks == (DWORD)nlinks)
- return (1);
- failure_start(file, line, "File %s has %d links, expected %d",
- pathname, bhfi.nNumberOfLinks, nlinks);
- failure_finish(NULL);
- return (0);
-#else
- struct stat st;
- int r;
-
- assertion_count(file, line);
- r = lstat(pathname, &st);
- if (r == 0 && st.st_nlink == nlinks)
- return (1);
- failure_start(file, line, "File %s has %d links, expected %d",
- pathname, st.st_nlink, nlinks);
- failure_finish(NULL);
- return (0);
-#endif
-}
-
-/* Verify size of 'pathname'. */
-int
-assertion_file_size(const char *file, int line, const char *pathname, long size)
-{
- int64_t filesize;
- int r;
-
- assertion_count(file, line);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- {
- BY_HANDLE_FILE_INFORMATION bhfi;
- r = !my_GetFileInformationByName(pathname, &bhfi);
- filesize = ((int64_t)bhfi.nFileSizeHigh << 32) + bhfi.nFileSizeLow;
- }
-#else
- {
- struct stat st;
- r = lstat(pathname, &st);
- filesize = st.st_size;
- }
-#endif
- if (r == 0 && filesize == size)
- return (1);
- failure_start(file, line, "File %s has size %ld, expected %ld",
- pathname, (long)filesize, (long)size);
- failure_finish(NULL);
- return (0);
-}
-
-/* Assert that 'pathname' is a dir. If mode >= 0, verify that too. */
-int
-assertion_is_dir(const char *file, int line, const char *pathname, int mode)
-{
- struct stat st;
- int r;
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- (void)mode; /* UNUSED */
-#endif
- assertion_count(file, line);
- r = lstat(pathname, &st);
- if (r != 0) {
- failure_start(file, line, "Dir should exist: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
- if (!S_ISDIR(st.st_mode)) {
- failure_start(file, line, "%s is not a dir", pathname);
- failure_finish(NULL);
- return (0);
- }
-#if !defined(_WIN32) || defined(__CYGWIN__)
- /* Windows doesn't handle permissions the same way as POSIX,
- * so just ignore the mode tests. */
- /* TODO: Can we do better here? */
- if (mode >= 0 && mode != (st.st_mode & 07777)) {
- failure_start(file, line, "Dir %s has wrong mode", pathname);
- logprintf(" Expected: 0%3o\n", mode);
- logprintf(" Found: 0%3o\n", st.st_mode & 07777);
- failure_finish(NULL);
- return (0);
- }
-#endif
- return (1);
-}
-
-/* Verify that 'pathname' is a regular file. If 'mode' is >= 0,
- * verify that too. */
-int
-assertion_is_reg(const char *file, int line, const char *pathname, int mode)
-{
- struct stat st;
- int r;
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- (void)mode; /* UNUSED */
-#endif
- assertion_count(file, line);
- r = lstat(pathname, &st);
- if (r != 0 || !S_ISREG(st.st_mode)) {
- failure_start(file, line, "File should exist: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
-#if !defined(_WIN32) || defined(__CYGWIN__)
- /* Windows doesn't handle permissions the same way as POSIX,
- * so just ignore the mode tests. */
- /* TODO: Can we do better here? */
- if (mode >= 0 && mode != (st.st_mode & 07777)) {
- failure_start(file, line, "File %s has wrong mode", pathname);
- logprintf(" Expected: 0%3o\n", mode);
- logprintf(" Found: 0%3o\n", st.st_mode & 07777);
- failure_finish(NULL);
- return (0);
- }
-#endif
- return (1);
-}
-
-/* Check whether 'pathname' is a symbolic link. If 'contents' is
- * non-NULL, verify that the symlink has those contents. */
-static int
-is_symlink(const char *file, int line,
- const char *pathname, const char *contents)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- (void)pathname; /* UNUSED */
- (void)contents; /* UNUSED */
- assertion_count(file, line);
- /* Windows sort-of has real symlinks, but they're only usable
- * by privileged users and are crippled even then, so there's
- * really not much point in bothering with this. */
- return (0);
-#else
- char buff[300];
- struct stat st;
- ssize_t linklen;
- int r;
-
- assertion_count(file, line);
- r = lstat(pathname, &st);
- if (r != 0) {
- failure_start(file, line,
- "Symlink should exist: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
- if (!S_ISLNK(st.st_mode))
- return (0);
- if (contents == NULL)
- return (1);
- linklen = readlink(pathname, buff, sizeof(buff));
- if (linklen < 0) {
- failure_start(file, line, "Can't read symlink %s", pathname);
- failure_finish(NULL);
- return (0);
- }
- buff[linklen] = '\0';
- if (strcmp(buff, contents) != 0)
- return (0);
- return (1);
-#endif
-}
-
-/* Assert that path is a symlink that (optionally) contains contents. */
-int
-assertion_is_symlink(const char *file, int line,
- const char *path, const char *contents)
-{
- if (is_symlink(file, line, path, contents))
- return (1);
- if (contents)
- failure_start(file, line, "File %s is not a symlink to %s",
- path, contents);
- else
- failure_start(file, line, "File %s is not a symlink", path);
- failure_finish(NULL);
- return (0);
-}
-
-
-/* Create a directory and report any errors. */
-int
-assertion_make_dir(const char *file, int line, const char *dirname, int mode)
-{
- assertion_count(file, line);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- (void)mode; /* UNUSED */
- if (0 == _mkdir(dirname))
- return (1);
-#else
- if (0 == mkdir(dirname, mode))
- return (1);
-#endif
- failure_start(file, line, "Could not create directory %s", dirname);
- failure_finish(NULL);
- return(0);
-}
-
-/* Create a file with the specified contents and report any failures. */
-int
-assertion_make_file(const char *file, int line,
- const char *path, int mode, const char *contents)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* TODO: Rework this to set file mode as well. */
- FILE *f;
- (void)mode; /* UNUSED */
- assertion_count(file, line);
- f = fopen(path, "wb");
- if (f == NULL) {
- failure_start(file, line, "Could not create file %s", path);
- failure_finish(NULL);
- return (0);
- }
- if (contents != NULL) {
- if (strlen(contents)
- != fwrite(contents, 1, strlen(contents), f)) {
- fclose(f);
- failure_start(file, line,
- "Could not write file %s", path);
- failure_finish(NULL);
- return (0);
- }
- }
- fclose(f);
- return (1);
-#else
- int fd;
- assertion_count(file, line);
- fd = open(path, O_CREAT | O_WRONLY, mode >= 0 ? mode : 0644);
- if (fd < 0) {
- failure_start(file, line, "Could not create %s", path);
- failure_finish(NULL);
- return (0);
- }
- if (contents != NULL) {
- if ((ssize_t)strlen(contents)
- != write(fd, contents, strlen(contents))) {
- close(fd);
- failure_start(file, line, "Could not write to %s", path);
- failure_finish(NULL);
- return (0);
- }
- }
- close(fd);
- return (1);
-#endif
-}
-
-/* Create a hardlink and report any failures. */
-int
-assertion_make_hardlink(const char *file, int line,
- const char *newpath, const char *linkto)
-{
- int succeeded;
-
- assertion_count(file, line);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- succeeded = my_CreateHardLinkA(newpath, linkto);
-#elif HAVE_LINK
- succeeded = !link(linkto, newpath);
-#else
- succeeded = 0;
-#endif
- if (succeeded)
- return (1);
- failure_start(file, line, "Could not create hardlink");
- logprintf(" New link: %s\n", newpath);
- logprintf(" Old name: %s\n", linkto);
- failure_finish(NULL);
- return(0);
-}
-
-/* Create a symlink and report any failures. */
-int
-assertion_make_symlink(const char *file, int line,
- const char *newpath, const char *linkto)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- int targetIsDir = 0; /* TODO: Fix this */
- assertion_count(file, line);
- if (my_CreateSymbolicLinkA(newpath, linkto, targetIsDir))
- return (1);
-#elif HAVE_SYMLINK
- assertion_count(file, line);
- if (0 == symlink(linkto, newpath))
- return (1);
-#endif
- failure_start(file, line, "Could not create symlink");
- logprintf(" New link: %s\n", newpath);
- logprintf(" Old name: %s\n", linkto);
- failure_finish(NULL);
- return(0);
-}
-
-/* Set umask, report failures. */
-int
-assertion_umask(const char *file, int line, int mask)
-{
- assertion_count(file, line);
- (void)file; /* UNUSED */
- (void)line; /* UNUSED */
- umask(mask);
- return (1);
-}
-
-/*
- *
- * UTILITIES for use by tests.
- *
- */
-
-/*
- * Check whether platform supports symlinks. This is intended
- * for tests to use in deciding whether to bother testing symlink
- * support; if the platform doesn't support symlinks, there's no point
- * in checking whether the program being tested can create them.
- *
- * Note that the first time this test is called, we actually go out to
- * disk to create and verify a symlink. This is necessary because
- * symlink support is actually a property of a particular filesystem
- * and can thus vary between directories on a single system. After
- * the first call, this returns the cached result from memory, so it's
- * safe to call it as often as you wish.
- */
-int
-canSymlink(void)
-{
- /* Remember the test result */
- static int value = 0, tested = 0;
- if (tested)
- return (value);
-
- ++tested;
- assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
- /* Note: Cygwin has its own symlink() emulation that does not
- * use the Win32 CreateSymbolicLink() function. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- value = my_CreateSymbolicLinkA("canSymlink.1", "canSymlink.0", 0)
- && is_symlink(__FILE__, __LINE__, "canSymlink.1", "canSymlink.0");
-#elif HAVE_SYMLINK
- value = (0 == symlink("canSymlink.0", "canSymlink.1"))
- && is_symlink(__FILE__, __LINE__, "canSymlink.1","canSymlink.0");
-#endif
- return (value);
-}
-
-/*
- * Can this platform run the gzip program?
- */
-/* Platform-dependent options for hiding the output of a subcommand. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-static const char *redirectArgs = ">NUL 2>NUL"; /* Win32 cmd.exe */
-#else
-static const char *redirectArgs = ">/dev/null 2>/dev/null"; /* POSIX 'sh' */
-#endif
-int
-canGzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("gzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the gunzip program?
- */
-int
-canGunzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("gunzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Sleep as needed; useful for verifying disk timestamp changes by
- * ensuring that the wall-clock time has actually changed before we
- * go back to re-read something from disk.
- */
-void
-sleepUntilAfter(time_t t)
-{
- while (t >= time(NULL))
-#if defined(_WIN32) && !defined(__CYGWIN__)
- Sleep(500);
-#else
- sleep(1);
-#endif
-}
-
-/*
- * Call standard system() call, but build up the command line using
- * sprintf() conventions.
- */
-int
-systemf(const char *fmt, ...)
-{
- char buff[8192];
- va_list ap;
- int r;
-
- va_start(ap, fmt);
- vsprintf(buff, fmt, ap);
- if (verbosity > VERBOSITY_FULL)
- logprintf("Cmd: %s\n", buff);
- r = system(buff);
- va_end(ap);
- return (r);
-}
-
-/*
- * Slurp a file into memory for ease of comparison and testing.
- * Returns size of file in 'sizep' if non-NULL, null-terminates
- * data in memory for ease of use.
- */
-char *
-slurpfile(size_t * sizep, const char *fmt, ...)
-{
- char filename[8192];
- struct stat st;
- va_list ap;
- char *p;
- ssize_t bytes_read;
- FILE *f;
- int r;
-
- va_start(ap, fmt);
- vsprintf(filename, fmt, ap);
- va_end(ap);
-
- f = fopen(filename, "rb");
- if (f == NULL) {
- /* Note: No error; non-existent file is okay here. */
- return (NULL);
- }
- r = fstat(fileno(f), &st);
- if (r != 0) {
- logprintf("Can't stat file %s\n", filename);
- fclose(f);
- return (NULL);
- }
- p = malloc((size_t)st.st_size + 1);
- if (p == NULL) {
- logprintf("Can't allocate %ld bytes of memory to read file %s\n",
- (long int)st.st_size, filename);
- fclose(f);
- return (NULL);
- }
- bytes_read = fread(p, 1, (size_t)st.st_size, f);
- if (bytes_read < st.st_size) {
- logprintf("Can't read file %s\n", filename);
- fclose(f);
- free(p);
- return (NULL);
- }
- p[st.st_size] = '\0';
- if (sizep != NULL)
- *sizep = (size_t)st.st_size;
- fclose(f);
- return (p);
-}
-
-/* Read a uuencoded file from the reference directory, decode, and
- * write the result into the current directory. */
-#define UUDECODE(c) (((c) - 0x20) & 0x3f)
-void
-extract_reference_file(const char *name)
-{
- char buff[1024];
- FILE *in, *out;
-
- sprintf(buff, "%s/%s.uu", refdir, name);
- in = fopen(buff, "r");
- failure("Couldn't open reference file %s", buff);
- assert(in != NULL);
- if (in == NULL)
- return;
- /* Read up to and including the 'begin' line. */
- for (;;) {
- if (fgets(buff, sizeof(buff), in) == NULL) {
- /* TODO: This is a failure. */
- return;
- }
- if (memcmp(buff, "begin ", 6) == 0)
- break;
- }
- /* Now, decode the rest and write it. */
- /* Not a lot of error checking here; the input better be right. */
- out = fopen(name, "wb");
- while (fgets(buff, sizeof(buff), in) != NULL) {
- char *p = buff;
- int bytes;
-
- if (memcmp(buff, "end", 3) == 0)
- break;
-
- bytes = UUDECODE(*p++);
- while (bytes > 0) {
- int n = 0;
- /* Write out 1-3 bytes from that. */
- if (bytes > 0) {
- n = UUDECODE(*p++) << 18;
- n |= UUDECODE(*p++) << 12;
- fputc(n >> 16, out);
- --bytes;
- }
- if (bytes > 0) {
- n |= UUDECODE(*p++) << 6;
- fputc((n >> 8) & 0xFF, out);
- --bytes;
- }
- if (bytes > 0) {
- n |= UUDECODE(*p++);
- fputc(n & 0xFF, out);
- --bytes;
- }
- }
- }
- fclose(out);
- fclose(in);
-}
-
-/*
- *
- * TEST management
- *
- */
-
-/*
- * "list.h" is simply created by "grep DEFINE_TEST test_*.c"; it has
- * a line like
- * DEFINE_TEST(test_function)
- * for each test.
- */
-
-/* Use "list.h" to declare all of the test functions. */
-#undef DEFINE_TEST
-#define DEFINE_TEST(name) void name(void);
-#include "list.h"
-
-/* Use "list.h" to create a list of all tests (functions and names). */
-#undef DEFINE_TEST
-#define DEFINE_TEST(n) { n, #n, 0 },
-struct { void (*func)(void); const char *name; int failures; } tests[] = {
- #include "list.h"
-};
-
-/*
- * Summarize repeated failures in the just-completed test.
- */
-static void
-test_summarize(const char *filename, int failed)
-{
- unsigned int i;
-
- switch (verbosity) {
- case VERBOSITY_SUMMARY_ONLY:
- printf(failed ? "E" : ".");
- fflush(stdout);
- break;
- case VERBOSITY_PASSFAIL:
- printf(failed ? "FAIL\n" : "ok\n");
- break;
- }
-
- log_console = (verbosity == VERBOSITY_LIGHT_REPORT);
-
- for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].count > 1 && !failed_lines[i].skip)
- logprintf("%s:%d: Summary: Failed %d times\n",
- filename, i, failed_lines[i].count);
- }
- /* Clear the failure history for the next file. */
- memset(failed_lines, 0, sizeof(failed_lines));
-}
-
-/*
- * Actually run a single test, with appropriate setup and cleanup.
- */
-static int
-test_run(int i, const char *tmpdir)
-{
- char logfilename[64];
- int failures_before = failures;
- int oldumask;
-
- switch (verbosity) {
- case VERBOSITY_SUMMARY_ONLY: /* No per-test reports at all */
- break;
- case VERBOSITY_PASSFAIL: /* rest of line will include ok/FAIL marker */
- printf("%3d: %-50s", i, tests[i].name);
- fflush(stdout);
- break;
- default: /* Title of test, details will follow */
- printf("%3d: %s\n", i, tests[i].name);
- }
-
- /* Chdir to the top-level work directory. */
- if (!assertChdir(tmpdir)) {
- fprintf(stderr,
- "ERROR: Can't chdir to top work dir %s\n", tmpdir);
- exit(1);
- }
- /* Create a log file for this test. */
- sprintf(logfilename, "%s.log", tests[i].name);
- logfile = fopen(logfilename, "w");
- fprintf(logfile, "%s\n\n", tests[i].name);
- /* Chdir() to a work dir for this specific test. */
- if (!assertMakeDir(tests[i].name, 0755)
- || !assertChdir(tests[i].name)) {
- fprintf(stderr,
- "ERROR: Can't chdir to work dir %s/%s\n",
- tmpdir, tests[i].name);
- exit(1);
- }
- /* Explicitly reset the locale before each test. */
- setlocale(LC_ALL, "C");
- /* Record the umask before we run the test. */
- umask(oldumask = umask(0));
- /*
- * Run the actual test.
- */
- (*tests[i].func)();
- /*
- * Clean up and report afterwards.
- */
- /* Restore umask */
- umask(oldumask);
- /* Reset locale. */
- setlocale(LC_ALL, "C");
- /* Reset directory. */
- if (!assertChdir(tmpdir)) {
- fprintf(stderr, "ERROR: Couldn't chdir to temp dir %s\n",
- tmpdir);
- exit(1);
- }
- /* Report per-test summaries. */
- tests[i].failures = failures - failures_before;
- test_summarize(test_filename, tests[i].failures);
- /* Close the per-test log file. */
- fclose(logfile);
- logfile = NULL;
- /* If there were no failures, we can remove the work dir and logfile. */
- if (tests[i].failures == 0) {
- if (!keep_temp_files && assertChdir(tmpdir)) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure not to leave empty directories.
- * Sometimes a processing of closing files used by tests
- * is not done, then rmdir will be failed and it will
- * leave a empty test directory. So we should wait a few
- * seconds and retry rmdir. */
- int r, t;
- for (t = 0; t < 10; t++) {
- if (t > 0)
- Sleep(1000);
- r = systemf("rmdir /S /Q %s", tests[i].name);
- if (r == 0)
- break;
- }
- systemf("del %s", logfilename);
-#else
- systemf("rm -rf %s", tests[i].name);
- systemf("rm %s", logfilename);
-#endif
- }
- }
- /* Return appropriate status. */
- return (tests[i].failures);
-}
-
-/*
- *
- *
- * MAIN and support routines.
- *
- *
- */
-
-static void
-usage(const char *program)
-{
- static const int limit = sizeof(tests) / sizeof(tests[0]);
- int i;
-
- printf("Usage: %s [options] <test> <test> ...\n", program);
- printf("Default is to run all tests.\n");
- printf("Otherwise, specify the numbers of the tests you wish to run.\n");
- printf("Options:\n");
- printf(" -d Dump core after any failure, for debugging.\n");
- printf(" -k Keep all temp files.\n");
- printf(" Default: temp files for successful tests deleted.\n");
-#ifdef PROGRAM
- printf(" -p <path> Path to executable to be tested.\n");
- printf(" Default: path taken from " ENVBASE " environment variable.\n");
-#endif
- printf(" -q Quiet.\n");
- printf(" -r <dir> Path to dir containing reference files.\n");
- printf(" Default: Current directory.\n");
- printf(" -v Verbose.\n");
- printf("Available tests:\n");
- for (i = 0; i < limit; i++)
- printf(" %d: %s\n", i, tests[i].name);
- exit(1);
-}
-
-static char *
-get_refdir(const char *d)
-{
- char tried[512] = { '\0' };
- char buff[128];
- char *pwd, *p;
-
- /* If a dir was specified, try that */
- if (d != NULL) {
- pwd = NULL;
- snprintf(buff, sizeof(buff), "%s", d);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
- goto failure;
- }
-
- /* Get the current dir. */
- pwd = getcwd(NULL, 0);
- while (pwd[strlen(pwd) - 1] == '\n')
- pwd[strlen(pwd) - 1] = '\0';
-
- /* Look for a known file. */
- snprintf(buff, sizeof(buff), "%s", pwd);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
-
- snprintf(buff, sizeof(buff), "%s/test", pwd);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
-
-#if defined(LIBRARY)
- snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
-#else
- snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
-#endif
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
-
- if (memcmp(pwd, "/usr/obj", 8) == 0) {
- snprintf(buff, sizeof(buff), "%s", pwd + 8);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
-
- snprintf(buff, sizeof(buff), "%s/test", pwd + 8);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
- }
-
-failure:
- printf("Unable to locate known reference file %s\n", KNOWNREF);
- printf(" Checked following directories:\n%s\n", tried);
-#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
- DebugBreak();
-#endif
- exit(1);
-
-success:
- free(p);
- free(pwd);
- return strdup(buff);
-}
-
-int
-main(int argc, char **argv)
-{
- static const int limit = sizeof(tests) / sizeof(tests[0]);
- int i, tests_run = 0, tests_failed = 0, option;
- time_t now;
- char *refdir_alloc = NULL;
- const char *progname;
- const char *tmp, *option_arg, *p;
- char tmpdir[256];
- char tmpdir_timestamp[256];
-
- (void)argc; /* UNUSED */
-
-#if defined(HAVE__CrtSetReportMode)
- /* To stop to run the default invalid parameter handler. */
- _set_invalid_parameter_handler(invalid_parameter_handler);
- /* Disable annoying assertion message box. */
- _CrtSetReportMode(_CRT_ASSERT, 0);
-#endif
-
- /*
- * Name of this program, used to build root of our temp directory
- * tree.
- */
- progname = p = argv[0];
- while (*p != '\0') {
- /* Support \ or / dir separators for Windows compat. */
- if (*p == '/' || *p == '\\')
- progname = p + 1;
- ++p;
- }
-
-#ifdef PROGRAM
- /* Get the target program from environment, if available. */
- testprogfile = getenv(ENVBASE);
-#endif
-
- if (getenv("TMPDIR") != NULL)
- tmp = getenv("TMPDIR");
- else if (getenv("TMP") != NULL)
- tmp = getenv("TMP");
- else if (getenv("TEMP") != NULL)
- tmp = getenv("TEMP");
- else if (getenv("TEMPDIR") != NULL)
- tmp = getenv("TEMPDIR");
- else
- tmp = "/tmp";
-
- /* Allow -d to be controlled through the environment. */
- if (getenv(ENVBASE "_DEBUG") != NULL)
- dump_on_failure = 1;
-
- /* Get the directory holding test files from environment. */
- refdir = getenv(ENVBASE "_TEST_FILES");
-
- /*
- * Parse options, without using getopt(), which isn't available
- * on all platforms.
- */
- ++argv; /* Skip program name */
- while (*argv != NULL) {
- if (**argv != '-')
- break;
- p = *argv++;
- ++p; /* Skip '-' */
- while (*p != '\0') {
- option = *p++;
- option_arg = NULL;
- /* If 'opt' takes an argument, parse that. */
- if (option == 'p' || option == 'r') {
- if (*p != '\0')
- option_arg = p;
- else if (*argv == NULL) {
- fprintf(stderr,
- "Option -%c requires argument.\n",
- option);
- usage(progname);
- } else
- option_arg = *argv++;
- p = ""; /* End of this option word. */
- }
-
- /* Now, handle the option. */
- switch (option) {
- case 'd':
- dump_on_failure = 1;
- break;
- case 'k':
- keep_temp_files = 1;
- break;
- case 'p':
-#ifdef PROGRAM
- testprogfile = option_arg;
-#else
- usage(progname);
-#endif
- break;
- case 'q':
- verbosity--;
- break;
- case 'r':
- refdir = option_arg;
- break;
- case 'v':
- verbosity++;
- break;
- default:
- usage(progname);
- }
- }
- }
-
- /*
- * Sanity-check that our options make sense.
- */
-#ifdef PROGRAM
- if (testprogfile == NULL)
- usage(progname);
- {
- char *testprg;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Command.com sometimes rejects '/' separators. */
- testprg = strdup(testprogfile);
- for (i = 0; testprg[i] != '\0'; i++) {
- if (testprg[i] == '/')
- testprg[i] = '\\';
- }
- testprogfile = testprg;
-#endif
- /* Quote the name that gets put into shell command lines. */
- testprg = malloc(strlen(testprogfile) + 3);
- strcpy(testprg, "\"");
- strcat(testprg, testprogfile);
- strcat(testprg, "\"");
- testprog = testprg;
- }
-#endif
-
- /*
- * Create a temp directory for the following tests.
- * Include the time the tests started as part of the name,
- * to make it easier to track the results of multiple tests.
- */
- now = time(NULL);
- for (i = 0; ; i++) {
- strftime(tmpdir_timestamp, sizeof(tmpdir_timestamp),
- "%Y-%m-%dT%H.%M.%S",
- localtime(&now));
- sprintf(tmpdir, "%s/%s.%s-%03d", tmp, progname,
- tmpdir_timestamp, i);
- if (assertMakeDir(tmpdir,0755))
- break;
- if (i >= 999) {
- fprintf(stderr,
- "ERROR: Unable to create temp directory %s\n",
- tmpdir);
- exit(1);
- }
- }
-
- /*
- * If the user didn't specify a directory for locating
- * reference files, try to find the reference files in
- * the "usual places."
- */
- refdir = refdir_alloc = get_refdir(refdir);
-
- /*
- * Banner with basic information.
- */
- printf("\n");
- printf("If tests fail or crash, details will be in:\n");
- printf(" %s\n", tmpdir);
- printf("\n");
- if (verbosity > VERBOSITY_SUMMARY_ONLY) {
- printf("Reference files will be read from: %s\n", refdir);
-#ifdef PROGRAM
- printf("Running tests on: %s\n", testprog);
-#endif
- printf("Exercising: ");
- fflush(stdout);
- printf("%s\n", EXTRA_VERSION);
- } else {
- printf("Running ");
- fflush(stdout);
- }
-
- /*
- * Run some or all of the individual tests.
- */
- if (*argv == NULL) {
- /* Default: Run all tests. */
- for (i = 0; i < limit; i++) {
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
- }
- } else {
- while (*(argv) != NULL) {
- if (**argv >= '0' && **argv <= '9') {
- i = atoi(*argv);
- if (i < 0 || i >= limit) {
- printf("*** INVALID Test %s\n", *argv);
- free(refdir_alloc);
- usage(progname);
- /* usage() never returns */
- }
- } else {
- for (i = 0; i < limit; ++i) {
- if (strcmp(*argv, tests[i].name) == 0)
- break;
- }
- if (i >= limit) {
- printf("*** INVALID Test ``%s''\n",
- *argv);
- free(refdir_alloc);
- usage(progname);
- /* usage() never returns */
- }
- }
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
- argv++;
- }
- }
-
- /*
- * Report summary statistics.
- */
- if (verbosity > VERBOSITY_SUMMARY_ONLY) {
- printf("\n");
- printf("Totals:\n");
- printf(" Tests run: %8d\n", tests_run);
- printf(" Tests failed: %8d\n", tests_failed);
- printf(" Assertions checked:%8d\n", assertions);
- printf(" Assertions failed: %8d\n", failures);
- printf(" Skips reported: %8d\n", skips);
- }
- if (failures) {
- printf("\n");
- printf("Failing tests:\n");
- for (i = 0; i < limit; ++i) {
- if (tests[i].failures)
- printf(" %d: %s (%d failures)\n", i,
- tests[i].name, tests[i].failures);
- }
- printf("\n");
- printf("Details for failing tests: %s\n", tmpdir);
- printf("\n");
- } else {
- if (verbosity == VERBOSITY_SUMMARY_ONLY)
- printf("\n");
- printf("%d tests passed, no failures\n", tests_run);
- }
-
- free(refdir_alloc);
-
- /* If the final tmpdir is empty, we can remove it. */
- /* This should be the usual case when all tests succeed. */
- assertChdir("..");
- rmdir(tmpdir);
-
- return (tests_failed ? 1 : 0);
-}
diff --git a/usr.bin/cpio/test/test.h b/usr.bin/cpio/test/test.h
deleted file mode 100644
index 8b1352a1aaee..000000000000
--- a/usr.bin/cpio/test/test.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2003-2006 Tim Kientzle
- * 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.
- *
- * $FreeBSD$
- */
-
-/* Every test program should #include "test.h" as the first thing. */
-
-/*
- * The goal of this file (and the matching test.c) is to
- * simplify the very repetitive test-*.c test programs.
- */
-#if defined(HAVE_CONFIG_H)
-/* Most POSIX platforms use the 'configure' script to build config.h */
-#include "config.h"
-#elif defined(__FreeBSD__)
-/* Building as part of FreeBSD system requires a pre-built config.h. */
-#include "config_freebsd.h"
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-/* Win32 can't run the 'configure' script. */
-#include "config_windows.h"
-#else
-/* Warn if the library hasn't been (automatically or manually) configured. */
-#error Oops: No config.h and no pre-built configuration in test.h.
-#endif
-
-#include <sys/types.h> /* Windows requires this before sys/stat.h */
-#include <sys/stat.h>
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#endif
-#if HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#define dirent direct
-#endif
-#include <errno.h>
-#include <fcntl.h>
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <wchar.h>
-#ifdef HAVE_WINDOWS_H
-#include <windows.h>
-#endif
-
-/*
- * System-specific tweaks. We really want to minimize these
- * as much as possible, since they make it harder to understand
- * the mainline code.
- */
-
-/* Windows (including Visual Studio and MinGW but not Cygwin) */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include "../cpio_windows.h"
-#if !defined(__BORLANDC__)
-#define strdup _strdup
-#endif
-#define LOCALE_DE "deu"
-#else
-#define LOCALE_DE "de_DE.UTF-8"
-#endif
-
-/* Visual Studio */
-#ifdef _MSC_VER
-#define snprintf sprintf_s
-#endif
-
-/* Cygwin */
-#if defined(__CYGWIN__)
-/* Cygwin-1.7.x is lazy about populating nlinks, so don't
- * expect it to be accurate. */
-# define NLINKS_INACCURATE_FOR_DIRS
-#endif
-
-#if defined(__HAIKU__) || defined(__QNXNTO__)
-/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
-#include <stdint.h>
-#endif
-
-/* Get a real definition for __FBSDID if we can */
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
-/* If not, define it so as to avoid dangling semicolons. */
-#ifndef __FBSDID
-#define __FBSDID(a) struct _undefined_hack
-#endif
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-/*
- * Redefine DEFINE_TEST for use in defining the test functions.
- */
-#undef DEFINE_TEST
-#define DEFINE_TEST(name) void name(void); void name(void)
-
-/* An implementation of the standard assert() macro */
-#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
-/* chdir() and error if it fails */
-#define assertChdir(path) \
- assertion_chdir(__FILE__, __LINE__, path)
-/* Assert two integers are the same. Reports value of each one if not. */
-#define assertEqualInt(v1,v2) \
- assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-/* Assert two strings are the same. Reports value of each one if not. */
-#define assertEqualString(v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-/* As above, but v1 and v2 are wchar_t * */
-#define assertEqualWString(v1,v2) \
- assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-/* As above, but raw blocks of bytes. */
-#define assertEqualMem(v1, v2, l) \
- assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
-/* Assert two files are the same; allow printf-style expansion of second name.
- * See below for comments about variable arguments here...
- */
-#define assertEqualFile \
- assertion_setup(__FILE__, __LINE__);assertion_equal_file
-/* Assert that a file is empty; supports printf-style arguments. */
-#define assertEmptyFile \
- assertion_setup(__FILE__, __LINE__);assertion_empty_file
-/* Assert that a file is not empty; supports printf-style arguments. */
-#define assertNonEmptyFile \
- assertion_setup(__FILE__, __LINE__);assertion_non_empty_file
-#define assertFileAtime(pathname, sec, nsec) \
- assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
-#define assertFileAtimeRecent(pathname) \
- assertion_file_atime_recent(__FILE__, __LINE__, pathname)
-#define assertFileBirthtime(pathname, sec, nsec) \
- assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
-#define assertFileBirthtimeRecent(pathname) \
- assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
-/* Assert that a file exists; supports printf-style arguments. */
-#define assertFileExists \
- assertion_setup(__FILE__, __LINE__);assertion_file_exists
-/* Assert that a file exists; supports printf-style arguments. */
-#define assertFileNotExists \
- assertion_setup(__FILE__, __LINE__);assertion_file_not_exists
-/* Assert that file contents match a string; supports printf-style arguments. */
-#define assertFileContents \
- assertion_setup(__FILE__, __LINE__);assertion_file_contents
-#define assertFileMtime(pathname, sec, nsec) \
- assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
-#define assertFileMtimeRecent(pathname) \
- assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
-#define assertFileNLinks(pathname, nlinks) \
- assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
-#define assertFileSize(pathname, size) \
- assertion_file_size(__FILE__, __LINE__, pathname, size)
-#define assertTextFileContents \
- assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
-#define assertIsDir(pathname, mode) \
- assertion_is_dir(__FILE__, __LINE__, pathname, mode)
-#define assertIsHardlink(path1, path2) \
- assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
-#define assertIsNotHardlink(path1, path2) \
- assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
-#define assertIsReg(pathname, mode) \
- assertion_is_reg(__FILE__, __LINE__, pathname, mode)
-#define assertIsSymlink(pathname, contents) \
- assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
-/* Create a directory, report error if it fails. */
-#define assertMakeDir(dirname, mode) \
- assertion_make_dir(__FILE__, __LINE__, dirname, mode)
-#define assertMakeFile(path, mode, contents) \
- assertion_make_file(__FILE__, __LINE__, path, mode, contents)
-#define assertMakeHardlink(newfile, oldfile) \
- assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
-#define assertMakeSymlink(newfile, linkto) \
- assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
-#define assertUmask(mask) \
- assertion_umask(__FILE__, __LINE__, mask)
-
-/*
- * This would be simple with C99 variadic macros, but I don't want to
- * require that. Instead, I insert a function call before each
- * skipping() call to pass the file and line information down. Crude,
- * but effective.
- */
-#define skipping \
- assertion_setup(__FILE__, __LINE__);test_skipping
-
-/* Function declarations. These are defined in test_utility.c. */
-void failure(const char *fmt, ...);
-int assertion_assert(const char *, int, int, const char *, void *);
-int assertion_chdir(const char *, int, const char *);
-int assertion_empty_file(const char *, ...);
-int assertion_equal_file(const char *, const char *, ...);
-int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
-int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
-int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
-int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
-int assertion_file_atime(const char *, int, const char *, long, long);
-int assertion_file_atime_recent(const char *, int, const char *);
-int assertion_file_birthtime(const char *, int, const char *, long, long);
-int assertion_file_birthtime_recent(const char *, int, const char *);
-int assertion_file_contents(const void *, int, const char *, ...);
-int assertion_file_exists(const char *, ...);
-int assertion_file_mtime(const char *, int, const char *, long, long);
-int assertion_file_mtime_recent(const char *, int, const char *);
-int assertion_file_nlinks(const char *, int, const char *, int);
-int assertion_file_not_exists(const char *, ...);
-int assertion_file_size(const char *, int, const char *, long);
-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 *);
-int assertion_is_reg(const char *, int, const char *, int);
-int assertion_is_symlink(const char *, int, const char *, const char *);
-int assertion_make_dir(const char *, int, const char *, int);
-int assertion_make_file(const char *, int, const char *, int, const char *);
-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_non_empty_file(const char *, ...);
-int assertion_text_file_contents(const char *buff, const char *f);
-int assertion_umask(const char *, int, int);
-void assertion_setup(const char *, int);
-
-void test_skipping(const char *fmt, ...);
-
-/* Like sprintf, then system() */
-int systemf(const char * fmt, ...);
-
-/* Delay until time() returns a value after this. */
-void sleepUntilAfter(time_t);
-
-/* Return true if this platform can create symlinks. */
-int canSymlink(void);
-
-/* Return true if this platform can run the "gzip" program. */
-int canGzip(void);
-
-/* Return true if this platform can run the "gunzip" program. */
-int canGunzip(void);
-
-/* Suck file into string allocated via malloc(). Call free() when done. */
-/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
-char *slurpfile(size_t *, const char *fmt, ...);
-
-/* Extracts named reference file to the current directory. */
-void extract_reference_file(const char *);
-
-/*
- * Special interfaces for program test harness.
- */
-
-/* Pathname of exe to be tested. */
-const char *testprogfile;
-/* Name of exe to use in printf-formatted command strings. */
-/* On Windows, this includes leading/trailing quotes. */
-const char *testprog;
diff --git a/usr.bin/cpio/test/test_0.c b/usr.bin/cpio/test/test_0.c
deleted file mode 100644
index 75a1437fd70e..000000000000
--- a/usr.bin/cpio/test/test_0.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * This first test does basic sanity checks on the environment. For
- * most of these, we just exit on failure.
- */
-#if !defined(_WIN32) || defined(__CYGWIN__)
-#define DEV_NULL "/dev/null"
-#else
-#define DEV_NULL "NUL"
-#endif
-
-DEFINE_TEST(test_0)
-{
- struct stat st;
-
- failure("File %s does not exist?!", testprogfile);
- if (!assertEqualInt(0, stat(testprogfile, &st)))
- exit(1);
-
- failure("%s is not executable?!", testprogfile);
- if (!assert((st.st_mode & 0111) != 0))
- exit(1);
-
- /*
- * Try to succesfully run the program; this requires that
- * we know some option that will succeed.
- */
- if (0 == systemf("%s --version >" DEV_NULL, testprog)) {
- /* This worked. */
- } else if (0 == systemf("%s -W version >" DEV_NULL, testprog)) {
- /* This worked. */
- } else {
- failure("Unable to successfully run any of the following:\n"
- " * %s --version\n"
- " * %s -W version\n",
- testprog, testprog);
- assert(0);
- }
-
- /* TODO: Ensure that our reference files are available. */
-}
diff --git a/usr.bin/cpio/test/test_basic.c b/usr.bin/cpio/test/test_basic.c
deleted file mode 100644
index 3a3fae820bc6..000000000000
--- a/usr.bin/cpio/test/test_basic.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-static void
-verify_files(const char *msg)
-{
- /*
- * Verify unpacked files.
- */
-
- /* Regular file with 2 links. */
- assertIsReg("file", 0644);
- failure(msg);
- assertFileSize("file", 10);
- assertFileNLinks("file", 2);
-
- /* Another name for the same file. */
- assertIsHardlink("linkfile", "file");
-
- /* Symlink */
- if (canSymlink())
- assertIsSymlink("symlink", "file");
-
- /* Another file with 1 link and different permissions. */
- assertIsReg("file2", 0777);
- assertFileSize("file2", 10);
- assertFileNLinks("file2", 1);
-
- /* dir */
- assertIsDir("dir", 0775);
-}
-
-static void
-basic_cpio(const char *target,
- const char *pack_options,
- const char *unpack_options,
- const char *se)
-{
- int r;
-
- if (!assertMakeDir(target, 0775))
- return;
-
- /* Use the cpio program to create an archive. */
- r = systemf("%s -o %s < filelist >%s/archive 2>%s/pack.err",
- testprog, pack_options, target, target);
- failure("Error invoking %s -o %s", testprog, pack_options);
- assertEqualInt(r, 0);
-
- assertChdir(target);
-
- /* Verify stderr. */
- failure("Expected: %s, options=%s", se, pack_options);
- assertTextFileContents(se, "pack.err");
-
- /*
- * Use cpio to unpack the archive into another directory.
- */
- r = systemf("%s -i %s< archive >unpack.out 2>unpack.err",
- testprog, unpack_options);
- failure("Error invoking %s -i %s", testprog, unpack_options);
- assertEqualInt(r, 0);
-
- /* Verify stderr. */
- failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target);
- assertTextFileContents(se, "unpack.err");
-
- verify_files(pack_options);
-
- assertChdir("..");
-}
-
-static void
-passthrough(const char *target)
-{
- int r;
-
- if (!assertMakeDir(target, 0775))
- return;
-
- /*
- * Use cpio passthrough mode to copy files to another directory.
- */
- r = systemf("%s -p %s <filelist >%s/stdout 2>%s/stderr",
- testprog, target, target, target);
- failure("Error invoking %s -p", testprog);
- assertEqualInt(r, 0);
-
- assertChdir(target);
-
- /* Verify stderr. */
- failure("Error invoking %s -p in dir %s",
- testprog, target);
- assertTextFileContents("1 block\n", "stderr");
-
- verify_files("passthrough");
- assertChdir("..");
-}
-
-DEFINE_TEST(test_basic)
-{
- FILE *filelist;
- const char *msg;
-
- assertUmask(0);
-
- /*
- * Create an assortment of files on disk.
- */
- filelist = fopen("filelist", "w");
-
- /* File with 10 bytes content. */
- assertMakeFile("file", 0644, "1234567890");
- fprintf(filelist, "file\n");
-
- /* hardlink to above file. */
- assertMakeHardlink("linkfile", "file");
- fprintf(filelist, "linkfile\n");
-
- /* Symlink to above file. */
- if (canSymlink()) {
- assertMakeSymlink("symlink", "file");
- fprintf(filelist, "symlink\n");
- }
-
- /* Another file with different permissions. */
- assertMakeFile("file2", 0777, "1234567890");
- fprintf(filelist, "file2\n");
-
- /* Directory. */
- assertMakeDir("dir", 0775);
- fprintf(filelist, "dir\n");
- /* All done. */
- fclose(filelist);
-
- assertUmask(022);
-
- /* Archive/dearchive with a variety of options. */
- msg = canSymlink() ? "2 blocks\n" : "1 block\n";
- basic_cpio("copy", "", "", msg);
- basic_cpio("copy_odc", "--format=odc", "", msg);
- basic_cpio("copy_newc", "-H newc", "", "2 blocks\n");
- basic_cpio("copy_cpio", "-H odc", "", msg);
- msg = canSymlink() ? "9 blocks\n" : "8 blocks\n";
- basic_cpio("copy_ustar", "-H ustar", "", msg);
-
- /* Copy in one step using -p */
- passthrough("passthrough");
-}
diff --git a/usr.bin/cpio/test/test_cmdline.c b/usr.bin/cpio/test/test_cmdline.c
deleted file mode 100644
index 2dd7d651dc57..000000000000
--- a/usr.bin/cpio/test/test_cmdline.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * 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$");
-
-/*
- * Test the command-line parsing.
- */
-
-DEFINE_TEST(test_cmdline)
-{
- FILE *f;
-
- /* Create an empty file. */
- f = fopen("empty", "wb");
- assert(f != NULL);
- fclose(f);
-
- failure("-Q is an invalid option on every cpio program I know of");
- assert(0 != systemf("%s -i -Q <empty >1.out 2>1.err", testprog));
- assertEmptyFile("1.out");
-
- failure("-f requires an argument");
- assert(0 != systemf("%s -if <empty >2.out 2>2.err", testprog));
- assertEmptyFile("2.out");
-
- failure("-f requires an argument");
- assert(0 != systemf("%s -i -f <empty >3.out 2>3.err", testprog));
- assertEmptyFile("3.out");
-
- failure("--format requires an argument");
- assert(0 != systemf("%s -i --format <empty >4.out 2>4.err", testprog));
- assertEmptyFile("4.out");
-
- failure("--badopt is an invalid option");
- assert(0 != systemf("%s -i --badop <empty >5.out 2>5.err", testprog));
- assertEmptyFile("5.out");
-
- failure("--badopt is an invalid option");
- assert(0 != systemf("%s -i --badopt <empty >6.out 2>6.err", testprog));
- assertEmptyFile("6.out");
-
- failure("--n is ambiguous");
- assert(0 != systemf("%s -i --n <empty >7.out 2>7.err", testprog));
- assertEmptyFile("7.out");
-
- failure("--create forbids an argument");
- assert(0 != systemf("%s --create=arg <empty >8.out 2>8.err", testprog));
- assertEmptyFile("8.out");
-
- failure("-i with empty input should succeed");
- assert(0 == systemf("%s -i <empty >9.out 2>9.err", testprog));
- assertEmptyFile("9.out");
-
- failure("-o with empty input should succeed");
- assert(0 == systemf("%s -o <empty >10.out 2>10.err", testprog));
-
- failure("-i -p is nonsense");
- assert(0 != systemf("%s -i -p <empty >11.out 2>11.err", testprog));
- assertEmptyFile("11.out");
-
- failure("-p -i is nonsense");
- assert(0 != systemf("%s -p -i <empty >12.out 2>12.err", testprog));
- assertEmptyFile("12.out");
-
- failure("-i -o is nonsense");
- assert(0 != systemf("%s -i -o <empty >13.out 2>13.err", testprog));
- assertEmptyFile("13.out");
-
- failure("-o -i is nonsense");
- assert(0 != systemf("%s -o -i <empty >14.out 2>14.err", testprog));
- assertEmptyFile("14.out");
-
- failure("-o -p is nonsense");
- assert(0 != systemf("%s -o -p <empty >15.out 2>15.err", testprog));
- assertEmptyFile("15.out");
-
- failure("-p -o is nonsense");
- assert(0 != systemf("%s -p -o <empty >16.out 2>16.err", testprog));
- assertEmptyFile("16.out");
-
- failure("-p with empty input should fail");
- assert(0 != systemf("%s -p <empty >17.out 2>17.err", testprog));
- assertEmptyFile("17.out");
-}
diff --git a/usr.bin/cpio/test/test_format_newc.c b/usr.bin/cpio/test/test_format_newc.c
deleted file mode 100644
index eb87c312066e..000000000000
--- a/usr.bin/cpio/test/test_format_newc.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/* Number of bytes needed to pad 'n' to multiple of 'block', assuming
- * that 'block' is a power of two. This trick can be more easily
- * remembered as -n & (block - 1), but many compilers quite reasonably
- * warn about "-n" when n is an unsigned value. (~(n) + 1) is the
- * same thing, but written in a way that won't offend anyone. */
-#define PAD(n, block) ((~(n) + 1) & ((block) - 1))
-
-static int
-is_hex(const char *p, size_t l)
-{
- while (l > 0) {
- if ((*p >= '0' && *p <= '9')
- || (*p >= 'a' && *p <= 'f')
- || (*p >= 'A' && *p <= 'F'))
- {
- --l;
- ++p;
- } else
- return (0);
-
- }
- return (1);
-}
-
-static int
-from_hex(const char *p, size_t l)
-{
- int r = 0;
-
- while (l > 0) {
- r *= 16;
- if (*p >= 'a' && *p <= 'f')
- r += *p + 10 - 'a';
- else if (*p >= 'A' && *p <= 'F')
- r += *p + 10 - 'A';
- else
- r += *p - '0';
- --l;
- ++p;
- }
- return (r);
-}
-
-DEFINE_TEST(test_format_newc)
-{
- FILE *list;
- int r;
- int devmajor, devminor, ino, gid;
- int uid = -1;
- time_t t, t2, now;
- char *p, *e;
- size_t s, fs, ns;
-
- assertUmask(0);
-
-#if !defined(_WIN32)
- uid = getuid();
-#endif
-
- /*
- * Create an assortment of files.
- * TODO: Extend this to cover more filetypes.
- */
- list = fopen("list", "w");
-
- /* "file1" */
- assertMakeFile("file1", 0644, "1234567890");
- fprintf(list, "file1\n");
-
- /* "hardlink" */
- assertMakeHardlink("hardlink", "file1");
- fprintf(list, "hardlink\n");
-
- /* Another hardlink, but this one won't be archived. */
- assertMakeHardlink("hardlink2", "file1");
-
- /* "symlink" */
- if (canSymlink()) {
- assertMakeSymlink("symlink", "file1");
- fprintf(list, "symlink\n");
- }
-
- /* "dir" */
- assertMakeDir("dir", 0775);
- fprintf(list, "dir\n");
-
- /* Record some facts about what we just created: */
- now = time(NULL); /* They were all created w/in last two seconds. */
-
- /* Use the cpio program to create an archive. */
- fclose(list);
- r = systemf("%s -o --format=newc <list >newc.out 2>newc.err",
- testprog);
- if (!assertEqualInt(r, 0))
- return;
-
- /* Verify that nothing went to stderr. */
- if (canSymlink()) {
- assertTextFileContents("2 blocks\n", "newc.err");
- } else {
- assertTextFileContents("1 block\n", "newc.err");
- }
-
- /* Verify that stdout is a well-formed cpio file in "newc" format. */
- p = slurpfile(&s, "newc.out");
- assertEqualInt(s, canSymlink() ? 1024 : 512);
- e = p;
-
- /*
- * Some of these assertions could be stronger, but it's
- * a little tricky because they depend on the local environment.
- */
-
- /* First entry is "file1" */
- assert(is_hex(e, 110)); /* Entire header is octal digits. */
- assertEqualMem(e + 0, "070701", 6); /* Magic */
- ino = from_hex(e + 6, 8); /* ino */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Group members bits and others bits do not work. */
- assertEqualInt(0x8180, from_hex(e + 14, 8) & 0xffc0); /* Mode */
-#else
- assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
-#endif
- if (uid < 0)
- uid = from_hex(e + 22, 8);
- assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
- gid = from_hex(e + 30, 8); /* gid */
- assertEqualMem(e + 38, "00000003", 8); /* nlink */
- t = from_hex(e + 46, 8); /* mtime */
- failure("t=0x%08x now=0x%08x=%d", t, now, now);
- assert(t <= now); /* File wasn't created in future. */
- failure("t=0x%08x now - 2=0x%08x = %d", t, now - 2, now - 2);
- assert(t >= now - 2); /* File was created w/in last 2 secs. */
- failure("newc format stores body only with last appearance of a link\n"
- " first appearance should be empty, so this file size\n"
- " field should be zero");
- assertEqualInt(0, from_hex(e + 54, 8)); /* File size */
- fs = from_hex(e + 54, 8);
- fs += PAD(fs, 4);
- devmajor = from_hex(e + 62, 8); /* devmajor */
- devminor = from_hex(e + 70, 8); /* devminor */
- assert(is_hex(e + 78, 8)); /* rdevmajor */
- assert(is_hex(e + 86, 8)); /* rdevminor */
- assertEqualMem(e + 94, "00000006", 8); /* Name size */
- ns = from_hex(e + 94, 8);
- ns += PAD(ns + 2, 4);
- assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
- assertEqualMem(e + 110, "file1\0", 6); /* Name contents */
- /* Since there's another link, no file contents here. */
- /* But add in file size so that an error here doesn't cascade. */
- e += 110 + fs + ns;
-
- if (canSymlink()) {
- /* "symlink" pointing to "file1" */
- assert(is_hex(e, 110));
- assertEqualMem(e + 0, "070701", 6); /* Magic */
- assert(is_hex(e + 6, 8)); /* ino */
- assertEqualInt(0xa1ff, from_hex(e + 14, 8)); /* Mode */
- assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
- assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
- assertEqualMem(e + 38, "00000001", 8); /* nlink */
- t2 = from_hex(e + 46, 8); /* mtime */
- failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
- assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
- assertEqualMem(e + 54, "00000005", 8); /* File size */
- fs = from_hex(e + 54, 8);
- fs += PAD(fs, 4);
- assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
- assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
- assert(is_hex(e + 78, 8)); /* rdevmajor */
- assert(is_hex(e + 86, 8)); /* rdevminor */
- assertEqualMem(e + 94, "00000008", 8); /* Name size */
- ns = from_hex(e + 94, 8);
- ns += PAD(ns + 2, 4);
- assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
- assertEqualMem(e + 110, "symlink\0\0\0", 10); /* Name contents */
- assertEqualMem(e + 110 + ns, "file1\0\0\0", 8); /* symlink target */
- e += 110 + fs + ns;
- }
-
- /* "dir" */
- assert(is_hex(e, 110));
- assertEqualMem(e + 0, "070701", 6); /* Magic */
- assert(is_hex(e + 6, 8)); /* ino */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Group members bits and others bits do not work. */
- assertEqualInt(0x41c0, from_hex(e + 14, 8) & 0xffc0); /* Mode */
-#else
- /* Mode: sgid bit sometimes propagates from parent dirs, ignore it. */
- assertEqualInt(040775, from_hex(e + 14, 8) & ~02000);
-#endif
- assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
- assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
-#ifndef NLINKS_INACCURATE_FOR_DIRS
- assertEqualMem(e + 38, "00000002", 8); /* nlink */
-#endif
- t2 = from_hex(e + 46, 8); /* mtime */
- failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
- assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
- assertEqualMem(e + 54, "00000000", 8); /* File size */
- fs = from_hex(e + 54, 8);
- fs += PAD(fs, 4);
- assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
- assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
- assert(is_hex(e + 78, 8)); /* rdevmajor */
- assert(is_hex(e + 86, 8)); /* rdevminor */
- assertEqualMem(e + 94, "00000004", 8); /* Name size */
- ns = from_hex(e + 94, 8);
- ns += PAD(ns + 2, 4);
- assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
- assertEqualMem(e + 110, "dir\0\0\0", 6); /* Name contents */
- e += 110 + fs + ns;
-
- /* Hardlink identical to "file1" */
- /* Since we only wrote two of the three links to this
- * file, this link should get deferred by the hardlink logic. */
- assert(is_hex(e, 110));
- assertEqualMem(e + 0, "070701", 6); /* Magic */
- failure("If these aren't the same, then the hardlink detection failed to match them.");
- assertEqualInt(ino, from_hex(e + 6, 8)); /* ino */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Group members bits and others bits do not work. */
- assertEqualInt(0x8180, from_hex(e + 14, 8) & 0xffc0); /* Mode */
-#else
- assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
-#endif
- assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
- assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
- assertEqualMem(e + 38, "00000003", 8); /* nlink */
- t2 = from_hex(e + 46, 8); /* mtime */
- failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
- assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
- assertEqualInt(10, from_hex(e + 54, 8)); /* File size */
- fs = from_hex(e + 54, 8);
- fs += PAD(fs, 4);
- assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
- assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
- assert(is_hex(e + 78, 8)); /* rdevmajor */
- assert(is_hex(e + 86, 8)); /* rdevminor */
- assertEqualMem(e + 94, "00000009", 8); /* Name size */
- ns = from_hex(e + 94, 8);
- ns += PAD(ns + 2, 4);
- assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
- assertEqualMem(e + 110, "hardlink\0\0", 10); /* Name contents */
- assertEqualMem(e + 110 + ns, "1234567890\0\0", 12); /* File contents */
- e += 110 + ns + fs;
-
- /* Last entry is end-of-archive marker. */
- assert(is_hex(e, 110));
- assertEqualMem(e + 0, "070701", 6); /* Magic */
- assertEqualMem(e + 8, "00000000", 8); /* ino */
- assertEqualMem(e + 14, "00000000", 8); /* mode */
- assertEqualMem(e + 22, "00000000", 8); /* uid */
- assertEqualMem(e + 30, "00000000", 8); /* gid */
- assertEqualMem(e + 38, "00000001", 8); /* nlink */
- assertEqualMem(e + 46, "00000000", 8); /* mtime */
- assertEqualMem(e + 54, "00000000", 8); /* size */
- assertEqualMem(e + 62, "00000000", 8); /* devmajor */
- assertEqualMem(e + 70, "00000000", 8); /* devminor */
- assertEqualMem(e + 78, "00000000", 8); /* rdevmajor */
- assertEqualMem(e + 86, "00000000", 8); /* rdevminor */
- assertEqualInt(11, from_hex(e + 94, 8)); /* name size */
- assertEqualMem(e + 102, "00000000", 8); /* check field */
- assertEqualMem(e + 110, "TRAILER!!!\0\0", 12); /* Name */
-
- free(p);
-}
diff --git a/usr.bin/cpio/test/test_gcpio_compat.c b/usr.bin/cpio/test/test_gcpio_compat.c
deleted file mode 100644
index 3d992c488e21..000000000000
--- a/usr.bin/cpio/test/test_gcpio_compat.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-static void
-unpack_test(const char *from, const char *options, const char *se)
-{
- int r;
-
- /* Create a work dir named after the file we're unpacking. */
- assertMakeDir(from, 0775);
- assertChdir(from);
-
- /*
- * Use cpio to unpack the sample archive
- */
- extract_reference_file(from);
- r = systemf("%s -i %s < %s >unpack.out 2>unpack.err",
- testprog, options, from);
- failure("Error invoking %s -i %s < %s",
- testprog, options, from);
- assertEqualInt(r, 0);
-
- /* Verify that nothing went to stderr. */
- if (canSymlink()) {
- failure("Error invoking %s -i %s < %s",
- testprog, options, from);
- assertTextFileContents(se, "unpack.err");
- }
-
- /*
- * Verify unpacked files.
- */
-
- /* Regular file with 2 links. */
- assertIsReg("file", 0644);
- failure("%s", from);
- assertFileSize("file", 10);
- assertFileSize("linkfile", 10);
- failure("%s", from);
- assertFileNLinks("file", 2);
-
- /* Another name for the same file. */
- failure("%s", from);
- assertIsHardlink("linkfile", "file");
- assertFileSize("file", 10);
- assertFileSize("linkfile", 10);
-
- /* Symlink */
- if (canSymlink())
- assertIsSymlink("symlink", "file");
-
- /* dir */
- assertIsDir("dir", 0775);
-
- assertChdir("..");
-}
-
-DEFINE_TEST(test_gcpio_compat)
-{
- assertUmask(0);
-
- /* Dearchive sample files with a variety of options. */
- if (canSymlink()) {
- unpack_test("test_gcpio_compat_ref.bin",
- "--no-preserve-owner", "1 block\n");
- unpack_test("test_gcpio_compat_ref.crc",
- "--no-preserve-owner", "2 blocks\n");
- unpack_test("test_gcpio_compat_ref.newc",
- "--no-preserve-owner", "2 blocks\n");
- /* gcpio-2.9 only reads 6 blocks here */
- unpack_test("test_gcpio_compat_ref.ustar",
- "--no-preserve-owner", "7 blocks\n");
- } else {
- unpack_test("test_gcpio_compat_ref_nosym.bin",
- "--no-preserve-owner", "1 block\n");
- unpack_test("test_gcpio_compat_ref_nosym.crc",
- "--no-preserve-owner", "2 blocks\n");
- unpack_test("test_gcpio_compat_ref_nosym.newc",
- "--no-preserve-owner", "2 blocks\n");
- /* gcpio-2.9 only reads 6 blocks here */
- unpack_test("test_gcpio_compat_ref_nosym.ustar",
- "--no-preserve-owner", "7 blocks\n");
- }
-}
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref.bin.uu b/usr.bin/cpio/test/test_gcpio_compat_ref.bin.uu
deleted file mode 100644
index 745d8ab7851a..000000000000
--- a/usr.bin/cpio/test/test_gcpio_compat_ref.bin.uu
+++ /dev/null
@@ -1,16 +0,0 @@
-$FreeBSD$
-begin 644 test_gcpio_compat_ref.bin
-MQW%9`*IWI('H`^@#`@````U'=YD%````"@!F:6QE```Q,C,T-38W.#D*QW%9
-M`*IWI('H`^@#`@````U'=YD)````"@!L:6YK9FEL90``,3(S-#4V-S@Y"L=Q
-M60"K=^VAZ`/H`P$````-1X29"`````0`<WEM;&EN:P!F:6QEQW%9`*YW_4'H
-M`^@#`@````U'A9D$``````!D:7(`QW$``````````````0`````````+````
-M``!44D%)3$52(2$A````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-1````````````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref.crc.uu b/usr.bin/cpio/test/test_gcpio_compat_ref.crc.uu
deleted file mode 100644
index df8dde05bd82..000000000000
--- a/usr.bin/cpio/test/test_gcpio_compat_ref.crc.uu
+++ /dev/null
@@ -1,27 +0,0 @@
-$FreeBSD$
-begin 644 test_gcpio_compat_ref.crc
-M,#<P-S`R,#`S,S<W86$P,#`P.#%A-#`P,#`P,V4X,#`P,#`S93@P,#`P,#`P
-M,C0W,&0Y.3<W,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4Y,#`P,#`P,#`P,#`P
-M,#`P,#`P,#`P,#`U,#`P,#`P,#!F:6QE```P-S`W,#(P,#,S-S=A83`P,#`X
-M,6$T,#`P,#`S93@P,#`P,#-E.#`P,#`P,#`R-#<P9#DY-S<P,#`P,#`P83`P
-M,#`P,#`P,#`P,#`P-3DP,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#DP,#`P,#%E
-M-VQI;FMF:6QE```Q,C,T-38W.#D*```P-S`W,#(P,#,S-S=A8C`P,#!A,65D
-M,#`P,#`S93@P,#`P,#-E.#`P,#`P,#`Q-#<P9#DY.#0P,#`P,#`P-#`P,#`P
-M,#`P,#`P,#`P-3DP,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#@P,#`P,#`P,'-Y
-M;6QI;FL```!F:6QE,#<P-S`R,#`S,S<W864P,#`P-#%F9#`P,#`P,V4X,#`P
-M,#`S93@P,#`P,#`P,C0W,&0Y.3@U,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4Y
-M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#(P
-M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q,#`P,#`P
-M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
-M,#`P,&(P,#`P,#`P,%1204E,15(A(2$`````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-B````````````````````````````````````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref.newc.uu b/usr.bin/cpio/test/test_gcpio_compat_ref.newc.uu
deleted file mode 100644
index 1e29ba907bb4..000000000000
--- a/usr.bin/cpio/test/test_gcpio_compat_ref.newc.uu
+++ /dev/null
@@ -1,27 +0,0 @@
-$FreeBSD$
-begin 644 test_gcpio_compat_ref.newc
-M,#<P-S`Q,#`S,S<W86$P,#`P.#%A-#`P,#`P,V4X,#`P,#`S93@P,#`P,#`P
-M,C0W,&0Y.3<W,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4Y,#`P,#`P,#`P,#`P
-M,#`P,#`P,#`P,#`U,#`P,#`P,#!F:6QE```P-S`W,#$P,#,S-S=A83`P,#`X
-M,6$T,#`P,#`S93@P,#`P,#-E.#`P,#`P,#`R-#<P9#DY-S<P,#`P,#`P83`P
-M,#`P,#`P,#`P,#`P-3DP,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#DP,#`P,#`P
-M,&QI;FMF:6QE```Q,C,T-38W.#D*```P-S`W,#$P,#,S-S=A8C`P,#!A,65D
-M,#`P,#`S93@P,#`P,#-E.#`P,#`P,#`Q-#<P9#DY.#0P,#`P,#`P-#`P,#`P
-M,#`P,#`P,#`P-3DP,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#@P,#`P,#`P,'-Y
-M;6QI;FL```!F:6QE,#<P-S`Q,#`S,S<W864P,#`P-#%F9#`P,#`P,V4X,#`P
-M,#`S93@P,#`P,#`P,C0W,&0Y.3@U,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4Y
-M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#$P
-M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q,#`P,#`P
-M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
-M,#`P,&(P,#`P,#`P,%1204E,15(A(2$`````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-B````````````````````````````````````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref.ustar.uu b/usr.bin/cpio/test/test_gcpio_compat_ref.ustar.uu
deleted file mode 100644
index 77989f4aed06..000000000000
--- a/usr.bin/cpio/test/test_gcpio_compat_ref.ustar.uu
+++ /dev/null
@@ -1,84 +0,0 @@
-$FreeBSD$
-begin 644 test_gcpio_compat_ref.ustar
-M9FEL90``````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````#`P,#`V-#0`,#`P,3<U,``P,#`Q-S4P`#`P,#`P,#`P,#$R
-M`#$P-S`S,S$T-38W`#`P,3$S-C,`,```````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````!U<W1A<@`P,'1I;0``
-M````````````````````````````````````=&EM````````````````````
-M```````````````````P,#`P,#`P`#`P,#`P,#``````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````Q,C,T-38W.#D*````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````&QI;FMF:6QE````
-M````````````````````````````````````````````````````````````
-M```````````````````````````````````````````````````````````P
-M,#`P-C0T`#`P,#$W-3``,#`P,3<U,``P,#`P,#`P,#`P,``Q,#<P,S,Q-#4V
-M-P`P,#$S,#<W`#%F:6QE````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````=7-T87(`,#!T:6T`````````````````
-M`````````````````````'1I;0``````````````````````````````````
-M````,#`P,#`P,``P,#`P,#`P````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````<WEM;&EN:P``````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````#`P,#`W-34`,#`P,3<U,``P,#`Q-S4P`#`P,#`P
-M,#`P,#`P`#$P-S`S,S$T-C`T`#`P,3(W-C0`,F9I;&4`````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````!U<W1A<@`P
-M,'1I;0``````````````````````````````````````=&EM````````````
-M```````````````````````````P,#`P,#`P`#`P,#`P,#``````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````!D:7(O````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````,#`P,#<W-0`P,#`Q
-M-S4P`#`P,#$W-3``,#`P,#`P,#`P,#``,3`W,#,S,30V,#4`,#`Q,3,P,0`U
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````'5S=&%R`#`P=&EM````````````````````````````````
-M``````!T:6T``````````````````````````````````````#`P,#`P,#``
-M,#`P,#`P,```````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-=````````````````````````````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu
deleted file mode 100644
index 7a2a272394f3..000000000000
--- a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu
+++ /dev/null
@@ -1,17 +0,0 @@
-$FreeBSD$
-
-begin 644 test_gcpio_compat_ref_nosym.bin
-MQW%4`-[Z_4'H`^@#`@`VNZU*NQX$``````!D:7(`QW%4`-SZI('H`^@#`@`G
-MNZU*NQX%````"@!F:6QE```Q,C,T-38W.#D*QW%4`-SZI('H`^@#`@`GNZU*
-MNQX)````"@!L:6YK9FEL90``,3(S-#4V-S@Y"L=Q``````````````$`````
-M````"P``````5%)!24Q%4B$A(0``````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-1````````````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu
deleted file mode 100644
index 0147df7355fb..000000000000
--- a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu
+++ /dev/null
@@ -1,17 +0,0 @@
-$FreeBSD$
-
-begin 644 test_gcpio_compat_ref_nosym.crc
-M,#<P-S`R,#`U-D9!1$4P,#`P-#%&1#`P,#`P,T4X,#`P,#`S13@P,#`P,#`P
-M,C1!040Q14)",#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4T,#`P,#`P0D(P,35"
-M,#`S-C`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#(P,#4V1D%$0S`P,#`X
-M,4$T,#`P,#`S13@P,#`P,#-%.#`P,#`P,#`R-$%!1#%%0D(P,#`P,#`P,#`P
-M,#`P,#`P,#`P,#`P-30P,#`P,#!"0C`Q-4(P,#(W,#`P,#`P,#4P,#`P,#`P
-M,&9I;&4``#`W,#<P,C`P-39&041#,#`P,#@Q030P,#`P,#-%.#`P,#`P,T4X
-M,#`P,#`P,#(T04%$,45"0C`P,#`P,#!!,#`P,#`P,#`P,#`P,#`U-#`P,#`P
-M,$)",#$U0C`P,C<P,#`P,#`P.3`P,#`P,44W;&EN:V9I;&4``#$R,S0U-C<X
-M.0H``#`W,#<P,C`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
-M,#`P,#$P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
-M,#`P,#`P,#`P,#`P,#`P0C`P,#`P,#`P5%)!24Q%4B$A(0``````````````
-1````````````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu
deleted file mode 100644
index e2a49003e396..000000000000
--- a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu
+++ /dev/null
@@ -1,17 +0,0 @@
-$FreeBSD$
-
-begin 644 test_gcpio_compat_ref_nosym.newc
-M,#<P-S`Q,#`U-D9!1$4P,#`P-#%&1#`P,#`P,T4X,#`P,#`S13@P,#`P,#`P
-M,C1!040Q14)",#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4T,#`P,#`P0D(P,35"
-M,#`S-C`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#$P,#4V1D%$0S`P,#`X
-M,4$T,#`P,#`S13@P,#`P,#-%.#`P,#`P,#`R-$%!1#%%0D(P,#`P,#`P,#`P
-M,#`P,#`P,#`P,#`P-30P,#`P,#!"0C`Q-4(P,#(W,#`P,#`P,#4P,#`P,#`P
-M,&9I;&4``#`W,#<P,3`P-39&041#,#`P,#@Q030P,#`P,#-%.#`P,#`P,T4X
-M,#`P,#`P,#(T04%$,45"0C`P,#`P,#!!,#`P,#`P,#`P,#`P,#`U-#`P,#`P
-M,$)",#$U0C`P,C<P,#`P,#`P.3`P,#`P,#`P;&EN:V9I;&4``#$R,S0U-C<X
-M.0H``#`W,#<P,3`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
-M,#`P,#$P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
-M,#`P,#`P,#`P,#`P,#`P0C`P,#`P,#`P5%)!24Q%4B$A(0``````````````
-1````````````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu
deleted file mode 100644
index b5cbd6689a7d..000000000000
--- a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu
+++ /dev/null
@@ -1,74 +0,0 @@
-$FreeBSD$
-
-begin 644 test_gcpio_compat_ref_nosym.ustar
-M9&ER+P``````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````#`P,#`W-S4`,#`P,3<U,``P,#`Q-S4P`#`P,#`P,#`P,#`P
-M`#$Q,C4S,C$W,C<S`#`P,3$S-3$`-0``````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````!U<W1A<@`P,'1I;0``
-M````````````````````````````````````=&EM````````````````````
-M```````````````````P,#`P,C<S`#8V,#`P-C8`````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````!F:6QE````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````,#`P,#8T-``P,#`Q-S4P`#`P
-M,#$W-3``,#`P,#`P,#`P,3(`,3$R-3,R,3<R-S,`,#`Q,30R,P`P````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````'5S=&%R`#`P=&EM``````````````````````````````````````!T
-M:6T``````````````````````````````````````#`P,#`R-S,`-C8P,#`T
-M-P``````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````#$R,S0U-C<X.0H`
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````;&EN:V9I;&4`````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````#`P,#`V-#0`,#`P,3<U,``P,#`Q-S4P`#`P,#`P
-M,#`P,#`P`#$Q,C4S,C$W,C<S`#`P,3,Q,S<`,69I;&4`````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````!U<W1A<@`P
-M,'1I;0``````````````````````````````````````=&EM````````````
-M```````````````````````````P,#`P,C<S`#8V,#`P-#<`````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-,````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_option_B_upper.c b/usr.bin/cpio/test/test_option_B_upper.c
deleted file mode 100644
index b040354b6053..000000000000
--- a/usr.bin/cpio/test/test_option_B_upper.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_B_upper)
-{
- struct stat st;
- int r;
-
- /*
- * Create a file on disk.
- */
- assertMakeFile("file", 0644, NULL);
-
- /* Create an archive without -B; this should be 512 bytes. */
- r = systemf("echo file | %s -o > small.cpio 2>small.err", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "small.err");
- assertEqualInt(0, stat("small.cpio", &st));
- assertEqualInt(512, st.st_size);
-
- /* Create an archive with -B; this should be 5120 bytes. */
- r = systemf("echo file | %s -oB > large.cpio 2>large.err", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "large.err");
- assertEqualInt(0, stat("large.cpio", &st));
- assertEqualInt(5120, st.st_size);
-}
diff --git a/usr.bin/cpio/test/test_option_C_upper.c b/usr.bin/cpio/test/test_option_C_upper.c
deleted file mode 100644
index c8e63fd34fb5..000000000000
--- a/usr.bin/cpio/test/test_option_C_upper.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_C_upper)
-{
- int r;
-
- /*
- * Create a file on disk.
- */
- assertMakeFile("file", 0644, NULL);
-
- /* Create an archive without -C; this should be 512 bytes. */
- r = systemf("echo file | %s -o > small.cpio 2>small.err", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "small.err");
- assertFileSize("small.cpio", 512);
-
- /* Create an archive with -C 513; this should be 513 bytes. */
- r = systemf("echo file | %s -o -C 513 > 513.cpio 2>513.err",
- testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "513.err");
- assertFileSize("513.cpio", 513);
-
- /* Create an archive with -C 12345; this should be 12345 bytes. */
- r = systemf("echo file | %s -o -C12345 > 12345.cpio 2>12345.err",
- testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "12345.err");
- assertFileSize("12345.cpio", 12345);
-
- /* Create an archive with invalid -C request */
- assert(0 != systemf("echo file | %s -o -C > bad.cpio 2>bad.err",
- testprog));
- assertEmptyFile("bad.cpio");
-}
diff --git a/usr.bin/cpio/test/test_option_J_upper.c b/usr.bin/cpio/test/test_option_J_upper.c
deleted file mode 100644
index 532aacf39cc2..000000000000
--- a/usr.bin/cpio/test/test_option_J_upper.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * 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_J_upper)
-{
- char *p;
- int r;
- size_t s;
-
- /* Create a file. */
- assertMakeFile("f", 0644, "a");
-
- /* Archive it with xz compression. */
- r = systemf("echo f | %s -o -J >archive.out 2>archive.err",
- testprog);
- p = slurpfile(&s, "archive.err");
- p[s] = '\0';
- if (r != 0) {
- if (strstr(p, "compression not available") != NULL) {
- skipping("This version of bsdcpio was compiled "
- "without xz support");
- return;
- }
- failure("-J option is broken");
- assertEqualInt(r, 0);
- return;
- }
- /* Check that the archive file has an xz signature. */
- p = slurpfile(&s, "archive.out");
- assert(s > 2);
- assertEqualMem(p, "\3757zXZ", 5);
-}
diff --git a/usr.bin/cpio/test/test_option_L_upper.c b/usr.bin/cpio/test/test_option_L_upper.c
deleted file mode 100644
index 0acc100ec5d1..000000000000
--- a/usr.bin/cpio/test/test_option_L_upper.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/* This is a little pointless, as Windows doesn't support symlinks
- * (except for the seriously crippled CreateSymbolicLink API) so these
- * tests won't run on Windows. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define CAT "type"
-#else
-#define CAT "cat"
-#endif
-
-DEFINE_TEST(test_option_L_upper)
-{
- FILE *filelist;
- int r;
-
- if (!canSymlink()) {
- skipping("Symlink tests");
- return;
- }
-
- filelist = fopen("filelist", "w");
-
- /* Create a file and a symlink to the file. */
- assertMakeFile("file", 0644, "1234567890");
- fprintf(filelist, "file\n");
-
- /* Symlink to above file. */
- assertMakeSymlink("symlink", "file");
- fprintf(filelist, "symlink\n");
-
- fclose(filelist);
-
- r = systemf(CAT " filelist | %s -pd copy >copy.out 2>copy.err", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "copy.err");
-
- failure("Regular -p without -L should preserve symlinks.");
- assertIsSymlink("copy/symlink", NULL);
-
- r = systemf(CAT " filelist | %s -pd -L copy-L >copy-L.out 2>copy-L.err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("copy-L.out");
- assertTextFileContents("1 block\n", "copy-L.err");
- failure("-pdL should dereference symlinks and turn them into files.");
- assertIsReg("copy-L/symlink", -1);
-
- r = systemf(CAT " filelist | %s -o >archive.out 2>archive.err", testprog);
- failure("Error invoking %s -o ", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "archive.err");
-
- assertMakeDir("unpack", 0755);
- assertChdir("unpack");
- r = systemf(CAT " ../archive.out | %s -i >unpack.out 2>unpack.err", testprog);
- failure("Error invoking %s -i", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "unpack.err");
- assertChdir("..");
-
- assertIsSymlink("unpack/symlink", NULL);
-
- r = systemf(CAT " filelist | %s -oL >archive-L.out 2>archive-L.err", testprog);
- failure("Error invoking %s -oL", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "archive-L.err");
-
- assertMakeDir("unpack-L", 0755);
- assertChdir("unpack-L");
- r = systemf(CAT " ../archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog);
- failure("Error invoking %s -i < archive-L.out", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "unpack-L.err");
- assertChdir("..");
- assertIsReg("unpack-L/symlink", -1);
-}
diff --git a/usr.bin/cpio/test/test_option_Z_upper.c b/usr.bin/cpio/test/test_option_Z_upper.c
deleted file mode 100644
index 936ce0c2d3e6..000000000000
--- a/usr.bin/cpio/test/test_option_Z_upper.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * 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_Z_upper)
-{
- char *p;
- int r;
- size_t s;
-
- /* Create a file. */
- assertMakeFile("f", 0644, "a");
-
- /* Archive it with compress compression. */
- r = systemf("echo f | %s -oZ >archive.out 2>archive.err",
- testprog);
- p = slurpfile(&s, "archive.err");
- p[s] = '\0';
- if (r != 0) {
- if (strstr(p, "compression not available") != NULL) {
- skipping("This version of bsdcpio was compiled "
- "without compress support");
- return;
- }
- failure("-Z option is broken");
- assertEqualInt(r, 0);
- return;
- }
- /* Check that the archive file has a compress signature. */
- p = slurpfile(&s, "archive.out");
- assert(s > 2);
- assertEqualMem(p, "\x1f\x9d", 2);
-}
diff --git a/usr.bin/cpio/test/test_option_a.c b/usr.bin/cpio/test/test_option_a.c
deleted file mode 100644
index af4b48e577d5..000000000000
--- a/usr.bin/cpio/test/test_option_a.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*-
- * Copyright (c) 2003-2008 Tim Kientzle
- * 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"
-#if defined(HAVE_UTIME_H)
-#include <utime.h>
-#elif defined(HAVE_SYS_UTIME_H)
-#include <sys/utime.h>
-#endif
-__FBSDID("$FreeBSD$");
-
-static struct {
- const char *name;
- time_t atime_sec;
-} files[] = {
- { "f0", 0 },
- { "f1", 0 },
- { "f2", 0 },
- { "f3", 0 },
- { "f4", 0 },
- { "f5", 0 }
-};
-
-/*
- * Create a bunch of test files and record their atimes.
- * For the atime preserve/change tests, the files must have
- * atimes in the past. We can accomplish this by explicitly invoking
- * utime() on platforms that support it or by simply sleeping
- * for a second after creating the files. (Creating all of the files
- * at once means we only need to sleep once.)
- */
-static void
-test_create(void)
-{
- struct stat st;
- struct utimbuf times;
- static const int numfiles = sizeof(files) / sizeof(files[0]);
- int i;
-
- for (i = 0; i < numfiles; ++i) {
- /*
- * Note: Have to write at least one byte to the file.
- * cpio doesn't bother reading the file if it's zero length,
- * so the atime never gets changed in that case, which
- * makes the tests below rather pointless.
- */
- assertMakeFile(files[i].name, 0644, "a");
-
- /* If utime() isn't supported on your platform, just
- * #ifdef this section out. Most of the test below is
- * still valid. */
- memset(&times, 0, sizeof(times));
- times.actime = 1;
- times.modtime = 3;
- assertEqualInt(0, utime(files[i].name, &times));
-
- /* Record whatever atime the file ended up with. */
- /* If utime() is available, this should be 1, but there's
- * no harm in being careful. */
- assertEqualInt(0, stat(files[i].name, &st));
- files[i].atime_sec = st.st_atime;
- }
-
- /* Wait until the atime on the last file is actually in the past. */
- sleepUntilAfter(files[numfiles - 1].atime_sec);
-}
-
-DEFINE_TEST(test_option_a)
-{
- struct stat st;
- int r;
- char *p;
-
- /* Create all of the test files. */
- test_create();
-
- /* Sanity check; verify that atimes really do get modified. */
- assert((p = slurpfile(NULL, "f0")) != NULL);
- free(p);
- assertEqualInt(0, stat("f0", &st));
- if (st.st_atime == files[0].atime_sec) {
- skipping("Cannot verify -a option\n"
- " Your system appears to not support atime.");
- }
- else
- {
- /*
- * If this disk is mounted noatime, then we can't
- * verify correct operation without -a.
- */
-
- /* Copy the file without -a; should change the atime. */
- r = systemf("echo %s | %s -pd copy-no-a > copy-no-a.out 2>copy-no-a.err", files[1].name, testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "copy-no-a.err");
- assertEmptyFile("copy-no-a.out");
- assertEqualInt(0, stat(files[1].name, &st));
- failure("Copying file without -a should have changed atime.");
- assert(st.st_atime != files[1].atime_sec);
-
- /* Archive the file without -a; should change the atime. */
- r = systemf("echo %s | %s -o > archive-no-a.out 2>archive-no-a.err", files[2].name, testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "copy-no-a.err");
- assertEqualInt(0, stat(files[2].name, &st));
- failure("Archiving file without -a should have changed atime.");
- assert(st.st_atime != files[2].atime_sec);
- }
-
- /*
- * We can, of course, still verify that the atime is unchanged
- * when using the -a option.
- */
-
- /* Copy the file with -a; should not change the atime. */
- r = systemf("echo %s | %s -pad copy-a > copy-a.out 2>copy-a.err",
- files[3].name, testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "copy-a.err");
- assertEmptyFile("copy-a.out");
- assertEqualInt(0, stat(files[3].name, &st));
- failure("Copying file with -a should not have changed atime.");
- assertEqualInt(st.st_atime, files[3].atime_sec);
-
- /* Archive the file with -a; should not change the atime. */
- r = systemf("echo %s | %s -oa > archive-a.out 2>archive-a.err",
- files[4].name, testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "copy-a.err");
- assertEqualInt(0, stat(files[4].name, &st));
- failure("Archiving file with -a should not have changed atime.");
- assertEqualInt(st.st_atime, files[4].atime_sec);
-}
diff --git a/usr.bin/cpio/test/test_option_c.c b/usr.bin/cpio/test/test_option_c.c
deleted file mode 100644
index 241bcf67bb15..000000000000
--- a/usr.bin/cpio/test/test_option_c.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-static int
-is_octal(const char *p, size_t l)
-{
- while (l > 0) {
- if (*p < '0' || *p > '7')
- return (0);
- --l;
- ++p;
- }
- return (1);
-}
-
-static int
-from_octal(const char *p, size_t l)
-{
- int r = 0;
-
- while (l > 0) {
- r *= 8;
- r += *p - '0';
- --l;
- ++p;
- }
- return (r);
-}
-
-DEFINE_TEST(test_option_c)
-{
- FILE *filelist;
- int r;
- int uid = -1;
- int dev, ino, gid;
- time_t t, now;
- char *p, *e;
- size_t s;
-
- assertUmask(0);
-
-#if !defined(_WIN32)
- uid = getuid();
-#endif
-
- /*
- * Create an assortment of files.
- * TODO: Extend this to cover more filetypes.
- */
- filelist = fopen("filelist", "w");
-
- /* "file" */
- assertMakeFile("file", 0644, "1234567890");
- fprintf(filelist, "file\n");
-
- /* "symlink" */
- if (canSymlink()) {
- assertMakeSymlink("symlink", "file");
- fprintf(filelist, "symlink\n");
- }
-
- /* "dir" */
- assertMakeDir("dir", 0775);
- /* Record some facts about what we just created: */
- now = time(NULL); /* They were all created w/in last two seconds. */
- fprintf(filelist, "dir\n");
-
- /* Use the cpio program to create an archive. */
- fclose(filelist);
- r = systemf("%s -oc <filelist >basic.out 2>basic.err", testprog);
- /* Verify that nothing went to stderr. */
- assertTextFileContents("1 block\n", "basic.err");
-
- /* Assert that the program finished. */
- failure("%s -oc crashed", testprog);
- if (!assertEqualInt(r, 0))
- return;
-
- /* Verify that stdout is a well-formed cpio file in "odc" format. */
- p = slurpfile(&s, "basic.out");
- assertEqualInt(s, 512);
- e = p;
-
- /*
- * Some of these assertions could be stronger, but it's
- * a little tricky because they depend on the local environment.
- */
-
- /* First entry is "file" */
- assert(is_octal(e, 76)); /* Entire header is octal digits. */
- assertEqualMem(e + 0, "070707", 6); /* Magic */
- assert(is_octal(e + 6, 6)); /* dev */
- dev = from_octal(e + 6, 6);
- assert(is_octal(e + 12, 6)); /* ino */
- ino = from_octal(e + 12, 6);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Group members bits and others bits do not work. */
- assertEqualMem(e + 18, "100666", 6); /* Mode */
-#else
- assertEqualMem(e + 18, "100644", 6); /* Mode */
-#endif
- if (uid < 0)
- uid = from_octal(e + 24, 6);
- assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
- assert(is_octal(e + 30, 6)); /* gid */
- gid = from_octal(e + 30, 6);
- assertEqualMem(e + 36, "000001", 6); /* nlink */
- failure("file entries should not have rdev set (dev field was 0%o)",
- dev);
- assertEqualMem(e + 42, "000000", 6); /* rdev */
- t = from_octal(e + 48, 11); /* mtime */
- assert(t <= now); /* File wasn't created in future. */
- assert(t >= now - 2); /* File was created w/in last 2 secs. */
- assertEqualMem(e + 59, "000005", 6); /* Name size */
- assertEqualMem(e + 65, "00000000012", 11); /* File size */
- assertEqualMem(e + 76, "file\0", 5); /* Name contents */
- assertEqualMem(e + 81, "1234567890", 10); /* File contents */
- e += 91;
-
- /* "symlink" pointing to "file" */
- if (canSymlink()) {
- assert(is_octal(e, 76)); /* Entire header is octal digits. */
- assertEqualMem(e + 0, "070707", 6); /* Magic */
- assertEqualInt(dev, from_octal(e + 6, 6)); /* dev */
- assert(ino != from_octal(e + 12, 6)); /* ino */
-#if !defined(_WIN32) || defined(__CYGWIN__)
- /* On Windows, symbolic link and group members bits and
- * others bits do not work. */
- assertEqualMem(e + 18, "120777", 6); /* Mode */
-#endif
- assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
- assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */
- assertEqualMem(e + 36, "000001", 6); /* nlink */
- failure("file entries should have rdev == 0 (dev was 0%o)",
- from_octal(e + 6, 6));
- assertEqualMem(e + 42, "000000", 6); /* rdev */
- t = from_octal(e + 48, 11); /* mtime */
- assert(t <= now); /* File wasn't created in future. */
- assert(t >= now - 2); /* File was created w/in last 2 secs. */
- assertEqualMem(e + 59, "000010", 6); /* Name size */
- assertEqualMem(e + 65, "00000000004", 11); /* File size */
- assertEqualMem(e + 76, "symlink\0", 8); /* Name contents */
- assertEqualMem(e + 84, "file", 4); /* Symlink target. */
- e += 88;
- }
-
- /* "dir" */
- assert(is_octal(e, 76));
- assertEqualMem(e + 0, "070707", 6); /* Magic */
- /* Dev should be same as first entry. */
- assert(is_octal(e + 6, 6)); /* dev */
- assertEqualInt(dev, from_octal(e + 6, 6));
- /* Ino must be different from first entry. */
- assert(is_octal(e + 12, 6)); /* ino */
- assert(dev != from_octal(e + 12, 6));
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Group members bits and others bits do not work. */
- assertEqualMem(e + 18, "040777", 6); /* Mode */
-#else
- /* Accept 042775 to accomodate systems where sgid bit propagates. */
- if (memcmp(e + 18, "042775", 6) != 0)
- assertEqualMem(e + 18, "040775", 6); /* Mode */
-#endif
- assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
- /* Gid should be same as first entry. */
- assert(is_octal(e + 30, 6)); /* gid */
- assertEqualInt(gid, from_octal(e + 30, 6));
-#ifndef NLINKS_INACCURATE_FOR_DIRS
- assertEqualMem(e + 36, "000002", 6); /* Nlink */
-#endif
- t = from_octal(e + 48, 11); /* mtime */
- assert(t <= now); /* File wasn't created in future. */
- assert(t >= now - 2); /* File was created w/in last 2 secs. */
- assertEqualMem(e + 59, "000004", 6); /* Name size */
- assertEqualMem(e + 65, "00000000000", 11); /* File size */
- assertEqualMem(e + 76, "dir\0", 4); /* name */
- e += 80;
-
- /* TODO: Verify other types of entries. */
-
- /* Last entry is end-of-archive marker. */
- assert(is_octal(e, 76));
- assertEqualMem(e + 0, "070707", 6); /* Magic */
- assertEqualMem(e + 6, "000000", 6); /* dev */
- assertEqualMem(e + 12, "000000", 6); /* ino */
- assertEqualMem(e + 18, "000000", 6); /* Mode */
- assertEqualMem(e + 24, "000000", 6); /* uid */
- assertEqualMem(e + 30, "000000", 6); /* gid */
- assertEqualMem(e + 36, "000001", 6); /* Nlink */
- assertEqualMem(e + 42, "000000", 6); /* rdev */
- assertEqualMem(e + 48, "00000000000", 11); /* mtime */
- assertEqualMem(e + 59, "000013", 6); /* Name size */
- assertEqualMem(e + 65, "00000000000", 11); /* File size */
- assertEqualMem(e + 76, "TRAILER!!!\0", 11); /* Name */
-
- free(p);
-}
diff --git a/usr.bin/cpio/test/test_option_d.c b/usr.bin/cpio/test/test_option_d.c
deleted file mode 100644
index 9ff14539698f..000000000000
--- a/usr.bin/cpio/test/test_option_d.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_d)
-{
- int r;
-
- /*
- * Create a file in a directory.
- */
- assertMakeDir("dir", 0755);
- assertMakeFile("dir/file", 0644, NULL);
-
- /* Create an archive. */
- r = systemf("echo dir/file | %s -o > archive.cpio 2>archive.err", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "archive.err");
- assertFileSize("archive.cpio", 512);
-
- /* Dearchive without -d, this should fail. */
- assertMakeDir("without-d", 0755);
- assertChdir("without-d");
- r = systemf("%s -i < ../archive.cpio >out 2>err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("out");
- /* And the file should not be restored. */
- assertFileNotExists("dir/file");
-
- /* Dearchive with -d, this should succeed. */
- assertChdir("..");
- assertMakeDir("with-d", 0755);
- assertChdir("with-d");
- r = systemf("%s -id < ../archive.cpio >out 2>err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("out");
- assertTextFileContents("1 block\n", "err");
- /* And the file should be restored. */
- assertFileExists("dir/file");
-}
diff --git a/usr.bin/cpio/test/test_option_f.c b/usr.bin/cpio/test/test_option_f.c
deleted file mode 100644
index 784e0858431b..000000000000
--- a/usr.bin/cpio/test/test_option_f.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * Unpack the archive in a new dir.
- */
-static void
-unpack(const char *dirname, const char *option)
-{
- int r;
-
- assertMakeDir(dirname, 0755);
- assertChdir(dirname);
- extract_reference_file("test_option_f.cpio");
- r = systemf("%s -i %s < test_option_f.cpio > copy-no-a.out 2>copy-no-a.err", testprog, option);
- assertEqualInt(0, r);
- assertChdir("..");
-}
-
-DEFINE_TEST(test_option_f)
-{
- /* Calibrate: No -f option, so everything should be extracted. */
- unpack("t0", "--no-preserve-owner");
- assertFileExists("t0/a123");
- assertFileExists("t0/a234");
- assertFileExists("t0/b123");
- assertFileExists("t0/b234");
-
- /* Don't extract 'a*' files. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Single quotes isn't used by command.exe. */
- unpack("t1", "--no-preserve-owner -f a*");
-#else
- unpack("t1", "--no-preserve-owner -f 'a*'");
-#endif
- assertFileNotExists("t1/a123");
- assertFileNotExists("t1/a234");
- assertFileExists("t1/b123");
- assertFileExists("t1/b234");
-
- /* Don't extract 'b*' files. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Single quotes isn't used by command.exe. */
- unpack("t2", "--no-preserve-owner -f b*");
-#else
- unpack("t2", "--no-preserve-owner -f 'b*'");
-#endif
- assertFileExists("t2/a123");
- assertFileExists("t2/a234");
- assertFileNotExists("t2/b123");
- assertFileNotExists("t2/b234");
-}
diff --git a/usr.bin/cpio/test/test_option_f.cpio.uu b/usr.bin/cpio/test/test_option_f.cpio.uu
deleted file mode 100644
index 42c63c39685e..000000000000
--- a/usr.bin/cpio/test/test_option_f.cpio.uu
+++ /dev/null
@@ -1,16 +0,0 @@
-$FreeBSD$
-begin 644 test_option_f.cpio
-M,#<P-S`W,#`P,3,Q-C(Q-38Q,3`P-C0T,#`Q-S4P,#`Q-S4P,#`P,#`Q,#`P
-M,#`P,3`W,S4Q,3(U,C8P,#`P,#4P,#`P,#`P,#`P,&$Q,C,`,#<P-S`W,#`P
-M,3,Q-C(Q-38S,3`P-C0T,#`Q-S4P,#`Q-S4P,#`P,#`Q,#`P,#`P,3`W,S4Q
-M,3(U-#`P,#`P,#4P,#`P,#`P,#`P,&$R,S0`,#<P-S`W,#`P,3,Q-C(Q-38R
-M,3`P-C0T,#`Q-S4P,#`Q-S4P,#`P,#`Q,#`P,#`P,3`W,S4Q,3(U,S0P,#`P
-M,#4P,#`P,#`P,#`P,&(Q,C,`,#<P-S`W,#`P,3,Q-C(Q-38T,3`P-C0T,#`Q
-M-S4P,#`Q-S4P,#`P,#`Q,#`P,#`P,3`W,S4Q,3(U-#,P,#`P,#4P,#`P,#`P
-M,#`P,&(R,S0`,#<P-S`W,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
-M,#`P,#`Q,#`P,#`P,#`P,#`P,#`P,#`P,#`P,3,P,#`P,#`P,#`P,%1204E,
-M15(A(2$`````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-1````````````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_option_help.c b/usr.bin/cpio/test/test_option_help.c
deleted file mode 100644
index 56234306f539..000000000000
--- a/usr.bin/cpio/test/test_option_help.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * Test that "--help", "-h", and "-W help" options all work and
- * generate reasonable output.
- */
-
-static int
-in_first_line(const char *p, const char *substring)
-{
- size_t l = strlen(substring);
-
- while (*p != '\0' && *p != '\n') {
- if (memcmp(p, substring, l) == 0)
- return (1);
- ++p;
- }
- return (0);
-}
-
-DEFINE_TEST(test_option_help)
-{
- int r;
- char *p;
- size_t plen;
-
- /* Exercise --help option. */
- r = systemf("%s --help >help.stdout 2>help.stderr", testprog);
- assertEqualInt(r, 0);
- failure("--help should generate nothing to stderr.");
- assertEmptyFile("help.stderr");
- /* Help message should start with name of program. */
- p = slurpfile(&plen, "help.stdout");
- failure("Help output should be long enough.");
- assert(plen >= 7);
- failure("First line of help output should contain string 'bsdcpio'");
- assert(in_first_line(p, "bsdcpio"));
- /*
- * TODO: Extend this check to further verify that --help output
- * looks approximately right.
- */
- free(p);
-
- /* -h option should generate the same output. */
- r = systemf("%s -h >h.stdout 2>h.stderr", testprog);
- assertEqualInt(r, 0);
- failure("-h should generate nothing to stderr.");
- assertEmptyFile("h.stderr");
- failure("stdout should be same for -h and --help");
- assertEqualFile("h.stdout", "help.stdout");
-
- /* -W help should be another synonym. */
- r = systemf("%s -W help >Whelp.stdout 2>Whelp.stderr", testprog);
- assertEqualInt(r, 0);
- failure("-W help should generate nothing to stderr.");
- assertEmptyFile("Whelp.stderr");
- failure("stdout should be same for -W help and --help");
- assertEqualFile("Whelp.stdout", "help.stdout");
-}
diff --git a/usr.bin/cpio/test/test_option_l.c b/usr.bin/cpio/test/test_option_l.c
deleted file mode 100644
index 5c76e688e6e9..000000000000
--- a/usr.bin/cpio/test/test_option_l.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_l)
-{
- int r;
-
- /* Create a file. */
- assertMakeFile("f", 0644, "a");
-
- /* Copy the file to the "copy" dir. */
- r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
- testprog);
- assertEqualInt(r, 0);
-
- /* Check that the copy is a true copy and not a link. */
- assertIsNotHardlink("f", "copy/f");
-
- /* Copy the file to the "link" dir with the -l option. */
- r = systemf("echo f | %s -pld link >link.out 2>link.err",
- testprog);
- assertEqualInt(r, 0);
-
- /* Check that this is a link and not a copy. */
- assertIsHardlink("f", "link/f");
-}
diff --git a/usr.bin/cpio/test/test_option_lzma.c b/usr.bin/cpio/test/test_option_lzma.c
deleted file mode 100644
index c6e335301505..000000000000
--- a/usr.bin/cpio/test/test_option_lzma.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_lzma)
-{
- char *p;
- int r;
- size_t s;
-
- /* Create a file. */
- assertMakeFile("f", 0644, "a");
-
- /* Archive it with lzma compression. */
- r = systemf("echo f | %s -o --lzma >archive.out 2>archive.err",
- testprog);
- p = slurpfile(&s, "archive.err");
- p[s] = '\0';
- if (r != 0) {
- if (strstr(p, "compression not available") != NULL) {
- skipping("This version of bsdcpio was compiled "
- "without lzma support");
- return;
- }
- failure("--lzma option is broken");
- assertEqualInt(r, 0);
- return;
- }
- /* Check that the archive file has an lzma signature. */
- p = slurpfile(&s, "archive.out");
- assert(s > 2);
- assertEqualMem(p, "\x5d\00\00", 3);
-}
diff --git a/usr.bin/cpio/test/test_option_m.c b/usr.bin/cpio/test/test_option_m.c
deleted file mode 100644
index de880b2883e1..000000000000
--- a/usr.bin/cpio/test/test_option_m.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_m)
-{
- int r;
-
- /*
- * The reference archive has one file with an mtime in 1970, 1
- * second after the start of the epoch.
- */
-
- /* Restored without -m, the result should have a current mtime. */
- assertMakeDir("without-m", 0755);
- assertChdir("without-m");
- extract_reference_file("test_option_m.cpio");
- r = systemf("%s --no-preserve-owner -i < test_option_m.cpio >out 2>err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("out");
- assertTextFileContents("1 block\n", "err");
- /* Should have been created within the last few seconds. */
- assertFileMtimeRecent("file");
-
- /* With -m, it should have an mtime in 1970. */
- assertChdir("..");
- assertMakeDir("with-m", 0755);
- assertChdir("with-m");
- extract_reference_file("test_option_m.cpio");
- r = systemf("%s --no-preserve-owner -im < test_option_m.cpio >out 2>err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("out");
- assertTextFileContents("1 block\n", "err");
- /*
- * mtime in reference archive is '1' == 1 second after
- * midnight Jan 1, 1970 UTC.
- */
- assertFileMtime("file", 1, 0);
-}
diff --git a/usr.bin/cpio/test/test_option_m.cpio.uu b/usr.bin/cpio/test/test_option_m.cpio.uu
deleted file mode 100644
index 3d2002355e55..000000000000
--- a/usr.bin/cpio/test/test_option_m.cpio.uu
+++ /dev/null
@@ -1,16 +0,0 @@
-$FreeBSD$
-begin 644 test_option_m.cpio
-M,#<P-S`W,#`P,3,Q-#4P,#8T,3`P-C0T,#`Q-S4P,#`Q-S4P,#`P,#`Q,#`P
-M,#`P,#`P,#`P,#`P,#$P,#`P,#4P,#`P,#`P,#`P,&9I;&4`,#<P-S`W,#`P
-M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q,#`P,#`P,#`P,#`P
-M,#`P,#`P,#`P,3,P,#`P,#`P,#`P,%1204E,15(A(2$`````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-1````````````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_option_t.c b/usr.bin/cpio/test/test_option_t.c
deleted file mode 100644
index 4427bb3a6cd7..000000000000
--- a/usr.bin/cpio/test/test_option_t.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_t)
-{
- char *p;
- int r;
-
- /* List reference archive, make sure the TOC is correct. */
- extract_reference_file("test_option_t.cpio");
- r = systemf("%s -it < test_option_t.cpio >it.out 2>it.err", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "it.err");
- extract_reference_file("test_option_t.stdout");
- p = slurpfile(NULL, "test_option_t.stdout");
- assertTextFileContents(p, "it.out");
- free(p);
-
- /* We accept plain "-t" as a synonym for "-it" */
- r = systemf("%s -t < test_option_t.cpio >t.out 2>t.err", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "t.err");
- extract_reference_file("test_option_t.stdout");
- p = slurpfile(NULL, "test_option_t.stdout");
- assertTextFileContents(p, "t.out");
- free(p);
-
- /* But "-ot" is an error. */
- assert(0 != systemf("%s -ot < test_option_t.cpio >ot.out 2>ot.err",
- testprog));
- assertEmptyFile("ot.out");
-
- /* List reference archive verbosely, make sure the TOC is correct. */
- r = systemf("%s -itv < test_option_t.cpio >tv.out 2>tv.err", testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "tv.err");
- extract_reference_file("test_option_tv.stdout");
-
- /* This doesn't work because the usernames on different systems
- * are different and cpio now looks up numeric UIDs on
- * the local system. */
- /* assertEqualFile("tv.out", "test_option_tv.stdout"); */
-
- /* List reference archive with numeric IDs, verify TOC is correct. */
- r = systemf("%s -itnv < test_option_t.cpio >itnv.out 2>itnv.err",
- testprog);
- assertEqualInt(r, 0);
- assertTextFileContents("1 block\n", "itnv.err");
- p = slurpfile(NULL, "itnv.out");
- /* Since -n uses numeric UID/GID, this part should be the
- * same on every system. */
- assertEqualMem(p, "-rw-r--r-- 1 1000 1000 0 ",42);
- /* Date varies depending on local timezone. */
- if (memcmp(p + 42, "Dec 31 1969", 12) == 0) {
- /* East of Greenwich we get Dec 31, 1969. */
- } else {
- /* West of Greenwich get Jan 1, 1970 */
- assertEqualMem(p + 42, "Jan ", 4);
- /* Some systems format "Jan 01", some "Jan 1" */
- assert(p[46] == ' ' || p[46] == '0');
- assertEqualMem(p + 47, "1 1970 ", 8);
- }
- assertEqualMem(p + 54, " file", 5);
- free(p);
-
- /* But "-n" without "-t" is an error. */
- assert(0 != systemf("%s -in < test_option_t.cpio >in.out 2>in.err",
- testprog));
- assertEmptyFile("in.out");
-}
diff --git a/usr.bin/cpio/test/test_option_t.cpio.uu b/usr.bin/cpio/test/test_option_t.cpio.uu
deleted file mode 100644
index 055fe747d06f..000000000000
--- a/usr.bin/cpio/test/test_option_t.cpio.uu
+++ /dev/null
@@ -1,16 +0,0 @@
-$FreeBSD$
-begin 644 test_option_t.cpio
-M,#<P-S`W,#`P,3,Q-#4P,#8T,3`P-C0T,#`Q-S4P,#`Q-S4P,#`P,#`Q,#`P
-M,#`P,#`P,#`P,#`P,#$P,#`P,#4P,#`P,#`P,#`P,&9I;&4`,#<P-S`W,#`P
-M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q,#`P,#`P,#`P,#`P
-M,#`P,#`P,#`P,3,P,#`P,#`P,#`P,%1204E,15(A(2$`````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-1````````````````````````
-`
-end
diff --git a/usr.bin/cpio/test/test_option_t.stdout.uu b/usr.bin/cpio/test/test_option_t.stdout.uu
deleted file mode 100644
index 2457706eceed..000000000000
--- a/usr.bin/cpio/test/test_option_t.stdout.uu
+++ /dev/null
@@ -1,5 +0,0 @@
-$FreeBSD$
-begin 644 test_option_t.stdout
-%9FEL90H`
-`
-end
diff --git a/usr.bin/cpio/test/test_option_tv.stdout.uu b/usr.bin/cpio/test/test_option_tv.stdout.uu
deleted file mode 100644
index 7f1879c80b16..000000000000
--- a/usr.bin/cpio/test/test_option_tv.stdout.uu
+++ /dev/null
@@ -1,6 +0,0 @@
-$FreeBSD$
-begin 644 test_option_tv.stdout
-M+7)W+7(M+7(M+2`@(#$@=&EM("`@("`@=&EM("`@("`@("`@("`@(#`@1&5C
-/(#,Q("`Q.38Y(&9I;&4*
-`
-end
diff --git a/usr.bin/cpio/test/test_option_u.c b/usr.bin/cpio/test/test_option_u.c
deleted file mode 100644
index 08058aa45396..000000000000
--- a/usr.bin/cpio/test/test_option_u.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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"
-#if defined(HAVE_UTIME_H)
-#include <utime.h>
-#elif defined(HAVE_SYS_UTIME_H)
-#include <sys/utime.h>
-#endif
-__FBSDID("$FreeBSD$");
-
-DEFINE_TEST(test_option_u)
-{
- struct utimbuf times;
- char *p;
- size_t s;
- int r;
-
- /* Create a file. */
- assertMakeFile("f", 0644, "a");
-
- /* Copy the file to the "copy" dir. */
- r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
- testprog);
- assertEqualInt(r, 0);
-
- /* Check that the file contains only a single "a" */
- p = slurpfile(&s, "copy/f");
- assertEqualInt(s, 1);
- assertEqualMem(p, "a", 1);
-
- /* Recreate the file with a single "b" */
- assertMakeFile("f", 0644, "b");
-
- /* Set the mtime to the distant past. */
- memset(&times, 0, sizeof(times));
- times.actime = 1;
- times.modtime = 3;
- assertEqualInt(0, utime("f", &times));
-
- /* Copy the file to the "copy" dir. */
- r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
- testprog);
- assertEqualInt(r, 0);
-
- /* Verify that the file hasn't changed (it wasn't overwritten) */
- p = slurpfile(&s, "copy/f");
- assertEqualInt(s, 1);
- assertEqualMem(p, "a", 1);
-
- /* Copy the file to the "copy" dir with -u (force) */
- r = systemf("echo f | %s -pud copy >copy.out 2>copy.err",
- testprog);
- assertEqualInt(r, 0);
-
- /* Verify that the file has changed (it was overwritten) */
- p = slurpfile(&s, "copy/f");
- assertEqualInt(s, 1);
- assertEqualMem(p, "b", 1);
-}
diff --git a/usr.bin/cpio/test/test_option_version.c b/usr.bin/cpio/test/test_option_version.c
deleted file mode 100644
index 7345da1e5157..000000000000
--- a/usr.bin/cpio/test/test_option_version.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * Test that --version option works and generates reasonable output.
- */
-
-static void
-verify(const char *p, size_t s)
-{
- const char *q = p;
-
- /* Version message should start with name of program, then space. */
- failure("version message too short:", p);
- if (!assert(s > 6))
- return;
- failure("Version message should begin with 'bsdcpio': %s", p);
- if (!assertEqualMem(q, "bsdcpio ", 8))
- /* If we're not testing bsdcpio, don't keep going. */
- return;
- q += 8; s -= 8;
- /* Version number is a series of digits and periods. */
- while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
- ++q;
- --s;
- }
- /* Version number terminated by space. */
- failure("Version: %s", p);
- assert(s > 1);
- /* Skip a single trailing a,b,c, or d. */
- if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
- ++q;
- failure("Version: %s", p);
- assert(*q == ' ');
- ++q; --s;
- /* Separator. */
- failure("Version: %s", p);
- assertEqualMem(q, "-- ", 3);
- q += 3; s -= 3;
- /* libarchive name and version number */
- assert(s > 11);
- failure("Version: %s", p);
- assertEqualMem(q, "libarchive ", 11);
- q += 11; s -= 11;
- /* Version number is a series of digits and periods. */
- while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
- ++q;
- --s;
- }
- /* Skip a single trailing a,b,c, or d. */
- if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
- ++q;
- /* All terminated by end-of-line: \r, \r\n, or \n */
- assert(s >= 1);
- failure("Version: %s", p);
- if (*q == '\x0d') {
- if (q[1] != '\0')
- assertEqualMem(q, "\x0d\x0a", 2);
- } else
- assertEqualMem(q, "\x0a", 1);
-}
-
-
-DEFINE_TEST(test_option_version)
-{
- int r;
- char *p;
- size_t s;
-
- r = systemf("%s --version >version.stdout 2>version.stderr", testprog);
- if (r != 0)
- r = systemf("%s -W version >version.stdout 2>version.stderr",
- testprog);
- failure("Unable to run either %s --version or %s -W version",
- testprog, testprog);
- if (!assert(r == 0))
- return;
-
- /* --version should generate nothing to stderr. */
- assertEmptyFile("version.stderr");
- /* Verify format of version message. */
- p = slurpfile(&s, "version.stdout");
- verify(p, s);
- free(p);
-}
diff --git a/usr.bin/cpio/test/test_option_y.c b/usr.bin/cpio/test/test_option_y.c
deleted file mode 100644
index 8e81ee752a1d..000000000000
--- a/usr.bin/cpio/test/test_option_y.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_y)
-{
- char *p;
- int r;
- size_t s;
-
- /* Create a file. */
- assertMakeFile("f", 0644, "a");
-
- /* Archive it with bzip2 compression. */
- r = systemf("echo f | %s -oy >archive.out 2>archive.err",
- testprog);
- p = slurpfile(&s, "archive.err");
- p[s] = '\0';
- if (r != 0) {
- if (strstr(p, "compression not available") != NULL) {
- skipping("This version of bsdcpio was compiled "
- "without bzip2 support");
- return;
- }
- failure("-y option is broken");
- assertEqualInt(r, 0);
- return;
- }
- assertTextFileContents("1 block\n", "archive.err");
- /* Check that the archive file has a bzip2 signature. */
- p = slurpfile(&s, "archive.out");
- assert(s > 2);
- assertEqualMem(p, "BZh9", 4);
-}
diff --git a/usr.bin/cpio/test/test_option_z.c b/usr.bin/cpio/test/test_option_z.c
deleted file mode 100644
index 91d37ac1983a..000000000000
--- a/usr.bin/cpio/test/test_option_z.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_z)
-{
- char *p;
- int r;
- size_t s;
-
- /* Create a file. */
- assertMakeFile("f", 0644, "a");
-
- /* Archive it with gzip compression. */
- r = systemf("echo f | %s -oz >archive.out 2>archive.err",
- testprog);
- p = slurpfile(&s, "archive.err");
- p[s] = '\0';
- if (r != 0) {
- if (strstr(p, "compression not available") != NULL) {
- skipping("This version of bsdcpio was compiled "
- "without gzip support");
- return;
- }
- failure("-z option is broken");
- assertEqualInt(r, 0);
- return;
- }
- /* Check that the archive file has a gzip signature. */
- p = slurpfile(&s, "archive.out");
- assert(s > 4);
- assertEqualMem(p, "\x1f\x8b\x08\x00", 4);
-}
diff --git a/usr.bin/cpio/test/test_owner_parse.c b/usr.bin/cpio/test/test_owner_parse.c
deleted file mode 100644
index d07724e0e776..000000000000
--- a/usr.bin/cpio/test/test_owner_parse.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * 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$");
-
-#include "../cpio.h"
-#include "err.h"
-
-#if !defined(_WIN32)
-#define ROOT "root"
-static int root_uids[] = { 0 };
-/* Solaris 9 root has gid 1 (other) */
-static int root_gids[] = { 0, 1 };
-#elif defined(__CYGWIN__)
-/* On cygwin, the Administrator user most likely exists (unless
- * it has been renamed or is in a non-English localization), but
- * its primary group membership depends on how the user set up
- * their /etc/passwd. Likely values are 513 (None), 545 (Users),
- * or 544 (Administrators). Just check for one of those...
- * TODO: Handle non-English localizations...e.g. French 'Administrateur'
- * Use CreateWellKnownSID() and LookupAccountName()?
- */
-#define ROOT "Administrator"
-static int root_uids[] = { 500 };
-static int root_gids[] = { 513, 545, 544 };
-#endif
-
-#if defined(ROOT)
-static int
-int_in_list(int i, int *l, size_t n)
-{
- while (n-- > 0)
- if (*l++ == i)
- return (1);
- failure("%d", i);
- return (0);
-}
-#endif
-
-DEFINE_TEST(test_owner_parse)
-{
-#if !defined(ROOT)
- skipping("No uid/gid configuration for this OS");
-#else
- int uid, gid;
-
- assert(NULL == owner_parse(ROOT, &uid, &gid));
- assert(int_in_list(uid, root_uids,
- sizeof(root_uids)/sizeof(root_uids[0])));
- assertEqualInt(-1, gid);
-
-
- assert(NULL == owner_parse(ROOT ":", &uid, &gid));
- assert(int_in_list(uid, root_uids,
- sizeof(root_uids)/sizeof(root_uids[0])));
- assert(int_in_list(gid, root_gids,
- sizeof(root_gids)/sizeof(root_gids[0])));
-
- assert(NULL == owner_parse(ROOT ".", &uid, &gid));
- assert(int_in_list(uid, root_uids,
- sizeof(root_uids)/sizeof(root_uids[0])));
- assert(int_in_list(gid, root_gids,
- sizeof(root_gids)/sizeof(root_gids[0])));
-
- assert(NULL == owner_parse("111", &uid, &gid));
- assertEqualInt(111, uid);
- assertEqualInt(-1, gid);
-
- assert(NULL == owner_parse("112:", &uid, &gid));
- assertEqualInt(112, uid);
- /* Can't assert gid, since we don't know gid for user #112. */
-
- assert(NULL == owner_parse("113.", &uid, &gid));
- assertEqualInt(113, uid);
- /* Can't assert gid, since we don't know gid for user #113. */
-
- assert(NULL == owner_parse(":114", &uid, &gid));
- assertEqualInt(-1, uid);
- assertEqualInt(114, gid);
-
- assert(NULL == owner_parse(".115", &uid, &gid));
- assertEqualInt(-1, uid);
- assertEqualInt(115, gid);
-
- assert(NULL == owner_parse("116:117", &uid, &gid));
- assertEqualInt(116, uid);
- assertEqualInt(117, gid);
-
- /*
- * TODO: Lookup current user/group name, build strings and
- * use those to verify username/groupname lookups for ordinary
- * users.
- */
-
- assert(NULL != owner_parse(":nonexistentgroup", &uid, &gid));
- assert(NULL != owner_parse(ROOT ":nonexistentgroup", &uid, &gid));
- assert(NULL !=
- owner_parse("nonexistentuser:nonexistentgroup", &uid, &gid));
-#endif
-}
diff --git a/usr.bin/cpio/test/test_passthrough_dotdot.c b/usr.bin/cpio/test/test_passthrough_dotdot.c
deleted file mode 100644
index 58d82349acad..000000000000
--- a/usr.bin/cpio/test/test_passthrough_dotdot.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * Verify that "cpio -p .." works.
- */
-
-DEFINE_TEST(test_passthrough_dotdot)
-{
- int r;
- FILE *filelist;
-
- assertUmask(0);
-
- /*
- * Create an assortment of files on disk.
- */
- filelist = fopen("filelist", "w");
-
- /* Directory. */
- assertMakeDir("dir", 0755);
- assertChdir("dir");
-
- fprintf(filelist, ".\n");
-
- /* File with 10 bytes content. */
- assertMakeFile("file", 0642, "1234567890");
- fprintf(filelist, "file\n");
-
- /* All done. */
- fclose(filelist);
-
-
- /*
- * Use cpio passthrough mode to copy files to another directory.
- */
- r = systemf("%s -pdvm .. <../filelist >../stdout 2>../stderr",
- testprog);
- failure("Error invoking %s -pd ..", testprog);
- assertEqualInt(r, 0);
-
- assertChdir("..");
-
- /* Verify stderr and stdout. */
- assertTextFileContents("../.\n../file\n1 block\n", "stderr");
- assertEmptyFile("stdout");
-
- /* Regular file. */
- assertIsReg("file", 0642);
- assertFileSize("file", 10);
- assertFileNLinks("file", 1);
-}
diff --git a/usr.bin/cpio/test/test_passthrough_reverse.c b/usr.bin/cpio/test/test_passthrough_reverse.c
deleted file mode 100644
index 42df75abd4ce..000000000000
--- a/usr.bin/cpio/test/test_passthrough_reverse.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * As reported by Bernd Walter: Some people are in the habit of
- * using "find -d" to generate a list for cpio -p because that
- * copies the top-level dir last, which preserves owner and mode
- * information. That's not necessary for bsdcpio (libarchive defers
- * restoring directory information), but bsdcpio should still generate
- * the correct results with this usage.
- */
-
-DEFINE_TEST(test_passthrough_reverse)
-{
- int r;
- FILE *filelist;
-
- assertUmask(0);
-
- /*
- * Create an assortment of files on disk.
- */
- filelist = fopen("filelist", "w");
-
- /* Directory. */
- assertMakeDir("dir", 0743);
-
- /* File with 10 bytes content. */
- assertMakeFile("dir/file", 0644, "1234567890");
- fprintf(filelist, "dir/file\n");
-
- /* Write dir last. */
- fprintf(filelist, "dir\n");
-
- /* All done. */
- fclose(filelist);
-
-
- /*
- * Use cpio passthrough mode to copy files to another directory.
- */
- r = systemf("%s -pdvm out <filelist >stdout 2>stderr", testprog);
- failure("Error invoking %s -pd out", testprog);
- assertEqualInt(r, 0);
-
- assertChdir("out");
-
- /* Verify stderr and stdout. */
- assertTextFileContents("out/dir/file\nout/dir\n1 block\n",
- "../stderr");
- assertEmptyFile("../stdout");
-
- /* dir */
- assertIsDir("dir", 0743);
-
-
- /* Regular file. */
- assertIsReg("dir/file", 0644);
- assertFileSize("dir/file", 10);
- assertFileNLinks("dir/file", 1);
-}
diff --git a/usr.bin/cpio/test/test_pathmatch.c b/usr.bin/cpio/test/test_pathmatch.c
deleted file mode 100644
index 177c2bcc4af4..000000000000
--- a/usr.bin/cpio/test/test_pathmatch.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-#include "pathmatch.h"
-
-/*
- * Verify that the pattern matcher implements the wildcard logic specified
- * in SUSv2 for the cpio command. This is essentially the
- * shell glob syntax:
- * * - matches any sequence of chars, including '/'
- * ? - matches any single char, including '/'
- * [...] - matches any of a set of chars, '-' specifies a range,
- * initial '!' is undefined
- *
- * The specification in SUSv2 is a bit incomplete, I assume the following:
- * Trailing '-' in [...] is not special.
- *
- * TODO: Figure out if there's a good way to extend this to handle
- * Windows paths that use '\' as a path separator. <sigh>
- */
-
-DEFINE_TEST(test_pathmatch)
-{
- assertEqualInt(1, lafe_pathmatch("a/b/c", "a/b/c", 0));
- assertEqualInt(0, lafe_pathmatch("a/b/", "a/b/c", 0));
- assertEqualInt(0, lafe_pathmatch("a/b", "a/b/c", 0));
- assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b/", 0));
- assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b", 0));
-
- /* Empty pattern only matches empty string. */
- assertEqualInt(1, lafe_pathmatch("","", 0));
- assertEqualInt(0, lafe_pathmatch("","a", 0));
- assertEqualInt(1, lafe_pathmatch("*","", 0));
- assertEqualInt(1, lafe_pathmatch("*","a", 0));
- assertEqualInt(1, lafe_pathmatch("*","abcd", 0));
- /* SUSv2: * matches / */
- assertEqualInt(1, lafe_pathmatch("*","abcd/efgh/ijkl", 0));
- assertEqualInt(1, lafe_pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0));
- assertEqualInt(1, lafe_pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0));
- assertEqualInt(1, lafe_pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0));
- assertEqualInt(0, lafe_pathmatch("?", "", 0));
- assertEqualInt(0, lafe_pathmatch("?", "\0", 0));
- assertEqualInt(1, lafe_pathmatch("?", "a", 0));
- assertEqualInt(0, lafe_pathmatch("?", "ab", 0));
- assertEqualInt(1, lafe_pathmatch("?", ".", 0));
- assertEqualInt(1, lafe_pathmatch("?", "?", 0));
- assertEqualInt(1, lafe_pathmatch("a", "a", 0));
- assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
- assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
- assertEqualInt(1, lafe_pathmatch("a?c", "abc", 0));
- /* SUSv2: ? matches / */
- assertEqualInt(1, lafe_pathmatch("a?c", "a/c", 0));
- assertEqualInt(1, lafe_pathmatch("a?*c*", "a/c", 0));
- assertEqualInt(1, lafe_pathmatch("*a*", "a/c", 0));
- assertEqualInt(1, lafe_pathmatch("*a*", "/a/c", 0));
- assertEqualInt(1, lafe_pathmatch("*a*", "defaaaaaaa", 0));
- assertEqualInt(0, lafe_pathmatch("a*", "defghi", 0));
- assertEqualInt(0, lafe_pathmatch("*a*", "defghi", 0));
-
- /* Character classes */
- assertEqualInt(1, lafe_pathmatch("abc[def", "abc[def", 0));
- assertEqualInt(0, lafe_pathmatch("abc[def]", "abc[def", 0));
- assertEqualInt(0, lafe_pathmatch("abc[def", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[def]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[def]", "abce", 0));
- assertEqualInt(1, lafe_pathmatch("abc[def]", "abcf", 0));
- assertEqualInt(0, lafe_pathmatch("abc[def]", "abcg", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abc*", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d*f]", "abcdefghi", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d*", "abcdefghi", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d*", "abc[defghi", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abce", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcf", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d-f]", "abcg", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abca", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abce", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcf", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcg", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abch", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abci", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcj", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abck", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcl", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abc-", 0));
-
- /* [] matches nothing, [!] is the same as ? */
- assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcdefg", 0));
- assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcqefg", 0));
- assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcefg", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcdefg", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcqefg", 0));
- assertEqualInt(0, lafe_pathmatch("abc[!]efg", "abcefg", 0));
-
- /* I assume: Trailing '-' is non-special. */
- assertEqualInt(0, lafe_pathmatch("abc[d-fh-]", "abcl", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abch", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
-
- /* ']' can be backslash-quoted within a character class. */
- assertEqualInt(1, lafe_pathmatch("abc[\\]]", "abc]", 0));
- assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abc]", 0));
- assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abc]", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d]e]", "abcde]", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d\\]e]", "abc]", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d\\]e]", "abcd]e", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d]e]", "abc]", 0));
-
- /* backslash-quoted chars can appear as either end of a range. */
- assertEqualInt(1, lafe_pathmatch("abc[\\d-f]gh", "abcegh", 0));
- assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abcggh", 0));
- assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abc\\gh", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-\\f]gh", "abcegh", 0));
- assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
- assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
- /* backslash-quoted '-' isn't special. */
- assertEqualInt(0, lafe_pathmatch("abc[d\\-f]gh", "abcegh", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d\\-f]gh", "abc-gh", 0));
-
- /* Leading '!' negates a character class. */
- assertEqualInt(0, lafe_pathmatch("abc[!d]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!d]", "abce", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!d]", "abcc", 0));
- assertEqualInt(0, lafe_pathmatch("abc[!d-z]", "abcq", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!d-gi-z]", "abch", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!fgijkl]", "abch", 0));
- assertEqualInt(0, lafe_pathmatch("abc[!fghijkl]", "abch", 0));
-
- /* Backslash quotes next character. */
- assertEqualInt(0, lafe_pathmatch("abc\\[def]", "abc\\d", 0));
- assertEqualInt(1, lafe_pathmatch("abc\\[def]", "abc[def]", 0));
- assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc[def]", 0));
- assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc\\[def]", 0));
- assertEqualInt(1, lafe_pathmatch("abc\\\\[def]", "abc\\d", 0));
- assertEqualInt(1, lafe_pathmatch("abcd\\", "abcd\\", 0));
- assertEqualInt(0, lafe_pathmatch("abcd\\", "abcd\\[", 0));
- assertEqualInt(0, lafe_pathmatch("abcd\\", "abcde", 0));
- assertEqualInt(0, lafe_pathmatch("abcd\\[", "abcd\\", 0));
-
- /*
- * Because '.' and '/' have special meanings, we can
- * identify many equivalent paths even if they're expressed
- * differently. (But quoting a character with '\\' suppresses
- * special meanings!)
- */
- assertEqualInt(0, lafe_pathmatch("a/b/", "a/bc", 0));
- assertEqualInt(1, lafe_pathmatch("a/./b", "a/b", 0));
- assertEqualInt(0, lafe_pathmatch("a\\/./b", "a/b", 0));
- assertEqualInt(0, lafe_pathmatch("a/\\./b", "a/b", 0));
- assertEqualInt(0, lafe_pathmatch("a/.\\/b", "a/b", 0));
- assertEqualInt(0, lafe_pathmatch("a\\/\\.\\/b", "a/b", 0));
- assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def/", 0));
- assertEqualInt(1, lafe_pathmatch("abc/def", "./././abc/./def", 0));
- assertEqualInt(1, lafe_pathmatch("abc/def/././//", "./././abc/./def/", 0));
- assertEqualInt(1, lafe_pathmatch(".////abc/.//def", "./././abc/./def", 0));
- assertEqualInt(1, lafe_pathmatch("./abc?def/", "abc/def/", 0));
- failure("\"?./\" is not the same as \"/./\"");
- assertEqualInt(0, lafe_pathmatch("./abc?./def/", "abc/def/", 0));
- failure("Trailing '/' should match no trailing '/'");
- assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def", 0));
- failure("Trailing '/./' is still the same directory.");
- assertEqualInt(1, lafe_pathmatch("./abc/./def/./", "abc/def", 0));
- failure("Trailing '/.' is still the same directory.");
- assertEqualInt(1, lafe_pathmatch("./abc/./def/.", "abc/def", 0));
- assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/", 0));
- failure("Trailing '/./' is still the same directory.");
- assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/./", 0));
- failure("Trailing '/.' is still the same directory.");
- assertEqualInt(1, lafe_pathmatch("./abc*/./def", "abc/def/.", 0));
-
- /* Matches not anchored at beginning. */
- assertEqualInt(0,
- lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
- assertEqualInt(1,
- lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START));
- assertEqualInt(0,
- lafe_pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
- assertEqualInt(1,
- lafe_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
- assertEqualInt(0,
- lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
- assertEqualInt(0,
- lafe_pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
-
- /* Matches not anchored at end. */
- assertEqualInt(0,
- lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(0,
- lafe_pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(0,
- lafe_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(0,
- lafe_pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(0,
- lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
-}
diff --git a/usr.bin/tar/COPYING b/usr.bin/tar/COPYING
deleted file mode 100644
index 9a88a8091105..000000000000
--- a/usr.bin/tar/COPYING
+++ /dev/null
@@ -1,62 +0,0 @@
-$FreeBSD$
-
-All of the C source code and documentation in this package is subject
-to the following:
-
-Copyright (c) 2003-2007 Tim Kientzle
-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.
-
-Some of the filename pattern matching code is based on code subject
-to the following license:
-
-/*
- * Copyright (c) 1989, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Guido van Rossum.
- *
- * 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.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- */
diff --git a/usr.bin/tar/Makefile b/usr.bin/tar/Makefile
index 2ca6fd22c954..f026b1f36a08 100644
--- a/usr.bin/tar/Makefile
+++ b/usr.bin/tar/Makefile
@@ -1,8 +1,12 @@
# $FreeBSD$
.include <bsd.own.mk>
+LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive
+
PROG= bsdtar
BSDTAR_VERSION_STRING=2.8.5
+
+.PATH: ${LIBARCHIVEDIR}/tar
SRCS= bsdtar.c \
cmdline.c \
getdate.c \
@@ -12,7 +16,7 @@ SRCS= bsdtar.c \
util.c \
write.c
-.PATH: ${.CURDIR}/../../lib/libarchive/libarchive_fe
+.PATH: ${LIBARCHIVEDIR}/libarchive_fe
SRCS+= err.c \
line_reader.c \
matching.c \
@@ -30,15 +34,18 @@ LDADD+= -lmd
.endif
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
+CFLAGS+= -DPLATFORM_CONFIG_H=\"${.CURDIR}/config_freebsd.h\"
+CFLAGS+= -I${LIBARCHIVEDIR}/tar -I${LIBARCHIVEDIR}/libarchive
+CFLAGS+= -I${LIBARCHIVEDIR}/libarchive_fe
SYMLINKS= bsdtar ${BINDIR}/tar
MLINKS= bsdtar.1 tar.1
DEBUG_FLAGS=-g
-.PHONY: check test
+.PHONY: check test clean-test
check test: $(PROG) bsdtar.1.gz
- cd ${.CURDIR}/test && make test
+ cd ${.CURDIR}/test && make obj && make test
+
+clean-test:
+ cd ${.CURDIR}/test && make clean
.include <bsd.prog.mk>
diff --git a/usr.bin/tar/bsdtar.1 b/usr.bin/tar/bsdtar.1
deleted file mode 100644
index 14c77e9b2e4a..000000000000
--- a/usr.bin/tar/bsdtar.1
+++ /dev/null
@@ -1,1029 +0,0 @@
-.\" Copyright (c) 2003-2007 Tim Kientzle
-.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd Oct 12, 2009
-.Dt BSDTAR 1
-.Os
-.Sh NAME
-.Nm tar
-.Nd manipulate tape archives
-.Sh SYNOPSIS
-.Nm
-.Op Ar bundled-flags Ao args Ac
-.Op Ao Ar file Ac | Ao Ar pattern Ac ...
-.Nm
-.Brq Fl c
-.Op Ar options
-.Op Ar files | Ar directories
-.Nm
-.Brq Fl r | Fl u
-.Fl f Ar archive-file
-.Op Ar options
-.Op Ar files | Ar directories
-.Nm
-.Brq Fl t | Fl x
-.Op Ar options
-.Op Ar patterns
-.Sh DESCRIPTION
-.Nm
-creates and manipulates streaming archive files.
-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
-.Dq bundled
-option word.
-This usage is provided for compatibility with historical implementations.
-See COMPATIBILITY below for details.
-.Pp
-The other synopsis forms show the preferred usage.
-The first option to
-.Nm
-is a mode indicator from the following list:
-.Bl -tag -compact -width indent
-.It Fl c
-Create a new archive containing the specified items.
-The long option form is
-.Fl Fl create .
-.It Fl r
-Like
-.Fl c ,
-but new entries are appended to the archive.
-Note that this only works on uncompressed archives stored in regular files.
-The
-.Fl f
-option is required.
-The long option form is
-.Fl Fl append .
-.It Fl t
-List archive contents to stdout.
-The long option form is
-.Fl Fl list .
-.It Fl u
-Like
-.Fl r ,
-but new entries are added only if they have a modification date
-newer than the corresponding entry in the archive.
-Note that this only works on uncompressed archives stored in regular files.
-The
-.Fl f
-option is required.
-The long form is
-.Fl Fl update .
-.It Fl x
-Extract to disk from the archive.
-If a file with the same name appears more than once in the archive,
-each copy will be extracted, with later copies overwriting (replacing)
-earlier copies.
-The long option form is
-.Fl Fl extract .
-.El
-.Pp
-In
-.Fl c ,
-.Fl r ,
-or
-.Fl u
-mode, each specified file or directory is added to the
-archive in the order specified on the command line.
-By default, the contents of each directory are also archived.
-.Pp
-In extract or list mode, the entire command line
-is read and parsed before the archive is opened.
-The pathnames or patterns on the command line indicate
-which items in the archive should be processed.
-Patterns are shell-style globbing patterns as
-documented in
-.Xr tcsh 1 .
-.Sh OPTIONS
-Unless specifically stated otherwise, options are applicable in
-all operating modes.
-.Bl -tag -width indent
-.It Cm @ Ns Pa archive
-(c and r mode only)
-The specified archive is opened and the entries
-in it will be appended to the current archive.
-As a simple example,
-.Dl Nm Fl c Fl f Pa - Pa newfile Cm @ Ns Pa original.tar
-writes a new archive to standard output containing a file
-.Pa newfile
-and all of the entries from
-.Pa original.tar .
-In contrast,
-.Dl Nm Fl c Fl f Pa - Pa newfile Pa original.tar
-creates a new archive with only two entries.
-Similarly,
-.Dl Nm Fl czf Pa - Fl Fl format Cm pax Cm @ Ns Pa -
-reads an archive from standard input (whose format will be determined
-automatically) and converts it into a gzip-compressed
-pax-format archive on stdout.
-In this way,
-.Nm
-can be used to convert archives from one format to another.
-.It Fl B , Fl Fl read-full-blocks
-Ignored for compatibility with other
-.Xr tar 1
-implementations.
-.It Fl b Ar blocksize , Fl Fl block-size Ar blocksize
-Specify the block size, in 512-byte records, for tape drive I/O.
-As a rule, this argument is only needed when reading from or writing
-to tape drives, and usually not even then as the default block size of
-20 records (10240 bytes) is very common.
-.It Fl C Ar directory
-In c and r mode, this changes the directory before adding
-the following files.
-In x mode, change directories after opening the archive
-but before extracting entries from the archive.
-.It Fl Fl chroot
-(x mode only)
-.Fn chroot
-to the current directory after processing any
-.Fl C
-options and before extracting any files.
-.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 format Ar format
-(c, r, u mode only)
-Use the specified format for the created archive.
-Supported formats include
-.Dq cpio ,
-.Dq pax ,
-.Dq shar ,
-and
-.Dq ustar .
-Other formats may also be supported; see
-.Xr libarchive-formats 5
-for more information about currently-supported formats.
-In r and u modes, when extending an existing archive, the format specified
-here must be compatible with the format of the existing archive on disk.
-.It Fl f Ar file , Fl Fl file Ar file
-Read the archive from or write the archive to the specified file.
-The filename can be
-.Pa -
-for standard input or standard output.
-The default varies by system;
-on
-.Fx ,
-the default is
-.Pa /dev/sa0 ;
-on Linux, the default is
-.Pa /dev/st0 .
-.It Fl Fl gid Ar id
-Use the provided group id number.
-On extract, this overrides the group id in the archive;
-the group name in the archive will be ignored.
-On create, this overrides the group id read from disk;
-if
-.Fl Fl gname
-is not also specified, the group name will be set to
-match the group id.
-.It Fl Fl gname Ar name
-Use the provided group name.
-On extract, this overrides the group name in the archive;
-if the provided group name does not exist on the system,
-the group id
-(from the archive or from the
-.Fl Fl gid
-option)
-will be used instead.
-On create, this sets the group name that will be stored
-in the archive;
-the name will not be verified against the system group database.
-.It Fl H
-(c and r mode 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)
-Synonym for
-.Fl L .
-.It Fl I
-Synonym for
-.Fl T .
-.It Fl Fl help
-Show usage.
-.It Fl Fl include Ar pattern
-Process only files or directories that match the specified pattern.
-Note that exclusions specified with
-.Fl Fl exclude
-take precedence over inclusions.
-If no inclusions are explicitly specified, all entries are processed by
-default.
-The
-.Fl Fl include
-option is especially useful when filtering archives.
-For example, the command
-.Dl Nm Fl c Fl f Pa new.tar Fl Fl include='*foo*' Cm @ Ns Pa old.tgz
-creates a new archive
-.Pa new.tar
-containing only the entries from
-.Pa old.tgz
-containing the string
-.Sq foo .
-.It Fl J , Fl Fl xz
-(c mode only)
-Compress the resulting archive with
-.Xr xz 1 .
-In extract or list modes, this option is ignored.
-Note that, unlike other
-.Nm tar
-implementations, this implementation recognizes XZ compression
-automatically when reading archives.
-.It Fl j , Fl Fl bzip , Fl Fl bzip2 , Fl Fl bunzip2
-(c mode only)
-Compress the resulting archive with
-.Xr bzip2 1 .
-In extract or list modes, this option is ignored.
-Note that, unlike other
-.Nm tar
-implementations, this implementation recognizes bzip2 compression
-automatically when reading archives.
-.It Fl k , Fl Fl keep-old-files
-(x mode only)
-Do not overwrite existing files.
-In particular, if a file appears more than once in an archive,
-later copies will not overwrite earlier copies.
-.It Fl Fl keep-newer-files
-(x mode only)
-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)
-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.
-.It Fl l , Fl Fl check-links
-(c and r modes only)
-Issue a warning message unless all links to each file are archived.
-.It Fl Fl lzma
-(c mode only) Compress the resulting archive with the original LZMA algorithm.
-Use of this option is discouraged and new archives should be created with
-.Fl Fl xz
-instead.
-Note that, unlike other
-.Nm tar
-implementations, this implementation recognizes LZMA compression
-automatically when reading archives.
-.It Fl m , Fl Fl modification-time
-(x mode only)
-Do not extract modification time.
-By default, the modification time is set to the time stored in the archive.
-.It Fl n , Fl Fl norecurse , Fl Fl no-recursion
-(c, r, u modes only)
-Do not recursively archive the contents of directories.
-.It Fl Fl newer Ar date
-(c, r, u modes only)
-Only include files and directories newer than the specified date.
-This compares ctime entries.
-.It Fl Fl newer-mtime Ar date
-(c, r, u modes only)
-Like
-.Fl Fl newer ,
-except it compares mtime entries instead of ctime entries.
-.It Fl Fl newer-than Pa file
-(c, r, u modes only)
-Only include files and directories newer than the specified file.
-This compares ctime entries.
-.It Fl Fl newer-mtime-than Pa file
-(c, r, u modes only)
-Like
-.Fl Fl newer-than ,
-except it compares mtime entries instead of ctime entries.
-.It Fl Fl nodump
-(c and r modes only)
-Honor the nodump file flag by skipping this file.
-.It Fl Fl null
-(use with
-.Fl I
-or
-.Fl T )
-Filenames or patterns are separated by null characters,
-not by newlines.
-This is often used to read filenames output by the
-.Fl print0
-option to
-.Xr find 1 .
-.It Fl Fl no-same-owner
-(x mode only)
-Do not extract owner and group IDs.
-This is the reverse of
-.Fl Fl same-owner
-and the default behavior if
-.Nm
-is run as non-root.
-.It Fl Fl no-same-permissions
-(x mode only)
-Do not extract full permissions (SGID, SUID, sticky bit, ACLs,
-extended attributes or extended file flags).
-This is the reverse of
-.Fl p
-and the default behavior if
-.Nm
-is run as non-root.
-.It Fl Fl numeric-owner
-This is equivalent to
-.Fl Fl uname
-.Qq
-.Fl Fl gname
-.Qq .
-On extract, it causes user and group names in the archive
-to be ignored in favor of the numeric user and group ids.
-On create, it causes user and group names to not be stored
-in the archive.
-.It Fl O , Fl Fl to-stdout
-(x, t modes only)
-In extract (-x) mode, files will be written to standard out rather than
-being extracted to disk.
-In list (-t) mode, the file listing will be written to stderr rather than
-the usual stdout.
-.It Fl o
-(x mode)
-Use the user and group of the user running the program rather
-than those specified in the archive.
-Note that this has no significance unless
-.Fl p
-is specified, and the program is being run by the root user.
-In this case, the file modes and flags from
-the archive will be restored, but ACLs or owner information in
-the archive will be discarded.
-.It Fl o
-(c, r, u mode)
-A synonym for
-.Fl Fl format Ar ustar
-.It Fl Fl one-file-system
-(c, r, and u modes)
-Do not cross mount points.
-.It Fl Fl options Ar options
-Select optional behaviors for particular modules.
-The argument is a text string containing comma-separated
-keywords and values.
-These are passed to the modules that handle particular
-formats to control how those formats will behave.
-Each option has one of the following forms:
-.Bl -tag -compact -width indent
-.It Ar key=value
-The key will be set to the specified value in every module that supports it.
-Modules that do not support this key will ignore it.
-.It Ar key
-The key will be enabled in every module that supports it.
-This is equivalent to
-.Ar key Ns Cm =1 .
-.It Ar !key
-The key will be disabled in every module that supports it.
-.It Ar module:key=value , Ar module:key , Ar module:!key
-As above, but the corresponding key and value will be provided
-only to modules whose name matches
-.Ar module .
-.El
-The currently supported modules and keys are:
-.Bl -tag -compact -width indent
-.It Cm iso9660:joliet
-Support Joliet extensions.
-This is enabled by default, use
-.Cm !joliet
-or
-.Cm iso9660:!joliet
-to disable.
-.It Cm iso9660:rockridge
-Support Rock Ridge extensions.
-This is enabled by default, use
-.Cm !rockridge
-or
-.Cm iso9660:!rockridge
-to disable.
-.It Cm gzip:compression-level
-A decimal integer from 0 to 9 specifying the gzip compression level.
-.It Cm xz:compression-level
-A decimal integer from 0 to 9 specifying the xz compression level.
-.It Cm mtree: Ns Ar keyword
-The mtree writer module allows you to specify which mtree keywords
-will be included in the output.
-Supported keywords include:
-.Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent ,
-.Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 ,
-.Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname .
-The default is equivalent to:
-.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname .
-.It Cm mtree:all
-Enables all of the above keywords.
-You can also use
-.Cm mtree:!all
-to disable all keywords.
-.It Cm mtree:use-set
-Enable generation of
-.Cm /set
-lines in the output.
-.It Cm mtree:indent
-Produce human-readable output by indenting options and splitting lines
-to fit into 80 columns.
-.It Cm zip:compression Ns = Ns Ar type
-Use
-.Ar type
-as compression method.
-Supported values are store (uncompressed) and deflate (gzip algorithm).
-.El
-If a provided option is not supported by any module, that
-is a fatal error.
-.It Fl P , Fl Fl absolute-paths
-Preserve pathnames.
-By default, absolute pathnames (those that begin with a /
-character) have the leading slash removed both when creating archives
-and extracting from them.
-Also,
-.Nm
-will refuse to extract archive entries whose pathnames contain
-.Pa ..
-or whose target directory would be altered by a symlink.
-This option suppresses these behaviors.
-.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
-.Nm
-is being run by root and can be overriden by also specifying
-.Fl Fl no-same-owner
-and
-.Fl Fl no-same-permissions .
-.It Fl Fl posix
-(c, r, u mode only)
-Synonym for
-.Fl Fl format Ar pax
-.It Fl q , Fl Fl fast-read
-(x and t mode only)
-Extract or list only the first archive entry that matches each pattern
-or filename operand.
-Exit as soon as each specified pattern or filename has been matched.
-By default, the archive is always read to the very end, since
-there can be multiple entries with the same name and, by convention,
-later entries overwrite earlier entries.
-This option is provided as a performance optimization.
-.It Fl S
-(x mode only)
-Extract files as sparse files.
-For every block on disk, check first if it contains only NULL bytes and seek
-over it otherwise.
-This works similar to the conv=sparse option of dd.
-.It Fl Fl same-owner
-(x mode only)
-Extract owner and group IDs.
-This is the reverse of
-.Fl Fl no-same-owner
-and the default behavior if
-.Nm
-is run as root.
-.It Fl Fl strip-components Ar count
-(x mode only)
-Remove the specified number of leading path elements.
-Pathnames with fewer elements will be silently skipped.
-Note that the pathname is edited after checking inclusion/exclusion patterns
-but before security checks.
-.It Fl s Ar pattern
-Modify file or archive member names according to
-.Pa pattern .
-The pattern has the format
-.Ar /old/new/ Ns Op gps
-where
-.Ar old
-is a basic regular expression,
-.Ar new
-is the replacement string of the matched part,
-and the optional trailing letters modify
-how the replacement is handled.
-If
-.Ar old
-is not matched, the pattern is skipped.
-Within
-.Ar new ,
-~ is substituted with the match, \e1 to \e9 with the content of
-the corresponding captured group.
-The optional trailing g specifies that matching should continue
-after the matched part and stopped on the first unmatched pattern.
-The optional trailing s specifies that the pattern applies to the value
-of symbolic links.
-The optional trailing p specifies that after a successful substitution
-the original path name and the new path name should be printed to
-standard error.
-.It Fl T Ar filename , Fl Fl files-from Ar filename
-In x or t mode,
-.Nm
-will read the list of names to be extracted from
-.Pa filename .
-In c mode,
-.Nm
-will read names to be archived from
-.Pa filename .
-The special name
-.Dq -C
-on a line by itself will cause the current directory to be changed to
-the directory specified on the following line.
-Names are terminated by newlines unless
-.Fl Fl null
-is specified.
-Note that
-.Fl Fl null
-also disables the special handling of lines containing
-.Dq -C .
-.It Fl Fl totals
-(c, r, u mode only)
-After archiving all files, print a summary to stderr.
-.It Fl U , Fl Fl unlink , Fl Fl unlink-first
-(x mode only)
-Unlink files before creating them.
-This can be a minor performance optimization if most files
-already exist, but can make things slower if most files
-do not already exist.
-This flag also causes
-.Nm
-to remove intervening directory symlinks instead of
-reporting an error.
-See the SECURITY section below for more details.
-.It Fl Fl uid Ar id
-Use the provided user id number and ignore the user
-name from the archive.
-On create, if
-.Fl Fl uname
-is not also specified, the user name will be set to
-match the user id.
-.It Fl Fl uname Ar name
-Use the provided user name.
-On extract, this overrides the user name in the archive;
-if the provided user name does not exist on the system,
-it will be ignored and the user id
-(from the archive or from the
-.Fl Fl uid
-option)
-will be used instead.
-On create, this sets the user name that will be stored
-in the archive;
-the name is not verified against the system user database.
-.It Fl Fl use-compress-program Ar program
-Pipe the input (in x or t mode) or the output (in c mode) through
-.Pa program
-instead of using the builtin compression support.
-.It Fl v , Fl Fl verbose
-Produce verbose output.
-In create and extract modes,
-.Nm
-will list each file name as it is read from or written to
-the archive.
-In list mode,
-.Nm
-will produce output similar to that of
-.Xr ls 1 .
-Additional
-.Fl v
-options will provide additional detail.
-.It Fl Fl version
-Print version of
-.Nm
-and
-.Nm libarchive ,
-and exit.
-.It Fl w , Fl Fl confirmation , Fl Fl interactive
-Ask for confirmation for every action.
-.It Fl X Ar filename , Fl Fl exclude-from Ar filename
-Read a list of exclusion patterns from the specified file.
-See
-.Fl Fl exclude
-for more information about the handling of exclusions.
-.It Fl y
-(c mode only)
-Compress the resulting archive with
-.Xr bzip2 1 .
-In extract or list modes, this option is ignored.
-Note that, unlike other
-.Nm tar
-implementations, this implementation recognizes bzip2 compression
-automatically when reading archives.
-.It Fl Z , Fl Fl compress , Fl Fl uncompress
-(c mode only)
-Compress the resulting archive with
-.Xr compress 1 .
-In extract or list modes, this option is ignored.
-Note that, unlike other
-.Nm tar
-implementations, this implementation recognizes compress compression
-automatically when reading archives.
-.It Fl z , Fl Fl gunzip , Fl Fl gzip
-(c mode only)
-Compress the resulting archive with
-.Xr gzip 1 .
-In extract or list modes, this option is ignored.
-Note that, unlike other
-.Nm tar
-implementations, this implementation recognizes gzip compression
-automatically when reading archives.
-.El
-.Sh ENVIRONMENT
-The following environment variables affect the execution of
-.Nm :
-.Bl -tag -width ".Ev BLOCKSIZE"
-.It Ev LANG
-The locale to use.
-See
-.Xr environ 7
-for more information.
-.It Ev TAPE
-The default device.
-The
-.Fl f
-option overrides this.
-Please see the description of the
-.Fl f
-option above for more details.
-.It Ev TZ
-The timezone to use when displaying dates.
-See
-.Xr environ 7
-for more information.
-.El
-.Sh EXIT STATUS
-.Ex -std
-.Sh EXAMPLES
-The following creates a new archive
-called
-.Ar file.tar.gz
-that contains two files
-.Ar source.c
-and
-.Ar source.h :
-.Dl Nm Fl czf Pa file.tar.gz Pa source.c Pa source.h
-.Pp
-To view a detailed table of contents for this
-archive:
-.Dl Nm Fl tvf Pa file.tar.gz
-.Pp
-To extract all entries from the archive on
-the default tape drive:
-.Dl Nm Fl x
-.Pp
-To examine the contents of an ISO 9660 cdrom image:
-.Dl Nm Fl tf Pa image.iso
-.Pp
-To move file hierarchies, invoke
-.Nm
-as
-.Dl Nm Fl cf Pa - Fl C Pa srcdir\ . | Nm Fl xpf Pa - Fl C Pa destdir
-or more traditionally
-.Dl cd srcdir \&; Nm Fl cf Pa -\ . | ( cd destdir \&; Nm Fl xpf Pa - )
-.Pp
-In create mode, the list of files and directories to be archived
-can also include directory change instructions of the form
-.Cm -C Ns Pa foo/baz
-and archive inclusions of the form
-.Cm @ Ns Pa archive-file .
-For example, the command line
-.Dl Nm Fl c Fl f Pa new.tar Pa foo1 Cm @ Ns Pa old.tgz Cm -C Ns Pa /tmp Pa foo2
-will create a new archive
-.Pa new.tar .
-.Nm
-will read the file
-.Pa foo1
-from the current directory and add it to the output archive.
-It will then read each entry from
-.Pa old.tgz
-and add those entries to the output archive.
-Finally, it will switch to the
-.Pa /tmp
-directory and add
-.Pa foo2
-to the output archive.
-.Pp
-An input file in
-.Xr mtree 5
-format can be used to create an output archive with arbitrary ownership,
-permissions, or names that differ from existing data on disk:
-.Pp
-.Dl $ cat input.mtree
-.Dl #mtree
-.Dl usr/bin uid=0 gid=0 mode=0755 type=dir
-.Dl usr/bin/ls uid=0 gid=0 mode=0755 type=file content=myls
-.Dl $ tar -cvf output.tar @input.mtree
-.Pp
-The
-.Fl Fl newer
-and
-.Fl Fl newer-mtime
-switches accept a variety of common date and time specifications, including
-.Dq 12 Mar 2005 7:14:29pm ,
-.Dq 2005-03-12 19:14 ,
-.Dq 5 minutes ago ,
-and
-.Dq 19:14 PST May 1 .
-.Pp
-The
-.Fl Fl options
-argument can be used to control various details of archive generation
-or reading.
-For example, you can generate mtree output which only contains
-.Cm type , Cm time ,
-and
-.Cm uid
-keywords:
-.Dl Nm Fl cf Pa file.tar Fl Fl format=mtree Fl Fl options='!all,type,time,uid' Pa dir
-or you can set the compression level used by gzip or xz compression:
-.Dl Nm Fl czf Pa file.tar Fl Fl options='compression-level=9' .
-For more details, see the explanation of the
-.Fn archive_read_set_options
-and
-.Fn archive_write_set_options
-API calls that are described in
-.Xr archive_read 3
-and
-.Xr archive_write 3 .
-.Sh COMPATIBILITY
-The bundled-arguments format is supported for compatibility
-with historic implementations.
-It consists of an initial word (with no leading - character) in which
-each character indicates an option.
-Arguments follow as separate words.
-The order of the arguments must match the order
-of the corresponding characters in the bundled command word.
-For example,
-.Dl Nm Cm tbf 32 Pa file.tar
-specifies three flags
-.Cm t ,
-.Cm b ,
-and
-.Cm f .
-The
-.Cm b
-and
-.Cm f
-flags both require arguments,
-so there must be two additional items
-on the command line.
-The
-.Ar 32
-is the argument to the
-.Cm b
-flag, and
-.Ar file.tar
-is the argument to the
-.Cm f
-flag.
-.Pp
-The mode options c, r, t, u, and x and the options
-b, f, l, m, o, v, and w comply with SUSv2.
-.Pp
-For maximum portability, scripts that invoke
-.Nm tar
-should use the bundled-argument format above, should limit
-themselves to the
-.Cm c ,
-.Cm t ,
-and
-.Cm x
-modes, and the
-.Cm b ,
-.Cm f ,
-.Cm m ,
-.Cm v ,
-and
-.Cm w
-options.
-.Pp
-Additional long options are provided to improve compatibility with other
-tar implementations.
-.Sh SECURITY
-Certain security issues are common to many archiving programs, including
-.Nm .
-In particular, carefully-crafted archives can request that
-.Nm
-extract files to locations outside of the target directory.
-This can potentially be used to cause unwitting users to overwrite
-files they did not intend to overwrite.
-If the archive is being extracted by the superuser, any file
-on the system can potentially be overwritten.
-There are three ways this can happen.
-Although
-.Nm
-has mechanisms to protect against each one,
-savvy users should be aware of the implications:
-.Bl -bullet -width indent
-.It
-Archive entries can have absolute pathnames.
-By default,
-.Nm
-removes the leading
-.Pa /
-character from filenames before restoring them to guard against this problem.
-.It
-Archive entries can have pathnames that include
-.Pa ..
-components.
-By default,
-.Nm
-will not extract files containing
-.Pa ..
-components in their pathname.
-.It
-Archive entries can exploit symbolic links to restore
-files to other directories.
-An archive can restore a symbolic link to another directory,
-then use that link to restore a file into that directory.
-To guard against this,
-.Nm
-checks each extracted path for symlinks.
-If the final path element is a symlink, it will be removed
-and replaced with the archive entry.
-If
-.Fl U
-is specified, any intermediate symlink will also be unconditionally removed.
-If neither
-.Fl U
-nor
-.Fl P
-is specified,
-.Nm
-will refuse to extract the entry.
-.El
-To protect yourself, you should be wary of any archives that
-come from untrusted sources.
-You should examine the contents of an archive with
-.Dl Nm Fl tf Pa filename
-before extraction.
-You should use the
-.Fl k
-option to ensure that
-.Nm
-will not overwrite any existing files or the
-.Fl U
-option to remove any pre-existing files.
-You should generally not extract archives while running with super-user
-privileges.
-Note that the
-.Fl P
-option to
-.Nm
-disables the security checks above and allows you to extract
-an archive while preserving any absolute pathnames,
-.Pa ..
-components, or symlinks to other directories.
-.Sh SEE ALSO
-.Xr bzip2 1 ,
-.Xr compress 1 ,
-.Xr cpio 1 ,
-.Xr gzip 1 ,
-.Xr mt 1 ,
-.Xr pax 1 ,
-.Xr shar 1 ,
-.Xr xz 1 ,
-.Xr libarchive 3 ,
-.Xr libarchive-formats 5 ,
-.Xr tar 5
-.Sh STANDARDS
-There is no current POSIX standard for the tar command; it appeared
-in
-.St -p1003.1-96
-but was dropped from
-.St -p1003.1-2001 .
-The options supported by this implementation were developed by surveying a
-number of existing tar implementations as well as the old POSIX specification
-for tar and the current POSIX specification for pax.
-.Pp
-The ustar and pax interchange file formats are defined by
-.St -p1003.1-2001
-for the pax command.
-.Sh HISTORY
-A
-.Nm tar
-command appeared in Seventh Edition Unix, which was released in January, 1979.
-There have been numerous other implementations,
-many of which extended the file format.
-John Gilmore's
-.Nm pdtar
-public-domain implementation (circa November, 1987)
-was quite influential, and formed the basis of GNU tar.
-GNU tar was included as the standard system tar
-in
-.Fx
-beginning with
-.Fx 1.0 .
-.Pp
-This is a complete re-implementation based on the
-.Xr libarchive 3
-library.
-It was first released with
-.Fx 5.4
-in May, 2005.
-.Sh BUGS
-This program follows
-.St -p1003.1-96
-for the definition of the
-.Fl l
-option.
-Note that GNU tar prior to version 1.15 treated
-.Fl l
-as a synonym for the
-.Fl Fl one-file-system
-option.
-.Pp
-The
-.Fl C Pa dir
-option may differ from historic implementations.
-.Pp
-All archive output is written in correctly-sized blocks, even
-if the output is being compressed.
-Whether or not the last output block is padded to a full
-block size varies depending on the format and the
-output device.
-For tar and cpio formats, the last block of output is padded
-to a full block size if the output is being
-written to standard output or to a character or block device such as
-a tape drive.
-If the output is being written to a regular file, the last block
-will not be padded.
-Many compressors, including
-.Xr gzip 1
-and
-.Xr bzip2 1 ,
-complain about the null padding when decompressing an archive created by
-.Nm ,
-although they still extract it correctly.
-.Pp
-The compression and decompression is implemented internally, so
-there may be insignificant differences between the compressed output
-generated by
-.Dl Nm Fl czf Pa - file
-and that generated by
-.Dl Nm Fl cf Pa - file | Nm gzip
-.Pp
-The default should be to read and write archives to the standard I/O paths,
-but tradition (and POSIX) dictates otherwise.
-.Pp
-The
-.Cm r
-and
-.Cm u
-modes require that the archive be uncompressed
-and located in a regular file on disk.
-Other archives can be modified using
-.Cm c
-mode with the
-.Pa @archive-file
-extension.
-.Pp
-To archive a file called
-.Pa @foo
-or
-.Pa -foo
-you must specify it as
-.Pa ./@foo
-or
-.Pa ./-foo ,
-respectively.
-.Pp
-In create mode, a leading
-.Pa ./
-is always removed.
-A leading
-.Pa /
-is stripped unless the
-.Fl P
-option is specified.
-.Pp
-There needs to be better support for file selection on both create
-and extract.
-.Pp
-There is not yet any support for multi-volume archives or for archiving
-sparse files.
-.Pp
-Converting between dissimilar archive formats (such as tar and cpio) using the
-.Cm @ Ns Pa -
-convention can cause hard link information to be lost.
-(This is a consequence of the incompatible ways that different archive
-formats store hardlink information.)
diff --git a/usr.bin/tar/bsdtar.c b/usr.bin/tar/bsdtar.c
deleted file mode 100644
index 0bb6a7fab646..000000000000
--- a/usr.bin/tar/bsdtar.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/*-
- * Copyright (c) 2003-2008 Tim Kientzle
- * 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 "bsdtar_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_LANGINFO_H
-#include <langinfo.h>
-#endif
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "bsdtar.h"
-#include "err.h"
-
-/*
- * Per POSIX.1-1988, tar defaults to reading/writing archives to/from
- * the default tape device for the system. Pick something reasonable here.
- */
-#ifdef __linux
-#define _PATH_DEFTAPE "/dev/st0"
-#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define _PATH_DEFTAPE "\\\\.\\tape0"
-#endif
-
-#ifndef _PATH_DEFTAPE
-#define _PATH_DEFTAPE "/dev/tape"
-#endif
-
-#ifdef __MINGW32__
-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;
-
-static void
-siginfo_handler(int sig)
-{
- (void)sig; /* UNUSED */
- siginfo_occurred = 1;
-}
-
-int
-need_report(void)
-{
- int r = siginfo_occurred;
- siginfo_occurred = 0;
- return (r);
-}
-#else
-int
-need_report(void)
-{
- return (0);
-}
-#endif
-
-/* External function to parse a date/time string */
-time_t get_date(time_t, const char *);
-
-static void long_help(void);
-static void only_mode(struct bsdtar *, const char *opt,
- const char *valid);
-static void set_mode(struct bsdtar *, char opt);
-static void version(void);
-
-/* A basic set of security flags to request from libarchive. */
-#define SECURITY \
- (ARCHIVE_EXTRACT_SECURE_SYMLINKS \
- | ARCHIVE_EXTRACT_SECURE_NODOTDOT)
-
-int
-main(int argc, char **argv)
-{
- struct bsdtar *bsdtar, bsdtar_storage;
- int opt, t;
- char option_o;
- char possible_help_request;
- char buff[16];
- time_t now;
-
- /*
- * Use a pointer for consistency, but stack-allocated storage
- * for ease of cleanup.
- */
- _bsdtar = bsdtar = &bsdtar_storage;
- memset(bsdtar, 0, sizeof(*bsdtar));
- bsdtar->fd = -1; /* Mark as "unused" */
- option_o = 0;
-
-#if defined(HAVE_SIGACTION) && (defined(SIGINFO) || defined(SIGUSR1))
- { /* Catch SIGINFO and SIGUSR1, if they exist. */
- struct sigaction sa;
- sa.sa_handler = siginfo_handler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
-#ifdef SIGINFO
- if (sigaction(SIGINFO, &sa, NULL))
- lafe_errc(1, errno, "sigaction(SIGINFO) failed");
-#endif
-#ifdef SIGUSR1
- /* ... and treat SIGUSR1 the same way as SIGINFO. */
- if (sigaction(SIGUSR1, &sa, NULL))
- lafe_errc(1, errno, "sigaction(SIGUSR1) failed");
-#endif
- }
-#endif
-
- /* Need lafe_progname before calling lafe_warnc. */
- if (*argv == NULL)
- lafe_progname = "bsdtar";
- else {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- lafe_progname = strrchr(*argv, '\\');
-#else
- lafe_progname = strrchr(*argv, '/');
-#endif
- if (lafe_progname != NULL)
- lafe_progname++;
- else
- lafe_progname = *argv;
- }
-
- time(&now);
-
-#if HAVE_SETLOCALE
- if (setlocale(LC_ALL, "") == NULL)
- 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');
-#endif
- possible_help_request = 0;
-
- /* Look up uid of current user for future reference */
- bsdtar->user_uid = geteuid();
-
- /* Default: open tape drive. */
- bsdtar->filename = getenv("TAPE");
- if (bsdtar->filename == NULL)
- bsdtar->filename = _PATH_DEFTAPE;
-
- /* Default: preserve mod time on extract */
- bsdtar->extract_flags = ARCHIVE_EXTRACT_TIME;
-
- /* Default: Perform basic security checks. */
- bsdtar->extract_flags |= SECURITY;
-
-#ifndef _WIN32
- /* On POSIX systems, assume --same-owner and -p when run by
- * the root user. This doesn't make any sense on Windows. */
- if (bsdtar->user_uid == 0) {
- /* --same-owner */
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER;
- /* -p */
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM;
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL;
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR;
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
- }
-#endif
-
- bsdtar->argv = argv;
- bsdtar->argc = argc;
-
- /*
- * Comments following each option indicate where that option
- * originated: SUSv2, POSIX, GNU tar, star, etc. If there's
- * no such comment, then I don't know of anyone else who
- * implements that option.
- */
- while ((opt = bsdtar_getopt(bsdtar)) != -1) {
- switch (opt) {
- case 'B': /* GNU tar */
- /* libarchive doesn't need this; just ignore it. */
- break;
- case 'b': /* SUSv2 */
- t = atoi(bsdtar->optarg);
- if (t <= 0 || t > 8192)
- lafe_errc(1, 0,
- "Argument to -b is out of range (1..8192)");
- bsdtar->bytes_per_block = 512 * t;
- break;
- case 'C': /* GNU tar */
- set_chdir(bsdtar, bsdtar->optarg);
- break;
- case 'c': /* SUSv2 */
- set_mode(bsdtar, opt);
- break;
- case OPTION_CHECK_LINKS: /* GNU tar */
- bsdtar->option_warn_links = 1;
- break;
- case OPTION_CHROOT: /* NetBSD */
- bsdtar->option_chroot = 1;
- break;
- case OPTION_EXCLUDE: /* GNU tar */
- if (lafe_exclude(&bsdtar->matching, bsdtar->optarg))
- lafe_errc(1, 0,
- "Couldn't exclude %s\n", bsdtar->optarg);
- break;
- case OPTION_FORMAT: /* GNU tar, others */
- bsdtar->create_format = bsdtar->optarg;
- break;
- case OPTION_OPTIONS:
- bsdtar->option_options = bsdtar->optarg;
- break;
- case 'f': /* SUSv2 */
- bsdtar->filename = bsdtar->optarg;
- if (strcmp(bsdtar->filename, "-") == 0)
- bsdtar->filename = NULL;
- break;
- case 'H': /* BSD convention */
- bsdtar->symlink_mode = 'H';
- break;
- case 'h': /* Linux Standards Base, gtar; synonym for -L */
- bsdtar->symlink_mode = 'L';
- /* Hack: -h by itself is the "help" command. */
- possible_help_request = 1;
- break;
- case OPTION_HELP: /* GNU tar, others */
- long_help();
- exit(0);
- break;
- case 'I': /* GNU tar */
- /*
- * TODO: Allow 'names' to come from an archive,
- * not just a text file. Design a good UI for
- * allowing names and mode/owner to be read
- * from an archive, with contents coming from
- * disk. This can be used to "refresh" an
- * archive or to design archives with special
- * permissions without having to create those
- * permissions on disk.
- */
- bsdtar->names_from_file = bsdtar->optarg;
- break;
- case OPTION_INCLUDE:
- /*
- * Noone else has the @archive extension, so
- * noone else needs this to filter entries
- * when transforming archives.
- */
- if (lafe_include(&bsdtar->matching, bsdtar->optarg))
- lafe_errc(1, 0,
- "Failed to add %s to inclusion list",
- bsdtar->optarg);
- break;
- case 'j': /* GNU tar */
- if (bsdtar->create_compression != '\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')
- lafe_errc(1, 0,
- "Can't specify both -%c and -%c", opt,
- bsdtar->create_compression);
- bsdtar->create_compression = opt;
- break;
- case 'k': /* GNU tar */
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE;
- break;
- case OPTION_KEEP_NEWER_FILES: /* GNU tar */
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
- break;
- case 'L': /* BSD convention */
- bsdtar->symlink_mode = 'L';
- break;
- case 'l': /* SUSv2 and GNU tar beginning with 1.16 */
- /* GNU tar 1.13 used -l for --one-file-system */
- bsdtar->option_warn_links = 1;
- break;
- case OPTION_LZMA:
- if (bsdtar->create_compression != '\0')
- lafe_errc(1, 0,
- "Can't specify both -%c and -%c", opt,
- bsdtar->create_compression);
- bsdtar->create_compression = opt;
- break;
- case 'm': /* SUSv2 */
- bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_TIME;
- break;
- case 'n': /* GNU tar */
- bsdtar->option_no_subdirs = 1;
- break;
- /*
- * Selecting files by time:
- * --newer-?time='date' Only files newer than 'date'
- * --newer-?time-than='file' Only files newer than time
- * on specified file (useful for incremental backups)
- * TODO: Add corresponding "older" options to reverse these.
- */
- case OPTION_NEWER_CTIME: /* GNU tar */
- bsdtar->newer_ctime_sec = get_date(now, bsdtar->optarg);
- break;
- case OPTION_NEWER_CTIME_THAN:
- {
- struct stat st;
- if (stat(bsdtar->optarg, &st) != 0)
- lafe_errc(1, 0,
- "Can't open file %s", bsdtar->optarg);
- bsdtar->newer_ctime_sec = st.st_ctime;
- bsdtar->newer_ctime_nsec =
- ARCHIVE_STAT_CTIME_NANOS(&st);
- }
- break;
- case OPTION_NEWER_MTIME: /* GNU tar */
- bsdtar->newer_mtime_sec = get_date(now, bsdtar->optarg);
- break;
- case OPTION_NEWER_MTIME_THAN:
- {
- struct stat st;
- if (stat(bsdtar->optarg, &st) != 0)
- lafe_errc(1, 0,
- "Can't open file %s", bsdtar->optarg);
- bsdtar->newer_mtime_sec = st.st_mtime;
- bsdtar->newer_mtime_nsec =
- ARCHIVE_STAT_MTIME_NANOS(&st);
- }
- break;
- case OPTION_NODUMP: /* star */
- bsdtar->option_honor_nodump = 1;
- break;
- case OPTION_NO_SAME_OWNER: /* GNU tar */
- bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
- break;
- case OPTION_NO_SAME_PERMISSIONS: /* GNU tar */
- bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_PERM;
- bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_ACL;
- bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_XATTR;
- bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_FFLAGS;
- break;
- case OPTION_NULL: /* GNU tar */
- bsdtar->option_null++;
- break;
- case OPTION_NUMERIC_OWNER: /* GNU tar */
- bsdtar->option_numeric_owner++;
- break;
- case 'O': /* GNU tar */
- bsdtar->option_stdout = 1;
- break;
- case 'o': /* SUSv2 and GNU conflict here, but not fatally */
- option_o = 1; /* Record it and resolve it later. */
- break;
- case OPTION_ONE_FILE_SYSTEM: /* GNU tar */
- bsdtar->option_dont_traverse_mounts = 1;
- break;
-#if 0
- /*
- * The common BSD -P option is not necessary, since
- * our default is to archive symlinks, not follow
- * them. This is convenient, as -P conflicts with GNU
- * tar anyway.
- */
- case 'P': /* BSD convention */
- /* Default behavior, no option necessary. */
- break;
-#endif
- case 'P': /* GNU tar */
- bsdtar->extract_flags &= ~SECURITY;
- bsdtar->option_absolute_paths = 1;
- break;
- case 'p': /* GNU tar, star */
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM;
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL;
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR;
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
- break;
- case OPTION_POSIX: /* GNU tar */
- bsdtar->create_format = "pax";
- break;
- case 'q': /* FreeBSD GNU tar --fast-read, NetBSD -q */
- bsdtar->option_fast_read = 1;
- break;
- case 'r': /* SUSv2 */
- set_mode(bsdtar, opt);
- break;
- case 'S': /* NetBSD pax-as-tar */
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_SPARSE;
- break;
- case 's': /* NetBSD pax-as-tar */
-#if HAVE_REGEX_H
- add_substitution(bsdtar, bsdtar->optarg);
-#else
- lafe_warnc(0,
- "-s is not supported by this version of bsdtar");
- usage();
-#endif
- break;
- case OPTION_SAME_OWNER: /* GNU tar */
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER;
- break;
- case OPTION_STRIP_COMPONENTS: /* GNU tar 1.15 */
- bsdtar->strip_components = atoi(bsdtar->optarg);
- break;
- case 'T': /* GNU tar */
- bsdtar->names_from_file = bsdtar->optarg;
- break;
- case 't': /* SUSv2 */
- set_mode(bsdtar, opt);
- bsdtar->verbose++;
- break;
- case OPTION_TOTALS: /* GNU tar */
- bsdtar->option_totals++;
- break;
- case 'U': /* GNU tar */
- bsdtar->extract_flags |= ARCHIVE_EXTRACT_UNLINK;
- bsdtar->option_unlink_first = 1;
- break;
- case 'u': /* SUSv2 */
- set_mode(bsdtar, opt);
- break;
- case 'v': /* SUSv2 */
- bsdtar->verbose++;
- break;
- case OPTION_VERSION: /* GNU convention */
- version();
- break;
-#if 0
- /*
- * The -W longopt feature is handled inside of
- * bsdtar_getopt(), so -W is not available here.
- */
- case 'W': /* Obscure GNU convention. */
- break;
-#endif
- case 'w': /* SUSv2 */
- bsdtar->option_interactive = 1;
- break;
- case 'X': /* GNU tar */
- if (lafe_exclude_from_file(&bsdtar->matching, bsdtar->optarg))
- lafe_errc(1, 0,
- "failed to process exclusions from file %s",
- bsdtar->optarg);
- break;
- case 'x': /* SUSv2 */
- set_mode(bsdtar, opt);
- break;
- case 'y': /* FreeBSD version of GNU tar */
- if (bsdtar->create_compression != '\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')
- 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')
- lafe_errc(1, 0,
- "Can't specify both -%c and -%c", opt,
- bsdtar->create_compression);
- bsdtar->create_compression = opt;
- break;
- case OPTION_USE_COMPRESS_PROGRAM:
- bsdtar->compress_program = bsdtar->optarg;
- break;
- default:
- usage();
- }
- }
-
- /*
- * Sanity-check options.
- */
-
- /* If no "real" mode was specified, treat -h as --help. */
- if ((bsdtar->mode == '\0') && possible_help_request) {
- long_help();
- exit(0);
- }
-
- /* Otherwise, a mode is required. */
- if (bsdtar->mode == '\0')
- lafe_errc(1, 0,
- "Must specify one of -c, -r, -t, -u, -x");
-
- /* Check boolean options only permitted in certain modes. */
- if (bsdtar->option_dont_traverse_mounts)
- only_mode(bsdtar, "--one-file-system", "cru");
- if (bsdtar->option_fast_read)
- only_mode(bsdtar, "--fast-read", "xt");
- if (bsdtar->option_honor_nodump)
- only_mode(bsdtar, "--nodump", "cru");
- if (option_o > 0) {
- switch (bsdtar->mode) {
- case 'c':
- /*
- * In GNU tar, -o means "old format." The
- * "ustar" format is the closest thing
- * supported by libarchive.
- */
- bsdtar->create_format = "ustar";
- /* TODO: bsdtar->create_format = "v7"; */
- break;
- case 'x':
- /* POSIX-compatible behavior. */
- bsdtar->option_no_owner = 1;
- bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
- break;
- default:
- only_mode(bsdtar, "-o", "xc");
- break;
- }
- }
- if (bsdtar->option_no_subdirs)
- only_mode(bsdtar, "-n", "cru");
- if (bsdtar->option_stdout)
- only_mode(bsdtar, "-O", "xt");
- if (bsdtar->option_unlink_first)
- only_mode(bsdtar, "-U", "x");
- if (bsdtar->option_warn_links)
- only_mode(bsdtar, "--check-links", "cr");
-
- /* Check other parameters only permitted in certain modes. */
- if (bsdtar->create_compression != '\0') {
- strcpy(buff, "-?");
- buff[1] = bsdtar->create_compression;
- only_mode(bsdtar, buff, "cxt");
- }
- if (bsdtar->create_format != NULL)
- only_mode(bsdtar, "--format", "cru");
- if (bsdtar->symlink_mode != '\0') {
- strcpy(buff, "-?");
- buff[1] = bsdtar->symlink_mode;
- only_mode(bsdtar, buff, "cru");
- }
- if (bsdtar->strip_components != 0)
- only_mode(bsdtar, "--strip-components", "xt");
-
- switch(bsdtar->mode) {
- case 'c':
- tar_mode_c(bsdtar);
- break;
- case 'r':
- tar_mode_r(bsdtar);
- break;
- case 't':
- tar_mode_t(bsdtar);
- break;
- case 'u':
- tar_mode_u(bsdtar);
- break;
- case 'x':
- tar_mode_x(bsdtar);
- break;
- }
-
- lafe_cleanup_exclusions(&bsdtar->matching);
-#if HAVE_REGEX_H
- cleanup_substitution(bsdtar);
-#endif
-
- if (bsdtar->return_value != 0)
- lafe_warnc(0,
- "Error exit delayed from previous errors.");
- return (bsdtar->return_value);
-}
-
-static void
-set_mode(struct bsdtar *bsdtar, char opt)
-{
- if (bsdtar->mode != '\0' && bsdtar->mode != opt)
- lafe_errc(1, 0,
- "Can't specify both -%c and -%c", opt, bsdtar->mode);
- bsdtar->mode = opt;
-}
-
-/*
- * Verify that the mode is correct.
- */
-static void
-only_mode(struct bsdtar *bsdtar, const char *opt, const char *valid_modes)
-{
- if (strchr(valid_modes, bsdtar->mode) == NULL)
- lafe_errc(1, 0,
- "Option %s is not permitted in mode -%c",
- opt, bsdtar->mode);
-}
-
-
-void
-usage(void)
-{
- const char *p;
-
- p = lafe_progname;
-
- fprintf(stderr, "Usage:\n");
- fprintf(stderr, " List: %s -tf <archive-filename>\n", p);
- fprintf(stderr, " Extract: %s -xf <archive-filename>\n", p);
- fprintf(stderr, " Create: %s -cf <archive-filename> [filenames...]\n", p);
- fprintf(stderr, " Help: %s --help\n", p);
- exit(1);
-}
-
-static void
-version(void)
-{
- printf("bsdtar %s - %s\n",
- BSDTAR_VERSION_STRING,
- archive_version());
- exit(0);
-}
-
-static const char *long_help_msg =
- "First option must be a mode specifier:\n"
- " -c Create -r Add/Replace -t List -u Update -x Extract\n"
- "Common Options:\n"
- " -b # Use # 512-byte records per I/O block\n"
- " -f <filename> Location of archive (default " _PATH_DEFTAPE ")\n"
- " -v Verbose\n"
- " -w Interactive\n"
- "Create: %p -c [options] [<file> | <dir> | @<archive> | -C <dir> ]\n"
- " <file>, <dir> add these items to archive\n"
- " -z, -j, -J, --lzma Compress archive with gzip/bzip2/xz/lzma\n"
- " --format {ustar|pax|cpio|shar} Select archive format\n"
- " --exclude <pattern> Skip files that match pattern\n"
- " -C <dir> Change to <dir> before processing remaining files\n"
- " @<archive> Add entries from <archive> to output\n"
- "List: %p -t [options] [<patterns>]\n"
- " <patterns> If specified, list only entries that match\n"
- "Extract: %p -x [options] [<patterns>]\n"
- " <patterns> If specified, extract only entries that match\n"
- " -k Keep (don't overwrite) existing files\n"
- " -m Don't restore modification times\n"
- " -O Write entries to stdout, don't restore to disk\n"
- " -p Restore permissions (including ACLs, owner, file flags)\n";
-
-
-/*
- * Note that the word 'bsdtar' will always appear in the first line
- * of output.
- *
- * In particular, /bin/sh scripts that need to test for the presence
- * of bsdtar can use the following template:
- *
- * if (tar --help 2>&1 | grep bsdtar >/dev/null 2>&1 ) then \
- * echo bsdtar; else echo not bsdtar; fi
- */
-static void
-long_help(void)
-{
- const char *prog;
- const char *p;
-
- prog = lafe_progname;
-
- fflush(stderr);
-
- p = (strcmp(prog,"bsdtar") != 0) ? "(bsdtar)" : "";
- printf("%s%s: manipulate archive files\n", prog, p);
-
- for (p = long_help_msg; *p != '\0'; p++) {
- if (*p == '%') {
- if (p[1] == 'p') {
- fputs(prog, stdout);
- p++;
- } else
- putchar('%');
- } else
- putchar(*p);
- }
- version();
-}
diff --git a/usr.bin/tar/bsdtar.h b/usr.bin/tar/bsdtar.h
deleted file mode 100644
index 919156a0b1ab..000000000000
--- a/usr.bin/tar/bsdtar.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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.
- *
- * $FreeBSD$
- */
-
-#include "bsdtar_platform.h"
-#include <stdio.h>
-
-#include "matching.h"
-
-#define DEFAULT_BYTES_PER_BLOCK (20*512)
-
-/*
- * The internal state for the "bsdtar" program.
- *
- * Keeping all of the state in a structure like this simplifies memory
- * leak testing (at exit, anything left on the heap is suspect). A
- * pointer to this structure is passed to most bsdtar internal
- * functions.
- */
-struct bsdtar {
- /* Options */
- const char *filename; /* -f filename */
- const char *create_format; /* -F format */
- char *pending_chdir; /* -C dir */
- const char *names_from_file; /* -T file */
- time_t newer_ctime_sec; /* --newer/--newer-than */
- long newer_ctime_nsec; /* --newer/--newer-than */
- time_t newer_mtime_sec; /* --newer-mtime */
- long newer_mtime_nsec; /* --newer-mtime-than */
- int bytes_per_block; /* -b block_size */
- int verbose; /* -v */
- int extract_flags; /* Flags for extract operation */
- int strip_components; /* Remove this many leading dirs */
- char mode; /* Program mode: 'c', 't', 'r', 'u', 'x' */
- char symlink_mode; /* H or L, per BSD conventions */
- char create_compression; /* j, y, or z */
- const char *compress_program;
- char option_absolute_paths; /* -P */
- char option_chroot; /* --chroot */
- char option_dont_traverse_mounts; /* --one-file-system */
- char option_fast_read; /* --fast-read */
- const char *option_options; /* --options */
- char option_honor_nodump; /* --nodump */
- char option_interactive; /* -w */
- char option_no_owner; /* -o */
- char option_no_subdirs; /* -n */
- char option_null; /* --null */
- char option_numeric_owner; /* --numeric-owner */
- char option_stdout; /* -O */
- char option_totals; /* --totals */
- char option_unlink_first; /* -U */
- char option_warn_links; /* --check-links */
- char day_first; /* show day before month in -tv output */
-
- /* If >= 0, then close this when done. */
- int fd;
-
- /* Miscellaneous state information */
- int argc;
- char **argv;
- const char *optarg;
- size_t gs_width; /* For 'list_item' in read.c */
- size_t u_width; /* for 'list_item' in read.c */
- uid_t user_uid; /* UID running this program */
- int return_value; /* Value returned by main() */
- char warned_lead_slash; /* Already displayed warning */
- char next_line_is_dir; /* Used for -C parsing in -cT */
-
- /*
- * Data for various subsystems. Full definitions are located in
- * the file where they are used.
- */
- struct archive *diskreader; /* for write.c */
- struct archive_entry_linkresolver *resolver; /* for write.c */
- struct archive_dir *archive_dir; /* for write.c */
- struct name_cache *gname_cache; /* for write.c */
- char *buff; /* for write.c */
- struct lafe_matching *matching; /* for matching.c */
- struct security *security; /* for read.c */
- struct name_cache *uname_cache; /* for write.c */
- struct siginfo_data *siginfo; /* for siginfo.c */
- struct substitution *substitution; /* for subst.c */
-};
-
-/* Fake short equivalents for long options that otherwise lack them. */
-enum {
- OPTION_CHECK_LINKS = 1,
- OPTION_CHROOT,
- OPTION_EXCLUDE,
- OPTION_FORMAT,
- OPTION_OPTIONS,
- OPTION_HELP,
- OPTION_INCLUDE,
- OPTION_KEEP_NEWER_FILES,
- OPTION_LZMA,
- OPTION_NEWER_CTIME,
- OPTION_NEWER_CTIME_THAN,
- OPTION_NEWER_MTIME,
- OPTION_NEWER_MTIME_THAN,
- OPTION_NODUMP,
- OPTION_NO_SAME_OWNER,
- OPTION_NO_SAME_PERMISSIONS,
- OPTION_NULL,
- OPTION_NUMERIC_OWNER,
- OPTION_ONE_FILE_SYSTEM,
- OPTION_POSIX,
- OPTION_SAME_OWNER,
- OPTION_STRIP_COMPONENTS,
- OPTION_TOTALS,
- OPTION_USE_COMPRESS_PROGRAM,
- OPTION_VERSION
-};
-
-int bsdtar_getopt(struct bsdtar *);
-void do_chdir(struct bsdtar *);
-int edit_pathname(struct bsdtar *, struct archive_entry *);
-int need_report(void);
-int pathcmp(const char *a, const char *b);
-void safe_fprintf(FILE *, const char *fmt, ...);
-void set_chdir(struct bsdtar *, const char *newdir);
-const char *tar_i64toa(int64_t);
-void tar_mode_c(struct bsdtar *bsdtar);
-void tar_mode_r(struct bsdtar *bsdtar);
-void tar_mode_t(struct bsdtar *bsdtar);
-void tar_mode_u(struct bsdtar *bsdtar);
-void tar_mode_x(struct bsdtar *bsdtar);
-void usage(void);
-int yes(const char *fmt, ...);
-
-#if HAVE_REGEX_H
-void add_substitution(struct bsdtar *, const char *);
-int apply_substitution(struct bsdtar *, const char *, char **, int);
-void cleanup_substitution(struct bsdtar *);
-#endif
diff --git a/usr.bin/tar/bsdtar_platform.h b/usr.bin/tar/bsdtar_platform.h
deleted file mode 100644
index c9b9dd6b4206..000000000000
--- a/usr.bin/tar/bsdtar_platform.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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.
- *
- * $FreeBSD$
- */
-
-/*
- * This header is the first thing included in any of the bsdtar
- * source files. As far as possible, platform-specific issues should
- * be dealt with here and not within individual source files.
- */
-
-#ifndef BSDTAR_PLATFORM_H_INCLUDED
-#define BSDTAR_PLATFORM_H_INCLUDED
-
-#if defined(PLATFORM_CONFIG_H)
-/* Use hand-built config.h in environments that need it. */
-#include PLATFORM_CONFIG_H
-#else
-/* Not having a config.h of some sort is a serious problem. */
-#include "config.h"
-#endif
-
-/* Get a real definition for __FBSDID if we can */
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
-/* If not, define it so as to avoid dangling semicolons. */
-#ifndef __FBSDID
-#define __FBSDID(a) struct _undefined_hack
-#endif
-
-#ifdef HAVE_LIBARCHIVE
-/* If we're using the platform libarchive, include system headers. */
-#include <archive.h>
-#include <archive_entry.h>
-#else
-/* Otherwise, include user headers. */
-#include "archive.h"
-#include "archive_entry.h"
-#endif
-
-#ifdef HAVE_LIBACL
-#include <acl/libacl.h>
-#endif
-
-/*
- * Include "dirent.h" (or it's equivalent on several different platforms).
- *
- * This is slightly modified from the GNU autoconf recipe.
- * In particular, FreeBSD includes d_namlen in it's dirent structure,
- * so my configure script includes an explicit test for the d_namlen
- * field.
- */
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# if HAVE_DIRENT_D_NAMLEN
-# define DIRENT_NAMLEN(dirent) (dirent)->d_namlen
-# else
-# define DIRENT_NAMLEN(dirent) strlen((dirent)->d_name)
-# endif
-#else
-# define dirent direct
-# define DIRENT_NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif
-#endif
-
-#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
-#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_ctimespec.tv_nsec
-#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_mtimespec.tv_nsec
-#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
-#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_ctim.tv_nsec
-#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_mtim.tv_nsec
-#elif HAVE_STRUCT_STAT_ST_MTIME_N
-#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_ctime_n
-#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_mtime_n
-#elif HAVE_STRUCT_STAT_ST_UMTIME
-#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_uctime * 1000
-#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_umtime * 1000
-#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
-#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_ctime_usec * 1000
-#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_mtime_usec * 1000
-#else
-#define ARCHIVE_STAT_CTIME_NANOS(st) (0)
-#define ARCHIVE_STAT_MTIME_NANOS(st) (0)
-#endif
-
-/* How to mark functions that don't return. */
-/* This facilitates use of some newer static code analysis tools. */
-#undef __LA_DEAD
-#if defined(__GNUC__) && (__GNUC__ > 2 || \
- (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
-#define __LA_DEAD __attribute__((__noreturn__))
-#else
-#define __LA_DEAD
-#endif
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include "bsdtar_windows.h"
-#endif
-
-#endif /* !BSDTAR_PLATFORM_H_INCLUDED */
diff --git a/usr.bin/tar/cmdline.c b/usr.bin/tar/cmdline.c
deleted file mode 100644
index ba3e8a1b2a88..000000000000
--- a/usr.bin/tar/cmdline.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*-
- * Copyright (c) 2003-2008 Tim Kientzle
- * 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.
- */
-
-/*
- * Command line parser for tar.
- */
-
-#include "bsdtar_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "bsdtar.h"
-#include "err.h"
-
-/*
- * Short options for tar. Please keep this sorted.
- */
-static const char *short_options
- = "Bb:C:cf:HhI:JjkLlmnOoPpqrSs:T:tUuvW:wX:xyZz";
-
-/*
- * Long options for tar. Please keep this list sorted.
- *
- * The symbolic names for options that lack a short equivalent are
- * defined in bsdtar.h. Also note that so far I've found no need
- * to support optional arguments to long options. That would be
- * a small change to the code below.
- */
-
-static struct option {
- const char *name;
- int required; /* 1 if this option requires an argument. */
- int equivalent; /* Equivalent short option. */
-} tar_longopts[] = {
- { "absolute-paths", 0, 'P' },
- { "append", 0, 'r' },
- { "block-size", 1, 'b' },
- { "bunzip2", 0, 'j' },
- { "bzip", 0, 'j' },
- { "bzip2", 0, 'j' },
- { "cd", 1, 'C' },
- { "check-links", 0, OPTION_CHECK_LINKS },
- { "chroot", 0, OPTION_CHROOT },
- { "compress", 0, 'Z' },
- { "confirmation", 0, 'w' },
- { "create", 0, 'c' },
- { "dereference", 0, 'L' },
- { "directory", 1, 'C' },
- { "exclude", 1, OPTION_EXCLUDE },
- { "exclude-from", 1, 'X' },
- { "extract", 0, 'x' },
- { "fast-read", 0, 'q' },
- { "file", 1, 'f' },
- { "files-from", 1, 'T' },
- { "format", 1, OPTION_FORMAT },
- { "options", 1, OPTION_OPTIONS },
- { "gunzip", 0, 'z' },
- { "gzip", 0, 'z' },
- { "help", 0, OPTION_HELP },
- { "include", 1, OPTION_INCLUDE },
- { "interactive", 0, 'w' },
- { "insecure", 0, 'P' },
- { "keep-newer-files", 0, OPTION_KEEP_NEWER_FILES },
- { "keep-old-files", 0, 'k' },
- { "list", 0, 't' },
- { "lzma", 0, OPTION_LZMA },
- { "modification-time", 0, 'm' },
- { "newer", 1, OPTION_NEWER_CTIME },
- { "newer-ctime", 1, OPTION_NEWER_CTIME },
- { "newer-ctime-than", 1, OPTION_NEWER_CTIME_THAN },
- { "newer-mtime", 1, OPTION_NEWER_MTIME },
- { "newer-mtime-than", 1, OPTION_NEWER_MTIME_THAN },
- { "newer-than", 1, OPTION_NEWER_CTIME_THAN },
- { "nodump", 0, OPTION_NODUMP },
- { "norecurse", 0, 'n' },
- { "no-recursion", 0, 'n' },
- { "no-same-owner", 0, OPTION_NO_SAME_OWNER },
- { "no-same-permissions", 0, OPTION_NO_SAME_PERMISSIONS },
- { "null", 0, OPTION_NULL },
- { "numeric-owner", 0, OPTION_NUMERIC_OWNER },
- { "one-file-system", 0, OPTION_ONE_FILE_SYSTEM },
- { "posix", 0, OPTION_POSIX },
- { "preserve-permissions", 0, 'p' },
- { "read-full-blocks", 0, 'B' },
- { "same-owner", 0, OPTION_SAME_OWNER },
- { "same-permissions", 0, 'p' },
- { "strip-components", 1, OPTION_STRIP_COMPONENTS },
- { "to-stdout", 0, 'O' },
- { "totals", 0, OPTION_TOTALS },
- { "uncompress", 0, 'Z' },
- { "unlink", 0, 'U' },
- { "unlink-first", 0, 'U' },
- { "update", 0, 'u' },
- { "use-compress-program", 1, OPTION_USE_COMPRESS_PROGRAM },
- { "verbose", 0, 'v' },
- { "version", 0, OPTION_VERSION },
- { "xz", 0, 'J' },
- { NULL, 0, 0 }
-};
-
-/*
- * This getopt implementation has two key features that common
- * getopt_long() implementations lack. Apart from those, it's a
- * straightforward option parser, considerably simplified by not
- * needing to support the wealth of exotic getopt_long() features. It
- * has, of course, been shamelessly tailored for bsdtar. (If you're
- * looking for a generic getopt_long() implementation for your
- * project, I recommend Gregory Pietsch's public domain getopt_long()
- * implementation.) The two additional features are:
- *
- * Old-style tar arguments: The original tar implementation treated
- * the first argument word as a list of single-character option
- * letters. All arguments follow as separate words. For example,
- * tar xbf 32 /dev/tape
- * Here, the "xbf" is three option letters, "32" is the argument for
- * "b" and "/dev/tape" is the argument for "f". We support this usage
- * if the first command-line argument does not begin with '-'. We
- * also allow regular short and long options to follow, e.g.,
- * tar xbf 32 /dev/tape -P --format=pax
- *
- * -W long options: There's an obscure GNU convention (only rarely
- * supported even there) that allows "-W option=argument" as an
- * alternative way to support long options. This was supported in
- * early bsdtar as a way to access long options on platforms that did
- * not support getopt_long() and is preserved here for backwards
- * compatibility. (Of course, if I'd started with a custom
- * command-line parser from the beginning, I would have had normal
- * long option support on every platform so that hack wouldn't have
- * been necessary. Oh, well. Some mistakes you just have to live
- * with.)
- *
- * TODO: We should be able to use this to pull files and intermingled
- * options (such as -C) from the command line in write mode. That
- * will require a little rethinking of the argument handling in
- * bsdtar.c.
- *
- * TODO: If we want to support arbitrary command-line options from -T
- * input (as GNU tar does), we may need to extend this to handle option
- * words from sources other than argv/arc. I'm not really sure if I
- * like that feature of GNU tar, so it's certainly not a priority.
- */
-
-int
-bsdtar_getopt(struct bsdtar *bsdtar)
-{
- enum { state_start = 0, state_old_tar, state_next_word,
- state_short, state_long };
- static int state = state_start;
- static char *opt_word;
-
- const struct option *popt, *match = NULL, *match2 = NULL;
- const char *p, *long_prefix = "--";
- size_t optlength;
- int opt = '?';
- int required = 0;
-
- bsdtar->optarg = NULL;
-
- /* First time through, initialize everything. */
- if (state == state_start) {
- /* Skip program name. */
- ++bsdtar->argv;
- --bsdtar->argc;
- if (*bsdtar->argv == NULL)
- return (-1);
- /* Decide between "new style" and "old style" arguments. */
- if (bsdtar->argv[0][0] == '-') {
- state = state_next_word;
- } else {
- state = state_old_tar;
- opt_word = *bsdtar->argv++;
- --bsdtar->argc;
- }
- }
-
- /*
- * We're parsing old-style tar arguments
- */
- if (state == state_old_tar) {
- /* Get the next option character. */
- opt = *opt_word++;
- if (opt == '\0') {
- /* New-style args can follow old-style. */
- state = state_next_word;
- } else {
- /* See if it takes an argument. */
- p = strchr(short_options, opt);
- if (p == NULL)
- return ('?');
- if (p[1] == ':') {
- bsdtar->optarg = *bsdtar->argv;
- if (bsdtar->optarg == NULL) {
- lafe_warnc(0,
- "Option %c requires an argument",
- opt);
- return ('?');
- }
- ++bsdtar->argv;
- --bsdtar->argc;
- }
- }
- }
-
- /*
- * We're ready to look at the next word in argv.
- */
- if (state == state_next_word) {
- /* No more arguments, so no more options. */
- if (bsdtar->argv[0] == NULL)
- return (-1);
- /* Doesn't start with '-', so no more options. */
- if (bsdtar->argv[0][0] != '-')
- return (-1);
- /* "--" marks end of options; consume it and return. */
- if (strcmp(bsdtar->argv[0], "--") == 0) {
- ++bsdtar->argv;
- --bsdtar->argc;
- return (-1);
- }
- /* Get next word for parsing. */
- opt_word = *bsdtar->argv++;
- --bsdtar->argc;
- if (opt_word[1] == '-') {
- /* Set up long option parser. */
- state = state_long;
- opt_word += 2; /* Skip leading '--' */
- } else {
- /* Set up short option parser. */
- state = state_short;
- ++opt_word; /* Skip leading '-' */
- }
- }
-
- /*
- * We're parsing a group of POSIX-style single-character options.
- */
- if (state == state_short) {
- /* Peel next option off of a group of short options. */
- opt = *opt_word++;
- if (opt == '\0') {
- /* End of this group; recurse to get next option. */
- state = state_next_word;
- return bsdtar_getopt(bsdtar);
- }
-
- /* Does this option take an argument? */
- p = strchr(short_options, opt);
- if (p == NULL)
- return ('?');
- if (p[1] == ':')
- required = 1;
-
- /* If it takes an argument, parse that. */
- if (required) {
- /* If arg is run-in, opt_word already points to it. */
- if (opt_word[0] == '\0') {
- /* Otherwise, pick up the next word. */
- opt_word = *bsdtar->argv;
- if (opt_word == NULL) {
- lafe_warnc(0,
- "Option -%c requires an argument",
- opt);
- return ('?');
- }
- ++bsdtar->argv;
- --bsdtar->argc;
- }
- if (opt == 'W') {
- state = state_long;
- long_prefix = "-W "; /* For clearer errors. */
- } else {
- state = state_next_word;
- bsdtar->optarg = opt_word;
- }
- }
- }
-
- /* We're reading a long option, including -W long=arg convention. */
- if (state == state_long) {
- /* After this long option, we'll be starting a new word. */
- state = state_next_word;
-
- /* Option name ends at '=' if there is one. */
- p = strchr(opt_word, '=');
- if (p != NULL) {
- optlength = (size_t)(p - opt_word);
- bsdtar->optarg = (char *)(uintptr_t)(p + 1);
- } else {
- optlength = strlen(opt_word);
- }
-
- /* Search the table for an unambiguous match. */
- for (popt = tar_longopts; popt->name != NULL; popt++) {
- /* Short-circuit if first chars don't match. */
- if (popt->name[0] != opt_word[0])
- continue;
- /* If option is a prefix of name in table, record it.*/
- if (strncmp(opt_word, popt->name, optlength) == 0) {
- match2 = match; /* Record up to two matches. */
- match = popt;
- /* If it's an exact match, we're done. */
- if (strlen(popt->name) == optlength) {
- match2 = NULL; /* Forget the others. */
- break;
- }
- }
- }
-
- /* Fail if there wasn't a unique match. */
- if (match == NULL) {
- lafe_warnc(0,
- "Option %s%s is not supported",
- long_prefix, opt_word);
- return ('?');
- }
- if (match2 != NULL) {
- lafe_warnc(0,
- "Ambiguous option %s%s (matches --%s and --%s)",
- long_prefix, opt_word, match->name, match2->name);
- return ('?');
- }
-
- /* We've found a unique match; does it need an argument? */
- if (match->required) {
- /* Argument required: get next word if necessary. */
- if (bsdtar->optarg == NULL) {
- bsdtar->optarg = *bsdtar->argv;
- if (bsdtar->optarg == NULL) {
- lafe_warnc(0,
- "Option %s%s requires an argument",
- long_prefix, match->name);
- return ('?');
- }
- ++bsdtar->argv;
- --bsdtar->argc;
- }
- } else {
- /* Argument forbidden: fail if there is one. */
- if (bsdtar->optarg != NULL) {
- lafe_warnc(0,
- "Option %s%s does not allow an argument",
- long_prefix, match->name);
- return ('?');
- }
- }
- return (match->equivalent);
- }
-
- return (opt);
-}
diff --git a/usr.bin/tar/getdate.c b/usr.bin/tar/getdate.c
deleted file mode 100644
index ffaa679ba1a3..000000000000
--- a/usr.bin/tar/getdate.c
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- * This code is in the public domain and has no copyright.
- *
- * This is a plain C recursive-descent translation of an old
- * public-domain YACC grammar that has been used for parsing dates in
- * very many open-source projects.
- *
- * Since the original authors were generous enough to donate their
- * work to the public domain, I feel compelled to match their
- * generosity.
- *
- * Tim Kientzle, February 2009.
- */
-
-/*
- * Header comment from original getdate.y:
- */
-
-/*
-** Originally written by Steven M. Bellovin <smb@research.att.com> while
-** at the University of North Carolina at Chapel Hill. Later tweaked by
-** a couple of people on Usenet. Completely overhauled by Rich $alz
-** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
-**
-** This grammar has 10 shift/reduce conflicts.
-**
-** This code is in the public domain and has no copyright.
-*/
-
-#ifdef __FreeBSD__
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-/* This file defines a single public function. */
-time_t get_date(time_t now, char *);
-
-/* Basic time units. */
-#define EPOCH 1970
-#define MINUTE (60L)
-#define HOUR (60L * MINUTE)
-#define DAY (24L * HOUR)
-
-/* Daylight-savings mode: on, off, or not yet known. */
-enum DSTMODE { DSTon, DSToff, DSTmaybe };
-/* Meridian: am or pm. */
-enum { tAM, tPM };
-/* Token types returned by nexttoken() */
-enum { tAGO = 260, tDAY, tDAYZONE, tAMPM, tMONTH, tMONTH_UNIT, tSEC_UNIT,
- tUNUMBER, tZONE, tDST };
-struct token { int token; time_t value; };
-
-/*
- * Parser state.
- */
-struct gdstate {
- struct token *tokenp; /* Pointer to next token. */
- /* HaveXxxx counts how many of this kind of phrase we've seen;
- * it's a fatal error to have more than one time, zone, day,
- * or date phrase. */
- int HaveYear;
- int HaveMonth;
- int HaveDay;
- int HaveWeekDay; /* Day of week */
- int HaveTime; /* Hour/minute/second */
- int HaveZone; /* timezone and/or DST info */
- int HaveRel; /* time offset; we can have more than one */
- /* Absolute time values. */
- time_t Timezone; /* Seconds offset from GMT */
- time_t Day;
- time_t Hour;
- time_t Minutes;
- time_t Month;
- time_t Seconds;
- time_t Year;
- /* DST selection */
- enum DSTMODE DSTmode;
- /* Day of week accounting, e.g., "3rd Tuesday" */
- time_t DayOrdinal; /* "3" in "3rd Tuesday" */
- time_t DayNumber; /* "Tuesday" in "3rd Tuesday" */
- /* Relative time values: hour/day/week offsets are measured in
- * seconds, month/year are counted in months. */
- time_t RelMonth;
- time_t RelSeconds;
-};
-
-/*
- * A series of functions that recognize certain common time phrases.
- * Each function returns 1 if it managed to make sense of some of the
- * tokens, zero otherwise.
- */
-
-/*
- * hour:minute or hour:minute:second with optional AM, PM, or numeric
- * timezone offset
- */
-static int
-timephrase(struct gdstate *gds)
-{
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == ':'
- && gds->tokenp[2].token == tUNUMBER
- && gds->tokenp[3].token == ':'
- && gds->tokenp[4].token == tUNUMBER) {
- /* "12:14:18" or "22:08:07" */
- ++gds->HaveTime;
- gds->Hour = gds->tokenp[0].value;
- gds->Minutes = gds->tokenp[2].value;
- gds->Seconds = gds->tokenp[4].value;
- gds->tokenp += 5;
- }
- else if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == ':'
- && gds->tokenp[2].token == tUNUMBER) {
- /* "12:14" or "22:08" */
- ++gds->HaveTime;
- gds->Hour = gds->tokenp[0].value;
- gds->Minutes = gds->tokenp[2].value;
- gds->Seconds = 0;
- gds->tokenp += 3;
- }
- else if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tAMPM) {
- /* "7" is a time if it's followed by "am" or "pm" */
- ++gds->HaveTime;
- gds->Hour = gds->tokenp[0].value;
- gds->Minutes = gds->Seconds = 0;
- /* We'll handle the AM/PM below. */
- gds->tokenp += 1;
- } else {
- /* We can't handle this. */
- return 0;
- }
-
- if (gds->tokenp[0].token == tAMPM) {
- /* "7:12pm", "12:20:13am" */
- if (gds->Hour == 12)
- gds->Hour = 0;
- if (gds->tokenp[0].value == tPM)
- gds->Hour += 12;
- gds->tokenp += 1;
- }
- if (gds->tokenp[0].token == '+'
- && gds->tokenp[1].token == tUNUMBER) {
- /* "7:14+0700" */
- gds->HaveZone++;
- gds->DSTmode = DSToff;
- gds->Timezone = - ((gds->tokenp[1].value / 100) * HOUR
- + (gds->tokenp[1].value % 100) * MINUTE);
- gds->tokenp += 2;
- }
- if (gds->tokenp[0].token == '-'
- && gds->tokenp[1].token == tUNUMBER) {
- /* "19:14:12-0530" */
- gds->HaveZone++;
- gds->DSTmode = DSToff;
- gds->Timezone = + ((gds->tokenp[1].value / 100) * HOUR
- + (gds->tokenp[1].value % 100) * MINUTE);
- gds->tokenp += 2;
- }
- return 1;
-}
-
-/*
- * Timezone name, possibly including DST.
- */
-static int
-zonephrase(struct gdstate *gds)
-{
- if (gds->tokenp[0].token == tZONE
- && gds->tokenp[1].token == tDST) {
- gds->HaveZone++;
- gds->Timezone = gds->tokenp[0].value;
- gds->DSTmode = DSTon;
- gds->tokenp += 1;
- return 1;
- }
-
- if (gds->tokenp[0].token == tZONE) {
- gds->HaveZone++;
- gds->Timezone = gds->tokenp[0].value;
- gds->DSTmode = DSToff;
- gds->tokenp += 1;
- return 1;
- }
-
- if (gds->tokenp[0].token == tDAYZONE) {
- gds->HaveZone++;
- gds->Timezone = gds->tokenp[0].value;
- gds->DSTmode = DSTon;
- gds->tokenp += 1;
- return 1;
- }
- return 0;
-}
-
-/*
- * Year/month/day in various combinations.
- */
-static int
-datephrase(struct gdstate *gds)
-{
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == '/'
- && gds->tokenp[2].token == tUNUMBER
- && gds->tokenp[3].token == '/'
- && gds->tokenp[4].token == tUNUMBER) {
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- if (gds->tokenp[0].value >= 13) {
- /* First number is big: 2004/01/29, 99/02/17 */
- gds->Year = gds->tokenp[0].value;
- gds->Month = gds->tokenp[2].value;
- gds->Day = gds->tokenp[4].value;
- } else if ((gds->tokenp[4].value >= 13)
- || (gds->tokenp[2].value >= 13)) {
- /* Last number is big: 01/07/98 */
- /* Middle number is big: 01/29/04 */
- gds->Month = gds->tokenp[0].value;
- gds->Day = gds->tokenp[2].value;
- gds->Year = gds->tokenp[4].value;
- } else {
- /* No significant clues: 02/03/04 */
- gds->Month = gds->tokenp[0].value;
- gds->Day = gds->tokenp[2].value;
- gds->Year = gds->tokenp[4].value;
- }
- gds->tokenp += 5;
- return 1;
- }
-
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == '/'
- && gds->tokenp[2].token == tUNUMBER) {
- /* "1/15" */
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Month = gds->tokenp[0].value;
- gds->Day = gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
-
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == '-'
- && gds->tokenp[2].token == tUNUMBER
- && gds->tokenp[3].token == '-'
- && gds->tokenp[4].token == tUNUMBER) {
- /* ISO 8601 format. yyyy-mm-dd. */
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Year = gds->tokenp[0].value;
- gds->Month = gds->tokenp[2].value;
- gds->Day = gds->tokenp[4].value;
- gds->tokenp += 5;
- return 1;
- }
-
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == '-'
- && gds->tokenp[2].token == tMONTH
- && gds->tokenp[3].token == '-'
- && gds->tokenp[4].token == tUNUMBER) {
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- if (gds->tokenp[0].value > 31) {
- /* e.g. 1992-Jun-17 */
- gds->Year = gds->tokenp[0].value;
- gds->Month = gds->tokenp[2].value;
- gds->Day = gds->tokenp[4].value;
- } else {
- /* e.g. 17-JUN-1992. */
- gds->Day = gds->tokenp[0].value;
- gds->Month = gds->tokenp[2].value;
- gds->Year = gds->tokenp[4].value;
- }
- gds->tokenp += 5;
- return 1;
- }
-
- if (gds->tokenp[0].token == tMONTH
- && gds->tokenp[1].token == tUNUMBER
- && gds->tokenp[2].token == ','
- && gds->tokenp[3].token == tUNUMBER) {
- /* "June 17, 2001" */
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Month = gds->tokenp[0].value;
- gds->Day = gds->tokenp[1].value;
- gds->Year = gds->tokenp[3].value;
- gds->tokenp += 4;
- return 1;
- }
-
- if (gds->tokenp[0].token == tMONTH
- && gds->tokenp[1].token == tUNUMBER) {
- /* "May 3" */
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Month = gds->tokenp[0].value;
- gds->Day = gds->tokenp[1].value;
- gds->tokenp += 2;
- return 1;
- }
-
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tMONTH
- && gds->tokenp[2].token == tUNUMBER) {
- /* "12 Sept 1997" */
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Day = gds->tokenp[0].value;
- gds->Month = gds->tokenp[1].value;
- gds->Year = gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
-
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tMONTH) {
- /* "12 Sept" */
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Day = gds->tokenp[0].value;
- gds->Month = gds->tokenp[1].value;
- gds->tokenp += 2;
- return 1;
- }
-
- return 0;
-}
-
-/*
- * Relative time phrase: "tomorrow", "yesterday", "+1 hour", etc.
- */
-static int
-relunitphrase(struct gdstate *gds)
-{
- if (gds->tokenp[0].token == '-'
- && gds->tokenp[1].token == tUNUMBER
- && gds->tokenp[2].token == tSEC_UNIT) {
- /* "-3 hours" */
- gds->HaveRel++;
- gds->RelSeconds -= gds->tokenp[1].value * gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
- if (gds->tokenp[0].token == '+'
- && gds->tokenp[1].token == tUNUMBER
- && gds->tokenp[2].token == tSEC_UNIT) {
- /* "+1 minute" */
- gds->HaveRel++;
- gds->RelSeconds += gds->tokenp[1].value * gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tSEC_UNIT) {
- /* "1 day" */
- gds->HaveRel++;
- gds->RelSeconds += gds->tokenp[1].value * gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
- if (gds->tokenp[0].token == '-'
- && gds->tokenp[1].token == tUNUMBER
- && gds->tokenp[2].token == tMONTH_UNIT) {
- /* "-3 months" */
- gds->HaveRel++;
- gds->RelMonth -= gds->tokenp[1].value * gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
- if (gds->tokenp[0].token == '+'
- && gds->tokenp[1].token == tUNUMBER
- && gds->tokenp[2].token == tMONTH_UNIT) {
- /* "+5 years" */
- gds->HaveRel++;
- gds->RelMonth += gds->tokenp[1].value * gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tMONTH_UNIT) {
- /* "2 years" */
- gds->HaveRel++;
- gds->RelMonth += gds->tokenp[0].value * gds->tokenp[1].value;
- gds->tokenp += 2;
- return 1;
- }
- if (gds->tokenp[0].token == tSEC_UNIT) {
- /* "now", "tomorrow" */
- gds->HaveRel++;
- gds->RelSeconds += gds->tokenp[0].value;
- ++gds->tokenp;
- return 1;
- }
- if (gds->tokenp[0].token == tMONTH_UNIT) {
- /* "month" */
- gds->HaveRel++;
- gds->RelMonth += gds->tokenp[0].value;
- gds->tokenp += 1;
- return 1;
- }
- return 0;
-}
-
-/*
- * Day of the week specification.
- */
-static int
-dayphrase(struct gdstate *gds)
-{
- if (gds->tokenp[0].token == tDAY) {
- /* "tues", "wednesday," */
- gds->HaveWeekDay++;
- gds->DayOrdinal = 1;
- gds->DayNumber = gds->tokenp[0].value;
- gds->tokenp += 1;
- if (gds->tokenp[0].token == ',')
- gds->tokenp += 1;
- return 1;
- }
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tDAY) {
- /* "second tues" "3 wed" */
- gds->HaveWeekDay++;
- gds->DayOrdinal = gds->tokenp[0].value;
- gds->DayNumber = gds->tokenp[1].value;
- gds->tokenp += 2;
- return 1;
- }
- return 0;
-}
-
-/*
- * Try to match a phrase using one of the above functions.
- * This layer also deals with a couple of generic issues.
- */
-static int
-phrase(struct gdstate *gds)
-{
- if (timephrase(gds))
- return 1;
- if (zonephrase(gds))
- return 1;
- if (datephrase(gds))
- return 1;
- if (dayphrase(gds))
- return 1;
- if (relunitphrase(gds)) {
- if (gds->tokenp[0].token == tAGO) {
- gds->RelSeconds = -gds->RelSeconds;
- gds->RelMonth = -gds->RelMonth;
- gds->tokenp += 1;
- }
- return 1;
- }
-
- /* Bare numbers sometimes have meaning. */
- if (gds->tokenp[0].token == tUNUMBER) {
- if (gds->HaveTime && !gds->HaveYear && !gds->HaveRel) {
- gds->HaveYear++;
- gds->Year = gds->tokenp[0].value;
- gds->tokenp += 1;
- return 1;
- }
-
- if(gds->tokenp[0].value > 10000) {
- /* "20040301" */
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Day= (gds->tokenp[0].value)%100;
- gds->Month= (gds->tokenp[0].value/100)%100;
- gds->Year = gds->tokenp[0].value/10000;
- gds->tokenp += 1;
- return 1;
- }
-
- if (gds->tokenp[0].value < 24) {
- gds->HaveTime++;
- gds->Hour = gds->tokenp[0].value;
- gds->Minutes = 0;
- gds->Seconds = 0;
- gds->tokenp += 1;
- return 1;
- }
-
- if ((gds->tokenp[0].value / 100 < 24)
- && (gds->tokenp[0].value % 100 < 60)) {
- /* "513" is same as "5:13" */
- gds->Hour = gds->tokenp[0].value / 100;
- gds->Minutes = gds->tokenp[0].value % 100;
- gds->Seconds = 0;
- gds->tokenp += 1;
- return 1;
- }
- }
-
- return 0;
-}
-
-/*
- * A dictionary of time words.
- */
-static struct LEXICON {
- size_t abbrev;
- const char *name;
- int type;
- time_t value;
-} const TimeWords[] = {
- /* am/pm */
- { 0, "am", tAMPM, tAM },
- { 0, "pm", tAMPM, tPM },
-
- /* Month names. */
- { 3, "january", tMONTH, 1 },
- { 3, "february", tMONTH, 2 },
- { 3, "march", tMONTH, 3 },
- { 3, "april", tMONTH, 4 },
- { 3, "may", tMONTH, 5 },
- { 3, "june", tMONTH, 6 },
- { 3, "july", tMONTH, 7 },
- { 3, "august", tMONTH, 8 },
- { 3, "september", tMONTH, 9 },
- { 3, "october", tMONTH, 10 },
- { 3, "november", tMONTH, 11 },
- { 3, "december", tMONTH, 12 },
-
- /* Days of the week. */
- { 2, "sunday", tDAY, 0 },
- { 3, "monday", tDAY, 1 },
- { 2, "tuesday", tDAY, 2 },
- { 3, "wednesday", tDAY, 3 },
- { 2, "thursday", tDAY, 4 },
- { 2, "friday", tDAY, 5 },
- { 2, "saturday", tDAY, 6 },
-
- /* Timezones: Offsets are in seconds. */
- { 0, "gmt", tZONE, 0*HOUR }, /* Greenwich Mean */
- { 0, "ut", tZONE, 0*HOUR }, /* Universal (Coordinated) */
- { 0, "utc", tZONE, 0*HOUR },
- { 0, "wet", tZONE, 0*HOUR }, /* Western European */
- { 0, "bst", tDAYZONE, 0*HOUR }, /* British Summer */
- { 0, "wat", tZONE, 1*HOUR }, /* West Africa */
- { 0, "at", tZONE, 2*HOUR }, /* Azores */
- /* { 0, "bst", tZONE, 3*HOUR }, */ /* Brazil Standard: Conflict */
- /* { 0, "gst", tZONE, 3*HOUR }, */ /* Greenland Standard: Conflict*/
- { 0, "nft", tZONE, 3*HOUR+30*MINUTE }, /* Newfoundland */
- { 0, "nst", tZONE, 3*HOUR+30*MINUTE }, /* Newfoundland Standard */
- { 0, "ndt", tDAYZONE, 3*HOUR+30*MINUTE }, /* Newfoundland Daylight */
- { 0, "ast", tZONE, 4*HOUR }, /* Atlantic Standard */
- { 0, "adt", tDAYZONE, 4*HOUR }, /* Atlantic Daylight */
- { 0, "est", tZONE, 5*HOUR }, /* Eastern Standard */
- { 0, "edt", tDAYZONE, 5*HOUR }, /* Eastern Daylight */
- { 0, "cst", tZONE, 6*HOUR }, /* Central Standard */
- { 0, "cdt", tDAYZONE, 6*HOUR }, /* Central Daylight */
- { 0, "mst", tZONE, 7*HOUR }, /* Mountain Standard */
- { 0, "mdt", tDAYZONE, 7*HOUR }, /* Mountain Daylight */
- { 0, "pst", tZONE, 8*HOUR }, /* Pacific Standard */
- { 0, "pdt", tDAYZONE, 8*HOUR }, /* Pacific Daylight */
- { 0, "yst", tZONE, 9*HOUR }, /* Yukon Standard */
- { 0, "ydt", tDAYZONE, 9*HOUR }, /* Yukon Daylight */
- { 0, "hst", tZONE, 10*HOUR }, /* Hawaii Standard */
- { 0, "hdt", tDAYZONE, 10*HOUR }, /* Hawaii Daylight */
- { 0, "cat", tZONE, 10*HOUR }, /* Central Alaska */
- { 0, "ahst", tZONE, 10*HOUR }, /* Alaska-Hawaii Standard */
- { 0, "nt", tZONE, 11*HOUR }, /* Nome */
- { 0, "idlw", tZONE, 12*HOUR }, /* Intl Date Line West */
- { 0, "cet", tZONE, -1*HOUR }, /* Central European */
- { 0, "met", tZONE, -1*HOUR }, /* Middle European */
- { 0, "mewt", tZONE, -1*HOUR }, /* Middle European Winter */
- { 0, "mest", tDAYZONE, -1*HOUR }, /* Middle European Summer */
- { 0, "swt", tZONE, -1*HOUR }, /* Swedish Winter */
- { 0, "sst", tDAYZONE, -1*HOUR }, /* Swedish Summer */
- { 0, "fwt", tZONE, -1*HOUR }, /* French Winter */
- { 0, "fst", tDAYZONE, -1*HOUR }, /* French Summer */
- { 0, "eet", tZONE, -2*HOUR }, /* Eastern Eur, USSR Zone 1 */
- { 0, "bt", tZONE, -3*HOUR }, /* Baghdad, USSR Zone 2 */
- { 0, "it", tZONE, -3*HOUR-30*MINUTE },/* Iran */
- { 0, "zp4", tZONE, -4*HOUR }, /* USSR Zone 3 */
- { 0, "zp5", tZONE, -5*HOUR }, /* USSR Zone 4 */
- { 0, "ist", tZONE, -5*HOUR-30*MINUTE },/* Indian Standard */
- { 0, "zp6", tZONE, -6*HOUR }, /* USSR Zone 5 */
- /* { 0, "nst", tZONE, -6.5*HOUR }, */ /* North Sumatra: Conflict */
- /* { 0, "sst", tZONE, -7*HOUR }, */ /* So Sumatra, USSR 6: Conflict */
- { 0, "wast", tZONE, -7*HOUR }, /* West Australian Standard */
- { 0, "wadt", tDAYZONE, -7*HOUR }, /* West Australian Daylight */
- { 0, "jt", tZONE, -7*HOUR-30*MINUTE },/* Java (3pm in Cronusland!)*/
- { 0, "cct", tZONE, -8*HOUR }, /* China Coast, USSR Zone 7 */
- { 0, "jst", tZONE, -9*HOUR }, /* Japan Std, USSR Zone 8 */
- { 0, "cast", tZONE, -9*HOUR-30*MINUTE },/* Ctrl Australian Std */
- { 0, "cadt", tDAYZONE, -9*HOUR-30*MINUTE },/* Ctrl Australian Daylt */
- { 0, "east", tZONE, -10*HOUR }, /* Eastern Australian Std */
- { 0, "eadt", tDAYZONE, -10*HOUR }, /* Eastern Australian Daylt */
- { 0, "gst", tZONE, -10*HOUR }, /* Guam Std, USSR Zone 9 */
- { 0, "nzt", tZONE, -12*HOUR }, /* New Zealand */
- { 0, "nzst", tZONE, -12*HOUR }, /* New Zealand Standard */
- { 0, "nzdt", tDAYZONE, -12*HOUR }, /* New Zealand Daylight */
- { 0, "idle", tZONE, -12*HOUR }, /* Intl Date Line East */
-
- { 0, "dst", tDST, 0 },
-
- /* Time units. */
- { 4, "years", tMONTH_UNIT, 12 },
- { 5, "months", tMONTH_UNIT, 1 },
- { 9, "fortnights", tSEC_UNIT, 14 * DAY },
- { 4, "weeks", tSEC_UNIT, 7 * DAY },
- { 3, "days", tSEC_UNIT, DAY },
- { 4, "hours", tSEC_UNIT, HOUR },
- { 3, "minutes", tSEC_UNIT, MINUTE },
- { 3, "seconds", tSEC_UNIT, 1 },
-
- /* Relative-time words. */
- { 0, "tomorrow", tSEC_UNIT, DAY },
- { 0, "yesterday", tSEC_UNIT, -DAY },
- { 0, "today", tSEC_UNIT, 0 },
- { 0, "now", tSEC_UNIT, 0 },
- { 0, "last", tUNUMBER, -1 },
- { 0, "this", tSEC_UNIT, 0 },
- { 0, "next", tUNUMBER, 2 },
- { 0, "first", tUNUMBER, 1 },
- { 0, "1st", tUNUMBER, 1 },
-/* { 0, "second", tUNUMBER, 2 }, */
- { 0, "2nd", tUNUMBER, 2 },
- { 0, "third", tUNUMBER, 3 },
- { 0, "3rd", tUNUMBER, 3 },
- { 0, "fourth", tUNUMBER, 4 },
- { 0, "4th", tUNUMBER, 4 },
- { 0, "fifth", tUNUMBER, 5 },
- { 0, "5th", tUNUMBER, 5 },
- { 0, "sixth", tUNUMBER, 6 },
- { 0, "seventh", tUNUMBER, 7 },
- { 0, "eighth", tUNUMBER, 8 },
- { 0, "ninth", tUNUMBER, 9 },
- { 0, "tenth", tUNUMBER, 10 },
- { 0, "eleventh", tUNUMBER, 11 },
- { 0, "twelfth", tUNUMBER, 12 },
- { 0, "ago", tAGO, 1 },
-
- /* Military timezones. */
- { 0, "a", tZONE, 1*HOUR },
- { 0, "b", tZONE, 2*HOUR },
- { 0, "c", tZONE, 3*HOUR },
- { 0, "d", tZONE, 4*HOUR },
- { 0, "e", tZONE, 5*HOUR },
- { 0, "f", tZONE, 6*HOUR },
- { 0, "g", tZONE, 7*HOUR },
- { 0, "h", tZONE, 8*HOUR },
- { 0, "i", tZONE, 9*HOUR },
- { 0, "k", tZONE, 10*HOUR },
- { 0, "l", tZONE, 11*HOUR },
- { 0, "m", tZONE, 12*HOUR },
- { 0, "n", tZONE, -1*HOUR },
- { 0, "o", tZONE, -2*HOUR },
- { 0, "p", tZONE, -3*HOUR },
- { 0, "q", tZONE, -4*HOUR },
- { 0, "r", tZONE, -5*HOUR },
- { 0, "s", tZONE, -6*HOUR },
- { 0, "t", tZONE, -7*HOUR },
- { 0, "u", tZONE, -8*HOUR },
- { 0, "v", tZONE, -9*HOUR },
- { 0, "w", tZONE, -10*HOUR },
- { 0, "x", tZONE, -11*HOUR },
- { 0, "y", tZONE, -12*HOUR },
- { 0, "z", tZONE, 0*HOUR },
-
- /* End of table. */
- { 0, NULL, 0, 0 }
-};
-
-/*
- * Year is either:
- * = A number from 0 to 99, which means a year from 1970 to 2069, or
- * = The actual year (>=100).
- */
-static time_t
-Convert(time_t Month, time_t Day, time_t Year,
- time_t Hours, time_t Minutes, time_t Seconds,
- time_t Timezone, enum DSTMODE DSTmode)
-{
- static int DaysInMonth[12] = {
- 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
- time_t Julian;
- int i;
-
- if (Year < 69)
- Year += 2000;
- else if (Year < 100)
- Year += 1900;
- DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
- ? 29 : 28;
- /* Checking for 2038 bogusly assumes that time_t is 32 bits. But
- I'm too lazy to try to check for time_t overflow in another way. */
- if (Year < EPOCH || Year > 2038
- || Month < 1 || Month > 12
- /* Lint fluff: "conversion from long may lose accuracy" */
- || Day < 1 || Day > DaysInMonth[(int)--Month]
- || Hours < 0 || Hours > 23
- || Minutes < 0 || Minutes > 59
- || Seconds < 0 || Seconds > 59)
- return -1;
-
- Julian = Day - 1;
- for (i = 0; i < Month; i++)
- Julian += DaysInMonth[i];
- for (i = EPOCH; i < Year; i++)
- Julian += 365 + (i % 4 == 0);
- Julian *= DAY;
- Julian += Timezone;
- Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
- if (DSTmode == DSTon
- || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
- Julian -= HOUR;
- return Julian;
-}
-
-
-static time_t
-DSTcorrect(time_t Start, time_t Future)
-{
- time_t StartDay;
- time_t FutureDay;
-
- StartDay = (localtime(&Start)->tm_hour + 1) % 24;
- FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
- return (Future - Start) + (StartDay - FutureDay) * HOUR;
-}
-
-
-static time_t
-RelativeDate(time_t Start, time_t zone, int dstmode,
- time_t DayOrdinal, time_t DayNumber)
-{
- struct tm *tm;
- time_t t, now;
-
- t = Start - zone;
- tm = gmtime(&t);
- now = Start;
- now += DAY * ((DayNumber - tm->tm_wday + 7) % 7);
- now += 7 * DAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
- if (dstmode == DSTmaybe)
- return DSTcorrect(Start, now);
- return now - Start;
-}
-
-
-static time_t
-RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
-{
- struct tm *tm;
- time_t Month;
- time_t Year;
-
- if (RelMonth == 0)
- return 0;
- tm = localtime(&Start);
- Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
- Year = Month / 12;
- Month = Month % 12 + 1;
- return DSTcorrect(Start,
- Convert(Month, (time_t)tm->tm_mday, Year,
- (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
- Timezone, DSTmaybe));
-}
-
-/*
- * Tokenizer.
- */
-static int
-nexttoken(char **in, time_t *value)
-{
- char c;
- char buff[64];
-
- for ( ; ; ) {
- while (isspace((unsigned char)**in))
- ++*in;
-
- /* Skip parenthesized comments. */
- if (**in == '(') {
- int Count = 0;
- do {
- c = *(*in)++;
- if (c == '\0')
- return c;
- if (c == '(')
- Count++;
- else if (c == ')')
- Count--;
- } while (Count > 0);
- continue;
- }
-
- /* Try the next token in the word table first. */
- /* This allows us to match "2nd", for example. */
- {
- char *src = *in;
- const struct LEXICON *tp;
- unsigned i = 0;
-
- /* Force to lowercase and strip '.' characters. */
- while (*src != '\0'
- && (isalnum((unsigned char)*src) || *src == '.')
- && i < sizeof(buff)-1) {
- if (*src != '.') {
- if (isupper((unsigned char)*src))
- buff[i++] = tolower((unsigned char)*src);
- else
- buff[i++] = *src;
- }
- src++;
- }
- buff[i] = '\0';
-
- /*
- * Find the first match. If the word can be
- * abbreviated, make sure we match at least
- * the minimum abbreviation.
- */
- for (tp = TimeWords; tp->name; tp++) {
- size_t abbrev = tp->abbrev;
- if (abbrev == 0)
- abbrev = strlen(tp->name);
- if (strlen(buff) >= abbrev
- && strncmp(tp->name, buff, strlen(buff))
- == 0) {
- /* Skip over token. */
- *in = src;
- /* Return the match. */
- *value = tp->value;
- return tp->type;
- }
- }
- }
-
- /*
- * Not in the word table, maybe it's a number. Note:
- * Because '-' and '+' have other special meanings, I
- * don't deal with signed numbers here.
- */
- if (isdigit((unsigned char)(c = **in))) {
- for (*value = 0; isdigit((unsigned char)(c = *(*in)++)); )
- *value = 10 * *value + c - '0';
- (*in)--;
- return (tUNUMBER);
- }
-
- return *(*in)++;
- }
-}
-
-#define TM_YEAR_ORIGIN 1900
-
-/* Yield A - B, measured in seconds. */
-static long
-difftm (struct tm *a, struct tm *b)
-{
- int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
- int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
- int days = (
- /* difference in day of year */
- a->tm_yday - b->tm_yday
- /* + intervening leap days */
- + ((ay >> 2) - (by >> 2))
- - (ay/100 - by/100)
- + ((ay/100 >> 2) - (by/100 >> 2))
- /* + difference in years * 365 */
- + (long)(ay-by) * 365
- );
- return (days * DAY + (a->tm_hour - b->tm_hour) * HOUR
- + (a->tm_min - b->tm_min) * MINUTE
- + (a->tm_sec - b->tm_sec));
-}
-
-/*
- *
- * The public function.
- *
- * TODO: tokens[] array should be dynamically sized.
- */
-time_t
-get_date(time_t now, char *p)
-{
- struct token tokens[256];
- struct gdstate _gds;
- struct token *lasttoken;
- struct gdstate *gds;
- struct tm local, *tm;
- struct tm gmt, *gmt_ptr;
- time_t Start;
- time_t tod;
- long tzone;
-
- /* Clear out the parsed token array. */
- memset(tokens, 0, sizeof(tokens));
- /* Initialize the parser state. */
- memset(&_gds, 0, sizeof(_gds));
- gds = &_gds;
-
- /* Look up the current time. */
- memset(&local, 0, sizeof(local));
- tm = localtime (&now);
- if (tm == NULL)
- return -1;
- local = *tm;
-
- /* Look up UTC if we can and use that to determine the current
- * timezone offset. */
- memset(&gmt, 0, sizeof(gmt));
- gmt_ptr = gmtime (&now);
- if (gmt_ptr != NULL) {
- /* Copy, in case localtime and gmtime use the same buffer. */
- gmt = *gmt_ptr;
- }
- if (gmt_ptr != NULL)
- tzone = difftm (&gmt, &local);
- else
- /* This system doesn't understand timezones; fake it. */
- tzone = 0;
- if(local.tm_isdst)
- tzone += HOUR;
-
- /* Tokenize the input string. */
- lasttoken = tokens;
- while ((lasttoken->token = nexttoken(&p, &lasttoken->value)) != 0) {
- ++lasttoken;
- if (lasttoken > tokens + 255)
- return -1;
- }
- gds->tokenp = tokens;
-
- /* Match phrases until we run out of input tokens. */
- while (gds->tokenp < lasttoken) {
- if (!phrase(gds))
- return -1;
- }
-
- /* Use current local timezone if none was specified. */
- if (!gds->HaveZone) {
- gds->Timezone = tzone;
- gds->DSTmode = DSTmaybe;
- }
-
- /* If a timezone was specified, use that for generating the default
- * time components instead of the local timezone. */
- if (gds->HaveZone && gmt_ptr != NULL) {
- now -= gds->Timezone;
- gmt_ptr = gmtime (&now);
- if (gmt_ptr != NULL)
- local = *gmt_ptr;
- now += gds->Timezone;
- }
-
- if (!gds->HaveYear)
- gds->Year = local.tm_year + 1900;
- if (!gds->HaveMonth)
- gds->Month = local.tm_mon + 1;
- if (!gds->HaveDay)
- gds->Day = local.tm_mday;
- /* Note: No default for hour/min/sec; a specifier that just
- * gives date always refers to 00:00 on that date. */
-
- /* If we saw more than one time, timezone, weekday, year, month,
- * or day, then give up. */
- if (gds->HaveTime > 1 || gds->HaveZone > 1 || gds->HaveWeekDay > 1
- || gds->HaveYear > 1 || gds->HaveMonth > 1 || gds->HaveDay > 1)
- return -1;
-
- /* Compute an absolute time based on whatever absolute information
- * we collected. */
- if (gds->HaveYear || gds->HaveMonth || gds->HaveDay
- || gds->HaveTime || gds->HaveWeekDay) {
- Start = Convert(gds->Month, gds->Day, gds->Year,
- gds->Hour, gds->Minutes, gds->Seconds,
- gds->Timezone, gds->DSTmode);
- if (Start < 0)
- return -1;
- } else {
- Start = now;
- if (!gds->HaveRel)
- Start -= local.tm_hour * HOUR + local.tm_min * MINUTE
- + local.tm_sec;
- }
-
- /* Add the relative offset. */
- Start += gds->RelSeconds;
- Start += RelativeMonth(Start, gds->Timezone, gds->RelMonth);
-
- /* Adjust for day-of-week offsets. */
- if (gds->HaveWeekDay
- && !(gds->HaveYear || gds->HaveMonth || gds->HaveDay)) {
- tod = RelativeDate(Start, gds->Timezone,
- gds->DSTmode, gds->DayOrdinal, gds->DayNumber);
- Start += tod;
- }
-
- /* -1 is an error indicator, so return 0 instead of -1 if
- * that's the actual time. */
- return Start == -1 ? 0 : Start;
-}
-
-
-#if defined(TEST)
-
-/* ARGSUSED */
-int
-main(int argc, char **argv)
-{
- time_t d;
-
- while (*++argv != NULL) {
- (void)printf("Input: %s\n", *argv);
- d = get_date(*argv);
- if (d == -1)
- (void)printf("Bad format - couldn't convert.\n");
- else
- (void)printf("Output: %s\n", ctime(&d));
- }
- exit(0);
- /* NOTREACHED */
-}
-#endif /* defined(TEST) */
diff --git a/usr.bin/tar/read.c b/usr.bin/tar/read.c
deleted file mode 100644
index b1616ec2e765..000000000000
--- a/usr.bin/tar/read.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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 "bsdtar_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "bsdtar.h"
-#include "err.h"
-
-struct progress_data {
- struct bsdtar *bsdtar;
- struct archive *archive;
- struct archive_entry *entry;
-};
-
-static void list_item_verbose(struct bsdtar *, FILE *,
- struct archive_entry *);
-static void read_archive(struct bsdtar *bsdtar, char mode);
-
-void
-tar_mode_t(struct bsdtar *bsdtar)
-{
- read_archive(bsdtar, 't');
- if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archive") != 0)
- bsdtar->return_value = 1;
-}
-
-void
-tar_mode_x(struct bsdtar *bsdtar)
-{
- read_archive(bsdtar, 'x');
-
- if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archive") != 0)
- bsdtar->return_value = 1;
-}
-
-static void
-progress_func(void *cookie)
-{
- struct progress_data *progress_data = cookie;
- struct bsdtar *bsdtar = progress_data->bsdtar;
- struct archive *a = progress_data->archive;
- struct archive_entry *entry = progress_data->entry;
- uint64_t comp, uncomp;
- int compression;
-
- if (!need_report())
- return;
-
- if (bsdtar->verbose)
- fprintf(stderr, "\n");
- if (a != NULL) {
- comp = archive_position_compressed(a);
- uncomp = archive_position_uncompressed(a);
- if (comp > uncomp)
- compression = 0;
- else
- compression = (int)((uncomp - comp) * 100 / uncomp);
- fprintf(stderr,
- "In: %s bytes, compression %d%%;",
- tar_i64toa(comp), compression);
- fprintf(stderr, " Out: %d files, %s bytes\n",
- archive_file_count(a), tar_i64toa(uncomp));
- }
- if (entry != NULL) {
- safe_fprintf(stderr, "Current: %s",
- archive_entry_pathname(entry));
- fprintf(stderr, " (%s bytes)\n",
- tar_i64toa(archive_entry_size(entry)));
- }
-}
-
-/*
- * Handle 'x' and 't' modes.
- */
-static void
-read_archive(struct bsdtar *bsdtar, char mode)
-{
- struct progress_data progress_data;
- FILE *out;
- struct archive *a;
- struct archive_entry *entry;
- const struct stat *st;
- int r;
-
- while (*bsdtar->argv) {
- lafe_include(&bsdtar->matching, *bsdtar->argv);
- bsdtar->argv++;
- }
-
- if (bsdtar->names_from_file != NULL)
- lafe_include_from_file(&bsdtar->matching,
- bsdtar->names_from_file, bsdtar->option_null);
-
- a = archive_read_new();
- if (bsdtar->compress_program != NULL)
- archive_read_support_compression_program(a, bsdtar->compress_program);
- else
- archive_read_support_compression_all(a);
- archive_read_support_format_all(a);
- if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options))
- 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))
- lafe_errc(1, 0, "Error opening archive: %s",
- archive_error_string(a));
-
- do_chdir(bsdtar);
-
- if (mode == 'x') {
- /* Set an extract callback so that we can handle SIGINFO. */
- progress_data.bsdtar = bsdtar;
- progress_data.archive = a;
- archive_read_extract_set_progress_callback(a, progress_func,
- &progress_data);
- }
-
- if (mode == 'x' && bsdtar->option_chroot) {
-#if HAVE_CHROOT
- if (chroot(".") != 0)
- lafe_errc(1, errno, "Can't chroot to \".\"");
-#else
- lafe_errc(1, 0,
- "chroot isn't supported on this platform");
-#endif
- }
-
- for (;;) {
- /* Support --fast-read option */
- if (bsdtar->option_fast_read &&
- lafe_unmatched_inclusions(bsdtar->matching) == 0)
- break;
-
- r = archive_read_next_header(a, &entry);
- progress_data.entry = entry;
- if (r == ARCHIVE_EOF)
- break;
- if (r < ARCHIVE_OK)
- lafe_warnc(0, "%s", archive_error_string(a));
- if (r <= ARCHIVE_WARN)
- bsdtar->return_value = 1;
- if (r == ARCHIVE_RETRY) {
- /* Retryable error: try again */
- lafe_warnc(0, "Retrying...");
- continue;
- }
- if (r == ARCHIVE_FATAL)
- break;
-
- if (bsdtar->option_numeric_owner) {
- archive_entry_set_uname(entry, NULL);
- archive_entry_set_gname(entry, NULL);
- }
-
- /*
- * Exclude entries that are too old.
- */
- st = archive_entry_stat(entry);
- if (bsdtar->newer_ctime_sec > 0) {
- if (st->st_ctime < bsdtar->newer_ctime_sec)
- continue; /* Too old, skip it. */
- if (st->st_ctime == bsdtar->newer_ctime_sec
- && ARCHIVE_STAT_CTIME_NANOS(st)
- <= bsdtar->newer_ctime_nsec)
- continue; /* Too old, skip it. */
- }
- if (bsdtar->newer_mtime_sec > 0) {
- if (st->st_mtime < bsdtar->newer_mtime_sec)
- continue; /* Too old, skip it. */
- if (st->st_mtime == bsdtar->newer_mtime_sec
- && ARCHIVE_STAT_MTIME_NANOS(st)
- <= bsdtar->newer_mtime_nsec)
- continue; /* Too old, skip it. */
- }
-
- /*
- * Note that pattern exclusions are checked before
- * pathname rewrites are handled. This gives more
- * control over exclusions, since rewrites always lose
- * information. (For example, consider a rewrite
- * s/foo[0-9]/foo/. If we check exclusions after the
- * rewrite, there would be no way to exclude foo1/bar
- * while allowing foo2/bar.)
- */
- if (lafe_excluded(bsdtar->matching, archive_entry_pathname(entry)))
- continue; /* Excluded by a pattern test. */
-
- if (mode == 't') {
- /* Perversely, gtar uses -O to mean "send to stderr"
- * when used with -t. */
- out = bsdtar->option_stdout ? stderr : stdout;
-
- /*
- * TODO: Provide some reasonable way to
- * preview rewrites. gtar always displays
- * the unedited path in -t output, which means
- * you cannot easily preview rewrites.
- */
- if (bsdtar->verbose < 2)
- safe_fprintf(out, "%s",
- archive_entry_pathname(entry));
- else
- list_item_verbose(bsdtar, out, entry);
- fflush(out);
- r = archive_read_data_skip(a);
- if (r == ARCHIVE_WARN) {
- fprintf(out, "\n");
- lafe_warnc(0, "%s",
- archive_error_string(a));
- }
- if (r == ARCHIVE_RETRY) {
- fprintf(out, "\n");
- lafe_warnc(0, "%s",
- archive_error_string(a));
- }
- if (r == ARCHIVE_FATAL) {
- fprintf(out, "\n");
- lafe_warnc(0, "%s",
- archive_error_string(a));
- bsdtar->return_value = 1;
- break;
- }
- fprintf(out, "\n");
- } else {
- /* Note: some rewrite failures prevent extraction. */
- if (edit_pathname(bsdtar, entry))
- continue; /* Excluded by a rewrite failure. */
-
- if (bsdtar->option_interactive &&
- !yes("extract '%s'", archive_entry_pathname(entry)))
- continue;
-
- /*
- * Format here is from SUSv2, including the
- * deferred '\n'.
- */
- if (bsdtar->verbose) {
- safe_fprintf(stderr, "x %s",
- archive_entry_pathname(entry));
- fflush(stderr);
- }
-
- // TODO siginfo_printinfo(bsdtar, 0);
-
- if (bsdtar->option_stdout)
- r = archive_read_data_into_fd(a, 1);
- else
- r = archive_read_extract(a, entry,
- bsdtar->extract_flags);
- if (r != ARCHIVE_OK) {
- if (!bsdtar->verbose)
- safe_fprintf(stderr, "%s",
- archive_entry_pathname(entry));
- safe_fprintf(stderr, ": %s",
- archive_error_string(a));
- if (!bsdtar->verbose)
- fprintf(stderr, "\n");
- bsdtar->return_value = 1;
- }
- if (bsdtar->verbose)
- fprintf(stderr, "\n");
- if (r == ARCHIVE_FATAL)
- break;
- }
- }
-
-
- r = archive_read_close(a);
- if (r != ARCHIVE_OK)
- lafe_warnc(0, "%s", archive_error_string(a));
- if (r <= ARCHIVE_WARN)
- bsdtar->return_value = 1;
-
- if (bsdtar->verbose > 2)
- fprintf(stdout, "Archive Format: %s, Compression: %s\n",
- archive_format_name(a), archive_compression_name(a));
-
- archive_read_finish(a);
-}
-
-
-/*
- * Display information about the current file.
- *
- * The format here roughly duplicates the output of 'ls -l'.
- * This is based on SUSv2, where 'tar tv' is documented as
- * listing additional information in an "unspecified format,"
- * and 'pax -l' is documented as using the same format as 'ls -l'.
- */
-static void
-list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
-{
- char tmp[100];
- size_t w;
- const char *p;
- const char *fmt;
- time_t tim;
- static time_t now;
-
- /*
- * We avoid collecting the entire list in memory at once by
- * listing things as we see them. However, that also means we can't
- * just pre-compute the field widths. Instead, we start with guesses
- * and just widen them as necessary. These numbers are completely
- * arbitrary.
- */
- if (!bsdtar->u_width) {
- bsdtar->u_width = 6;
- bsdtar->gs_width = 13;
- }
- if (!now)
- time(&now);
- fprintf(out, "%s %d ",
- archive_entry_strmode(entry),
- archive_entry_nlink(entry));
-
- /* Use uname if it's present, else uid. */
- p = archive_entry_uname(entry);
- if ((p == NULL) || (*p == '\0')) {
- sprintf(tmp, "%lu ",
- (unsigned long)archive_entry_uid(entry));
- p = tmp;
- }
- w = strlen(p);
- if (w > bsdtar->u_width)
- bsdtar->u_width = w;
- fprintf(out, "%-*s ", (int)bsdtar->u_width, p);
-
- /* Use gname if it's present, else gid. */
- p = archive_entry_gname(entry);
- if (p != NULL && p[0] != '\0') {
- fprintf(out, "%s", p);
- w = strlen(p);
- } else {
- sprintf(tmp, "%lu",
- (unsigned long)archive_entry_gid(entry));
- w = strlen(tmp);
- fprintf(out, "%s", tmp);
- }
-
- /*
- * Print device number or file size, right-aligned so as to make
- * total width of group and devnum/filesize fields be gs_width.
- * If gs_width is too small, grow it.
- */
- if (archive_entry_filetype(entry) == AE_IFCHR
- || archive_entry_filetype(entry) == AE_IFBLK) {
- sprintf(tmp, "%lu,%lu",
- (unsigned long)archive_entry_rdevmajor(entry),
- (unsigned long)archive_entry_rdevminor(entry));
- } else {
- strcpy(tmp, tar_i64toa(archive_entry_size(entry)));
- }
- if (w + strlen(tmp) >= bsdtar->gs_width)
- bsdtar->gs_width = w+strlen(tmp)+1;
- fprintf(out, "%*s", (int)(bsdtar->gs_width - w), tmp);
-
- /* Format the time using 'ls -l' conventions. */
- tim = archive_entry_mtime(entry);
-#define HALF_YEAR (time_t)365 * 86400 / 2
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define DAY_FMT "%d" /* Windows' strftime function does not support %e format. */
-#else
-#define DAY_FMT "%e" /* Day number without leading zeros */
-#endif
- if (tim < now - HALF_YEAR || tim > now + HALF_YEAR)
- fmt = bsdtar->day_first ? DAY_FMT " %b %Y" : "%b " DAY_FMT " %Y";
- else
- fmt = bsdtar->day_first ? DAY_FMT " %b %H:%M" : "%b " DAY_FMT " %H:%M";
- strftime(tmp, sizeof(tmp), fmt, localtime(&tim));
- fprintf(out, " %s ", tmp);
- safe_fprintf(out, "%s", archive_entry_pathname(entry));
-
- /* Extra information for links. */
- if (archive_entry_hardlink(entry)) /* Hard link */
- safe_fprintf(out, " link to %s",
- archive_entry_hardlink(entry));
- else if (archive_entry_symlink(entry)) /* Symbolic link */
- safe_fprintf(out, " -> %s", archive_entry_symlink(entry));
-}
diff --git a/usr.bin/tar/subst.c b/usr.bin/tar/subst.c
deleted file mode 100644
index 765f74b66a6b..000000000000
--- a/usr.bin/tar/subst.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*-
- * Copyright (c) 2008 Joerg Sonnenberger
- * 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 "bsdtar_platform.h"
-__FBSDID("$FreeBSD$");
-
-#if HAVE_REGEX_H
-#include "bsdtar.h"
-
-#include <errno.h>
-#include <regex.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef REG_BASIC
-#define REG_BASIC 0
-#endif
-
-#include "err.h"
-
-struct subst_rule {
- struct subst_rule *next;
- regex_t re;
- char *result;
- unsigned int global:1, print:1, symlink:1;
-};
-
-struct substitution {
- struct subst_rule *first_rule, *last_rule;
-};
-
-static void
-init_substitution(struct bsdtar *bsdtar)
-{
- struct substitution *subst;
-
- bsdtar->substitution = subst = malloc(sizeof(*subst));
- if (subst == NULL)
- lafe_errc(1, errno, "Out of memory");
- subst->first_rule = subst->last_rule = NULL;
-}
-
-void
-add_substitution(struct bsdtar *bsdtar, const char *rule_text)
-{
- struct subst_rule *rule;
- struct substitution *subst;
- const char *end_pattern, *start_subst;
- char *pattern;
- int r;
-
- if ((subst = bsdtar->substitution) == NULL) {
- init_substitution(bsdtar);
- subst = bsdtar->substitution;
- }
-
- rule = malloc(sizeof(*rule));
- if (rule == NULL)
- lafe_errc(1, errno, "Out of memory");
- rule->next = NULL;
-
- if (subst->last_rule == NULL)
- subst->first_rule = rule;
- else
- subst->last_rule->next = rule;
- subst->last_rule = rule;
-
- if (*rule_text == '\0')
- lafe_errc(1, 0, "Empty replacement string");
- end_pattern = strchr(rule_text + 1, *rule_text);
- if (end_pattern == NULL)
- lafe_errc(1, 0, "Invalid replacement string");
-
- pattern = malloc(end_pattern - rule_text);
- if (pattern == NULL)
- 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));
- 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)
- lafe_errc(1, 0, "Invalid replacement string");
-
- rule->result = malloc(end_pattern - start_subst + 1);
- if (rule->result == NULL)
- lafe_errc(1, errno, "Out of memory");
- memcpy(rule->result, start_subst, end_pattern - start_subst);
- rule->result[end_pattern - start_subst] = '\0';
-
- rule->global = 0;
- rule->print = 0;
- rule->symlink = 0;
-
- while (*++end_pattern) {
- switch (*end_pattern) {
- case 'g':
- case 'G':
- rule->global = 1;
- break;
- case 'p':
- case 'P':
- rule->print = 1;
- break;
- case 's':
- case 'S':
- rule->symlink = 1;
- break;
- default:
- lafe_errc(1, 0, "Invalid replacement flag %c", *end_pattern);
- }
- }
-}
-
-static void
-realloc_strncat(char **str, const char *append, size_t len)
-{
- char *new_str;
- size_t old_len;
-
- if (*str == NULL)
- old_len = 0;
- else
- old_len = strlen(*str);
-
- new_str = malloc(old_len + len + 1);
- if (new_str == NULL)
- 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';
- free(*str);
- *str = new_str;
-}
-
-static void
-realloc_strcat(char **str, const char *append)
-{
- char *new_str;
- size_t old_len;
-
- if (*str == NULL)
- old_len = 0;
- else
- old_len = strlen(*str);
-
- new_str = malloc(old_len + strlen(append) + 1);
- if (new_str == NULL)
- lafe_errc(1, errno, "Out of memory");
- memcpy(new_str, *str, old_len);
- strcpy(new_str + old_len, append);
- free(*str);
- *str = new_str;
-}
-
-int
-apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, int symlink_only)
-{
- const char *path = name;
- regmatch_t matches[10];
- size_t i, j;
- struct subst_rule *rule;
- struct substitution *subst;
- int c, got_match, print_match;
-
- *result = NULL;
-
- if ((subst = bsdtar->substitution) == NULL)
- return 0;
-
- got_match = 0;
- print_match = 0;
-
- for (rule = subst->first_rule; rule != NULL; rule = rule->next) {
- if (symlink_only && !rule->symlink)
- continue;
- if (regexec(&rule->re, name, 10, matches, 0))
- continue;
-
- got_match = 1;
- print_match |= rule->print;
- realloc_strncat(result, name, matches[0].rm_so);
-
- for (i = 0, j = 0; rule->result[i] != '\0'; ++i) {
- if (rule->result[i] == '~') {
- realloc_strncat(result, rule->result + j, i - j);
- realloc_strncat(result, name, matches[0].rm_eo);
- j = i + 1;
- continue;
- }
- if (rule->result[i] != '\\')
- continue;
-
- ++i;
- c = rule->result[i];
- switch (c) {
- case '~':
- case '\\':
- realloc_strncat(result, rule->result + j, i - j - 1);
- j = i;
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- realloc_strncat(result, rule->result + j, i - j - 1);
- if ((size_t)(c - '0') > (size_t)(rule->re.re_nsub)) {
- free(*result);
- *result = NULL;
- return -1;
- }
- realloc_strncat(result, name + matches[c - '0'].rm_so, matches[c - '0'].rm_eo - matches[c - '0'].rm_so);
- j = i + 1;
- break;
- default:
- /* Just continue; */
- break;
- }
-
- }
-
- realloc_strcat(result, rule->result + j);
-
- name += matches[0].rm_eo;
-
- if (!rule->global)
- break;
- }
-
- if (got_match)
- realloc_strcat(result, name);
-
- if (print_match)
- fprintf(stderr, "%s >> %s\n", path, *result);
-
- return got_match;
-}
-
-void
-cleanup_substitution(struct bsdtar *bsdtar)
-{
- struct subst_rule *rule;
- struct substitution *subst;
-
- if ((subst = bsdtar->substitution) == NULL)
- return;
-
- while ((rule = subst->first_rule) != NULL) {
- subst->first_rule = rule->next;
- free(rule->result);
- free(rule);
- }
- free(subst);
-}
-#endif /* HAVE_REGEX_H */
diff --git a/usr.bin/tar/test/Makefile b/usr.bin/tar/test/Makefile
index bce8b5301c2b..d282616ac06e 100644
--- a/usr.bin/tar/test/Makefile
+++ b/usr.bin/tar/test/Makefile
@@ -1,13 +1,13 @@
# $FreeBSD$
-# Where to find the tar sources (for the internal unit tests)
-TAR_SRCDIR=${.CURDIR}/..
-.PATH: ${TAR_SRCDIR}
+LIBARCHIVEDIR= ${.CURDIR}/../../../contrib/libarchive
+.PATH: ${LIBARCHIVEDIR}/tar
# Some tar sources are pulled in for white-box tests
-TAR_SRCS= \
+TAR_SRCS= \
getdate.c
+.PATH: ${LIBARCHIVEDIR}/tar/test
TESTS= \
test_0.c \
test_basic.c \
@@ -26,7 +26,7 @@ TESTS= \
test_version.c
# Build the test program
-SRCS= ${TAR_SRCS} \
+SRCS= ${TAR_SRCS} \
${TESTS} \
list.h \
main.c
@@ -37,24 +37,25 @@ NO_MAN=yes
PROG=bsdtar_test
DPADD=${LIBARCHIVE} ${LIBBZ2} ${LIBZ}
-CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
-CFLAGS+= -I..
+CFLAGS+= -DPLATFORM_CONFIG_H=\"${.CURDIR}/../config_freebsd.h\"
LDADD= -larchive -lz -lbz2
CFLAGS+= -static -g -O2 -Wall
-CFLAGS+= -I${.OBJDIR}
-CFLAGS+= -I${TAR_SRCDIR}
+CFLAGS+= -I${.CURDIR}/.. -I${.OBJDIR}
+CFLAGS+= -I${LIBARCHIVEDIR}/tar
# Uncomment to link against dmalloc
#LDADD+= -L/usr/local/lib -ldmalloc
#CFLAGS+= -I/usr/local/include -DUSE_DMALLOC
check test: bsdtar_test
- ./bsdtar_test -p ${.OBJDIR}/../bsdtar -r ${.CURDIR}
+ ./bsdtar_test -p ${.OBJDIR}/../bsdtar -r ${LIBARCHIVEDIR}/tar/test
list.h: ${TESTS} Makefile
- (cd ${.CURDIR}; cat ${TESTS}) | grep DEFINE_TEST > list.h
+ (cd ${LIBARCHIVEDIR}/tar/test; cat ${TESTS}) | \
+ grep DEFINE_TEST > ${.OBJDIR}/list.h
clean:
+ rm -f ${CLEANFILES}
rm -f *.out
rm -f *.o
rm -f *.core
diff --git a/usr.bin/tar/test/main.c b/usr.bin/tar/test/main.c
deleted file mode 100644
index bd1db1d793eb..000000000000
--- a/usr.bin/tar/test/main.c
+++ /dev/null
@@ -1,2242 +0,0 @@
-/*
- * Copyright (c) 2003-2009 Tim Kientzle
- * 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"
-#include <errno.h>
-#include <locale.h>
-#include <stdarg.h>
-#include <time.h>
-
-/*
- * 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.
- */
-__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) ? "" : "")
-
-/*
- *
- * 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.
- */
-#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
-
-#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 and log data for successful tests. */
-static int keep_temp_files = 0;
-/* 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 reported skips. */
-static int skips = 0;
-/* Cumulative count of assertions checked. */
-static int assertions = 0;
-
-/* Directory where uuencoded reference files can be found. */
-static const char *refdir;
-
-/*
- * Report log information selectively to console and/or disk log.
- */
-static int log_console = 0;
-static FILE *logfile;
-static void
-vlogprintf(const char *fmt, va_list ap)
-{
-#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
-}
-
-static void
-logprintf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vlogprintf(fmt, ap);
- va_end(ap);
-}
-
-/* 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 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); */
-}
-
-/*
- * For each test source file, we remember how many times each
- * assertion was reported. Cleared before each new test,
- * used by test_summarize().
- */
-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;
-
- /* 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);
-#if _MSC_VER
- logprintf("%s(%d): ", filename, line);
-#else
- logprintf("%s:%d: ", filename, line);
-#endif
- vlogprintf(fmt, ap);
- va_end(ap);
- 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;
-}
-
-/* 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
-failure_finish(void *extra)
-{
- (void)extra; /* UNUSED (maybe) */
-#ifdef EXTRA_DUMP
- if (extra != NULL)
- logprintf(" detail: %s\n", EXTRA_DUMP(extra));
-#endif
-
- if (dump_on_failure) {
- fprintf(stderr,
- " *** forcing core dump so failure can be debugged ***\n");
- *(char *)(NULL) = 0;
- exit(1);
- }
-}
-
-/* Inform user that we're skipping some checks. */
-void
-test_skipping(const char *fmt, ...)
-{
- char buff[1024];
- va_list ap;
-
- va_start(ap, fmt);
- vsprintf(buff, fmt, ap);
- va_end(ap);
- /* failure_start() isn't quite right, but is awfully convenient. */
- failure_start(test_filename, test_line, "SKIPPING: %s", buff);
- --failures; /* Undo failures++ in failure_start() */
- /* Don't failure_finish() here. */
- /* Mark as skip, so doesn't count as failed test. */
- failed_lines[test_line].skip = 1;
- ++skips;
-}
-
-/*
- *
- * ASSERTIONS
- *
- */
-
-/* Generic assert() just displays the failed condition. */
-int
-assertion_assert(const char *file, int line, int value,
- const char *condition, void *extra)
-{
- assertion_count(file, line);
- if (!value) {
- failure_start(file, line, "Assertion failed: %s", condition);
- failure_finish(extra);
- }
- return (value);
-}
-
-/* chdir() and report any errors */
-int
-assertion_chdir(const char *file, int line, const char *pathname)
-{
- assertion_count(file, line);
- if (chdir(pathname) == 0)
- return (1);
- failure_start(file, line, "chdir(\"%s\")", pathname);
- failure_finish(NULL);
- return (0);
-
-}
-
-/* Verify two integers are equal. */
-int
-assertion_equal_int(const char *file, int line,
- long long v1, const char *e1, long long v2, const char *e2, void *extra)
-{
- assertion_count(file, line);
- if (v1 == v2)
- return (1);
- failure_start(file, line, "%s != %s", e1, e2);
- logprintf(" %s=%lld (0x%llx, 0%llo)\n", e1, v1, v1, v1);
- logprintf(" %s=%lld (0x%llx, 0%llo)\n", e2, v2, v2, v2);
- failure_finish(extra);
- return (0);
-}
-
-static void strdump(const char *e, const char *p)
-{
- const char *q = p;
-
- logprintf(" %s = ", e);
- if (p == NULL) {
- logprintf("NULL");
- return;
- }
- logprintf("\"");
- while (*p != '\0') {
- unsigned int c = 0xff & *p++;
- switch (c) {
- case '\a': printf("\a"); break;
- case '\b': printf("\b"); break;
- case '\n': printf("\n"); break;
- case '\r': printf("\r"); break;
- default:
- if (c >= 32 && c < 127)
- logprintf("%c", c);
- else
- logprintf("\\x%02X", c);
- }
- }
- logprintf("\"");
- logprintf(" (length %d)\n", q == NULL ? -1 : (int)strlen(q));
-}
-
-/* Verify two strings are equal, dump them if not. */
-int
-assertion_equal_string(const char *file, int line,
- const char *v1, const char *e1,
- const char *v2, const char *e2,
- void *extra)
-{
- assertion_count(file, line);
- if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0))
- return (1);
- failure_start(file, line, "%s != %s", e1, e2);
- strdump(e1, v1);
- strdump(e2, v2);
- failure_finish(extra);
- return (0);
-}
-
-static void
-wcsdump(const char *e, const wchar_t *w)
-{
- logprintf(" %s = ", e);
- if (w == NULL) {
- logprintf("(null)");
- return;
- }
- logprintf("\"");
- while (*w != L'\0') {
- unsigned int c = *w++;
- if (c >= 32 && c < 127)
- logprintf("%c", c);
- else if (c < 256)
- logprintf("\\x%02X", c);
- else if (c < 0x10000)
- logprintf("\\u%04X", c);
- else
- logprintf("\\U%08X", c);
- }
- logprintf("\"\n");
-}
-
-#ifndef HAVE_WCSCMP
-static int
-wcscmp(const wchar_t *s1, const wchar_t *s2)
-{
-
- while (*s1 == *s2++) {
- if (*s1++ == L'\0')
- return 0;
- }
- if (*s1 > *--s2)
- return 1;
- else
- return -1;
-}
-#endif
-
-/* Verify that two wide strings are equal, dump them if not. */
-int
-assertion_equal_wstring(const char *file, int line,
- const wchar_t *v1, const char *e1,
- const wchar_t *v2, const char *e2,
- void *extra)
-{
- assertion_count(file, line);
- if (v1 == v2 || wcscmp(v1, v2) == 0)
- return (1);
- failure_start(file, line, "%s != %s", e1, e2);
- wcsdump(e1, v1);
- wcsdump(e2, v2);
- failure_finish(extra);
- return (0);
-}
-
-/*
- * Pretty standard hexdump routine. As a bonus, if ref != NULL, then
- * any bytes in p that differ from ref will be highlighted with '_'
- * before and after the hex value.
- */
-static void
-hexdump(const char *p, const char *ref, size_t l, size_t offset)
-{
- size_t i, j;
- char sep;
-
- if (p == NULL) {
- logprintf("(null)\n");
- return;
- }
- for(i=0; i < l; i+=16) {
- logprintf("%04x", (unsigned)(i + offset));
- sep = ' ';
- for (j = 0; j < 16 && i + j < l; j++) {
- if (ref != NULL && p[i + j] != ref[i + j])
- sep = '_';
- logprintf("%c%02x", sep, 0xff & (int)p[i+j]);
- if (ref != NULL && p[i + j] == ref[i + j])
- sep = ' ';
- }
- for (; j < 16; j++) {
- logprintf("%c ", sep);
- sep = ' ';
- }
- logprintf("%c", sep);
- for (j=0; j < 16 && i + j < l; j++) {
- int c = p[i + j];
- if (c >= ' ' && c <= 126)
- logprintf("%c", c);
- else
- logprintf(".");
- }
- logprintf("\n");
- }
-}
-
-/* Verify that two blocks of memory are the same, display the first
- * block of differences if they're not. */
-int
-assertion_equal_mem(const char *file, int line,
- const void *_v1, const char *e1,
- const void *_v2, const char *e2,
- size_t l, const char *ld, void *extra)
-{
- const char *v1 = (const char *)_v1;
- const char *v2 = (const char *)_v2;
- size_t offset;
-
- assertion_count(file, line);
- if (v1 == v2 || (v1 != NULL && v2 != NULL && memcmp(v1, v2, l) == 0))
- return (1);
-
- failure_start(file, line, "%s != %s", e1, e2);
- logprintf(" size %s = %d\n", ld, (int)l);
- /* Dump 48 bytes (3 lines) so that the first difference is
- * in the second line. */
- offset = 0;
- while (l > 64 && memcmp(v1, v2, 32) == 0) {
- /* Two lines agree, so step forward one line. */
- v1 += 16;
- v2 += 16;
- l -= 16;
- offset += 16;
- }
- logprintf(" Dump of %s\n", e1);
- hexdump(v1, v2, l < 64 ? l : 64, offset);
- logprintf(" Dump of %s\n", e2);
- hexdump(v2, v1, l < 64 ? l : 64, offset);
- logprintf("\n");
- failure_finish(extra);
- return (0);
-}
-
-/* Verify that the named file exists and is empty. */
-int
-assertion_empty_file(const char *f1fmt, ...)
-{
- char buff[1024];
- char f1[1024];
- struct stat st;
- va_list ap;
- ssize_t s;
- FILE *f;
-
- assertion_count(test_filename, test_line);
- va_start(ap, f1fmt);
- vsprintf(f1, f1fmt, ap);
- va_end(ap);
-
- if (stat(f1, &st) != 0) {
- failure_start(test_filename, test_line, "Stat failed: %s", f1);
- failure_finish(NULL);
- return (0);
- }
- if (st.st_size == 0)
- return (1);
-
- failure_start(test_filename, test_line, "File should be empty: %s", f1);
- logprintf(" File size: %d\n", (int)st.st_size);
- logprintf(" Contents:\n");
- f = fopen(f1, "rb");
- if (f == NULL) {
- logprintf(" Unable to open %s\n", f1);
- } else {
- s = ((off_t)sizeof(buff) < st.st_size) ?
- (ssize_t)sizeof(buff) : (ssize_t)st.st_size;
- s = fread(buff, 1, s, f);
- hexdump(buff, NULL, s, 0);
- fclose(f);
- }
- failure_finish(NULL);
- return (0);
-}
-
-/* Verify that the named file exists and is not empty. */
-int
-assertion_non_empty_file(const char *f1fmt, ...)
-{
- char f1[1024];
- struct stat st;
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, f1fmt);
- vsprintf(f1, f1fmt, ap);
- va_end(ap);
-
- if (stat(f1, &st) != 0) {
- failure_start(test_filename, test_line, "Stat failed: %s", f1);
- failure_finish(NULL);
- return (0);
- }
- if (st.st_size == 0) {
- failure_start(test_filename, test_line, "File empty: %s", f1);
- failure_finish(NULL);
- return (0);
- }
- return (1);
-}
-
-/* Verify that two files have the same contents. */
-/* TODO: hexdump the first bytes that actually differ. */
-int
-assertion_equal_file(const char *fn1, const char *f2pattern, ...)
-{
- char fn2[1024];
- va_list ap;
- char buff1[1024];
- char buff2[1024];
- FILE *f1, *f2;
- int n1, n2;
-
- assertion_count(test_filename, test_line);
- va_start(ap, f2pattern);
- vsprintf(fn2, f2pattern, ap);
- va_end(ap);
-
- f1 = fopen(fn1, "rb");
- f2 = fopen(fn2, "rb");
- for (;;) {
- n1 = fread(buff1, 1, sizeof(buff1), f1);
- n2 = fread(buff2, 1, sizeof(buff2), f2);
- if (n1 != n2)
- break;
- if (n1 == 0 && n2 == 0) {
- fclose(f1);
- fclose(f2);
- return (1);
- }
- if (memcmp(buff1, buff2, n1) != 0)
- break;
- }
- fclose(f1);
- fclose(f2);
- failure_start(test_filename, test_line, "Files not identical");
- logprintf(" file1=\"%s\"\n", fn1);
- logprintf(" file2=\"%s\"\n", fn2);
- failure_finish(test_extra);
- return (0);
-}
-
-/* Verify that the named file does exist. */
-int
-assertion_file_exists(const char *fpattern, ...)
-{
- char f[1024];
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
- va_end(ap);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (!_access(f, 0))
- return (1);
-#else
- if (!access(f, F_OK))
- return (1);
-#endif
- failure_start(test_filename, test_line, "File should exist: %s", f);
- failure_finish(test_extra);
- return (0);
-}
-
-/* Verify that the named file doesn't exist. */
-int
-assertion_file_not_exists(const char *fpattern, ...)
-{
- char f[1024];
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
- va_end(ap);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (_access(f, 0))
- return (1);
-#else
- if (access(f, F_OK))
- return (1);
-#endif
- failure_start(test_filename, test_line, "File should not exist: %s", f);
- failure_finish(test_extra);
- return (0);
-}
-
-/* Compare the contents of a file to a block of memory. */
-int
-assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
-{
- char fn[1024];
- va_list ap;
- char *contents;
- FILE *f;
- int n;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(fn, fpattern, ap);
- va_end(ap);
-
- f = fopen(fn, "rb");
- if (f == NULL) {
- failure_start(test_filename, test_line,
- "File should exist: %s", fn);
- failure_finish(test_extra);
- return (0);
- }
- contents = malloc(s * 2);
- n = fread(contents, 1, s * 2, f);
- fclose(f);
- if (n == s && memcmp(buff, contents, s) == 0) {
- free(contents);
- return (1);
- }
- failure_start(test_filename, test_line, "File contents don't match");
- logprintf(" file=\"%s\"\n", fn);
- if (n > 0)
- hexdump(contents, buff, n > 512 ? 512 : n, 0);
- else {
- logprintf(" File empty, contents should be:\n");
- hexdump(buff, NULL, s > 512 ? 512 : s, 0);
- }
- failure_finish(test_extra);
- free(contents);
- return (0);
-}
-
-/* Check the contents of a text file, being tolerant of line endings. */
-int
-assertion_text_file_contents(const char *buff, const char *fn)
-{
- char *contents;
- const char *btxt, *ftxt;
- FILE *f;
- int n, s;
-
- assertion_count(test_filename, test_line);
- f = fopen(fn, "r");
- s = strlen(buff);
- contents = malloc(s * 2 + 128);
- n = fread(contents, 1, s * 2 + 128 - 1, f);
- if (n >= 0)
- contents[n] = '\0';
- fclose(f);
- /* Compare texts. */
- btxt = buff;
- ftxt = (const char *)contents;
- while (*btxt != '\0' && *ftxt != '\0') {
- if (*btxt == *ftxt) {
- ++btxt;
- ++ftxt;
- continue;
- }
- if (btxt[0] == '\n' && ftxt[0] == '\r' && ftxt[1] == '\n') {
- /* Pass over different new line characters. */
- ++btxt;
- ftxt += 2;
- continue;
- }
- break;
- }
- if (*btxt == '\0' && *ftxt == '\0') {
- free(contents);
- return (1);
- }
- failure_start(test_filename, test_line, "Contents don't match");
- logprintf(" file=\"%s\"\n", fn);
- if (n > 0)
- hexdump(contents, buff, n, 0);
- else {
- logprintf(" File empty, contents should be:\n");
- hexdump(buff, NULL, s, 0);
- }
- failure_finish(test_extra);
- free(contents);
- return (0);
-}
-
-/* Verify that a text file contains the specified lines, regardless of order */
-/* This could be more efficient if we sorted both sets of lines, etc, but
- * since this is used only for testing and only ever deals with a dozen or so
- * lines at a time, this relatively crude approach is just fine. */
-int
-assertion_file_contains_lines_any_order(const char *file, int line,
- const char *pathname, const char *lines[])
-{
- char *buff;
- size_t buff_size;
- size_t expected_count, actual_count, i, j;
- char **expected;
- char *p, **actual;
- char c;
- int expected_failure = 0, actual_failure = 0;
-
- assertion_count(file, line);
-
- buff = slurpfile(&buff_size, "%s", pathname);
- if (buff == NULL) {
- failure_start(pathname, line, "Can't read file: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
-
- // Make a copy of the provided lines and count up the expected file size.
- expected_count = 0;
- for (i = 0; lines[i] != NULL; ++i) {
- }
- expected_count = i;
- expected = malloc(sizeof(char *) * expected_count);
- for (i = 0; lines[i] != NULL; ++i) {
- expected[i] = strdup(lines[i]);
- }
-
- // Break the file into lines
- actual_count = 0;
- for (c = '\0', p = buff; p < buff + buff_size; ++p) {
- if (*p == '\x0d' || *p == '\x0a')
- *p = '\0';
- if (c == '\0' && *p != '\0')
- ++actual_count;
- c = *p;
- }
- actual = malloc(sizeof(char *) * actual_count);
- for (j = 0, p = buff; p < buff + buff_size; p += 1 + strlen(p)) {
- if (*p != '\0') {
- actual[j] = p;
- ++j;
- }
- }
-
- // Erase matching lines from both lists
- for (i = 0; i < expected_count; ++i) {
- if (expected[i] == NULL)
- continue;
- for (j = 0; j < actual_count; ++j) {
- if (actual[j] == NULL)
- continue;
- if (strcmp(expected[i], actual[j]) == 0) {
- free(expected[i]);
- expected[i] = NULL;
- actual[j] = NULL;
- break;
- }
- }
- }
-
- // If there's anything left, it's a failure
- for (i = 0; i < expected_count; ++i) {
- if (expected[i] != NULL)
- ++expected_failure;
- }
- for (j = 0; j < actual_count; ++j) {
- if (actual[j] != NULL)
- ++actual_failure;
- }
- if (expected_failure == 0 && actual_failure == 0) {
- free(buff);
- free(expected);
- free(actual);
- return (1);
- }
- failure_start(file, line, "File doesn't match: %s", pathname);
- for (i = 0; i < expected_count; ++i) {
- if (expected[i] != NULL) {
- logprintf(" Expected but not present: %s\n", expected[i]);
- free(expected[i]);
- }
- }
- for (j = 0; j < actual_count; ++j) {
- if (actual[j] != NULL)
- logprintf(" Present but not expected: %s\n", actual[j]);
- }
- failure_finish(NULL);
- free(buff);
- free(expected);
- free(actual);
- return (0);
-}
-
-/* Test that two paths point to the same file. */
-/* As a side-effect, asserts that both files exist. */
-static int
-is_hardlink(const char *file, int line,
- const char *path1, const char *path2)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- BY_HANDLE_FILE_INFORMATION bhfi1, bhfi2;
- int r;
-
- assertion_count(file, line);
- r = my_GetFileInformationByName(path1, &bhfi1);
- if (r == 0) {
- failure_start(file, line, "File %s can't be inspected?", path1);
- failure_finish(NULL);
- return (0);
- }
- r = my_GetFileInformationByName(path2, &bhfi2);
- if (r == 0) {
- failure_start(file, line, "File %s can't be inspected?", path2);
- failure_finish(NULL);
- return (0);
- }
- return (bhfi1.dwVolumeSerialNumber == bhfi2.dwVolumeSerialNumber
- && bhfi1.nFileIndexHigh == bhfi2.nFileIndexHigh
- && bhfi1.nFileIndexLow == bhfi2.nFileIndexLow);
-#else
- struct stat st1, st2;
- int r;
-
- assertion_count(file, line);
- r = lstat(path1, &st1);
- if (r != 0) {
- failure_start(file, line, "File should exist: %s", path1);
- failure_finish(NULL);
- return (0);
- }
- r = lstat(path2, &st2);
- if (r != 0) {
- failure_start(file, line, "File should exist: %s", path2);
- failure_finish(NULL);
- return (0);
- }
- return (st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev);
-#endif
-}
-
-int
-assertion_is_hardlink(const char *file, int line,
- const char *path1, const char *path2)
-{
- if (is_hardlink(file, line, path1, path2))
- return (1);
- failure_start(file, line,
- "Files %s and %s are not hardlinked", path1, path2);
- failure_finish(NULL);
- return (0);
-}
-
-int
-assertion_is_not_hardlink(const char *file, int line,
- const char *path1, const char *path2)
-{
- if (!is_hardlink(file, line, path1, path2))
- return (1);
- failure_start(file, line,
- "Files %s and %s should not be hardlinked", path1, path2);
- failure_finish(NULL);
- return (0);
-}
-
-/* Verify a/b/mtime of 'pathname'. */
-/* If 'recent', verify that it's within last 10 seconds. */
-static int
-assertion_file_time(const char *file, int line,
- const char *pathname, long t, long nsec, char type, int recent)
-{
- long long filet, filet_nsec;
- int r;
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define EPOC_TIME (116444736000000000ULL)
- FILETIME ftime, fbirthtime, fatime, fmtime;
- ULARGE_INTEGER wintm;
- HANDLE h;
- ftime.dwLowDateTime = 0;
- ftime.dwHighDateTime = 0;
-
- assertion_count(file, line);
- h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE) {
- failure_start(file, line, "Can't access %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- r = GetFileTime(h, &fbirthtime, &fatime, &fmtime);
- switch (type) {
- case 'a': ftime = fatime; break;
- case 'b': ftime = fbirthtime; break;
- case 'm': ftime = fmtime; break;
- }
- CloseHandle(h);
- if (r == 0) {
- failure_start(file, line, "Can't GetFileTime %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- wintm.LowPart = ftime.dwLowDateTime;
- wintm.HighPart = ftime.dwHighDateTime;
- filet = (wintm.QuadPart - EPOC_TIME) / 10000000;
- filet_nsec = ((wintm.QuadPart - EPOC_TIME) % 10000000) * 100;
- nsec = (nsec / 100) * 100; /* Round the request */
-#else
- struct stat st;
-
- assertion_count(file, line);
- r = lstat(pathname, &st);
- if (r != 0) {
- failure_start(file, line, "Can't stat %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- switch (type) {
- case 'a': filet = st.st_atime; break;
- case 'm': filet = st.st_mtime; break;
- case 'b': filet = 0; break;
- default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type);
- exit(1);
- }
-#if defined(__FreeBSD__)
- switch (type) {
- case 'a': filet_nsec = st.st_atimespec.tv_nsec; break;
- case 'b': filet = st.st_birthtime;
- filet_nsec = st.st_birthtimespec.tv_nsec; break;
- case 'm': filet_nsec = st.st_mtimespec.tv_nsec; break;
- default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type);
- exit(1);
- }
- /* FreeBSD generally only stores to microsecond res, so round. */
- filet_nsec = (filet_nsec / 1000) * 1000;
- nsec = (nsec / 1000) * 1000;
-#else
- filet_nsec = nsec = 0; /* Generic POSIX only has whole seconds. */
- if (type == 'b') return (1); /* Generic POSIX doesn't have birthtime */
-#if defined(__HAIKU__)
- if (type == 'a') return (1); /* Haiku doesn't have atime. */
-#endif
-#endif
-#endif
- if (recent) {
- /* Check that requested time is up-to-date. */
- time_t now = time(NULL);
- if (filet < now - 10 || filet > now + 1) {
- failure_start(file, line,
- "File %s has %ctime %ld, %ld seconds ago\n",
- pathname, type, filet, now - filet);
- failure_finish(NULL);
- return (0);
- }
- } else if (filet != t || filet_nsec != nsec) {
- failure_start(file, line,
- "File %s has %ctime %ld.%09ld, expected %ld.%09ld",
- pathname, type, filet, filet_nsec, t, nsec);
- failure_finish(NULL);
- return (0);
- }
- return (1);
-}
-
-/* Verify atime of 'pathname'. */
-int
-assertion_file_atime(const char *file, int line,
- const char *pathname, long t, long nsec)
-{
- return assertion_file_time(file, line, pathname, t, nsec, 'a', 0);
-}
-
-/* Verify atime of 'pathname' is up-to-date. */
-int
-assertion_file_atime_recent(const char *file, int line, const char *pathname)
-{
- return assertion_file_time(file, line, pathname, 0, 0, 'a', 1);
-}
-
-/* Verify birthtime of 'pathname'. */
-int
-assertion_file_birthtime(const char *file, int line,
- const char *pathname, long t, long nsec)
-{
- return assertion_file_time(file, line, pathname, t, nsec, 'b', 0);
-}
-
-/* Verify birthtime of 'pathname' is up-to-date. */
-int
-assertion_file_birthtime_recent(const char *file, int line,
- const char *pathname)
-{
- return assertion_file_time(file, line, pathname, 0, 0, 'b', 1);
-}
-
-/* Verify mtime of 'pathname'. */
-int
-assertion_file_mtime(const char *file, int line,
- const char *pathname, long t, long nsec)
-{
- return assertion_file_time(file, line, pathname, t, nsec, 'm', 0);
-}
-
-/* Verify mtime of 'pathname' is up-to-date. */
-int
-assertion_file_mtime_recent(const char *file, int line, const char *pathname)
-{
- return assertion_file_time(file, line, pathname, 0, 0, 'm', 1);
-}
-
-/* Verify number of links to 'pathname'. */
-int
-assertion_file_nlinks(const char *file, int line,
- const char *pathname, int nlinks)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- BY_HANDLE_FILE_INFORMATION bhfi;
- int r;
-
- assertion_count(file, line);
- r = my_GetFileInformationByName(pathname, &bhfi);
- if (r != 0 && bhfi.nNumberOfLinks == (DWORD)nlinks)
- return (1);
- failure_start(file, line, "File %s has %d links, expected %d",
- pathname, bhfi.nNumberOfLinks, nlinks);
- failure_finish(NULL);
- return (0);
-#else
- struct stat st;
- int r;
-
- assertion_count(file, line);
- r = lstat(pathname, &st);
- if (r == 0 && st.st_nlink == nlinks)
- return (1);
- failure_start(file, line, "File %s has %d links, expected %d",
- pathname, st.st_nlink, nlinks);
- failure_finish(NULL);
- return (0);
-#endif
-}
-
-/* Verify size of 'pathname'. */
-int
-assertion_file_size(const char *file, int line, const char *pathname, long size)
-{
- int64_t filesize;
- int r;
-
- assertion_count(file, line);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- {
- BY_HANDLE_FILE_INFORMATION bhfi;
- r = !my_GetFileInformationByName(pathname, &bhfi);
- filesize = ((int64_t)bhfi.nFileSizeHigh << 32) + bhfi.nFileSizeLow;
- }
-#else
- {
- struct stat st;
- r = lstat(pathname, &st);
- filesize = st.st_size;
- }
-#endif
- if (r == 0 && filesize == size)
- return (1);
- failure_start(file, line, "File %s has size %ld, expected %ld",
- pathname, (long)filesize, (long)size);
- failure_finish(NULL);
- return (0);
-}
-
-/* Assert that 'pathname' is a dir. If mode >= 0, verify that too. */
-int
-assertion_is_dir(const char *file, int line, const char *pathname, int mode)
-{
- struct stat st;
- int r;
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- (void)mode; /* UNUSED */
-#endif
- assertion_count(file, line);
- r = lstat(pathname, &st);
- if (r != 0) {
- failure_start(file, line, "Dir should exist: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
- if (!S_ISDIR(st.st_mode)) {
- failure_start(file, line, "%s is not a dir", pathname);
- failure_finish(NULL);
- return (0);
- }
-#if !defined(_WIN32) || defined(__CYGWIN__)
- /* Windows doesn't handle permissions the same way as POSIX,
- * so just ignore the mode tests. */
- /* TODO: Can we do better here? */
- if (mode >= 0 && mode != (st.st_mode & 07777)) {
- failure_start(file, line, "Dir %s has wrong mode", pathname);
- logprintf(" Expected: 0%3o\n", mode);
- logprintf(" Found: 0%3o\n", st.st_mode & 07777);
- failure_finish(NULL);
- return (0);
- }
-#endif
- return (1);
-}
-
-/* Verify that 'pathname' is a regular file. If 'mode' is >= 0,
- * verify that too. */
-int
-assertion_is_reg(const char *file, int line, const char *pathname, int mode)
-{
- struct stat st;
- int r;
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- (void)mode; /* UNUSED */
-#endif
- assertion_count(file, line);
- r = lstat(pathname, &st);
- if (r != 0 || !S_ISREG(st.st_mode)) {
- failure_start(file, line, "File should exist: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
-#if !defined(_WIN32) || defined(__CYGWIN__)
- /* Windows doesn't handle permissions the same way as POSIX,
- * so just ignore the mode tests. */
- /* TODO: Can we do better here? */
- if (mode >= 0 && mode != (st.st_mode & 07777)) {
- failure_start(file, line, "File %s has wrong mode", pathname);
- logprintf(" Expected: 0%3o\n", mode);
- logprintf(" Found: 0%3o\n", st.st_mode & 07777);
- failure_finish(NULL);
- return (0);
- }
-#endif
- return (1);
-}
-
-/* Check whether 'pathname' is a symbolic link. If 'contents' is
- * non-NULL, verify that the symlink has those contents. */
-static int
-is_symlink(const char *file, int line,
- const char *pathname, const char *contents)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- (void)pathname; /* UNUSED */
- (void)contents; /* UNUSED */
- assertion_count(file, line);
- /* Windows sort-of has real symlinks, but they're only usable
- * by privileged users and are crippled even then, so there's
- * really not much point in bothering with this. */
- return (0);
-#else
- char buff[300];
- struct stat st;
- ssize_t linklen;
- int r;
-
- assertion_count(file, line);
- r = lstat(pathname, &st);
- if (r != 0) {
- failure_start(file, line,
- "Symlink should exist: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
- if (!S_ISLNK(st.st_mode))
- return (0);
- if (contents == NULL)
- return (1);
- linklen = readlink(pathname, buff, sizeof(buff));
- if (linklen < 0) {
- failure_start(file, line, "Can't read symlink %s", pathname);
- failure_finish(NULL);
- return (0);
- }
- buff[linklen] = '\0';
- if (strcmp(buff, contents) != 0)
- return (0);
- return (1);
-#endif
-}
-
-/* Assert that path is a symlink that (optionally) contains contents. */
-int
-assertion_is_symlink(const char *file, int line,
- const char *path, const char *contents)
-{
- if (is_symlink(file, line, path, contents))
- return (1);
- if (contents)
- failure_start(file, line, "File %s is not a symlink to %s",
- path, contents);
- else
- failure_start(file, line, "File %s is not a symlink", path);
- failure_finish(NULL);
- return (0);
-}
-
-
-/* Create a directory and report any errors. */
-int
-assertion_make_dir(const char *file, int line, const char *dirname, int mode)
-{
- assertion_count(file, line);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- (void)mode; /* UNUSED */
- if (0 == _mkdir(dirname))
- return (1);
-#else
- if (0 == mkdir(dirname, mode))
- return (1);
-#endif
- failure_start(file, line, "Could not create directory %s", dirname);
- failure_finish(NULL);
- return(0);
-}
-
-/* Create a file with the specified contents and report any failures. */
-int
-assertion_make_file(const char *file, int line,
- const char *path, int mode, const char *contents)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* TODO: Rework this to set file mode as well. */
- FILE *f;
- (void)mode; /* UNUSED */
- assertion_count(file, line);
- f = fopen(path, "wb");
- if (f == NULL) {
- failure_start(file, line, "Could not create file %s", path);
- failure_finish(NULL);
- return (0);
- }
- if (contents != NULL) {
- if (strlen(contents)
- != fwrite(contents, 1, strlen(contents), f)) {
- fclose(f);
- failure_start(file, line,
- "Could not write file %s", path);
- failure_finish(NULL);
- return (0);
- }
- }
- fclose(f);
- return (1);
-#else
- int fd;
- assertion_count(file, line);
- fd = open(path, O_CREAT | O_WRONLY, mode >= 0 ? mode : 0644);
- if (fd < 0) {
- failure_start(file, line, "Could not create %s", path);
- failure_finish(NULL);
- return (0);
- }
- if (contents != NULL) {
- if ((ssize_t)strlen(contents)
- != write(fd, contents, strlen(contents))) {
- close(fd);
- failure_start(file, line, "Could not write to %s", path);
- failure_finish(NULL);
- return (0);
- }
- }
- close(fd);
- return (1);
-#endif
-}
-
-/* Create a hardlink and report any failures. */
-int
-assertion_make_hardlink(const char *file, int line,
- const char *newpath, const char *linkto)
-{
- int succeeded;
-
- assertion_count(file, line);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- succeeded = my_CreateHardLinkA(newpath, linkto);
-#elif HAVE_LINK
- succeeded = !link(linkto, newpath);
-#else
- succeeded = 0;
-#endif
- if (succeeded)
- return (1);
- failure_start(file, line, "Could not create hardlink");
- logprintf(" New link: %s\n", newpath);
- logprintf(" Old name: %s\n", linkto);
- failure_finish(NULL);
- return(0);
-}
-
-/* Create a symlink and report any failures. */
-int
-assertion_make_symlink(const char *file, int line,
- const char *newpath, const char *linkto)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- int targetIsDir = 0; /* TODO: Fix this */
- assertion_count(file, line);
- if (my_CreateSymbolicLinkA(newpath, linkto, targetIsDir))
- return (1);
-#elif HAVE_SYMLINK
- assertion_count(file, line);
- if (0 == symlink(linkto, newpath))
- return (1);
-#endif
- failure_start(file, line, "Could not create symlink");
- logprintf(" New link: %s\n", newpath);
- logprintf(" Old name: %s\n", linkto);
- failure_finish(NULL);
- return(0);
-}
-
-/* Set umask, report failures. */
-int
-assertion_umask(const char *file, int line, int mask)
-{
- assertion_count(file, line);
- (void)file; /* UNUSED */
- (void)line; /* UNUSED */
- umask(mask);
- return (1);
-}
-
-/*
- *
- * UTILITIES for use by tests.
- *
- */
-
-/*
- * Check whether platform supports symlinks. This is intended
- * for tests to use in deciding whether to bother testing symlink
- * support; if the platform doesn't support symlinks, there's no point
- * in checking whether the program being tested can create them.
- *
- * Note that the first time this test is called, we actually go out to
- * disk to create and verify a symlink. This is necessary because
- * symlink support is actually a property of a particular filesystem
- * and can thus vary between directories on a single system. After
- * the first call, this returns the cached result from memory, so it's
- * safe to call it as often as you wish.
- */
-int
-canSymlink(void)
-{
- /* Remember the test result */
- static int value = 0, tested = 0;
- if (tested)
- return (value);
-
- ++tested;
- assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
- /* Note: Cygwin has its own symlink() emulation that does not
- * use the Win32 CreateSymbolicLink() function. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- value = my_CreateSymbolicLinkA("canSymlink.1", "canSymlink.0", 0)
- && is_symlink(__FILE__, __LINE__, "canSymlink.1", "canSymlink.0");
-#elif HAVE_SYMLINK
- value = (0 == symlink("canSymlink.0", "canSymlink.1"))
- && is_symlink(__FILE__, __LINE__, "canSymlink.1","canSymlink.0");
-#endif
- return (value);
-}
-
-/*
- * Can this platform run the gzip program?
- */
-/* Platform-dependent options for hiding the output of a subcommand. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-static const char *redirectArgs = ">NUL 2>NUL"; /* Win32 cmd.exe */
-#else
-static const char *redirectArgs = ">/dev/null 2>/dev/null"; /* POSIX 'sh' */
-#endif
-int
-canGzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("gzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the gunzip program?
- */
-int
-canGunzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("gunzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Sleep as needed; useful for verifying disk timestamp changes by
- * ensuring that the wall-clock time has actually changed before we
- * go back to re-read something from disk.
- */
-void
-sleepUntilAfter(time_t t)
-{
- while (t >= time(NULL))
-#if defined(_WIN32) && !defined(__CYGWIN__)
- Sleep(500);
-#else
- sleep(1);
-#endif
-}
-
-/*
- * Call standard system() call, but build up the command line using
- * sprintf() conventions.
- */
-int
-systemf(const char *fmt, ...)
-{
- char buff[8192];
- va_list ap;
- int r;
-
- va_start(ap, fmt);
- vsprintf(buff, fmt, ap);
- if (verbosity > VERBOSITY_FULL)
- logprintf("Cmd: %s\n", buff);
- r = system(buff);
- va_end(ap);
- return (r);
-}
-
-/*
- * Slurp a file into memory for ease of comparison and testing.
- * Returns size of file in 'sizep' if non-NULL, null-terminates
- * data in memory for ease of use.
- */
-char *
-slurpfile(size_t * sizep, const char *fmt, ...)
-{
- char filename[8192];
- struct stat st;
- va_list ap;
- char *p;
- ssize_t bytes_read;
- FILE *f;
- int r;
-
- va_start(ap, fmt);
- vsprintf(filename, fmt, ap);
- va_end(ap);
-
- f = fopen(filename, "rb");
- if (f == NULL) {
- /* Note: No error; non-existent file is okay here. */
- return (NULL);
- }
- r = fstat(fileno(f), &st);
- if (r != 0) {
- logprintf("Can't stat file %s\n", filename);
- fclose(f);
- return (NULL);
- }
- p = malloc((size_t)st.st_size + 1);
- if (p == NULL) {
- logprintf("Can't allocate %ld bytes of memory to read file %s\n",
- (long int)st.st_size, filename);
- fclose(f);
- return (NULL);
- }
- bytes_read = fread(p, 1, (size_t)st.st_size, f);
- if (bytes_read < st.st_size) {
- logprintf("Can't read file %s\n", filename);
- fclose(f);
- free(p);
- return (NULL);
- }
- p[st.st_size] = '\0';
- if (sizep != NULL)
- *sizep = (size_t)st.st_size;
- fclose(f);
- return (p);
-}
-
-/* Read a uuencoded file from the reference directory, decode, and
- * write the result into the current directory. */
-#define UUDECODE(c) (((c) - 0x20) & 0x3f)
-void
-extract_reference_file(const char *name)
-{
- char buff[1024];
- FILE *in, *out;
-
- sprintf(buff, "%s/%s.uu", refdir, name);
- in = fopen(buff, "r");
- failure("Couldn't open reference file %s", buff);
- assert(in != NULL);
- if (in == NULL)
- return;
- /* Read up to and including the 'begin' line. */
- for (;;) {
- if (fgets(buff, sizeof(buff), in) == NULL) {
- /* TODO: This is a failure. */
- return;
- }
- if (memcmp(buff, "begin ", 6) == 0)
- break;
- }
- /* Now, decode the rest and write it. */
- /* Not a lot of error checking here; the input better be right. */
- out = fopen(name, "wb");
- while (fgets(buff, sizeof(buff), in) != NULL) {
- char *p = buff;
- int bytes;
-
- if (memcmp(buff, "end", 3) == 0)
- break;
-
- bytes = UUDECODE(*p++);
- while (bytes > 0) {
- int n = 0;
- /* Write out 1-3 bytes from that. */
- if (bytes > 0) {
- n = UUDECODE(*p++) << 18;
- n |= UUDECODE(*p++) << 12;
- fputc(n >> 16, out);
- --bytes;
- }
- if (bytes > 0) {
- n |= UUDECODE(*p++) << 6;
- fputc((n >> 8) & 0xFF, out);
- --bytes;
- }
- if (bytes > 0) {
- n |= UUDECODE(*p++);
- fputc(n & 0xFF, out);
- --bytes;
- }
- }
- }
- fclose(out);
- fclose(in);
-}
-
-/*
- *
- * TEST management
- *
- */
-
-/*
- * "list.h" is simply created by "grep DEFINE_TEST test_*.c"; it has
- * a line like
- * DEFINE_TEST(test_function)
- * for each test.
- */
-
-/* Use "list.h" to declare all of the test functions. */
-#undef DEFINE_TEST
-#define DEFINE_TEST(name) void name(void);
-#include "list.h"
-
-/* Use "list.h" to create a list of all tests (functions and names). */
-#undef DEFINE_TEST
-#define DEFINE_TEST(n) { n, #n, 0 },
-struct { void (*func)(void); const char *name; int failures; } tests[] = {
- #include "list.h"
-};
-
-/*
- * Summarize repeated failures in the just-completed test.
- */
-static void
-test_summarize(const char *filename, int failed)
-{
- unsigned int i;
-
- switch (verbosity) {
- case VERBOSITY_SUMMARY_ONLY:
- printf(failed ? "E" : ".");
- fflush(stdout);
- break;
- case VERBOSITY_PASSFAIL:
- printf(failed ? "FAIL\n" : "ok\n");
- break;
- }
-
- log_console = (verbosity == VERBOSITY_LIGHT_REPORT);
-
- for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].count > 1 && !failed_lines[i].skip)
- logprintf("%s:%d: Summary: Failed %d times\n",
- filename, i, failed_lines[i].count);
- }
- /* Clear the failure history for the next file. */
- memset(failed_lines, 0, sizeof(failed_lines));
-}
-
-/*
- * Actually run a single test, with appropriate setup and cleanup.
- */
-static int
-test_run(int i, const char *tmpdir)
-{
- char logfilename[64];
- int failures_before = failures;
- int oldumask;
-
- switch (verbosity) {
- case VERBOSITY_SUMMARY_ONLY: /* No per-test reports at all */
- break;
- case VERBOSITY_PASSFAIL: /* rest of line will include ok/FAIL marker */
- printf("%3d: %-50s", i, tests[i].name);
- fflush(stdout);
- break;
- default: /* Title of test, details will follow */
- printf("%3d: %s\n", i, tests[i].name);
- }
-
- /* Chdir to the top-level work directory. */
- if (!assertChdir(tmpdir)) {
- fprintf(stderr,
- "ERROR: Can't chdir to top work dir %s\n", tmpdir);
- exit(1);
- }
- /* Create a log file for this test. */
- sprintf(logfilename, "%s.log", tests[i].name);
- logfile = fopen(logfilename, "w");
- fprintf(logfile, "%s\n\n", tests[i].name);
- /* Chdir() to a work dir for this specific test. */
- if (!assertMakeDir(tests[i].name, 0755)
- || !assertChdir(tests[i].name)) {
- fprintf(stderr,
- "ERROR: Can't chdir to work dir %s/%s\n",
- tmpdir, tests[i].name);
- exit(1);
- }
- /* Explicitly reset the locale before each test. */
- setlocale(LC_ALL, "C");
- /* Record the umask before we run the test. */
- umask(oldumask = umask(0));
- /*
- * Run the actual test.
- */
- (*tests[i].func)();
- /*
- * Clean up and report afterwards.
- */
- /* Restore umask */
- umask(oldumask);
- /* Reset locale. */
- setlocale(LC_ALL, "C");
- /* Reset directory. */
- if (!assertChdir(tmpdir)) {
- fprintf(stderr, "ERROR: Couldn't chdir to temp dir %s\n",
- tmpdir);
- exit(1);
- }
- /* Report per-test summaries. */
- tests[i].failures = failures - failures_before;
- test_summarize(test_filename, tests[i].failures);
- /* Close the per-test log file. */
- fclose(logfile);
- logfile = NULL;
- /* If there were no failures, we can remove the work dir and logfile. */
- if (tests[i].failures == 0) {
- if (!keep_temp_files && assertChdir(tmpdir)) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure not to leave empty directories.
- * Sometimes a processing of closing files used by tests
- * is not done, then rmdir will be failed and it will
- * leave a empty test directory. So we should wait a few
- * seconds and retry rmdir. */
- int r, t;
- for (t = 0; t < 10; t++) {
- if (t > 0)
- Sleep(1000);
- r = systemf("rmdir /S /Q %s", tests[i].name);
- if (r == 0)
- break;
- }
- systemf("del %s", logfilename);
-#else
- systemf("rm -rf %s", tests[i].name);
- systemf("rm %s", logfilename);
-#endif
- }
- }
- /* Return appropriate status. */
- return (tests[i].failures);
-}
-
-/*
- *
- *
- * MAIN and support routines.
- *
- *
- */
-
-static void
-usage(const char *program)
-{
- static const int limit = sizeof(tests) / sizeof(tests[0]);
- int i;
-
- printf("Usage: %s [options] <test> <test> ...\n", program);
- printf("Default is to run all tests.\n");
- printf("Otherwise, specify the numbers of the tests you wish to run.\n");
- printf("Options:\n");
- printf(" -d Dump core after any failure, for debugging.\n");
- printf(" -k Keep all temp files.\n");
- printf(" Default: temp files for successful tests deleted.\n");
-#ifdef PROGRAM
- printf(" -p <path> Path to executable to be tested.\n");
- printf(" Default: path taken from " ENVBASE " environment variable.\n");
-#endif
- printf(" -q Quiet.\n");
- printf(" -r <dir> Path to dir containing reference files.\n");
- printf(" Default: Current directory.\n");
- printf(" -v Verbose.\n");
- printf("Available tests:\n");
- for (i = 0; i < limit; i++)
- printf(" %d: %s\n", i, tests[i].name);
- exit(1);
-}
-
-static char *
-get_refdir(const char *d)
-{
- char tried[512] = { '\0' };
- char buff[128];
- char *pwd, *p;
-
- /* If a dir was specified, try that */
- if (d != NULL) {
- pwd = NULL;
- snprintf(buff, sizeof(buff), "%s", d);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
- goto failure;
- }
-
- /* Get the current dir. */
- pwd = getcwd(NULL, 0);
- while (pwd[strlen(pwd) - 1] == '\n')
- pwd[strlen(pwd) - 1] = '\0';
-
- /* Look for a known file. */
- snprintf(buff, sizeof(buff), "%s", pwd);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
-
- snprintf(buff, sizeof(buff), "%s/test", pwd);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
-
-#if defined(LIBRARY)
- snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
-#else
- snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
-#endif
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
-
- if (memcmp(pwd, "/usr/obj", 8) == 0) {
- snprintf(buff, sizeof(buff), "%s", pwd + 8);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
-
- snprintf(buff, sizeof(buff), "%s/test", pwd + 8);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
- strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
- }
-
-failure:
- printf("Unable to locate known reference file %s\n", KNOWNREF);
- printf(" Checked following directories:\n%s\n", tried);
-#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
- DebugBreak();
-#endif
- exit(1);
-
-success:
- free(p);
- free(pwd);
- return strdup(buff);
-}
-
-int
-main(int argc, char **argv)
-{
- static const int limit = sizeof(tests) / sizeof(tests[0]);
- int i, tests_run = 0, tests_failed = 0, option;
- time_t now;
- char *refdir_alloc = NULL;
- const char *progname;
- const char *tmp, *option_arg, *p;
- char tmpdir[256];
- char tmpdir_timestamp[256];
-
- (void)argc; /* UNUSED */
-
-#if defined(HAVE__CrtSetReportMode)
- /* To stop to run the default invalid parameter handler. */
- _set_invalid_parameter_handler(invalid_parameter_handler);
- /* Disable annoying assertion message box. */
- _CrtSetReportMode(_CRT_ASSERT, 0);
-#endif
-
- /*
- * Name of this program, used to build root of our temp directory
- * tree.
- */
- progname = p = argv[0];
- while (*p != '\0') {
- /* Support \ or / dir separators for Windows compat. */
- if (*p == '/' || *p == '\\')
- progname = p + 1;
- ++p;
- }
-
-#ifdef PROGRAM
- /* Get the target program from environment, if available. */
- testprogfile = getenv(ENVBASE);
-#endif
-
- if (getenv("TMPDIR") != NULL)
- tmp = getenv("TMPDIR");
- else if (getenv("TMP") != NULL)
- tmp = getenv("TMP");
- else if (getenv("TEMP") != NULL)
- tmp = getenv("TEMP");
- else if (getenv("TEMPDIR") != NULL)
- tmp = getenv("TEMPDIR");
- else
- tmp = "/tmp";
-
- /* Allow -d to be controlled through the environment. */
- if (getenv(ENVBASE "_DEBUG") != NULL)
- dump_on_failure = 1;
-
- /* Get the directory holding test files from environment. */
- refdir = getenv(ENVBASE "_TEST_FILES");
-
- /*
- * Parse options, without using getopt(), which isn't available
- * on all platforms.
- */
- ++argv; /* Skip program name */
- while (*argv != NULL) {
- if (**argv != '-')
- break;
- p = *argv++;
- ++p; /* Skip '-' */
- while (*p != '\0') {
- option = *p++;
- option_arg = NULL;
- /* If 'opt' takes an argument, parse that. */
- if (option == 'p' || option == 'r') {
- if (*p != '\0')
- option_arg = p;
- else if (*argv == NULL) {
- fprintf(stderr,
- "Option -%c requires argument.\n",
- option);
- usage(progname);
- } else
- option_arg = *argv++;
- p = ""; /* End of this option word. */
- }
-
- /* Now, handle the option. */
- switch (option) {
- case 'd':
- dump_on_failure = 1;
- break;
- case 'k':
- keep_temp_files = 1;
- break;
- case 'p':
-#ifdef PROGRAM
- testprogfile = option_arg;
-#else
- fprintf(stderr, "-p option not permitted\n");
- usage(progname);
-#endif
- break;
- case 'q':
- verbosity--;
- break;
- case 'r':
- refdir = option_arg;
- break;
- case 'v':
- verbosity++;
- break;
- default:
- fprintf(stderr, "Unrecognized option '%c'\n",
- option);
- usage(progname);
- }
- }
- }
-
- /*
- * Sanity-check that our options make sense.
- */
-#ifdef PROGRAM
- if (testprogfile == NULL) {
- fprintf(stderr, "Program executable required\n");
- usage(progname);
- }
-
- {
- char *testprg;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Command.com sometimes rejects '/' separators. */
- testprg = strdup(testprogfile);
- for (i = 0; testprg[i] != '\0'; i++) {
- if (testprg[i] == '/')
- testprg[i] = '\\';
- }
- testprogfile = testprg;
-#endif
- /* Quote the name that gets put into shell command lines. */
- testprg = malloc(strlen(testprogfile) + 3);
- strcpy(testprg, "\"");
- strcat(testprg, testprogfile);
- strcat(testprg, "\"");
- testprog = testprg;
- }
-#endif
-
- /*
- * Create a temp directory for the following tests.
- * Include the time the tests started as part of the name,
- * to make it easier to track the results of multiple tests.
- */
- now = time(NULL);
- for (i = 0; ; i++) {
- strftime(tmpdir_timestamp, sizeof(tmpdir_timestamp),
- "%Y-%m-%dT%H.%M.%S",
- localtime(&now));
- sprintf(tmpdir, "%s/%s.%s-%03d", tmp, progname,
- tmpdir_timestamp, i);
- if (assertMakeDir(tmpdir,0755))
- break;
- if (i >= 999) {
- fprintf(stderr,
- "ERROR: Unable to create temp directory %s\n",
- tmpdir);
- exit(1);
- }
- }
-
- /*
- * If the user didn't specify a directory for locating
- * reference files, try to find the reference files in
- * the "usual places."
- */
- refdir = refdir_alloc = get_refdir(refdir);
-
- /*
- * Banner with basic information.
- */
- printf("\n");
- printf("If tests fail or crash, details will be in:\n");
- printf(" %s\n", tmpdir);
- printf("\n");
- if (verbosity > VERBOSITY_SUMMARY_ONLY) {
- printf("Reference files will be read from: %s\n", refdir);
-#ifdef PROGRAM
- printf("Running tests on: %s\n", testprog);
-#endif
- printf("Exercising: ");
- fflush(stdout);
- printf("%s\n", EXTRA_VERSION);
- } else {
- printf("Running ");
- fflush(stdout);
- }
-
- /*
- * Run some or all of the individual tests.
- */
- if (*argv == NULL) {
- /* Default: Run all tests. */
- for (i = 0; i < limit; i++) {
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
- }
- } else {
- while (*(argv) != NULL) {
- if (**argv >= '0' && **argv <= '9') {
- i = atoi(*argv);
- if (i < 0 || i >= limit) {
- printf("*** INVALID Test %s\n", *argv);
- free(refdir_alloc);
- usage(progname);
- /* usage() never returns */
- }
- } else {
- for (i = 0; i < limit; ++i) {
- if (strcmp(*argv, tests[i].name) == 0)
- break;
- }
- if (i >= limit) {
- printf("*** INVALID Test ``%s''\n",
- *argv);
- free(refdir_alloc);
- usage(progname);
- /* usage() never returns */
- }
- }
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
- argv++;
- }
- }
-
- /*
- * Report summary statistics.
- */
- if (verbosity > VERBOSITY_SUMMARY_ONLY) {
- printf("\n");
- printf("Totals:\n");
- printf(" Tests run: %8d\n", tests_run);
- printf(" Tests failed: %8d\n", tests_failed);
- printf(" Assertions checked:%8d\n", assertions);
- printf(" Assertions failed: %8d\n", failures);
- printf(" Skips reported: %8d\n", skips);
- }
- if (failures) {
- printf("\n");
- printf("Failing tests:\n");
- for (i = 0; i < limit; ++i) {
- if (tests[i].failures)
- printf(" %d: %s (%d failures)\n", i,
- tests[i].name, tests[i].failures);
- }
- printf("\n");
- printf("Details for failing tests: %s\n", tmpdir);
- printf("\n");
- } else {
- if (verbosity == VERBOSITY_SUMMARY_ONLY)
- printf("\n");
- printf("%d tests passed, no failures\n", tests_run);
- }
-
- free(refdir_alloc);
-
- /* If the final tmpdir is empty, we can remove it. */
- /* This should be the usual case when all tests succeed. */
- assertChdir("..");
- rmdir(tmpdir);
-
- return (tests_failed ? 1 : 0);
-}
diff --git a/usr.bin/tar/test/test.h b/usr.bin/tar/test/test.h
deleted file mode 100644
index a4a24617a145..000000000000
--- a/usr.bin/tar/test/test.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 2003-2006 Tim Kientzle
- * 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.
- *
- * $FreeBSD$
- */
-
-/* Every test program should #include "test.h" as the first thing. */
-
-/*
- * The goal of this file (and the matching test.c) is to
- * simplify the very repetitive test-*.c test programs.
- */
-#if defined(HAVE_CONFIG_H)
-/* Most POSIX platforms use the 'configure' script to build config.h */
-#include "config.h"
-#elif defined(__FreeBSD__)
-/* Building as part of FreeBSD system requires a pre-built config.h. */
-#include "config_freebsd.h"
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-/* Win32 can't run the 'configure' script. */
-#include "config_windows.h"
-#else
-/* Warn if the library hasn't been (automatically or manually) configured. */
-#error Oops: No config.h and no pre-built configuration in test.h.
-#endif
-
-#include <sys/types.h> /* Windows requires this before sys/stat.h */
-#include <sys/stat.h>
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#endif
-#if HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#define dirent direct
-#endif
-#include <errno.h>
-#include <fcntl.h>
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <wchar.h>
-#ifdef HAVE_WINDOWS_H
-#include <windows.h>
-#endif
-
-/*
- * System-specific tweaks. We really want to minimize these
- * as much as possible, since they make it harder to understand
- * the mainline code.
- */
-
-/* Windows (including Visual Studio and MinGW but not Cygwin) */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include "../bsdtar_windows.h"
-#if !defined(__BORLANDC__)
-#define strdup _strdup
-#endif
-#define LOCALE_DE "deu"
-#else
-#define LOCALE_DE "de_DE.UTF-8"
-#endif
-
-/* Visual Studio */
-#ifdef _MSC_VER
-#define snprintf sprintf_s
-#endif
-
-/* Cygwin */
-#if defined(__CYGWIN__)
-/* Cygwin-1.7.x is lazy about populating nlinks, so don't
- * expect it to be accurate. */
-# define NLINKS_INACCURATE_FOR_DIRS
-#endif
-
-#if defined(__HAIKU__) || defined(__QNXNTO__)
-/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
-#include <stdint.h>
-#endif
-
-/* Get a real definition for __FBSDID if we can */
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
-/* If not, define it so as to avoid dangling semicolons. */
-#ifndef __FBSDID
-#define __FBSDID(a) struct _undefined_hack
-#endif
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-/*
- * Redefine DEFINE_TEST for use in defining the test functions.
- */
-#undef DEFINE_TEST
-#define DEFINE_TEST(name) void name(void); void name(void)
-
-/* An implementation of the standard assert() macro */
-#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
-/* chdir() and error if it fails */
-#define assertChdir(path) \
- assertion_chdir(__FILE__, __LINE__, path)
-/* Assert two integers are the same. Reports value of each one if not. */
-#define assertEqualInt(v1,v2) \
- assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-/* Assert two strings are the same. Reports value of each one if not. */
-#define assertEqualString(v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-/* As above, but v1 and v2 are wchar_t * */
-#define assertEqualWString(v1,v2) \
- assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-/* As above, but raw blocks of bytes. */
-#define assertEqualMem(v1, v2, l) \
- assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
-/* Assert two files are the same; allow printf-style expansion of second name.
- * See below for comments about variable arguments here...
- */
-#define assertEqualFile \
- assertion_setup(__FILE__, __LINE__);assertion_equal_file
-/* Assert that a file is empty; supports printf-style arguments. */
-#define assertEmptyFile \
- assertion_setup(__FILE__, __LINE__);assertion_empty_file
-/* Assert that a file is not empty; supports printf-style arguments. */
-#define assertNonEmptyFile \
- assertion_setup(__FILE__, __LINE__);assertion_non_empty_file
-#define assertFileAtime(pathname, sec, nsec) \
- assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
-#define assertFileAtimeRecent(pathname) \
- assertion_file_atime_recent(__FILE__, __LINE__, pathname)
-#define assertFileBirthtime(pathname, sec, nsec) \
- assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
-#define assertFileBirthtimeRecent(pathname) \
- assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
-/* Assert that a file exists; supports printf-style arguments. */
-#define assertFileExists \
- assertion_setup(__FILE__, __LINE__);assertion_file_exists
-/* Assert that a file exists; supports printf-style arguments. */
-#define assertFileNotExists \
- assertion_setup(__FILE__, __LINE__);assertion_file_not_exists
-/* Assert that file contents match a string; supports printf-style arguments. */
-#define assertFileContents \
- assertion_setup(__FILE__, __LINE__);assertion_file_contents
-#define assertFileMtime(pathname, sec, nsec) \
- assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
-#define assertFileMtimeRecent(pathname) \
- assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
-#define assertFileNLinks(pathname, nlinks) \
- assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
-#define assertFileSize(pathname, size) \
- assertion_file_size(__FILE__, __LINE__, pathname, size)
-#define assertTextFileContents \
- assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
-#define assertFileContainsLinesAnyOrder(pathname, lines) \
- assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
-#define assertIsDir(pathname, mode) \
- assertion_is_dir(__FILE__, __LINE__, pathname, mode)
-#define assertIsHardlink(path1, path2) \
- assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
-#define assertIsNotHardlink(path1, path2) \
- assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
-#define assertIsReg(pathname, mode) \
- assertion_is_reg(__FILE__, __LINE__, pathname, mode)
-#define assertIsSymlink(pathname, contents) \
- assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
-/* Create a directory, report error if it fails. */
-#define assertMakeDir(dirname, mode) \
- assertion_make_dir(__FILE__, __LINE__, dirname, mode)
-#define assertMakeFile(path, mode, contents) \
- assertion_make_file(__FILE__, __LINE__, path, mode, contents)
-#define assertMakeHardlink(newfile, oldfile) \
- assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
-#define assertMakeSymlink(newfile, linkto) \
- assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
-#define assertUmask(mask) \
- assertion_umask(__FILE__, __LINE__, mask)
-
-/*
- * This would be simple with C99 variadic macros, but I don't want to
- * require that. Instead, I insert a function call before each
- * skipping() call to pass the file and line information down. Crude,
- * but effective.
- */
-#define skipping \
- assertion_setup(__FILE__, __LINE__);test_skipping
-
-/* Function declarations. These are defined in test_utility.c. */
-void failure(const char *fmt, ...);
-int assertion_assert(const char *, int, int, const char *, void *);
-int assertion_chdir(const char *, int, const char *);
-int assertion_empty_file(const char *, ...);
-int assertion_equal_file(const char *, const char *, ...);
-int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
-int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
-int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
-int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
-int assertion_file_atime(const char *, int, const char *, long, long);
-int assertion_file_atime_recent(const char *, int, const char *);
-int assertion_file_birthtime(const char *, int, const char *, long, long);
-int assertion_file_birthtime_recent(const char *, int, const char *);
-int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
-int assertion_file_contents(const void *, int, const char *, ...);
-int assertion_file_exists(const char *, ...);
-int assertion_file_mtime(const char *, int, const char *, long, long);
-int assertion_file_mtime_recent(const char *, int, const char *);
-int assertion_file_nlinks(const char *, int, const char *, int);
-int assertion_file_not_exists(const char *, ...);
-int assertion_file_size(const char *, int, const char *, long);
-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 *);
-int assertion_is_reg(const char *, int, const char *, int);
-int assertion_is_symlink(const char *, int, const char *, const char *);
-int assertion_make_dir(const char *, int, const char *, int);
-int assertion_make_file(const char *, int, const char *, int, const char *);
-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_non_empty_file(const char *, ...);
-int assertion_text_file_contents(const char *buff, const char *f);
-int assertion_umask(const char *, int, int);
-void assertion_setup(const char *, int);
-
-void test_skipping(const char *fmt, ...);
-
-/* Like sprintf, then system() */
-int systemf(const char * fmt, ...);
-
-/* Delay until time() returns a value after this. */
-void sleepUntilAfter(time_t);
-
-/* Return true if this platform can create symlinks. */
-int canSymlink(void);
-
-/* Return true if this platform can run the "gzip" program. */
-int canGzip(void);
-
-/* Return true if this platform can run the "gunzip" program. */
-int canGunzip(void);
-
-/* Suck file into string allocated via malloc(). Call free() when done. */
-/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
-char *slurpfile(size_t *, const char *fmt, ...);
-
-/* Extracts named reference file to the current directory. */
-void extract_reference_file(const char *);
-
-/*
- * Special interfaces for program test harness.
- */
-
-/* Pathname of exe to be tested. */
-const char *testprogfile;
-/* Name of exe to use in printf-formatted command strings. */
-/* On Windows, this includes leading/trailing quotes. */
-const char *testprog;
diff --git a/usr.bin/tar/test/test_0.c b/usr.bin/tar/test/test_0.c
deleted file mode 100644
index b97bd3712591..000000000000
--- a/usr.bin/tar/test/test_0.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * This first test does basic sanity checks on the environment. For
- * most of these, we just exit on failure.
- */
-#if !defined(_WIN32) || defined(__CYGWIN__)
-#define DEV_NULL "/dev/null"
-#else
-#define DEV_NULL "NUL"
-#endif
-
-DEFINE_TEST(test_0)
-{
- struct stat st;
-
- failure("File %s does not exist?!", testprog);
- if (!assertEqualInt(0, stat(testprogfile, &st)))
- exit(1);
-
- failure("%s is not executable?!", testprog);
- if (!assert((st.st_mode & 0111) != 0))
- exit(1);
-
- /*
- * Try to succesfully run the program; this requires that
- * we know some option that will succeed.
- */
- if (0 == systemf("%s --version >" DEV_NULL, testprog)) {
- /* This worked. */
- } else if (0 == systemf("%s -W version >" DEV_NULL, testprog)) {
- /* This worked. */
- } else {
- failure("Unable to successfully run any of the following:\n"
- " * %s --version\n"
- " * %s -W version\n",
- testprog, testprog);
- assert(0);
- }
-
- /* TODO: Ensure that our reference files are available. */
-}
diff --git a/usr.bin/tar/test/test_basic.c b/usr.bin/tar/test/test_basic.c
deleted file mode 100644
index 1fa334174145..000000000000
--- a/usr.bin/tar/test/test_basic.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-
-static void
-basic_tar(const char *target, const char *pack_options,
- const char *unpack_options, const char *flist)
-{
- int r;
-
- assertMakeDir(target, 0775);
-
- /* Use the tar program to create an archive. */
- r = systemf("%s cf - %s %s >%s/archive 2>%s/pack.err", testprog, pack_options, flist, target, target);
- failure("Error invoking %s cf -", testprog, pack_options);
- assertEqualInt(r, 0);
-
- assertChdir(target);
-
- /* Verify that nothing went to stderr. */
- assertEmptyFile("pack.err");
-
- /*
- * Use tar to unpack the archive into another directory.
- */
- r = systemf("%s xf archive %s >unpack.out 2>unpack.err", testprog, unpack_options);
- failure("Error invoking %s xf archive %s", testprog, unpack_options);
- assertEqualInt(r, 0);
-
- /* Verify that nothing went to stderr. */
- assertEmptyFile("unpack.err");
-
- /*
- * Verify unpacked files.
- */
-
- /* Regular file with 2 links. */
- assertIsReg("file", -1);
- assertFileSize("file", 10);
- failure("%s", target);
- assertFileNLinks("file", 2);
-
- /* Another name for the same file. */
- assertIsReg("linkfile", -1);
- assertFileSize("linkfile", 10);
- assertFileNLinks("linkfile", 2);
- assertIsHardlink("file", "linkfile");
-
- /* Symlink */
- if (canSymlink())
- assertIsSymlink("symlink", "file");
-
- /* dir */
- assertIsDir("dir", 0775);
- assertChdir("..");
-}
-
-DEFINE_TEST(test_basic)
-{
- FILE *f;
- const char *flist;
-
- assertUmask(0);
-
- /* File with 10 bytes content. */
- f = fopen("file", "wb");
- assert(f != NULL);
- assertEqualInt(10, fwrite("123456789", 1, 10, f));
- fclose(f);
-
- /* hardlink to above file. */
- assertMakeHardlink("linkfile", "file");
- assertIsHardlink("file", "linkfile");
-
- /* Symlink to above file. */
- if (canSymlink())
- assertMakeSymlink("symlink", "file");
-
- /* Directory. */
- assertMakeDir("dir", 0775);
-
- if (canSymlink())
- flist = "file linkfile symlink dir";
- else
- flist = "file linkfile dir";
- /* Archive/dearchive with a variety of options. */
- basic_tar("copy", "", "", flist);
- /* tar doesn't handle cpio symlinks correctly */
- /* basic_tar("copy_odc", "--format=odc", ""); */
- basic_tar("copy_ustar", "--format=ustar", "", flist);
-}
diff --git a/usr.bin/tar/test/test_copy.c b/usr.bin/tar/test/test_copy.c
deleted file mode 100644
index 5a1c4d075e43..000000000000
--- a/usr.bin/tar/test/test_copy.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-#if defined(__CYGWIN__)
-# include <limits.h>
-# include <sys/cygwin.h>
-#endif
-
-/*
- * Try to figure out how deep we can go in our tests. Assumes that
- * the first call to this function has the longest starting cwd (which
- * is currently "<testdir>/original"). This is mostly to work around
- * limits in our Win32 support.
- *
- * Background: On Posix systems, PATH_MAX is merely a limit on the
- * length of the string passed into a system call. By repeatedly
- * calling chdir(), you can work with arbitrarily long paths on such
- * systems. In contrast, Win32 APIs apply PATH_MAX limits to the full
- * absolute path, so the permissible length of a system call argument
- * varies with the cwd. Some APIs actually enforce limits
- * significantly less than PATH_MAX to ensure that you can create
- * files within the current working directory. The Win32 limits also
- * apply to Cygwin before 1.7.
- *
- * Someday, I want to convert the Win32 support to use newer
- * wide-character paths with '\\?\' prefix, which has a 32k PATH_MAX
- * instead of the rather anemic 260 character limit of the older
- * system calls. Then we can drop this mess (unless we want to
- * continue to special-case Cygwin 1.5 and earlier).
- */
-static int
-compute_loop_max(void)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- static int LOOP_MAX = 0;
- char buf[MAX_PATH];
- size_t cwdlen;
-
- if (LOOP_MAX == 0) {
- assert(_getcwd(buf, MAX_PATH) != NULL);
- cwdlen = strlen(buf);
- /* 12 characters = length of 8.3 filename */
- /* 4 characters = length of "/../" used in symlink tests */
- /* 1 character = length of extra "/" separator */
- LOOP_MAX = MAX_PATH - (int)cwdlen - 12 - 4 - 1;
- }
- return LOOP_MAX;
-#elif defined(__CYGWIN__) && !defined(HAVE_CYGWIN_CONV_PATH)
- static int LOOP_MAX = 0;
- if (LOOP_MAX == 0) {
- char wbuf[PATH_MAX];
- char pbuf[PATH_MAX];
- size_t wcwdlen;
- size_t pcwdlen;
- size_t cwdlen;
- assert(getcwd(pbuf, PATH_MAX) != NULL);
- pcwdlen = strlen(pbuf);
- cygwin_conv_to_full_win32_path(pbuf, wbuf);
- wcwdlen = strlen(wbuf);
- cwdlen = ((wcwdlen > pcwdlen) ? wcwdlen : pcwdlen);
- /* Cygwin helper needs an extra few characters. */
- LOOP_MAX = PATH_MAX - (int)cwdlen - 12 - 4 - 4;
- }
- return LOOP_MAX;
-#else
- /* cygwin-1.7 ends up here, along with "normal" unix */
- return 200; /* restore pre-r278 depth */
-#endif
-}
-
-/* filenames[i] is a distinctive filename of length i. */
-/* To simplify interpreting failures, each filename ends with a
- * decimal integer which is the length of the filename. E.g., A
- * filename ending in "_92" is 92 characters long. To detect errors
- * which drop or misplace characters, the filenames use a repeating
- * "abcdefghijklmnopqrstuvwxyz..." pattern. */
-static char *filenames[201];
-
-static void
-compute_filenames(void)
-{
- char buff[250];
- size_t i,j;
-
- filenames[0] = strdup("");
- filenames[1] = strdup("1");
- filenames[2] = strdup("a2");
- for (i = 3; i < sizeof(filenames)/sizeof(filenames[0]); ++i) {
- /* Fill with "abcdefghij..." */
- for (j = 0; j < i; ++j)
- buff[j] = 'a' + (j % 26);
- buff[j--] = '\0';
- /* Work from the end to fill in the number portion. */
- buff[j--] = '0' + (i % 10);
- if (i > 9) {
- buff[j--] = '0' + ((i / 10) % 10);
- if (i > 99)
- buff[j--] = '0' + (i / 100);
- }
- buff[j] = '_';
- /* Guard against obvious screwups in the above code. */
- assertEqualInt(strlen(buff), i);
- filenames[i] = strdup(buff);
- }
-}
-
-static void
-create_tree(void)
-{
- char buff[260];
- char buff2[260];
- int i;
- int LOOP_MAX;
-
- compute_filenames();
-
- /* Log that we'll be omitting some checks. */
- if (!canSymlink()) {
- skipping("Symlink checks");
- }
-
- assertMakeDir("original", 0775);
- assertEqualInt(0, chdir("original"));
- LOOP_MAX = compute_loop_max();
-
- assertMakeDir("f", 0775);
- assertMakeDir("l", 0775);
- assertMakeDir("m", 0775);
- assertMakeDir("s", 0775);
- assertMakeDir("d", 0775);
-
- for (i = 1; i < LOOP_MAX; i++) {
- failure("Internal sanity check failed: i = %d", i);
- assert(filenames[i] != NULL);
-
- sprintf(buff, "f/%s", filenames[i]);
- assertMakeFile(buff, 0777, buff);
-
- /* Create a link named "l/abcdef..." to the above. */
- sprintf(buff2, "l/%s", filenames[i]);
- assertMakeHardlink(buff2, buff);
-
- /* Create a link named "m/abcdef..." to the above. */
- sprintf(buff2, "m/%s", filenames[i]);
- assertMakeHardlink(buff2, buff);
-
- if (canSymlink()) {
- /* Create a symlink named "s/abcdef..." to the above. */
- sprintf(buff, "s/%s", filenames[i]);
- sprintf(buff2, "../f/%s", filenames[i]);
- failure("buff=\"%s\" buff2=\"%s\"", buff, buff2);
- assertMakeSymlink(buff, buff2);
- }
- /* Create a dir named "d/abcdef...". */
- buff[0] = 'd';
- failure("buff=\"%s\"", buff);
- assertMakeDir(buff, 0775);
- }
-
- assertEqualInt(0, chdir(".."));
-}
-
-#define LIMIT_NONE 200
-#define LIMIT_USTAR 100
-
-static void
-verify_tree(size_t limit)
-{
- char name1[260];
- char name2[260];
- size_t i, LOOP_MAX;
-
- LOOP_MAX = compute_loop_max();
-
- /* Generate the names we know should be there and verify them. */
- for (i = 1; i < LOOP_MAX; i++) {
- /* Verify a file named "f/abcdef..." */
- sprintf(name1, "f/%s", filenames[i]);
- if (i <= limit) {
- assertFileExists(name1);
- assertFileContents(name1, strlen(name1), name1);
- }
-
- sprintf(name2, "l/%s", filenames[i]);
- if (i + 2 <= limit) {
- /* Verify hardlink "l/abcdef..." */
- assertIsHardlink(name1, name2);
- /* Verify hardlink "m/abcdef..." */
- name2[0] = 'm';
- assertIsHardlink(name1, name2);
- }
-
- if (canSymlink()) {
- /* Verify symlink "s/abcdef..." */
- sprintf(name1, "s/%s", filenames[i]);
- sprintf(name2, "../f/%s", filenames[i]);
- if (strlen(name2) <= limit)
- assertIsSymlink(name1, name2);
- }
-
- /* Verify dir "d/abcdef...". */
- sprintf(name1, "d/%s", filenames[i]);
- if (i + 1 <= limit) { /* +1 for trailing slash */
- if (assertIsDir(name1, -1)) {
- /* TODO: opendir/readdir this
- * directory and make sure
- * it's empty.
- */
- }
- }
- }
-
-#if !defined(_WIN32) || defined(__CYGWIN__)
- {
- const char *dp;
- /* Now make sure nothing is there that shouldn't be. */
- for (dp = "dflms"; *dp != '\0'; ++dp) {
- DIR *d;
- struct dirent *de;
- char dir[2];
- dir[0] = *dp; dir[1] = '\0';
- d = opendir(dir);
- failure("Unable to open dir '%s'", dir);
- if (!assert(d != NULL))
- continue;
- while ((de = readdir(d)) != NULL) {
- char *p = de->d_name;
- if (p[0] == '.')
- continue;
- switch(dp[0]) {
- case 'l': case 'm': case 'd':
- failure("strlen(p)=%d", strlen(p));
- assert(strlen(p) < limit);
- assertEqualString(p,
- filenames[strlen(p)]);
- break;
- case 'f': case 's':
- failure("strlen(p)=%d", strlen(p));
- assert(strlen(p) < limit + 1);
- assertEqualString(p,
- filenames[strlen(p)]);
- break;
- default:
- failure("File %s shouldn't be here", p);
- assert(0);
- }
- }
- closedir(d);
- }
- }
-#endif
-}
-
-static void
-copy_basic(void)
-{
- int r;
-
- /* NOTE: for proper operation on cygwin-1.5 and windows, the
- * length of the name of the directory below, "plain", must be
- * less than or equal to the lengthe of the name of the original
- * directory, "original" This restriction derives from the
- * extremely limited pathname lengths on those platforms.
- */
- assertMakeDir("plain", 0775);
- assertEqualInt(0, chdir("plain"));
-
- /*
- * Use the tar program to create an archive.
- */
- r = systemf("%s cf archive -C ../original f d l m s >pack.out 2>pack.err",
- testprog);
- failure("Error invoking \"%s cf\"", testprog);
- assertEqualInt(r, 0);
-
- /* Verify that nothing went to stdout or stderr. */
- assertEmptyFile("pack.err");
- assertEmptyFile("pack.out");
-
- /*
- * Use tar to unpack the archive into another directory.
- */
- r = systemf("%s xf archive >unpack.out 2>unpack.err", testprog);
- failure("Error invoking %s xf archive", testprog);
- assertEqualInt(r, 0);
-
- /* Verify that nothing went to stdout or stderr. */
- assertEmptyFile("unpack.err");
- assertEmptyFile("unpack.out");
-
- verify_tree(LIMIT_NONE);
- assertEqualInt(0, chdir(".."));
-}
-
-static void
-copy_ustar(void)
-{
- const char *target = "ustar";
- int r;
-
- /* NOTE: for proper operation on cygwin-1.5 and windows, the
- * length of the name of the directory below, "ustar", must be
- * less than or equal to the lengthe of the name of the original
- * directory, "original" This restriction derives from the
- * extremely limited pathname lengths on those platforms.
- */
- assertMakeDir(target, 0775);
- assertEqualInt(0, chdir(target));
-
- /*
- * Use the tar program to create an archive.
- */
- r = systemf("%s cf archive --format=ustar -C ../original f d l m s >pack.out 2>pack.err",
- testprog);
- failure("Error invoking \"%s cf archive --format=ustar\"", testprog);
- assertEqualInt(r, 0);
-
- /* Verify that nothing went to stdout. */
- assertEmptyFile("pack.out");
- /* Stderr is non-empty, since there are a bunch of files
- * with filenames too long to archive. */
-
- /*
- * Use tar to unpack the archive into another directory.
- */
- r = systemf("%s xf archive >unpack.out 2>unpack.err", testprog);
- failure("Error invoking %s xf archive", testprog);
- assertEqualInt(r, 0);
-
- /* Verify that nothing went to stdout or stderr. */
- assertEmptyFile("unpack.err");
- assertEmptyFile("unpack.out");
-
- verify_tree(LIMIT_USTAR);
- assertEqualInt(0, chdir("../.."));
-}
-
-DEFINE_TEST(test_copy)
-{
- assertUmask(0);
- create_tree(); /* Create sample files in "original" dir. */
-
- /* Test simple "tar -c | tar -x" pipeline copy. */
- copy_basic();
-
- /* Same, but constrain to ustar format. */
- copy_ustar();
-}
diff --git a/usr.bin/tar/test/test_empty_mtree.c b/usr.bin/tar/test/test_empty_mtree.c
deleted file mode 100644
index 6f8a5e91aa1a..000000000000
--- a/usr.bin/tar/test/test_empty_mtree.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * 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$");
-
-/*
- * Regression test: We used to get a bogus error message when we
- * asked tar to copy entries out of an empty archive. See
- * Issue 51 on libarchive.googlecode.com for details.
- */
-DEFINE_TEST(test_empty_mtree)
-{
- int r;
-
- assertMakeFile("test1.mtree", 0777, "#mtree\n");
-
- r = systemf("%s cf test1.tar @test1.mtree >test1.out 2>test1.err",
- testprog);
- failure("Error invoking %s cf", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("test1.out");
- assertEmptyFile("test1.err");
-}
diff --git a/usr.bin/tar/test/test_getdate.c b/usr.bin/tar/test/test_getdate.c
deleted file mode 100644
index cd6d55a93e6a..000000000000
--- a/usr.bin/tar/test/test_getdate.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-#include <time.h>
-
-/*
- * Verify that the getdate() function works.
- */
-
-time_t get_date(time_t, const char *);
-
-DEFINE_TEST(test_getdate)
-{
- time_t now = time(NULL);
-
- assertEqualInt(get_date(now, "Jan 1, 1970 UTC"), 0);
- assertEqualInt(get_date(now, "7:12:18-0530 4 May 1983"), 420900138);
- assertEqualInt(get_date(now, "2004/01/29 513 mest"), 1075345980);
- assertEqualInt(get_date(now, "99/02/17 7pm utc"), 919278000);
- assertEqualInt(get_date(now, "02/17/99 7:11am est"), 919253460);
- /* It's important that we handle ctime() format. */
- assertEqualInt(get_date(now, "Sun Feb 22 17:38:26 PST 2009"),
- 1235353106);
- /* Basic relative offsets. */
- /* If we use the actual current time as the reference, then
- * these tests break around DST changes, so it's actually
- * important to use a specific reference time here. */
- assertEqualInt(get_date(0, "tomorrow"), 24 * 60 * 60);
- assertEqualInt(get_date(0, "yesterday"), - 24 * 60 * 60);
- assertEqualInt(get_date(0, "now + 1 hour"), 60 * 60);
- assertEqualInt(get_date(0, "now + 1 hour + 1 minute"), 60 * 60 + 60);
- /* Repeat the above for a different start time. */
- now = 1231113600; /* Jan 5, 2009 00:00 UTC */
- assertEqualInt(get_date(0, "Jan 5, 2009 00:00 UTC"), now);
- assertEqualInt(get_date(now, "tomorrow"), now + 24 * 60 * 60);
- assertEqualInt(get_date(now, "yesterday"), now - 24 * 60 * 60);
- assertEqualInt(get_date(now, "now + 1 hour"), now + 60 * 60);
- assertEqualInt(get_date(now, "now + 1 hour + 1 minute"),
- now + 60 * 60 + 60);
- assertEqualInt(get_date(now, "tomorrow 5:16am UTC"),
- now + 24 * 60 * 60 + 5 * 60 * 60 + 16 * 60);
- assertEqualInt(get_date(now, "UTC 5:16am tomorrow"),
- now + 24 * 60 * 60 + 5 * 60 * 60 + 16 * 60);
-
- /* Jan 5, 2009 was a Monday. */
- assertEqualInt(get_date(now, "monday UTC"), now);
- assertEqualInt(get_date(now, "sunday UTC"), now + 6 * 24 * 60 * 60);
- assertEqualInt(get_date(now, "tuesday UTC"), now + 24 * 60 * 60);
- /* "next tuesday" is one week after "tuesday" */
- assertEqualInt(get_date(now, "UTC next tuesday"),
- now + 8 * 24 * 60 * 60);
- /* "last tuesday" is one week before "tuesday" */
- assertEqualInt(get_date(now, "last tuesday UTC"),
- now - 6 * 24 * 60 * 60);
- /* TODO: Lots more tests here. */
-}
diff --git a/usr.bin/tar/test/test_help.c b/usr.bin/tar/test/test_help.c
deleted file mode 100644
index 0e7d1c97ea62..000000000000
--- a/usr.bin/tar/test/test_help.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * Test that "--help", "-h", and "-W help" options all work and
- * generate reasonable output.
- */
-
-static int
-in_first_line(const char *p, const char *substring)
-{
- size_t l = strlen(substring);
-
- while (*p != '\0' && *p != '\n') {
- if (memcmp(p, substring, l) == 0)
- return (1);
- ++p;
- }
- return (0);
-}
-
-DEFINE_TEST(test_help)
-{
- int r;
- char *p;
- size_t plen;
-
- /* Exercise --help option. */
- r = systemf("%s --help >help.stdout 2>help.stderr", testprog);
- assertEqualInt(r, 0);
- failure("--help should generate nothing to stderr.");
- assertEmptyFile("help.stderr");
- /* Help message should start with name of program. */
- p = slurpfile(&plen, "help.stdout");
- failure("Help output should be long enough.");
- assert(plen >= 6);
- failure("First line of help output should contain 'bsdtar': %s", p);
- assert(in_first_line(p, "bsdtar"));
- /*
- * TODO: Extend this check to further verify that --help output
- * looks approximately right.
- */
- free(p);
-
- /* -h option should generate the same output. */
- r = systemf("%s -h >h.stdout 2>h.stderr", testprog);
- assertEqualInt(r, 0);
- failure("-h should generate nothing to stderr.");
- assertEmptyFile("h.stderr");
- failure("stdout should be same for -h and --help");
- assertEqualFile("h.stdout", "help.stdout");
-
- /* -W help should be another synonym. */
- r = systemf("%s -W help >Whelp.stdout 2>Whelp.stderr", testprog);
- assertEqualInt(r, 0);
- failure("-W help should generate nothing to stderr.");
- assertEmptyFile("Whelp.stderr");
- failure("stdout should be same for -W help and --help");
- assertEqualFile("Whelp.stdout", "help.stdout");
-}
diff --git a/usr.bin/tar/test/test_option_T_upper.c b/usr.bin/tar/test/test_option_T_upper.c
deleted file mode 100644
index 87127ccb9373..000000000000
--- a/usr.bin/tar/test/test_option_T_upper.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*-
- * Copyright (c) 2003-2008 Tim Kientzle
- * 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$");
-
-static int
-touch(const char *fn, int fail)
-{
- FILE *f = fopen(fn, "w");
- if (fail) {
- failure("Couldn't create file '%s', errno=%d (%s)\n",
- fn, errno, strerror(errno));
- if (!assert(f != NULL))
- return (0); /* Failure. */
- } else {
- if (f == NULL)
- return (0); /* Soft failure. */
- }
- fclose(f);
- return (1); /* Success */
-}
-
-DEFINE_TEST(test_option_T_upper)
-{
- FILE *f;
- int r;
- struct stat st;
- int gnarlyFilesSupported;
-
- /* Create a simple dir heirarchy; bail if anything fails. */
- if (!assertMakeDir("d1", 0755)) return;
- if (!assertMakeDir("d1/d2", 0755)) return;
- if (!touch("f", 1)) return;
- if (!touch("d1/f1", 1)) return;
- if (!touch("d1/f2", 1)) return;
- if (!touch("d1/d2/f3", 1)) return;
- if (!touch("d1/d2/f4", 1)) return;
- if (!touch("d1/d2/f5", 1)) return;
- if (!touch("d1/d2/f6", 1)) return;
- /* Some platforms don't permit such things; just skip it. */
- gnarlyFilesSupported = touch("d1/d2/f\x0a", 0);
-
- /* Populate a file list */
- f = fopen("filelist", "w+");
- if (!assert(f != NULL))
- return;
- /* Use a variety of text line endings. */
- fprintf(f, "f\x0d"); /* CR */
- fprintf(f, "d1/f1\x0d\x0a"); /* CRLF */
- fprintf(f, "d1/d2/f4\x0a"); /* NL */
- fprintf(f, "d1/d2/f6"); /* EOF */
- fclose(f);
-
- /* Populate a second file list */
- f = fopen("filelist2", "w+");
- if (!assert(f != NULL))
- return;
- /* Use null-terminated names. */
- fprintf(f, "d1/d2/f3");
- fwrite("\0", 1, 1, f);
- fprintf(f, "d1/d2/f5");
- fwrite("\0", 1, 1, f);
- if (gnarlyFilesSupported) {
- fprintf(f, "d1/d2/f\x0a");
- fwrite("\0", 1, 1, f);
- }
- fclose(f);
-
- /* Use -c -T to archive up the files. */
- r = systemf("%s -c -f test1.tar -T filelist > test1.out 2> test1.err",
- testprog);
- assert(r == 0);
- assertEmptyFile("test1.out");
- assertEmptyFile("test1.err");
-
- /* Use -x -T to dearchive the files */
- if (!assertMakeDir("test1", 0755)) return;
- systemf("%s -x -f test1.tar -T filelist -C test1"
- " > test1b.out 2> test1b.err", testprog);
- assertEmptyFile("test1b.out");
- assertEmptyFile("test1b.err");
-
- /* Verify the files were extracted. */
- assertFileExists("test1/f");
- assertFileExists("test1/d1/f1");
- assertFileNotExists("test1/d1/f2");
- assertFileNotExists("test1/d1/d2/f3");
- assertFileExists("test1/d1/d2/f4");
- assertFileNotExists("test1/d1/d2/f5");
- assertFileExists("test1/d1/d2/f6");
- if (gnarlyFilesSupported) {
- assertFileNotExists("test1/d1/d2/f\x0a");
- }
-
- /* Use -r -T to add more files to the archive. */
- systemf("%s -r -f test1.tar --null -T filelist2 > test2.out 2> test2.err",
- testprog);
- assertEmptyFile("test2.out");
- assertEmptyFile("test2.err");
-
- /* Use -x without -T to dearchive the files (ensure -r worked) */
- if (!assertMakeDir("test3", 0755)) return;
- systemf("%s -x -f test1.tar -C test3"
- " > test3.out 2> test3.err", testprog);
- assertEmptyFile("test3.out");
- assertEmptyFile("test3.err");
- /* Verify the files were extracted.*/
- assertFileExists("test3/f");
- assertFileExists("test3/d1/f1");
- assertFileNotExists("test3/d1/f2");
- assertFileExists("test3/d1/d2/f3");
- assertFileExists("test3/d1/d2/f4");
- assertFileExists("test3/d1/d2/f5");
- assertFileExists("test3/d1/d2/f6");
- if (gnarlyFilesSupported) {
- assertFileExists("test3/d1/d2/f\x0a");
- }
-
- /* Use -x -T to dearchive the files (verify -x -T together) */
- if (!assertMakeDir("test2", 0755)) return;
- systemf("%s -x -f test1.tar -T filelist -C test2"
- " > test2b.out 2> test2b.err", testprog);
- assertEmptyFile("test2b.out");
- assertEmptyFile("test2b.err");
- /* Verify the files were extracted.*/
- assertFileExists("test2/f");
- assertFileExists("test2/d1/f1");
- assertFileNotExists("test2/d1/f2");
- assertFileNotExists("test2/d1/d2/f3");
- assertFileExists("test2/d1/d2/f4");
- assertFileNotExists("test2/d1/d2/f5");
- assertFileExists("test2/d1/d2/f6");
- if (gnarlyFilesSupported) {
- assertFileNotExists("test2/d1/d2/f\x0a");
- }
-
- assertMakeDir("test4", 0755);
- assertMakeDir("test4_out", 0755);
- assertMakeDir("test4_out2", 0755);
- assertMakeDir("test4/d1", 0755);
- assertEqualInt(1, touch("test4/d1/foo", 0));
-
- /* Does bsdtar support -s option ? */
- systemf("%s -cf - -s /foo/bar/ test4/d1/foo > check.out 2> check.err",
- testprog);
- assertEqualInt(0, stat("check.err", &st));
- if (st.st_size == 0) {
- systemf("%s -cf - -s /foo/bar/ test4/d1/foo | %s -xf - -C test4_out",
- testprog, testprog);
- assertEmptyFile("test4_out/test4/d1/bar");
- systemf("%s -cf - -s /d1/d2/ test4/d1/foo | %s -xf - -C test4_out",
- testprog, testprog);
- assertEmptyFile("test4_out/test4/d2/foo");
- systemf("%s -cf - -s ,test4/d1/foo,, test4/d1/foo | %s -tvf - > test4.lst",
- testprog, testprog);
- assertEmptyFile("test4.lst");
- systemf("%s -cf - test4/d1/foo | %s -xf - -s /foo/bar/ -C test4_out2",
- testprog, testprog);
- assertEmptyFile("test4_out2/test4/d1/bar");
- } else {
- skipping("bsdtar does not support -s option on this platform");
- }
-
- /* TODO: Include some use of -C directory-changing within the filelist. */
- /* I'm pretty sure -C within the filelist is broken on extract. */
-}
diff --git a/usr.bin/tar/test/test_option_q.c b/usr.bin/tar/test/test_option_q.c
deleted file mode 100644
index c8e95400dfe4..000000000000
--- a/usr.bin/tar/test/test_option_q.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_q)
-{
- FILE *f;
- int r;
-
- /*
- * Create an archive with several different versions of the
- * same files. By default, the last version will overwrite
- * any earlier versions. The -q/--fast-read option will
- * stop early, so we can verify -q/--fast-read by seeing
- * which version of each file actually ended up being
- * extracted. This also exercises -r mode, since that's
- * what we use to build up the test archive.
- */
-
- f = fopen("foo", "w");
- assert(f != NULL);
- fprintf(f, "foo1");
- fclose(f);
-
- assertEqualInt(0, systemf("%s -cf archive.tar foo", testprog));
-
- f = fopen("foo", "w");
- assert(f != NULL);
- fprintf(f, "foo2");
- fclose(f);
-
- assertEqualInt(0, systemf("%s -rf archive.tar foo", testprog));
-
- f = fopen("bar", "w");
- assert(f != NULL);
- fprintf(f, "bar1");
- fclose(f);
-
- assertEqualInt(0, systemf("%s -rf archive.tar bar", testprog));
-
- f = fopen("foo", "w");
- assert(f != NULL);
- fprintf(f, "foo3");
- fclose(f);
-
- assertEqualInt(0, systemf("%s -rf archive.tar foo", testprog));
-
- f = fopen("bar", "w");
- assert(f != NULL);
- fprintf(f, "bar2");
- fclose(f);
-
- assertEqualInt(0, systemf("%s -rf archive.tar bar", testprog));
-
- /*
- * Now, try extracting from the test archive with various
- * combinations of -q.
- */
-
- /* Test 1: -q foo should only extract the first foo. */
- assertMakeDir("test1", 0755);
- assertChdir("test1");
- r = systemf("%s -xf ../archive.tar -q foo >test.out 2>test.err",
- testprog);
- failure("Fatal error trying to use -q option");
- if (!assertEqualInt(0, r))
- return;
-
- assertFileContents("foo1", 4, "foo");
- assertEmptyFile("test.out");
- assertEmptyFile("test.err");
- assertChdir("..");
-
- /* Test 2: -q foo bar should extract up to the first bar. */
- assertMakeDir("test2", 0755);
- assertChdir("test2");
- assertEqualInt(0,
- systemf("%s -xf ../archive.tar -q foo bar >test.out 2>test.err", testprog));
- assertFileContents("foo2", 4, "foo");
- assertFileContents("bar1", 4, "bar");
- assertEmptyFile("test.out");
- assertEmptyFile("test.err");
- assertChdir("..");
-
- /* Test 3: Same as test 2, but use --fast-read spelling. */
- assertMakeDir("test3", 0755);
- assertChdir("test3");
- assertEqualInt(0,
- systemf("%s -xf ../archive.tar --fast-read foo bar >test.out 2>test.err", testprog));
- assertFileContents("foo2", 4, "foo");
- assertFileContents("bar1", 4, "bar");
- assertEmptyFile("test.out");
- assertEmptyFile("test.err");
- assertChdir("..");
-
- /* Test 4: Without -q, should extract everything. */
- assertMakeDir("test4", 0755);
- assertChdir("test4");
- assertEqualInt(0,
- systemf("%s -xf ../archive.tar foo bar >test.out 2>test.err", testprog));
- assertFileContents("foo3", 4, "foo");
- assertFileContents("bar2", 4, "bar");
- assertEmptyFile("test.out");
- assertEmptyFile("test.err");
- assertChdir("..");
-}
diff --git a/usr.bin/tar/test/test_option_r.c b/usr.bin/tar/test/test_option_r.c
deleted file mode 100644
index 516a8307936c..000000000000
--- a/usr.bin/tar/test/test_option_r.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * Also see test_option_q for additional validation of -r support.
- */
-DEFINE_TEST(test_option_r)
-{
- char buff[15];
- char *p0, *p1;
- size_t s;
- FILE *f;
- int r;
-
- /* Create a file */
- f = fopen("f1", "w");
- if (!assert(f != NULL))
- return;
- assertEqualInt(3, fwrite("abc", 1, 3, f));
- fclose(f);
-
- /* Archive that one file. */
- r = systemf("%s cf archive.tar --format=ustar f1 >step1.out 2>step1.err", testprog);
- failure("Error invoking %s cf archive.tar f1", testprog);
- assertEqualInt(r, 0);
-
- /* Verify that nothing went to stdout or stderr. */
- assertEmptyFile("step1.out");
- assertEmptyFile("step1.err");
-
-
- /* Do some basic validation of the constructed archive. */
- p0 = slurpfile(&s, "archive.tar");
- if (!assert(p0 != NULL))
- return;
- if (!assert(s >= 2048)) {
- free(p0);
- return;
- }
- assertEqualMem(p0 + 0, "f1", 3);
- assertEqualMem(p0 + 512, "abc", 3);
- assertEqualMem(p0 + 1024, "\0\0\0\0\0\0\0\0", 8);
- assertEqualMem(p0 + 1536, "\0\0\0\0\0\0\0\0", 8);
-
- /* Edit that file */
- f = fopen("f1", "w");
- if (!assert(f != NULL))
- return;
- assertEqualInt(3, fwrite("123", 1, 3, f));
- fclose(f);
-
- /* Update the archive. */
- r = systemf("%s rf archive.tar --format=ustar f1 >step2.out 2>step2.err", testprog);
- failure("Error invoking %s rf archive.tar f1", testprog);
- assertEqualInt(r, 0);
-
- /* Verify that nothing went to stdout or stderr. */
- assertEmptyFile("step2.out");
- assertEmptyFile("step2.err");
-
- /* Do some basic validation of the constructed archive. */
- p1 = slurpfile(&s, "archive.tar");
- if (!assert(p1 != NULL)) {
- free(p0);
- return;
- }
- assert(s >= 3072);
- /* Verify first entry is unchanged. */
- assertEqualMem(p0, p1, 1024);
- /* Verify that second entry is correct. */
- assertEqualMem(p1 + 1024, "f1", 3);
- assertEqualMem(p1 + 1536, "123", 3);
- /* Verify end-of-archive marker. */
- assertEqualMem(p1 + 2048, "\0\0\0\0\0\0\0\0", 8);
- assertEqualMem(p1 + 2560, "\0\0\0\0\0\0\0\0", 8);
- free(p0);
- free(p1);
-
- /* Unpack both items */
- assertMakeDir("step3", 0775);
- assertChdir("step3");
- r = systemf("%s xf ../archive.tar", testprog);
- failure("Error invoking %s xf archive.tar", testprog);
- assertEqualInt(r, 0);
-
- /* Verify that the second one overwrote the first. */
- f = fopen("f1", "r");
- if (assert(f != NULL)) {
- assertEqualInt(3, fread(buff, 1, 3, f));
- assertEqualMem(buff, "123", 3);
- fclose(f);
- }
-}
diff --git a/usr.bin/tar/test/test_option_s.c b/usr.bin/tar/test/test_option_s.c
deleted file mode 100644
index 94d634514944..000000000000
--- a/usr.bin/tar/test/test_option_s.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * Copyright (c) 2003-2008 Tim Kientzle
- * 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$");
-
-static int
-mkfile(const char *fn, const char *contents)
-{
- FILE *f = fopen(fn, "w");
- failure("Couldn't create file '%s', errno=%d (%s)\n",
- fn, errno, strerror(errno));
- if (!assert(f != NULL))
- return (1); /* Failure. */
- if (contents != NULL)
- assertEqualInt(strlen(contents),
- fwrite(contents, 1, strlen(contents), f));
- assertEqualInt(0, fclose(f));
- return (0); /* Success */
-}
-
-DEFINE_TEST(test_option_s)
-{
- struct stat st;
-
- /* Create a sample file heirarchy. */
- assertMakeDir("in", 0755);
- assertMakeDir("in/d1", 0755);
- assertEqualInt(0, mkfile("in/d1/foo", "foo"));
- assertEqualInt(0, mkfile("in/d1/bar", "bar"));
-
- /* Does bsdtar support -s option ? */
- systemf("%s -cf - -s /foo/bar/ in/d1/foo > NUL 2> check.err",
- testprog);
- assertEqualInt(0, stat("check.err", &st));
- if (st.st_size != 0) {
- skipping("%s does not support -s option on this platform",
- testprog);
- return;
- }
-
- /*
- * Test 1: Filename substitution when creating archives.
- */
- assertMakeDir("test1", 0755);
- systemf("%s -cf - -s /foo/bar/ in/d1/foo | %s -xf - -C test1",
- testprog, testprog);
- assertFileContents("foo", 3, "test1/in/d1/bar");
- systemf("%s -cf - -s /d1/d2/ in/d1/foo | %s -xf - -C test1",
- testprog, testprog);
- assertFileContents("foo", 3, "test1/in/d2/foo");
-
-
- /*
- * Test 2: Basic substitution when extracting archive.
- */
- assertMakeDir("test2", 0755);
- systemf("%s -cf - in/d1/foo | %s -xf - -s /foo/bar/ -C test2",
- testprog, testprog);
- assertFileContents("foo", 3, "test2/in/d1/bar");
-
- /*
- * Test 3: Files with empty names shouldn't be archived.
- */
- systemf("%s -cf - -s ,in/d1/foo,, in/d1/foo | %s -tvf - > in.lst",
- testprog, testprog);
- assertEmptyFile("in.lst");
-
- /*
- * Test 4: Multiple substitutions when extracting archive.
- */
- assertMakeDir("test4", 0755);
- systemf("%s -cf - in/d1/foo in/d1/bar | %s -xf - -s /foo/bar/ -s }bar}baz} -C test4",
- testprog, testprog);
- assertFileContents("foo", 3, "test4/in/d1/bar");
- assertFileContents("bar", 3, "test4/in/d1/baz");
-
- /*
- * Test 5: Name-switching substitutions when extracting archive.
- */
- assertMakeDir("test5", 0755);
- systemf("%s -cf - in/d1/foo in/d1/bar | %s -xf - -s /foo/bar/ -s }bar}foo} -C test5",
- testprog, testprog);
- assertFileContents("foo", 3, "test5/in/d1/bar");
- assertFileContents("bar", 3, "test5/in/d1/foo");
-}
diff --git a/usr.bin/tar/test/test_patterns.c b/usr.bin/tar/test/test_patterns.c
deleted file mode 100644
index f909e27d6e23..000000000000
--- a/usr.bin/tar/test/test_patterns.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_patterns)
-{
- FILE *f;
- int r;
- const char *reffile2 = "test_patterns_2.tar";
- const char *reffile3 = "test_patterns_3.tar";
- const char *reffile4 = "test_patterns_4.tar";
-
- const char *tar2aExpected[] = {
- "/tmp/foo/bar/",
- "/tmp/foo/bar/baz",
- NULL
- };
-
- /*
- * Test basic command-line pattern handling.
- */
-
- /*
- * Test 1: Files on the command line that don't get matched
- * didn't produce an error.
- *
- * John Baldwin reported this problem in PR bin/121598
- */
- f = fopen("foo", "w");
- assert(f != NULL);
- fclose(f);
- r = systemf("%s cfv tar1.tgz foo > tar1a.out 2> tar1a.err", testprog);
- assertEqualInt(r, 0);
- r = systemf("%s xv --no-same-owner -f tar1.tgz foo bar > tar1b.out 2> tar1b.err", testprog);
- failure("tar should return non-zero because a file was given on the command line that's not in the archive");
- assert(r != 0);
-
- /*
- * Test 2: Check basic matching of full paths that start with /
- */
- extract_reference_file(reffile2);
-
- r = systemf("%s tf %s /tmp/foo/bar > tar2a.out 2> tar2a.err",
- testprog, reffile2);
- assertEqualInt(r, 0);
- assertFileContainsLinesAnyOrder("tar2a.out", tar2aExpected);
- assertEmptyFile("tar2a.err");
-
- /*
- * Test 3 archive has some entries starting with '/' and some not.
- */
- extract_reference_file(reffile3);
-
- /* Test 3a: Pattern tmp/foo/bar should not match /tmp/foo/bar */
- r = systemf("%s x --no-same-owner -f %s tmp/foo/bar > tar3a.out 2> tar3a.err",
- testprog, reffile3);
- assert(r != 0);
- assertEmptyFile("tar3a.out");
-
- /* Test 3b: Pattern /tmp/foo/baz should not match tmp/foo/baz */
- assertNonEmptyFile("tar3a.err");
- /* Again, with the '/' */
- r = systemf("%s x --no-same-owner -f %s /tmp/foo/baz > tar3b.out 2> tar3b.err",
- testprog, reffile3);
- assert(r != 0);
- assertEmptyFile("tar3b.out");
- assertNonEmptyFile("tar3b.err");
-
- /* Test 3c: ./tmp/foo/bar should not match /tmp/foo/bar */
- r = systemf("%s x --no-same-owner -f %s ./tmp/foo/bar > tar3c.out 2> tar3c.err",
- testprog, reffile3);
- assert(r != 0);
- assertEmptyFile("tar3c.out");
- assertNonEmptyFile("tar3c.err");
-
- /* Test 3d: ./tmp/foo/baz should match tmp/foo/baz */
- r = systemf("%s x --no-same-owner -f %s ./tmp/foo/baz > tar3d.out 2> tar3d.err",
- testprog, reffile3);
- assertEqualInt(r, 0);
- assertEmptyFile("tar3d.out");
- assertEmptyFile("tar3d.err");
- assertFileExists("tmp/foo/baz/bar");
-
- /*
- * Test 4 archive has some entries starting with windows drive letters
- * such as 'c:\', '//./c:/' or '//?/c:/'.
- */
- extract_reference_file(reffile4);
-
- r = systemf("%s x --no-same-owner -f %s -C tmp > tar4.out 2> tar4.err",
- testprog, reffile4);
- assert(r != 0);
- assertEmptyFile("tar4.out");
- assertNonEmptyFile("tar4.err");
-
- for (r = 1; r <= 54; r++) {
- char file_a[] = "tmp/fileXX";
- char file_b1[] = "tmp/server/share/fileXX";
- char file_b2[] = "tmp/server\\share\\fileXX";
- char file_c[] = "tmp/../fileXX";
- char *filex;
- int xsize;
-
- switch (r) {
- case 15: case 18:
- /*
- * Including server and share names.
- * //?/UNC/server/share/file15
- * //?/unc/server/share/file18
- */
- filex = file_b1;
- xsize = sizeof(file_b1);
- break;
- case 35: case 38: case 52:
- /*
- * Including server and share names.
- * \\?\UNC\server\share\file35
- * \\?\unc\server\share\file38
- * \/?/uNc/server\share\file52
- */
- filex = file_b2;
- xsize = sizeof(file_b2);
- break;
- default:
- filex = file_a;
- xsize = sizeof(file_a);
- break;
- }
- filex[xsize-3] = '0' + r / 10;
- filex[xsize-2] = '0' + r % 10;
- switch (r) {
- case 5: case 6: case 17: case 20: case 25:
- case 26: case 37: case 40: case 43: case 54:
- /*
- * Not extracted patterns.
- * D:../file05
- * c:../../file06
- * //?/UNC/../file17
- * //?/unc/../file20
- * z:..\file25
- * c:..\..\file26
- * \\?\UNC\..\file37
- * \\?\unc\..\file40
- * c:../..\file43
- * \/?\UnC\../file54
- */
- assertFileNotExists(filex);
- filex = file_c;
- xsize = sizeof(file_c);
- filex[xsize-3] = '0' + r / 10;
- filex[xsize-2] = '0' + r % 10;
- assertFileNotExists(filex);
- break;
- default:
- /* Extracted patterns. */
- assertFileExists(filex);
- break;
- }
- }
-}
diff --git a/usr.bin/tar/test/test_patterns_2.tar.uu b/usr.bin/tar/test/test_patterns_2.tar.uu
deleted file mode 100644
index f3a0a7507ab3..000000000000
--- a/usr.bin/tar/test/test_patterns_2.tar.uu
+++ /dev/null
@@ -1,233 +0,0 @@
-$FreeBSD$
-
-begin 644 test_patterns_2.tar
-M+W1M<"]F;V\O````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````#`P,#<U-2``,#`Q-S4P(``P,#`P,#`@`#`P,#`P,#`P,#`P
-M(#$Q,#4Q,C$R-C4V(#`Q,C0T,0`@-0``````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````!U<W1A<@`P,'1I;0``
-M````````````````````````````````````=VAE96P`````````````````
-M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````O=&UP+V9O;R]B87(O````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````,#`P-S4U(``P,#$W-3`@`#`P
-M,#`P,"``,#`P,#`P,#`P,#`@,3$P-3$R,3(V-3,@,#$S,C`R`"`U````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````'5S=&%R`#`P=&EM``````````````````````````````````````!W
-M:&5E;````````````````````````````````````#`P,#`P,"``,#`P,#`P
-M(```````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````"]T;7`O9F]O+V)A
-M>@``````````````````````````````````````````````````````````
-M```````````````````````````````````````````````````````````P
-M,#`V-#0@`#`P,3<U,"``,#`P,#`P(``P,#`P,#`P,#`P,"`Q,3`U,3(Q,C8U
-M-B`P,3,Q,C8`(#``````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````=7-T87(`,#!T:6T`````````````````
-M`````````````````````'=H965L````````````````````````````````
-M````,#`P,#`P(``P,#`P,#`@````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````+W1M<"]F;V\O8F%R+V)A>@``````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````#`P,#8T-"``,#`Q-S4P(``P,#`P,#`@`#`P,#`P
-M,#`P,#`P(#$Q,#4Q,C$R-C4S(#`Q,S8V-P`@,```````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````!U<W1A<@`P
-M,'1I;0``````````````````````````````````````=VAE96P`````````
-M```````````````````````````P,#`P,#`@`#`P,#`P,"``````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-9````````````````````````````````````
-`
-end
diff --git a/usr.bin/tar/test/test_patterns_3.tar.uu b/usr.bin/tar/test/test_patterns_3.tar.uu
deleted file mode 100644
index 8a19f80967b0..000000000000
--- a/usr.bin/tar/test/test_patterns_3.tar.uu
+++ /dev/null
@@ -1,233 +0,0 @@
-$FreeBSD$
-
-begin 644 test_patterns_3.tar
-M+W1M<"]F;V\O8F%R+P``````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````#`P,#<U-2``,#`Q-S4P(``P,#`P,#`@`#`P,#`P,#`P,#`P
-M(#$Q,#4S,C`W-34R(#`Q,S(P-@`@-0``````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````!U<W1A<@`P,'1I;0``
-M````````````````````````````````````=VAE96P`````````````````
-M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````O=&UP+V9O;R]B87(O8F%Z+P``````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````,#`P-S4U(``P,#$W-3`@`#`P
-M,#`P,"``,#`P,#`P,#`P,#`@,3$P-3,R,#<U-3(@,#$S-S8R`"`U````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````'5S=&%R`#`P=&EM``````````````````````````````````````!W
-M:&5E;````````````````````````````````````#`P,#`P,"``,#`P,#`P
-M(```````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````'1M<"]F;V\O8F%Z
-M+P``````````````````````````````````````````````````````````
-M```````````````````````````````````````````````````````````P
-M,#`W-34@`#`P,3<U,"``,#`P,#`P(``P,#`P,#`P,#`P,"`Q,3`U,S(P-S4V
-M,"`P,3,Q,S8`(#4`````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````=7-T87(`,#!T:6T`````````````````
-M`````````````````````'=H965L````````````````````````````````
-M````,#`P,#`P(``P,#`P,#`@````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````=&UP+V9O;R]B87HO8F%R+P``````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````#`P,#<U-2``,#`Q-S4P(``P,#`P,#`@`#`P,#`P
-M,#`P,#`P(#$Q,#4S,C`W-38P(#`Q,S<P,@`@-0``````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````!U<W1A<@`P
-M,'1I;0``````````````````````````````````````=VAE96P`````````
-M```````````````````````````P,#`P,#`@`#`P,#`P,"``````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-9````````````````````````````````````
-`
-end
diff --git a/usr.bin/tar/test/test_patterns_4.tar.uu b/usr.bin/tar/test/test_patterns_4.tar.uu
deleted file mode 100644
index 3fc62e49dc37..000000000000
--- a/usr.bin/tar/test/test_patterns_4.tar.uu
+++ /dev/null
@@ -1,643 +0,0 @@
-$FreeBSD$
-
-begin 644 test_patterns_4.tar
-M+V9I;&4P,0``````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P,#`P
-M(#$Q,34P-C<T-C0R(#`Q,#,S-@`@,```````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````!U<W1A<@`P,```````
-M````````````````````````````````````````````````````````````
-M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````O+BXO9FEL93`R````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````,#`P-C0T(``P,#$W-3$@`#`P
-M,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$P-34R`"`P````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````'5S=&%R`#`P````````````````````````````````````````````
-M`````````````````````````````````````````#`P,#`P,"``,#`P,#`P
-M(```````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````"\N+B\N+B]F:6QE
-M,#,`````````````````````````````````````````````````````````
-M```````````````````````````````````````````````````````````P
-M,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q,3$U,#8W-#8T
-M,B`P,3`W-C8`(#``````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````=7-T87(`,#``````````````````````
-M````````````````````````````````````````````````````````````
-M````,#`P,#`P(``P,#`P,#`@````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````8SHO9FEL93`T````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P
-M,#`P,#`P(#$Q,34P-C<T-C0R(#`Q,#4W-@`@,```````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````!U<W1A<@`P
-M,```````````````````````````````````````````````````````````
-M```````````````````````````P,#`P,#`@`#`P,#`P,"``````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````!$.BXN+V9I;&4P-0``````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````,#`P-C0T(``P,#$W
-M-3$@`#`P,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$P-C<T`"`P
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````'5S=&%R`#`P````````````````````````````````````
-M`````````````````````````````````````````````````#`P,#`P,"``
-M,#`P,#`P(```````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````````````&,Z+BXO
-M+BXO9FEL93`V````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````P,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q,3$U
-M,#8W-#8T,B`P,3$Q-#<`(#``````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````=7-T87(`,#``````````````
-M````````````````````````````````````````````````````````````
-M````````````,#`P,#`P(``P,#`P,#`@````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````0SHO+BXO9FEL93`W````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@
-M`#`P,#`P,#`P,#`P(#$Q,34P-C<T-C0R(#`Q,#<U-``@,```````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````````````!U
-M<W1A<@`P,```````````````````````````````````````````````````
-M```````````````````````````````````P,#`P,#`@`#`P,#`P,"``````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````!A.B\N+B\N+B]F:6QE,#@`
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````,#`P-C0T
-M(``P,#$W-3$@`#`P,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$Q
-M,C(V`"`P````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````'5S=&%R`#`P````````````````````````````
-M`````````````````````````````````````````````````````````#`P
-M,#`P,"``,#`P,#`P(```````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`"\O+B]C.B]F:6QE,#D`````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````P,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P
-M,"`Q,3$U,#8W-#8T,B`P,3$P-S8`(#``````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````=7-T87(`,#``````
-M````````````````````````````````````````````````````````````
-M````````````````````,#`P,#`P(``P,#`P,#`@````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````+R\N+T,Z+RXN+V9I;&4Q,```````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````#`P,#8T-"``,#`Q-S4Q(``P
-M,#$W-3$@`#`P,#`P,#`P,#`P(#$Q,34P-C<T-C0R(#`Q,3(T,0`@,```````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````!U<W1A<@`P,```````````````````````````````````````````
-M```````````````````````````````````````````P,#`P,#`@`#`P,#`P
-M,"``````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````````````````````````````O+S\O8SHO9FEL
-M93$Q````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M,#`P-C0T(``P,#$W-3$@`#`P,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V
-M-#(@,#$Q,3$P`"`P````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````'5S=&%R`#`P````````````````````
-M````````````````````````````````````````````````````````````
-M`````#`P,#`P,"``,#`P,#`P(```````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````"\O/R]#.B\N+B]F:6QE,3(`````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````P,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P
-M,#`P,#`P,"`Q,3$U,#8W-#8T,B`P,3$R-C0`(#``````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````=7-T87(`
-M,#``````````````````````````````````````````````````````````
-M````````````````````````````,#`P,#`P(``P,#`P,#`@````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````+R\O+V,Z+V9I;&4Q,P``````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````#`P,#8T-"``,#`Q
-M-S4Q(``P,#$W-3$@`#`P,#`P,#`P,#`P(#$Q,34P-C<T-C0R(#`Q,3`W,@`@
-M,```````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````!U<W1A<@`P,```````````````````````````````````
-M```````````````````````````````````````````````````P,#`P,#`@
-M`#`P,#`P,"``````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````````````````````````````````````O+R\O
-M0SHO+R\O+V9I;&4Q-```````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````,#`P-C0T(``P,#$W-3$@`#`P,3<U,2``,#`P,#`P,#`P,#`@,3$Q
-M-3`V-S0V-#(@,#$Q,S(W`"`P````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````'5S=&%R`#`P````````````
-M````````````````````````````````````````````````````````````
-M`````````````#`P,#`P,"``,#`P,#`P(```````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````"\O/R]53D,O<V5R=F5R+W-H87)E+V9I;&4Q-0``````
-M````````````````````````````````````````````````````````````
-M```````````````````````````````P,#`V-#0@`#`P,3<U,2``,#`Q-S4Q
-M(``P,#`P,#`P,#`P,"`Q,3$U,#8W-#8T,B`P,3,V,S4`(#``````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M=7-T87(`,#``````````````````````````````````````````````````
-M````````````````````````````````````,#`P,#`P(``P,#`P,#`@````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````+R\_+U5.0R]F:6QE,38`
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````````````#`P,#8T
-M-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P,#`P(#$Q,34P-C<T-C0R(#`Q
-M,3(R-@`@,```````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````!U<W1A<@`P,```````````````````````````
-M```````````````````````````````````````````````````````````P
-M,#`P,#`@`#`P,#`P,"``````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```O+S\O54Y#+RXN+V9I;&4Q-P``````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````,#`P-C0T(``P,#$W-3$@`#`P,3<U,2``,#`P,#`P,#`P
-M,#`@,3$Q-3`V-S0V-#(@,#$Q-#0R`"`P````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````'5S=&%R`#`P````
-M````````````````````````````````````````````````````````````
-M`````````````````````#`P,#`P,"``,#`P,#`P(```````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````"\O/R]U;F,O<V5R=F5R+W-H87)E+V9I;&4Q
-M.```````````````````````````````````````````````````````````
-M```````````````````````````````````````P,#`V-#0@`#`P,3<U,2``
-M,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q,3$U,#8W-#8T,B`P,30P,#``(#``````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````=7-T87(`,#``````````````````````````````````````````
-M````````````````````````````````````````````,#`P,#`P(``P,#`P
-M,#`@````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````+R\_+W5N8R]F
-M:6QE,3D`````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P,#`P(#$Q,34P-C<T
-M-C0R(#`Q,3,W,0`@,```````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````!U<W1A<@`P,```````````````````
-M````````````````````````````````````````````````````````````
-M```````P,#`P,#`@`#`P,#`P,"``````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````O+S\O=6YC+RXN+V9I;&4R,```````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````,#`P-C0T(``P,#$W-3$@`#`P,3<U,2``,#`P
-M,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$Q-3<T`"`P````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````````````'5S=&%R
-M`#`P````````````````````````````````````````````````````````
-M`````````````````````````````#`P,#`P,"``,#`P,#`P(```````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````%QF:6QE,C$`````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````````````````````````````P,#`V-#0@`#`P
-M,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q,3$U,#8W-#8T,B`P,3`T,34`
-M(#``````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````=7-T87(`,#``````````````````````````````````
-M````````````````````````````````````````````````````,#`P,#`P
-M(``P,#`P,#`@````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````7"XN
-M7&9I;&4R,@``````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P,#`P(#$Q
-M,34P-C<T-C0R(#`Q,#<P-@`@,```````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````!U<W1A<@`P,```````````
-M````````````````````````````````````````````````````````````
-M```````````````P,#`P,#`@`#`P,#`P,"``````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````!<+BY<+BY<9FEL93(S````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````,#`P-C0T(``P,#$W-3$@`#`P,3<U
-M,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$Q,3<W`"`P````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`'5S=&%R`#`P````````````````````````````````````````````````
-M`````````````````````````````````````#`P,#`P,"``,#`P,#`P(```
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````$,Z7&9I;&4R-```````
-M````````````````````````````````````````````````````````````
-M```````````````````````````````````````````````````````P,#`V
-M-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q,3$U,#8W-#8T,B`P
-M,3`V,34`(#``````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````=7-T87(`,#``````````````````````````
-M````````````````````````````````````````````````````````````
-M,#`P,#`P(``P,#`P,#`@````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````>CHN+EQF:6QE,C4`````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P
-M,#`P(#$Q,34P-C<T-C0R(#`Q,3`T,0`@,```````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````!U<W1A<@`P,```
-M````````````````````````````````````````````````````````````
-M```````````````````````P,#`P,#`@`#`P,#`P,"``````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````!C.BXN7"XN7&9I;&4R-@``````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````,#`P-C0T(``P,#$W-3$@
-M`#`P,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$Q,S`S`"`P````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````'5S=&%R`#`P````````````````````````````````````````
-M`````````````````````````````````````````````#`P,#`P,"``,#`P
-M,#`P(```````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````````%HZ7"XN7&9I
-M;&4R-P``````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```P,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q,3$U,#8W
-M-#8T,B`P,3$Q,S<`(#``````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````=7-T87(`,#``````````````````
-M````````````````````````````````````````````````````````````
-M````````,#`P,#`P(``P,#`P,#`@````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````0SI<+BY<+BY<9FEL93(X````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P
-M,#`P,#`P,#`P(#$Q,34P-C<T-C0R(#`Q,30P,0`@,```````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````````!U<W1A
-M<@`P,```````````````````````````````````````````````````````
-M```````````````````````````````P,#`P,#`@`#`P,#`P,"``````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````!<7"Y<8SI<9FEL93(Y````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````,#`P-C0T(``P
-M,#$W-3$@`#`P,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$Q,S8T
-M`"`P````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````'5S=&%R`#`P````````````````````````````````
-M`````````````````````````````````````````````````````#`P,#`P
-M,"``,#`P,#`P(```````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````````````````%Q<
-M+EQ#.EPN+EQF:6QE,S``````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````P,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q
-M,3$U,#8W-#8T,B`P,3$V,#0`(#``````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````=7-T87(`,#``````````
-M````````````````````````````````````````````````````````````
-M````````````````,#`P,#`P(``P,#`P,#`@````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````7%P_7&,Z7&9I;&4S,0``````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W
-M-3$@`#`P,#`P,#`P,#`P(#$Q,34P-C<T-C0R(#`Q,3,W-@`@,```````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``!U<W1A<@`P,```````````````````````````````````````````````
-M```````````````````````````````````````P,#`P,#`@`#`P,#`P,"``
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````!<7#]<1#I<+BY<9FEL
-M93,R````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````,#`P
-M-C0T(``P,#$W-3$@`#`P,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@
-M,#$Q-C,P`"`P````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````'5S=&%R`#`P````````````````````````
-M````````````````````````````````````````````````````````````
-M`#`P,#`P,"``,#`P,#`P(```````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````%Q<7%QC.EQF:6QE,S,`````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````P,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P
-M,#`P,"`Q,3$U,#8W-#8T,B`P,3$T,S4`(#``````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````=7-T87(`,#``
-M````````````````````````````````````````````````````````````
-M````````````````````````,#`P,#`P(``P,#`P,#`@````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````7%Q<7$,Z7%Q<7%QF:6QE,S0`````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````#`P,#8T-"``,#`Q-S4Q
-M(``P,#$W-3$@`#`P,#`P,#`P,#`P(#$Q,34P-C<T-C0R(#`Q,C$U-@`@,```
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````!U<W1A<@`P,```````````````````````````````````````
-M```````````````````````````````````````````````P,#`P,#`@`#`P
-M,#`P,"``````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````!<7#]<54Y#
-M7'-E<G9E<EQS:&%R95QF:6QE,S4`````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````,#`P-C0T(``P,#$W-3$@`#`P,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V
-M-S0V-#(@,#$T,C4U`"`P````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````'5S=&%R`#`P````````````````
-M````````````````````````````````````````````````````````````
-M`````````#`P,#`P,"``,#`P,#`P(```````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````%Q</UQ53D-<9FEL93,V````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````````P,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P
-M,#`P,#`P,#`P,"`Q,3$U,#8W-#8T,B`P,3$U,30`(#``````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````=7-T
-M87(`,#``````````````````````````````````````````````````````
-M````````````````````````````````,#`P,#`P(``P,#`P,#`@````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````7%P_7%5.0UPN+EQF:6QE,S<`
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````````#`P,#8T-"``
-M,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P,#`P(#$Q,34P-C<T-C0R(#`Q,C`P
-M-0`@,```````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````!U<W1A<@`P,```````````````````````````````
-M```````````````````````````````````````````````````````P,#`P
-M,#`@`#`P,#`P,"``````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````````````!<
-M7#]<=6YC7'-E<G9E<EQS:&%R95QF:6QE,S@`````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````,#`P-C0T(``P,#$W-3$@`#`P,3<U,2``,#`P,#`P,#`P,#`@
-M,3$Q-3`V-S0V-#(@,#$T-#(P`"`P````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````'5S=&%R`#`P````````
-M````````````````````````````````````````````````````````````
-M`````````````````#`P,#`P,"``,#`P,#`P(```````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````%Q</UQU;F-<9FEL93,Y````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````````````````P,#`V-#0@`#`P,3<U,2``,#`Q
-M-S4Q(``P,#`P,#`P,#`P,"`Q,3$U,#8W-#8T,B`P,3$V-3<`(#``````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````=7-T87(`,#``````````````````````````````````````````````
-M````````````````````````````````````````,#`P,#`P(``P,#`P,#`@
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````7%P_7'5N8UPN+EQF
-M:6QE-#``````````````````````````````````````````````````````
-M`````````````````````````````````````````````````````````#`P
-M,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P,#`P(#$Q,34P-C<T-C0R
-M(#`Q,C$S-P`@,```````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````!U<W1A<@`P,```````````````````````
-M````````````````````````````````````````````````````````````
-M```P,#`P,#`@`#`P,#`P,"``````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````!<+BXO9FEL930Q````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````,#`P-C0T(``P,#$W-3$@`#`P,3<U,2``,#`P,#`P
-M,#`P,#`@,3$Q-3`V-S0V-#(@,#$P-C,R`"`P````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````````'5S=&%R`#`P
-M````````````````````````````````````````````````````````````
-M`````````````````````````#`P,#`P,"``,#`P,#`P(```````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````%PN+B\N+EQF:6QE-#(`````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````````````````````````P,#`V-#0@`#`P,3<U
-M,2``,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q,3$U,#8W-#8T,B`P,3$Q,C,`(#``
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````=7-T87(`,#``````````````````````````````````````
-M````````````````````````````````````````````````,#`P,#`P(``P
-M,#`P,#`@````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````8SHN+B\N
-M+EQF:6QE-#,`````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P,#`P(#$Q,34P
-M-C<T-C0R(#`Q,3(R-0`@,```````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````!U<W1A<@`P,```````````````
-M````````````````````````````````````````````````````````````
-M```````````P,#`P,#`@`#`P,#`P,"``````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````!#.B\N+EQF:6QE-#0`````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````,#`P-C0T(``P,#$W-3$@`#`P,3<U,2``
-M,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$Q,#,R`"`P````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````````````````'5S
-M=&%R`#`P````````````````````````````````````````````````````
-M`````````````````````````````````#`P,#`P,"``,#`P,#`P(```````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````$0Z7"XN+RXN7&9I;&4T-0``
-M````````````````````````````````````````````````````````````
-M```````````````````````````````````````````````````P,#`V-#0@
-M`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q,3$U,#8W-#8T,B`P,3$S
-M,C0`(#``````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````=7-T87(`,#``````````````````````````````
-M````````````````````````````````````````````````````````,#`P
-M,#`P(``P,#`P,#`@````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M7"\N+V,Z7&9I;&4T-@``````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P,#`P
-M(#$Q,34P-C<T-C0R(#`Q,3(S,0`@,```````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````!U<W1A<@`P,```````
-M````````````````````````````````````````````````````````````
-M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````!<7"XO0SI<+BY<9FEL930W````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````,#`P-C0T(``P,#$W-3$@`#`P
-M,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$Q-3,W`"`P````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````'5S=&%R`#`P````````````````````````````````````````````
-M`````````````````````````````````````````#`P,#`P,"``,#`P,#`P
-M(```````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````%PO/UQC.B]F:6QE
-M-#@`````````````````````````````````````````````````````````
-M```````````````````````````````````````````````````````````P
-M,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q,3$U,#8W-#8T
-M,B`P,3$R-30`(#``````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````=7-T87(`,#``````````````````````
-M````````````````````````````````````````````````````````````
-M````,#`P,#`P(``P,#`P,#`@````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````7%P_+T0Z+RXN7&9I;&4T.0``````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P
-M,#`P,#`P(#$Q,34P-C<T-C0R(#`Q,34P-@`@,```````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````!U<W1A<@`P
-M,```````````````````````````````````````````````````````````
-M```````````````````````````P,#`P,#`@`#`P,#`P,"``````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````!<+R]<1#I<9FEL934P````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````,#`P-C0T(``P,#$W
-M-3$@`#`P,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$Q,C0S`"`P
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````'5S=&%R`#`P````````````````````````````````````
-M`````````````````````````````````````````````````#`P,#`P,"``
-M,#`P,#`P(```````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````````````````````````````%Q<+R]C
-M.EPO+UQ<9FEL934Q````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````P,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P,"`Q,3$U
-M,#8W-#8T,B`P,3$W,S$`(#``````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````=7-T87(`,#``````````````
-M````````````````````````````````````````````````````````````
-M````````````,#`P,#`P(``P,#`P,#`@````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````7"\_+W5.8R]S97)V97)<<VAA<F5<9FEL934R````````
-M````````````````````````````````````````````````````````````
-M`````````````````````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@
-M`#`P,#`P,#`P,#`P(#$Q,34P-C<T-C0R(#`Q-#$T-0`@,```````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````````````````````!U
-M<W1A<@`P,```````````````````````````````````````````````````
-M```````````````````````````````````P,#`P,#`@`#`P,#`P,"``````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````!<7#\O54YC7&9I;&4U,P``
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````,#`P-C0T
-M(``P,#$W-3$@`#`P,3<U,2``,#`P,#`P,#`P,#`@,3$Q-3`V-S0V-#(@,#$Q
-M-#<V`"`P````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````````````'5S=&%R`#`P````````````````````````````
-M`````````````````````````````````````````````````````````#`P
-M,#`P,"``,#`P,#`P(```````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`%PO/UQ5;D-<+BXO9FEL934T````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````P,#`V-#0@`#`P,3<U,2``,#`Q-S4Q(``P,#`P,#`P,#`P
-M,"`Q,3$U,#8W-#8T,B`P,3$W,3(`(#``````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````=7-T87(`,#``````
-M````````````````````````````````````````````````````````````
-M````````````````````,#`P,#`P(``P,#`P,#`@````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-'````````````
-`
-end
diff --git a/usr.bin/tar/test/test_stdio.c b/usr.bin/tar/test/test_stdio.c
deleted file mode 100644
index 1780d967c8c3..000000000000
--- a/usr.bin/tar/test/test_stdio.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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_stdio)
-{
- FILE *filelist;
- char *p;
- size_t s;
- int r;
-
- assertUmask(0);
-
- /*
- * Create a couple of files on disk.
- */
- /* File */
- assertMakeFile("f", 0755, "abc");
- /* Link to above file. */
- assertMakeHardlink("l", "f");
-
- /* Create file list (text mode here) */
- filelist = fopen("filelist", "w");
- assert(filelist != NULL);
- fprintf(filelist, "f\n");
- fprintf(filelist, "l\n");
- fclose(filelist);
-
- /*
- * Archive/dearchive with a variety of options, verifying
- * stdio paths.
- */
-
- /* 'cf' should generate no output unless there's an error. */
- r = systemf("%s cf archive f l >cf.out 2>cf.err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("cf.out");
- assertEmptyFile("cf.err");
-
- /* 'cvf' should generate file list on stderr, empty stdout. */
- r = systemf("%s cvf archive f l >cvf.out 2>cvf.err", testprog);
- assertEqualInt(r, 0);
- failure("'cv' writes filenames to stderr, nothing to stdout (SUSv2)\n"
- "Note that GNU tar writes the file list to stdout by default.");
- assertEmptyFile("cvf.out");
- /* TODO: Verify cvf.err has file list in SUSv2-prescribed format. */
-
- /* 'cvf -' should generate file list on stderr, archive on stdout. */
- r = systemf("%s cvf - f l >cvf-.out 2>cvf-.err", testprog);
- assertEqualInt(r, 0);
- failure("cvf - should write archive to stdout");
- /* TODO: Verify cvf-.out has archive. */
- failure("cvf - should write file list to stderr (SUSv2)");
- /* TODO: Verify cvf-.err has verbose file list. */
-
- /* 'tf' should generate file list on stdout, empty stderr. */
- r = systemf("%s tf archive >tf.out 2>tf.err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("tf.err");
- failure("'t' mode should write results to stdout");
- /* TODO: Verify tf.out has file list. */
-
- /* 'tvf' should generate file list on stdout, empty stderr. */
- r = systemf("%s tvf archive >tvf.out 2>tvf.err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("tvf.err");
- failure("'tv' mode should write results to stdout");
- /* TODO: Verify tvf.out has file list. */
-
- /* 'tvf -' uses stdin, file list on stdout, empty stderr. */
- r = systemf("%s tvf - < archive >tvf-.out 2>tvf-.err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("tvf-.err");
- /* TODO: Verify tvf-.out has file list. */
-
- /* Basic 'xf' should generate no output on stdout or stderr. */
- r = systemf("%s xf archive >xf.out 2>xf.err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("xf.err");
- assertEmptyFile("xf.out");
-
- /* 'xvf' should generate list on stderr, empty stdout. */
- r = systemf("%s xvf archive >xvf.out 2>xvf.err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("xvf.out");
- /* TODO: Verify xvf.err */
-
- /* 'xvOf' should generate list on stderr, file contents on stdout. */
- r = systemf("%s xvOf archive >xvOf.out 2>xvOf.err", testprog);
- assertEqualInt(r, 0);
- /* Verify xvOf.out is the file contents */
- p = slurpfile(&s, "xvOf.out");
- assert(s = 3);
- assertEqualMem(p, "abc", 3);
- /* TODO: Verify xvf.err */
-
- /* 'xvf -' should generate list on stderr, empty stdout. */
- r = systemf("%s xvf - < archive >xvf-.out 2>xvf-.err", testprog);
- assertEqualInt(r, 0);
- assertEmptyFile("xvf-.out");
- /* TODO: Verify xvf-.err */
-}
diff --git a/usr.bin/tar/test/test_strip_components.c b/usr.bin/tar/test/test_strip_components.c
deleted file mode 100644
index 271f2091a443..000000000000
--- a/usr.bin/tar/test/test_strip_components.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-static int
-touch(const char *fn)
-{
- FILE *f = fopen(fn, "w");
- failure("Couldn't create file '%s', errno=%d (%s)\n",
- fn, errno, strerror(errno));
- if (!assert(f != NULL))
- return (0); /* Failure. */
- fclose(f);
- return (1); /* Success */
-}
-
-DEFINE_TEST(test_strip_components)
-{
- assertMakeDir("d0", 0755);
- assertChdir("d0");
- assertMakeDir("d1", 0755);
- assertMakeDir("d1/d2", 0755);
- assertMakeDir("d1/d2/d3", 0755);
- assertEqualInt(1, touch("d1/d2/f1"));
- assertMakeHardlink("l1", "d1/d2/f1");
- assertMakeHardlink("d1/l2", "d1/d2/f1");
- if (canSymlink()) {
- assertMakeSymlink("s1", "d1/d2/f1");
- assertMakeSymlink("d1/s2", "d2/f1");
- }
- assertChdir("..");
-
- assertEqualInt(0, systemf("%s -cf test.tar d0", testprog));
-
- assertMakeDir("target", 0755);
- assertEqualInt(0, systemf("%s -x -C target --strip-components 2 "
- "-f test.tar", testprog));
-
- failure("d0/ is too short and should not get restored");
- assertFileNotExists("target/d0");
- failure("d0/d1/ is too short and should not get restored");
- assertFileNotExists("target/d1");
- failure("d0/d1/s2 is a symlink to something that won't be extracted");
- /* If platform supports symlinks, target/s2 is a broken symlink. */
- /* If platform does not support symlink, target/s2 doesn't exist. */
- assertFileNotExists("target/s2");
- if (canSymlink())
- assertIsSymlink("target/s2", "d2/f1");
- failure("d0/d1/d2 should be extracted");
- assertIsDir("target/d2", -1);
-
- /*
- * This next is a complicated case. d0/l1, d0/d1/l2, and
- * d0/d1/d2/f1 are all hardlinks to the same file; d0/l1 can't
- * be extracted with --strip-components=2 and the other two
- * can. Remember that tar normally stores the first file with
- * a body and the other as hardlink entries to the first
- * appearance. So the final result depends on the order in
- * which these three names get archived. If d0/l1 is first,
- * none of the three can be restored. If either of the longer
- * names are first, then the two longer ones can both be
- * restored.
- *
- * The tree-walking code used by bsdtar always visits files
- * before subdirectories, so bsdtar's behavior is fortunately
- * deterministic: d0/l1 will always get stored first and the
- * other two will be stored as hardlinks to d0/l1. Since
- * d0/l1 can't be extracted, none of these three will be
- * extracted.
- *
- * It may be worth extending this test to force a particular
- * archiving order so as to exercise both of the cases described
- * above.
- *
- * Of course, this is all totally different for cpio and newc
- * formats because the hardlink management is different.
- * TODO: Rename this to test_strip_components_tar and create
- * parallel tests for cpio and newc formats.
- */
- failure("d0/l1 is too short and should not get restored");
- assertFileNotExists("target/l1");
- failure("d0/d1/l2 is a hardlink to file whose name was too short");
- assertFileNotExists("target/l2");
- failure("d0/d1/d2/f1 is a hardlink to file whose name was too short");
- assertFileNotExists("target/d2/f1");
-}
diff --git a/usr.bin/tar/test/test_symlink_dir.c b/usr.bin/tar/test/test_symlink_dir.c
deleted file mode 100644
index f0cfebb33b99..000000000000
--- a/usr.bin/tar/test/test_symlink_dir.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * tar -x -P should follow existing symlinks for dirs, but not other
- * content. Plain tar -x should remove symlinks when they're in the
- * way of a dir extraction.
- */
-
-static int
-mkfile(const char *name, int mode, const char *contents, size_t size)
-{
- FILE *f = fopen(name, "wb");
- size_t written;
-
- (void)mode; /* UNUSED */
- if (f == NULL)
- return (-1);
- written = fwrite(contents, 1, size, f);
- fclose(f);
- if (size != written)
- return (-1);
- return (0);
-}
-
-DEFINE_TEST(test_symlink_dir)
-{
- assertUmask(0);
-
- assertMakeDir("source", 0755);
- assertEqualInt(0, mkfile("source/file", 0755, "a", 1));
- assertEqualInt(0, mkfile("source/file2", 0755, "ab", 2));
- assertMakeDir("source/dir", 0755);
- assertMakeDir("source/dir/d", 0755);
- assertEqualInt(0, mkfile("source/dir/f", 0755, "abc", 3));
- assertMakeDir("source/dir2", 0755);
- assertMakeDir("source/dir2/d2", 0755);
- assertEqualInt(0, mkfile("source/dir2/f2", 0755, "abcd", 4));
- assertMakeDir("source/dir3", 0755);
- assertMakeDir("source/dir3/d3", 0755);
- assertEqualInt(0, mkfile("source/dir3/f3", 0755, "abcde", 5));
-
- assertEqualInt(0,
- systemf("%s -cf test.tar -C source dir dir2 dir3 file file2",
- testprog));
-
- /*
- * Extract with -x and without -P.
- */
- assertMakeDir("dest1", 0755);
- /* "dir" is a symlink to an existing "dest1/real_dir" */
- assertMakeDir("dest1/real_dir", 0755);
- if (canSymlink()) {
- assertMakeSymlink("dest1/dir", "real_dir");
- /* "dir2" is a symlink to a non-existing "real_dir2" */
- assertMakeSymlink("dest1/dir2", "real_dir2");
- } else {
- skipping("some symlink checks");
- }
- /* "dir3" is a symlink to an existing "non_dir3" */
- assertEqualInt(0, mkfile("dest1/non_dir3", 0755, "abcdef", 6));
- if (canSymlink())
- assertMakeSymlink("dest1/dir3", "non_dir3");
- /* "file" is a symlink to existing "real_file" */
- assertEqualInt(0, mkfile("dest1/real_file", 0755, "abcdefg", 7));
- if (canSymlink()) {
- assertMakeSymlink("dest1/file", "real_file");
- /* "file2" is a symlink to non-existing "real_file2" */
- assertMakeSymlink("dest1/file2", "real_file2");
- }
- assertEqualInt(0, systemf("%s -xf test.tar -C dest1", testprog));
-
- /* dest1/dir symlink should be replaced */
- failure("symlink to dir was followed when it shouldn't be");
- assertIsDir("dest1/dir", -1);
- /* dest1/dir2 symlink should be replaced */
- failure("Broken symlink wasn't replaced with dir");
- assertIsDir("dest1/dir2", -1);
- /* dest1/dir3 symlink should be replaced */
- failure("Symlink to non-dir wasn't replaced with dir");
- assertIsDir("dest1/dir3", -1);
- /* dest1/file symlink should be replaced */
- failure("Symlink to existing file should be replaced");
- assertIsReg("dest1/file", -1);
- /* dest1/file2 symlink should be replaced */
- failure("Symlink to non-existing file should be replaced");
- assertIsReg("dest1/file2", -1);
-
- /*
- * Extract with both -x and -P
- */
- assertMakeDir("dest2", 0755);
- /* "dir" is a symlink to existing "real_dir" */
- assertMakeDir("dest2/real_dir", 0755);
- if (canSymlink())
- assertMakeSymlink("dest2/dir", "real_dir");
- /* "dir2" is a symlink to a non-existing "real_dir2" */
- if (canSymlink())
- assertMakeSymlink("dest2/dir2", "real_dir2");
- /* "dir3" is a symlink to an existing "non_dir3" */
- assertEqualInt(0, mkfile("dest2/non_dir3", 0755, "abcdefgh", 8));
- if (canSymlink())
- assertMakeSymlink("dest2/dir3", "non_dir3");
- /* "file" is a symlink to existing "real_file" */
- assertEqualInt(0, mkfile("dest2/real_file", 0755, "abcdefghi", 9));
- if (canSymlink())
- assertMakeSymlink("dest2/file", "real_file");
- /* "file2" is a symlink to non-existing "real_file2" */
- if (canSymlink())
- assertMakeSymlink("dest2/file2", "real_file2");
- assertEqualInt(0, systemf("%s -xPf test.tar -C dest2", testprog));
-
- /* dest2/dir symlink should be followed */
- if (canSymlink()) {
- assertIsSymlink("dest2/dir", "real_dir");
- assertIsDir("dest2/real_dir", -1);
- }
-
- /* Contents of 'dir' should be restored */
- assertIsDir("dest2/dir/d", -1);
- assertIsReg("dest2/dir/f", -1);
- assertFileSize("dest2/dir/f", 3);
- /* dest2/dir2 symlink should be removed */
- failure("Broken symlink wasn't replaced with dir");
- assertIsDir("dest2/dir2", -1);
- /* dest2/dir3 symlink should be removed */
- failure("Symlink to non-dir wasn't replaced with dir");
- assertIsDir("dest2/dir3", -1);
- /* dest2/file symlink should be removed;
- * even -P shouldn't follow symlinks for files */
- failure("Symlink to existing file should be removed");
- assertIsReg("dest2/file", -1);
- /* dest2/file2 symlink should be removed */
- failure("Symlink to non-existing file should be removed");
- assertIsReg("dest2/file2", -1);
-}
diff --git a/usr.bin/tar/test/test_version.c b/usr.bin/tar/test/test_version.c
deleted file mode 100644
index e4aacc8344de..000000000000
--- a/usr.bin/tar/test/test_version.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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$");
-
-/*
- * Test that --version option works and generates reasonable output.
- */
-
-DEFINE_TEST(test_version)
-{
- int r;
- char *p, *q;
- size_t s;
-
-
- r = systemf("%s --version >version.stdout 2>version.stderr", testprog);
- if (r != 0)
- r = systemf("%s -W version >version.stdout 2>version.stderr",
- testprog);
- failure("Unable to run either %s --version or %s -W version",
- testprog, testprog);
- if (!assert(r == 0))
- return;
-
- /* --version should generate nothing to stdout. */
- assertEmptyFile("version.stderr");
- /* Verify format of version message. */
- q = p = slurpfile(&s, "version.stdout");
- /* Version message should start with name of program, then space. */
- assert(s > 6);
- failure("Version must start with 'bsdtar': ``%s''", p);
- if (!assertEqualMem(q, "bsdtar ", 7))
- return;
- q += 7; s -= 7;
- /* Version number is a series of digits and periods. */
- while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
- ++q;
- --s;
- }
- /* Version number terminated by space. */
- failure("No space after bsdtar version: ``%s''", p);
- assert(s > 1);
- /* Skip a single trailing a,b,c, or d. */
- if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
- ++q;
- failure("No space after bsdtar version: ``%s''", p);
- assert(*q == ' ');
- ++q; --s;
- /* Separator. */
- failure("No `-' between bsdtar and libarchive versions: ``%s''", p);
- assertEqualMem(q, "- ", 2);
- q += 2; s -= 2;
- /* libarchive name and version number */
- failure("Not long enough for libarchive version: ``%s''", p);
- assert(s > 11);
- failure("Libarchive version must start with `libarchive': ``%s''", p);
- assertEqualMem(q, "libarchive ", 11);
- q += 11; s -= 11;
- /* Version number is a series of digits and periods. */
- while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
- ++q;
- --s;
- }
- /* Skip a single trailing a,b,c, or d. */
- if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
- ++q;
- /* All terminated by end-of-line. */
- assert(s >= 1);
- /* Skip an optional CR character (e.g., Windows) */
- failure("Version output must end with \\n or \\r\\n");
- if (*q == '\r') { ++q; --s; }
- assertEqualMem(q, "\n", 1);
- free(p);
-}
diff --git a/usr.bin/tar/tree.c b/usr.bin/tar/tree.c
deleted file mode 100644
index a94f809b0a6d..000000000000
--- a/usr.bin/tar/tree.c
+++ /dev/null
@@ -1,820 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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.
- */
-
-/*-
- * This is a new directory-walking system that addresses a number
- * of problems I've had with fts(3). In particular, it has no
- * pathname-length limits (other than the size of 'int'), handles
- * deep logical traversals, uses considerably less memory, and has
- * an opaque interface (easier to modify in the future).
- *
- * Internally, it keeps a single list of "tree_entry" items that
- * represent filesystem objects that require further attention.
- * Non-directories are not kept in memory: they are pulled from
- * readdir(), returned to the client, then freed as soon as possible.
- * Any directory entry to be traversed gets pushed onto the stack.
- *
- * There is surprisingly little information that needs to be kept for
- * each item on the stack. Just the name, depth (represented here as the
- * string length of the parent directory's pathname), and some markers
- * indicating how to get back to the parent (via chdir("..") for a
- * regular dir or via fchdir(2) for a symlink).
- */
-#include "bsdtar_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if defined(HAVE_WINDOWS_H) && !defined(__CYGWIN__)
-#include <windows.h>
-#endif
-
-#include "tree.h"
-
-/*
- * TODO:
- * 1) Loop checking.
- * 3) Arbitrary logical traversals by closing/reopening intermediate fds.
- */
-
-struct tree_entry {
- int depth;
- struct tree_entry *next;
- struct tree_entry *parent;
- char *name;
- size_t dirname_length;
- dev_t dev;
- ino_t ino;
- int flags;
- /* How to return back to the parent of a symlink. */
-#ifdef HAVE_FCHDIR
- int symlink_parent_fd;
-#elif defined(_WIN32) && !defined(__CYGWIN__)
- char *symlink_parent_path;
-#else
-#error fchdir function required.
-#endif
-};
-
-/* Definitions for tree_entry.flags bitmap. */
-#define isDir 1 /* This entry is a regular directory. */
-#define isDirLink 2 /* This entry is a symbolic link to a directory. */
-#define needsFirstVisit 4 /* This is an initial entry. */
-#define needsDescent 8 /* This entry needs to be previsited. */
-#define needsOpen 16 /* This is a directory that needs to be opened. */
-#define needsAscent 32 /* This entry needs to be postvisited. */
-
-/*
- * On Windows, "first visit" is handled as a pattern to be handed to
- * _findfirst(). This is consistent with Windows conventions that
- * file patterns are handled within the application. On Posix,
- * "first visit" is just returned to the client.
- */
-
-/*
- * Local data for this package.
- */
-struct tree {
- struct tree_entry *stack;
- struct tree_entry *current;
-#if defined(HAVE_WINDOWS_H) && !defined(__CYGWIN__)
- HANDLE d;
- BY_HANDLE_FILE_INFORMATION fileInfo;
-#define INVALID_DIR_HANDLE INVALID_HANDLE_VALUE
- WIN32_FIND_DATA _findData;
- WIN32_FIND_DATA *findData;
-#else
- DIR *d;
-#define INVALID_DIR_HANDLE NULL
- struct dirent *de;
-#endif
- int flags;
- int visit_type;
- int tree_errno; /* Error code from last failed operation. */
-
- /* Dynamically-sized buffer for holding path */
- char *buff;
- size_t buff_length;
-
- const char *basename; /* Last path element */
- size_t dirname_length; /* Leading dir length */
- size_t path_length; /* Total path length */
-
- int depth;
- int openCount;
- int maxOpenCount;
-
- struct stat lst;
- struct stat st;
-};
-
-/* Definitions for tree.flags bitmap. */
-#define hasStat 16 /* The st entry is valid. */
-#define hasLstat 32 /* The lst entry is valid. */
-#define hasFileInfo 64 /* The Windows fileInfo entry is valid. */
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-static int
-tree_dir_next_windows(struct tree *t, const char *pattern);
-#else
-static int
-tree_dir_next_posix(struct tree *t);
-#endif
-
-#ifdef HAVE_DIRENT_D_NAMLEN
-/* BSD extension; avoids need for a strlen() call. */
-#define D_NAMELEN(dp) (dp)->d_namlen
-#else
-#define D_NAMELEN(dp) (strlen((dp)->d_name))
-#endif
-
-#include <stdio.h>
-void
-tree_dump(struct tree *t, FILE *out)
-{
- char buff[300];
- struct tree_entry *te;
-
- fprintf(out, "\tdepth: %d\n", t->depth);
- fprintf(out, "\tbuff: %s\n", t->buff);
- fprintf(out, "\tpwd: %s\n", getcwd(buff, sizeof(buff)));
- fprintf(out, "\tbasename: %s\n", t->basename);
- fprintf(out, "\tstack:\n");
- for (te = t->stack; te != NULL; te = te->next) {
- fprintf(out, "\t\t%s%d:\"%s\" %s%s%s%s%s%s\n",
- t->current == te ? "*" : " ",
- te->depth,
- te->name,
- te->flags & needsFirstVisit ? "V" : "",
- te->flags & needsDescent ? "D" : "",
- te->flags & needsOpen ? "O" : "",
- te->flags & needsAscent ? "A" : "",
- te->flags & isDirLink ? "L" : "",
- (t->current == te && t->d) ? "+" : ""
- );
- }
-}
-
-/*
- * Add a directory path to the current stack.
- */
-static void
-tree_push(struct tree *t, const char *path)
-{
- struct tree_entry *te;
-
- te = malloc(sizeof(*te));
- memset(te, 0, sizeof(*te));
- te->next = t->stack;
- te->parent = t->current;
- if (te->parent)
- te->depth = te->parent->depth + 1;
- t->stack = te;
-#ifdef HAVE_FCHDIR
- te->symlink_parent_fd = -1;
- te->name = strdup(path);
-#elif defined(_WIN32) && !defined(__CYGWIN__)
- te->symlink_parent_path = NULL;
- te->name = strdup(path);
-#endif
- te->flags = needsDescent | needsOpen | needsAscent;
- te->dirname_length = t->dirname_length;
-}
-
-/*
- * Append a name to the current dir path.
- */
-static void
-tree_append(struct tree *t, const char *name, size_t name_length)
-{
- char *p;
- size_t size_needed;
-
- if (t->buff != NULL)
- t->buff[t->dirname_length] = '\0';
- /* Strip trailing '/' from name, unless entire name is "/". */
- while (name_length > 1 && name[name_length - 1] == '/')
- name_length--;
-
- /* Resize pathname buffer as needed. */
- size_needed = name_length + 1 + t->dirname_length;
- if (t->buff_length < size_needed) {
- if (t->buff_length < 1024)
- t->buff_length = 1024;
- while (t->buff_length < size_needed)
- t->buff_length *= 2;
- t->buff = realloc(t->buff, t->buff_length);
- }
- if (t->buff == NULL)
- abort();
- p = t->buff + t->dirname_length;
- t->path_length = t->dirname_length + name_length;
- /* Add a separating '/' if it's needed. */
- if (t->dirname_length > 0 && p[-1] != '/') {
- *p++ = '/';
- t->path_length ++;
- }
-#if HAVE_STRNCPY_S
- strncpy_s(p, t->buff_length - (p - t->buff), name, name_length);
-#else
- strncpy(p, name, name_length);
-#endif
- p[name_length] = '\0';
- t->basename = p;
-}
-
-/*
- * Open a directory tree for traversal.
- */
-struct tree *
-tree_open(const char *path)
-{
-#ifdef HAVE_FCHDIR
- struct tree *t;
-
- t = malloc(sizeof(*t));
- memset(t, 0, sizeof(*t));
- /* First item is set up a lot like a symlink traversal. */
- tree_push(t, path);
- t->stack->flags = needsFirstVisit | isDirLink | needsAscent;
- t->stack->symlink_parent_fd = open(".", O_RDONLY);
- t->openCount++;
- t->d = INVALID_DIR_HANDLE;
- return (t);
-#elif defined(_WIN32) && !defined(__CYGWIN__)
- struct tree *t;
- char *cwd = _getcwd(NULL, 0);
- char *pathname = strdup(path), *p, *base;
-
- if (pathname == NULL)
- abort();
- for (p = pathname; *p != '\0'; ++p) {
- if (*p == '\\')
- *p = '/';
- }
- base = pathname;
-
- t = malloc(sizeof(*t));
- memset(t, 0, sizeof(*t));
- /* First item is set up a lot like a symlink traversal. */
- /* printf("Looking for wildcard in %s\n", path); */
- /* TODO: wildcard detection here screws up on \\?\c:\ UNC names */
- if (strchr(base, '*') || strchr(base, '?')) {
- // It has a wildcard in it...
- // Separate the last element.
- p = strrchr(base, '/');
- if (p != NULL) {
- *p = '\0';
- chdir(base);
- tree_append(t, base, p - base);
- t->dirname_length = t->path_length;
- base = p + 1;
- }
- }
- tree_push(t, base);
- free(pathname);
- t->stack->flags = needsFirstVisit | isDirLink | needsAscent;
- t->stack->symlink_parent_path = cwd;
- t->d = INVALID_DIR_HANDLE;
- return (t);
-#endif
-}
-
-/*
- * We've finished a directory; ascend back to the parent.
- */
-static int
-tree_ascend(struct tree *t)
-{
- struct tree_entry *te;
- int r = 0;
-
- te = t->stack;
- t->depth--;
- if (te->flags & isDirLink) {
-#ifdef HAVE_FCHDIR
- if (fchdir(te->symlink_parent_fd) != 0) {
- t->tree_errno = errno;
- r = TREE_ERROR_FATAL;
- }
- close(te->symlink_parent_fd);
-#elif defined(_WIN32) && !defined(__CYGWIN__)
- if (SetCurrentDirectory(te->symlink_parent_path) == 0) {
- t->tree_errno = errno;
- r = TREE_ERROR_FATAL;
- }
- free(te->symlink_parent_path);
- te->symlink_parent_path = NULL;
-#endif
- t->openCount--;
- } else {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (SetCurrentDirectory("..") == 0) {
-#else
- if (chdir("..") != 0) {
-#endif
- t->tree_errno = errno;
- r = TREE_ERROR_FATAL;
- }
- }
- return (r);
-}
-
-/*
- * Pop the working stack.
- */
-static void
-tree_pop(struct tree *t)
-{
- struct tree_entry *te;
-
- if (t->buff)
- t->buff[t->dirname_length] = '\0';
- if (t->stack == t->current && t->current != NULL)
- t->current = t->current->parent;
- te = t->stack;
- t->stack = te->next;
- t->dirname_length = te->dirname_length;
- if (t->buff) {
- t->basename = t->buff + t->dirname_length;
- while (t->basename[0] == '/')
- t->basename++;
- }
- free(te->name);
- free(te);
-}
-
-/*
- * Get the next item in the tree traversal.
- */
-int
-tree_next(struct tree *t)
-{
- int r;
-
- /* If we're called again after a fatal error, that's an API
- * violation. Just crash now. */
- if (t->visit_type == TREE_ERROR_FATAL) {
- fprintf(stderr, "Unable to continue traversing"
- " directory hierarchy after a fatal error.");
- abort();
- }
-
- while (t->stack != NULL) {
- /* If there's an open dir, get the next entry from there. */
- if (t->d != INVALID_DIR_HANDLE) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- r = tree_dir_next_windows(t, NULL);
-#else
- r = tree_dir_next_posix(t);
-#endif
- if (r == 0)
- continue;
- return (r);
- }
-
- if (t->stack->flags & needsFirstVisit) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- char *d = t->stack->name;
- t->stack->flags &= ~needsFirstVisit;
- if (strchr(d, '*') || strchr(d, '?')) {
- r = tree_dir_next_windows(t, d);
- if (r == 0)
- continue;
- return (r);
- }
- // Not a pattern, handle it as-is...
-#endif
- /* Top stack item needs a regular visit. */
- t->current = t->stack;
- tree_append(t, t->stack->name, strlen(t->stack->name));
- //t->dirname_length = t->path_length;
- //tree_pop(t);
- t->stack->flags &= ~needsFirstVisit;
- return (t->visit_type = TREE_REGULAR);
- } else if (t->stack->flags & needsDescent) {
- /* Top stack item is dir to descend into. */
- t->current = t->stack;
- tree_append(t, t->stack->name, strlen(t->stack->name));
- t->stack->flags &= ~needsDescent;
- /* If it is a link, set up fd for the ascent. */
- if (t->stack->flags & isDirLink) {
-#ifdef HAVE_FCHDIR
- t->stack->symlink_parent_fd = open(".", O_RDONLY);
- t->openCount++;
- if (t->openCount > t->maxOpenCount)
- t->maxOpenCount = t->openCount;
-#elif defined(_WIN32) && !defined(__CYGWIN__)
- t->stack->symlink_parent_path = _getcwd(NULL, 0);
-#endif
- }
- t->dirname_length = t->path_length;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (t->path_length == 259 || !SetCurrentDirectory(t->stack->name) != 0)
-#else
- if (chdir(t->stack->name) != 0)
-#endif
- {
- /* chdir() failed; return error */
- tree_pop(t);
- t->tree_errno = errno;
- return (t->visit_type = TREE_ERROR_DIR);
- }
- t->depth++;
- return (t->visit_type = TREE_POSTDESCENT);
- } else if (t->stack->flags & needsOpen) {
- t->stack->flags &= ~needsOpen;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- r = tree_dir_next_windows(t, "*");
-#else
- r = tree_dir_next_posix(t);
-#endif
- if (r == 0)
- continue;
- return (r);
- } else if (t->stack->flags & needsAscent) {
- /* Top stack item is dir and we're done with it. */
- r = tree_ascend(t);
- tree_pop(t);
- t->visit_type = r != 0 ? r : TREE_POSTASCENT;
- return (t->visit_type);
- } else {
- /* Top item on stack is dead. */
- tree_pop(t);
- t->flags &= ~hasLstat;
- t->flags &= ~hasStat;
- }
- }
- return (t->visit_type = 0);
-}
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-static int
-tree_dir_next_windows(struct tree *t, const char *pattern)
-{
- const char *name;
- size_t namelen;
- int r;
-
- for (;;) {
- if (pattern != NULL) {
- t->d = FindFirstFile(pattern, &t->_findData);
- if (t->d == INVALID_DIR_HANDLE) {
- r = tree_ascend(t); /* Undo "chdir" */
- tree_pop(t);
- t->tree_errno = errno;
- t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
- return (t->visit_type);
- }
- t->findData = &t->_findData;
- pattern = NULL;
- } else if (!FindNextFile(t->d, &t->_findData)) {
- FindClose(t->d);
- t->d = INVALID_DIR_HANDLE;
- t->findData = NULL;
- return (0);
- }
- name = t->findData->cFileName;
- namelen = strlen(name);
- t->flags &= ~hasLstat;
- t->flags &= ~hasStat;
- if (name[0] == '.' && name[1] == '\0')
- continue;
- if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
- continue;
- tree_append(t, name, namelen);
- return (t->visit_type = TREE_REGULAR);
- }
-}
-#else
-static int
-tree_dir_next_posix(struct tree *t)
-{
- int r;
- const char *name;
- size_t namelen;
-
- if (t->d == NULL) {
- if ((t->d = opendir(".")) == NULL) {
- r = tree_ascend(t); /* Undo "chdir" */
- tree_pop(t);
- t->tree_errno = errno;
- t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
- return (t->visit_type);
- }
- }
- for (;;) {
- t->de = readdir(t->d);
- if (t->de == NULL) {
- closedir(t->d);
- t->d = INVALID_DIR_HANDLE;
- return (0);
- }
- name = t->de->d_name;
- namelen = D_NAMELEN(t->de);
- t->flags &= ~hasLstat;
- t->flags &= ~hasStat;
- if (name[0] == '.' && name[1] == '\0')
- continue;
- if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
- continue;
- tree_append(t, name, namelen);
- return (t->visit_type = TREE_REGULAR);
- }
-}
-#endif
-
-/*
- * Return error code.
- */
-int
-tree_errno(struct tree *t)
-{
- return (t->tree_errno);
-}
-
-/*
- * Called by the client to mark the directory just returned from
- * tree_next() as needing to be visited.
- */
-void
-tree_descend(struct tree *t)
-{
- if (t->visit_type != TREE_REGULAR)
- return;
-
- if (tree_current_is_physical_dir(t)) {
- tree_push(t, t->basename);
- t->stack->flags |= isDir;
- } else if (tree_current_is_dir(t)) {
- tree_push(t, t->basename);
- t->stack->flags |= isDirLink;
- }
-}
-
-/*
- * Get the stat() data for the entry just returned from tree_next().
- */
-const struct stat *
-tree_current_stat(struct tree *t)
-{
- if (!(t->flags & hasStat)) {
- if (stat(tree_current_access_path(t), &t->st) != 0)
- return NULL;
- t->flags |= hasStat;
- }
- return (&t->st);
-}
-
-#if defined(HAVE_WINDOWS_H) && !defined(__CYGWIN__)
-const BY_HANDLE_FILE_INFORMATION *
-tree_current_file_information(struct tree *t)
-{
- if (!(t->flags & hasFileInfo)) {
- HANDLE h = CreateFile(tree_current_access_path(t),
- 0, 0, NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
- NULL);
- if (h == INVALID_HANDLE_VALUE)
- return NULL;
- if (!GetFileInformationByHandle(h, &t->fileInfo)) {
- CloseHandle(h);
- return NULL;
- }
- CloseHandle(h);
- t->flags |= hasFileInfo;
- }
- return (&t->fileInfo);
-}
-#endif
-/*
- * Get the lstat() data for the entry just returned from tree_next().
- */
-const struct stat *
-tree_current_lstat(struct tree *t)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- return (tree_current_stat(t));
-#else
- if (!(t->flags & hasLstat)) {
- if (lstat(tree_current_access_path(t), &t->lst) != 0)
- return NULL;
- t->flags |= hasLstat;
- }
- return (&t->lst);
-#endif
-}
-
-/*
- * Test whether current entry is a dir or link to a dir.
- */
-int
-tree_current_is_dir(struct tree *t)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (t->findData)
- return (t->findData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
- if (tree_current_file_information(t))
- return (t->fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
- return (0);
-#else
- const struct stat *st;
- /*
- * If we already have lstat() info, then try some
- * cheap tests to determine if this is a dir.
- */
- if (t->flags & hasLstat) {
- /* If lstat() says it's a dir, it must be a dir. */
- if (S_ISDIR(tree_current_lstat(t)->st_mode))
- return 1;
- /* Not a dir; might be a link to a dir. */
- /* If it's not a link, then it's not a link to a dir. */
- if (!S_ISLNK(tree_current_lstat(t)->st_mode))
- return 0;
- /*
- * It's a link, but we don't know what it's a link to,
- * so we'll have to use stat().
- */
- }
-
- st = tree_current_stat(t);
- /* If we can't stat it, it's not a dir. */
- if (st == NULL)
- return 0;
- /* Use the definitive test. Hopefully this is cached. */
- return (S_ISDIR(st->st_mode));
-#endif
-}
-
-/*
- * Test whether current entry is a physical directory. Usually, we
- * already have at least one of stat() or lstat() in memory, so we
- * use tricks to try to avoid an extra trip to the disk.
- */
-int
-tree_current_is_physical_dir(struct tree *t)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (tree_current_is_physical_link(t))
- return (0);
- return (tree_current_is_dir(t));
-#else
- const struct stat *st;
-
- /*
- * If stat() says it isn't a dir, then it's not a dir.
- * If stat() data is cached, this check is free, so do it first.
- */
- if ((t->flags & hasStat)
- && (!S_ISDIR(tree_current_stat(t)->st_mode)))
- return 0;
-
- /*
- * Either stat() said it was a dir (in which case, we have
- * to determine whether it's really a link to a dir) or
- * stat() info wasn't available. So we use lstat(), which
- * hopefully is already cached.
- */
-
- st = tree_current_lstat(t);
- /* If we can't stat it, it's not a dir. */
- if (st == NULL)
- return 0;
- /* Use the definitive test. Hopefully this is cached. */
- return (S_ISDIR(st->st_mode));
-#endif
-}
-
-/*
- * Test whether current entry is a symbolic link.
- */
-int
-tree_current_is_physical_link(struct tree *t)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#ifndef IO_REPARSE_TAG_SYMLINK
-/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
-#define IO_REPARSE_TAG_SYMLINK 0xA000000CL
-#endif
- if (t->findData)
- return ((t->findData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
- && (t->findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK));
- return (0);
-#else
- const struct stat *st = tree_current_lstat(t);
- if (st == NULL)
- return 0;
- return (S_ISLNK(st->st_mode));
-#endif
-}
-
-/*
- * Return the access path for the entry just returned from tree_next().
- */
-const char *
-tree_current_access_path(struct tree *t)
-{
- return (t->basename);
-}
-
-/*
- * Return the full path for the entry just returned from tree_next().
- */
-const char *
-tree_current_path(struct tree *t)
-{
- return (t->buff);
-}
-
-/*
- * Return the length of the path for the entry just returned from tree_next().
- */
-size_t
-tree_current_pathlen(struct tree *t)
-{
- return (t->path_length);
-}
-
-/*
- * Return the nesting depth of the entry just returned from tree_next().
- */
-int
-tree_current_depth(struct tree *t)
-{
- return (t->depth);
-}
-
-/*
- * Terminate the traversal and release any resources.
- */
-void
-tree_close(struct tree *t)
-{
- /* Release anything remaining in the stack. */
- while (t->stack != NULL)
- tree_pop(t);
- free(t->buff);
- /* TODO: Ensure that premature close() resets cwd */
-#if 0
-#ifdef HAVE_FCHDIR
- if (t->initialDirFd >= 0) {
- int s = fchdir(t->initialDirFd);
- (void)s; /* UNUSED */
- close(t->initialDirFd);
- t->initialDirFd = -1;
- }
-#elif defined(_WIN32) && !defined(__CYGWIN__)
- if (t->initialDir != NULL) {
- SetCurrentDir(t->initialDir);
- free(t->initialDir);
- t->initialDir = NULL;
- }
-#endif
-#endif
- free(t);
-}
diff --git a/usr.bin/tar/tree.h b/usr.bin/tar/tree.h
deleted file mode 100644
index 3ae74fd3a185..000000000000
--- a/usr.bin/tar/tree.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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.
- *
- * $FreeBSD$
- */
-
-/*-
- * A set of routines for traversing directory trees.
- * Similar in concept to the fts library, but with a few
- * important differences:
- * * Uses less memory. In particular, fts stores an entire directory
- * in memory at a time. This package only keeps enough subdirectory
- * information in memory to track the traversal. Information
- * about non-directories is discarded as soon as possible.
- * * Supports very deep logical traversals. The fts package
- * uses "non-chdir" approach for logical traversals. This
- * package does use a chdir approach for logical traversals
- * and can therefore handle pathnames much longer than PATH_MAX.
- * * Supports deep physical traversals "out of the box."
- * Due to the memory optimizations above, there's no need to
- * limit dir names to 32k.
- */
-
-#include <sys/stat.h>
-#include <stdio.h>
-
-struct tree;
-
-/* Initiate/terminate a tree traversal. */
-struct tree *tree_open(const char * /* pathname */);
-void tree_close(struct tree *);
-
-/*
- * tree_next() returns Zero if there is no next entry, non-zero if
- * there is. Note that directories are visited three times.
- * Directories are always visited first as part of enumerating their
- * parent; that is a "regular" visit. If tree_descend() is invoked at
- * that time, the directory is added to a work list and will
- * subsequently be visited two more times: once just after descending
- * into the directory ("postdescent") and again just after ascending
- * back to the parent ("postascent").
- *
- * TREE_ERROR_DIR is returned if the descent failed (because the
- * directory couldn't be opened, for instance). This is returned
- * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
- * fatal error, but it does imply that the relevant subtree won't be
- * visited. TREE_ERROR_FATAL is returned for an error that left the
- * traversal completely hosed. Right now, this is only returned for
- * chdir() failures during ascent.
- */
-#define TREE_REGULAR 1
-#define TREE_POSTDESCENT 2
-#define TREE_POSTASCENT 3
-#define TREE_ERROR_DIR -1
-#define TREE_ERROR_FATAL -2
-
-int tree_next(struct tree *);
-
-/* Errno value associated with the last traversal error. */
-int tree_errno(struct tree *);
-
-/*
- * Request that current entry be visited. If you invoke it on every
- * directory, you'll get a physical traversal. This is ignored if the
- * current entry isn't a directory or a link to a directory. So, if
- * you invoke this on every returned path, you'll get a full logical
- * traversal.
- */
-void tree_descend(struct tree *);
-
-/*
- * Return information about the current entry.
- */
-
-/* Current depth in the traversal. */
-int tree_current_depth(struct tree *);
-
-/*
- * The current full pathname, length of the full pathname, and a name
- * that can be used to access the file. Because tree does use chdir
- * extensively, the access path is almost never the same as the full
- * current path.
- *
- * TODO: Flesh out this interface to provide other information. In
- * particular, Windows can provide file size, mode, and some permission
- * information without invoking stat() at all.
- *
- * TODO: On platforms that support it, use openat()-style operations
- * to eliminate the chdir() operations entirely while still supporting
- * arbitrarily deep traversals. This makes access_path troublesome to
- * support, of course, which means we'll need a rich enough interface
- * that clients can function without it. (In particular, we'll need
- * tree_current_open() that returns an open file descriptor.)
- *
- * TODO: Provide tree_current_archive_entry().
- */
-const char *tree_current_path(struct tree *);
-size_t tree_current_pathlen(struct tree *);
-const char *tree_current_access_path(struct tree *);
-
-/*
- * Request the lstat() or stat() data for the current path. Since the
- * tree package needs to do some of this anyway, and caches the
- * results, you should take advantage of it here if you need it rather
- * than make a redundant stat() or lstat() call of your own.
- */
-const struct stat *tree_current_stat(struct tree *);
-const struct stat *tree_current_lstat(struct tree *);
-
-/* The following functions use tricks to avoid a certain number of
- * stat()/lstat() calls. */
-/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
-int tree_current_is_physical_dir(struct tree *);
-/* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */
-int tree_current_is_physical_link(struct tree *);
-/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
-int tree_current_is_dir(struct tree *);
-
-/* For testing/debugging: Dump the internal status to the given filehandle. */
-void tree_dump(struct tree *, FILE *);
diff --git a/usr.bin/tar/util.c b/usr.bin/tar/util.c
deleted file mode 100644
index 8e8b4a5a066a..000000000000
--- a/usr.bin/tar/util.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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 "bsdtar_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h> /* Linux doesn't define mode_t, etc. in sys/stat.h. */
-#endif
-#include <ctype.h>
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#ifdef HAVE_STDARG_H
-#include <stdarg.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_WCTYPE_H
-#include <wctype.h>
-#else
-/* If we don't have wctype, we need to hack up some version of iswprint(). */
-#define iswprint isprint
-#endif
-
-#include "bsdtar.h"
-#include "err.h"
-
-static size_t bsdtar_expand_char(char *, size_t, char);
-static const char *strip_components(const char *path, int elements);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define read _read
-#endif
-
-/* TODO: Hack up a version of mbtowc for platforms with no wide
- * character support at all. I think the following might suffice,
- * but it needs careful testing.
- * #if !HAVE_MBTOWC
- * #define mbtowc(wcp, p, n) ((*wcp = *p), 1)
- * #endif
- */
-
-/*
- * Print a string, taking care with any non-printable characters.
- *
- * Note that we use a stack-allocated buffer to receive the formatted
- * string if we can. This is partly performance (avoiding a call to
- * malloc()), partly out of expedience (we have to call vsnprintf()
- * before malloc() anyway to find out how big a buffer we need; we may
- * as well point that first call at a small local buffer in case it
- * works), but mostly for safety (so we can use this to print messages
- * about out-of-memory conditions).
- */
-
-void
-safe_fprintf(FILE *f, const char *fmt, ...)
-{
- char fmtbuff_stack[256]; /* Place to format the printf() string. */
- char outbuff[256]; /* Buffer for outgoing characters. */
- char *fmtbuff_heap; /* If fmtbuff_stack is too small, we use malloc */
- char *fmtbuff; /* Pointer to fmtbuff_stack or fmtbuff_heap. */
- int fmtbuff_length;
- int length, n;
- va_list ap;
- const char *p;
- unsigned i;
- wchar_t wc;
- char try_wc;
-
- /* Use a stack-allocated buffer if we can, for speed and safety. */
- fmtbuff_heap = NULL;
- fmtbuff_length = sizeof(fmtbuff_stack);
- fmtbuff = fmtbuff_stack;
-
- /* Try formatting into the stack buffer. */
- va_start(ap, fmt);
- length = vsnprintf(fmtbuff, fmtbuff_length, fmt, ap);
- va_end(ap);
-
- /* If the result was too large, allocate a buffer on the heap. */
- if (length >= fmtbuff_length) {
- fmtbuff_length = length+1;
- fmtbuff_heap = malloc(fmtbuff_length);
-
- /* Reformat the result into the heap buffer if we can. */
- if (fmtbuff_heap != NULL) {
- fmtbuff = fmtbuff_heap;
- va_start(ap, fmt);
- length = vsnprintf(fmtbuff, fmtbuff_length, fmt, ap);
- va_end(ap);
- } else {
- /* Leave fmtbuff pointing to the truncated
- * string in fmtbuff_stack. */
- length = sizeof(fmtbuff_stack) - 1;
- }
- }
-
- /* Note: mbrtowc() has a cleaner API, but mbtowc() seems a bit
- * more portable, so we use that here instead. */
- n = mbtowc(NULL, NULL, 1); /* Reset the shift state. */
-
- /* Write data, expanding unprintable characters. */
- p = fmtbuff;
- i = 0;
- try_wc = 1;
- while (*p != '\0') {
-
- /* Convert to wide char, test if the wide
- * char is printable in the current locale. */
- if (try_wc && (n = mbtowc(&wc, p, length)) != -1) {
- length -= n;
- if (iswprint(wc) && wc != L'\\') {
- /* Printable, copy the bytes through. */
- while (n-- > 0)
- outbuff[i++] = *p++;
- } else {
- /* Not printable, format the bytes. */
- while (n-- > 0)
- i += (unsigned)bsdtar_expand_char(
- outbuff, i, *p++);
- }
- } else {
- /* After any conversion failure, don't bother
- * trying to convert the rest. */
- i += (unsigned)bsdtar_expand_char(outbuff, i, *p++);
- try_wc = 0;
- }
-
- /* If our output buffer is full, dump it and keep going. */
- if (i > (sizeof(outbuff) - 20)) {
- outbuff[i] = '\0';
- fprintf(f, "%s", outbuff);
- i = 0;
- }
- }
- outbuff[i] = '\0';
- fprintf(f, "%s", outbuff);
-
- /* If we allocated a heap-based formatting buffer, free it now. */
- if (fmtbuff_heap != NULL)
- free(fmtbuff_heap);
-}
-
-/*
- * Render an arbitrary sequence of bytes into printable ASCII characters.
- */
-static size_t
-bsdtar_expand_char(char *buff, size_t offset, char c)
-{
- size_t i = offset;
-
- if (isprint((unsigned char)c) && c != '\\')
- buff[i++] = c;
- else {
- buff[i++] = '\\';
- switch (c) {
- case '\a': buff[i++] = 'a'; break;
- case '\b': buff[i++] = 'b'; break;
- case '\f': buff[i++] = 'f'; break;
- case '\n': buff[i++] = 'n'; break;
-#if '\r' != '\n'
- /* On some platforms, \n and \r are the same. */
- case '\r': buff[i++] = 'r'; break;
-#endif
- case '\t': buff[i++] = 't'; break;
- case '\v': buff[i++] = 'v'; break;
- case '\\': buff[i++] = '\\'; break;
- default:
- sprintf(buff + i, "%03o", 0xFF & (int)c);
- i += 3;
- }
- }
-
- return (i - offset);
-}
-
-int
-yes(const char *fmt, ...)
-{
- char buff[32];
- char *p;
- ssize_t l;
-
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fprintf(stderr, " (y/N)? ");
- fflush(stderr);
-
- l = read(2, buff, sizeof(buff) - 1);
- if (l < 0) {
- fprintf(stderr, "Keyboard read failed\n");
- exit(1);
- }
- if (l == 0)
- return (0);
- buff[l] = 0;
-
- for (p = buff; *p != '\0'; p++) {
- if (isspace((unsigned char)*p))
- continue;
- switch(*p) {
- case 'y': case 'Y':
- return (1);
- case 'n': case 'N':
- return (0);
- default:
- return (0);
- }
- }
-
- return (0);
-}
-
-/*-
- * The logic here for -C <dir> attempts to avoid
- * chdir() as long as possible. For example:
- * "-C /foo -C /bar file" needs chdir("/bar") but not chdir("/foo")
- * "-C /foo -C bar file" needs chdir("/foo/bar")
- * "-C /foo -C bar /file1" does not need chdir()
- * "-C /foo -C bar /file1 file2" needs chdir("/foo/bar") before file2
- *
- * The only correct way to handle this is to record a "pending" chdir
- * request and combine multiple requests intelligently until we
- * need to process a non-absolute file. set_chdir() adds the new dir
- * to the pending list; do_chdir() actually executes any pending chdir.
- *
- * This way, programs that build tar command lines don't have to worry
- * about -C with non-existent directories; such requests will only
- * fail if the directory must be accessed.
- *
- * TODO: Make this handle Windows paths correctly.
- */
-void
-set_chdir(struct bsdtar *bsdtar, const char *newdir)
-{
- if (newdir[0] == '/') {
- /* The -C /foo -C /bar case; dump first one. */
- free(bsdtar->pending_chdir);
- bsdtar->pending_chdir = NULL;
- }
- if (bsdtar->pending_chdir == NULL)
- /* Easy case: no previously-saved dir. */
- bsdtar->pending_chdir = strdup(newdir);
- else {
- /* The -C /foo -C bar case; concatenate */
- char *old_pending = bsdtar->pending_chdir;
- size_t old_len = strlen(old_pending);
- bsdtar->pending_chdir = malloc(old_len + strlen(newdir) + 2);
- if (old_pending[old_len - 1] == '/')
- old_pending[old_len - 1] = '\0';
- if (bsdtar->pending_chdir != NULL)
- sprintf(bsdtar->pending_chdir, "%s/%s",
- old_pending, newdir);
- free(old_pending);
- }
- if (bsdtar->pending_chdir == NULL)
- lafe_errc(1, errno, "No memory");
-}
-
-void
-do_chdir(struct bsdtar *bsdtar)
-{
- if (bsdtar->pending_chdir == NULL)
- return;
-
- if (chdir(bsdtar->pending_chdir) != 0) {
- lafe_errc(1, 0, "could not chdir to '%s'\n",
- bsdtar->pending_chdir);
- }
- free(bsdtar->pending_chdir);
- bsdtar->pending_chdir = NULL;
-}
-
-static const char *
-strip_components(const char *p, int elements)
-{
- /* Skip as many elements as necessary. */
- while (elements > 0) {
- switch (*p++) {
- case '/':
-#if defined(_WIN32) && !defined(__CYGWIN__)
- case '\\': /* Support \ path sep on Windows ONLY. */
-#endif
- elements--;
- break;
- case '\0':
- /* Path is too short, skip it. */
- return (NULL);
- }
- }
-
- /* Skip any / characters. This handles short paths that have
- * additional / termination. This also handles the case where
- * the logic above stops in the middle of a duplicate //
- * sequence (which would otherwise get converted to an
- * absolute path). */
- for (;;) {
- switch (*p) {
- case '/':
-#if defined(_WIN32) && !defined(__CYGWIN__)
- case '\\': /* Support \ path sep on Windows ONLY. */
-#endif
- ++p;
- break;
- case '\0':
- return (NULL);
- default:
- return (p);
- }
- }
-}
-
-/*
- * Handle --strip-components and any future path-rewriting options.
- * Returns non-zero if the pathname should not be extracted.
- *
- * TODO: Support pax-style regex path rewrites.
- */
-int
-edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
-{
- const char *name = archive_entry_pathname(entry);
-#if HAVE_REGEX_H
- char *subst_name;
- int r;
-#endif
-
-#if HAVE_REGEX_H
- r = apply_substitution(bsdtar, name, &subst_name, 0);
- if (r == -1) {
- lafe_warnc(0, "Invalid substitution, skipping entry");
- return 1;
- }
- if (r == 1) {
- archive_entry_copy_pathname(entry, subst_name);
- if (*subst_name == '\0') {
- free(subst_name);
- return -1;
- } else
- free(subst_name);
- name = archive_entry_pathname(entry);
- }
-
- if (archive_entry_hardlink(entry)) {
- r = apply_substitution(bsdtar, archive_entry_hardlink(entry), &subst_name, 1);
- if (r == -1) {
- lafe_warnc(0, "Invalid substitution, skipping entry");
- return 1;
- }
- if (r == 1) {
- archive_entry_copy_hardlink(entry, subst_name);
- free(subst_name);
- }
- }
- if (archive_entry_symlink(entry) != NULL) {
- r = apply_substitution(bsdtar, archive_entry_symlink(entry), &subst_name, 1);
- if (r == -1) {
- lafe_warnc(0, "Invalid substitution, skipping entry");
- return 1;
- }
- if (r == 1) {
- archive_entry_copy_symlink(entry, subst_name);
- free(subst_name);
- }
- }
-#endif
-
- /* Strip leading dir names as per --strip-components option. */
- if (bsdtar->strip_components > 0) {
- const char *linkname = archive_entry_hardlink(entry);
-
- name = strip_components(name, bsdtar->strip_components);
- if (name == NULL)
- return (1);
-
- if (linkname != NULL) {
- linkname = strip_components(linkname,
- bsdtar->strip_components);
- if (linkname == NULL)
- return (1);
- archive_entry_copy_hardlink(entry, linkname);
- }
- }
-
- /* By default, don't write or restore absolute pathnames. */
- if (!bsdtar->option_absolute_paths) {
- const char *rp, *p = name;
- int slashonly = 1;
-
- /* Remove leading "//./" or "//?/" or "//?/UNC/"
- * (absolute path prefixes used by Windows API) */
- if ((p[0] == '/' || p[0] == '\\') &&
- (p[1] == '/' || p[1] == '\\') &&
- (p[2] == '.' || p[2] == '?') &&
- (p[3] == '/' || p[3] == '\\'))
- {
- if (p[2] == '?' &&
- (p[4] == 'U' || p[4] == 'u') &&
- (p[5] == 'N' || p[5] == 'n') &&
- (p[6] == 'C' || p[6] == 'c') &&
- (p[7] == '/' || p[7] == '\\'))
- p += 8;
- else
- p += 4;
- slashonly = 0;
- }
- do {
- rp = p;
- /* Remove leading drive letter from archives created
- * on Windows. */
- if (((p[0] >= 'a' && p[0] <= 'z') ||
- (p[0] >= 'A' && p[0] <= 'Z')) &&
- p[1] == ':') {
- p += 2;
- slashonly = 0;
- }
- /* Remove leading "/../", "//", etc. */
- while (p[0] == '/' || p[0] == '\\') {
- if (p[1] == '.' && p[2] == '.' &&
- (p[3] == '/' || p[3] == '\\')) {
- p += 3; /* Remove "/..", leave "/"
- * for next pass. */
- slashonly = 0;
- } else
- p += 1; /* Remove "/". */
- }
- } while (rp != p);
-
- if (p != name && !bsdtar->warned_lead_slash) {
- /* Generate a warning the first time this happens. */
- if (slashonly)
- lafe_warnc(0,
- "Removing leading '%c' from member names",
- name[0]);
- else
- lafe_warnc(0,
- "Removing leading drive letter from "
- "member names");
- bsdtar->warned_lead_slash = 1;
- }
-
- /* Special case: Stripping everything yields ".". */
- if (*p == '\0')
- name = ".";
- else
- name = p;
- } else {
- /* Strip redundant leading '/' characters. */
- while (name[0] == '/' && name[1] == '/')
- name++;
- }
-
- /* Safely replace name in archive_entry. */
- if (name != archive_entry_pathname(entry)) {
- char *q = strdup(name);
- archive_entry_copy_pathname(entry, q);
- free(q);
- }
- return (0);
-}
-
-/*
- * It would be nice to just use printf() for formatting large numbers,
- * but the compatibility problems are quite a headache. Hence the
- * following simple utility function.
- */
-const char *
-tar_i64toa(int64_t n0)
-{
- static char buff[24];
- int64_t n = n0 < 0 ? -n0 : n0;
- char *p = buff + sizeof(buff);
-
- *--p = '\0';
- do {
- *--p = '0' + (int)(n % 10);
- n /= 10;
- } while (n > 0);
- if (n0 < 0)
- *--p = '-';
- return p;
-}
-
-/*
- * Like strcmp(), but try to be a little more aware of the fact that
- * we're comparing two paths. Right now, it just handles leading
- * "./" and trailing '/' specially, so that "a/b/" == "./a/b"
- *
- * TODO: Make this better, so that "./a//b/./c/" == "a/b/c"
- * TODO: After this works, push it down into libarchive.
- * TODO: Publish the path normalization routines in libarchive so
- * that bsdtar can normalize paths and use fast strcmp() instead
- * of this.
- *
- * Note: This is currently only used within write.c, so should
- * not handle \ path separators.
- */
-
-int
-pathcmp(const char *a, const char *b)
-{
- /* Skip leading './' */
- if (a[0] == '.' && a[1] == '/' && a[2] != '\0')
- a += 2;
- if (b[0] == '.' && b[1] == '/' && b[2] != '\0')
- b += 2;
- /* Find the first difference, or return (0) if none. */
- while (*a == *b) {
- if (*a == '\0')
- return (0);
- a++;
- b++;
- }
- /*
- * If one ends in '/' and the other one doesn't,
- * they're the same.
- */
- if (a[0] == '/' && a[1] == '\0' && b[0] == '\0')
- return (0);
- if (a[0] == '\0' && b[0] == '/' && b[1] == '\0')
- return (0);
- /* They're really different, return the correct sign. */
- return (*(const unsigned char *)a - *(const unsigned char *)b);
-}
diff --git a/usr.bin/tar/write.c b/usr.bin/tar/write.c
deleted file mode 100644
index 32e43c60e680..000000000000
--- a/usr.bin/tar/write.c
+++ /dev/null
@@ -1,1159 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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 "bsdtar_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ATTR_XATTR_H
-#include <attr/xattr.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_LINUX_FS_H
-#include <linux/fs.h> /* for Linux file flags */
-#endif
-/*
- * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
- * As the include guards don't agree, the order of include is important.
- */
-#ifdef HAVE_LINUX_EXT2_FS_H
-#include <linux/ext2_fs.h> /* for Linux file flags */
-#endif
-#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
-/* This header exists but is broken on Cygwin. */
-#include <ext2fs/ext2_fs.h>
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "bsdtar.h"
-#include "err.h"
-#include "line_reader.h"
-#include "tree.h"
-
-/* Size of buffer for holding file data prior to writing. */
-#define FILEDATABUFLEN 65536
-
-/* Fixed size of uname/gname caches. */
-#define name_cache_size 101
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-static const char * const NO_NAME = "(noname)";
-
-struct archive_dir_entry {
- struct archive_dir_entry *next;
- time_t mtime_sec;
- int mtime_nsec;
- char *name;
-};
-
-struct archive_dir {
- struct archive_dir_entry *head, *tail;
-};
-
-struct name_cache {
- int probes;
- int hits;
- size_t size;
- struct {
- id_t id;
- const char *name;
- } cache[name_cache_size];
-};
-
-static void add_dir_list(struct bsdtar *bsdtar, const char *path,
- time_t mtime_sec, int mtime_nsec);
-static int append_archive(struct bsdtar *, struct archive *,
- struct archive *ina);
-static int append_archive_filename(struct bsdtar *,
- struct archive *, const char *fname);
-static void archive_names_from_file(struct bsdtar *bsdtar,
- struct archive *a);
-static int copy_file_data(struct bsdtar *, struct archive *a,
- struct archive *ina, struct archive_entry *);
-static int new_enough(struct bsdtar *, const char *path,
- const struct stat *);
-static void report_write(struct bsdtar *, struct archive *,
- struct archive_entry *, int64_t progress);
-static void test_for_append(struct bsdtar *);
-static void write_archive(struct archive *, struct bsdtar *);
-static void write_entry_backend(struct bsdtar *, struct archive *,
- struct archive_entry *);
-static int write_file_data(struct bsdtar *, struct archive *,
- struct archive_entry *, int fd);
-static void write_hierarchy(struct bsdtar *, struct archive *,
- const char *);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-/* Not a full lseek() emulation, but enough for our needs here. */
-static int
-seek_file(int fd, int64_t offset, int whence)
-{
- LARGE_INTEGER distance;
- (void)whence; /* UNUSED */
- distance.QuadPart = offset;
- return (SetFilePointerEx((HANDLE)_get_osfhandle(fd),
- distance, NULL, FILE_BEGIN) ? 1 : -1);
-}
-#define open _open
-#define close _close
-#define read _read
-#define lseek seek_file
-#endif
-
-void
-tar_mode_c(struct bsdtar *bsdtar)
-{
- struct archive *a;
- int r;
-
- if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL)
- lafe_errc(1, 0, "no files or directories specified");
-
- a = archive_write_new();
-
- /* Support any format that the library supports. */
- if (bsdtar->create_format == NULL) {
- r = archive_write_set_format_pax_restricted(a);
- bsdtar->create_format = "pax restricted";
- } else {
- r = archive_write_set_format_by_name(a, bsdtar->create_format);
- }
- if (r != ARCHIVE_OK) {
- fprintf(stderr, "Can't use format %s: %s\n",
- bsdtar->create_format,
- archive_error_string(a));
- usage();
- }
-
- /*
- * If user explicitly set the block size, then assume they
- * want the last block padded as well. Otherwise, use the
- * default block size and accept archive_write_open_file()'s
- * default padding decisions.
- */
- if (bsdtar->bytes_per_block != 0) {
- archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
- archive_write_set_bytes_in_last_block(a,
- bsdtar->bytes_per_block);
- } else
- archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK);
-
- if (bsdtar->compress_program) {
- archive_write_set_compression_program(a, bsdtar->compress_program);
- } else {
- switch (bsdtar->create_compression) {
- case 0:
- r = archive_write_set_compression_none(a);
- break;
- case 'j': case 'y':
- r = archive_write_set_compression_bzip2(a);
- break;
- case 'J':
- r = archive_write_set_compression_xz(a);
- break;
- case OPTION_LZMA:
- r = archive_write_set_compression_lzma(a);
- break;
- case 'z':
- r = archive_write_set_compression_gzip(a);
- break;
- case 'Z':
- r = archive_write_set_compression_compress(a);
- break;
- default:
- lafe_errc(1, 0,
- "Unrecognized compression option -%c",
- bsdtar->create_compression);
- }
- if (r != ARCHIVE_OK) {
- lafe_errc(1, 0,
- "Unsupported compression option -%c",
- bsdtar->create_compression);
- }
- }
-
- if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options))
- lafe_errc(1, 0, "%s", archive_error_string(a));
- if (ARCHIVE_OK != archive_write_open_file(a, bsdtar->filename))
- lafe_errc(1, 0, "%s", archive_error_string(a));
- write_archive(a, bsdtar);
-}
-
-/*
- * Same as 'c', except we only support tar or empty formats in
- * uncompressed files on disk.
- */
-void
-tar_mode_r(struct bsdtar *bsdtar)
-{
- int64_t end_offset;
- int format;
- struct archive *a;
- struct archive_entry *entry;
- int r;
-
- /* Sanity-test some arguments and the file. */
- test_for_append(bsdtar);
-
- format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
-
-#if defined(__BORLANDC__)
- bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY);
-#else
- bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY, 0666);
-#endif
- if (bsdtar->fd < 0)
- lafe_errc(1, errno,
- "Cannot open %s", bsdtar->filename);
-
- a = archive_read_new();
- archive_read_support_compression_all(a);
- archive_read_support_format_tar(a);
- archive_read_support_format_gnutar(a);
- r = archive_read_open_fd(a, bsdtar->fd, 10240);
- if (r != ARCHIVE_OK)
- lafe_errc(1, archive_errno(a),
- "Can't read archive %s: %s", bsdtar->filename,
- archive_error_string(a));
- while (0 == archive_read_next_header(a, &entry)) {
- if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) {
- archive_read_finish(a);
- close(bsdtar->fd);
- lafe_errc(1, 0,
- "Cannot append to compressed archive.");
- }
- /* Keep going until we hit end-of-archive */
- format = archive_format(a);
- }
-
- end_offset = archive_read_header_position(a);
- archive_read_finish(a);
-
- /* Re-open archive for writing */
- a = archive_write_new();
- archive_write_set_compression_none(a);
- /*
- * Set the format to be used for writing. To allow people to
- * extend empty files, we need to allow them to specify the format,
- * which opens the possibility that they will specify a format that
- * doesn't match the existing format. Hence, the following bit
- * of arcane ugliness.
- */
-
- if (bsdtar->create_format != NULL) {
- /* If the user requested a format, use that, but ... */
- archive_write_set_format_by_name(a,
- bsdtar->create_format);
- /* ... complain if it's not compatible. */
- format &= ARCHIVE_FORMAT_BASE_MASK;
- if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK)
- && format != ARCHIVE_FORMAT_EMPTY) {
- lafe_errc(1, 0,
- "Format %s is incompatible with the archive %s.",
- bsdtar->create_format, bsdtar->filename);
- }
- } else {
- /*
- * Just preserve the current format, with a little care
- * for formats that libarchive can't write.
- */
- if (format == ARCHIVE_FORMAT_TAR_GNUTAR)
- /* TODO: When gtar supports pax, use pax restricted. */
- format = ARCHIVE_FORMAT_TAR_USTAR;
- if (format == ARCHIVE_FORMAT_EMPTY)
- format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
- archive_write_set_format(a, format);
- }
- if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0)
- lafe_errc(1, errno, "Could not seek to archive end");
- if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options))
- lafe_errc(1, 0, "%s", archive_error_string(a));
- if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd))
- lafe_errc(1, 0, "%s", archive_error_string(a));
-
- write_archive(a, bsdtar); /* XXX check return val XXX */
-
- close(bsdtar->fd);
- bsdtar->fd = -1;
-}
-
-void
-tar_mode_u(struct bsdtar *bsdtar)
-{
- int64_t end_offset;
- struct archive *a;
- struct archive_entry *entry;
- int format;
- struct archive_dir_entry *p;
- struct archive_dir archive_dir;
-
- bsdtar->archive_dir = &archive_dir;
- memset(&archive_dir, 0, sizeof(archive_dir));
-
- format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
-
- /* Sanity-test some arguments and the file. */
- test_for_append(bsdtar);
-
- bsdtar->fd = open(bsdtar->filename, O_RDWR | O_BINARY);
- if (bsdtar->fd < 0)
- lafe_errc(1, errno,
- "Cannot open %s", bsdtar->filename);
-
- a = archive_read_new();
- archive_read_support_compression_all(a);
- archive_read_support_format_tar(a);
- archive_read_support_format_gnutar(a);
- if (archive_read_open_fd(a, bsdtar->fd,
- bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block :
- DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
- lafe_errc(1, 0,
- "Can't open %s: %s", bsdtar->filename,
- archive_error_string(a));
- }
-
- /* Build a list of all entries and their recorded mod times. */
- while (0 == archive_read_next_header(a, &entry)) {
- if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) {
- archive_read_finish(a);
- close(bsdtar->fd);
- lafe_errc(1, 0,
- "Cannot append to compressed archive.");
- }
- add_dir_list(bsdtar, archive_entry_pathname(entry),
- archive_entry_mtime(entry),
- archive_entry_mtime_nsec(entry));
- /* Record the last format determination we see */
- format = archive_format(a);
- /* Keep going until we hit end-of-archive */
- }
-
- end_offset = archive_read_header_position(a);
- archive_read_finish(a);
-
- /* Re-open archive for writing. */
- a = archive_write_new();
- archive_write_set_compression_none(a);
- /*
- * Set format to same one auto-detected above, except that
- * we don't write GNU tar format, so use ustar instead.
- */
- if (format == ARCHIVE_FORMAT_TAR_GNUTAR)
- format = ARCHIVE_FORMAT_TAR_USTAR;
- archive_write_set_format(a, format);
- if (bsdtar->bytes_per_block != 0) {
- archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
- archive_write_set_bytes_in_last_block(a,
- bsdtar->bytes_per_block);
- } else
- archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK);
- if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0)
- lafe_errc(1, errno, "Could not seek to archive end");
- if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options))
- lafe_errc(1, 0, "%s", archive_error_string(a));
- if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd))
- lafe_errc(1, 0, "%s", archive_error_string(a));
-
- write_archive(a, bsdtar);
-
- close(bsdtar->fd);
- bsdtar->fd = -1;
-
- while (bsdtar->archive_dir->head != NULL) {
- p = bsdtar->archive_dir->head->next;
- free(bsdtar->archive_dir->head->name);
- free(bsdtar->archive_dir->head);
- bsdtar->archive_dir->head = p;
- }
- bsdtar->archive_dir->tail = NULL;
-}
-
-
-/*
- * Write user-specified files/dirs to opened archive.
- */
-static void
-write_archive(struct archive *a, struct bsdtar *bsdtar)
-{
- const char *arg;
- struct archive_entry *entry, *sparse_entry;
-
- /* Allocate a buffer for file data. */
- if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL)
- lafe_errc(1, 0, "cannot allocate memory");
-
- if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL)
- lafe_errc(1, 0, "cannot create link resolver");
- archive_entry_linkresolver_set_strategy(bsdtar->resolver,
- archive_format(a));
- if ((bsdtar->diskreader = archive_read_disk_new()) == NULL)
- lafe_errc(1, 0, "Cannot create read_disk object");
- archive_read_disk_set_standard_lookup(bsdtar->diskreader);
-
- if (bsdtar->names_from_file != NULL)
- archive_names_from_file(bsdtar, a);
-
- while (*bsdtar->argv) {
- arg = *bsdtar->argv;
- if (arg[0] == '-' && arg[1] == 'C') {
- arg += 2;
- if (*arg == '\0') {
- bsdtar->argv++;
- arg = *bsdtar->argv;
- if (arg == NULL) {
- lafe_warnc(0, "%s",
- "Missing argument for -C");
- bsdtar->return_value = 1;
- goto cleanup;
- }
- }
- set_chdir(bsdtar, arg);
- } else {
- if (*arg != '/' && (arg[0] != '@' || arg[1] != '/'))
- do_chdir(bsdtar); /* Handle a deferred -C */
- if (*arg == '@') {
- if (append_archive_filename(bsdtar, a,
- arg + 1) != 0)
- break;
- } else
- write_hierarchy(bsdtar, a, arg);
- }
- bsdtar->argv++;
- }
-
- entry = NULL;
- archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
- while (entry != NULL) {
- write_entry_backend(bsdtar, a, entry);
- archive_entry_free(entry);
- entry = NULL;
- archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
- }
-
- if (archive_write_close(a)) {
- lafe_warnc(0, "%s", archive_error_string(a));
- bsdtar->return_value = 1;
- }
-
-cleanup:
- /* Free file data buffer. */
- free(bsdtar->buff);
- archive_entry_linkresolver_free(bsdtar->resolver);
- bsdtar->resolver = NULL;
- archive_read_finish(bsdtar->diskreader);
- bsdtar->diskreader = NULL;
-
- if (bsdtar->option_totals) {
- fprintf(stderr, "Total bytes written: %s\n",
- tar_i64toa(archive_position_compressed(a)));
- }
-
- archive_write_finish(a);
-}
-
-/*
- * Archive names specified in file.
- *
- * Unless --null was specified, a line containing exactly "-C" will
- * cause the next line to be a directory to pass to chdir(). If
- * --null is specified, then a line "-C" is just another filename.
- */
-static void
-archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
-{
- struct lafe_line_reader *lr;
- const char *line;
-
- bsdtar->next_line_is_dir = 0;
-
- lr = lafe_line_reader(bsdtar->names_from_file, bsdtar->option_null);
- while ((line = lafe_line_reader_next(lr)) != NULL) {
- if (bsdtar->next_line_is_dir) {
- set_chdir(bsdtar, line);
- bsdtar->next_line_is_dir = 0;
- } else if (!bsdtar->option_null && strcmp(line, "-C") == 0)
- bsdtar->next_line_is_dir = 1;
- else {
- if (*line != '/')
- do_chdir(bsdtar); /* Handle a deferred -C */
- write_hierarchy(bsdtar, a, line);
- }
- }
- lafe_line_reader_free(lr);
- if (bsdtar->next_line_is_dir)
- lafe_errc(1, errno,
- "Unexpected end of filename list; "
- "directory expected after -C");
-}
-
-/*
- * Copy from specified archive to current archive. Returns non-zero
- * for write errors (which force us to terminate the entire archiving
- * operation). If there are errors reading the input archive, we set
- * bsdtar->return_value but return zero, so the overall archiving
- * operation will complete and return non-zero.
- */
-static int
-append_archive_filename(struct bsdtar *bsdtar, struct archive *a,
- const char *filename)
-{
- struct archive *ina;
- int rc;
-
- if (strcmp(filename, "-") == 0)
- filename = NULL; /* Library uses NULL for stdio. */
-
- ina = archive_read_new();
- archive_read_support_format_all(ina);
- archive_read_support_compression_all(ina);
- if (archive_read_open_file(ina, filename, 10240)) {
- lafe_warnc(0, "%s", archive_error_string(ina));
- bsdtar->return_value = 1;
- return (0);
- }
-
- rc = append_archive(bsdtar, a, ina);
-
- if (rc != ARCHIVE_OK) {
- lafe_warnc(0, "Error reading archive %s: %s",
- filename, archive_error_string(ina));
- bsdtar->return_value = 1;
- }
- archive_read_finish(ina);
-
- return (rc);
-}
-
-static int
-append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
-{
- struct archive_entry *in_entry;
- int e;
-
- while (0 == archive_read_next_header(ina, &in_entry)) {
- if (!new_enough(bsdtar, archive_entry_pathname(in_entry),
- archive_entry_stat(in_entry)))
- continue;
- if (lafe_excluded(bsdtar->matching, archive_entry_pathname(in_entry)))
- continue;
- if (bsdtar->option_interactive &&
- !yes("copy '%s'", archive_entry_pathname(in_entry)))
- continue;
- if (bsdtar->verbose)
- safe_fprintf(stderr, "a %s",
- archive_entry_pathname(in_entry));
- if (need_report())
- report_write(bsdtar, a, in_entry, 0);
-
- e = archive_write_header(a, in_entry);
- if (e != ARCHIVE_OK) {
- if (!bsdtar->verbose)
- lafe_warnc(0, "%s: %s",
- archive_entry_pathname(in_entry),
- archive_error_string(a));
- else
- fprintf(stderr, ": %s", archive_error_string(a));
- }
- if (e == ARCHIVE_FATAL)
- exit(1);
-
- if (e >= ARCHIVE_WARN) {
- if (archive_entry_size(in_entry) == 0)
- archive_read_data_skip(ina);
- else if (copy_file_data(bsdtar, a, ina, in_entry))
- exit(1);
- }
-
- if (bsdtar->verbose)
- fprintf(stderr, "\n");
- }
-
- /* Note: If we got here, we saw no write errors, so return success. */
- return (0);
-}
-
-/* Helper function to copy data between archives. */
-static int
-copy_file_data(struct bsdtar *bsdtar, struct archive *a,
- struct archive *ina, struct archive_entry *entry)
-{
- ssize_t bytes_read;
- ssize_t bytes_written;
- int64_t progress = 0;
-
- bytes_read = archive_read_data(ina, bsdtar->buff, FILEDATABUFLEN);
- while (bytes_read > 0) {
- if (need_report())
- report_write(bsdtar, a, entry, progress);
-
- bytes_written = archive_write_data(a, bsdtar->buff,
- bytes_read);
- if (bytes_written < bytes_read) {
- lafe_warnc(0, "%s", archive_error_string(a));
- return (-1);
- }
- progress += bytes_written;
- bytes_read = archive_read_data(ina, bsdtar->buff,
- FILEDATABUFLEN);
- }
-
- return (0);
-}
-
-/*
- * Add the file or dir hierarchy named by 'path' to the archive
- */
-static void
-write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
-{
- struct archive_entry *entry = NULL, *spare_entry = NULL;
- struct tree *tree;
- char symlink_mode = bsdtar->symlink_mode;
- dev_t first_dev = 0;
- int dev_recorded = 0;
- int tree_ret;
-
- tree = tree_open(path);
-
- if (!tree) {
- lafe_warnc(errno, "%s: Cannot open", path);
- bsdtar->return_value = 1;
- return;
- }
-
- while ((tree_ret = tree_next(tree)) != 0) {
- int r;
- const char *name = tree_current_path(tree);
- const struct stat *st = NULL; /* info to use for this entry */
- const struct stat *lst = NULL; /* lstat() information */
- int descend;
-
- if (tree_ret == TREE_ERROR_FATAL)
- lafe_errc(1, tree_errno(tree),
- "%s: Unable to continue traversing directory tree",
- name);
- if (tree_ret == TREE_ERROR_DIR) {
- lafe_warnc(errno,
- "%s: Couldn't visit directory", name);
- bsdtar->return_value = 1;
- }
- if (tree_ret != TREE_REGULAR)
- continue;
-
- /*
- * If this file/dir is excluded by a filename
- * pattern, skip it.
- */
- if (lafe_excluded(bsdtar->matching, name))
- continue;
-
- /*
- * Get lstat() info from the tree library.
- */
- lst = tree_current_lstat(tree);
- if (lst == NULL) {
- /* Couldn't lstat(); must not exist. */
- lafe_warnc(errno, "%s: Cannot stat", name);
- /* Return error if files disappear during traverse. */
- bsdtar->return_value = 1;
- continue;
- }
-
- /*
- * Distinguish 'L'/'P'/'H' symlink following.
- */
- switch(symlink_mode) {
- case 'H':
- /* 'H': After the first item, rest like 'P'. */
- symlink_mode = 'P';
- /* 'H': First item (from command line) like 'L'. */
- /* FALLTHROUGH */
- case 'L':
- /* 'L': Do descend through a symlink to dir. */
- descend = tree_current_is_dir(tree);
- /* 'L': Follow symlinks to files. */
- archive_read_disk_set_symlink_logical(bsdtar->diskreader);
- /* 'L': Archive symlinks as targets, if we can. */
- st = tree_current_stat(tree);
- if (st != NULL)
- break;
- /* If stat fails, we have a broken symlink;
- * in that case, don't follow the link. */
- /* FALLTHROUGH */
- default:
- /* 'P': Don't descend through a symlink to dir. */
- descend = tree_current_is_physical_dir(tree);
- /* 'P': Don't follow symlinks to files. */
- archive_read_disk_set_symlink_physical(bsdtar->diskreader);
- /* 'P': Archive symlinks as symlinks. */
- st = lst;
- break;
- }
-
- if (bsdtar->option_no_subdirs)
- descend = 0;
-
- /*
- * Are we about to cross to a new filesystem?
- */
- if (!dev_recorded) {
- /* This is the initial file system. */
- first_dev = lst->st_dev;
- dev_recorded = 1;
- } else if (lst->st_dev == first_dev) {
- /* The starting file system is always acceptable. */
- } else if (descend == 0) {
- /* We're not descending, so no need to check. */
- } else if (bsdtar->option_dont_traverse_mounts) {
- descend = 0;
- } else {
- /* We're prepared to cross a mount point. */
-
- /* XXX TODO: check whether this filesystem is
- * synthetic and/or local. Add a new
- * --local-only option to skip non-local
- * filesystems. Skip synthetic filesystems
- * regardless.
- *
- * The results should be cached, since
- * tree.c doesn't usually visit a directory
- * and the directory contents together. A simple
- * move-to-front list should perform quite well.
- *
- * This is going to be heavily OS dependent:
- * FreeBSD's statfs() in conjunction with getvfsbyname()
- * provides all of this; NetBSD's statvfs() does
- * most of it; other systems will vary.
- */
- }
-
- /*
- * In -u mode, check that the file is newer than what's
- * already in the archive; in all modes, obey --newerXXX flags.
- */
- if (!new_enough(bsdtar, name, st)) {
- if (!descend)
- continue;
- if (bsdtar->option_interactive &&
- !yes("add '%s'", name))
- continue;
- tree_descend(tree);
- continue;
- }
-
- archive_entry_free(entry);
- entry = archive_entry_new();
-
- archive_entry_set_pathname(entry, name);
- archive_entry_copy_sourcepath(entry,
- tree_current_access_path(tree));
-
- /* Populate the archive_entry with metadata from the disk. */
- /* XXX TODO: Arrange to open a regular file before
- * calling this so we can pass in an fd and shorten
- * the race to query metadata. The linkify dance
- * makes this more complex than it might sound. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* TODO: tree.c uses stat(), which is badly broken
- * on Windows. To fix this, we should
- * deprecate tree_current_stat() and provide a new
- * call tree_populate_entry(t, entry). This call
- * would use stat() internally on POSIX and
- * GetInfoByFileHandle() internally on Windows.
- * This would be another step towards a tree-walker
- * that can be integrated deep into libarchive.
- * For now, just set st to NULL on Windows;
- * archive_read_disk_entry_from_file() should
- * be smart enough to use platform-appropriate
- * ways to probe file information.
- */
- st = NULL;
-#endif
- r = archive_read_disk_entry_from_file(bsdtar->diskreader,
- entry, -1, st);
- if (r != ARCHIVE_OK)
- lafe_warnc(archive_errno(bsdtar->diskreader),
- "%s", archive_error_string(bsdtar->diskreader));
- if (r < ARCHIVE_WARN)
- continue;
-
- /* XXX TODO: Just use flag data from entry; avoid the
- * duplicate check here. */
-
- /*
- * If this file/dir is flagged "nodump" and we're
- * honoring such flags, skip this file/dir.
- */
-#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
- /* BSD systems store flags in struct stat */
- if (bsdtar->option_honor_nodump &&
- (lst->st_flags & UF_NODUMP))
- continue;
-#endif
-
-#if defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL)
- /* Linux uses ioctl to read flags. */
- if (bsdtar->option_honor_nodump) {
- int fd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY);
- if (fd >= 0) {
- unsigned long fflags;
- int r = ioctl(fd, EXT2_IOC_GETFLAGS, &fflags);
- close(fd);
- if (r >= 0 && (fflags & EXT2_NODUMP_FL))
- continue;
- }
- }
-#endif
-
- /*
- * If the user vetoes this file/directory, skip it.
- * We want this to be fairly late; if some other
- * check would veto this file, we shouldn't bother
- * the user with it.
- */
- if (bsdtar->option_interactive &&
- !yes("add '%s'", name))
- continue;
-
- if (descend)
- tree_descend(tree);
-
- /*
- * Rewrite the pathname to be archived. If rewrite
- * fails, skip the entry.
- */
- if (edit_pathname(bsdtar, entry))
- continue;
-
- /* Display entry as we process it.
- * This format is required by SUSv2. */
- if (bsdtar->verbose)
- safe_fprintf(stderr, "a %s",
- archive_entry_pathname(entry));
-
- /* Non-regular files get archived with zero size. */
- if (archive_entry_filetype(entry) != AE_IFREG)
- archive_entry_set_size(entry, 0);
-
- archive_entry_linkify(bsdtar->resolver, &entry, &spare_entry);
-
- while (entry != NULL) {
- write_entry_backend(bsdtar, a, entry);
- archive_entry_free(entry);
- entry = spare_entry;
- spare_entry = NULL;
- }
-
- if (bsdtar->verbose)
- fprintf(stderr, "\n");
- }
- archive_entry_free(entry);
- tree_close(tree);
-}
-
-/*
- * Backend for write_entry.
- */
-static void
-write_entry_backend(struct bsdtar *bsdtar, struct archive *a,
- struct archive_entry *entry)
-{
- int fd = -1;
- int e;
-
- if (archive_entry_size(entry) > 0) {
- const char *pathname = archive_entry_sourcepath(entry);
- fd = open(pathname, O_RDONLY | O_BINARY);
- if (fd == -1) {
- bsdtar->return_value = 1;
- if (!bsdtar->verbose)
- lafe_warnc(errno,
- "%s: could not open file", pathname);
- else
- fprintf(stderr, ": %s", strerror(errno));
- return;
- }
- }
-
- e = archive_write_header(a, entry);
- if (e != ARCHIVE_OK) {
- if (!bsdtar->verbose)
- lafe_warnc(0, "%s: %s",
- archive_entry_pathname(entry),
- archive_error_string(a));
- else
- fprintf(stderr, ": %s", archive_error_string(a));
- }
-
- if (e == ARCHIVE_FATAL)
- exit(1);
-
- /*
- * If we opened a file earlier, write it out now. Note that
- * the format handler might have reset the size field to zero
- * to inform us that the archive body won't get stored. In
- * that case, just skip the write.
- */
- if (e >= ARCHIVE_WARN && fd >= 0 && archive_entry_size(entry) > 0) {
- if (write_file_data(bsdtar, a, entry, fd))
- exit(1);
- }
-
- /*
- * If we opened a file, close it now even if there was an error
- * which made us decide not to write the archive body.
- */
- if (fd >= 0)
- close(fd);
-}
-
-static void
-report_write(struct bsdtar *bsdtar, struct archive *a,
- struct archive_entry *entry, int64_t progress)
-{
- uint64_t comp, uncomp;
- int compression;
-
- if (bsdtar->verbose)
- fprintf(stderr, "\n");
- comp = archive_position_compressed(a);
- uncomp = archive_position_uncompressed(a);
- fprintf(stderr, "In: %d files, %s bytes;",
- archive_file_count(a), tar_i64toa(uncomp));
- if (comp > uncomp)
- compression = 0;
- else
- compression = (int)((uncomp - comp) * 100 / uncomp);
- fprintf(stderr,
- " Out: %s bytes, compression %d%%\n",
- tar_i64toa(comp), compression);
- /* Can't have two calls to tar_i64toa() pending, so split the output. */
- safe_fprintf(stderr, "Current: %s (%s",
- archive_entry_pathname(entry),
- tar_i64toa(progress));
- fprintf(stderr, "/%s bytes)\n",
- tar_i64toa(archive_entry_size(entry)));
-}
-
-
-/* Helper function to copy file to archive. */
-static int
-write_file_data(struct bsdtar *bsdtar, struct archive *a,
- struct archive_entry *entry, int fd)
-{
- ssize_t bytes_read;
- ssize_t bytes_written;
- int64_t progress = 0;
-
- bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN);
- while (bytes_read > 0) {
- if (need_report())
- report_write(bsdtar, a, entry, progress);
-
- bytes_written = archive_write_data(a, bsdtar->buff,
- bytes_read);
- if (bytes_written < 0) {
- /* Write failed; this is bad */
- lafe_warnc(0, "%s", archive_error_string(a));
- return (-1);
- }
- if (bytes_written < bytes_read) {
- /* Write was truncated; warn but continue. */
- lafe_warnc(0,
- "%s: Truncated write; file may have grown while being archived.",
- archive_entry_pathname(entry));
- return (0);
- }
- progress += bytes_written;
- bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN);
- }
- if (bytes_read < 0) {
- lafe_warnc(errno,
- "%s: Read error",
- archive_entry_pathname(entry));
- bsdtar->return_value = 1;
- }
- return 0;
-}
-
-/*
- * Test if the specified file is new enough to include in the archive.
- */
-static int
-new_enough(struct bsdtar *bsdtar, const char *path, const struct stat *st)
-{
- struct archive_dir_entry *p;
-
- /*
- * If this file/dir is excluded by a time comparison, skip it.
- */
- if (bsdtar->newer_ctime_sec > 0) {
- if (st->st_ctime < bsdtar->newer_ctime_sec)
- return (0); /* Too old, skip it. */
- if (st->st_ctime == bsdtar->newer_ctime_sec
- && ARCHIVE_STAT_CTIME_NANOS(st)
- <= bsdtar->newer_ctime_nsec)
- return (0); /* Too old, skip it. */
- }
- if (bsdtar->newer_mtime_sec > 0) {
- if (st->st_mtime < bsdtar->newer_mtime_sec)
- return (0); /* Too old, skip it. */
- if (st->st_mtime == bsdtar->newer_mtime_sec
- && ARCHIVE_STAT_MTIME_NANOS(st)
- <= bsdtar->newer_mtime_nsec)
- return (0); /* Too old, skip it. */
- }
-
- /*
- * In -u mode, we only write an entry if it's newer than
- * what was already in the archive.
- */
- if (bsdtar->archive_dir != NULL &&
- bsdtar->archive_dir->head != NULL) {
- for (p = bsdtar->archive_dir->head; p != NULL; p = p->next) {
- if (pathcmp(path, p->name)==0)
- return (p->mtime_sec < st->st_mtime ||
- (p->mtime_sec == st->st_mtime &&
- p->mtime_nsec
- < ARCHIVE_STAT_MTIME_NANOS(st)));
- }
- }
-
- /* If the file wasn't rejected, include it. */
- return (1);
-}
-
-/*
- * Add an entry to the dir list for 'u' mode.
- *
- * XXX TODO: Make this fast.
- */
-static void
-add_dir_list(struct bsdtar *bsdtar, const char *path,
- time_t mtime_sec, int mtime_nsec)
-{
- struct archive_dir_entry *p;
-
- /*
- * Search entire list to see if this file has appeared before.
- * If it has, override the timestamp data.
- */
- p = bsdtar->archive_dir->head;
- while (p != NULL) {
- if (strcmp(path, p->name)==0) {
- p->mtime_sec = mtime_sec;
- p->mtime_nsec = mtime_nsec;
- return;
- }
- p = p->next;
- }
-
- p = malloc(sizeof(*p));
- if (p == NULL)
- lafe_errc(1, ENOMEM, "Can't read archive directory");
-
- p->name = strdup(path);
- if (p->name == NULL)
- lafe_errc(1, ENOMEM, "Can't read archive directory");
- p->mtime_sec = mtime_sec;
- p->mtime_nsec = mtime_nsec;
- p->next = NULL;
- if (bsdtar->archive_dir->tail == NULL) {
- bsdtar->archive_dir->head = bsdtar->archive_dir->tail = p;
- } else {
- bsdtar->archive_dir->tail->next = p;
- bsdtar->archive_dir->tail = p;
- }
-}
-
-static void
-test_for_append(struct bsdtar *bsdtar)
-{
- struct stat s;
-
- if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL)
- lafe_errc(1, 0, "no files or directories specified");
- if (bsdtar->filename == NULL)
- lafe_errc(1, 0, "Cannot append to stdout.");
-
- if (bsdtar->create_compression != 0)
- lafe_errc(1, 0,
- "Cannot append to %s with compression", bsdtar->filename);
-
- if (stat(bsdtar->filename, &s) != 0)
- return;
-
- if (!S_ISREG(s.st_mode) && !S_ISBLK(s.st_mode))
- lafe_errc(1, 0,
- "Cannot append to %s: not a regular file.",
- bsdtar->filename);
-
-/* Is this an appropriate check here on Windows? */
-/*
- if (GetFileType(handle) != FILE_TYPE_DISK)
- lafe_errc(1, 0, "Cannot append");
-*/
-
-}