new command: bsdtar.
This commit is contained in:
parent
470ab03b86
commit
ba759ef03e
73 changed files with 15490 additions and 1 deletions
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
SUBDIR= aal add_route adduser advent arp ash at autil awk \
|
SUBDIR= aal add_route adduser advent arp ash at autil awk \
|
||||||
backup badblocks banner basename bigmake binpackage \
|
backup badblocks banner basename bigmake binpackage \
|
||||||
binpackages binsizes bzip2 bzip2recover cal calendar \
|
binpackages binsizes bsdtar bzip2 bzip2recover cal calendar \
|
||||||
cat cawf cd cdprobe checkhier chmem \
|
cat cawf cd cdprobe checkhier chmem \
|
||||||
chmod chown chroot ci cksum cleantmp clear cmp co \
|
chmod chown chroot ci cksum cleantmp clear cmp co \
|
||||||
comm compress cp crc cron crontab cut datasizes date \
|
comm compress cp crc cron crontab cut datasizes date \
|
||||||
|
|
19
commands/bsdtar/Makefile
Normal file
19
commands/bsdtar/Makefile
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
PROG= bsdtar
|
||||||
|
SRCS= bsdtar.c \
|
||||||
|
cmdline.c \
|
||||||
|
getdate.c \
|
||||||
|
read.c \
|
||||||
|
subst.c \
|
||||||
|
tree.c \
|
||||||
|
util.c \
|
||||||
|
write.c
|
||||||
|
.include "${.CURDIR}/libarchive_fe/Makefile.inc"
|
||||||
|
|
||||||
|
DPADD+= ${LIBARCHIVE} ${LIBZ} ${LIBBZ2}
|
||||||
|
LDADD+= -larchive -lbz2 -lz
|
||||||
|
CPPFLAGS+= -DHAVE_CONFIG_H
|
||||||
|
CPPFLAGS+= -I${.CURDIR} -I${.CURDIR}/libarchive_fe
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
921
commands/bsdtar/bsdtar.1
Normal file
921
commands/bsdtar/bsdtar.1
Normal file
|
@ -0,0 +1,921 @@
|
||||||
|
.\" 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: src/usr.bin/tar/bsdtar.1,v 1.46 2008/12/06 07:37:55 kientzle Exp $
|
||||||
|
.\"
|
||||||
|
.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,
|
||||||
|
and ISO 9660 cdrom images and can create tar, pax, cpio, ar,
|
||||||
|
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.
|
||||||
|
.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.
|
||||||
|
.It Fl t
|
||||||
|
List archive contents to stdout.
|
||||||
|
.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.
|
||||||
|
.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.
|
||||||
|
.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 -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 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 -check-links
|
||||||
|
(c and r modes only)
|
||||||
|
Issue a warning message unless all links to each file are archived.
|
||||||
|
.It Fl -chroot
|
||||||
|
(x mode only)
|
||||||
|
.Fn chroot
|
||||||
|
to the current directory after processing any
|
||||||
|
.Fl C
|
||||||
|
options and before extracting any files.
|
||||||
|
.It 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 -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
|
||||||
|
Read the archive from or write the archive to the specified file.
|
||||||
|
The filename can be
|
||||||
|
.Pa -
|
||||||
|
for standard input or standard output.
|
||||||
|
If not specified, the default tape device will be used.
|
||||||
|
(On
|
||||||
|
.Fx ,
|
||||||
|
the default tape device is
|
||||||
|
.Pa /dev/sa0 . )
|
||||||
|
.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 -include Ar pattern
|
||||||
|
Process only files or directories that match the specified pattern.
|
||||||
|
Note that exclusions specified with
|
||||||
|
.Fl -exclude
|
||||||
|
take precedence over inclusions.
|
||||||
|
If no inclusions are explicitly specified, all entries are processed by
|
||||||
|
default.
|
||||||
|
The
|
||||||
|
.Fl -include
|
||||||
|
option is especially useful when filtering archives.
|
||||||
|
For example, the command
|
||||||
|
.Dl Nm Fl c Fl f Pa new.tar 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
|
||||||
|
(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
|
||||||
|
(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 -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
|
||||||
|
(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
|
||||||
|
This is a synonym for the
|
||||||
|
.Fl -check-links
|
||||||
|
option.
|
||||||
|
.It Fl m
|
||||||
|
(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
|
||||||
|
(c, r, u modes only)
|
||||||
|
Do not recursively archive the contents of directories.
|
||||||
|
.It 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 -newer-mtime Ar date
|
||||||
|
(c, r, u modes only)
|
||||||
|
Like
|
||||||
|
.Fl -newer ,
|
||||||
|
except it compares mtime entries instead of ctime entries.
|
||||||
|
.It 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 -newer-mtime-than Pa file
|
||||||
|
(c, r, u modes only)
|
||||||
|
Like
|
||||||
|
.Fl -newer-than ,
|
||||||
|
except it compares mtime entries instead of ctime entries.
|
||||||
|
.It Fl -nodump
|
||||||
|
(c and r modes only)
|
||||||
|
Honor the nodump file flag by skipping this file.
|
||||||
|
.It Fl -null
|
||||||
|
(use with
|
||||||
|
.Fl I ,
|
||||||
|
.Fl T ,
|
||||||
|
or
|
||||||
|
.Fl X )
|
||||||
|
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 -numeric-owner
|
||||||
|
(x mode only)
|
||||||
|
Ignore symbolic user and group names when restoring archives to disk,
|
||||||
|
only numeric uid and gid values will be obeyed.
|
||||||
|
.It Fl O
|
||||||
|
(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 -format Ar ustar
|
||||||
|
.It Fl -one-file-system
|
||||||
|
(c, r, and u modes)
|
||||||
|
Do not cross mount points.
|
||||||
|
.It 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
|
||||||
|
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
|
||||||
|
(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.
|
||||||
|
By default, newly-created files are owned by the user running
|
||||||
|
.Nm ,
|
||||||
|
the file mode is restored for newly-created regular files, and
|
||||||
|
all other types of entries receive default permissions.
|
||||||
|
If
|
||||||
|
.Nm
|
||||||
|
is being run by root, the default is to restore the owner unless the
|
||||||
|
.Fl o
|
||||||
|
option is also specified.
|
||||||
|
.It Fl q ( 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 similiar to the conv=sparse option of dd.
|
||||||
|
.It 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, \1 to \9 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
|
||||||
|
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 -null
|
||||||
|
is specified.
|
||||||
|
Note that
|
||||||
|
.Fl -null
|
||||||
|
also disables the special handling of lines containing
|
||||||
|
.Dq -C .
|
||||||
|
.It Fl U
|
||||||
|
(x mode only)
|
||||||
|
Unlink files before creating them.
|
||||||
|
Without this option,
|
||||||
|
.Nm
|
||||||
|
overwrites existing files, which preserves existing hardlinks.
|
||||||
|
With this option, existing hardlinks will be broken, as will any
|
||||||
|
symlink that would affect the location of an extracted file.
|
||||||
|
.It 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
|
||||||
|
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 -version
|
||||||
|
Print version of
|
||||||
|
.Nm
|
||||||
|
and
|
||||||
|
.Nm libarchive ,
|
||||||
|
and exit.
|
||||||
|
.It Fl w
|
||||||
|
Ask for confirmation for every action.
|
||||||
|
.It Fl X Ar filename
|
||||||
|
Read a list of exclusion patterns from the specified file.
|
||||||
|
See
|
||||||
|
.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
|
||||||
|
(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.
|
||||||
|
.It Fl Z
|
||||||
|
(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.
|
||||||
|
.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 tape device.
|
||||||
|
The
|
||||||
|
.Fl f
|
||||||
|
option overrides this.
|
||||||
|
.It Ev TZ
|
||||||
|
The timezone to use when displaying dates.
|
||||||
|
See
|
||||||
|
.Xr environ 7
|
||||||
|
for more information.
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width ".Ev BLOCKSIZE"
|
||||||
|
.It Pa /dev/sa0
|
||||||
|
The default tape device, if not overridden by the
|
||||||
|
.Ev TAPE
|
||||||
|
environment variable or the
|
||||||
|
.Fl f
|
||||||
|
option.
|
||||||
|
.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 -newer
|
||||||
|
and
|
||||||
|
.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 -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 -format=mtree 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 -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 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 used 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.
|
||||||
|
.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 -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.)
|
||||||
|
.Pp
|
||||||
|
There are alternative long options for many of the short options that
|
||||||
|
are deliberately not documented.
|
734
commands/bsdtar/bsdtar.c
Normal file
734
commands/bsdtar/bsdtar.c
Normal file
|
@ -0,0 +1,734 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/bsdtar.c,v 1.93 2008/11/08 04:43:24 kientzle Exp $");
|
||||||
|
|
||||||
|
#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();
|
||||||
|
}
|
165
commands/bsdtar/bsdtar.h
Normal file
165
commands/bsdtar/bsdtar.h
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/bsdtar.h,v 1.37 2008/12/06 07:37:14 kientzle Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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);
|
||||||
|
#ifndef __minix
|
||||||
|
const char *tar_i64toa(int64_t);
|
||||||
|
#else
|
||||||
|
/* This is not really 64itoa, but it is simpler to do this than replace
|
||||||
|
* tar_i64toa everywhere
|
||||||
|
*/
|
||||||
|
const char *tar_i64toa(int32_t);
|
||||||
|
#endif
|
||||||
|
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
|
132
commands/bsdtar/bsdtar_platform.h
Normal file
132
commands/bsdtar/bsdtar_platform.h
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/bsdtar_platform.h,v 1.26 2008/12/06 07:37:14 kientzle Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 */
|
381
commands/bsdtar/cmdline.c
Normal file
381
commands/bsdtar/cmdline.c
Normal file
|
@ -0,0 +1,381 @@
|
||||||
|
/*-
|
||||||
|
* 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);
|
||||||
|
}
|
763
commands/bsdtar/config.h
Normal file
763
commands/bsdtar/config.h
Normal file
|
@ -0,0 +1,763 @@
|
||||||
|
/* config.h. Generated from config.h.in by configure. */
|
||||||
|
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* Version number of bsdcpio */
|
||||||
|
#define BSDCPIO_VERSION_STRING "2.8.3"
|
||||||
|
|
||||||
|
/* Version number of bsdtar */
|
||||||
|
#define BSDTAR_VERSION_STRING "2.8.3"
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `acl_create_entry' function. */
|
||||||
|
/* #undef HAVE_ACL_CREATE_ENTRY */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `acl_get_link' function. */
|
||||||
|
/* #undef HAVE_ACL_GET_LINK */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `acl_get_link_np' function. */
|
||||||
|
/* #undef HAVE_ACL_GET_LINK_NP */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `acl_get_perm' function. */
|
||||||
|
/* #undef HAVE_ACL_GET_PERM */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `acl_get_perm_np' function. */
|
||||||
|
/* #undef HAVE_ACL_GET_PERM_NP */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `acl_init' function. */
|
||||||
|
/* #undef HAVE_ACL_INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <acl/libacl.h> header file. */
|
||||||
|
/* #undef HAVE_ACL_LIBACL_H */
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `acl_permset_t'. */
|
||||||
|
/* #undef HAVE_ACL_PERMSET_T */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `acl_set_fd' function. */
|
||||||
|
/* #undef HAVE_ACL_SET_FD */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `acl_set_fd_np' function. */
|
||||||
|
/* #undef HAVE_ACL_SET_FD_NP */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `acl_set_file' function. */
|
||||||
|
/* #undef HAVE_ACL_SET_FILE */
|
||||||
|
|
||||||
|
/* True for systems with POSIX ACL support */
|
||||||
|
/* #undef HAVE_ACL_USER */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <attr/xattr.h> header file. */
|
||||||
|
/* #undef HAVE_ATTR_XATTR_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <bzlib.h> header file. */
|
||||||
|
#define HAVE_BZLIB_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `chflags' function. */
|
||||||
|
/* #undef HAVE_CHFLAGS */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `chown' function. */
|
||||||
|
#define HAVE_CHOWN 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `chroot' function. */
|
||||||
|
#define HAVE_CHROOT 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <ctype.h> header file. */
|
||||||
|
#define HAVE_CTYPE_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `cygwin_conv_path' function. */
|
||||||
|
/* #undef HAVE_CYGWIN_CONV_PATH */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `INT64_MAX', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#define HAVE_DECL_INT64_MAX 0
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `INT64_MIN', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#define HAVE_DECL_INT64_MIN 0
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#define HAVE_DECL_SIZE_MAX 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#define HAVE_DECL_SSIZE_MAX 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#define HAVE_DECL_STRERROR_R 0
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `UINT32_MAX', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#define HAVE_DECL_UINT32_MAX 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `UINT64_MAX', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#define HAVE_DECL_UINT64_MAX 0
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||||
|
*/
|
||||||
|
#define HAVE_DIRENT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
|
/* #undef HAVE_DLFCN_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||||
|
#define HAVE_DOPRNT 1
|
||||||
|
|
||||||
|
/* Define to 1 if nl_langinfo supports D_MD_ORDER */
|
||||||
|
/* #undef HAVE_D_MD_ORDER */
|
||||||
|
|
||||||
|
/* A possible errno value for invalid file format errors */
|
||||||
|
/* #undef HAVE_EFTYPE */
|
||||||
|
|
||||||
|
/* A possible errno value for invalid file format errors */
|
||||||
|
#define HAVE_EILSEQ 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <errno.h> header file. */
|
||||||
|
#define HAVE_ERRNO_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <expat.h> header file. */
|
||||||
|
/* #undef HAVE_EXPAT_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <ext2fs/ext2_fs.h> header file. */
|
||||||
|
/* #undef HAVE_EXT2FS_EXT2_FS_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `extattr_get_file' function. */
|
||||||
|
/* #undef HAVE_EXTATTR_GET_FILE */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `extattr_list_file' function. */
|
||||||
|
/* #undef HAVE_EXTATTR_LIST_FILE */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `extattr_set_fd' function. */
|
||||||
|
/* #undef HAVE_EXTATTR_SET_FD */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `extattr_set_file' function. */
|
||||||
|
/* #undef HAVE_EXTATTR_SET_FILE */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fchdir' function. */
|
||||||
|
#define HAVE_FCHDIR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fchflags' function. */
|
||||||
|
/* #undef HAVE_FCHFLAGS */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fchmod' function. */
|
||||||
|
#define HAVE_FCHMOD 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fchown' function. */
|
||||||
|
#define HAVE_FCHOWN 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fcntl' function. */
|
||||||
|
#define HAVE_FCNTL 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||||
|
#define HAVE_FCNTL_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fork' function. */
|
||||||
|
#define HAVE_FORK 1
|
||||||
|
|
||||||
|
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
|
||||||
|
/* #undef HAVE_FSEEKO */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fsetxattr' function. */
|
||||||
|
/* #undef HAVE_FSETXATTR */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fstat' function. */
|
||||||
|
#define HAVE_FSTAT 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `ftruncate' function. */
|
||||||
|
#define HAVE_FTRUNCATE 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `futimens' function. */
|
||||||
|
/* #undef HAVE_FUTIMENS */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `futimes' function. */
|
||||||
|
/* #undef HAVE_FUTIMES */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `geteuid' function. */
|
||||||
|
#define HAVE_GETEUID 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getgrgid_r' function. */
|
||||||
|
/* #undef HAVE_GETGRGID_R */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getgrnam_r' function. */
|
||||||
|
/* #undef HAVE_GETGRNAM_R */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getpid' function. */
|
||||||
|
#define HAVE_GETPID 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getpwnam_r' function. */
|
||||||
|
/* #undef HAVE_GETPWNAM_R */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getpwuid_r' function. */
|
||||||
|
/* #undef HAVE_GETPWUID_R */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getxattr' function. */
|
||||||
|
/* #undef HAVE_GETXATTR */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <grp.h> header file. */
|
||||||
|
#define HAVE_GRP_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `intmax_t'. */
|
||||||
|
#define HAVE_INTMAX_T 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#define HAVE_INTTYPES_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <io.h> header file. */
|
||||||
|
/* #undef HAVE_IO_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <langinfo.h> header file. */
|
||||||
|
/* #undef HAVE_LANGINFO_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `lchflags' function. */
|
||||||
|
/* #undef HAVE_LCHFLAGS */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `lchmod' function. */
|
||||||
|
/* #undef HAVE_LCHMOD */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `lchown' function. */
|
||||||
|
/* #undef HAVE_LCHOWN */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `lgetxattr' function. */
|
||||||
|
/* #undef HAVE_LGETXATTR */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `acl' library (-lacl). */
|
||||||
|
/* #undef HAVE_LIBACL */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `attr' library (-lattr). */
|
||||||
|
/* #undef HAVE_LIBATTR */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `bz2' library (-lbz2). */
|
||||||
|
#define HAVE_LIBBZ2 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `expat' library (-lexpat). */
|
||||||
|
/* #undef HAVE_LIBEXPAT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `lzma' library (-llzma). */
|
||||||
|
/* #undef HAVE_LIBLZMA */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `lzmadec' library (-llzmadec). */
|
||||||
|
/* #undef HAVE_LIBLZMADEC */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `xml2' library (-lxml2). */
|
||||||
|
/* #undef HAVE_LIBXML2 */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <libxml/xmlreader.h> header file. */
|
||||||
|
/* #undef HAVE_LIBXML_XMLREADER_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `z' library (-lz). */
|
||||||
|
#define HAVE_LIBZ 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <limits.h> header file. */
|
||||||
|
#define HAVE_LIMITS_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `link' function. */
|
||||||
|
#define HAVE_LINK 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <linux/fs.h> header file. */
|
||||||
|
/* #undef HAVE_LINUX_FS_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `listxattr' function. */
|
||||||
|
/* #undef HAVE_LISTXATTR */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `llistxattr' function. */
|
||||||
|
/* #undef HAVE_LLISTXATTR */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <locale.h> header file. */
|
||||||
|
#define HAVE_LOCALE_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `long long int'. */
|
||||||
|
/* #undef HAVE_LONG_LONG_INT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `lsetxattr' function. */
|
||||||
|
/* #undef HAVE_LSETXATTR */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `lstat' function. */
|
||||||
|
#define HAVE_LSTAT 1
|
||||||
|
|
||||||
|
/* Define to 1 if `lstat' has the bug that it succeeds when given the
|
||||||
|
zero-length file name argument. */
|
||||||
|
/* #undef HAVE_LSTAT_EMPTY_STRING_BUG */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `lutimes' function. */
|
||||||
|
/* #undef HAVE_LUTIMES */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <lzmadec.h> header file. */
|
||||||
|
/* #undef HAVE_LZMADEC_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <lzma.h> header file. */
|
||||||
|
/* #undef HAVE_LZMA_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `MD5Init' function. */
|
||||||
|
/* #undef HAVE_MD5INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <md5.h> header file. */
|
||||||
|
/* #undef HAVE_MD5_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `memmove' function. */
|
||||||
|
#define HAVE_MEMMOVE 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
/* #undef HAVE_MEMORY_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `memset' function. */
|
||||||
|
#define HAVE_MEMSET 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `mkdir' function. */
|
||||||
|
#define HAVE_MKDIR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `mkfifo' function. */
|
||||||
|
#define HAVE_MKFIFO 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `mknod' function. */
|
||||||
|
#define HAVE_MKNOD 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||||
|
/* #undef HAVE_NDIR_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `nl_langinfo' function. */
|
||||||
|
/* #undef HAVE_NL_LANGINFO */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/md5.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_MD5_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/ripemd.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_RIPEMD_H */
|
||||||
|
|
||||||
|
/* Define to 1 if your openssl has the `SHA256_Init' function. */
|
||||||
|
/* #undef HAVE_OPENSSL_SHA256_INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if your openssl has the `SHA384_Init' function. */
|
||||||
|
/* #undef HAVE_OPENSSL_SHA384_INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if your openssl has the `SHA512_Init' function. */
|
||||||
|
/* #undef HAVE_OPENSSL_SHA512_INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/sha.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_SHA_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <paths.h> header file. */
|
||||||
|
/* #undef HAVE_PATHS_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `pipe' function. */
|
||||||
|
#define HAVE_PIPE 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `poll' function. */
|
||||||
|
/* #undef HAVE_POLL */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <poll.h> header file. */
|
||||||
|
/* #undef HAVE_POLL_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <pwd.h> header file. */
|
||||||
|
#define HAVE_PWD_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `readlink' function. */
|
||||||
|
#define HAVE_READLINK 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <regex.h> header file. */
|
||||||
|
#define HAVE_REGEX_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <ripemd.h> header file. */
|
||||||
|
/* #undef HAVE_RIPEMD_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `RMD160Init' function. */
|
||||||
|
/* #undef HAVE_RMD160INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <rmd160.h> header file. */
|
||||||
|
/* #undef HAVE_RMD160_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `select' function. */
|
||||||
|
#define HAVE_SELECT 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setenv' function. */
|
||||||
|
#define HAVE_SETENV 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setlocale' function. */
|
||||||
|
#define HAVE_SETLOCALE 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `SHA1Init' function. */
|
||||||
|
/* #undef HAVE_SHA1INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sha1.h> header file. */
|
||||||
|
/* #undef HAVE_SHA1_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `SHA256Init' function. */
|
||||||
|
/* #undef HAVE_SHA256INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sha256.h> header file. */
|
||||||
|
/* #undef HAVE_SHA256_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `SHA256_Init' function. */
|
||||||
|
/* #undef HAVE_SHA256_INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sha2.h> header file. */
|
||||||
|
/* #undef HAVE_SHA2_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `SHA384Init' function. */
|
||||||
|
/* #undef HAVE_SHA384INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `SHA384_Init' function. */
|
||||||
|
/* #undef HAVE_SHA384_INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `SHA512Init' function. */
|
||||||
|
/* #undef HAVE_SHA512INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `SHA512_Init' function. */
|
||||||
|
/* #undef HAVE_SHA512_INIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sha.h> header file. */
|
||||||
|
/* #undef HAVE_SHA_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `sigaction' function. */
|
||||||
|
#define HAVE_SIGACTION 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <signal.h> header file. */
|
||||||
|
#define HAVE_SIGNAL_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if `stat' has the bug that it succeeds when given the
|
||||||
|
zero-length file name argument. */
|
||||||
|
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||||
|
#define HAVE_STDARG_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#define HAVE_STDINT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#define HAVE_STDLIB_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strchr' function. */
|
||||||
|
#define HAVE_STRCHR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strdup' function. */
|
||||||
|
#define HAVE_STRDUP 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strerror' function. */
|
||||||
|
#define HAVE_STRERROR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strerror_r' function. */
|
||||||
|
/* #undef HAVE_STRERROR_R */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strftime' function. */
|
||||||
|
#define HAVE_STRFTIME 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#define HAVE_STRINGS_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#define HAVE_STRING_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strncpy_s' function. */
|
||||||
|
/* #undef HAVE_STRNCPY_S */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strrchr' function. */
|
||||||
|
#define HAVE_STRRCHR 1
|
||||||
|
|
||||||
|
/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
|
||||||
|
/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIME */
|
||||||
|
|
||||||
|
/* Define to 1 if `st_birthtimespec.tv_nsec' is a member of `struct stat'. */
|
||||||
|
/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC */
|
||||||
|
|
||||||
|
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
|
||||||
|
/* #undef HAVE_STRUCT_STAT_ST_BLKSIZE */
|
||||||
|
|
||||||
|
/* Define to 1 if `st_flags' is a member of `struct stat'. */
|
||||||
|
/* #undef HAVE_STRUCT_STAT_ST_FLAGS */
|
||||||
|
|
||||||
|
/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */
|
||||||
|
/* #undef HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC */
|
||||||
|
|
||||||
|
/* Define to 1 if `st_mtime_n' is a member of `struct stat'. */
|
||||||
|
/* #undef HAVE_STRUCT_STAT_ST_MTIME_N */
|
||||||
|
|
||||||
|
/* Define to 1 if `st_mtime_usec' is a member of `struct stat'. */
|
||||||
|
/* #undef HAVE_STRUCT_STAT_ST_MTIME_USEC */
|
||||||
|
|
||||||
|
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
|
||||||
|
/* #undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC */
|
||||||
|
|
||||||
|
/* Define to 1 if `st_umtime' is a member of `struct stat'. */
|
||||||
|
/* #undef HAVE_STRUCT_STAT_ST_UMTIME */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `symlink' function. */
|
||||||
|
#define HAVE_SYMLINK 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/acl.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_ACL_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/cdefs.h> header file. */
|
||||||
|
#define HAVE_SYS_CDEFS_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||||
|
*/
|
||||||
|
/* #undef HAVE_SYS_DIR_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/extattr.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_EXTATTR_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||||
|
#define HAVE_SYS_IOCTL_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/mkdev.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_MKDEV_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||||
|
*/
|
||||||
|
/* #undef HAVE_SYS_NDIR_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||||
|
#define HAVE_SYS_PARAM_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_POLL_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||||
|
#define HAVE_SYS_SELECT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#define HAVE_SYS_STAT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||||
|
#define HAVE_SYS_TIME_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#define HAVE_SYS_TYPES_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/utime.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_UTIME_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||||
|
#define HAVE_SYS_WAIT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/xattr.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_XATTR_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `timegm' function. */
|
||||||
|
#define HAVE_TIMEGM 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <time.h> header file. */
|
||||||
|
#define HAVE_TIME_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `tzset' function. */
|
||||||
|
#define HAVE_TZSET 1
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `uintmax_t'. */
|
||||||
|
#define HAVE_UINTMAX_T 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#define HAVE_UNISTD_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `unsetenv' function. */
|
||||||
|
#define HAVE_UNSETENV 1
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `unsigned long long'. */
|
||||||
|
/* #undef HAVE_UNSIGNED_LONG_LONG */
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `unsigned long long int'. */
|
||||||
|
/* #undef HAVE_UNSIGNED_LONG_LONG_INT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `utime' function. */
|
||||||
|
#define HAVE_UTIME 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `utimensat' function. */
|
||||||
|
/* #undef HAVE_UTIMENSAT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `utimes' function. */
|
||||||
|
/* #undef HAVE_UTIMES */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <utime.h> header file. */
|
||||||
|
#define HAVE_UTIME_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vfork' function. */
|
||||||
|
/* #undef HAVE_VFORK */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vprintf' function. */
|
||||||
|
#define HAVE_VPRINTF 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <wchar.h> header file. */
|
||||||
|
#define HAVE_WCHAR_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `wchar_t'. */
|
||||||
|
#define HAVE_WCHAR_T 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `wcrtomb' function. */
|
||||||
|
/* #undef HAVE_WCRTOMB */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `wcscpy' function. */
|
||||||
|
#define HAVE_WCSCPY 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `wcslen' function. */
|
||||||
|
#define HAVE_WCSLEN 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `wctomb' function. */
|
||||||
|
#define HAVE_WCTOMB 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <wctype.h> header file. */
|
||||||
|
/* #undef HAVE_WCTYPE_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <windows.h> header file. */
|
||||||
|
/* #undef HAVE_WINDOWS_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `wmemcmp' function. */
|
||||||
|
#define HAVE_WMEMCMP 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `wmemcpy' function. */
|
||||||
|
#define HAVE_WMEMCPY 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <zlib.h> header file. */
|
||||||
|
#define HAVE_ZLIB_H 1
|
||||||
|
|
||||||
|
/* Version number of libarchive as a single integer */
|
||||||
|
#define LIBARCHIVE_VERSION_NUMBER "2008003"
|
||||||
|
|
||||||
|
/* Version number of libarchive */
|
||||||
|
#define LIBARCHIVE_VERSION_STRING "2.8.3"
|
||||||
|
|
||||||
|
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
|
||||||
|
slash. */
|
||||||
|
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
|
||||||
|
|
||||||
|
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||||
|
*/
|
||||||
|
#define LT_OBJDIR ".libs/"
|
||||||
|
|
||||||
|
/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
|
||||||
|
*/
|
||||||
|
/* #undef MAJOR_IN_MKDEV */
|
||||||
|
|
||||||
|
/* Define to 1 if `major', `minor', and `makedev' are declared in
|
||||||
|
<sysmacros.h>. */
|
||||||
|
/* #undef MAJOR_IN_SYSMACROS */
|
||||||
|
|
||||||
|
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||||
|
/* #undef NO_MINUS_C_MINUS_O */
|
||||||
|
|
||||||
|
/* Name of package */
|
||||||
|
#define PACKAGE "libarchive"
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#define PACKAGE_BUGREPORT "kientzle@freebsd.org"
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#define PACKAGE_NAME "libarchive"
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#define PACKAGE_STRING "libarchive 2.8.3"
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#define PACKAGE_TARNAME "libarchive"
|
||||||
|
|
||||||
|
/* Define to the home page for this package. */
|
||||||
|
#define PACKAGE_URL ""
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#define PACKAGE_VERSION "2.8.3"
|
||||||
|
|
||||||
|
/* The size of `wchar_t', as computed by sizeof. */
|
||||||
|
#define SIZEOF_WCHAR_T 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#define STDC_HEADERS 1
|
||||||
|
|
||||||
|
/* Define to 1 if strerror_r returns char *. */
|
||||||
|
/* #undef STRERROR_R_CHAR_P */
|
||||||
|
|
||||||
|
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||||
|
#define TIME_WITH_SYS_TIME 1
|
||||||
|
|
||||||
|
/* Enable extensions on AIX 3, Interix. */
|
||||||
|
#ifndef _ALL_SOURCE
|
||||||
|
# define _ALL_SOURCE 1
|
||||||
|
#endif
|
||||||
|
/* Enable GNU extensions on systems that have them. */
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
# define _GNU_SOURCE 1
|
||||||
|
#endif
|
||||||
|
/* Enable threading extensions on Solaris. */
|
||||||
|
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||||
|
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||||
|
#endif
|
||||||
|
/* Enable extensions on HP NonStop. */
|
||||||
|
#ifndef _TANDEM_SOURCE
|
||||||
|
# define _TANDEM_SOURCE 1
|
||||||
|
#endif
|
||||||
|
/* Enable general extensions on Solaris. */
|
||||||
|
#ifndef __EXTENSIONS__
|
||||||
|
# define __EXTENSIONS__ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Version number of package */
|
||||||
|
#define VERSION "2.8.3"
|
||||||
|
|
||||||
|
/* Define to '0x0500' for Windows 2000 APIs. */
|
||||||
|
/* #undef WINVER */
|
||||||
|
|
||||||
|
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||||
|
/* #undef _FILE_OFFSET_BITS */
|
||||||
|
|
||||||
|
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
|
||||||
|
/* #undef _LARGEFILE_SOURCE */
|
||||||
|
|
||||||
|
/* Define for large files, on AIX-style hosts. */
|
||||||
|
/* #undef _LARGE_FILES */
|
||||||
|
|
||||||
|
/* Define to 1 if on MINIX. */
|
||||||
|
#define _MINIX 1
|
||||||
|
|
||||||
|
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||||
|
this defined. */
|
||||||
|
#define _POSIX_1_SOURCE 2
|
||||||
|
|
||||||
|
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||||
|
#define _POSIX_SOURCE 1
|
||||||
|
|
||||||
|
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
|
||||||
|
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||||
|
#define below would cause a syntax error. */
|
||||||
|
/* #undef _UINT64_T */
|
||||||
|
|
||||||
|
/* Define to '0x0500' for Windows 2000 APIs. */
|
||||||
|
/* #undef _WIN32_WINNT */
|
||||||
|
|
||||||
|
/* Define to empty if `const' does not conform to ANSI C. */
|
||||||
|
/* #undef const */
|
||||||
|
|
||||||
|
/* Define to match typeof st_gid field of struct stat if <sys/types.h> doesn't
|
||||||
|
define. */
|
||||||
|
/* #undef gid_t */
|
||||||
|
|
||||||
|
/* Define to `unsigned long' if <sys/types.h> does not define. */
|
||||||
|
#define id_t unsigned long
|
||||||
|
|
||||||
|
/* Define to the type of a signed integer type of width exactly 64 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
/* #undef int64_t */
|
||||||
|
|
||||||
|
/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
|
||||||
|
not define. */
|
||||||
|
/* #undef intmax_t */
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> does not define. */
|
||||||
|
/* #undef mode_t */
|
||||||
|
|
||||||
|
/* Define to `long long' if <sys/types.h> does not define. */
|
||||||
|
/* #undef off_t */
|
||||||
|
|
||||||
|
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||||
|
/* #undef size_t */
|
||||||
|
|
||||||
|
/* Define to match typeof st_uid field of struct stat if <sys/types.h> doesn't
|
||||||
|
define. */
|
||||||
|
/* #undef uid_t */
|
||||||
|
|
||||||
|
/* Define to the type of an unsigned integer type of width exactly 64 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
/* #undef uint64_t */
|
||||||
|
|
||||||
|
/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
|
||||||
|
do not define. */
|
||||||
|
/* #undef uintmax_t */
|
||||||
|
|
||||||
|
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||||
|
/* #undef uintptr_t */
|
1037
commands/bsdtar/getdate.c
Normal file
1037
commands/bsdtar/getdate.c
Normal file
File diff suppressed because it is too large
Load diff
6
commands/bsdtar/libarchive_fe/Makefile.inc
Normal file
6
commands/bsdtar/libarchive_fe/Makefile.inc
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.PATH: ${.CURDIR}/libarchive_fe
|
||||||
|
|
||||||
|
SRCS+= err.c \
|
||||||
|
line_reader.c \
|
||||||
|
matching.c \
|
||||||
|
pathmatch.c
|
74
commands/bsdtar/libarchive_fe/err.c
Normal file
74
commands/bsdtar/libarchive_fe/err.c
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*-
|
||||||
|
* 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 "lafe_platform.h"
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#ifdef HAVE_STDARG_H
|
||||||
|
#include <stdarg.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifdef HAVE_STDLIB_H
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "err.h"
|
||||||
|
|
||||||
|
const char *lafe_progname;
|
||||||
|
|
||||||
|
static void
|
||||||
|
lafe_vwarnc(int code, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: ", lafe_progname);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
if (code != 0)
|
||||||
|
fprintf(stderr, ": %s", strerror(code));
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lafe_warnc(int code, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
lafe_vwarnc(code, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lafe_errc(int eval, int code, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
lafe_vwarnc(code, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
exit(eval);
|
||||||
|
}
|
41
commands/bsdtar/libarchive_fe/err.h
Normal file
41
commands/bsdtar/libarchive_fe/err.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2009 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LAFE_ERR_H
|
||||||
|
#define LAFE_ERR_H
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && (__GNUC__ > 2 || \
|
||||||
|
(__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
|
||||||
|
#define __LA_DEAD __attribute__((__noreturn__))
|
||||||
|
#else
|
||||||
|
#define __LA_DEAD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const char *lafe_progname;
|
||||||
|
|
||||||
|
void lafe_warnc(int code, const char *fmt, ...);
|
||||||
|
void lafe_errc(int eval, int code, const char *fmt, ...) __LA_DEAD;
|
||||||
|
|
||||||
|
#endif
|
55
commands/bsdtar/libarchive_fe/lafe_platform.h
Normal file
55
commands/bsdtar/libarchive_fe/lafe_platform.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/cpio/cpio_platform.h,v 1.2 2008/12/06 07:15:42 kientzle Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This header is the first thing included in any of the libarchive_fe
|
||||||
|
* source files. As far as possible, platform-specific issues should
|
||||||
|
* be dealt with here and not within individual source files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LAFE_PLATFORM_H_INCLUDED
|
||||||
|
#define LAFE_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
|
||||||
|
|
||||||
|
#endif
|
171
commands/bsdtar/libarchive_fe/line_reader.c
Normal file
171
commands/bsdtar/libarchive_fe/line_reader.c
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 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
|
||||||
|
* 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 "lafe_platform.h"
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "err.h"
|
||||||
|
#include "line_reader.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__)
|
||||||
|
#define strdup _strdup
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read lines from file and do something with each one. If option_null
|
||||||
|
* is set, lines are terminated with zero bytes; otherwise, they're
|
||||||
|
* terminated with newlines.
|
||||||
|
*
|
||||||
|
* This uses a self-sizing buffer to handle arbitrarily-long lines.
|
||||||
|
*/
|
||||||
|
struct lafe_line_reader {
|
||||||
|
FILE *f;
|
||||||
|
char *buff, *buff_end, *line_start, *line_end, *p;
|
||||||
|
char *pathname;
|
||||||
|
size_t buff_length;
|
||||||
|
int nullSeparator; /* Lines separated by null, not CR/CRLF/etc. */
|
||||||
|
int ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lafe_line_reader *
|
||||||
|
lafe_line_reader(const char *pathname, int nullSeparator)
|
||||||
|
{
|
||||||
|
struct lafe_line_reader *lr;
|
||||||
|
|
||||||
|
lr = calloc(1, sizeof(*lr));
|
||||||
|
if (lr == NULL)
|
||||||
|
lafe_errc(1, ENOMEM, "Can't open %s", pathname);
|
||||||
|
|
||||||
|
lr->nullSeparator = nullSeparator;
|
||||||
|
lr->pathname = strdup(pathname);
|
||||||
|
|
||||||
|
if (strcmp(pathname, "-") == 0)
|
||||||
|
lr->f = stdin;
|
||||||
|
else
|
||||||
|
lr->f = fopen(pathname, "r");
|
||||||
|
if (lr->f == NULL)
|
||||||
|
lafe_errc(1, errno, "Couldn't open %s", pathname);
|
||||||
|
lr->buff_length = 8192;
|
||||||
|
lr->buff = malloc(lr->buff_length);
|
||||||
|
if (lr->buff == NULL)
|
||||||
|
lafe_errc(1, ENOMEM, "Can't read %s", pathname);
|
||||||
|
lr->line_start = lr->line_end = lr->buff_end = lr->buff;
|
||||||
|
|
||||||
|
return (lr);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
lafe_line_reader_next(struct lafe_line_reader *lr)
|
||||||
|
{
|
||||||
|
size_t bytes_wanted, bytes_read, new_buff_size;
|
||||||
|
char *line_start, *p;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
/* If there's a line in the buffer, return it immediately. */
|
||||||
|
while (lr->line_end < lr->buff_end) {
|
||||||
|
if (lr->nullSeparator) {
|
||||||
|
if (*lr->line_end == '\0') {
|
||||||
|
line_start = lr->line_start;
|
||||||
|
lr->line_start = lr->line_end + 1;
|
||||||
|
lr->line_end = lr->line_start;
|
||||||
|
return (line_start);
|
||||||
|
}
|
||||||
|
} else if (*lr->line_end == '\x0a' || *lr->line_end == '\x0d') {
|
||||||
|
*lr->line_end = '\0';
|
||||||
|
line_start = lr->line_start;
|
||||||
|
lr->line_start = lr->line_end + 1;
|
||||||
|
lr->line_end = lr->line_start;
|
||||||
|
if (line_start[0] != '\0')
|
||||||
|
return (line_start);
|
||||||
|
}
|
||||||
|
lr->line_end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we're at end-of-file, process the final data. */
|
||||||
|
if (lr->f == NULL) {
|
||||||
|
/* If there's more text, return one last line. */
|
||||||
|
if (lr->line_end > lr->line_start) {
|
||||||
|
*lr->line_end = '\0';
|
||||||
|
line_start = lr->line_start;
|
||||||
|
lr->line_start = lr->line_end + 1;
|
||||||
|
lr->line_end = lr->line_start;
|
||||||
|
return (line_start);
|
||||||
|
}
|
||||||
|
/* Otherwise, we're done. */
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buffer only has part of a line. */
|
||||||
|
if (lr->line_start > lr->buff) {
|
||||||
|
/* Move a leftover fractional line to the beginning. */
|
||||||
|
memmove(lr->buff, lr->line_start,
|
||||||
|
lr->buff_end - lr->line_start);
|
||||||
|
lr->buff_end -= lr->line_start - lr->buff;
|
||||||
|
lr->line_end -= lr->line_start - lr->buff;
|
||||||
|
lr->line_start = lr->buff;
|
||||||
|
} else {
|
||||||
|
/* Line is too big; enlarge the buffer. */
|
||||||
|
new_buff_size = lr->buff_length * 2;
|
||||||
|
if (new_buff_size <= lr->buff_length)
|
||||||
|
lafe_errc(1, ENOMEM,
|
||||||
|
"Line too long in %s", lr->pathname);
|
||||||
|
lr->buff_length = new_buff_size;
|
||||||
|
p = realloc(lr->buff, new_buff_size);
|
||||||
|
if (p == NULL)
|
||||||
|
lafe_errc(1, ENOMEM,
|
||||||
|
"Line too long in %s", lr->pathname);
|
||||||
|
lr->buff_end = p + (lr->buff_end - lr->buff);
|
||||||
|
lr->line_end = p + (lr->line_end - lr->buff);
|
||||||
|
lr->line_start = lr->buff = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get some more data into the buffer. */
|
||||||
|
bytes_wanted = lr->buff + lr->buff_length - lr->buff_end;
|
||||||
|
bytes_read = fread(lr->buff_end, 1, bytes_wanted, lr->f);
|
||||||
|
lr->buff_end += bytes_read;
|
||||||
|
|
||||||
|
if (ferror(lr->f))
|
||||||
|
lafe_errc(1, errno, "Can't read %s", lr->pathname);
|
||||||
|
if (feof(lr->f)) {
|
||||||
|
if (lr->f != stdin)
|
||||||
|
fclose(lr->f);
|
||||||
|
lr->f = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lafe_line_reader_free(struct lafe_line_reader *lr)
|
||||||
|
{
|
||||||
|
free(lr->buff);
|
||||||
|
free(lr->pathname);
|
||||||
|
free(lr);
|
||||||
|
}
|
35
commands/bsdtar/libarchive_fe/line_reader.h
Normal file
35
commands/bsdtar/libarchive_fe/line_reader.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2009 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LAFE_LINE_READER_H
|
||||||
|
#define LAFE_LINE_READER_H
|
||||||
|
|
||||||
|
struct lafe_line_reader;
|
||||||
|
|
||||||
|
struct lafe_line_reader *lafe_line_reader(const char *, int nullSeparator);
|
||||||
|
const char *lafe_line_reader_next(struct lafe_line_reader *);
|
||||||
|
void lafe_line_reader_free(struct lafe_line_reader *);
|
||||||
|
|
||||||
|
#endif
|
284
commands/bsdtar/libarchive_fe/matching.c
Normal file
284
commands/bsdtar/libarchive_fe/matching.c
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
/*-
|
||||||
|
* 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 "lafe_platform.h"
|
||||||
|
__FBSDID("$FreeBSD: src/usr.bin/cpio/matching.c,v 1.2 2008/06/21 02:20:20 kientzle Exp $");
|
||||||
|
|
||||||
|
#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 "err.h"
|
||||||
|
#include "line_reader.h"
|
||||||
|
#include "matching.h"
|
||||||
|
#include "pathmatch.h"
|
||||||
|
|
||||||
|
struct match {
|
||||||
|
struct match *next;
|
||||||
|
int matches;
|
||||||
|
char pattern[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lafe_matching {
|
||||||
|
struct match *exclusions;
|
||||||
|
int exclusions_count;
|
||||||
|
struct match *inclusions;
|
||||||
|
int inclusions_count;
|
||||||
|
int inclusions_unmatched_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void add_pattern(struct match **list, const char *pattern);
|
||||||
|
static void initialize_matching(struct lafe_matching **);
|
||||||
|
static int match_exclusion(struct match *, const char *pathname);
|
||||||
|
static int match_inclusion(struct match *, const char *pathname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The matching logic here needs to be re-thought. I started out to
|
||||||
|
* try to mimic gtar's matching logic, but it's not entirely
|
||||||
|
* consistent. In particular 'tar -t' and 'tar -x' interpret patterns
|
||||||
|
* on the command line as anchored, but --exclude doesn't.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility functions to manage exclusion/inclusion patterns
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
lafe_exclude(struct lafe_matching **matching, const char *pattern)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (*matching == NULL)
|
||||||
|
initialize_matching(matching);
|
||||||
|
add_pattern(&((*matching)->exclusions), pattern);
|
||||||
|
(*matching)->exclusions_count++;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lafe_exclude_from_file(struct lafe_matching **matching, const char *pathname)
|
||||||
|
{
|
||||||
|
struct lafe_line_reader *lr;
|
||||||
|
const char *p;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
lr = lafe_line_reader(pathname, 0);
|
||||||
|
while ((p = lafe_line_reader_next(lr)) != NULL) {
|
||||||
|
if (lafe_exclude(matching, p) != 0)
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
lafe_line_reader_free(lr);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lafe_include(struct lafe_matching **matching, const char *pattern)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (*matching == NULL)
|
||||||
|
initialize_matching(matching);
|
||||||
|
add_pattern(&((*matching)->inclusions), pattern);
|
||||||
|
(*matching)->inclusions_count++;
|
||||||
|
(*matching)->inclusions_unmatched_count++;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lafe_include_from_file(struct lafe_matching **matching, const char *pathname,
|
||||||
|
int nullSeparator)
|
||||||
|
{
|
||||||
|
struct lafe_line_reader *lr;
|
||||||
|
const char *p;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
lr = lafe_line_reader(pathname, nullSeparator);
|
||||||
|
while ((p = lafe_line_reader_next(lr)) != NULL) {
|
||||||
|
if (lafe_include(matching, p) != 0)
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
lafe_line_reader_free(lr);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_pattern(struct match **list, const char *pattern)
|
||||||
|
{
|
||||||
|
struct match *match;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = strlen(pattern);
|
||||||
|
match = malloc(sizeof(*match) + len + 1);
|
||||||
|
if (match == NULL)
|
||||||
|
lafe_errc(1, errno, "Out of memory");
|
||||||
|
strcpy(match->pattern, pattern);
|
||||||
|
/* Both "foo/" and "foo" should match "foo/bar". */
|
||||||
|
if (len && match->pattern[len - 1] == '/')
|
||||||
|
match->pattern[strlen(match->pattern)-1] = '\0';
|
||||||
|
match->next = *list;
|
||||||
|
*list = match;
|
||||||
|
match->matches = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
lafe_excluded(struct lafe_matching *matching, const char *pathname)
|
||||||
|
{
|
||||||
|
struct match *match;
|
||||||
|
struct match *matched;
|
||||||
|
|
||||||
|
if (matching == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/* Exclusions take priority */
|
||||||
|
for (match = matching->exclusions; match != NULL; match = match->next){
|
||||||
|
if (match_exclusion(match, pathname))
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then check for inclusions */
|
||||||
|
matched = NULL;
|
||||||
|
for (match = matching->inclusions; match != NULL; match = match->next){
|
||||||
|
if (match_inclusion(match, pathname)) {
|
||||||
|
/*
|
||||||
|
* If this pattern has never been matched,
|
||||||
|
* then we're done.
|
||||||
|
*/
|
||||||
|
if (match->matches == 0) {
|
||||||
|
match->matches++;
|
||||||
|
matching->inclusions_unmatched_count--;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Otherwise, remember the match but keep checking
|
||||||
|
* in case we can tick off an unmatched pattern.
|
||||||
|
*/
|
||||||
|
matched = match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* We didn't find a pattern that had never been matched, but
|
||||||
|
* we did find a match, so count it and exit.
|
||||||
|
*/
|
||||||
|
if (matched != NULL) {
|
||||||
|
matched->matches++;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there were inclusions, default is to exclude. */
|
||||||
|
if (matching->inclusions != NULL)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
/* No explicit inclusions, default is to match. */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a little odd, but it matches the default behavior of
|
||||||
|
* gtar. In particular, 'a*b' will match 'foo/a1111/222b/bar'
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
match_exclusion(struct match *match, const char *pathname)
|
||||||
|
{
|
||||||
|
return (lafe_pathmatch(match->pattern,
|
||||||
|
pathname,
|
||||||
|
PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Again, mimic gtar: inclusions are always anchored (have to match
|
||||||
|
* the beginning of the path) even though exclusions are not anchored.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
match_inclusion(struct match *match, const char *pathname)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
return (lafe_pathmatch(match->pattern, pathname, 0));
|
||||||
|
#else
|
||||||
|
return (lafe_pathmatch(match->pattern, pathname, PATHMATCH_NO_ANCHOR_END));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lafe_cleanup_exclusions(struct lafe_matching **matching)
|
||||||
|
{
|
||||||
|
struct match *p, *q;
|
||||||
|
|
||||||
|
if (*matching == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (p = (*matching)->inclusions; p != NULL; ) {
|
||||||
|
q = p;
|
||||||
|
p = p->next;
|
||||||
|
free(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = (*matching)->exclusions; p != NULL; ) {
|
||||||
|
q = p;
|
||||||
|
p = p->next;
|
||||||
|
free(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(*matching);
|
||||||
|
*matching = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initialize_matching(struct lafe_matching **matching)
|
||||||
|
{
|
||||||
|
*matching = calloc(sizeof(**matching), 1);
|
||||||
|
if (*matching == NULL)
|
||||||
|
lafe_errc(1, errno, "No memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lafe_unmatched_inclusions(struct lafe_matching *matching)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (matching == NULL)
|
||||||
|
return (0);
|
||||||
|
return (matching->inclusions_unmatched_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lafe_unmatched_inclusions_warn(struct lafe_matching *matching, const char *msg)
|
||||||
|
{
|
||||||
|
struct match *p;
|
||||||
|
|
||||||
|
if (matching == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
for (p = matching->inclusions; p != NULL; p = p->next) {
|
||||||
|
if (p->matches == 0)
|
||||||
|
lafe_warnc(0, "%s: %s", p->pattern, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (matching->inclusions_unmatched_count);
|
||||||
|
}
|
46
commands/bsdtar/libarchive_fe/matching.h
Normal file
46
commands/bsdtar/libarchive_fe/matching.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*-
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* $FreeBSD$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MATCHING_H
|
||||||
|
#define MATCHING_H
|
||||||
|
|
||||||
|
struct lafe_matching;
|
||||||
|
|
||||||
|
int lafe_exclude(struct lafe_matching **matching, const char *pattern);
|
||||||
|
int lafe_exclude_from_file(struct lafe_matching **matching,
|
||||||
|
const char *pathname);
|
||||||
|
int lafe_include(struct lafe_matching **matching, const char *pattern);
|
||||||
|
int lafe_include_from_file(struct lafe_matching **matching,
|
||||||
|
const char *pathname, int nullSeparator);
|
||||||
|
|
||||||
|
int lafe_excluded(struct lafe_matching *, const char *pathname);
|
||||||
|
void lafe_cleanup_exclusions(struct lafe_matching **);
|
||||||
|
int lafe_unmatched_inclusions(struct lafe_matching *);
|
||||||
|
int lafe_unmatched_inclusions_warn(struct lafe_matching *, const char *msg);
|
||||||
|
|
||||||
|
#endif
|
255
commands/bsdtar/libarchive_fe/pathmatch.c
Normal file
255
commands/bsdtar/libarchive_fe/pathmatch.c
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
/*-
|
||||||
|
* 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 "lafe_platform.h"
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pathmatch.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether a character 'c' is matched by a list specification [...]:
|
||||||
|
* * Leading '!' negates the class.
|
||||||
|
* * <char>-<char> is a range of characters
|
||||||
|
* * \<char> removes any special meaning for <char>
|
||||||
|
*
|
||||||
|
* Some interesting boundary cases:
|
||||||
|
* a-d-e is one range (a-d) followed by two single characters - and e.
|
||||||
|
* \a-\d is same as a-d
|
||||||
|
* a\-d is three single characters: a, d, -
|
||||||
|
* Trailing - is not special (so [a-] is two characters a and -).
|
||||||
|
* Initial - is not special ([a-] is same as [-a] is same as [\\-a])
|
||||||
|
* This function never sees a trailing \.
|
||||||
|
* [] always fails
|
||||||
|
* [!] always succeeds
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
pm_list(const char *start, const char *end, const char c, int flags)
|
||||||
|
{
|
||||||
|
const char *p = start;
|
||||||
|
char rangeStart = '\0', nextRangeStart;
|
||||||
|
int match = 1, nomatch = 0;
|
||||||
|
|
||||||
|
/* This will be used soon... */
|
||||||
|
(void)flags; /* UNUSED */
|
||||||
|
|
||||||
|
/* If this is a negated class, return success for nomatch. */
|
||||||
|
if (*p == '!' && p < end) {
|
||||||
|
match = 0;
|
||||||
|
nomatch = 1;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (p < end) {
|
||||||
|
nextRangeStart = '\0';
|
||||||
|
switch (*p) {
|
||||||
|
case '-':
|
||||||
|
/* Trailing or initial '-' is not special. */
|
||||||
|
if ((rangeStart == '\0') || (p == end - 1)) {
|
||||||
|
if (*p == c)
|
||||||
|
return (match);
|
||||||
|
} else {
|
||||||
|
char rangeEnd = *++p;
|
||||||
|
if (rangeEnd == '\\')
|
||||||
|
rangeEnd = *++p;
|
||||||
|
if ((rangeStart <= c) && (c <= rangeEnd))
|
||||||
|
return (match);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
++p;
|
||||||
|
/* Fall through */
|
||||||
|
default:
|
||||||
|
if (*p == c)
|
||||||
|
return (match);
|
||||||
|
nextRangeStart = *p; /* Possible start of range. */
|
||||||
|
}
|
||||||
|
rangeStart = nextRangeStart;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
return (nomatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If s is pointing to "./", ".//", "./././" or the like, skip it.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
pm_slashskip(const char *s) {
|
||||||
|
while ((*s == '/')
|
||||||
|
|| (s[0] == '.' && s[1] == '/')
|
||||||
|
|| (s[0] == '.' && s[1] == '\0'))
|
||||||
|
++s;
|
||||||
|
return (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pm(const char *p, const char *s, int flags)
|
||||||
|
{
|
||||||
|
const char *end;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ignore leading './', './/', '././', etc.
|
||||||
|
*/
|
||||||
|
if (s[0] == '.' && s[1] == '/')
|
||||||
|
s = pm_slashskip(s + 1);
|
||||||
|
if (p[0] == '.' && p[1] == '/')
|
||||||
|
p = pm_slashskip(p + 1);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
switch (*p) {
|
||||||
|
case '\0':
|
||||||
|
if (s[0] == '/') {
|
||||||
|
if (flags & PATHMATCH_NO_ANCHOR_END)
|
||||||
|
return (1);
|
||||||
|
/* "dir" == "dir/" == "dir/." */
|
||||||
|
s = pm_slashskip(s);
|
||||||
|
}
|
||||||
|
return (*s == '\0');
|
||||||
|
case '?':
|
||||||
|
/* ? always succeds, unless we hit end of 's' */
|
||||||
|
if (*s == '\0')
|
||||||
|
return (0);
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
/* "*" == "**" == "***" ... */
|
||||||
|
while (*p == '*')
|
||||||
|
++p;
|
||||||
|
/* Trailing '*' always succeeds. */
|
||||||
|
if (*p == '\0')
|
||||||
|
return (1);
|
||||||
|
while (*s) {
|
||||||
|
if (lafe_pathmatch(p, s, flags))
|
||||||
|
return (1);
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
case '[':
|
||||||
|
/*
|
||||||
|
* Find the end of the [...] character class,
|
||||||
|
* ignoring \] that might occur within the class.
|
||||||
|
*/
|
||||||
|
end = p + 1;
|
||||||
|
while (*end != '\0' && *end != ']') {
|
||||||
|
if (*end == '\\' && end[1] != '\0')
|
||||||
|
++end;
|
||||||
|
++end;
|
||||||
|
}
|
||||||
|
if (*end == ']') {
|
||||||
|
/* We found [...], try to match it. */
|
||||||
|
if (!pm_list(p + 1, end, *s, flags))
|
||||||
|
return (0);
|
||||||
|
p = end; /* Jump to trailing ']' char. */
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
/* No final ']', so just match '['. */
|
||||||
|
if (*p != *s)
|
||||||
|
return (0);
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
/* Trailing '\\' matches itself. */
|
||||||
|
if (p[1] == '\0') {
|
||||||
|
if (*s != '\\')
|
||||||
|
return (0);
|
||||||
|
} else {
|
||||||
|
++p;
|
||||||
|
if (*p != *s)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
if (*s != '/' && *s != '\0')
|
||||||
|
return (0);
|
||||||
|
/* Note: pattern "/\./" won't match "/";
|
||||||
|
* pm_slashskip() correctly stops at backslash. */
|
||||||
|
p = pm_slashskip(p);
|
||||||
|
s = pm_slashskip(s);
|
||||||
|
if (*p == '\0' && (flags & PATHMATCH_NO_ANCHOR_END))
|
||||||
|
return (1);
|
||||||
|
--p; /* Counteract the increment below. */
|
||||||
|
--s;
|
||||||
|
break;
|
||||||
|
case '$':
|
||||||
|
/* '$' is special only at end of pattern and only
|
||||||
|
* if PATHMATCH_NO_ANCHOR_END is specified. */
|
||||||
|
if (p[1] == '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
|
||||||
|
/* "dir" == "dir/" == "dir/." */
|
||||||
|
return (*pm_slashskip(s) == '\0');
|
||||||
|
}
|
||||||
|
/* Otherwise, '$' is not special. */
|
||||||
|
/* FALL THROUGH */
|
||||||
|
default:
|
||||||
|
if (*p != *s)
|
||||||
|
return (0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main entry point. */
|
||||||
|
int
|
||||||
|
lafe_pathmatch(const char *p, const char *s, int flags)
|
||||||
|
{
|
||||||
|
/* Empty pattern only matches the empty string. */
|
||||||
|
if (p == NULL || *p == '\0')
|
||||||
|
return (s == NULL || *s == '\0');
|
||||||
|
|
||||||
|
/* Leading '^' anchors the start of the pattern. */
|
||||||
|
if (*p == '^') {
|
||||||
|
++p;
|
||||||
|
flags &= ~PATHMATCH_NO_ANCHOR_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '/' && *s != '/')
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/* Certain patterns and file names anchor implicitly. */
|
||||||
|
if (*p == '*' || *p == '/' || *p == '/') {
|
||||||
|
while (*p == '/')
|
||||||
|
++p;
|
||||||
|
while (*s == '/')
|
||||||
|
++s;
|
||||||
|
return (pm(p, s, flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If start is unanchored, try to match start of each path element. */
|
||||||
|
if (flags & PATHMATCH_NO_ANCHOR_START) {
|
||||||
|
for ( ; s != NULL; s = strchr(s, '/')) {
|
||||||
|
if (*s == '/')
|
||||||
|
s++;
|
||||||
|
if (pm(p, s, flags))
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Default: Match from beginning. */
|
||||||
|
return (pm(p, s, flags));
|
||||||
|
}
|
42
commands/bsdtar/libarchive_fe/pathmatch.h
Normal file
42
commands/bsdtar/libarchive_fe/pathmatch.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*-
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* $FreeBSD$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LAFE_PATHMATCH_H
|
||||||
|
#define LAFE_PATHMATCH_H
|
||||||
|
|
||||||
|
/* Don't anchor at beginning unless the pattern starts with "^" */
|
||||||
|
#define PATHMATCH_NO_ANCHOR_START 1
|
||||||
|
/* Don't anchor at end unless the pattern ends with "$" */
|
||||||
|
#define PATHMATCH_NO_ANCHOR_END 2
|
||||||
|
|
||||||
|
/* Note that "^" and "$" are not special unless you set the corresponding
|
||||||
|
* flag above. */
|
||||||
|
|
||||||
|
int lafe_pathmatch(const char *p, const char *s, int flags);
|
||||||
|
|
||||||
|
#endif
|
440
commands/bsdtar/read.c
Normal file
440
commands/bsdtar/read.c
Normal file
|
@ -0,0 +1,440 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/read.c,v 1.40 2008/08/21 06:41:14 kientzle Exp $");
|
||||||
|
|
||||||
|
#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;
|
||||||
|
#ifndef __minix
|
||||||
|
uint64_t comp, uncomp;
|
||||||
|
#else
|
||||||
|
size_t comp, uncomp;
|
||||||
|
#endif
|
||||||
|
if (!need_report())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (bsdtar->verbose)
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
if (a != NULL) {
|
||||||
|
comp = archive_position_compressed(a);
|
||||||
|
uncomp = archive_position_uncompressed(a);
|
||||||
|
fprintf(stderr,
|
||||||
|
"In: %s bytes, compression %d%%;",
|
||||||
|
tar_i64toa(comp), (int)((uncomp - comp) * 100 / uncomp));
|
||||||
|
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));
|
||||||
|
}
|
289
commands/bsdtar/subst.c
Normal file
289
commands/bsdtar/subst.c
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/subst.c,v 1.4 2008/06/15 10:08:16 kientzle Exp $");
|
||||||
|
|
||||||
|
#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 */
|
1
commands/bsdtar/test/.deps/bsdtar_test-main.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-main.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_0.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_0.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_basic.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_basic.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_copy.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_copy.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_getdate.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_getdate.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_help.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_help.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_option_q.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_option_q.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_option_r.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_option_r.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_option_s.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_option_s.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_patterns.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_patterns.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_stdio.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_stdio.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_version.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_version.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
1
commands/bsdtar/test/.deps/bsdtar_test-test_windows.Po
Normal file
1
commands/bsdtar/test/.deps/bsdtar_test-test_windows.Po
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# dummy
|
67
commands/bsdtar/test/CMakeLists.txt
Normal file
67
commands/bsdtar/test/CMakeLists.txt
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
############################################
|
||||||
|
#
|
||||||
|
# How to build bsdtar_test
|
||||||
|
#
|
||||||
|
############################################
|
||||||
|
IF(ENABLE_TAR AND ENABLE_TEST)
|
||||||
|
SET(bsdtar_test_SOURCES
|
||||||
|
../getdate.c
|
||||||
|
main.c
|
||||||
|
test.h
|
||||||
|
test_0.c
|
||||||
|
test_basic.c
|
||||||
|
test_copy.c
|
||||||
|
test_empty_mtree.c
|
||||||
|
test_getdate.c
|
||||||
|
test_help.c
|
||||||
|
test_option_T_upper.c
|
||||||
|
test_option_q.c
|
||||||
|
test_option_r.c
|
||||||
|
test_option_s.c
|
||||||
|
test_patterns.c
|
||||||
|
test_stdio.c
|
||||||
|
test_strip_components.c
|
||||||
|
test_symlink_dir.c
|
||||||
|
test_version.c
|
||||||
|
test_windows.c
|
||||||
|
)
|
||||||
|
IF(WIN32 AND NOT CYGWIN)
|
||||||
|
LIST(APPEND bsdtar_test_SOURCES ../bsdtar_windows.c)
|
||||||
|
LIST(APPEND bsdtar_test_SOURCES ../bsdtar_windows.h)
|
||||||
|
ENDIF(WIN32 AND NOT CYGWIN)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Register target
|
||||||
|
#
|
||||||
|
ADD_EXECUTABLE(bsdtar_test ${bsdtar_test_SOURCES})
|
||||||
|
SET_PROPERTY(TARGET bsdtar_test PROPERTY COMPILE_DEFINITIONS LIST_H)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate list.h by grepping DEFINE_TEST() lines out of the C sources.
|
||||||
|
#
|
||||||
|
GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h
|
||||||
|
${CMAKE_CURRENT_LIST_FILE} ${bsdtar_test_SOURCES})
|
||||||
|
SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
# list.h has a line DEFINE_TEST(testname) for every
|
||||||
|
# test. We can use that to define the tests for cmake by
|
||||||
|
# defining a DEFINE_TEST macro and reading list.h in.
|
||||||
|
MACRO (DEFINE_TEST _testname)
|
||||||
|
ADD_TEST_28(
|
||||||
|
NAME bsdtar_${_testname}
|
||||||
|
COMMAND bsdtar_test -vv
|
||||||
|
-p $<TARGET_FILE:bsdtar>
|
||||||
|
-r ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${_testname})
|
||||||
|
ENDMACRO (DEFINE_TEST _testname)
|
||||||
|
|
||||||
|
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h)
|
||||||
|
|
||||||
|
# Experimental new test handling
|
||||||
|
ADD_CUSTOM_TARGET(run_bsdtar_test
|
||||||
|
COMMAND bsdtar_test -p ${BSDTAR} -r ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
ADD_DEPENDENCIES(run_bsdtar_test bsdtar)
|
||||||
|
ADD_DEPENDENCIES(run_all_tests run_bsdtar_test)
|
||||||
|
|
||||||
|
ENDIF (ENABLE_TAR AND ENABLE_TEST)
|
75
commands/bsdtar/test/config.sh
Executable file
75
commands/bsdtar/test/config.sh
Executable file
|
@ -0,0 +1,75 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 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: src/usr.bin/tar/test/config.sh,v 1.2 2007/03/11 19:33:45 kientzle Exp $
|
||||||
|
|
||||||
|
THISDIR=`cd \`dirname $0\`;/bin/pwd`
|
||||||
|
|
||||||
|
# TESTDIR defaults to /tmp/bsdtar- + the name of the script
|
||||||
|
if [ -z "$TESTDIR" ]; then
|
||||||
|
TESTDIR=/tmp/bsdtar-`echo $0 | sed -e 's|.*/||' -e 's|\.sh||' -e 's/[^a-z0-9_-]/_/g'`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Find bsdtar
|
||||||
|
# The first three paths here are the usual locations of a bsdtar
|
||||||
|
# that has just been built. The remaining paths might find a bsdtar
|
||||||
|
# installed on the local system somewhere.
|
||||||
|
if [ -z "$BSDTAR" ]; then
|
||||||
|
for T in "$THISDIR/../bsdtar" "$THISDIR/../../bsdtar" \
|
||||||
|
"/usr/obj`dirname $THISDIR`/bsdtar" "/usr/local/bin/bsdtar" \
|
||||||
|
"/usr/bin/bsdtar" "/usr/bin/tar" "bsdtar" "tar"
|
||||||
|
do
|
||||||
|
if ( /bin/sh -c "$T --version" | grep "bsdtar" ) >/dev/null 2>&1; then
|
||||||
|
BSDTAR="$T"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Find GNU tar
|
||||||
|
if [ -z "$GTAR" ]; then
|
||||||
|
for T in gtar gnutar tar /usr/local/bin/gtar* /usr/local/bin/gnutar* /usr/bin/gtar* /usr/bin/gnutar*
|
||||||
|
do
|
||||||
|
if ( /bin/sh -c "$T --version" | grep "GNU tar" ) >/dev/null 2>&1; then
|
||||||
|
GTAR="$T"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Find CPIO
|
||||||
|
if [ -z "$CPIO" ]; then
|
||||||
|
CPIO=cpio
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo BSDTAR=$BSDTAR '('`$BSDTAR --version`')'
|
||||||
|
echo GTAR=$GTAR '('`$GTAR --version | head -n 1`')'
|
||||||
|
echo CPIO=$CPIO '('`$CPIO --version`')'
|
||||||
|
|
||||||
|
# Remove and recreate the directory we'll use for these tests
|
||||||
|
rm -rf $TESTDIR
|
||||||
|
mkdir -p $TESTDIR || exit 1
|
||||||
|
cd $TESTDIR || exit 1
|
||||||
|
echo TESTDIR=$TESTDIR
|
||||||
|
|
16
commands/bsdtar/test/list.h
Normal file
16
commands/bsdtar/test/list.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
DEFINE_TEST(test_0)
|
||||||
|
DEFINE_TEST(test_basic)
|
||||||
|
DEFINE_TEST(test_copy)
|
||||||
|
DEFINE_TEST(test_empty_mtree)
|
||||||
|
DEFINE_TEST(test_getdate)
|
||||||
|
DEFINE_TEST(test_help)
|
||||||
|
DEFINE_TEST(test_option_T_upper)
|
||||||
|
DEFINE_TEST(test_option_q)
|
||||||
|
DEFINE_TEST(test_option_r)
|
||||||
|
DEFINE_TEST(test_option_s)
|
||||||
|
DEFINE_TEST(test_patterns)
|
||||||
|
DEFINE_TEST(test_stdio)
|
||||||
|
DEFINE_TEST(test_strip_components)
|
||||||
|
DEFINE_TEST(test_symlink_dir)
|
||||||
|
DEFINE_TEST(test_version)
|
||||||
|
DEFINE_TEST(test_windows)
|
2226
commands/bsdtar/test/main.c
Normal file
2226
commands/bsdtar/test/main.c
Normal file
File diff suppressed because it is too large
Load diff
76
commands/bsdtar/test/test-acl.sh
Executable file
76
commands/bsdtar/test/test-acl.sh
Executable file
|
@ -0,0 +1,76 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 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: src/usr.bin/tar/test/test-acl.sh,v 1.1 2007/03/11 10:36:42 kientzle Exp $
|
||||||
|
|
||||||
|
# Exercise copying of ACLs
|
||||||
|
echo "ACL handling"
|
||||||
|
# Basic test configuration
|
||||||
|
TESTDIR=/mnt/da0/acl-test
|
||||||
|
. `dirname $0`/config.sh
|
||||||
|
|
||||||
|
# Create some files with ACLs
|
||||||
|
mkdir original
|
||||||
|
cd original
|
||||||
|
touch a
|
||||||
|
chmod 664 a
|
||||||
|
setfacl -m user:bin:rw- -m group:78:r-x a \
|
||||||
|
|| echo XXX failed to set access ACL on a XXX
|
||||||
|
mkdir d
|
||||||
|
chmod 775 d
|
||||||
|
setfacl -m user:daemon:rw- -m group:78:r-x d \
|
||||||
|
|| echo XXX failed to set access ACL on d XXX
|
||||||
|
setfacl -d -m user::rw- -m group::rw- -m other::rw- -m group:79:r-- d \
|
||||||
|
|| echo XXX failed to set default ACL on d XXX
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Copy the dir with -p
|
||||||
|
echo " -p preserves ACLs"
|
||||||
|
mkdir copy
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | (cd copy; ${BSDTAR} -xpf -)
|
||||||
|
|
||||||
|
# Verify the ACLs
|
||||||
|
cd copy
|
||||||
|
if [ "user::rw- user:bin:rw- group::rw- group:78:r-x mask::rwx other::r--" \
|
||||||
|
= "`echo \`getfacl -q a\``" ]; then
|
||||||
|
# It matches!!
|
||||||
|
else
|
||||||
|
echo XXX a has wrong ACL XXX `getfacl -q a`
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "user::rwx user:daemon:rw- group::rwx group:78:r-x mask::rwx other::r-x" \
|
||||||
|
= "`echo \`getfacl -q d\``" ]; then
|
||||||
|
# It matches!!
|
||||||
|
else
|
||||||
|
echo XXX d has wrong ACL XXX `getfacl -q d`
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ "user::rw- group::rw- group:79:r-- mask::rw- other::rw-" \
|
||||||
|
= "`echo \`getfacl -q -d d\``" ]; then
|
||||||
|
# It matches!!
|
||||||
|
else
|
||||||
|
echo XXX d has wrong ACL XXX `getfacl -q -d d`
|
||||||
|
fi
|
||||||
|
|
432
commands/bsdtar/test/test-basic.sh
Executable file
432
commands/bsdtar/test/test-basic.sh
Executable file
|
@ -0,0 +1,432 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 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: src/usr.bin/tar/test/test-basic.sh,v 1.5 2007/04/18 04:35:17 kientzle Exp $
|
||||||
|
|
||||||
|
# Generate a dir tree with various data and copy it using
|
||||||
|
# a variety of tools and flags. This mostly checks that
|
||||||
|
# we can read archives we write and those written by gtar
|
||||||
|
# and cpio.
|
||||||
|
|
||||||
|
echo "Basic archiving/copy interoperability tests"
|
||||||
|
# Basic configuration
|
||||||
|
. `dirname $0`/config.sh
|
||||||
|
|
||||||
|
# We need some files to archive; generate some random files and files
|
||||||
|
# with very long names and other special attributes
|
||||||
|
mkdir -p original
|
||||||
|
cd original
|
||||||
|
# Create some long files with random text data
|
||||||
|
for f in f0 f1 f2 f3 f4 f5 f6 f7 f8 f9; do
|
||||||
|
dd if=/dev/urandom bs=1k count=100 2>/dev/null | od > $f
|
||||||
|
done
|
||||||
|
# A sparse file
|
||||||
|
dd if=/dev/zero of=sparse bs=1 count=1 oseek=100000 2>/dev/null
|
||||||
|
# Files with long names
|
||||||
|
touch a
|
||||||
|
touch ab
|
||||||
|
touch abc
|
||||||
|
touch abcd
|
||||||
|
touch abcde
|
||||||
|
touch abcdef
|
||||||
|
touch abcdefg
|
||||||
|
touch abcdefgh
|
||||||
|
touch abcdefghi
|
||||||
|
touch abcdefghij
|
||||||
|
touch abcdefghijk
|
||||||
|
touch abcdefghijkl
|
||||||
|
touch abcdefghijklm
|
||||||
|
touch abcdefghijklmn
|
||||||
|
touch abcdefghijklmno
|
||||||
|
touch abcdefghijklmnop
|
||||||
|
touch abcdefghijklmnopq
|
||||||
|
touch abcdefghijklmnopqr
|
||||||
|
touch abcdefghijklmnopqrs
|
||||||
|
touch abcdefghijklmnopqrst
|
||||||
|
touch abcdefghijklmnopqrstu
|
||||||
|
touch abcdefghijklmnopqrstuv
|
||||||
|
touch abcdefghijklmnopqrstuvw
|
||||||
|
touch abcdefghijklmnopqrstuvwx
|
||||||
|
touch abcdefghijklmnopqrstuvwxy
|
||||||
|
touch abcdefghijklmnopqrstuvwxyz
|
||||||
|
|
||||||
|
touch abcdefghijklmnopqrstuvwxyza
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzab
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabc
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcd
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcde
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdef
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefg
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefgh
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghi
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghij
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijk
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijkl
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklm
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmn
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmno
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnop
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopq
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
|
||||||
|
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyza
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabc
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcde
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmno
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnop
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopq
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
|
||||||
|
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyza
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabc
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcde
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmno
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnop
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopq
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
|
||||||
|
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyza
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabc
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcde
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmno
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnop
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopq
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
|
||||||
|
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyza
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabc
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcde
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmno
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnop
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopq
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
|
||||||
|
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyza
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabc
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcde
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmno
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnop
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopq
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
|
||||||
|
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyza
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabc
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcde
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmno
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnop
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopq
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
|
||||||
|
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyza
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabc
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcde
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmno
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnop
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopq
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy
|
||||||
|
touch abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
|
||||||
|
|
||||||
|
# A file with a long pathname
|
||||||
|
mkdir -p 1abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Basic test of archiving/dearchiving
|
||||||
|
echo " bsdtar -c | bsdtar -x"
|
||||||
|
mkdir copy-default
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | (cd copy-default; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original copy-default || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Exercise gzip compression (test compressed output with gunzip -t
|
||||||
|
echo " bsdtar -cz | gunzip -t"
|
||||||
|
(cd original && ${BSDTAR} -czf - .) | gunzip -tq
|
||||||
|
|
||||||
|
# Ensure our compression works with gunzip program
|
||||||
|
echo " bsdtar -cz | gunzip | bsdtar -x"
|
||||||
|
mkdir copy-gzip2
|
||||||
|
(cd original && ${BSDTAR} -czf - .) | gunzip -q | (cd copy-gzip2; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original copy-gzip2 || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure our decompression works with gzip program
|
||||||
|
echo " bsdtar -c | gzip | bsdtar -x"
|
||||||
|
mkdir copy-gunzip
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | gzip | (cd copy-gunzip; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original copy-gunzip || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure our gzip compression/decompression work with each other
|
||||||
|
echo " bsdtar -cz | bsdtar -x"
|
||||||
|
mkdir copy-gzip-gunzip
|
||||||
|
(cd original && ${BSDTAR} -czf - .) | (cd copy-gzip-gunzip; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original copy-gzip-gunzip || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure our decompression works with bzip2 program
|
||||||
|
echo " bsdtar -c | bzip2 | bsdtar -x"
|
||||||
|
mkdir copy-bunzip
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | bzip2 | (cd copy-bunzip; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original copy-bunzip || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure our compression works with bunzip2 program
|
||||||
|
echo " bsdtar -cy | bunzip2 | bsdtar -x"
|
||||||
|
mkdir copy-bzip2
|
||||||
|
(cd original && ${BSDTAR} -cyf - .) | bunzip2 -q | (cd copy-bzip2; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original copy-bzip2 || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure our bzip2 compression/decompression work with each other
|
||||||
|
echo " bsdtar -cy | bsdtar -x"
|
||||||
|
mkdir copy-bzip2-bunzip2
|
||||||
|
(cd original && ${BSDTAR} -cyf - .) | (cd copy-bzip2-bunzip2; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original copy-bzip2-bunzip2 || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure that archive listing works
|
||||||
|
echo " bsdtar -c | bsdtar -t"
|
||||||
|
(cd original && find .) | sort > list-original
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | ${BSDTAR} -tf - | sed 's|/$||' | sort > list-default
|
||||||
|
(diff list-original list-default || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure that listing of deflated archives works
|
||||||
|
echo " bsdtar -cz | bsdtar -t"
|
||||||
|
(cd original && ${BSDTAR} -czf - .) | ${BSDTAR} -tf - | sed 's|/$||' | sort > list-gzip
|
||||||
|
(diff list-original list-gzip || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure that listing of bzip2ed archives works
|
||||||
|
echo " bsdtar -cy | bsdtar -t"
|
||||||
|
(cd original && ${BSDTAR} -cyf - .) | ${BSDTAR} -tf - | sed 's|/$||' | sort > list-bzip2
|
||||||
|
(diff list-original list-bzip2 || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Filtering exercises different areas of the library.
|
||||||
|
echo " Convert tar archive to a tar archive"
|
||||||
|
mkdir filter-tar-tar
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | ${BSDTAR} -cf - @- | (cd filter-tar-tar; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original filter-tar-tar || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Make sure that reading and writing a tar archive doesn't change it.
|
||||||
|
echo " bsdtar -cf- @- | cmp"
|
||||||
|
(cd original && ${BSDTAR} -cf - .) > original.tar
|
||||||
|
${BSDTAR} -cf - @- < original.tar | cmp - original.tar || echo XXX FAILED XXX
|
||||||
|
|
||||||
|
# Filtering as format conversion
|
||||||
|
echo " Convert tar archive to cpio archive"
|
||||||
|
mkdir filter-tar-cpio
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | ${BSDTAR} -cf - --format=cpio @- | (cd filter-tar-cpio; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original filter-tar-cpio || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Test basic --include selection logic
|
||||||
|
echo " Convert tar to cpio with selection"
|
||||||
|
mkdir filter-tar-selected
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | ${BSDTAR} -cf - --format=cpio --include=./f3 @- | (cd filter-tar-selected; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original/f3 filter-tar-selected/f3 || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
# Should be no files in copy except for 'f3'
|
||||||
|
(cd filter-tar-selected ; ls | grep -v f3 | grep .) && echo XXX FAILED XXX
|
||||||
|
|
||||||
|
# Test --include with wildcards
|
||||||
|
echo " Convert tar to cpio selecting with wildcards"
|
||||||
|
mkdir filter-tar-selected2
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | ${BSDTAR} -cf - --format=cpio --include='./f*' @- | (cd filter-tar-selected2; ${BSDTAR} -xf -)
|
||||||
|
for f in f1 f2 f3 f4 f5 f6 f7 f8 f9; do
|
||||||
|
(diff -r original/$f filter-tar-selected2/$f || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
done
|
||||||
|
# Should be no files in copy except for 'f[0-9]'
|
||||||
|
(cd filter-tar-selected2 ; ls | grep -v 'f[0-9]' | grep .) && echo XXX FAILED XXX
|
||||||
|
|
||||||
|
# Check read/write of basic odc cpio format
|
||||||
|
echo " bsdtar -c --format=cpio | bsdtar -x"
|
||||||
|
mkdir copy-cpio
|
||||||
|
(cd original && ${BSDTAR} -cf - --format cpio .) | (cd copy-cpio; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original copy-cpio || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure we can read gtar archives
|
||||||
|
echo " gtar -c | bsdtar -x"
|
||||||
|
mkdir copy-gtar
|
||||||
|
(cd original && ${GTAR} -cf - .) | (cd copy-gtar; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original copy-gtar || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure we can read svr4crc cpio archives
|
||||||
|
echo " cpio -H crc | bsdtar -x"
|
||||||
|
mkdir copy-svr4crc
|
||||||
|
(cd original && find . | ${CPIO} -o -H crc 2>/dev/null) | (cd copy-svr4crc; ${BSDTAR} -xf -)
|
||||||
|
(diff -r original copy-svr4crc || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Ensure we generate proper shar output
|
||||||
|
echo " bsdtar -c --format=shar | /bin/sh"
|
||||||
|
mkdir copy-shar
|
||||||
|
(cd original && ${BSDTAR} -cf - --format=shar --exclude=sparse .) | (cd copy-shar; /bin/sh >/dev/null)
|
||||||
|
(diff -r --exclude=sparse original copy-shar || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Check that -u (update) picks up no new files
|
||||||
|
echo " bsdtar -u doesn't pick up unchanged files"
|
||||||
|
(cd original && ${BSDTAR} -cf ../test-u.tar -b 1 .)
|
||||||
|
cp test-u.tar test-u1.tar
|
||||||
|
(cd original && ${BSDTAR} -uf ../test-u1.tar .)
|
||||||
|
(diff test-u.tar test-u1.tar || echo XXX FAILED XXX 1>&2) | head
|
||||||
|
|
||||||
|
# Check that -u (update) does pick up actual changed files
|
||||||
|
echo " bsdtar -u does pick up changed files"
|
||||||
|
(cd original && echo hello >>f0)
|
||||||
|
cp test-u.tar test-u2.tar
|
||||||
|
(cd original && ${BSDTAR} -uf ../test-u2.tar .)
|
||||||
|
# All this really tests is that the archive did change.
|
||||||
|
cmp -s test-u.tar test-u2.tar && echo XXX FAILED XXX
|
||||||
|
# Now, unpack the archive and verify the contents (including the change to f0)
|
||||||
|
mkdir copy-u-test2
|
||||||
|
(cd copy-u-test2 && ${BSDTAR} -xf ../test-u2.tar)
|
||||||
|
(diff -r original copy-u-test2 || echo XXX FAILED XXX 1>&2) | head
|
60
commands/bsdtar/test/test-deep-dir.sh
Executable file
60
commands/bsdtar/test/test-deep-dir.sh
Executable file
|
@ -0,0 +1,60 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 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: src/usr.bin/tar/test/test-deep-dir.sh,v 1.1 2007/03/11 10:36:42 kientzle Exp $
|
||||||
|
|
||||||
|
# Stress the deep directory logic; the actual depth here seems to
|
||||||
|
# be limited by the shell. This should be restructured to get around
|
||||||
|
# that limit (possibly by using perl to build the deep tree?)
|
||||||
|
echo Deep directory tests
|
||||||
|
|
||||||
|
# Basic test configuration
|
||||||
|
. `dirname $0`/config.sh
|
||||||
|
|
||||||
|
# Create a deep dir (shell seems to be limited by PATH_MAX)
|
||||||
|
mkdir original
|
||||||
|
cd original
|
||||||
|
I=0
|
||||||
|
while [ $I -lt 200 ]
|
||||||
|
do
|
||||||
|
mkdir a$I
|
||||||
|
cd a$I
|
||||||
|
I=$(($I + 1))
|
||||||
|
done
|
||||||
|
while [ $I -gt 0 ] ; do cd ..; I=$(($I - 1)); done
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Copy this using bsdtar
|
||||||
|
echo " tar -c | tar -x"
|
||||||
|
mkdir copy
|
||||||
|
(cd original; ${BSDTAR} -cf - .) | (cd copy; ${BSDTAR} -xf -)
|
||||||
|
diff -r original copy || echo XXX FAILURE XXX
|
||||||
|
|
||||||
|
# Copy gtar->bsdtar
|
||||||
|
echo " gtar -c | tar -x"
|
||||||
|
mkdir copy-gtar
|
||||||
|
(cd original; ${GTAR} -cf - .) | (cd copy-gtar; ${BSDTAR} -xf -)
|
||||||
|
diff -r original copy-gtar || echo XXX FAILURE XXX
|
||||||
|
cd ..
|
||||||
|
|
74
commands/bsdtar/test/test-flags.sh
Executable file
74
commands/bsdtar/test/test-flags.sh
Executable file
|
@ -0,0 +1,74 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 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: src/usr.bin/tar/test/test-flags.sh,v 1.1 2007/03/11 10:36:42 kientzle Exp $
|
||||||
|
|
||||||
|
# Exercise copying of file flags
|
||||||
|
echo "File Flag handling"
|
||||||
|
# Basic test configuration
|
||||||
|
. `dirname $0`/config.sh
|
||||||
|
|
||||||
|
# Create some files with various flags set
|
||||||
|
mkdir original
|
||||||
|
FLAGS='uchg opaque nodump uappnd'
|
||||||
|
for f in $FLAGS; do
|
||||||
|
touch original/test.$f
|
||||||
|
chflags $f original/test.$f
|
||||||
|
done
|
||||||
|
#ls -ol ${TESTDIR}/original
|
||||||
|
|
||||||
|
# Copy the dir with -p
|
||||||
|
echo " -p preserves flags"
|
||||||
|
mkdir copy
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | (cd copy; ${BSDTAR} -xpf -)
|
||||||
|
# Verify that the flags are set
|
||||||
|
for f in $FLAGS; do
|
||||||
|
[ "$f" = `ls -ol copy/test.$f | awk '{print $5}'` ] \
|
||||||
|
|| echo XXX FAIL: $f not preserved with -p XXX
|
||||||
|
done
|
||||||
|
#ls -ol ${TESTDIR}/copy
|
||||||
|
|
||||||
|
# Copy the dir without -p
|
||||||
|
echo " flags omitted without -p"
|
||||||
|
mkdir copy2
|
||||||
|
(cd original && ${BSDTAR} -cf - .) | (cd copy2; ${BSDTAR} -xf -)
|
||||||
|
# Verify that the flags are not set
|
||||||
|
for f in $FLAGS; do
|
||||||
|
[ "$f" = `ls -ol copy2/test.$f | awk '{print $5}'` ] \
|
||||||
|
&& echo XXX FAIL: $f copied without -p XXX
|
||||||
|
done
|
||||||
|
#ls -ol ${TESTDIR}/copy2
|
||||||
|
|
||||||
|
# Strip off the flags so we can clean this directory on the next test
|
||||||
|
for f in $FLAGS; do
|
||||||
|
if [ $f = 'nodump' ]; then
|
||||||
|
chflags dump original/test.$f
|
||||||
|
chflags dump copy/test.$f
|
||||||
|
else
|
||||||
|
chflags no$f original/test.$f
|
||||||
|
chflags no$f copy/test.$f
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
cd ..
|
||||||
|
|
52
commands/bsdtar/test/test-nodump.sh
Executable file
52
commands/bsdtar/test/test-nodump.sh
Executable file
|
@ -0,0 +1,52 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 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: src/usr.bin/tar/test/test-nodump.sh,v 1.1 2007/03/11 10:36:42 kientzle Exp $
|
||||||
|
|
||||||
|
# Test that archiving obeys the 'nodump' flag
|
||||||
|
echo "Verify 'nodump'"
|
||||||
|
# Basic test configuration
|
||||||
|
. `dirname $0`/config.sh
|
||||||
|
|
||||||
|
# Create some sample files, 'b' is marked nodump
|
||||||
|
mkdir original
|
||||||
|
cd original
|
||||||
|
touch a
|
||||||
|
touch b
|
||||||
|
touch c
|
||||||
|
# 'chflags' on FreeBSD, 'chattr' on Linux
|
||||||
|
( chflags nodump b || chattr +d b ) >/dev/null 2>&1 || echo XXX NO chflags/chattr command XXX
|
||||||
|
|
||||||
|
# Copy files with --nodump
|
||||||
|
cd ..
|
||||||
|
mkdir copy
|
||||||
|
(cd original && ${BSDTAR} -cf - --nodump .) | (cd copy; ${BSDTAR} -xf -)
|
||||||
|
|
||||||
|
# Verify that 'b' wasn't copied
|
||||||
|
echo " File marked nodump wasn't copied"
|
||||||
|
if [ -e copy/b ] ; then echo XXX Copied nodump file XXX; fi
|
||||||
|
echo " File not marked nodump was copied"
|
||||||
|
if [ \! -e copy/a ] ; then echo XXX Failed to copy non-nodump file a XXX; fi
|
||||||
|
diff -r --exclude=b original copy || echo XXX FAILURE XXX
|
||||||
|
cd ..
|
51
commands/bsdtar/test/test-overwrite.sh
Executable file
51
commands/bsdtar/test/test-overwrite.sh
Executable file
|
@ -0,0 +1,51 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 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: src/usr.bin/tar/test/test-overwrite.sh,v 1.1 2007/03/11 10:36:42 kientzle Exp $
|
||||||
|
|
||||||
|
echo "Test overwrite avoidance"
|
||||||
|
. `dirname $0`/config.sh
|
||||||
|
|
||||||
|
# Create a file with some data.
|
||||||
|
# This ensures that test.tar actually has some data in it
|
||||||
|
# by the time tar tries to add it to itself.
|
||||||
|
dd if=/dev/urandom of=a bs=1k count=100 >/dev/null 2>&1
|
||||||
|
|
||||||
|
# Now try to implicitly add archive to itself
|
||||||
|
${BSDTAR} -cf test.tar . || echo XXX FAILED XXX
|
||||||
|
|
||||||
|
# Create another file
|
||||||
|
dd if=/dev/urandom of=b bs=1k count=100 >/dev/null 2>&1
|
||||||
|
|
||||||
|
# Try again.
|
||||||
|
${BSDTAR} -cf test.tar . || echo XXX FAILED XXX
|
||||||
|
|
||||||
|
# Extract the archive and check that the two files got archived, despite the warning
|
||||||
|
mkdir compare
|
||||||
|
cd compare
|
||||||
|
${BSDTAR} -xf ../test.tar
|
||||||
|
cmp a ../a || echo XXX a didn't archive correctly XXX
|
||||||
|
cmp b ../b || echo XXX b didn't archive correctly XXX
|
||||||
|
|
||||||
|
# TODO: Test overwrite avoidance on extract
|
40
commands/bsdtar/test/test-utf8.sh
Executable file
40
commands/bsdtar/test/test-utf8.sh
Executable file
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 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: src/usr.bin/tar/test/test-utf8.sh,v 1.1 2007/03/11 10:36:42 kientzle Exp $
|
||||||
|
|
||||||
|
echo "Test UTF8 filenames"
|
||||||
|
. `dirname $0`/config.sh
|
||||||
|
|
||||||
|
# Create some files with names in UTF8
|
||||||
|
export LC_ALL=en_US.UTF-8
|
||||||
|
touch "Greek: Γειά σας"
|
||||||
|
touch "Hebrew: שלום"
|
||||||
|
touch "Russian: Здравствуйте!"
|
||||||
|
touch "Japanese: <20><><EFBFBD><EFBFBD><EFBFBD>, コンニチハ"
|
||||||
|
touch "Chinese: <20><>"
|
||||||
|
|
||||||
|
tar -cf test.tar .
|
||||||
|
|
||||||
|
# TODO: Verify the resulting archive
|
289
commands/bsdtar/test/test.h
Normal file
289
commands/bsdtar/test/test.h
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/*
|
||||||
|
* 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: src/usr.bin/tar/test/test.h,v 1.4 2008/08/21 07:04:57 kientzle Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
/* Haiku OS */
|
||||||
|
#if defined(__HAIKU__)
|
||||||
|
/* Haiku has 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;
|
67
commands/bsdtar/test/test_0.c
Normal file
67
commands/bsdtar/test/test_0.c
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_0.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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. */
|
||||||
|
}
|
115
commands/bsdtar/test/test_basic.c
Normal file
115
commands/bsdtar/test/test_basic.c
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_basic.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $");
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
372
commands/bsdtar/test/test_copy.c
Normal file
372
commands/bsdtar/test/test_copy.c
Normal file
|
@ -0,0 +1,372 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_copy.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $");
|
||||||
|
|
||||||
|
#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();
|
||||||
|
}
|
45
commands/bsdtar/test/test_empty_mtree.c
Normal file
45
commands/bsdtar/test/test_empty_mtree.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*-
|
||||||
|
* 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");
|
||||||
|
}
|
80
commands/bsdtar/test/test_getdate.c
Normal file
80
commands/bsdtar/test/test_getdate.c
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_getdate.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $");
|
||||||
|
|
||||||
|
#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. */
|
||||||
|
}
|
84
commands/bsdtar/test/test_help.c
Normal file
84
commands/bsdtar/test/test_help.c
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_help.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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");
|
||||||
|
}
|
188
commands/bsdtar/test/test_option_T_upper.c
Normal file
188
commands/bsdtar/test/test_option_T_upper.c
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_option_T.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $");
|
||||||
|
|
||||||
|
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. */
|
||||||
|
}
|
129
commands/bsdtar/test/test_option_q.c
Normal file
129
commands/bsdtar/test/test_option_q.c
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_option_q.c,v 1.3 2008/08/22 01:35:08 kientzle Exp $");
|
||||||
|
|
||||||
|
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("..");
|
||||||
|
}
|
117
commands/bsdtar/test/test_option_r.c
Normal file
117
commands/bsdtar/test/test_option_r.c
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/*-
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
107
commands/bsdtar/test/test_option_s.c
Normal file
107
commands/bsdtar/test/test_option_s.c
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_option_T.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $");
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
184
commands/bsdtar/test/test_patterns.c
Normal file
184
commands/bsdtar/test/test_patterns.c
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_patterns.c,v 1.6 2008/08/21 22:28:00 kientzle Exp $");
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
231
commands/bsdtar/test/test_patterns_2.tar.uu
Normal file
231
commands/bsdtar/test/test_patterns_2.tar.uu
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
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
|
231
commands/bsdtar/test/test_patterns_3.tar.uu
Normal file
231
commands/bsdtar/test/test_patterns_3.tar.uu
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
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
|
641
commands/bsdtar/test/test_patterns_4.tar.uu
Normal file
641
commands/bsdtar/test/test_patterns_4.tar.uu
Normal file
|
@ -0,0 +1,641 @@
|
||||||
|
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
|
125
commands/bsdtar/test/test_stdio.c
Normal file
125
commands/bsdtar/test/test_stdio.c
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_stdio.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $");
|
||||||
|
|
||||||
|
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 */
|
||||||
|
}
|
109
commands/bsdtar/test/test_strip_components.c
Normal file
109
commands/bsdtar/test/test_strip_components.c
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_strip_components.c,v 1.2 2008/11/10 05:24:13 kientzle Exp $");
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
160
commands/bsdtar/test/test_symlink_dir.c
Normal file
160
commands/bsdtar/test/test_symlink_dir.c
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_symlink_dir.c,v 1.1 2008/09/14 02:16:04 kientzle Exp $");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
97
commands/bsdtar/test/test_version.c
Normal file
97
commands/bsdtar/test/test_version.c
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/test/test_version.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
323
commands/bsdtar/test/test_windows.c
Normal file
323
commands/bsdtar/test/test_windows.c
Normal file
|
@ -0,0 +1,323 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2009 Michihiro NAKAJIMA
|
||||||
|
* 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(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
mkfile(const char *name)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
f = fopen(name, "wb");
|
||||||
|
assert(f != NULL);
|
||||||
|
assertEqualInt(5, fwrite("01234", 1, 5, f));
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mkfullpath(char **path1, char **path2, const char *tpath, int type)
|
||||||
|
{
|
||||||
|
char *fp1 = NULL, *fp2 = NULL, *p1 = NULL, *p2 = NULL;
|
||||||
|
size_t l;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get full path name of "tpath"
|
||||||
|
*/
|
||||||
|
l = GetFullPathNameA(tpath, 0, NULL, NULL);
|
||||||
|
assert(0 != l);
|
||||||
|
fp1 = malloc(l);
|
||||||
|
assert(NULL != fp1);
|
||||||
|
fp2 = malloc(l*2);
|
||||||
|
assert(NULL != fp2);
|
||||||
|
l = GetFullPathNameA(tpath, l, fp1, NULL);
|
||||||
|
if ((type & 0x01) == 0) {
|
||||||
|
for (p1 = fp1; *p1 != '\0'; p1++)
|
||||||
|
if (*p1 == '\\')
|
||||||
|
*p1 = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case 0: /* start with "/" */
|
||||||
|
case 1: /* start with "\" */
|
||||||
|
/* strip "c:" */
|
||||||
|
memmove(fp1, fp1 + 2, l - 2);
|
||||||
|
fp1[l -2] = '\0';
|
||||||
|
p1 = fp1 + 1;
|
||||||
|
break;
|
||||||
|
case 2: /* start with "c:/" */
|
||||||
|
case 3: /* start with "c:\" */
|
||||||
|
p1 = fp1 + 3;
|
||||||
|
break;
|
||||||
|
case 4: /* start with "//./c:/" */
|
||||||
|
case 5: /* start with "\\.\c:\" */
|
||||||
|
case 6: /* start with "//?/c:/" */
|
||||||
|
case 7: /* start with "\\?\c:\" */
|
||||||
|
p1 = malloc(l + 4 + 1);
|
||||||
|
assert(NULL != p1);
|
||||||
|
if (type & 0x1)
|
||||||
|
memcpy(p1, "\\\\.\\", 4);
|
||||||
|
else
|
||||||
|
memcpy(p1, "//./", 4);
|
||||||
|
if (type == 6 || type == 7)
|
||||||
|
p1[2] = '?';
|
||||||
|
memcpy(p1 + 4, fp1, l);
|
||||||
|
p1[l + 4] = '\0';
|
||||||
|
free(fp1);
|
||||||
|
fp1 = p1;
|
||||||
|
p1 = fp1 + 7;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Strip leading drive names and converting "\" to "\\"
|
||||||
|
*/
|
||||||
|
p2 = fp2;
|
||||||
|
while (*p1 != '\0') {
|
||||||
|
if (*p1 == '\\')
|
||||||
|
*p2 = '/';
|
||||||
|
else
|
||||||
|
*p2 = *p1;
|
||||||
|
++p1;
|
||||||
|
++p2;
|
||||||
|
}
|
||||||
|
*p2++ = '\r';
|
||||||
|
*p2++ = '\n';
|
||||||
|
*p2 = '\0';
|
||||||
|
|
||||||
|
*path1 = fp1;
|
||||||
|
*path2 = fp2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *list1[] = {"aaa/", "aaa/file1", "aaa/xxa/", "aaa/xxb/",
|
||||||
|
"aaa/zzc/", "aaa/zzc/file1", "aaa/xxb/file1", "aaa/xxa/file1",
|
||||||
|
"aab/", "aac/", "abb/", "abc/", "abd/", NULL};
|
||||||
|
static const char *list2[] = {"bbb/", "bbb/file1", "bbb/xxa/", "bbb/xxb/",
|
||||||
|
"bbb/zzc/", "bbb/zzc/file1", "bbb/xxb/file1", "bbb/xxa/file1", "bbc/",
|
||||||
|
"bbd/", "bcc/", "bcd/", "bce/", NULL};
|
||||||
|
static const char *list3[] = {"aac/", "abc/", "bbc/", "bcc/", "ccc/", NULL};
|
||||||
|
static const char *list4[] = {"fff/abca", "fff/acca", NULL};
|
||||||
|
static const char *list5[] = {"aaa/file1", "aaa/xxa/", "aaa/xxa/file1",
|
||||||
|
"aaa/xxb/", "aaa/xxb/file1", "aaa/zzc/", "aaa/zzc/file1", NULL};
|
||||||
|
static const char *list6[] = {"fff/abca", "fff/acca", "aaa/xxa/",
|
||||||
|
"aaa/xxa/file1", "aaa/xxb/", "aaa/xxb/file1", NULL};
|
||||||
|
#endif /* _WIN32 && !__CYGWIN__ */
|
||||||
|
|
||||||
|
DEFINE_TEST(test_windows)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
char *fp1, *fp2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Preparre tests.
|
||||||
|
* Create directories and files.
|
||||||
|
*/
|
||||||
|
assertMakeDir("tmp", 0775);
|
||||||
|
assertChdir("tmp");
|
||||||
|
|
||||||
|
assertMakeDir("aaa", 0775);
|
||||||
|
assertMakeDir("aaa/xxa", 0775);
|
||||||
|
assertMakeDir("aaa/xxb", 0775);
|
||||||
|
assertMakeDir("aaa/zzc", 0775);
|
||||||
|
mkfile("aaa/file1");
|
||||||
|
mkfile("aaa/xxa/file1");
|
||||||
|
mkfile("aaa/xxb/file1");
|
||||||
|
mkfile("aaa/zzc/file1");
|
||||||
|
assertMakeDir("aab", 0775);
|
||||||
|
assertMakeDir("aac", 0775);
|
||||||
|
assertMakeDir("abb", 0775);
|
||||||
|
assertMakeDir("abc", 0775);
|
||||||
|
assertMakeDir("abd", 0775);
|
||||||
|
assertMakeDir("bbb", 0775);
|
||||||
|
assertMakeDir("bbb/xxa", 0775);
|
||||||
|
assertMakeDir("bbb/xxb", 0775);
|
||||||
|
assertMakeDir("bbb/zzc", 0775);
|
||||||
|
mkfile("bbb/file1");
|
||||||
|
mkfile("bbb/xxa/file1");
|
||||||
|
mkfile("bbb/xxb/file1");
|
||||||
|
mkfile("bbb/zzc/file1");
|
||||||
|
assertMakeDir("bbc", 0775);
|
||||||
|
assertMakeDir("bbd", 0775);
|
||||||
|
assertMakeDir("bcc", 0775);
|
||||||
|
assertMakeDir("bcd", 0775);
|
||||||
|
assertEqualInt(0, _mkdir("bce"));
|
||||||
|
assertEqualInt(0, _mkdir("ccc"));
|
||||||
|
assertEqualInt(0, _mkdir("fff"));
|
||||||
|
mkfile("fff/aaaa");
|
||||||
|
mkfile("fff/abba");
|
||||||
|
mkfile("fff/abca");
|
||||||
|
mkfile("fff/acba");
|
||||||
|
mkfile("fff/acca");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test1: Command line pattern matching.
|
||||||
|
*/
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive1.tar a*", testprog));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive1.tar > ../list1", testprog));
|
||||||
|
assertFileContainsLinesAnyOrder("../list1", list1);
|
||||||
|
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive2.tar b*", testprog));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive2.tar > ../list2", testprog));
|
||||||
|
assertFileContainsLinesAnyOrder("../list2", list2);
|
||||||
|
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive3.tar ??c", testprog));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive3.tar > ../list3", testprog));
|
||||||
|
assertFileContainsLinesAnyOrder("../list3", list3);
|
||||||
|
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive3b.tar *c", testprog));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive3b.tar > ../list3b", testprog));
|
||||||
|
assertFileContainsLinesAnyOrder("../list3b", list3);
|
||||||
|
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive4.tar fff/a?ca", testprog));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive4.tar > ../list4", testprog));
|
||||||
|
assertFileContainsLinesAnyOrder("../list4", list4);
|
||||||
|
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive5.tar aaa\\*", testprog));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive5.tar > ../list5", testprog));
|
||||||
|
assertFileContainsLinesAnyOrder("../list5", list5);
|
||||||
|
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive6.tar fff\\a?ca aaa\\xx*", testprog));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive6.tar > ../list6", testprog));
|
||||||
|
assertFileContainsLinesAnyOrder("../list6", list6);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test2: Archive the file start with drive letters.
|
||||||
|
*/
|
||||||
|
/* Test2a: start with "/" */
|
||||||
|
mkfullpath(&fp1, &fp2, "aaa/file1", 0);
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive10.tar %s > ../out10 2> ../err10",
|
||||||
|
testprog, fp1));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive10.tar > ../list10", testprog));
|
||||||
|
/* Check drive letters have been stripped. */
|
||||||
|
assertFileContents(fp2, strlen(fp2), "../list10");
|
||||||
|
free(fp1);
|
||||||
|
free(fp2);
|
||||||
|
|
||||||
|
/* Test2b: start with "\" */
|
||||||
|
mkfullpath(&fp1, &fp2, "aaa/file1", 1);
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive11.tar %s > ../out11 2> ../err11",
|
||||||
|
testprog, fp1));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive11.tar > ../list11", testprog));
|
||||||
|
/* Check drive letters have been stripped. */
|
||||||
|
assertFileContents(fp2, strlen(fp2), "../list11");
|
||||||
|
free(fp1);
|
||||||
|
free(fp2);
|
||||||
|
|
||||||
|
/* Test2c: start with "c:/" */
|
||||||
|
mkfullpath(&fp1, &fp2, "aaa/file1", 2);
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive12.tar %s > ../out12 2> ../err12",
|
||||||
|
testprog, fp1));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive12.tar > ../list12", testprog));
|
||||||
|
/* Check drive letters have been stripped. */
|
||||||
|
assertFileContents(fp2, strlen(fp2), "../list12");
|
||||||
|
free(fp1);
|
||||||
|
free(fp2);
|
||||||
|
|
||||||
|
/* Test2d: start with "c:\" */
|
||||||
|
mkfullpath(&fp1, &fp2, "aaa/file1", 3);
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive13.tar %s > ../out13 2> ../err13",
|
||||||
|
testprog, fp1));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive13.tar > ../list13", testprog));
|
||||||
|
/* Check drive letters have been stripped. */
|
||||||
|
assertFileContents(fp2, strlen(fp2), "../list13");
|
||||||
|
free(fp1);
|
||||||
|
free(fp2);
|
||||||
|
|
||||||
|
/* Test2e: start with "//./c:/" */
|
||||||
|
mkfullpath(&fp1, &fp2, "aaa/file1", 4);
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive14.tar %s > ../out14 2> ../err14",
|
||||||
|
testprog, fp1));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive14.tar > ../list14", testprog));
|
||||||
|
/* Check drive letters have been stripped. */
|
||||||
|
assertFileContents(fp2, strlen(fp2), "../list14");
|
||||||
|
free(fp1);
|
||||||
|
free(fp2);
|
||||||
|
|
||||||
|
/* Test2f: start with "\\.\c:\" */
|
||||||
|
mkfullpath(&fp1, &fp2, "aaa/file1", 5);
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive15.tar %s > ../out15 2> ../err15",
|
||||||
|
testprog, fp1));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive15.tar > ../list15", testprog));
|
||||||
|
/* Check drive letters have been stripped. */
|
||||||
|
assertFileContents(fp2, strlen(fp2), "../list15");
|
||||||
|
free(fp1);
|
||||||
|
free(fp2);
|
||||||
|
|
||||||
|
/* Test2g: start with "//?/c:/" */
|
||||||
|
mkfullpath(&fp1, &fp2, "aaa/file1", 6);
|
||||||
|
failure("fp1=%s, fp2=%s", fp1, fp2);
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive16.tar %s > ../out16 2> ../err16",
|
||||||
|
testprog, fp1));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive16.tar > ../list16", testprog));
|
||||||
|
/* Check drive letters have been stripped. */
|
||||||
|
assertFileContents(fp2, strlen(fp2), "../list16");
|
||||||
|
free(fp1);
|
||||||
|
free(fp2);
|
||||||
|
|
||||||
|
/* Test2h: start with "\\?\c:\" */
|
||||||
|
mkfullpath(&fp1, &fp2, "aaa/file1", 7);
|
||||||
|
failure("fp1=%s, fp2=%s", fp1, fp2);
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -cf ../archive17.tar %s > ../out17 2> ../err17",
|
||||||
|
testprog, fp1));
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -tf ../archive17.tar > ../list17", testprog));
|
||||||
|
/* Check drive letters have been stripped. */
|
||||||
|
assertFileContents(fp2, strlen(fp2), "../list17");
|
||||||
|
free(fp1);
|
||||||
|
free(fp2);
|
||||||
|
#else
|
||||||
|
skipping("Windows specific test");
|
||||||
|
#endif /* _WIN32 && !__CYGWIN__ */
|
||||||
|
}
|
821
commands/bsdtar/tree.c
Normal file
821
commands/bsdtar/tree.c
Normal file
|
@ -0,0 +1,821 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/tree.c,v 1.9 2008/11/27 05:49:52 kientzle Exp $");
|
||||||
|
|
||||||
|
#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 heirarchy 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);
|
||||||
|
}
|
141
commands/bsdtar/tree.h
Normal file
141
commands/bsdtar/tree.h
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/tree.h,v 1.4 2008/11/27 05:49:52 kientzle Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* 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 *);
|
577
commands/bsdtar/util.c
Normal file
577
commands/bsdtar/util.c
Normal file
|
@ -0,0 +1,577 @@
|
||||||
|
/*-
|
||||||
|
* 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: src/usr.bin/tar/util.c,v 1.23 2008/12/15 06:00:25 kientzle Exp $");
|
||||||
|
|
||||||
|
#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)
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef __minix
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
const char *
|
||||||
|
tar_i64toa(int32_t n0)
|
||||||
|
{
|
||||||
|
static char buff[24];
|
||||||
|
int32_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;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
1180
commands/bsdtar/write.c
Normal file
1180
commands/bsdtar/write.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue