diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2009-11-15 18:32:03 +0100 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2009-11-15 18:32:03 +0100 |
| commit | cb3baab306e5951dc3a176fd9061f596a05b4729 (patch) | |
| tree | 1074fd193e9be7e62aa431effde391213705fc36 /libarchive/libarchive-2.5.5/tar | |
| parent | c10a5c533a5b71c03f0e8d52dea81eb77dbebfd7 (diff) | |
| download | tuxcmd-modules-cb3baab306e5951dc3a176fd9061f596a05b4729.tar.xz | |
Rebase libarchive to 2.7.1
Diffstat (limited to 'libarchive/libarchive-2.5.5/tar')
25 files changed, 0 insertions, 11325 deletions
diff --git a/libarchive/libarchive-2.5.5/tar/bsdtar.1 b/libarchive/libarchive-2.5.5/tar/bsdtar.1 deleted file mode 100644 index e790d60..0000000 --- a/libarchive/libarchive-2.5.5/tar/bsdtar.1 +++ /dev/null @@ -1,822 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/usr.bin/tar/bsdtar.1,v 1.43 2008/05/26 17:10:10 kientzle Exp $ -.\" -.Dd May 15, 2008 -.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 | directories -.Nm -.Brq Fl r | Fl u -.Fl f Ar archive-file -.Op Ar options -.Op Ar files | 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 ( Fl W Cm check-links ) -(c and r modes only) -Issue a warning message unless all links to each file are archived. -.It Fl -chroot ( Fl W Cm 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 ( Fl W Cm exclude Ns = Ns 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 ( Fl W Cm format Ns = Ns 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 ( Fl W Cm include Ns = Ns 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 ( Fl W Cm 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 ( Fl W Cm newer Ns = Ns 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 ( Fl W Cm newer-mtime Ns = Ns 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 ( Fl W Cm newer-than Ns = Ns 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 ( Fl W Cm newer-mtime-than Ns = Ns Pa file ) -(c, r, u modes only) -Like -.Fl -newer-than , -except it compares mtime entries instead of ctime entries. -.It Fl -nodump ( Fl W Cm nodump ) -(c and r modes only) -Honor the nodump file flag by skipping this file. -.It Fl -null ( Fl W Cm 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 ( Fl W Cm one-file-system ) -(c, r, and u modes) -Do not cross mount points. -.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 ( Fl W Cm strip-components Ns = Ns Ar count ) -(x and t 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 /old/new/[gps]. -old is a basic regular expression. -If it doesn't apply, the pattern is skipped. -new is the replacement string of the matched part. -~ 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 W Ar longopt=value -Long options (preceded by -.Fl - ) -are only supported directly on systems that have the -.Xr getopt_long 3 -function. -The -.Fl W -option can be used to access long options on systems that -do not support this function. -.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 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 . -.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 -On systems that support getopt_long(), additional long options -are available 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. diff --git a/libarchive/libarchive-2.5.5/tar/bsdtar.c b/libarchive/libarchive-2.5.5/tar/bsdtar.c deleted file mode 100644 index 1c13cc6..0000000 --- a/libarchive/libarchive-2.5.5/tar/bsdtar.c +++ /dev/null @@ -1,959 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.91 2008/05/26 17:10:10 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_GETOPT_LONG -#include <getopt.h> -#else -struct option { - const char *name; - int has_arg; - int *flag; - int val; -}; -#define no_argument 0 -#define required_argument 1 -#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 -#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" - -#if !HAVE_DECL_OPTARG -extern int optarg; -#endif - -#if !HAVE_DECL_OPTIND -extern int optind; -#endif - -/* - * 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 - -#ifndef _PATH_DEFTAPE -#define _PATH_DEFTAPE "/dev/tape" -#endif - -/* External function to parse a date/time string (from getdate.y) */ -time_t get_date(const char *); - -static int bsdtar_getopt(struct bsdtar *, const char *optstring, - const struct option **poption); -static void long_help(struct bsdtar *); -static void only_mode(struct bsdtar *, const char *opt, - const char *valid); -static char ** rewrite_argv(struct bsdtar *, - int *argc, char ** src_argv, - const char *optstring); -static void set_mode(struct bsdtar *, char opt); -static void version(void); - -/* - * The leading '+' here forces the GNU version of getopt() (as well as - * both the GNU and BSD versions of getopt_long) to stop at the first - * non-option. Otherwise, GNU getopt() permutes the arguments and - * screws up -C processing. - */ -static const char *tar_opts = "+Bb:C:cf:HhI:jkLlmnOoPprts:ST:UuvW:wX:xyZz"; - -/* - * Most of these long options are deliberately not documented. They - * are provided only to make life easier for people who also use GNU tar. - * The only long options documented in the manual page are the ones - * with no corresponding short option, such as --exclude, --nodump, - * and --fast-read. - * - * On systems that lack getopt_long, long options can be specified - * using -W longopt and -W longopt=value, e.g. "-W nodump" is the same - * as "--nodump" and "-W exclude=pattern" is the same as "--exclude - * pattern". This does not rely the GNU getopt() "W;" extension, so - * should work correctly on any system with a POSIX-compliant getopt(). - */ - -/* Fake short equivalents for long options that otherwise lack them. */ -enum { - OPTION_CHECK_LINKS = 1, - OPTION_CHROOT, - OPTION_EXCLUDE, - OPTION_FORMAT, - OPTION_HELP, - OPTION_INCLUDE, - OPTION_KEEP_NEWER_FILES, - 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_STRIP_COMPONENTS, - OPTION_TOTALS, - OPTION_USE_COMPRESS_PROGRAM, - OPTION_VERSION -}; - -/* - * If you add anything, be very careful to keep this list properly - * sorted, as the -W logic relies on it. - */ -static const struct option tar_longopts[] = { - { "absolute-paths", no_argument, NULL, 'P' }, - { "append", no_argument, NULL, 'r' }, - { "block-size", required_argument, NULL, 'b' }, - { "bunzip2", no_argument, NULL, 'j' }, - { "bzip", no_argument, NULL, 'j' }, - { "bzip2", no_argument, NULL, 'j' }, - { "cd", required_argument, NULL, 'C' }, - { "check-links", no_argument, NULL, OPTION_CHECK_LINKS }, - { "chroot", no_argument, NULL, OPTION_CHROOT }, - { "compress", no_argument, NULL, 'Z' }, - { "confirmation", no_argument, NULL, 'w' }, - { "create", no_argument, NULL, 'c' }, - { "dereference", no_argument, NULL, 'L' }, - { "directory", required_argument, NULL, 'C' }, - { "exclude", required_argument, NULL, OPTION_EXCLUDE }, - { "exclude-from", required_argument, NULL, 'X' }, - { "extract", no_argument, NULL, 'x' }, - { "fast-read", no_argument, NULL, 'q' }, - { "file", required_argument, NULL, 'f' }, - { "files-from", required_argument, NULL, 'T' }, - { "format", required_argument, NULL, OPTION_FORMAT }, - { "gunzip", no_argument, NULL, 'z' }, - { "gzip", no_argument, NULL, 'z' }, - { "help", no_argument, NULL, OPTION_HELP }, - { "include", required_argument, NULL, OPTION_INCLUDE }, - { "interactive", no_argument, NULL, 'w' }, - { "insecure", no_argument, NULL, 'P' }, - { "keep-newer-files", no_argument, NULL, OPTION_KEEP_NEWER_FILES }, - { "keep-old-files", no_argument, NULL, 'k' }, - { "list", no_argument, NULL, 't' }, - { "modification-time", no_argument, NULL, 'm' }, - { "newer", required_argument, NULL, OPTION_NEWER_CTIME }, - { "newer-ctime", required_argument, NULL, OPTION_NEWER_CTIME }, - { "newer-ctime-than", required_argument, NULL, OPTION_NEWER_CTIME_THAN }, - { "newer-mtime", required_argument, NULL, OPTION_NEWER_MTIME }, - { "newer-mtime-than", required_argument, NULL, OPTION_NEWER_MTIME_THAN }, - { "newer-than", required_argument, NULL, OPTION_NEWER_CTIME_THAN }, - { "nodump", no_argument, NULL, OPTION_NODUMP }, - { "norecurse", no_argument, NULL, 'n' }, - { "no-recursion", no_argument, NULL, 'n' }, - { "no-same-owner", no_argument, NULL, OPTION_NO_SAME_OWNER }, - { "no-same-permissions",no_argument, NULL, OPTION_NO_SAME_PERMISSIONS }, - { "null", no_argument, NULL, OPTION_NULL }, - { "numeric-owner", no_argument, NULL, OPTION_NUMERIC_OWNER }, - { "one-file-system", no_argument, NULL, OPTION_ONE_FILE_SYSTEM }, - { "posix", no_argument, NULL, OPTION_POSIX }, - { "preserve-permissions", no_argument, NULL, 'p' }, - { "read-full-blocks", no_argument, NULL, 'B' }, - { "same-permissions", no_argument, NULL, 'p' }, - { "strip-components", required_argument, NULL, OPTION_STRIP_COMPONENTS }, - { "to-stdout", no_argument, NULL, 'O' }, - { "totals", no_argument, NULL, OPTION_TOTALS }, - { "uncompress", no_argument, NULL, 'Z' }, - { "unlink", no_argument, NULL, 'U' }, - { "unlink-first", no_argument, NULL, 'U' }, - { "update", no_argument, NULL, 'u' }, - { "use-compress-program", - required_argument, NULL, OPTION_USE_COMPRESS_PROGRAM }, - { "verbose", no_argument, NULL, 'v' }, - { "version", no_argument, NULL, OPTION_VERSION }, - { NULL, 0, NULL, 0 } -}; - -/* 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; - const struct option *option; - int opt, t; - char option_o; - char possible_help_request; - char buff[16]; - - /* - * Use a pointer for consistency, but stack-allocated storage - * for ease of cleanup. - */ - bsdtar = &bsdtar_storage; - memset(bsdtar, 0, sizeof(*bsdtar)); - bsdtar->fd = -1; /* Mark as "unused" */ - option_o = 0; - - /* Need bsdtar->progname before calling bsdtar_warnc. */ - if (*argv == NULL) - bsdtar->progname = "bsdtar"; - else { - bsdtar->progname = strrchr(*argv, '/'); - if (bsdtar->progname != NULL) - bsdtar->progname++; - else - bsdtar->progname = *argv; - } - - if (setlocale(LC_ALL, "") == NULL) - bsdtar_warnc(bsdtar, 0, "Failed to set default locale"); -#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; - - /* Defaults for root user: */ - 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; - } - - /* Rewrite traditional-style tar arguments, if used. */ - argv = rewrite_argv(bsdtar, &argc, argv, tar_opts); - - bsdtar->argv = argv; - bsdtar->argc = argc; - - /* Process all remaining arguments now. */ - /* - * 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, tar_opts, &option)) != -1) { - switch (opt) { - case 'B': /* GNU tar */ - /* libarchive doesn't need this; just ignore it. */ - break; - case 'b': /* SUSv2 */ - t = atoi(optarg); - if (t <= 0 || t > 1024) - bsdtar_errc(bsdtar, 1, 0, - "Argument to -b is out of range (1..1024)"); - bsdtar->bytes_per_block = 512 * t; - break; - case 'C': /* GNU tar */ - set_chdir(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 (exclude(bsdtar, optarg)) - bsdtar_errc(bsdtar, 1, 0, - "Couldn't exclude %s\n", optarg); - break; - case OPTION_FORMAT: /* GNU tar, others */ - bsdtar->create_format = optarg; - break; - case 'f': /* SUSv2 */ - bsdtar->filename = 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(bsdtar); - 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 = optarg; - break; - case OPTION_INCLUDE: - /* - * Noone else has the @archive extension, so - * noone else needs this to filter entries - * when transforming archives. - */ - if (include(bsdtar, optarg)) - bsdtar_errc(bsdtar, 1, 0, - "Failed to add %s to inclusion list", - optarg); - break; - case 'j': /* GNU tar */ -#if HAVE_LIBBZ2 - if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, - "Can't specify both -%c and -%c", opt, - bsdtar->create_compression); - bsdtar->create_compression = opt; -#else - bsdtar_warnc(bsdtar, 0, "-j compression not supported by this version of bsdtar"); - usage(bsdtar); -#endif - 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 '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(optarg); - break; - case OPTION_NEWER_CTIME_THAN: - { - struct stat st; - if (stat(optarg, &st) != 0) - bsdtar_errc(bsdtar, 1, 0, - "Can't open file %s", 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(optarg); - break; - case OPTION_NEWER_MTIME_THAN: - { - struct stat st; - if (stat(optarg, &st) != 0) - bsdtar_errc(bsdtar, 1, 0, - "Can't open file %s", 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, optarg); -#else - bsdtar_warnc(bsdtar, 0, "-s is not supported by this version of bsdtar"); - usage(bsdtar); -#endif - break; - case OPTION_STRIP_COMPONENTS: /* GNU tar 1.15 */ - bsdtar->strip_components = atoi(optarg); - break; - case 'T': /* GNU tar */ - bsdtar->names_from_file = 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_getop(), so -W is not available here. - */ - case 'W': /* Obscure, but useful GNU convention. */ - break; -#endif - case 'w': /* SUSv2 */ - bsdtar->option_interactive = 1; - break; - case 'X': /* GNU tar */ - if (exclude_from_file(bsdtar, optarg)) - bsdtar_errc(bsdtar, 1, 0, - "failed to process exclusions from file %s", - optarg); - break; - case 'x': /* SUSv2 */ - set_mode(bsdtar, opt); - break; - case 'y': /* FreeBSD version of GNU tar */ -#if HAVE_LIBBZ2 - if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, - "Can't specify both -%c and -%c", opt, - bsdtar->create_compression); - bsdtar->create_compression = opt; -#else - bsdtar_warnc(bsdtar, 0, "-y compression not supported by this version of bsdtar"); - usage(bsdtar); -#endif - break; - case 'Z': /* GNU tar */ - if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 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 HAVE_LIBZ - if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, - "Can't specify both -%c and -%c", opt, - bsdtar->create_compression); - bsdtar->create_compression = opt; -#else - bsdtar_warnc(bsdtar, 0, "-z compression not supported by this version of bsdtar"); - usage(bsdtar); -#endif - break; - case OPTION_USE_COMPRESS_PROGRAM: - bsdtar->compress_program = optarg; - break; - default: - usage(bsdtar); - } - } - - /* - * Sanity-check options. - */ - - /* If no "real" mode was specified, treat -h as --help. */ - if ((bsdtar->mode == '\0') && possible_help_request) { - long_help(bsdtar); - exit(0); - } - - /* Otherwise, a mode is required. */ - if (bsdtar->mode == '\0') - bsdtar_errc(bsdtar, 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"); - - bsdtar->argc -= optind; - bsdtar->argv += optind; - - 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; - } - - cleanup_exclusions(bsdtar); -#if HAVE_REGEX_H - cleanup_substitution(bsdtar); -#endif - - if (bsdtar->return_value != 0) - bsdtar_warnc(bsdtar, 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) - bsdtar_errc(bsdtar, 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) - bsdtar_errc(bsdtar, 1, 0, - "Option %s is not permitted in mode -%c", - opt, bsdtar->mode); -} - - -/*- - * Convert traditional tar arguments into new-style. - * For example, - * tar tvfb file.tar 32 --exclude FOO - * will be converted to - * tar -t -v -f file.tar -b 32 --exclude FOO - * - * This requires building a new argv array. The initial bundled word - * gets expanded into a new string that looks like "-t\0-v\0-f\0-b\0". - * The new argv array has pointers into this string intermingled with - * pointers to the existing arguments. Arguments are moved to - * immediately follow their options. - * - * The optstring argument here is the same one passed to getopt(3). - * It is used to determine which option letters have trailing arguments. - */ -char ** -rewrite_argv(struct bsdtar *bsdtar, int *argc, char **src_argv, - const char *optstring) -{ - char **new_argv, **dest_argv; - const char *p; - char *src, *dest; - - if (src_argv[0] == NULL || src_argv[1] == NULL || - src_argv[1][0] == '-' || src_argv[1][0] == '\0') - return (src_argv); - - *argc += strlen(src_argv[1]) - 1; - new_argv = malloc((*argc + 1) * sizeof(new_argv[0])); - if (new_argv == NULL) - bsdtar_errc(bsdtar, 1, errno, "No Memory"); - - dest_argv = new_argv; - *dest_argv++ = *src_argv++; - - dest = malloc(strlen(*src_argv) * 3); - if (dest == NULL) - bsdtar_errc(bsdtar, 1, errno, "No memory"); - for (src = *src_argv++; *src != '\0'; src++) { - *dest_argv++ = dest; - *dest++ = '-'; - *dest++ = *src; - *dest++ = '\0'; - /* If option takes an argument, insert that into the list. */ - for (p = optstring; p != NULL && *p != '\0'; p++) { - if (*p != *src) - continue; - if (p[1] != ':') /* No arg required, done. */ - break; - if (*src_argv == NULL) /* No arg available? Error. */ - bsdtar_errc(bsdtar, 1, 0, - "Option %c requires an argument", - *src); - *dest_argv++ = *src_argv++; - break; - } - } - - /* Copy remaining arguments, including trailing NULL. */ - while ((*dest_argv++ = *src_argv++) != NULL) - ; - - return (new_argv); -} - -void -usage(struct bsdtar *bsdtar) -{ - const char *p; - - p = bsdtar->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); -#ifdef HAVE_GETOPT_LONG - fprintf(stderr, " Help: %s --help\n", p); -#else - fprintf(stderr, " Help: %s -h\n", p); -#endif - 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 Compress archive with gzip/bzip2\n" - " --format {ustar|pax|cpio|shar} Select archive format\n" -#ifdef HAVE_GETOPT_LONG - " --exclude <pattern> Skip files that match pattern\n" -#else - " -W exclude=<pattern> Skip files that match pattern\n" -#endif - " -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(struct bsdtar *bsdtar) -{ - const char *prog; - const char *p; - - prog = bsdtar->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(); -} - -static int -bsdtar_getopt(struct bsdtar *bsdtar, const char *optstring, - const struct option **poption) -{ - char *p, *q; - const struct option *option; - int opt; - int option_index; - size_t option_length; - - option_index = -1; - *poption = NULL; - -#ifdef HAVE_GETOPT_LONG - opt = getopt_long(bsdtar->argc, bsdtar->argv, optstring, - tar_longopts, &option_index); - if (option_index > -1) - *poption = tar_longopts + option_index; -#else - opt = getopt(bsdtar->argc, bsdtar->argv, optstring); -#endif - - /* Support long options through -W longopt=value */ - if (opt == 'W') { - p = optarg; - q = strchr(optarg, '='); - if (q != NULL) { - option_length = (size_t)(q - p); - optarg = q + 1; - } else { - option_length = strlen(p); - optarg = NULL; - } - option = tar_longopts; - while (option->name != NULL && - (strlen(option->name) < option_length || - strncmp(p, option->name, option_length) != 0 )) { - option++; - } - - if (option->name != NULL) { - *poption = option; - opt = option->val; - - /* If the first match was exact, we're done. */ - if (strncmp(p, option->name, strlen(option->name)) == 0) { - while (option->name != NULL) - option++; - } else { - /* Check if there's another match. */ - option++; - while (option->name != NULL && - (strlen(option->name) < option_length || - strncmp(p, option->name, option_length) != 0)) { - option++; - } - } - if (option->name != NULL) - bsdtar_errc(bsdtar, 1, 0, - "Ambiguous option %s " - "(matches both %s and %s)", - p, (*poption)->name, option->name); - - if ((*poption)->has_arg == required_argument - && optarg == NULL) - bsdtar_errc(bsdtar, 1, 0, - "Option \"%s\" requires argument", p); - } else { - opt = '?'; - /* TODO: Set up a fake 'struct option' for - * error reporting... ? ? ? */ - } - } - - return (opt); -} diff --git a/libarchive/libarchive-2.5.5/tar/bsdtar.h b/libarchive/libarchive-2.5.5/tar/bsdtar.h deleted file mode 100644 index 4153a44..0000000 --- a/libarchive/libarchive-2.5.5/tar/bsdtar.h +++ /dev/null @@ -1,139 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/usr.bin/tar/bsdtar.h,v 1.33 2008/05/26 17:10:10 kientzle Exp $ - */ - -#include "bsdtar_platform.h" -#include <stdio.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 */ - 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 */ - struct archive *archive; - const char *progname; - int argc; - char **argv; - 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_entry_linkresolver *resolver; - struct archive_dir *archive_dir; /* for write.c */ - struct name_cache *gname_cache; /* for write.c */ - struct 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 */ -}; - -void bsdtar_errc(struct bsdtar *, int _eval, int _code, - const char *fmt, ...); -void bsdtar_warnc(struct bsdtar *, int _code, const char *fmt, ...); -void cleanup_exclusions(struct bsdtar *); -void do_chdir(struct bsdtar *); -int edit_pathname(struct bsdtar *, struct archive_entry *); -int exclude(struct bsdtar *, const char *pattern); -int exclude_from_file(struct bsdtar *, const char *pathname); -int excluded(struct bsdtar *, const char *pathname); -int include(struct bsdtar *, const char *pattern); -int include_from_file(struct bsdtar *, const char *pathname); -int pathcmp(const char *a, const char *b); -int process_lines(struct bsdtar *bsdtar, const char *pathname, - int (*process)(struct bsdtar *, const char *)); -void safe_fprintf(FILE *, const char *fmt, ...); -void set_chdir(struct bsdtar *, const char *newdir); -void siginfo_init(struct bsdtar *); -void siginfo_setinfo(struct bsdtar *, const char * oper, - const char * path, int64_t size); -void siginfo_printinfo(struct bsdtar *, off_t progress); -void siginfo_done(struct bsdtar *); -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); -int unmatched_inclusions(struct bsdtar *bsdtar); -int unmatched_inclusions_warn(struct bsdtar *bsdtar, const char *msg); -void usage(struct bsdtar *); -int yes(const char *fmt, ...); - -#if HAVE_REGEX_H -void add_substitution(struct bsdtar *, const char *); -int apply_substitution(struct bsdtar *, const char *, char **, int); -void cleanup_substitution(struct bsdtar *); -#endif diff --git a/libarchive/libarchive-2.5.5/tar/bsdtar_platform.h b/libarchive/libarchive-2.5.5/tar/bsdtar_platform.h deleted file mode 100644 index ccb9d3c..0000000 --- a/libarchive/libarchive-2.5.5/tar/bsdtar_platform.h +++ /dev/null @@ -1,150 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/usr.bin/tar/bsdtar_platform.h,v 1.25 2008/01/02 00:23:00 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 -#elif defined(HAVE_CONFIG_H) -/* Most POSIX platforms use the 'configure' script to build config.h */ -#include "../config.h" -#else -/* Warn if bsdtar hasn't been (automatically or manually) configured. */ -#error Oops: No config.h and no built-in configuration in bsdtar_platform.h. -#endif /* !HAVE_CONFIG_H */ - -/* No non-FreeBSD platform will have __FBSDID, so just define it here. */ -#ifdef __FreeBSD__ -#include <sys/cdefs.h> /* For __FBSDID */ -#else -/* Just leaving this macro replacement empty leads to a dangling semicolon. */ -#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 - -/* - * Does this platform have complete-looking POSIX-style ACL support, - * including some variant of the acl_get_perm() function (which was - * omitted from the POSIX.1e draft)? - */ -#if HAVE_SYS_ACL_H && HAVE_ACL_PERMSET_T && HAVE_ACL_USER -#if HAVE_ACL_GET_PERM || HAVE_ACL_GET_PERM_NP -#define HAVE_POSIX_ACL 1 -#endif -#endif - -#ifdef HAVE_LIBACL -#include <acl/libacl.h> -#endif - -#if HAVE_ACL_GET_PERM -#define ACL_GET_PERM acl_get_perm -#else -#if HAVE_ACL_GET_PERM_NP -#define ACL_GET_PERM acl_get_perm_np -#endif -#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 - - -/* - * We need to be able to display a filesize using printf(). The type - * and format string here must be compatible with one another and - * large enough for any file. - */ -#if HAVE_UINTMAX_T -#define BSDTAR_FILESIZE_TYPE uintmax_t -#define BSDTAR_FILESIZE_PRINTF "%ju" -#else -#if HAVE_UNSIGNED_LONG_LONG -#define BSDTAR_FILESIZE_TYPE unsigned long long -#define BSDTAR_FILESIZE_PRINTF "%llu" -#else -#define BSDTAR_FILESIZE_TYPE unsigned long -#define BSDTAR_FILESIZE_PRINTF "%lu" -#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 -#else -#if 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 -#else -#define ARCHIVE_STAT_CTIME_NANOS(st) (0) -#define ARCHIVE_STAT_MTIME_NANOS(st) (0) -#endif -#endif - -#endif /* !BSDTAR_PLATFORM_H_INCLUDED */ diff --git a/libarchive/libarchive-2.5.5/tar/getdate.c b/libarchive/libarchive-2.5.5/tar/getdate.c deleted file mode 100644 index 895320b..0000000 --- a/libarchive/libarchive-2.5.5/tar/getdate.c +++ /dev/null @@ -1,2344 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.1. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Written by Richard Stallman by simplifying the original so called - ``semantic'' parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.1" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - tAGO = 258, - tDAY = 259, - tDAYZONE = 260, - tAMPM = 261, - tMONTH = 262, - tMONTH_UNIT = 263, - tSEC_UNIT = 264, - tUNUMBER = 265, - tZONE = 266, - tDST = 267 - }; -#endif -/* Tokens. */ -#define tAGO 258 -#define tDAY 259 -#define tDAYZONE 260 -#define tAMPM 261 -#define tMONTH 262 -#define tMONTH_UNIT 263 -#define tSEC_UNIT 264 -#define tUNUMBER 265 -#define tZONE 266 -#define tDST 267 - - - - -/* Copy the first part of user declarations. */ -#line 1 "getdate.y" - -/* - * March 2005: Further modified and simplified by Tim Kientzle: - * Eliminate minutes-based calculations (just do everything in - * seconds), have lexer only recognize unsigned integers (handle '+' - * and '-' characters in grammar), combine tables into one table with - * explicit abbreviation notes, do am/pm adjustments in the grammar - * (eliminate some state variables and post-processing). Among other - * things, these changes eliminated two shift/reduce conflicts. (Went - * from 10 to 8.) - * All of Tim Kientzle's changes to this file are public domain. - */ - -/* -** Originally written by Steven M. Bellovin <smb@research.att.com> while -** at the University of North Carolina at Chapel Hill. Later tweaked by -** a couple of people on Usenet. Completely overhauled by Rich $alz -** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990; -** -** This grammar has 10 shift/reduce conflicts. -** -** This code is in the public domain and has no copyright. -*/ -/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */ -/* SUPPRESS 288 on yyerrlab *//* Label unused */ - -#ifdef __FreeBSD__ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/usr.bin/tar/getdate.y,v 1.9 2007/07/20 01:27:50 kientzle Exp $"); -#endif - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#define yyparse getdate_yyparse -#define yylex getdate_yylex -#define yyerror getdate_yyerror - -static int yyparse(void); -static int yylex(void); -static int yyerror(const char *); - -time_t get_date(char *); - -#define EPOCH 1970 -#define HOUR(x) ((time_t)(x) * 60) -#define SECSPERDAY (24L * 60L * 60L) - -/* -** Daylight-savings mode: on, off, or not yet known. -*/ -typedef enum _DSTMODE { - DSTon, DSToff, DSTmaybe -} DSTMODE; - -/* -** Meridian: am or pm. -*/ -enum { tAM, tPM }; - -/* -** Global variables. We could get rid of most of these by using a good -** union as the yacc stack. (This routine was originally written before -** yacc had the %union construct.) Maybe someday; right now we only use -** the %union very rarely. -*/ -static char *yyInput; - -static DSTMODE yyDSTmode; -static time_t yyDayOrdinal; -static time_t yyDayNumber; -static int yyHaveDate; -static int yyHaveDay; -static int yyHaveRel; -static int yyHaveTime; -static int yyHaveZone; -static time_t yyTimezone; -static time_t yyDay; -static time_t yyHour; -static time_t yyMinutes; -static time_t yyMonth; -static time_t yySeconds; -static time_t yyYear; -static time_t yyRelMonth; -static time_t yyRelSeconds; - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 92 "getdate.y" -typedef union YYSTYPE { - time_t Number; -} YYSTYPE; -/* Line 196 of yacc.c. */ -#line 204 "tar/getdate.c" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 219 of yacc.c. */ -#line 216 "tar/getdate.c" - -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus)) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -#if ! defined (yyoverflow) || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# else -# define YYSTACK_ALLOC alloca -# if defined (__STDC__) || defined (__cplusplus) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# define YYINCLUDED_STDLIB_H -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1) -# endif -# ifdef __cplusplus -extern "C" { -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \ - && (defined (__STDC__) || defined (__cplusplus))) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \ - && (defined (__STDC__) || defined (__cplusplus))) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifdef __cplusplus -} -# endif -# endif -#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short int yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined (__GNUC__) && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined (__STDC__) || defined (__cplusplus) - typedef signed char yysigned_char; -#else - typedef short int yysigned_char; -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 2 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 50 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 18 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 11 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 41 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 59 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 267 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const unsigned char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 13, 16, 14, 2, 17, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 15, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const unsigned char yyprhs[] = -{ - 0, 0, 3, 4, 7, 9, 11, 13, 15, 17, - 19, 22, 24, 27, 31, 35, 39, 45, 47, 49, - 52, 54, 57, 60, 64, 70, 76, 82, 85, 90, - 93, 97, 100, 102, 106, 110, 113, 115, 119, 123, - 126, 128 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yysigned_char yyrhs[] = -{ - 19, 0, -1, -1, 19, 20, -1, 21, -1, 23, - -1, 25, -1, 24, -1, 26, -1, 28, -1, 10, - 6, -1, 22, -1, 22, 6, -1, 22, 13, 10, - -1, 22, 14, 10, -1, 10, 15, 10, -1, 10, - 15, 10, 15, 10, -1, 11, -1, 5, -1, 11, - 12, -1, 4, -1, 4, 16, -1, 10, 4, -1, - 10, 17, 10, -1, 10, 17, 10, 17, 10, -1, - 10, 14, 10, 14, 10, -1, 10, 14, 7, 14, - 10, -1, 7, 10, -1, 7, 10, 16, 10, -1, - 10, 7, -1, 10, 7, 10, -1, 27, 3, -1, - 27, -1, 14, 10, 9, -1, 13, 10, 9, -1, - 10, 9, -1, 9, -1, 14, 10, 8, -1, 13, - 10, 8, -1, 10, 8, -1, 8, -1, 10, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned short int yyrline[] = -{ - 0, 104, 104, 105, 108, 109, 110, 111, 112, 113, - 116, 126, 129, 136, 141, 148, 153, 160, 164, 168, - 174, 178, 183, 190, 195, 214, 220, 233, 238, 244, - 249, 257, 261, 264, 268, 272, 276, 280, 284, 288, - 292, 298 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "tAGO", "tDAY", "tDAYZONE", "tAMPM", - "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tUNUMBER", "tZONE", "tDST", "'+'", - "'-'", "':'", "','", "'/'", "$accept", "spec", "item", "time", - "bare_time", "zone", "day", "date", "rel", "relunit", "number", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const unsigned short int yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 43, 45, 58, 44, 47 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const unsigned char yyr1[] = -{ - 0, 18, 19, 19, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 22, 22, 23, 23, 23, - 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, - 25, 26, 26, 27, 27, 27, 27, 27, 27, 27, - 27, 28 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const unsigned char yyr2[] = -{ - 0, 2, 0, 2, 1, 1, 1, 1, 1, 1, - 2, 1, 2, 3, 3, 3, 5, 1, 1, 2, - 1, 2, 2, 3, 5, 5, 5, 2, 4, 2, - 3, 2, 1, 3, 3, 2, 1, 3, 3, 2, - 1, 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const unsigned char yydefact[] = -{ - 2, 0, 1, 20, 18, 0, 40, 36, 41, 17, - 0, 0, 3, 4, 11, 5, 7, 6, 8, 32, - 9, 21, 27, 22, 10, 29, 39, 35, 0, 0, - 0, 19, 0, 0, 12, 0, 0, 31, 0, 30, - 0, 0, 15, 23, 38, 34, 37, 33, 13, 14, - 28, 0, 0, 0, 0, 26, 25, 16, 24 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yysigned_char yydefgoto[] = -{ - -1, 1, 12, 13, 14, 15, 16, 17, 18, 19, - 20 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -8 -static const yysigned_char yypact[] = -{ - -8, 0, -8, 14, -8, 2, -8, -8, 11, 15, - 19, 21, -8, -8, 10, -8, -8, -8, -8, 29, - -8, -8, 17, -8, -8, 24, -8, -8, -4, 25, - 26, -8, -7, 13, -8, 27, 28, -8, 30, -8, - 31, 32, 33, 22, -8, -8, -8, -8, -8, -8, - -8, 34, 37, 39, 40, -8, -8, -8, -8 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yysigned_char yypgoto[] = -{ - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const unsigned char yytable[] = -{ - 2, 44, 45, 40, 3, 4, 41, 5, 6, 7, - 8, 9, 22, 10, 11, 23, 34, 24, 25, 26, - 27, 46, 47, 35, 36, 28, 29, 31, 30, 32, - 21, 33, 37, 38, 39, 42, 43, 48, 49, 54, - 50, 0, 0, 0, 55, 51, 52, 56, 53, 57, - 58 -}; - -static const yysigned_char yycheck[] = -{ - 0, 8, 9, 7, 4, 5, 10, 7, 8, 9, - 10, 11, 10, 13, 14, 4, 6, 6, 7, 8, - 9, 8, 9, 13, 14, 14, 15, 12, 17, 10, - 16, 10, 3, 16, 10, 10, 10, 10, 10, 17, - 10, -1, -1, -1, 10, 14, 14, 10, 15, 10, - 10 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const unsigned char yystos[] = -{ - 0, 19, 0, 4, 5, 7, 8, 9, 10, 11, - 13, 14, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 16, 10, 4, 6, 7, 8, 9, 14, 15, - 17, 12, 10, 10, 6, 13, 14, 3, 16, 10, - 7, 10, 10, 10, 8, 9, 8, 9, 10, 10, - 10, 14, 14, 15, 17, 10, 10, 10, 10 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (N) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (0) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_stack_print (short int *bottom, short int *top) -#else -static void -yy_stack_print (bottom, top) - short int *bottom; - short int *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (/* Nothing. */; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_reduce_print (int yyrule) -#else -static void -yy_reduce_print (yyrule) - int yyrule; -#endif -{ - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", - yyrule - 1, yylno); - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - size_t yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -#endif /* YYERROR_VERBOSE */ - - - -#if YYDEBUG -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -#else -static void -yysymprint (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - switch (yytype) - { - default: - break; - } - YYFPRINTF (yyoutput, ")"); -} - -#endif /* ! YYDEBUG */ -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM); -# else -int yyparse (); -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The look-ahead symbol. */ -int yychar; - -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM) -# else -int yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int -yyparse (void) -#else -int -yyparse () - ; -#endif -#endif -{ - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short int yyssa[YYINITDEPTH]; - short int *yyss = yyssa; - short int *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; - - - -#define YYPOPSTACK (yyvsp--, yyssp--) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ - int yylen; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short int *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - short int *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a look-ahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to look-ahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a look-ahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; - - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - yystate = yyn; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 4: -#line 108 "getdate.y" - { yyHaveTime++; } - break; - - case 5: -#line 109 "getdate.y" - { yyHaveZone++; } - break; - - case 6: -#line 110 "getdate.y" - { yyHaveDate++; } - break; - - case 7: -#line 111 "getdate.y" - { yyHaveDay++; } - break; - - case 8: -#line 112 "getdate.y" - { yyHaveRel++; } - break; - - case 10: -#line 116 "getdate.y" - { - /* "7am" */ - yyHour = (yyvsp[-1].Number); - if (yyHour == 12) - yyHour = 0; - yyMinutes = 0; - yySeconds = 0; - if ((yyvsp[0].Number) == tPM) - yyHour += 12; - } - break; - - case 11: -#line 126 "getdate.y" - { - /* "7:12:18" "19:17" */ - } - break; - - case 12: -#line 129 "getdate.y" - { - /* "7:12pm", "12:20:13am" */ - if (yyHour == 12) - yyHour = 0; - if ((yyvsp[0].Number) == tPM) - yyHour += 12; - } - break; - - case 13: -#line 136 "getdate.y" - { - /* "7:14+0700" */ - yyDSTmode = DSToff; - yyTimezone = - ((yyvsp[0].Number) % 100 + ((yyvsp[0].Number) / 100) * 60); - } - break; - - case 14: -#line 141 "getdate.y" - { - /* "19:14:12-0530" */ - yyDSTmode = DSToff; - yyTimezone = + ((yyvsp[0].Number) % 100 + ((yyvsp[0].Number) / 100) * 60); - } - break; - - case 15: -#line 148 "getdate.y" - { - yyHour = (yyvsp[-2].Number); - yyMinutes = (yyvsp[0].Number); - yySeconds = 0; - } - break; - - case 16: -#line 153 "getdate.y" - { - yyHour = (yyvsp[-4].Number); - yyMinutes = (yyvsp[-2].Number); - yySeconds = (yyvsp[0].Number); - } - break; - - case 17: -#line 160 "getdate.y" - { - yyTimezone = (yyvsp[0].Number); - yyDSTmode = DSToff; - } - break; - - case 18: -#line 164 "getdate.y" - { - yyTimezone = (yyvsp[0].Number); - yyDSTmode = DSTon; - } - break; - - case 19: -#line 168 "getdate.y" - { - yyTimezone = (yyvsp[-1].Number); - yyDSTmode = DSTon; - } - break; - - case 20: -#line 174 "getdate.y" - { - yyDayOrdinal = 1; - yyDayNumber = (yyvsp[0].Number); - } - break; - - case 21: -#line 178 "getdate.y" - { - /* "tue," "wednesday," */ - yyDayOrdinal = 1; - yyDayNumber = (yyvsp[-1].Number); - } - break; - - case 22: -#line 183 "getdate.y" - { - /* "second tues" "3 wed" */ - yyDayOrdinal = (yyvsp[-1].Number); - yyDayNumber = (yyvsp[0].Number); - } - break; - - case 23: -#line 190 "getdate.y" - { - /* "1/15" */ - yyMonth = (yyvsp[-2].Number); - yyDay = (yyvsp[0].Number); - } - break; - - case 24: -#line 195 "getdate.y" - { - if ((yyvsp[-4].Number) >= 13) { - /* First number is big: 2004/01/29, 99/02/17 */ - yyYear = (yyvsp[-4].Number); - yyMonth = (yyvsp[-2].Number); - yyDay = (yyvsp[0].Number); - } else if (((yyvsp[0].Number) >= 13) || ((yyvsp[-2].Number) >= 13)) { - /* Last number is big: 01/07/98 */ - /* Middle number is big: 01/29/04 */ - yyMonth = (yyvsp[-4].Number); - yyDay = (yyvsp[-2].Number); - yyYear = (yyvsp[0].Number); - } else { - /* No significant clues: 02/03/04 */ - yyMonth = (yyvsp[-4].Number); - yyDay = (yyvsp[-2].Number); - yyYear = (yyvsp[0].Number); - } - } - break; - - case 25: -#line 214 "getdate.y" - { - /* ISO 8601 format. yyyy-mm-dd. */ - yyYear = (yyvsp[-4].Number); - yyMonth = (yyvsp[-2].Number); - yyDay = (yyvsp[0].Number); - } - break; - - case 26: -#line 220 "getdate.y" - { - if ((yyvsp[-4].Number) > 31) { - /* e.g. 1992-Jun-17 */ - yyYear = (yyvsp[-4].Number); - yyMonth = (yyvsp[-2].Number); - yyDay = (yyvsp[0].Number); - } else { - /* e.g. 17-JUN-1992. */ - yyDay = (yyvsp[-4].Number); - yyMonth = (yyvsp[-2].Number); - yyYear = (yyvsp[0].Number); - } - } - break; - - case 27: -#line 233 "getdate.y" - { - /* "May 3" */ - yyMonth = (yyvsp[-1].Number); - yyDay = (yyvsp[0].Number); - } - break; - - case 28: -#line 238 "getdate.y" - { - /* "June 17, 2001" */ - yyMonth = (yyvsp[-3].Number); - yyDay = (yyvsp[-2].Number); - yyYear = (yyvsp[0].Number); - } - break; - - case 29: -#line 244 "getdate.y" - { - /* "12 Sept" */ - yyDay = (yyvsp[-1].Number); - yyMonth = (yyvsp[0].Number); - } - break; - - case 30: -#line 249 "getdate.y" - { - /* "12 Sept 1997" */ - yyDay = (yyvsp[-2].Number); - yyMonth = (yyvsp[-1].Number); - yyYear = (yyvsp[0].Number); - } - break; - - case 31: -#line 257 "getdate.y" - { - yyRelSeconds = -yyRelSeconds; - yyRelMonth = -yyRelMonth; - } - break; - - case 33: -#line 264 "getdate.y" - { - /* "-3 hours" */ - yyRelSeconds -= (yyvsp[-1].Number) * (yyvsp[0].Number); - } - break; - - case 34: -#line 268 "getdate.y" - { - /* "+1 minute" */ - yyRelSeconds += (yyvsp[-1].Number) * (yyvsp[0].Number); - } - break; - - case 35: -#line 272 "getdate.y" - { - /* "1 day" */ - yyRelSeconds += (yyvsp[-1].Number) * (yyvsp[0].Number); - } - break; - - case 36: -#line 276 "getdate.y" - { - /* "hour" */ - yyRelSeconds += (yyvsp[0].Number); - } - break; - - case 37: -#line 280 "getdate.y" - { - /* "-3 months" */ - yyRelMonth -= (yyvsp[-1].Number) * (yyvsp[0].Number); - } - break; - - case 38: -#line 284 "getdate.y" - { - /* "+5 years" */ - yyRelMonth += (yyvsp[-1].Number) * (yyvsp[0].Number); - } - break; - - case 39: -#line 288 "getdate.y" - { - /* "2 years" */ - yyRelMonth += (yyvsp[-1].Number) * (yyvsp[0].Number); - } - break; - - case 40: -#line 292 "getdate.y" - { - /* "6 months" */ - yyRelMonth += (yyvsp[0].Number); - } - break; - - case 41: -#line 298 "getdate.y" - { - if (yyHaveTime && yyHaveDate && !yyHaveRel) - yyYear = (yyvsp[0].Number); - else { - if((yyvsp[0].Number)>10000) { - /* "20040301" */ - yyHaveDate++; - yyDay= ((yyvsp[0].Number))%100; - yyMonth= ((yyvsp[0].Number)/100)%100; - yyYear = (yyvsp[0].Number)/10000; - } - else { - /* "513" is same as "5:13" */ - yyHaveTime++; - if ((yyvsp[0].Number) < 100) { - yyHour = (yyvsp[0].Number); - yyMinutes = 0; - } - else { - yyHour = (yyvsp[0].Number) / 100; - yyMinutes = (yyvsp[0].Number) % 100; - } - yySeconds = 0; - } - } - } - break; - - - default: break; - } - -/* Line 1126 of yacc.c. */ -#line 1590 "tar/getdate.c" - - yyvsp -= yylen; - yyssp -= yylen; - - - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (YYPACT_NINF < yyn && yyn < YYLAST) - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - char *yymsg = 0; -# define YYERROR_VERBOSE_ARGS_MAXIMUM 5 - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -#if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -#endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= yysize1 < yysize; - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= yysize1 < yysize; - yysize = yysize1; - - if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yymsg; - int yyi = 0; - while ((*yyp = *yyf)) - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - { - yyerror (YY_("syntax error")); - goto yyexhaustedlab; - } - } - else -#endif /* YYERROR_VERBOSE */ - yyerror (YY_("syntax error")); - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse look-ahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (0) - goto yyerrorlab; - -yyvsp -= yylen; - yyssp -= yylen; - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", yystos[yystate], yyvsp); - YYPOPSTACK; - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK; - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - return yyresult; -} - - -#line 327 "getdate.y" - - -static struct TABLE { - size_t abbrev; - const char *name; - int type; - time_t value; -} const TimeWords[] = { - /* am/pm */ - { 0, "am", tAMPM, tAM }, - { 0, "pm", tAMPM, tPM }, - - /* Month names. */ - { 3, "january", tMONTH, 1 }, - { 3, "february", tMONTH, 2 }, - { 3, "march", tMONTH, 3 }, - { 3, "april", tMONTH, 4 }, - { 3, "may", tMONTH, 5 }, - { 3, "june", tMONTH, 6 }, - { 3, "july", tMONTH, 7 }, - { 3, "august", tMONTH, 8 }, - { 3, "september", tMONTH, 9 }, - { 3, "october", tMONTH, 10 }, - { 3, "november", tMONTH, 11 }, - { 3, "december", tMONTH, 12 }, - - /* Days of the week. */ - { 2, "sunday", tDAY, 0 }, - { 3, "monday", tDAY, 1 }, - { 2, "tuesday", tDAY, 2 }, - { 3, "wednesday", tDAY, 3 }, - { 2, "thursday", tDAY, 4 }, - { 2, "friday", tDAY, 5 }, - { 2, "saturday", tDAY, 6 }, - - /* Timezones: Offsets are in minutes. */ - { 0, "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */ - { 0, "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */ - { 0, "utc", tZONE, HOUR( 0) }, - { 0, "wet", tZONE, HOUR( 0) }, /* Western European */ - { 0, "bst", tDAYZONE, HOUR( 0) }, /* British Summer */ - { 0, "wat", tZONE, HOUR( 1) }, /* West Africa */ - { 0, "at", tZONE, HOUR( 2) }, /* Azores */ - /* { 0, "bst", tZONE, HOUR( 3) }, */ /* Brazil Standard: Conflict */ - /* { 0, "gst", tZONE, HOUR( 3) }, */ /* Greenland Standard: Conflict*/ - { 0, "nft", tZONE, HOUR(3)+30 }, /* Newfoundland */ - { 0, "nst", tZONE, HOUR(3)+30 }, /* Newfoundland Standard */ - { 0, "ndt", tDAYZONE, HOUR(3)+30 }, /* Newfoundland Daylight */ - { 0, "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */ - { 0, "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */ - { 0, "est", tZONE, HOUR( 5) }, /* Eastern Standard */ - { 0, "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */ - { 0, "cst", tZONE, HOUR( 6) }, /* Central Standard */ - { 0, "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */ - { 0, "mst", tZONE, HOUR( 7) }, /* Mountain Standard */ - { 0, "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */ - { 0, "pst", tZONE, HOUR( 8) }, /* Pacific Standard */ - { 0, "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */ - { 0, "yst", tZONE, HOUR( 9) }, /* Yukon Standard */ - { 0, "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */ - { 0, "hst", tZONE, HOUR(10) }, /* Hawaii Standard */ - { 0, "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */ - { 0, "cat", tZONE, HOUR(10) }, /* Central Alaska */ - { 0, "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */ - { 0, "nt", tZONE, HOUR(11) }, /* Nome */ - { 0, "idlw", tZONE, HOUR(12) }, /* Intl Date Line West */ - { 0, "cet", tZONE, -HOUR(1) }, /* Central European */ - { 0, "met", tZONE, -HOUR(1) }, /* Middle European */ - { 0, "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */ - { 0, "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */ - { 0, "swt", tZONE, -HOUR(1) }, /* Swedish Winter */ - { 0, "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */ - { 0, "fwt", tZONE, -HOUR(1) }, /* French Winter */ - { 0, "fst", tDAYZONE, -HOUR(1) }, /* French Summer */ - { 0, "eet", tZONE, -HOUR(2) }, /* Eastern Eur, USSR Zone 1 */ - { 0, "bt", tZONE, -HOUR(3) }, /* Baghdad, USSR Zone 2 */ - { 0, "it", tZONE, -HOUR(3)-30 },/* Iran */ - { 0, "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */ - { 0, "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */ - { 0, "ist", tZONE, -HOUR(5)-30 },/* Indian Standard */ - { 0, "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */ - /* { 0, "nst", tZONE, -HOUR(6.5) }, */ /* North Sumatra: Conflict */ - /* { 0, "sst", tZONE, -HOUR(7) }, */ /* So Sumatra, USSR 6: Conflict */ - { 0, "wast", tZONE, -HOUR(7) }, /* West Australian Standard */ - { 0, "wadt", tDAYZONE, -HOUR(7) }, /* West Australian Daylight */ - { 0, "jt", tZONE, -HOUR(7)-30 },/* Java (3pm in Cronusland!)*/ - { 0, "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */ - { 0, "jst", tZONE, -HOUR(9) }, /* Japan Std, USSR Zone 8 */ - { 0, "cast", tZONE, -HOUR(9)-30 },/* Central Australian Std */ - { 0, "cadt", tDAYZONE, -HOUR(9)-30 },/* Central Australian Daylt */ - { 0, "east", tZONE, -HOUR(10) }, /* Eastern Australian Std */ - { 0, "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylt */ - { 0, "gst", tZONE, -HOUR(10) }, /* Guam Std, USSR Zone 9 */ - { 0, "nzt", tZONE, -HOUR(12) }, /* New Zealand */ - { 0, "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */ - { 0, "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */ - { 0, "idle", tZONE, -HOUR(12) }, /* Intl Date Line East */ - - { 0, "dst", tDST, 0 }, - - /* Time units. */ - { 4, "years", tMONTH_UNIT, 12 }, - { 5, "months", tMONTH_UNIT, 1 }, - { 9, "fortnights", tSEC_UNIT, 14 * 24 * 60 * 60 }, - { 4, "weeks", tSEC_UNIT, 7 * 24 * 60 * 60 }, - { 3, "days", tSEC_UNIT, 1 * 24 * 60 * 60 }, - { 4, "hours", tSEC_UNIT, 60 * 60 }, - { 3, "minutes", tSEC_UNIT, 60 }, - { 3, "seconds", tSEC_UNIT, 1 }, - - /* Relative-time words. */ - { 0, "tomorrow", tSEC_UNIT, 1 * 24 * 60 * 60 }, - { 0, "yesterday", tSEC_UNIT, -1 * 24 * 60 * 60 }, - { 0, "today", tSEC_UNIT, 0 }, - { 0, "now", tSEC_UNIT, 0 }, - { 0, "last", tUNUMBER, -1 }, - { 0, "this", tSEC_UNIT, 0 }, - { 0, "next", tUNUMBER, 2 }, - { 0, "first", tUNUMBER, 1 }, - { 0, "1st", tUNUMBER, 1 }, -/* { 0, "second", tUNUMBER, 2 }, */ - { 0, "2nd", tUNUMBER, 2 }, - { 0, "third", tUNUMBER, 3 }, - { 0, "3rd", tUNUMBER, 3 }, - { 0, "fourth", tUNUMBER, 4 }, - { 0, "4th", tUNUMBER, 4 }, - { 0, "fifth", tUNUMBER, 5 }, - { 0, "5th", tUNUMBER, 5 }, - { 0, "sixth", tUNUMBER, 6 }, - { 0, "seventh", tUNUMBER, 7 }, - { 0, "eighth", tUNUMBER, 8 }, - { 0, "ninth", tUNUMBER, 9 }, - { 0, "tenth", tUNUMBER, 10 }, - { 0, "eleventh", tUNUMBER, 11 }, - { 0, "twelfth", tUNUMBER, 12 }, - { 0, "ago", tAGO, 1 }, - - /* Military timezones. */ - { 0, "a", tZONE, HOUR( 1) }, - { 0, "b", tZONE, HOUR( 2) }, - { 0, "c", tZONE, HOUR( 3) }, - { 0, "d", tZONE, HOUR( 4) }, - { 0, "e", tZONE, HOUR( 5) }, - { 0, "f", tZONE, HOUR( 6) }, - { 0, "g", tZONE, HOUR( 7) }, - { 0, "h", tZONE, HOUR( 8) }, - { 0, "i", tZONE, HOUR( 9) }, - { 0, "k", tZONE, HOUR( 10) }, - { 0, "l", tZONE, HOUR( 11) }, - { 0, "m", tZONE, HOUR( 12) }, - { 0, "n", tZONE, HOUR(- 1) }, - { 0, "o", tZONE, HOUR(- 2) }, - { 0, "p", tZONE, HOUR(- 3) }, - { 0, "q", tZONE, HOUR(- 4) }, - { 0, "r", tZONE, HOUR(- 5) }, - { 0, "s", tZONE, HOUR(- 6) }, - { 0, "t", tZONE, HOUR(- 7) }, - { 0, "u", tZONE, HOUR(- 8) }, - { 0, "v", tZONE, HOUR(- 9) }, - { 0, "w", tZONE, HOUR(-10) }, - { 0, "x", tZONE, HOUR(-11) }, - { 0, "y", tZONE, HOUR(-12) }, - { 0, "z", tZONE, HOUR( 0) }, - - /* End of table. */ - { 0, NULL, 0, 0 } -}; - - - - -/* ARGSUSED */ -static int -yyerror(const char *s) -{ - (void)s; - return 0; -} - -static time_t -ToSeconds(time_t Hours, time_t Minutes, time_t Seconds) -{ - if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) - return -1; - if (Hours < 0 || Hours > 23) - return -1; - return (Hours * 60L + Minutes) * 60L + Seconds; -} - - -/* Year is either - * A number from 0 to 99, which means a year from 1970 to 2069, or - * The actual year (>=100). */ -static time_t -Convert(time_t Month, time_t Day, time_t Year, - time_t Hours, time_t Minutes, time_t Seconds, DSTMODE DSTmode) -{ - static int DaysInMonth[12] = { - 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; - time_t tod; - time_t Julian; - int i; - - if (Year < 69) - Year += 2000; - else if (Year < 100) - Year += 1900; - DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) - ? 29 : 28; - /* Checking for 2038 bogusly assumes that time_t is 32 bits. But - I'm too lazy to try to check for time_t overflow in another way. */ - if (Year < EPOCH || Year > 2038 - || Month < 1 || Month > 12 - /* Lint fluff: "conversion from long may lose accuracy" */ - || Day < 1 || Day > DaysInMonth[(int)--Month]) - return -1; - - Julian = Day - 1; - for (i = 0; i < Month; i++) - Julian += DaysInMonth[i]; - for (i = EPOCH; i < Year; i++) - Julian += 365 + (i % 4 == 0); - Julian *= SECSPERDAY; - Julian += yyTimezone * 60L; - if ((tod = ToSeconds(Hours, Minutes, Seconds)) < 0) - return -1; - Julian += tod; - if (DSTmode == DSTon - || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst)) - Julian -= 60 * 60; - return Julian; -} - - -static time_t -DSTcorrect(time_t Start, time_t Future) -{ - time_t StartDay; - time_t FutureDay; - - StartDay = (localtime(&Start)->tm_hour + 1) % 24; - FutureDay = (localtime(&Future)->tm_hour + 1) % 24; - return (Future - Start) + (StartDay - FutureDay) * 60L * 60L; -} - - -static time_t -RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber) -{ - struct tm *tm; - time_t now; - - now = Start; - tm = localtime(&now); - now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7); - now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); - return DSTcorrect(Start, now); -} - - -static time_t -RelativeMonth(time_t Start, time_t RelMonth) -{ - struct tm *tm; - time_t Month; - time_t Year; - - if (RelMonth == 0) - return 0; - tm = localtime(&Start); - Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth; - Year = Month / 12; - Month = Month % 12 + 1; - return DSTcorrect(Start, - Convert(Month, (time_t)tm->tm_mday, Year, - (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, - DSTmaybe)); -} - -static int -yylex(void) -{ - char c; - char buff[64]; - - for ( ; ; ) { - while (isspace((unsigned char)*yyInput)) - yyInput++; - - /* Skip parenthesized comments. */ - if (*yyInput == '(') { - int Count = 0; - do { - c = *yyInput++; - if (c == '\0') - return c; - if (c == '(') - Count++; - else if (c == ')') - Count--; - } while (Count > 0); - continue; - } - - /* Try the next token in the word table first. */ - /* This allows us to match "2nd", for example. */ - { - char *src = yyInput; - const struct TABLE *tp; - unsigned i = 0; - - /* Force to lowercase and strip '.' characters. */ - while (*src != '\0' - && (isalnum((unsigned char)*src) || *src == '.') - && i < sizeof(buff)-1) { - if (*src != '.') { - if (isupper((unsigned char)*src)) - buff[i++] = tolower((unsigned char)*src); - else - buff[i++] = *src; - } - src++; - } - buff[i++] = '\0'; - - /* - * Find the first match. If the word can be - * abbreviated, make sure we match at least - * the minimum abbreviation. - */ - for (tp = TimeWords; tp->name; tp++) { - size_t abbrev = tp->abbrev; - if (abbrev == 0) - abbrev = strlen(tp->name); - if (strlen(buff) >= abbrev - && strncmp(tp->name, buff, strlen(buff)) - == 0) { - /* Skip over token. */ - yyInput = src; - /* Return the match. */ - yylval.Number = tp->value; - return tp->type; - } - } - } - - /* - * Not in the word table, maybe it's a number. Note: - * Because '-' and '+' have other special meanings, I - * don't deal with signed numbers here. - */ - if (isdigit((unsigned char)(c = *yyInput))) { - for (yylval.Number = 0; isdigit((unsigned char)(c = *yyInput++)); ) - yylval.Number = 10 * yylval.Number + c - '0'; - yyInput--; - return (tUNUMBER); - } - - return (*yyInput++); - } -} - -#define TM_YEAR_ORIGIN 1900 - -/* Yield A - B, measured in seconds. */ -static long -difftm (struct tm *a, struct tm *b) -{ - int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); - int by = b->tm_year + (TM_YEAR_ORIGIN - 1); - int days = ( - /* difference in day of year */ - a->tm_yday - b->tm_yday - /* + intervening leap days */ - + ((ay >> 2) - (by >> 2)) - - (ay/100 - by/100) - + ((ay/100 >> 2) - (by/100 >> 2)) - /* + difference in years * 365 */ - + (long)(ay-by) * 365 - ); - return (60*(60*(24*days + (a->tm_hour - b->tm_hour)) - + (a->tm_min - b->tm_min)) - + (a->tm_sec - b->tm_sec)); -} - -time_t -get_date(char *p) -{ - struct tm *tm; - struct tm gmt, *gmt_ptr; - time_t Start; - time_t tod; - time_t nowtime; - long tzone; - - memset(&gmt, 0, sizeof(gmt)); - yyInput = p; - - (void)time (&nowtime); - - gmt_ptr = gmtime (&nowtime); - if (gmt_ptr != NULL) { - /* Copy, in case localtime and gmtime use the same buffer. */ - gmt = *gmt_ptr; - } - - if (! (tm = localtime (&nowtime))) - return -1; - - if (gmt_ptr != NULL) - tzone = difftm (&gmt, tm) / 60; - else - /* This system doesn't understand timezones; fake it. */ - tzone = 0; - if(tm->tm_isdst) - tzone += 60; - - yyYear = tm->tm_year + 1900; - yyMonth = tm->tm_mon + 1; - yyDay = tm->tm_mday; - yyTimezone = tzone; - yyDSTmode = DSTmaybe; - yyHour = 0; - yyMinutes = 0; - yySeconds = 0; - yyRelSeconds = 0; - yyRelMonth = 0; - yyHaveDate = 0; - yyHaveDay = 0; - yyHaveRel = 0; - yyHaveTime = 0; - yyHaveZone = 0; - - if (yyparse() - || yyHaveTime > 1 || yyHaveZone > 1 - || yyHaveDate > 1 || yyHaveDay > 1) - return -1; - - if (yyHaveDate || yyHaveTime || yyHaveDay) { - Start = Convert(yyMonth, yyDay, yyYear, - yyHour, yyMinutes, yySeconds, yyDSTmode); - if (Start < 0) - return -1; - } else { - Start = nowtime; - if (!yyHaveRel) - Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec; - } - - Start += yyRelSeconds; - Start += RelativeMonth(Start, yyRelMonth); - - if (yyHaveDay && !yyHaveDate) { - tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber); - Start += tod; - } - - /* Have to do *something* with a legitimate -1 so it's - * distinguishable from the error return value. (Alternately - * could set errno on error.) */ - return Start == -1 ? 0 : Start; -} - - -#if defined(TEST) - -/* ARGSUSED */ -int -main(int argc, char **argv) -{ - time_t d; - - while (*++argv != NULL) { - (void)printf("Input: %s\n", *argv); - d = get_date(*argv); - if (d == -1) - (void)printf("Bad format - couldn't convert.\n"); - else - (void)printf("Output: %s\n", ctime(&d)); - } - exit(0); - /* NOTREACHED */ -} -#endif /* defined(TEST) */ - - diff --git a/libarchive/libarchive-2.5.5/tar/getdate.y b/libarchive/libarchive-2.5.5/tar/getdate.y deleted file mode 100644 index 3253f6d..0000000 --- a/libarchive/libarchive-2.5.5/tar/getdate.y +++ /dev/null @@ -1,811 +0,0 @@ -%{ -/* - * March 2005: Further modified and simplified by Tim Kientzle: - * Eliminate minutes-based calculations (just do everything in - * seconds), have lexer only recognize unsigned integers (handle '+' - * and '-' characters in grammar), combine tables into one table with - * explicit abbreviation notes, do am/pm adjustments in the grammar - * (eliminate some state variables and post-processing). Among other - * things, these changes eliminated two shift/reduce conflicts. (Went - * from 10 to 8.) - * All of Tim Kientzle's changes to this file are public domain. - */ - -/* -** Originally written by Steven M. Bellovin <smb@research.att.com> while -** at the University of North Carolina at Chapel Hill. Later tweaked by -** a couple of people on Usenet. Completely overhauled by Rich $alz -** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990; -** -** This grammar has 10 shift/reduce conflicts. -** -** This code is in the public domain and has no copyright. -*/ -/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */ -/* SUPPRESS 288 on yyerrlab *//* Label unused */ - -#ifdef __FreeBSD__ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/usr.bin/tar/getdate.y,v 1.9 2007/07/20 01:27:50 kientzle Exp $"); -#endif - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#define yyparse getdate_yyparse -#define yylex getdate_yylex -#define yyerror getdate_yyerror - -static int yyparse(void); -static int yylex(void); -static int yyerror(const char *); - -time_t get_date(char *); - -#define EPOCH 1970 -#define HOUR(x) ((time_t)(x) * 60) -#define SECSPERDAY (24L * 60L * 60L) - -/* -** Daylight-savings mode: on, off, or not yet known. -*/ -typedef enum _DSTMODE { - DSTon, DSToff, DSTmaybe -} DSTMODE; - -/* -** Meridian: am or pm. -*/ -enum { tAM, tPM }; - -/* -** Global variables. We could get rid of most of these by using a good -** union as the yacc stack. (This routine was originally written before -** yacc had the %union construct.) Maybe someday; right now we only use -** the %union very rarely. -*/ -static char *yyInput; - -static DSTMODE yyDSTmode; -static time_t yyDayOrdinal; -static time_t yyDayNumber; -static int yyHaveDate; -static int yyHaveDay; -static int yyHaveRel; -static int yyHaveTime; -static int yyHaveZone; -static time_t yyTimezone; -static time_t yyDay; -static time_t yyHour; -static time_t yyMinutes; -static time_t yyMonth; -static time_t yySeconds; -static time_t yyYear; -static time_t yyRelMonth; -static time_t yyRelSeconds; - -%} - -%union { - time_t Number; -} - -%token tAGO tDAY tDAYZONE tAMPM tMONTH tMONTH_UNIT tSEC_UNIT tUNUMBER -%token tZONE tDST - -%type <Number> tDAY tDAYZONE tMONTH tMONTH_UNIT -%type <Number> tSEC_UNIT tUNUMBER tZONE tAMPM - -%% - -spec : /* NULL */ - | spec item - ; - -item : time { yyHaveTime++; } - | zone { yyHaveZone++; } - | date { yyHaveDate++; } - | day { yyHaveDay++; } - | rel { yyHaveRel++; } - | number - ; - -time : tUNUMBER tAMPM { - /* "7am" */ - yyHour = $1; - if (yyHour == 12) - yyHour = 0; - yyMinutes = 0; - yySeconds = 0; - if ($2 == tPM) - yyHour += 12; - } - | bare_time { - /* "7:12:18" "19:17" */ - } - | bare_time tAMPM { - /* "7:12pm", "12:20:13am" */ - if (yyHour == 12) - yyHour = 0; - if ($2 == tPM) - yyHour += 12; - } - | bare_time '+' tUNUMBER { - /* "7:14+0700" */ - yyDSTmode = DSToff; - yyTimezone = - ($3 % 100 + ($3 / 100) * 60); - } - | bare_time '-' tUNUMBER { - /* "19:14:12-0530" */ - yyDSTmode = DSToff; - yyTimezone = + ($3 % 100 + ($3 / 100) * 60); - } - ; - -bare_time : tUNUMBER ':' tUNUMBER { - yyHour = $1; - yyMinutes = $3; - yySeconds = 0; - } - | tUNUMBER ':' tUNUMBER ':' tUNUMBER { - yyHour = $1; - yyMinutes = $3; - yySeconds = $5; - } - ; - -zone : tZONE { - yyTimezone = $1; - yyDSTmode = DSToff; - } - | tDAYZONE { - yyTimezone = $1; - yyDSTmode = DSTon; - } - | tZONE tDST { - yyTimezone = $1; - yyDSTmode = DSTon; - } - ; - -day : tDAY { - yyDayOrdinal = 1; - yyDayNumber = $1; - } - | tDAY ',' { - /* "tue," "wednesday," */ - yyDayOrdinal = 1; - yyDayNumber = $1; - } - | tUNUMBER tDAY { - /* "second tues" "3 wed" */ - yyDayOrdinal = $1; - yyDayNumber = $2; - } - ; - -date : tUNUMBER '/' tUNUMBER { - /* "1/15" */ - yyMonth = $1; - yyDay = $3; - } - | tUNUMBER '/' tUNUMBER '/' tUNUMBER { - if ($1 >= 13) { - /* First number is big: 2004/01/29, 99/02/17 */ - yyYear = $1; - yyMonth = $3; - yyDay = $5; - } else if (($5 >= 13) || ($3 >= 13)) { - /* Last number is big: 01/07/98 */ - /* Middle number is big: 01/29/04 */ - yyMonth = $1; - yyDay = $3; - yyYear = $5; - } else { - /* No significant clues: 02/03/04 */ - yyMonth = $1; - yyDay = $3; - yyYear = $5; - } - } - | tUNUMBER '-' tUNUMBER '-' tUNUMBER { - /* ISO 8601 format. yyyy-mm-dd. */ - yyYear = $1; - yyMonth = $3; - yyDay = $5; - } - | tUNUMBER '-' tMONTH '-' tUNUMBER { - if ($1 > 31) { - /* e.g. 1992-Jun-17 */ - yyYear = $1; - yyMonth = $3; - yyDay = $5; - } else { - /* e.g. 17-JUN-1992. */ - yyDay = $1; - yyMonth = $3; - yyYear = $5; - } - } - | tMONTH tUNUMBER { - /* "May 3" */ - yyMonth = $1; - yyDay = $2; - } - | tMONTH tUNUMBER ',' tUNUMBER { - /* "June 17, 2001" */ - yyMonth = $1; - yyDay = $2; - yyYear = $4; - } - | tUNUMBER tMONTH { - /* "12 Sept" */ - yyDay = $1; - yyMonth = $2; - } - | tUNUMBER tMONTH tUNUMBER { - /* "12 Sept 1997" */ - yyDay = $1; - yyMonth = $2; - yyYear = $3; - } - ; - -rel : relunit tAGO { - yyRelSeconds = -yyRelSeconds; - yyRelMonth = -yyRelMonth; - } - | relunit - ; - -relunit : '-' tUNUMBER tSEC_UNIT { - /* "-3 hours" */ - yyRelSeconds -= $2 * $3; - } - | '+' tUNUMBER tSEC_UNIT { - /* "+1 minute" */ - yyRelSeconds += $2 * $3; - } - | tUNUMBER tSEC_UNIT { - /* "1 day" */ - yyRelSeconds += $1 * $2; - } - | tSEC_UNIT { - /* "hour" */ - yyRelSeconds += $1; - } - | '-' tUNUMBER tMONTH_UNIT { - /* "-3 months" */ - yyRelMonth -= $2 * $3; - } - | '+' tUNUMBER tMONTH_UNIT { - /* "+5 years" */ - yyRelMonth += $2 * $3; - } - | tUNUMBER tMONTH_UNIT { - /* "2 years" */ - yyRelMonth += $1 * $2; - } - | tMONTH_UNIT { - /* "6 months" */ - yyRelMonth += $1; - } - ; - -number : tUNUMBER { - if (yyHaveTime && yyHaveDate && !yyHaveRel) - yyYear = $1; - else { - if($1>10000) { - /* "20040301" */ - yyHaveDate++; - yyDay= ($1)%100; - yyMonth= ($1/100)%100; - yyYear = $1/10000; - } - else { - /* "513" is same as "5:13" */ - yyHaveTime++; - if ($1 < 100) { - yyHour = $1; - yyMinutes = 0; - } - else { - yyHour = $1 / 100; - yyMinutes = $1 % 100; - } - yySeconds = 0; - } - } - } - ; - - -%% - -static struct TABLE { - size_t abbrev; - const char *name; - int type; - time_t value; -} const TimeWords[] = { - /* am/pm */ - { 0, "am", tAMPM, tAM }, - { 0, "pm", tAMPM, tPM }, - - /* Month names. */ - { 3, "january", tMONTH, 1 }, - { 3, "february", tMONTH, 2 }, - { 3, "march", tMONTH, 3 }, - { 3, "april", tMONTH, 4 }, - { 3, "may", tMONTH, 5 }, - { 3, "june", tMONTH, 6 }, - { 3, "july", tMONTH, 7 }, - { 3, "august", tMONTH, 8 }, - { 3, "september", tMONTH, 9 }, - { 3, "october", tMONTH, 10 }, - { 3, "november", tMONTH, 11 }, - { 3, "december", tMONTH, 12 }, - - /* Days of the week. */ - { 2, "sunday", tDAY, 0 }, - { 3, "monday", tDAY, 1 }, - { 2, "tuesday", tDAY, 2 }, - { 3, "wednesday", tDAY, 3 }, - { 2, "thursday", tDAY, 4 }, - { 2, "friday", tDAY, 5 }, - { 2, "saturday", tDAY, 6 }, - - /* Timezones: Offsets are in minutes. */ - { 0, "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */ - { 0, "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */ - { 0, "utc", tZONE, HOUR( 0) }, - { 0, "wet", tZONE, HOUR( 0) }, /* Western European */ - { 0, "bst", tDAYZONE, HOUR( 0) }, /* British Summer */ - { 0, "wat", tZONE, HOUR( 1) }, /* West Africa */ - { 0, "at", tZONE, HOUR( 2) }, /* Azores */ - /* { 0, "bst", tZONE, HOUR( 3) }, */ /* Brazil Standard: Conflict */ - /* { 0, "gst", tZONE, HOUR( 3) }, */ /* Greenland Standard: Conflict*/ - { 0, "nft", tZONE, HOUR(3)+30 }, /* Newfoundland */ - { 0, "nst", tZONE, HOUR(3)+30 }, /* Newfoundland Standard */ - { 0, "ndt", tDAYZONE, HOUR(3)+30 }, /* Newfoundland Daylight */ - { 0, "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */ - { 0, "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */ - { 0, "est", tZONE, HOUR( 5) }, /* Eastern Standard */ - { 0, "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */ - { 0, "cst", tZONE, HOUR( 6) }, /* Central Standard */ - { 0, "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */ - { 0, "mst", tZONE, HOUR( 7) }, /* Mountain Standard */ - { 0, "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */ - { 0, "pst", tZONE, HOUR( 8) }, /* Pacific Standard */ - { 0, "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */ - { 0, "yst", tZONE, HOUR( 9) }, /* Yukon Standard */ - { 0, "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */ - { 0, "hst", tZONE, HOUR(10) }, /* Hawaii Standard */ - { 0, "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */ - { 0, "cat", tZONE, HOUR(10) }, /* Central Alaska */ - { 0, "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */ - { 0, "nt", tZONE, HOUR(11) }, /* Nome */ - { 0, "idlw", tZONE, HOUR(12) }, /* Intl Date Line West */ - { 0, "cet", tZONE, -HOUR(1) }, /* Central European */ - { 0, "met", tZONE, -HOUR(1) }, /* Middle European */ - { 0, "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */ - { 0, "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */ - { 0, "swt", tZONE, -HOUR(1) }, /* Swedish Winter */ - { 0, "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */ - { 0, "fwt", tZONE, -HOUR(1) }, /* French Winter */ - { 0, "fst", tDAYZONE, -HOUR(1) }, /* French Summer */ - { 0, "eet", tZONE, -HOUR(2) }, /* Eastern Eur, USSR Zone 1 */ - { 0, "bt", tZONE, -HOUR(3) }, /* Baghdad, USSR Zone 2 */ - { 0, "it", tZONE, -HOUR(3)-30 },/* Iran */ - { 0, "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */ - { 0, "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */ - { 0, "ist", tZONE, -HOUR(5)-30 },/* Indian Standard */ - { 0, "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */ - /* { 0, "nst", tZONE, -HOUR(6.5) }, */ /* North Sumatra: Conflict */ - /* { 0, "sst", tZONE, -HOUR(7) }, */ /* So Sumatra, USSR 6: Conflict */ - { 0, "wast", tZONE, -HOUR(7) }, /* West Australian Standard */ - { 0, "wadt", tDAYZONE, -HOUR(7) }, /* West Australian Daylight */ - { 0, "jt", tZONE, -HOUR(7)-30 },/* Java (3pm in Cronusland!)*/ - { 0, "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */ - { 0, "jst", tZONE, -HOUR(9) }, /* Japan Std, USSR Zone 8 */ - { 0, "cast", tZONE, -HOUR(9)-30 },/* Central Australian Std */ - { 0, "cadt", tDAYZONE, -HOUR(9)-30 },/* Central Australian Daylt */ - { 0, "east", tZONE, -HOUR(10) }, /* Eastern Australian Std */ - { 0, "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylt */ - { 0, "gst", tZONE, -HOUR(10) }, /* Guam Std, USSR Zone 9 */ - { 0, "nzt", tZONE, -HOUR(12) }, /* New Zealand */ - { 0, "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */ - { 0, "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */ - { 0, "idle", tZONE, -HOUR(12) }, /* Intl Date Line East */ - - { 0, "dst", tDST, 0 }, - - /* Time units. */ - { 4, "years", tMONTH_UNIT, 12 }, - { 5, "months", tMONTH_UNIT, 1 }, - { 9, "fortnights", tSEC_UNIT, 14 * 24 * 60 * 60 }, - { 4, "weeks", tSEC_UNIT, 7 * 24 * 60 * 60 }, - { 3, "days", tSEC_UNIT, 1 * 24 * 60 * 60 }, - { 4, "hours", tSEC_UNIT, 60 * 60 }, - { 3, "minutes", tSEC_UNIT, 60 }, - { 3, "seconds", tSEC_UNIT, 1 }, - - /* Relative-time words. */ - { 0, "tomorrow", tSEC_UNIT, 1 * 24 * 60 * 60 }, - { 0, "yesterday", tSEC_UNIT, -1 * 24 * 60 * 60 }, - { 0, "today", tSEC_UNIT, 0 }, - { 0, "now", tSEC_UNIT, 0 }, - { 0, "last", tUNUMBER, -1 }, - { 0, "this", tSEC_UNIT, 0 }, - { 0, "next", tUNUMBER, 2 }, - { 0, "first", tUNUMBER, 1 }, - { 0, "1st", tUNUMBER, 1 }, -/* { 0, "second", tUNUMBER, 2 }, */ - { 0, "2nd", tUNUMBER, 2 }, - { 0, "third", tUNUMBER, 3 }, - { 0, "3rd", tUNUMBER, 3 }, - { 0, "fourth", tUNUMBER, 4 }, - { 0, "4th", tUNUMBER, 4 }, - { 0, "fifth", tUNUMBER, 5 }, - { 0, "5th", tUNUMBER, 5 }, - { 0, "sixth", tUNUMBER, 6 }, - { 0, "seventh", tUNUMBER, 7 }, - { 0, "eighth", tUNUMBER, 8 }, - { 0, "ninth", tUNUMBER, 9 }, - { 0, "tenth", tUNUMBER, 10 }, - { 0, "eleventh", tUNUMBER, 11 }, - { 0, "twelfth", tUNUMBER, 12 }, - { 0, "ago", tAGO, 1 }, - - /* Military timezones. */ - { 0, "a", tZONE, HOUR( 1) }, - { 0, "b", tZONE, HOUR( 2) }, - { 0, "c", tZONE, HOUR( 3) }, - { 0, "d", tZONE, HOUR( 4) }, - { 0, "e", tZONE, HOUR( 5) }, - { 0, "f", tZONE, HOUR( 6) }, - { 0, "g", tZONE, HOUR( 7) }, - { 0, "h", tZONE, HOUR( 8) }, - { 0, "i", tZONE, HOUR( 9) }, - { 0, "k", tZONE, HOUR( 10) }, - { 0, "l", tZONE, HOUR( 11) }, - { 0, "m", tZONE, HOUR( 12) }, - { 0, "n", tZONE, HOUR(- 1) }, - { 0, "o", tZONE, HOUR(- 2) }, - { 0, "p", tZONE, HOUR(- 3) }, - { 0, "q", tZONE, HOUR(- 4) }, - { 0, "r", tZONE, HOUR(- 5) }, - { 0, "s", tZONE, HOUR(- 6) }, - { 0, "t", tZONE, HOUR(- 7) }, - { 0, "u", tZONE, HOUR(- 8) }, - { 0, "v", tZONE, HOUR(- 9) }, - { 0, "w", tZONE, HOUR(-10) }, - { 0, "x", tZONE, HOUR(-11) }, - { 0, "y", tZONE, HOUR(-12) }, - { 0, "z", tZONE, HOUR( 0) }, - - /* End of table. */ - { 0, NULL, 0, 0 } -}; - - - - -/* ARGSUSED */ -static int -yyerror(const char *s) -{ - (void)s; - return 0; -} - -static time_t -ToSeconds(time_t Hours, time_t Minutes, time_t Seconds) -{ - if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) - return -1; - if (Hours < 0 || Hours > 23) - return -1; - return (Hours * 60L + Minutes) * 60L + Seconds; -} - - -/* Year is either - * A number from 0 to 99, which means a year from 1970 to 2069, or - * The actual year (>=100). */ -static time_t -Convert(time_t Month, time_t Day, time_t Year, - time_t Hours, time_t Minutes, time_t Seconds, DSTMODE DSTmode) -{ - static int DaysInMonth[12] = { - 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; - time_t tod; - time_t Julian; - int i; - - if (Year < 69) - Year += 2000; - else if (Year < 100) - Year += 1900; - DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) - ? 29 : 28; - /* Checking for 2038 bogusly assumes that time_t is 32 bits. But - I'm too lazy to try to check for time_t overflow in another way. */ - if (Year < EPOCH || Year > 2038 - || Month < 1 || Month > 12 - /* Lint fluff: "conversion from long may lose accuracy" */ - || Day < 1 || Day > DaysInMonth[(int)--Month]) - return -1; - - Julian = Day - 1; - for (i = 0; i < Month; i++) - Julian += DaysInMonth[i]; - for (i = EPOCH; i < Year; i++) - Julian += 365 + (i % 4 == 0); - Julian *= SECSPERDAY; - Julian += yyTimezone * 60L; - if ((tod = ToSeconds(Hours, Minutes, Seconds)) < 0) - return -1; - Julian += tod; - if (DSTmode == DSTon - || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst)) - Julian -= 60 * 60; - return Julian; -} - - -static time_t -DSTcorrect(time_t Start, time_t Future) -{ - time_t StartDay; - time_t FutureDay; - - StartDay = (localtime(&Start)->tm_hour + 1) % 24; - FutureDay = (localtime(&Future)->tm_hour + 1) % 24; - return (Future - Start) + (StartDay - FutureDay) * 60L * 60L; -} - - -static time_t -RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber) -{ - struct tm *tm; - time_t now; - - now = Start; - tm = localtime(&now); - now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7); - now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); - return DSTcorrect(Start, now); -} - - -static time_t -RelativeMonth(time_t Start, time_t RelMonth) -{ - struct tm *tm; - time_t Month; - time_t Year; - - if (RelMonth == 0) - return 0; - tm = localtime(&Start); - Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth; - Year = Month / 12; - Month = Month % 12 + 1; - return DSTcorrect(Start, - Convert(Month, (time_t)tm->tm_mday, Year, - (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, - DSTmaybe)); -} - -static int -yylex(void) -{ - char c; - char buff[64]; - - for ( ; ; ) { - while (isspace((unsigned char)*yyInput)) - yyInput++; - - /* Skip parenthesized comments. */ - if (*yyInput == '(') { - int Count = 0; - do { - c = *yyInput++; - if (c == '\0') - return c; - if (c == '(') - Count++; - else if (c == ')') - Count--; - } while (Count > 0); - continue; - } - - /* Try the next token in the word table first. */ - /* This allows us to match "2nd", for example. */ - { - char *src = yyInput; - const struct TABLE *tp; - unsigned i = 0; - - /* Force to lowercase and strip '.' characters. */ - while (*src != '\0' - && (isalnum((unsigned char)*src) || *src == '.') - && i < sizeof(buff)-1) { - if (*src != '.') { - if (isupper((unsigned char)*src)) - buff[i++] = tolower((unsigned char)*src); - else - buff[i++] = *src; - } - src++; - } - buff[i++] = '\0'; - - /* - * Find the first match. If the word can be - * abbreviated, make sure we match at least - * the minimum abbreviation. - */ - for (tp = TimeWords; tp->name; tp++) { - size_t abbrev = tp->abbrev; - if (abbrev == 0) - abbrev = strlen(tp->name); - if (strlen(buff) >= abbrev - && strncmp(tp->name, buff, strlen(buff)) - == 0) { - /* Skip over token. */ - yyInput = src; - /* Return the match. */ - yylval.Number = tp->value; - return tp->type; - } - } - } - - /* - * Not in the word table, maybe it's a number. Note: - * Because '-' and '+' have other special meanings, I - * don't deal with signed numbers here. - */ - if (isdigit((unsigned char)(c = *yyInput))) { - for (yylval.Number = 0; isdigit((unsigned char)(c = *yyInput++)); ) - yylval.Number = 10 * yylval.Number + c - '0'; - yyInput--; - return (tUNUMBER); - } - - return (*yyInput++); - } -} - -#define TM_YEAR_ORIGIN 1900 - -/* Yield A - B, measured in seconds. */ -static long -difftm (struct tm *a, struct tm *b) -{ - int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); - int by = b->tm_year + (TM_YEAR_ORIGIN - 1); - int days = ( - /* difference in day of year */ - a->tm_yday - b->tm_yday - /* + intervening leap days */ - + ((ay >> 2) - (by >> 2)) - - (ay/100 - by/100) - + ((ay/100 >> 2) - (by/100 >> 2)) - /* + difference in years * 365 */ - + (long)(ay-by) * 365 - ); - return (60*(60*(24*days + (a->tm_hour - b->tm_hour)) - + (a->tm_min - b->tm_min)) - + (a->tm_sec - b->tm_sec)); -} - -time_t -get_date(char *p) -{ - struct tm *tm; - struct tm gmt, *gmt_ptr; - time_t Start; - time_t tod; - time_t nowtime; - long tzone; - - memset(&gmt, 0, sizeof(gmt)); - yyInput = p; - - (void)time (&nowtime); - - gmt_ptr = gmtime (&nowtime); - if (gmt_ptr != NULL) { - /* Copy, in case localtime and gmtime use the same buffer. */ - gmt = *gmt_ptr; - } - - if (! (tm = localtime (&nowtime))) - return -1; - - if (gmt_ptr != NULL) - tzone = difftm (&gmt, tm) / 60; - else - /* This system doesn't understand timezones; fake it. */ - tzone = 0; - if(tm->tm_isdst) - tzone += 60; - - yyYear = tm->tm_year + 1900; - yyMonth = tm->tm_mon + 1; - yyDay = tm->tm_mday; - yyTimezone = tzone; - yyDSTmode = DSTmaybe; - yyHour = 0; - yyMinutes = 0; - yySeconds = 0; - yyRelSeconds = 0; - yyRelMonth = 0; - yyHaveDate = 0; - yyHaveDay = 0; - yyHaveRel = 0; - yyHaveTime = 0; - yyHaveZone = 0; - - if (yyparse() - || yyHaveTime > 1 || yyHaveZone > 1 - || yyHaveDate > 1 || yyHaveDay > 1) - return -1; - - if (yyHaveDate || yyHaveTime || yyHaveDay) { - Start = Convert(yyMonth, yyDay, yyYear, - yyHour, yyMinutes, yySeconds, yyDSTmode); - if (Start < 0) - return -1; - } else { - Start = nowtime; - if (!yyHaveRel) - Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec; - } - - Start += yyRelSeconds; - Start += RelativeMonth(Start, yyRelMonth); - - if (yyHaveDay && !yyHaveDate) { - tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber); - Start += tod; - } - - /* Have to do *something* with a legitimate -1 so it's - * distinguishable from the error return value. (Alternately - * could set errno on error.) */ - return Start == -1 ? 0 : Start; -} - - -#if defined(TEST) - -/* ARGSUSED */ -int -main(int argc, char **argv) -{ - time_t d; - - while (*++argv != NULL) { - (void)printf("Input: %s\n", *argv); - d = get_date(*argv); - if (d == -1) - (void)printf("Bad format - couldn't convert.\n"); - else - (void)printf("Output: %s\n", ctime(&d)); - } - exit(0); - /* NOTREACHED */ -} -#endif /* defined(TEST) */ diff --git a/libarchive/libarchive-2.5.5/tar/matching.c b/libarchive/libarchive-2.5.5/tar/matching.c deleted file mode 100644 index 952055f..0000000 --- a/libarchive/libarchive-2.5.5/tar/matching.c +++ /dev/null @@ -1,444 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/matching.c,v 1.13 2008/05/26 17:10:10 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 "bsdtar.h" - -struct match { - struct match *next; - int matches; - char pattern[1]; -}; - -struct matching { - struct match *exclusions; - int exclusions_count; - struct match *inclusions; - int inclusions_count; - int inclusions_unmatched_count; -}; - - -static void add_pattern(struct bsdtar *, struct match **list, - const char *pattern); -static int bsdtar_fnmatch(const char *p, const char *s); -static void initialize_matching(struct bsdtar *); -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 -exclude(struct bsdtar *bsdtar, const char *pattern) -{ - struct matching *matching; - - if (bsdtar->matching == NULL) - initialize_matching(bsdtar); - matching = bsdtar->matching; - add_pattern(bsdtar, &(matching->exclusions), pattern); - matching->exclusions_count++; - return (0); -} - -int -exclude_from_file(struct bsdtar *bsdtar, const char *pathname) -{ - return (process_lines(bsdtar, pathname, &exclude)); -} - -int -include(struct bsdtar *bsdtar, const char *pattern) -{ - struct matching *matching; - - if (bsdtar->matching == NULL) - initialize_matching(bsdtar); - matching = bsdtar->matching; - add_pattern(bsdtar, &(matching->inclusions), pattern); - matching->inclusions_count++; - matching->inclusions_unmatched_count++; - return (0); -} - -int -include_from_file(struct bsdtar *bsdtar, const char *pathname) -{ - return (process_lines(bsdtar, pathname, &include)); -} - -static void -add_pattern(struct bsdtar *bsdtar, struct match **list, const char *pattern) -{ - struct match *match; - - match = malloc(sizeof(*match) + strlen(pattern) + 1); - if (match == NULL) - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); - if (pattern[0] == '/') - pattern++; - strcpy(match->pattern, pattern); - /* Both "foo/" and "foo" should match "foo/bar". */ - if (match->pattern[strlen(match->pattern)-1] == '/') - match->pattern[strlen(match->pattern)-1] = '\0'; - match->next = *list; - *list = match; - match->matches = 0; -} - - -int -excluded(struct bsdtar *bsdtar, const char *pathname) -{ - struct matching *matching; - struct match *match; - struct match *matched; - - matching = bsdtar->matching; - 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' - * - */ -int -match_exclusion(struct match *match, const char *pathname) -{ - const char *p; - - if (*match->pattern == '*' || *match->pattern == '/') - return (bsdtar_fnmatch(match->pattern, pathname) == 0); - - for (p = pathname; p != NULL; p = strchr(p, '/')) { - if (*p == '/') - p++; - if (bsdtar_fnmatch(match->pattern, p) == 0) - return (1); - } - return (0); -} - -/* - * Again, mimic gtar: inclusions are always anchored (have to match - * the beginning of the path) even though exclusions are not anchored. - */ -int -match_inclusion(struct match *match, const char *pathname) -{ - return (bsdtar_fnmatch(match->pattern, pathname) == 0); -} - -void -cleanup_exclusions(struct bsdtar *bsdtar) -{ - struct match *p, *q; - - if (bsdtar->matching) { - p = bsdtar->matching->inclusions; - while (p != NULL) { - q = p; - p = p->next; - free(q); - } - p = bsdtar->matching->exclusions; - while (p != NULL) { - q = p; - p = p->next; - free(q); - } - free(bsdtar->matching); - } -} - -static void -initialize_matching(struct bsdtar *bsdtar) -{ - bsdtar->matching = malloc(sizeof(*bsdtar->matching)); - if (bsdtar->matching == NULL) - bsdtar_errc(bsdtar, 1, errno, "No memory"); - memset(bsdtar->matching, 0, sizeof(*bsdtar->matching)); -} - -int -unmatched_inclusions(struct bsdtar *bsdtar) -{ - struct matching *matching; - - matching = bsdtar->matching; - if (matching == NULL) - return (0); - return (matching->inclusions_unmatched_count); -} - - -int -unmatched_inclusions_warn(struct bsdtar *bsdtar, const char *msg) -{ - struct matching *matching; - struct match *p; - - matching = bsdtar->matching; - if (matching == NULL) - return (0); - - p = matching->inclusions; - while (p != NULL) { - if (p->matches == 0) { - bsdtar->return_value = 1; - bsdtar_warnc(bsdtar, 0, "%s: %s", - p->pattern, msg); - } - p = p->next; - } - return (matching->inclusions_unmatched_count); -} - - - -#if defined(HAVE_FNMATCH) && defined(HAVE_FNM_LEADING_DIR) - -/* Use system fnmatch() if it suits our needs. */ -/* On Linux, _GNU_SOURCE must be defined to get FNM_LEADING_DIR. */ -#define _GNU_SOURCE -#include <fnmatch.h> -static int -bsdtar_fnmatch(const char *pattern, const char *string) -{ - return (fnmatch(pattern, string, FNM_LEADING_DIR)); -} - -#else -/* - * The following was hacked from BSD C library - * code: src/lib/libc/gen/fnmatch.c,v 1.15 2002/02/01 - * - * In particular, most of the flags were ripped out: this always - * behaves like FNM_LEADING_DIR is set and other flags specified - * by POSIX are unset. - * - * Normally, I would not conditionally compile something like this: If - * I have to support it anyway, everyone may as well use it. ;-) - * However, the full POSIX spec for fnmatch() includes a lot of - * advanced character handling that I'm not ready to put in here, so - * it's probably best if people use a local version when it's available. - */ - -/* - * Copyright (c) 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Guido van Rossum. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -static int -bsdtar_fnmatch(const char *pattern, const char *string) -{ - const char *saved_pattern; - int negate, matched; - char c; - - for (;;) { - switch (c = *pattern++) { - case '\0': - if (*string == '/' || *string == '\0') - return (0); - return (1); - case '?': - if (*string == '\0') - return (1); - ++string; - break; - case '*': - c = *pattern; - /* Collapse multiple stars. */ - while (c == '*') - c = *++pattern; - - /* Optimize for pattern with * at end. */ - if (c == '\0') - return (0); - - /* General case, use recursion. */ - while (*string != '\0') { - if (!bsdtar_fnmatch(pattern, string)) - return (0); - ++string; - } - return (1); - case '[': - if (*string == '\0') - return (1); - saved_pattern = pattern; - if (*pattern == '!' || *pattern == '^') { - negate = 1; - ++pattern; - } else - negate = 0; - matched = 0; - c = *pattern++; - do { - if (c == '\\') - c = *pattern++; - if (c == '\0') { - pattern = saved_pattern; - c = '['; - goto norm; - } - if (*pattern == '-') { - char c2 = *(pattern + 1); - if (c2 == '\0') { - pattern = saved_pattern; - c = '['; - goto norm; - } - if (c2 == ']') { - /* [a-] is not a range. */ - if (c == *string - || '-' == *string) - matched = 1; - pattern ++; - } else { - if (c <= *string - && *string <= c2) - matched = 1; - pattern += 2; - } - } else if (c == *string) - matched = 1; - c = *pattern++; - } while (c != ']'); - if (matched == negate) - return (1); - ++string; - break; - case '\\': - if ((c = *pattern++) == '\0') { - c = '\\'; - --pattern; - } - /* FALLTHROUGH */ - default: - norm: - if (c != *string) - return (1); - string++; - break; - } - } - /* NOTREACHED */ -} - -#endif diff --git a/libarchive/libarchive-2.5.5/tar/read.c b/libarchive/libarchive-2.5.5/tar/read.c deleted file mode 100644 index fbb8253..0000000 --- a/libarchive/libarchive-2.5.5/tar/read.c +++ /dev/null @@ -1,402 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/read.c,v 1.38 2008/05/26 17:10:10 kientzle Exp $"); - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef MAJOR_IN_MKDEV -#include <sys/mkdev.h> -#elif defined(MAJOR_IN_SYSMACROS) -#include <sys/sysmacros.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 -#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" - -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'); - unmatched_inclusions_warn(bsdtar, "Not found in archive"); -} - -void -tar_mode_x(struct bsdtar *bsdtar) -{ - /* We want to catch SIGINFO and SIGUSR1. */ - siginfo_init(bsdtar); - - read_archive(bsdtar, 'x'); - - unmatched_inclusions_warn(bsdtar, "Not found in archive"); - /* Restore old SIGINFO + SIGUSR1 handlers. */ - siginfo_done(bsdtar); -} - -static void -progress_func(void * cookie) -{ - struct bsdtar * bsdtar = cookie; - - siginfo_printinfo(bsdtar, 0); -} - -/* - * Handle 'x' and 't' modes. - */ -static void -read_archive(struct bsdtar *bsdtar, char mode) -{ - FILE *out; - struct archive *a; - struct archive_entry *entry; - const struct stat *st; - int r; - - while (*bsdtar->argv) { - include(bsdtar, *bsdtar->argv); - bsdtar->argv++; - } - - if (bsdtar->names_from_file != NULL) - include_from_file(bsdtar, bsdtar->names_from_file); - - 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_read_open_file(a, bsdtar->filename, - bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block : - DEFAULT_BYTES_PER_BLOCK)) - bsdtar_errc(bsdtar, 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. */ - archive_read_extract_set_progress_callback(a, progress_func, - bsdtar); - } - - if (mode == 'x' && bsdtar->option_chroot) { -#if HAVE_CHROOT - if (chroot(".") != 0) - bsdtar_errc(bsdtar, 1, errno, "Can't chroot to \".\""); -#else - bsdtar_errc(bsdtar, 1, 0, - "chroot isn't supported on this platform"); -#endif - } - - for (;;) { - /* Support --fast-read option */ - if (bsdtar->option_fast_read && - unmatched_inclusions(bsdtar) == 0) - break; - - r = archive_read_next_header(a, &entry); - if (r == ARCHIVE_EOF) - break; - if (r < ARCHIVE_OK) - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); - if (r <= ARCHIVE_WARN) - bsdtar->return_value = 1; - if (r == ARCHIVE_RETRY) { - /* Retryable error: try again */ - bsdtar_warnc(bsdtar, 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 (excluded(bsdtar, archive_entry_pathname(entry))) - continue; /* Excluded by a pattern test. */ - - /* - * Modify the pathname as requested by the user. We - * do this for -t as well to give users a way to - * preview the effects of their rewrites. We also do - * this before extraction security checks (including - * leading '/' removal). Note that some rewrite - * failures prevent extraction. - */ - if (edit_pathname(bsdtar, entry)) - continue; /* Excluded by a rewrite failure. */ - - if (mode == 't') { - /* Perversely, gtar uses -O to mean "send to stderr" - * when used with -t. */ - out = bsdtar->option_stdout ? stderr : stdout; - - 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"); - bsdtar_warnc(bsdtar, 0, "%s", - archive_error_string(a)); - } - if (r == ARCHIVE_RETRY) { - fprintf(out, "\n"); - bsdtar_warnc(bsdtar, 0, "%s", - archive_error_string(a)); - } - if (r == ARCHIVE_FATAL) { - fprintf(out, "\n"); - bsdtar_warnc(bsdtar, 0, "%s", - archive_error_string(a)); - bsdtar->return_value = 1; - break; - } - fprintf(out, "\n"); - } else { - 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); - } - - /* Tell the SIGINFO-handler code what we're doing. */ - siginfo_setinfo(bsdtar, "extracting", - archive_entry_pathname(entry), 0); - 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; - } - } - - 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) -{ - const struct stat *st; - char tmp[100]; - size_t w; - const char *p; - const char *fmt; - time_t tim; - static time_t now; - - st = archive_entry_stat(entry); - - /* - * 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), - (int)(st->st_nlink)); - - /* Use uname if it's present, else uid. */ - p = archive_entry_uname(entry); - if ((p == NULL) || (*p == '\0')) { - sprintf(tmp, "%lu ", (unsigned long)st->st_uid); - 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)st->st_gid); - 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 (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) { - sprintf(tmp, "%lu,%lu", - (unsigned long)major(st->st_rdev), - (unsigned long)minor(st->st_rdev)); /* ls(1) also casts here. */ - } else { - /* - * Note the use of platform-dependent macros to format - * the filesize here. We need the format string and the - * corresponding type for the cast. - */ - sprintf(tmp, BSDTAR_FILESIZE_PRINTF, - (BSDTAR_FILESIZE_TYPE)st->st_size); - } - 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 = (time_t)st->st_mtime; - if (abs(tim - now) > (365/2)*86400) - fmt = bsdtar->day_first ? "%e %b %Y" : "%b %e %Y"; - else - fmt = bsdtar->day_first ? "%e %b %H:%M" : "%b %e %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 (S_ISLNK(st->st_mode)) /* Symbolic link */ - safe_fprintf(out, " -> %s", archive_entry_symlink(entry)); -} diff --git a/libarchive/libarchive-2.5.5/tar/siginfo.c b/libarchive/libarchive-2.5.5/tar/siginfo.c deleted file mode 100644 index 249ee34..0000000 --- a/libarchive/libarchive-2.5.5/tar/siginfo.c +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * Copyright 2008 Colin Percival - * 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/siginfo.c,v 1.2 2008/05/22 21:08:36 cperciva Exp $"); - -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "bsdtar.h" - -/* Is there a pending SIGINFO or SIGUSR1? */ -static volatile sig_atomic_t siginfo_received = 0; - -struct siginfo_data { - /* What sort of operation are we doing? */ - char * oper; - - /* What path are we handling? */ - char * path; - - /* How large is the archive entry? */ - int64_t size; - - /* Old signal handlers. */ -#ifdef SIGINFO - void (*siginfo_old)(int); -#endif - void (*sigusr1_old)(int); -}; - -static void siginfo_handler(int sig); - -/* Handler for SIGINFO / SIGUSR1. */ -static void -siginfo_handler(int sig) -{ - - (void)sig; /* UNUSED */ - - /* Record that SIGINFO or SIGUSR1 has been received. */ - siginfo_received = 1; -} - -void -siginfo_init(struct bsdtar *bsdtar) -{ - - /* Allocate space for internal structure. */ - if ((bsdtar->siginfo = malloc(sizeof(struct siginfo_data))) == NULL) - bsdtar_errc(bsdtar, 1, errno, "malloc failed"); - - /* Set the strings to NULL so that free() is safe. */ - bsdtar->siginfo->path = bsdtar->siginfo->oper = NULL; - -#ifdef SIGINFO - /* We want to catch SIGINFO, if it exists. */ - bsdtar->siginfo->siginfo_old = signal(SIGINFO, siginfo_handler); -#endif - /* ... and treat SIGUSR1 the same way as SIGINFO. */ - bsdtar->siginfo->sigusr1_old = signal(SIGUSR1, siginfo_handler); -} - -void -siginfo_setinfo(struct bsdtar *bsdtar, const char * oper, const char * path, - int64_t size) -{ - - /* Free old operation and path strings. */ - free(bsdtar->siginfo->oper); - free(bsdtar->siginfo->path); - - /* Duplicate strings and store entry size. */ - if ((bsdtar->siginfo->oper = strdup(oper)) == NULL) - bsdtar_errc(bsdtar, 1, errno, "Cannot strdup"); - if ((bsdtar->siginfo->path = strdup(path)) == NULL) - bsdtar_errc(bsdtar, 1, errno, "Cannot strdup"); - bsdtar->siginfo->size = size; -} - -void -siginfo_printinfo(struct bsdtar *bsdtar, off_t progress) -{ - - /* If there's a signal to handle and we know what we're doing... */ - if ((siginfo_received == 1) && - (bsdtar->siginfo->path != NULL) && - (bsdtar->siginfo->oper != NULL)) { - if (bsdtar->verbose) - fprintf(stderr, "\n"); - if (bsdtar->siginfo->size > 0) { - safe_fprintf(stderr, "%s %s (%ju / %" PRId64 ")", - bsdtar->siginfo->oper, bsdtar->siginfo->path, - (uintmax_t)progress, bsdtar->siginfo->size); - } else { - safe_fprintf(stderr, "%s %s", - bsdtar->siginfo->oper, bsdtar->siginfo->path); - } - if (!bsdtar->verbose) - fprintf(stderr, "\n"); - siginfo_received = 0; - } -} - -void -siginfo_done(struct bsdtar *bsdtar) -{ - -#ifdef SIGINFO - /* Restore old SIGINFO handler. */ - signal(SIGINFO, bsdtar->siginfo->siginfo_old); -#endif - /* And the old SIGUSR1 handler, too. */ - signal(SIGUSR1, bsdtar->siginfo->sigusr1_old); - - /* Free strings. */ - free(bsdtar->siginfo->path); - free(bsdtar->siginfo->oper); - - /* Free internal data structure. */ - free(bsdtar->siginfo); -} diff --git a/libarchive/libarchive-2.5.5/tar/subst.c b/libarchive/libarchive-2.5.5/tar/subst.c deleted file mode 100644 index 1c32fb0..0000000 --- a/libarchive/libarchive-2.5.5/tar/subst.c +++ /dev/null @@ -1,287 +0,0 @@ -/*- - * Copyright (c) 2008 Joerg Sonnenberger - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: 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 - -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) - bsdtar_errc(bsdtar, 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) - bsdtar_errc(bsdtar, 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') - bsdtar_errc(bsdtar, 1, 0, "Empty replacement string"); - end_pattern = strchr(rule_text + 1, *rule_text); - if (end_pattern == NULL) - bsdtar_errc(bsdtar, 1, 0, "Invalid replacement string"); - - pattern = malloc(end_pattern - rule_text); - if (pattern == NULL) - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); - memcpy(pattern, rule_text + 1, end_pattern - rule_text - 1); - pattern[end_pattern - rule_text - 1] = '\0'; - - if ((r = regcomp(&rule->re, pattern, REG_BASIC)) != 0) { - char buf[80]; - regerror(r, &rule->re, buf, sizeof(buf)); - bsdtar_errc(bsdtar, 1, 0, "Invalid regular expression: %s", buf); - } - free(pattern); - - start_subst = end_pattern + 1; - end_pattern = strchr(start_subst, *rule_text); - if (end_pattern == NULL) - bsdtar_errc(bsdtar, 1, 0, "Invalid replacement string"); - - rule->result = malloc(end_pattern - start_subst + 1); - if (rule->result == NULL) - bsdtar_errc(bsdtar, 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: - bsdtar_errc(bsdtar, 1, 0, "Invalid replacement flag %c", *end_pattern); - } - } -} - -static void -realloc_strncat(struct bsdtar *bsdtar, 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) - bsdtar_errc(bsdtar, 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(struct bsdtar *bsdtar, 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) - bsdtar_errc(bsdtar, 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)) - break; - - got_match = 1; - print_match |= rule->print; - realloc_strncat(bsdtar, result, name, matches[0].rm_so); - - for (i = 0, j = 0; rule->result[i] != '\0'; ++i) { - if (rule->result[i] == '~') { - realloc_strncat(bsdtar, result, rule->result + j, i - j); - realloc_strncat(bsdtar, 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(bsdtar, 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(bsdtar, 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(bsdtar, 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(bsdtar, result, rule->result + j); - - name += matches[0].rm_eo; - - if (!rule->global) - break; - } - - if (got_match) - realloc_strcat(bsdtar, result, name); - - if (print_match) - fprintf(stderr, "%s >> %s\n", path, *result); - - return got_match; -} - -void -cleanup_substitution(struct bsdtar *bsdtar) -{ - struct subst_rule *rule; - struct substitution *subst; - - if ((subst = bsdtar->substitution) == NULL) - return; - - while ((rule = subst->first_rule) != NULL) { - subst->first_rule = rule->next; - free(rule->result); - free(rule); - } - free(subst); -} -#endif /* HAVE_REGEX_H */ diff --git a/libarchive/libarchive-2.5.5/tar/test/main.c b/libarchive/libarchive-2.5.5/tar/test/main.c deleted file mode 100644 index 27bb48d..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/main.c +++ /dev/null @@ -1,1015 +0,0 @@ -/* - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Various utility routines useful for test programs. - * Each test program is linked against this file. - */ -#include "test.h" - -#include <errno.h> -#include <locale.h> -#include <stdarg.h> -#include <time.h> - -/* - * This same file is used pretty much verbatim for all test harnesses. - * - * The next few lines are the only differences. - */ -#define PROGRAM "bsdtar" /* Name of program being tested. */ -#define ENVBASE "BSDTAR" /* Prefix for environment variables. */ -#undef EXTRA_DUMP /* How to dump extra data */ -/* How to generate extra version info. */ -#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "") -__FBSDID("$FreeBSD: src/usr.bin/tar/test/main.c,v 1.3 2008/06/15 10:07:54 kientzle Exp $"); - -/* - * "list.h" is simply created by "grep DEFINE_TEST"; it has - * a line like - * DEFINE_TEST(test_function) - * for each test. - * Include it here with a suitable DEFINE_TEST to declare all of the - * test functions. - */ -#undef DEFINE_TEST -#define DEFINE_TEST(name) void name(void); -#include "list.h" - -/* Interix doesn't define these in a standard header. */ -#if __INTERIX__ -extern char *optarg; -extern int optind; -#endif - -/* Enable core dump on failure. */ -static int dump_on_failure = 0; -/* Default is to remove temp dirs for successful tests. */ -static int keep_temp_files = 0; -/* Default is to print some basic information about each test. */ -static int quiet_flag = 0; -/* Default is to summarize repeated failures. */ -static int verbose = 0; -/* Cumulative count of component failures. */ -static int failures = 0; -/* Cumulative count of skipped component tests. */ -static int skips = 0; -/* Cumulative count of assertions. */ -static int assertions = 0; - -/* Directory where uuencoded reference files can be found. */ -static char *refdir; - -/* - * My own implementation of the standard assert() macro emits the - * message in the same format as GCC (file:line: message). - * It also includes some additional useful information. - * This makes it a lot easier to skim through test failures in - * Emacs. ;-) - * - * It also supports a few special features specifically to simplify - * test harnesses: - * failure(fmt, args) -- Stores a text string that gets - * printed if the following assertion fails, good for - * explaining subtle tests. - */ -static char msg[4096]; - -/* - * For each test source file, we remember how many times each - * failure was reported. - */ -static const char *failed_filename = NULL; -static struct line { - int line; - int count; -} failed_lines[1000]; - -/* - * Count this failure; return the number of previous failures. - */ -static int -previous_failures(const char *filename, int line) -{ - unsigned int i; - int count; - - if (failed_filename == NULL || strcmp(failed_filename, filename) != 0) - memset(failed_lines, 0, sizeof(failed_lines)); - failed_filename = filename; - - for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) { - if (failed_lines[i].line == line) { - count = failed_lines[i].count; - failed_lines[i].count++; - return (count); - } - if (failed_lines[i].line == 0) { - failed_lines[i].line = line; - failed_lines[i].count = 1; - return (0); - } - } - return (0); -} - -/* - * Copy arguments into file-local variables. - */ -static const char *test_filename; -static int test_line; -static void *test_extra; -void test_setup(const char *filename, int line) -{ - test_filename = filename; - test_line = line; -} - -/* - * Inform user that we're skipping a test. - */ -void -test_skipping(const char *fmt, ...) -{ - va_list ap; - - if (previous_failures(test_filename, test_line)) - return; - - va_start(ap, fmt); - fprintf(stderr, " *** SKIPPING: "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - ++skips; -} - -/* Common handling of failed tests. */ -static void -report_failure(void *extra) -{ - if (msg[0] != '\0') { - fprintf(stderr, " Description: %s\n", msg); - msg[0] = '\0'; - } - -#ifdef EXTRA_DUMP - if (extra != NULL) - fprintf(stderr, " detail: %s\n", EXTRA_DUMP(extra)); -#else - (void)extra; /* UNUSED */ -#endif - - if (dump_on_failure) { - fprintf(stderr, - " *** forcing core dump so failure can be debugged ***\n"); - *(char *)(NULL) = 0; - exit(1); - } -} - -/* - * Summarize repeated failures in the just-completed test file. - * The reports above suppress multiple failures from the same source - * line; this reports on any tests that did fail multiple times. - */ -static int -summarize_comparator(const void *a0, const void *b0) -{ - const struct line *a = a0, *b = b0; - if (a->line == 0 && b->line == 0) - return (0); - if (a->line == 0) - return (1); - if (b->line == 0) - return (-1); - return (a->line - b->line); -} - -static void -summarize(void) -{ - unsigned int i; - - qsort(failed_lines, sizeof(failed_lines)/sizeof(failed_lines[0]), - sizeof(failed_lines[0]), summarize_comparator); - for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) { - if (failed_lines[i].line == 0) - break; - if (failed_lines[i].count > 1) - fprintf(stderr, "%s:%d: Failed %d times\n", - failed_filename, failed_lines[i].line, - failed_lines[i].count); - } - /* Clear the failure history for the next file. */ - memset(failed_lines, 0, sizeof(failed_lines)); -} - -/* Set up a message to display only after a test fails. */ -void -failure(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vsprintf(msg, fmt, ap); - va_end(ap); -} - -/* Generic assert() just displays the failed condition. */ -int -test_assert(const char *file, int line, int value, const char *condition, void *extra) -{ - ++assertions; - if (value) { - msg[0] = '\0'; - return (value); - } - failures ++; - if (!verbose && previous_failures(file, line)) - return (value); - fprintf(stderr, "%s:%d: Assertion failed\n", file, line); - fprintf(stderr, " Condition: %s\n", condition); - report_failure(extra); - return (value); -} - -/* assertEqualInt() displays the values of the two integers. */ -int -test_assert_equal_int(const char *file, int line, - int v1, const char *e1, int v2, const char *e2, void *extra) -{ - ++assertions; - if (v1 == v2) { - msg[0] = '\0'; - return (1); - } - failures ++; - if (!verbose && previous_failures(file, line)) - return (0); - fprintf(stderr, "%s:%d: Assertion failed: Ints not equal\n", - file, line); - fprintf(stderr, " %s=%d\n", e1, v1); - fprintf(stderr, " %s=%d\n", e2, v2); - report_failure(extra); - return (0); -} - -static void strdump(const char *p) -{ - if (p == NULL) { - fprintf(stderr, "(null)"); - return; - } - fprintf(stderr, "\""); - while (*p != '\0') { - unsigned int c = 0xff & *p++; - switch (c) { - case '\a': fprintf(stderr, "\a"); break; - case '\b': fprintf(stderr, "\b"); break; - case '\n': fprintf(stderr, "\n"); break; - case '\r': fprintf(stderr, "\r"); break; - default: - if (c >= 32 && c < 127) - fprintf(stderr, "%c", c); - else - fprintf(stderr, "\\x%02X", c); - } - } - fprintf(stderr, "\""); -} - -/* assertEqualString() displays the values of the two strings. */ -int -test_assert_equal_string(const char *file, int line, - const char *v1, const char *e1, - const char *v2, const char *e2, - void *extra) -{ - ++assertions; - if (v1 == NULL || v2 == NULL) { - if (v1 == v2) { - msg[0] = '\0'; - return (1); - } - } else if (strcmp(v1, v2) == 0) { - msg[0] = '\0'; - return (1); - } - failures ++; - if (!verbose && previous_failures(file, line)) - return (0); - fprintf(stderr, "%s:%d: Assertion failed: Strings not equal\n", - file, line); - fprintf(stderr, " %s = ", e1); - strdump(v1); - fprintf(stderr, " (length %d)\n", v1 == NULL ? 0 : strlen(v1)); - fprintf(stderr, " %s = ", e2); - strdump(v2); - fprintf(stderr, " (length %d)\n", v2 == NULL ? 0 : strlen(v2)); - report_failure(extra); - return (0); -} - -static void wcsdump(const wchar_t *w) -{ - if (w == NULL) { - fprintf(stderr, "(null)"); - return; - } - fprintf(stderr, "\""); - while (*w != L'\0') { - unsigned int c = *w++; - if (c >= 32 && c < 127) - fprintf(stderr, "%c", c); - else if (c < 256) - fprintf(stderr, "\\x%02X", c); - else if (c < 0x10000) - fprintf(stderr, "\\u%04X", c); - else - fprintf(stderr, "\\U%08X", c); - } - fprintf(stderr, "\""); -} - -/* assertEqualWString() displays the values of the two strings. */ -int -test_assert_equal_wstring(const char *file, int line, - const wchar_t *v1, const char *e1, - const wchar_t *v2, const char *e2, - void *extra) -{ - ++assertions; - if (v1 == NULL) { - if (v2 == NULL) { - msg[0] = '\0'; - return (1); - } - } else if (v2 == NULL) { - if (v1 == NULL) { - msg[0] = '\0'; - return (1); - } - } else if (wcscmp(v1, v2) == 0) { - msg[0] = '\0'; - return (1); - } - failures ++; - if (!verbose && previous_failures(file, line)) - return (0); - fprintf(stderr, "%s:%d: Assertion failed: Unicode strings not equal\n", - file, line); - fprintf(stderr, " %s = ", e1); - wcsdump(v1); - fprintf(stderr, "\n"); - fprintf(stderr, " %s = ", e2); - wcsdump(v2); - fprintf(stderr, "\n"); - report_failure(extra); - return (0); -} - -/* - * Pretty standard hexdump routine. As a bonus, if ref != NULL, then - * any bytes in p that differ from ref will be highlighted with '_' - * before and after the hex value. - */ -static void -hexdump(const char *p, const char *ref, size_t l, size_t offset) -{ - size_t i, j; - char sep; - - for(i=0; i < l; i+=16) { - fprintf(stderr, "%04x", i + offset); - sep = ' '; - for (j = 0; j < 16 && i + j < l; j++) { - if (ref != NULL && p[i + j] != ref[i + j]) - sep = '_'; - fprintf(stderr, "%c%02x", sep, 0xff & (int)p[i+j]); - if (ref != NULL && p[i + j] == ref[i + j]) - sep = ' '; - } - for (; j < 16; j++) { - fprintf(stderr, "%c ", sep); - sep = ' '; - } - fprintf(stderr, "%c", sep); - for (j=0; j < 16 && i + j < l; j++) { - int c = p[i + j]; - if (c >= ' ' && c <= 126) - fprintf(stderr, "%c", c); - else - fprintf(stderr, "."); - } - fprintf(stderr, "\n"); - } -} - -/* assertEqualMem() displays the values of the two memory blocks. */ -/* TODO: For long blocks, hexdump the first bytes that actually differ. */ -int -test_assert_equal_mem(const char *file, int line, - const char *v1, const char *e1, - const char *v2, const char *e2, - size_t l, const char *ld, void *extra) -{ - ++assertions; - if (v1 == NULL || v2 == NULL) { - if (v1 == v2) { - msg[0] = '\0'; - return (1); - } - } else if (memcmp(v1, v2, l) == 0) { - msg[0] = '\0'; - return (1); - } - failures ++; - if (!verbose && previous_failures(file, line)) - return (0); - fprintf(stderr, "%s:%d: Assertion failed: memory not equal\n", - file, line); - fprintf(stderr, " size %s = %d\n", ld, (int)l); - fprintf(stderr, " Dump of %s\n", e1); - hexdump(v1, v2, l < 32 ? l : 32, 0); - fprintf(stderr, " Dump of %s\n", e2); - hexdump(v2, v1, l < 32 ? l : 32, 0); - fprintf(stderr, "\n"); - report_failure(extra); - return (0); -} - -int -test_assert_empty_file(const char *f1fmt, ...) -{ - char buff[1024]; - char f1[1024]; - struct stat st; - va_list ap; - ssize_t s; - int fd; - - - va_start(ap, f1fmt); - vsprintf(f1, f1fmt, ap); - va_end(ap); - - if (stat(f1, &st) != 0) { - fprintf(stderr, "%s:%d: Could not stat: %s\n", test_filename, test_line, f1); - report_failure(NULL); - return (0); - } - if (st.st_size == 0) - return (1); - - failures ++; - if (!verbose && previous_failures(test_filename, test_line)) - return (0); - - fprintf(stderr, "%s:%d: File not empty: %s\n", test_filename, test_line, f1); - fprintf(stderr, " File size: %d\n", (int)st.st_size); - fprintf(stderr, " Contents:\n"); - fd = open(f1, O_RDONLY); - if (fd < 0) { - fprintf(stderr, " Unable to open %s\n", f1); - } else { - s = sizeof(buff) < st.st_size ? sizeof(buff) : st.st_size; - s = read(fd, buff, s); - hexdump(buff, NULL, s, 0); - } - report_failure(NULL); - return (0); -} - -/* assertEqualFile() asserts that two files have the same contents. */ -/* TODO: hexdump the first bytes that actually differ. */ -int -test_assert_equal_file(const char *f1, const char *f2pattern, ...) -{ - char f2[1024]; - va_list ap; - char buff1[1024]; - char buff2[1024]; - int fd1, fd2; - int n1, n2; - - va_start(ap, f2pattern); - vsprintf(f2, f2pattern, ap); - va_end(ap); - - fd1 = open(f1, O_RDONLY); - fd2 = open(f2, O_RDONLY); - for (;;) { - n1 = read(fd1, buff1, sizeof(buff1)); - n2 = read(fd2, buff2, sizeof(buff2)); - if (n1 != n2) - break; - if (n1 == 0 && n2 == 0) - return (1); - if (memcmp(buff1, buff2, n1) != 0) - break; - } - failures ++; - if (!verbose && previous_failures(test_filename, test_line)) - return (0); - fprintf(stderr, "%s:%d: Files are not identical\n", - test_filename, test_line); - fprintf(stderr, " file1=\"%s\"\n", f1); - fprintf(stderr, " file2=\"%s\"\n", f2); - report_failure(test_extra); - return (0); -} - -int -test_assert_file_exists(const char *fpattern, ...) -{ - char f[1024]; - va_list ap; - - va_start(ap, fpattern); - vsprintf(f, fpattern, ap); - va_end(ap); - - if (!access(f, F_OK)) - return (1); - if (!previous_failures(test_filename, test_line)) { - fprintf(stderr, "%s:%d: File doesn't exist\n", - test_filename, test_line); - fprintf(stderr, " file=\"%s\"\n", f); - report_failure(test_extra); - } - return (0); -} - -int -test_assert_file_not_exists(const char *fpattern, ...) -{ - char f[1024]; - va_list ap; - - va_start(ap, fpattern); - vsprintf(f, fpattern, ap); - va_end(ap); - - if (access(f, F_OK)) - return (1); - if (!previous_failures(test_filename, test_line)) { - fprintf(stderr, "%s:%d: File exists and shouldn't\n", - test_filename, test_line); - fprintf(stderr, " file=\"%s\"\n", f); - report_failure(test_extra); - } - return (0); -} - -/* assertFileContents() asserts the contents of a file. */ -int -test_assert_file_contents(const void *buff, int s, const char *fpattern, ...) -{ - char f[1024]; - va_list ap; - char *contents; - int fd; - int n; - - va_start(ap, fpattern); - vsprintf(f, fpattern, ap); - va_end(ap); - - fd = open(f, O_RDONLY); - contents = malloc(s * 2); - n = read(fd, contents, s * 2); - if (n == s && memcmp(buff, contents, s) == 0) { - free(contents); - return (1); - } - failures ++; - if (!previous_failures(test_filename, test_line)) { - fprintf(stderr, "%s:%d: File contents don't match\n", - test_filename, test_line); - fprintf(stderr, " file=\"%s\"\n", f); - if (n > 0) - hexdump(contents, buff, n, 0); - else { - fprintf(stderr, " File empty, contents should be:\n"); - hexdump(buff, NULL, s, 0); - } - report_failure(test_extra); - } - free(contents); - return (0); -} - -/* - * Call standard system() call, but build up the command line using - * sprintf() conventions. - */ -int -systemf(const char *fmt, ...) -{ - char buff[8192]; - va_list ap; - int r; - - va_start(ap, fmt); - vsprintf(buff, fmt, ap); - r = system(buff); - va_end(ap); - return (r); -} - -/* - * Slurp a file into memory for ease of comparison and testing. - * Returns size of file in 'sizep' if non-NULL, null-terminates - * data in memory for ease of use. - */ -char * -slurpfile(size_t * sizep, const char *fmt, ...) -{ - char filename[8192]; - struct stat st; - va_list ap; - char *p; - ssize_t bytes_read; - int fd; - int r; - - va_start(ap, fmt); - vsprintf(filename, fmt, ap); - va_end(ap); - - fd = open(filename, O_RDONLY); - if (fd < 0) { - /* Note: No error; non-existent file is okay here. */ - return (NULL); - } - r = fstat(fd, &st); - if (r != 0) { - fprintf(stderr, "Can't stat file %s\n", filename); - close(fd); - return (NULL); - } - p = malloc(st.st_size + 1); - if (p == NULL) { - fprintf(stderr, "Can't allocate %ld bytes of memory to read file %s\n", (long int)st.st_size, filename); - close(fd); - return (NULL); - } - bytes_read = read(fd, p, st.st_size); - if (bytes_read < st.st_size) { - fprintf(stderr, "Can't read file %s\n", filename); - close(fd); - free(p); - return (NULL); - } - p[st.st_size] = '\0'; - if (sizep != NULL) - *sizep = (size_t)st.st_size; - close(fd); - return (p); -} - -/* - * "list.h" is automatically generated; it just has a lot of lines like: - * DEFINE_TEST(function_name) - * It's used above to declare all of the test functions. - * We reuse it here to define a list of all tests (functions and names). - */ -#undef DEFINE_TEST -#define DEFINE_TEST(n) { n, #n }, -struct { void (*func)(void); const char *name; } tests[] = { - #include "list.h" -}; - -/* - * Each test is run in a private work dir. Those work dirs - * do have consistent and predictable names, in case a group - * of tests need to collaborate. However, there is no provision - * for requiring that tests run in a certain order. - */ -static int test_run(int i, const char *tmpdir) -{ - int failures_before = failures; - - if (!quiet_flag) { - printf("%d: %s\n", i, tests[i].name); - fflush(stdout); - } - - /* - * Always explicitly chdir() in case the last test moved us to - * a strange place. - */ - if (chdir(tmpdir)) { - fprintf(stderr, - "ERROR: Couldn't chdir to temp dir %s\n", - tmpdir); - exit(1); - } - /* Create a temp directory for this specific test. */ - if (mkdir(tests[i].name, 0755)) { - fprintf(stderr, - "ERROR: Couldn't create temp dir ``%s''\n", - tests[i].name); - exit(1); - } - /* Chdir() to that work directory. */ - if (chdir(tests[i].name)) { - fprintf(stderr, - "ERROR: Couldn't chdir to temp dir ``%s''\n", - tests[i].name); - exit(1); - } - /* Explicitly reset the locale before each test. */ - setlocale(LC_ALL, "C"); - /* Run the actual test. */ - (*tests[i].func)(); - /* Summarize the results of this test. */ - summarize(); - /* If there were no failures, we can remove the work dir. */ - if (failures == failures_before) { - if (!keep_temp_files && chdir(tmpdir) == 0) { - systemf("rm -rf %s", tests[i].name); - } - } - /* Return appropriate status. */ - return (failures == failures_before ? 0 : 1); -} - -static void usage(const char *program) -{ - static const int limit = sizeof(tests) / sizeof(tests[0]); - int i; - - printf("Usage: %s [options] <test> <test> ...\n", program); - printf("Default is to run all tests.\n"); - printf("Otherwise, specify the numbers of the tests you wish to run.\n"); - printf("Options:\n"); - printf(" -d Dump core after any failure, for debugging.\n"); - printf(" -k Keep all temp files.\n"); - printf(" Default: temp files for successful tests deleted.\n"); -#ifdef PROGRAM - printf(" -p <path> Path to executable to be tested.\n"); - printf(" Default: path taken from " ENVBASE " environment variable.\n"); -#endif - printf(" -q Quiet.\n"); - printf(" -r <dir> Path to dir containing reference files.\n"); - printf(" Default: Current directory.\n"); - printf(" -v Verbose.\n"); - printf("Available tests:\n"); - for (i = 0; i < limit; i++) - printf(" %d: %s\n", i, tests[i].name); - exit(1); -} - -#define UUDECODE(c) (((c) - 0x20) & 0x3f) - -void -extract_reference_file(const char *name) -{ - char buff[1024]; - FILE *in, *out; - - sprintf(buff, "%s/%s.uu", refdir, name); - in = fopen(buff, "r"); - failure("Couldn't open reference file %s", buff); - assert(in != NULL); - if (in == NULL) - return; - /* Read up to and including the 'begin' line. */ - for (;;) { - if (fgets(buff, sizeof(buff), in) == NULL) { - /* TODO: This is a failure. */ - return; - } - if (memcmp(buff, "begin ", 6) == 0) - break; - } - /* Now, decode the rest and write it. */ - /* Not a lot of error checking here; the input better be right. */ - out = fopen(name, "w"); - while (fgets(buff, sizeof(buff), in) != NULL) { - char *p = buff; - int bytes; - - if (memcmp(buff, "end", 3) == 0) - break; - - bytes = UUDECODE(*p++); - while (bytes > 0) { - int n = 0; - /* Write out 1-3 bytes from that. */ - if (bytes > 0) { - n = UUDECODE(*p++) << 18; - n |= UUDECODE(*p++) << 12; - fputc(n >> 16, out); - --bytes; - } - if (bytes > 0) { - n |= UUDECODE(*p++) << 6; - fputc((n >> 8) & 0xFF, out); - --bytes; - } - if (bytes > 0) { - n |= UUDECODE(*p++); - fputc(n & 0xFF, out); - --bytes; - } - } - } - fclose(out); - fclose(in); -} - - -int main(int argc, char **argv) -{ - static const int limit = sizeof(tests) / sizeof(tests[0]); - int i, tests_run = 0, tests_failed = 0, opt; - time_t now; - char *refdir_alloc = NULL; - char *progname, *p; - char tmpdir[256]; - char tmpdir_timestamp[256]; - - /* - * Name of this program, used to build root of our temp directory - * tree. - */ - progname = p = argv[0]; - while (*p != '\0') { - if (*p == '/') - progname = p + 1; - ++p; - } - -#ifdef PROGRAM - /* Get the target program from environment, if available. */ - testprog = getenv(ENVBASE); -#endif - - /* Allow -d to be controlled through the environment. */ - if (getenv(ENVBASE "_DEBUG") != NULL) - dump_on_failure = 1; - - /* Get the directory holding test files from environment. */ - refdir = getenv(ENVBASE "_TEST_FILES"); - - /* - * Parse options. - */ - while ((opt = getopt(argc, argv, "dkp:qr:v")) != -1) { - switch (opt) { - case 'd': - dump_on_failure = 1; - break; - case 'k': - keep_temp_files = 1; - break; - case 'p': -#ifdef PROGRAM - testprog = optarg; -#else - usage(progname); -#endif - break; - case 'q': - quiet_flag++; - break; - case 'r': - refdir = optarg; - break; - case 'v': - verbose = 1; - break; - case '?': - default: - usage(progname); - } - } - argc -= optind; - argv += optind; - - /* - * Sanity-check that our options make sense. - */ -#ifdef PROGRAM - if (testprog == NULL) - usage(progname); -#endif - - /* - * Create a temp directory for the following tests. - * Include the time the tests started as part of the name, - * to make it easier to track the results of multiple tests. - */ - now = time(NULL); - for (i = 0; i < 1000; i++) { - strftime(tmpdir_timestamp, sizeof(tmpdir_timestamp), - "%Y-%m-%dT%H.%M.%S", - localtime(&now)); - sprintf(tmpdir, "/tmp/%s.%s-%03d", progname, tmpdir_timestamp, i); - if (mkdir(tmpdir,0755) == 0) - break; - if (errno == EEXIST) - continue; - fprintf(stderr, "ERROR: Unable to create temp directory %s\n", - tmpdir); - exit(1); - } - - /* - * If the user didn't specify a directory for locating - * reference files, use the current directory for that. - */ - if (refdir == NULL) { - systemf("/bin/pwd > %s/refdir", tmpdir); - refdir = refdir_alloc = slurpfile(NULL, "%s/refdir", tmpdir); - p = refdir + strlen(refdir); - while (p[-1] == '\n') { - --p; - *p = '\0'; - } - systemf("rm %s/refdir", tmpdir); - } - - /* - * Banner with basic information. - */ - if (!quiet_flag) { - printf("Running tests in: %s\n", tmpdir); - printf("Reference files will be read from: %s\n", refdir); -#ifdef PROGRAM - printf("Running tests on: %s\n", testprog); -#endif - printf("Exercising: "); - fflush(stdout); - printf("%s\n", EXTRA_VERSION); - } - - /* - * Run some or all of the individual tests. - */ - if (argc == 0) { - /* Default: Run all tests. */ - for (i = 0; i < limit; i++) { - if (test_run(i, tmpdir)) - tests_failed++; - tests_run++; - } - } else { - while (*(argv) != NULL) { - i = atoi(*argv); - if (**argv < '0' || **argv > '9' || i < 0 || i >= limit) { - printf("*** INVALID Test %s\n", *argv); - usage(progname); - } else { - if (test_run(i, tmpdir)) - tests_failed++; - tests_run++; - } - argv++; - } - } - - /* - * Report summary statistics. - */ - if (!quiet_flag) { - printf("\n"); - printf("%d of %d tests reported failures\n", - tests_failed, tests_run); - printf(" Total of %d assertions checked.\n", assertions); - printf(" Total of %d assertions failed.\n", failures); - printf(" Total of %d assertions skipped.\n", skips); - } - - free(refdir_alloc); - - /* If the final tmpdir is empty, we can remove it. */ - /* This should be the usual case when all tests succeed. */ - rmdir(tmpdir); - - return (tests_failed); -} diff --git a/libarchive/libarchive-2.5.5/tar/test/test.h b/libarchive/libarchive-2.5.5/tar/test/test.h deleted file mode 100644 index 30321e8..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/test.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2003-2006 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/usr.bin/tar/test/test.h,v 1.3 2008/06/15 10:07:54 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) -/* 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 <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#ifndef _WIN32 -#include <unistd.h> -#endif -#include <wchar.h> - -#ifdef USE_DMALLOC -#include <dmalloc.h> -#endif - -/* No non-FreeBSD platform will have __FBSDID, so just define it here. */ -#ifdef __FreeBSD__ -#include <sys/cdefs.h> /* For __FBSDID */ -#else -#define __FBSDID(a) /* null */ -#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) test_assert(__FILE__, __LINE__, (e), #e, NULL) - -/* Assert two integers are the same. Reports value of each one if not. */ -#define assertEqualInt(v1,v2) \ - test_assert_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) \ - test_assert_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL) -/* As above, but v1 and v2 are wchar_t * */ -#define assertEqualWString(v1,v2) \ - test_assert_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL) -/* As above, but raw blocks of bytes. */ -#define assertEqualMem(v1, v2, l) \ - test_assert_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 \ - test_setup(__FILE__, __LINE__);test_assert_equal_file -/* Assert that a file is empty; supports printf-style arguments. */ -#define assertEmptyFile \ - test_setup(__FILE__, __LINE__);test_assert_empty_file -/* Assert that a file exists; supports printf-style arguments. */ -#define assertFileExists \ - test_setup(__FILE__, __LINE__);test_assert_file_exists -/* Assert that a file exists; supports printf-style arguments. */ -#define assertFileNotExists \ - test_setup(__FILE__, __LINE__);test_assert_file_not_exists -/* Assert that file contents match a string; supports printf-style arguments. */ -#define assertFileContents \ - test_setup(__FILE__, __LINE__);test_assert_file_contents - -/* - * 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 \ - test_setup(__FILE__, __LINE__);test_skipping - -/* Function declarations. These are defined in test_utility.c. */ -void failure(const char *fmt, ...); -void test_setup(const char *, int); -void test_skipping(const char *fmt, ...); -int test_assert(const char *, int, int, const char *, void *); -int test_assert_empty_file(const char *, ...); -int test_assert_equal_file(const char *, const char *, ...); -int test_assert_equal_int(const char *, int, int, const char *, int, const char *, void *); -int test_assert_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *); -int test_assert_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *); -int test_assert_equal_mem(const char *, int, const char *, const char *, const char *, const char *, size_t, const char *, void *); -int test_assert_file_contents(const void *, int, const char *, ...); -int test_assert_file_exists(const char *, ...); -int test_assert_file_not_exists(const char *, ...); - -/* Like sprintf, then system() */ -int systemf(const char * fmt, ...); - -/* 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. */ -char *testprog; diff --git a/libarchive/libarchive-2.5.5/tar/test/test_0.c b/libarchive/libarchive-2.5.5/tar/test/test_0.c deleted file mode 100644 index 36c8b1e..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/test_0.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "test.h" -__FBSDID("$FreeBSD: 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. - */ - -DEFINE_TEST(test_0) -{ - struct stat st; - - failure("File %s does not exist?!", testprog); - if (!assertEqualInt(0, stat(testprog, &st))) - exit(1); - - failure("%s is not executable?!", testprog); - if (!assert((st.st_mode & 0111) != 0)) - exit(1); - - /* - * Try to succesfully run the program; this requires that - * we know some option that will succeed. - */ - if (0 == systemf("%s --version >/dev/null", testprog)) { - /* This worked. */ - } else if (0 == systemf("%s -W version >/dev/null", testprog)) { - /* This worked. */ - } else { - failure("Unable to successfully run any of the following:\n" - " * %s --version\n" - " * %s -W version\n", - testprog, testprog); - assert(0); - } - - /* TODO: Ensure that our reference files are available. */ -} diff --git a/libarchive/libarchive-2.5.5/tar/test/test_basic.c b/libarchive/libarchive-2.5.5/tar/test/test_basic.c deleted file mode 100644 index fff5112..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/test_basic.c +++ /dev/null @@ -1,158 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "test.h" -__FBSDID("$FreeBSD: 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) -{ - struct stat st, st2; - char buff[128]; - int r; - - assertEqualInt(0, mkdir(target, 0775)); - - /* Use the tar program to create an archive. */ - r = systemf("%s cf - %s `cat filelist` >%s/archive 2>%s/pack.err", testprog, pack_options, target, target); - failure("Error invoking %s cf -", testprog, pack_options); - assertEqualInt(r, 0); - - chdir(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. */ - r = lstat("file", &st); - failure("Failed to stat file %s/file, errno=%d", target, errno); - assertEqualInt(r, 0); - if (r == 0) { - assert(S_ISREG(st.st_mode)); - assertEqualInt(0644, st.st_mode & 0777); - assertEqualInt(10, st.st_size); - failure("file %s/file", target); - assertEqualInt(2, st.st_nlink); - } - - /* Another name for the same file. */ - r = lstat("linkfile", &st2); - failure("Failed to stat file %s/linkfile, errno=%d", target, errno); - assertEqualInt(r, 0); - if (r == 0) { - assert(S_ISREG(st2.st_mode)); - assertEqualInt(0644, st2.st_mode & 0777); - assertEqualInt(10, st2.st_size); - failure("file %s/linkfile", target); - assertEqualInt(2, st2.st_nlink); - /* Verify that the two are really hardlinked. */ - assertEqualInt(st.st_dev, st2.st_dev); - failure("%s/linkfile and %s/file aren't really hardlinks", target, target); - assertEqualInt(st.st_ino, st2.st_ino); - } - - /* Symlink */ - r = lstat("symlink", &st); - failure("Failed to stat file %s/symlink, errno=%d", target, errno); - assertEqualInt(r, 0); - if (r == 0) { - failure("symlink should be a symlink; actual mode is %o", - st.st_mode); - assert(S_ISLNK(st.st_mode)); - if (S_ISLNK(st.st_mode)) { - r = readlink("symlink", buff, sizeof(buff)); - assertEqualInt(r, 4); - buff[r] = '\0'; - assertEqualString(buff, "file"); - } - } - - /* dir */ - r = lstat("dir", &st); - if (r == 0) { - assertEqualInt(r, 0); - assert(S_ISDIR(st.st_mode)); - assertEqualInt(0775, st.st_mode & 0777); - } - - chdir(".."); -} - -DEFINE_TEST(test_basic) -{ - int fd; - int filelist; - int oldumask; - - oldumask = umask(0); - - /* - * Create an assortment of files on disk. - */ - filelist = open("filelist", O_CREAT | O_WRONLY, 0644); - - /* File with 10 bytes content. */ - fd = open("file", O_CREAT | O_WRONLY, 0644); - assert(fd >= 0); - assertEqualInt(10, write(fd, "123456789", 10)); - close(fd); - write(filelist, "file\n", 5); - - /* hardlink to above file. */ - assertEqualInt(0, link("file", "linkfile")); - write(filelist, "linkfile\n", 9); - - /* Symlink to above file. */ - assertEqualInt(0, symlink("file", "symlink")); - write(filelist, "symlink\n", 8); - - /* Directory. */ - assertEqualInt(0, mkdir("dir", 0775)); - write(filelist, "dir\n", 4); - /* All done. */ - close(filelist); - - /* Archive/dearchive with a variety of options. */ - basic_tar("copy", "", ""); - /* tar doesn't handle cpio symlinks correctly */ - /* basic_tar("copy_odc", "--format=odc", ""); */ - basic_tar("copy_ustar", "--format=ustar", ""); - - umask(oldumask); -} diff --git a/libarchive/libarchive-2.5.5/tar/test/test_copy.c b/libarchive/libarchive-2.5.5/tar/test/test_copy.c deleted file mode 100644 index b2eef8c..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/test_copy.c +++ /dev/null @@ -1,326 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_copy.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $"); - -static void -create_tree(void) -{ - char buff[260]; - char buff2[260]; - int i; - int fd; - - assertEqualInt(0, mkdir("original", 0775)); - chdir("original"); - assertEqualInt(0, mkdir("f", 0775)); - assertEqualInt(0, mkdir("l", 0775)); - assertEqualInt(0, mkdir("m", 0775)); - assertEqualInt(0, mkdir("s", 0775)); - assertEqualInt(0, mkdir("d", 0775)); - - for (i = 0; i < 200; i++) { - buff[0] = 'f'; - buff[1] = '/'; - /* Create a file named "f/abcdef..." */ - buff[i + 2] = 'a' + (i % 26); - buff[i + 3] = '\0'; - fd = open(buff, O_CREAT | O_WRONLY, 0644); - assert(fd >= 0); - assertEqualInt(i + 3, write(fd, buff, strlen(buff))); - close(fd); - - /* Create a link named "l/abcdef..." to the above. */ - strcpy(buff2, buff); - buff2[0] = 'l'; - assertEqualInt(0, link(buff, buff2)); - - /* Create a link named "m/abcdef..." to the above. */ - strcpy(buff2, buff); - buff2[0] = 'm'; - assertEqualInt(0, link(buff, buff2)); - - /* Create a symlink named "s/abcdef..." to the above. */ - strcpy(buff2 + 3, buff); - buff[0] = 's'; - buff2[0] = '.'; - buff2[1] = '.'; - buff2[2] = '/'; - assertEqualInt(0, symlink(buff2, buff)); - - /* Create a dir named "d/abcdef...". */ - buff[0] = 'd'; - assertEqualInt(0, mkdir(buff, 0775)); - } - - chdir(".."); -} - -#define LIMIT_NONE 0 -#define LIMIT_USTAR 1 - -static void -verify_tree(int limit) -{ - struct stat st, st2; - char filename[260]; - char name1[260]; - char name2[260]; - char contents[260]; - int i, j, r; - int fd; - int len; - const char *p, *dp; - DIR *d; - struct dirent *de; - - /* Generate the names we know should be there and verify them. */ - for (i = 1; i < 200; i++) { - /* Generate a base name of the correct length. */ - for (j = 0; j < i; ++j) - filename[j] = 'a' + (j % 26); -#if 0 - for (n = i; n > 0; n /= 10) - filename[--j] = '0' + (n % 10); -#endif - filename[i] = '\0'; - - /* Verify a file named "f/abcdef..." */ - strcpy(name1, "f/"); - strcat(name1, filename); - if (limit != LIMIT_USTAR || strlen(filename) <= 100) { - fd = open(name1, O_RDONLY); - failure("Couldn't open \"%s\": %s", - name1, strerror(errno)); - if (assert(fd >= 0)) { - len = read(fd, contents, i + 10); - close(fd); - assertEqualInt(len, i + 2); - /* Verify contents of 'contents' */ - contents[len] = '\0'; - failure("Each test file contains its own name"); - assertEqualString(name1, contents); - /* stat() for dev/ino for next check */ - assertEqualInt(0, lstat(name1, &st)); - } - } - - /* - * ustar allows 100 chars for links, and we have - * "original/" as part of the name, so the link - * names here can't exceed 91 chars. - */ - strcpy(name2, "l/"); - strcat(name2, filename); - if (limit != LIMIT_USTAR || strlen(name2) <= 100) { - /* Verify hardlink "l/abcdef..." */ - assertEqualInt(0, (r = lstat(name2, &st2))); - if (r == 0) { - assertEqualInt(st2.st_dev, st.st_dev); - assertEqualInt(st2.st_ino, st.st_ino); - } - - /* Verify hardlink "m_abcdef..." */ - name2[0] = 'm'; - assertEqualInt(0, (r = lstat(name2, &st2))); - if (r == 0) { - assertEqualInt(st2.st_dev, st.st_dev); - assertEqualInt(st2.st_ino, st.st_ino); - } - } - - /* - * Symlink text doesn't include the 'original/' prefix, - * so the limit here is 100 characters. - */ - /* Verify symlink "s/abcdef..." */ - strcpy(name2, "../s/"); - strcat(name2, filename); - if (limit != LIMIT_USTAR || strlen(name2) <= 100) { - /* This is a symlink. */ - failure("Couldn't stat %s (length %d)", - filename, strlen(filename)); - if (assertEqualInt(0, lstat(name2 + 3, &st2))) { - assert(S_ISLNK(st2.st_mode)); - /* This is a symlink to the file above. */ - failure("Couldn't stat %s", name2 + 3); - if (assertEqualInt(0, stat(name2 + 3, &st2))) { - assertEqualInt(st2.st_dev, st.st_dev); - assertEqualInt(st2.st_ino, st.st_ino); - } - } - } - - /* Verify dir "d/abcdef...". */ - strcpy(name1, "d/"); - strcat(name1, filename); - if (limit != LIMIT_USTAR || strlen(filename) < 100) { - /* This is a dir. */ - failure("Couldn't stat %s (length %d)", - name1, strlen(filename)); - if (assertEqualInt(0, lstat(name1, &st2))) { - if (assert(S_ISDIR(st2.st_mode))) { - /* TODO: opendir/readdir this - * directory and make sure - * it's empty. - */ - } - } - } - } - - /* Now make sure nothing is there that shouldn't be. */ - for (dp = "dflms"; *dp != '\0'; ++dp) { - char dir[2]; - dir[0] = *dp; dir[1] = '\0'; - d = opendir(dir); - while ((de = readdir(d)) != NULL) { - p = de->d_name; - switch(dp[0]) { - case 'l': case 'm': - if (limit == LIMIT_USTAR) { - failure("strlen(p) = %d", strlen(p)); - assert(strlen(p) <= 100); - } - case 'd': - if (limit == LIMIT_USTAR) { - failure("strlen(p)=%d", strlen(p)); - assert(strlen(p) < 100); - } - case 'f': case 's': - if (limit == LIMIT_USTAR) { - failure("strlen(p)=%d", strlen(p)); - assert(strlen(p) < 101); - } - /* Our files have very particular filename patterns. */ - if (p[0] != '.' || (p[1] != '.' && p[1] != '\0')) { - for (i = 0; p[i] != '\0' && i < 200; i++) { - failure("i=%d, p[i]='%c' 'a'+(i%%26)='%c'", i, p[i], 'a' + (i % 26)); - assertEqualInt(p[i], 'a' + (i % 26)); - } - assert(p[i] == '\0'); - } - break; - case '.': - assert(p[1] == '\0' || (p[1] == '.' && p[2] == '\0')); - break; - default: - failure("File %s shouldn't be here", p); - assert(0); - } - } - closedir(d); - } -} - -static void -copy_basic(void) -{ - int r; - - assertEqualInt(0, mkdir("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; - - assertEqualInt(0, mkdir(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"); - - chdir("original"); - verify_tree(LIMIT_USTAR); - chdir("../.."); -} - -DEFINE_TEST(test_copy) -{ - int oldumask; - - oldumask = umask(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(); - - umask(oldumask); -} diff --git a/libarchive/libarchive-2.5.5/tar/test/test_getdate.c b/libarchive/libarchive-2.5.5/tar/test/test_getdate.c deleted file mode 100644 index d75119c..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/test_getdate.c +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_getdate.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $"); - -/* - * Verify that the getdate() function works. - */ - -time_t get_date(const char *); - -DEFINE_TEST(test_getdate) -{ - assertEqualInt(0, get_date("Jan 1, 1970 UTC")); - /* TODO: Lots more tests here. */ -} diff --git a/libarchive/libarchive-2.5.5/tar/test/test_help.c b/libarchive/libarchive-2.5.5/tar/test/test_help.c deleted file mode 100644 index 163e212..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/test_help.c +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "test.h" -__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); - 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); - 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); - failure("-W help should generate nothing to stderr."); - assertEmptyFile("Whelp.stderr"); - failure("stdout should be same for -W help and --help"); - assertEqualFile("Whelp.stdout", "help.stdout"); -} diff --git a/libarchive/libarchive-2.5.5/tar/test/test_option_T.c b/libarchive/libarchive-2.5.5/tar/test/test_option_T.c deleted file mode 100644 index 6c9007b..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/test_option_T.c +++ /dev/null @@ -1,142 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_option_T.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $"); - -static int -touch(const char *fn) -{ - int fd = open(fn, O_RDWR | O_CREAT); - failure("Couldn't create file '%s', fd=%d, errno=%d (%s)\n", - fn, fd, errno, strerror(errno)); - if (!assert(fd > 0)) - return (0); /* Failure. */ - close(fd); - return (1); /* Success */ -} - -DEFINE_TEST(test_option_T) -{ - FILE *f; - - /* Create a simple dir heirarchy; bail if anything fails. */ - if (!assertEqualInt(0, mkdir("d1", 0755))) return; - if (!assertEqualInt(0, mkdir("d1/d2", 0755))) return; - if (!touch("d1/f1")) return; - if (!touch("d1/f2")) return; - if (!touch("d1/d2/f3")) return; - if (!touch("d1/d2/f4")) return; - if (!touch("d1/d2/f5")) return; - - /* Populate a file list */ - f = fopen("filelist", "w+"); - if (!assert(f != NULL)) - return; - fprintf(f, "d1/f1\n"); - fprintf(f, "d1/d2/f4\n"); - fclose(f); - - /* Populate a second file list */ - f = fopen("filelist2", "w+"); - if (!assert(f != NULL)) - return; - fprintf(f, "d1/d2/f3\n"); - fprintf(f, "d1/d2/f5\n"); - fclose(f); - - /* Use -c -T to archive up the files. */ - systemf("%s -c -f test1.tar -T filelist > test1.out 2> test1.err", - testprog); - assertEmptyFile("test1.out"); - assertEmptyFile("test1.err"); - - /* Use -x -T to dearchive the files */ - if (!assertEqualInt(0, mkdir("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/d1/f1"); - assertFileNotExists("test1/d1/f2"); - assertFileNotExists("test1/d1/d2/f3"); - assertFileExists("test1/d1/d2/f4"); - assertFileNotExists("test1/d1/d2/f5"); - - /* Use -r -T to add more files to the archive. */ - systemf("%s -r -f test1.tar -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 (!assertEqualInt(0, mkdir("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/d1/f1"); - assertFileNotExists("test3/d1/f2"); - assertFileExists("test3/d1/d2/f3"); - assertFileExists("test3/d1/d2/f4"); - assertFileExists("test3/d1/d2/f5"); - - /* Use -x -T to dearchive the files (verify -x -T together) */ - if (!assertEqualInt(0, mkdir("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/d1/f1"); - assertFileNotExists("test2/d1/f2"); - assertFileNotExists("test2/d1/d2/f3"); - assertFileExists("test2/d1/d2/f4"); - assertFileNotExists("test2/d1/d2/f5"); - - assertEqualInt(0, mkdir("test4", 0755)); - assertEqualInt(0, mkdir("test4_out", 0755)); - assertEqualInt(0, mkdir("test4_out2", 0755)); - assertEqualInt(0, mkdir("test4/d1", 0755)); - assertEqualInt(1, touch("test4/d1/foo")); - - 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"); - - /* TODO: Include some use of -C directory-changing within the filelist. */ - /* I'm pretty sure -C within the filelist is broken on extract. */ -} diff --git a/libarchive/libarchive-2.5.5/tar/test/test_patterns.c b/libarchive/libarchive-2.5.5/tar/test/test_patterns.c deleted file mode 100644 index e7b1679..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/test_patterns.c +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_patterns) -{ - int fd, r; - - /* - * Test basic command-line pattern handling. - */ - - /* - * John Baldwin reported this problem in PR bin/121598 - */ - fd = open("foo", O_CREAT | O_WRONLY, 0644); - assert(fd >= 0); - close(fd); - r = systemf("%s zcfv tar1.tgz foo > tar1a.out 2> tar1a.err", testprog); - assertEqualInt(r, 0); - r = systemf("%s zxfv 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); -} diff --git a/libarchive/libarchive-2.5.5/tar/test/test_stdio.c b/libarchive/libarchive-2.5.5/tar/test/test_stdio.c deleted file mode 100644 index d770cf1..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/test_stdio.c +++ /dev/null @@ -1,124 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_stdio.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $"); - -DEFINE_TEST(test_stdio) -{ - int fd; - int filelist; - int oldumask; - int r; - - oldumask = umask(0); - - /* - * Create a couple of files on disk. - */ - filelist = open("filelist", O_CREAT | O_WRONLY, 0644); - /* File */ - fd = open("f", O_CREAT | O_WRONLY, 0644); - assert(fd >= 0); - write(fd, "f\n", 2); - close(fd); - write(filelist, "f\n", 2); - /* Link to above file. */ - assertEqualInt(0, link("f", "l")); - write(filelist, "l\n", 2); - close(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); - /* TODO: Verify xvOf.out */ - /* 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 */ - - umask(oldumask); -} diff --git a/libarchive/libarchive-2.5.5/tar/test/test_version.c b/libarchive/libarchive-2.5.5/tar/test/test_version.c deleted file mode 100644 index 6ed656d..0000000 --- a/libarchive/libarchive-2.5.5/tar/test/test_version.c +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "test.h" -__FBSDID("$FreeBSD: 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: %s", p); - assertEqualMem(q, "bsdtar ", 7); - 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("Version: %s", p); - assert(s > 1); - /* Skip a single trailing a,b,c, or d. */ - if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd') - ++q; - failure("Version: %s", p); - assert(*q == ' '); - ++q; --s; - /* Separator. */ - failure("Version: %s", p); - assertEqualMem(q, "- ", 2); - q += 2; s -= 2; - /* libarchive name and version number */ - failure("Version: %s", p); - assert(s > 11); - failure("Version: %s", p); - assertEqualMem(q, "libarchive ", 11); - q += 11; s -= 11; - /* Version number is a series of digits and periods. */ - while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) { - ++q; - --s; - } - /* Skip a single trailing a,b,c, or d. */ - if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd') - ++q; - /* All terminated by a newline. */ - assert(s >= 1); - assertEqualMem(q, "\n", 1); - free(p); -} diff --git a/libarchive/libarchive-2.5.5/tar/tree.c b/libarchive/libarchive-2.5.5/tar/tree.c deleted file mode 100644 index 23e64e3..0000000 --- a/libarchive/libarchive-2.5.5/tar/tree.c +++ /dev/null @@ -1,542 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/*- - * This is a new directory-walking system that addresses a number - * of problems I've had with fts(3). In particular, it has no - * pathname-length limits (other than the size of 'int'), handles - * deep logical traversals, uses considerably less memory, and has - * an opaque interface (easier to modify in the future). - * - * Internally, it keeps a single list of "tree_entry" items that - * represent filesystem objects that require further attention. - * Non-directories are not kept in memory: they are pulled from - * readdir(), returned to the client, then freed as soon as possible. - * Any directory entry to be traversed gets pushed onto the stack. - * - * There is surprisingly little information that needs to be kept for - * each item on the stack. Just the name, depth (represented here as the - * string length of the parent directory's pathname), and some markers - * indicating how to get back to the parent (via chdir("..") for a - * regular dir or via fchdir(2) for a symlink). - */ -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/tree.c,v 1.8 2007/03/11 10:36:42 kientzle Exp $"); - -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.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 - -#include "tree.h" - -/* - * TODO: - * 1) Loop checking. - * 3) Arbitrary logical traversals by closing/reopening intermediate fds. - */ - -struct tree_entry { - struct tree_entry *next; - struct tree_entry *parent; - char *name; - size_t dirname_length; - dev_t dev; - ino_t ino; - int fd; - int flags; -}; - -/* 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 needsPreVisit 4 /* This entry needs to be previsited. */ -#define needsPostVisit 8 /* This entry needs to be postvisited. */ - -/* - * Local data for this package. - */ -struct tree { - struct tree_entry *stack; - struct tree_entry *current; - DIR *d; - int initialDirFd; - int flags; - int visit_type; - int tree_errno; /* Error code from last failed operation. */ - - char *buff; - const char *basename; - size_t buff_length; - size_t path_length; - size_t dirname_length; - - int depth; - int openCount; - int maxOpenCount; - - struct stat lst; - struct stat st; -}; - -/* Definitions for tree.flags bitmap. */ -#define needsReturn 8 /* Marks first entry as not having been returned yet. */ -#define hasStat 16 /* The st entry is set. */ -#define hasLstat 32 /* The lst entry is set. */ - - -#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 - -#if 0 -#include <stdio.h> -void -tree_dump(struct tree *t, FILE *out) -{ - struct tree_entry *te; - - fprintf(out, "\tdepth: %d\n", t->depth); - fprintf(out, "\tbuff: %s\n", t->buff); - fprintf(out, "\tpwd: "); fflush(stdout); system("pwd"); - fprintf(out, "\taccess: %s\n", t->basename); - fprintf(out, "\tstack:\n"); - for (te = t->stack; te != NULL; te = te->next) { - fprintf(out, "\t\tte->name: %s%s%s\n", te->name, - te->flags & needsPreVisit ? "" : " *", - t->current == te ? " (current)" : ""); - } -} -#endif - -/* - * 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; - t->stack = te; - te->fd = -1; - te->name = strdup(path); - te->flags = needsPreVisit | needsPostVisit; - te->dirname_length = t->dirname_length; -} - -/* - * Append a name to the current path. - */ -static void -tree_append(struct tree *t, const char *name, size_t name_length) -{ - char *p; - - 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. */ - while (name_length + 1 + t->dirname_length >= t->buff_length) { - t->buff_length *= 2; - if (t->buff_length < 1024) - t->buff_length = 1024; - t->buff = realloc(t->buff, t->buff_length); - } - 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 ++; - } - strncpy(p, name, name_length); - p[name_length] = '\0'; - t->basename = p; -} - -/* - * Open a directory tree for traversal. - */ -struct tree * -tree_open(const char *path) -{ - struct tree *t; - - t = malloc(sizeof(*t)); - memset(t, 0, sizeof(*t)); - tree_append(t, path, strlen(path)); - t->initialDirFd = open(".", O_RDONLY); - /* - * During most of the traversal, items are set up and then - * returned immediately from tree_next(). That doesn't work - * for the very first entry, so we set a flag for this special - * case. - */ - t->flags = needsReturn; - return (t); -} - -/* - * We've finished a directory; ascend back to the parent. - */ -static void -tree_ascend(struct tree *t) -{ - struct tree_entry *te; - - te = t->stack; - t->depth--; - if (te->flags & isDirLink) { - fchdir(te->fd); - close(te->fd); - t->openCount--; - } else { - chdir(".."); - } -} - -/* - * Pop the working stack. - */ -static void -tree_pop(struct tree *t) -{ - struct tree_entry *te; - - 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; - t->basename = t->buff + t->dirname_length; - /* Special case: starting dir doesn't skip leading '/'. */ - if (t->dirname_length > 0) - t->basename++; - free(te->name); - free(te); -} - -/* - * Get the next item in the tree traversal. - */ -int -tree_next(struct tree *t) -{ - struct dirent *de = NULL; - - /* Handle the startup case by returning the initial entry. */ - if (t->flags & needsReturn) { - t->flags &= ~needsReturn; - return (t->visit_type = TREE_REGULAR); - } - - while (t->stack != NULL) { - /* If there's an open dir, get the next entry from there. */ - while (t->d != NULL) { - de = readdir(t->d); - if (de == NULL) { - closedir(t->d); - t->d = NULL; - } else if (de->d_name[0] == '.' - && de->d_name[1] == '\0') { - /* Skip '.' */ - } else if (de->d_name[0] == '.' - && de->d_name[1] == '.' - && de->d_name[2] == '\0') { - /* Skip '..' */ - } else { - /* - * Append the path to the current path - * and return it. - */ - tree_append(t, de->d_name, D_NAMELEN(de)); - t->flags &= ~hasLstat; - t->flags &= ~hasStat; - return (t->visit_type = TREE_REGULAR); - } - } - - /* If the current dir needs to be visited, set it up. */ - if (t->stack->flags & needsPreVisit) { - t->current = t->stack; - tree_append(t, t->stack->name, strlen(t->stack->name)); - t->stack->flags &= ~needsPreVisit; - /* If it is a link, set up fd for the ascent. */ - if (t->stack->flags & isDirLink) { - t->stack->fd = open(".", O_RDONLY); - t->openCount++; - if (t->openCount > t->maxOpenCount) - t->maxOpenCount = t->openCount; - } - t->dirname_length = t->path_length; - if (chdir(t->stack->name) != 0) { - /* chdir() failed; return error */ - tree_pop(t); - t->tree_errno = errno; - return (t->visit_type = TREE_ERROR_DIR); - } - t->depth++; - t->d = opendir("."); - if (t->d == NULL) { - tree_ascend(t); /* Undo "chdir" */ - tree_pop(t); - t->tree_errno = errno; - return (t->visit_type = TREE_ERROR_DIR); - } - t->flags &= ~hasLstat; - t->flags &= ~hasStat; - t->basename = "."; - return (t->visit_type = TREE_POSTDESCENT); - } - - /* We've done everything necessary for the top stack entry. */ - if (t->stack->flags & needsPostVisit) { - tree_ascend(t); - tree_pop(t); - t->flags &= ~hasLstat; - t->flags &= ~hasStat; - return (t->visit_type = TREE_POSTASCENT); - } - } - return (t->visit_type = 0); -} - -/* - * 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(t->basename, &t->st) != 0) - return NULL; - t->flags |= hasStat; - } - return (&t->st); -} - -/* - * Get the lstat() data for the entry just returned from tree_next(). - */ -const struct stat * -tree_current_lstat(struct tree *t) -{ - if (!(t->flags & hasLstat)) { - if (lstat(t->basename, &t->lst) != 0) - return NULL; - t->flags |= hasLstat; - } - return (&t->lst); -} - -/* - * Test whether current entry is a dir or link to a dir. - */ -int -tree_current_is_dir(struct tree *t) -{ - 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)); -} - -/* - * 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) -{ - 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)); -} - -/* - * Test whether current entry is a symbolic link. - */ -int -tree_current_is_physical_link(struct tree *t) -{ - const struct stat *st = tree_current_lstat(t); - if (st == NULL) - return 0; - return (S_ISLNK(st->st_mode)); -} - -/* - * 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); - if (t->buff) - free(t->buff); - /* chdir() back to where we started. */ - if (t->initialDirFd >= 0) { - fchdir(t->initialDirFd); - close(t->initialDirFd); - t->initialDirFd = -1; - } - free(t); -} diff --git a/libarchive/libarchive-2.5.5/tar/tree.h b/libarchive/libarchive-2.5.5/tar/tree.h deleted file mode 100644 index a32a15f..0000000 --- a/libarchive/libarchive-2.5.5/tar/tree.h +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/usr.bin/tar/tree.h,v 1.3 2007/01/09 08:12:17 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 potentially visited three times. The first - * time as "regular" file. If tree_descend() is invoked at that time, - * the directory is added to a work list and will be visited two more - * times: once just after descending into the directory and again - * just after ascending back to the parent. - * - * TREE_ERROR is returned if the descent failed (because the - * directory couldn't be opened, for instance). This is returned - * instead of TREE_PREVISIT/TREE_POSTVISIT. - */ -#define TREE_REGULAR 1 -#define TREE_POSTDESCENT 2 -#define TREE_POSTASCENT 3 -#define TREE_ERROR_DIR -1 -int tree_next(struct tree *); - -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. - */ - -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. - */ -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 tests may use mechanisms much faster than stat()/lstat(). */ -/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */ -int tree_current_is_physical_dir(struct tree *); -/* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */ -int tree_current_is_physical_link(struct tree *); -/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */ -int tree_current_is_dir(struct tree *); - -/* For testing/debugging: Dump the internal status to the given filehandle. */ -void tree_dump(struct tree *, FILE *); diff --git a/libarchive/libarchive-2.5.5/tar/util.c b/libarchive/libarchive-2.5.5/tar/util.c deleted file mode 100644 index ee1e40d..0000000 --- a/libarchive/libarchive-2.5.5/tar/util.c +++ /dev/null @@ -1,489 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/util.c,v 1.20 2008/06/09 14:03:55 cperciva 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_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 "bsdtar.h" - -static void bsdtar_vwarnc(struct bsdtar *, int code, - const char *fmt, va_list ap); - -/* - * Print a string, taking care with any non-printable characters. - */ - -void -safe_fprintf(FILE *f, const char *fmt, ...) -{ - char *buff; - char *buff_heap; - int buff_length; - int length; - va_list ap; - char *p; - unsigned i; - char buff_stack[256]; - char copy_buff[256]; - - /* Use a stack-allocated buffer if we can, for speed and safety. */ - buff_heap = NULL; - buff_length = sizeof(buff_stack); - buff = buff_stack; - - va_start(ap, fmt); - length = vsnprintf(buff, buff_length, fmt, ap); - va_end(ap); - /* If the result is too large, allocate a buffer on the heap. */ - if (length >= buff_length) { - buff_length = length+1; - buff_heap = malloc(buff_length); - /* Failsafe: use the truncated string if malloc fails. */ - if (buff_heap != NULL) { - buff = buff_heap; - va_start(ap, fmt); - length = vsnprintf(buff, buff_length, fmt, ap); - va_end(ap); - } - } - - /* Write data, expanding unprintable characters. */ - p = buff; - i = 0; - while (*p != '\0') { - unsigned char c = *p++; - - if (isprint(c) && c != '\\') - copy_buff[i++] = c; - else { - copy_buff[i++] = '\\'; - switch (c) { - case '\a': copy_buff[i++] = 'a'; break; - case '\b': copy_buff[i++] = 'b'; break; - case '\f': copy_buff[i++] = 'f'; break; - case '\n': copy_buff[i++] = 'n'; break; -#if '\r' != '\n' - /* On some platforms, \n and \r are the same. */ - case '\r': copy_buff[i++] = 'r'; break; -#endif - case '\t': copy_buff[i++] = 't'; break; - case '\v': copy_buff[i++] = 'v'; break; - case '\\': copy_buff[i++] = '\\'; break; - default: - sprintf(copy_buff + i, "%03o", c); - i += 3; - } - } - - /* If our temp buffer is full, dump it and keep going. */ - if (i > (sizeof(copy_buff) - 8)) { - copy_buff[i++] = '\0'; - fprintf(f, "%s", copy_buff); - i = 0; - } - } - copy_buff[i++] = '\0'; - fprintf(f, "%s", copy_buff); - - /* If we allocated a heap-based buffer, free it now. */ - if (buff_heap != NULL) - free(buff_heap); -} - -static void -bsdtar_vwarnc(struct bsdtar *bsdtar, int code, const char *fmt, va_list ap) -{ - fprintf(stderr, "%s: ", bsdtar->progname); - vfprintf(stderr, fmt, ap); - if (code != 0) - fprintf(stderr, ": %s", strerror(code)); - fprintf(stderr, "\n"); -} - -void -bsdtar_warnc(struct bsdtar *bsdtar, int code, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - bsdtar_vwarnc(bsdtar, code, fmt, ap); - va_end(ap); -} - -void -bsdtar_errc(struct bsdtar *bsdtar, int eval, int code, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - bsdtar_vwarnc(bsdtar, code, fmt, ap); - va_end(ap); - exit(eval); -} - -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(0xff & (int)*p)) - continue; - switch(*p) { - case 'y': case 'Y': - return (1); - case 'n': case 'N': - return (0); - default: - return (0); - } - } - - return (0); -} - -/* - * 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. - * If the "process" function returns non-zero for any line, this - * function will return non-zero after attempting to process all - * remaining lines. - */ -int -process_lines(struct bsdtar *bsdtar, const char *pathname, - int (*process)(struct bsdtar *, const char *)) -{ - FILE *f; - char *buff, *buff_end, *line_start, *line_end, *p; - size_t buff_length, new_buff_length, bytes_read, bytes_wanted; - int separator; - int ret; - - separator = bsdtar->option_null ? '\0' : '\n'; - ret = 0; - - if (strcmp(pathname, "-") == 0) - f = stdin; - else - f = fopen(pathname, "r"); - if (f == NULL) - bsdtar_errc(bsdtar, 1, errno, "Couldn't open %s", pathname); - buff_length = 8192; - buff = malloc(buff_length); - if (buff == NULL) - bsdtar_errc(bsdtar, 1, ENOMEM, "Can't read %s", pathname); - line_start = line_end = buff_end = buff; - for (;;) { - /* Get some more data into the buffer. */ - bytes_wanted = buff + buff_length - buff_end; - bytes_read = fread(buff_end, 1, bytes_wanted, f); - buff_end += bytes_read; - /* Process all complete lines in the buffer. */ - while (line_end < buff_end) { - if (*line_end == separator) { - *line_end = '\0'; - if ((*process)(bsdtar, line_start) != 0) - ret = -1; - line_start = line_end + 1; - line_end = line_start; - } else - line_end++; - } - if (feof(f)) - break; - if (ferror(f)) - bsdtar_errc(bsdtar, 1, errno, - "Can't read %s", pathname); - if (line_start > buff) { - /* Move a leftover fractional line to the beginning. */ - memmove(buff, line_start, buff_end - line_start); - buff_end -= line_start - buff; - line_end -= line_start - buff; - line_start = buff; - } else { - /* Line is too big; enlarge the buffer. */ - new_buff_length = buff_length * 2; - if (new_buff_length <= buff_length) - bsdtar_errc(bsdtar, 1, ENOMEM, - "Line too long in %s", pathname); - buff_length = new_buff_length; - p = realloc(buff, buff_length); - if (p == NULL) - bsdtar_errc(bsdtar, 1, ENOMEM, - "Line too long in %s", pathname); - buff_end = p + (buff_end - buff); - line_end = p + (line_end - buff); - line_start = buff = p; - } - } - /* At end-of-file, handle the final line. */ - if (line_end > line_start) { - *line_end = '\0'; - if ((*process)(bsdtar, line_start) != 0) - ret = -1; - } - free(buff); - if (f != stdin) - fclose(f); - return (ret); -} - -/*- - * 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. - */ -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) - bsdtar_errc(bsdtar, 1, errno, "No memory"); -} - -void -do_chdir(struct bsdtar *bsdtar) -{ - if (bsdtar->pending_chdir == NULL) - return; - - if (chdir(bsdtar->pending_chdir) != 0) { - bsdtar_errc(bsdtar, 1, 0, "could not chdir to '%s'\n", - bsdtar->pending_chdir); - } - free(bsdtar->pending_chdir); - bsdtar->pending_chdir = NULL; -} - -/* - * 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; -#endif - int r; - -#if HAVE_REGEX_H - r = apply_substitution(bsdtar, name, &subst_name, 0); - if (r == -1) { - bsdtar_warnc(bsdtar, 0, "Invalid substituion, 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) { - bsdtar_warnc(bsdtar, 0, "Invalid substituion, 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) { - bsdtar_warnc(bsdtar, 0, "Invalid substituion, 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 ((r = bsdtar->strip_components) > 0) { - const char *p = name; - - while (r > 0) { - switch (*p++) { - case '/': - r--; - name = p; - break; - case '\0': - /* Path is too short, skip it. */ - return (1); - } - } - while (*name == '/') - ++name; - if (*name == '\0') - return (1); - } - - /* Strip redundant leading '/' characters. */ - while (name[0] == '/' && name[1] == '/') - name++; - - /* Strip leading '/' unless user has asked us not to. */ - if (name[0] == '/' && !bsdtar->option_absolute_paths) { - /* Generate a warning the first time this happens. */ - if (!bsdtar->warned_lead_slash) { - bsdtar_warnc(bsdtar, 0, - "Removing leading '/' from member names"); - bsdtar->warned_lead_slash = 1; - } - name++; - /* Special case: Stripping leading '/' from "/" yields ".". */ - if (*name == '\0') - 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); -} - -/* - * 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. - */ - -int -pathcmp(const char *a, const char *b) -{ - /* Skip leading './' */ - if (a[0] == '.' && a[1] == '/' && a[2] != '\0') - a += 2; - if (b[0] == '.' && b[1] == '/' && b[2] != '\0') - b += 2; - /* Find the first difference, or return (0) if none. */ - while (*a == *b) { - if (*a == '\0') - return (0); - a++; - b++; - } - /* - * If one ends in '/' and the other one doesn't, - * they're the same. - */ - if (a[0] == '/' && a[1] == '\0' && b[0] == '\0') - return (0); - if (a[0] == '\0' && b[0] == '/' && b[1] == '\0') - return (0); - /* They're really different, return the correct sign. */ - return (*(const unsigned char *)a - *(const unsigned char *)b); -} diff --git a/libarchive/libarchive-2.5.5/tar/write.c b/libarchive/libarchive-2.5.5/tar/write.c deleted file mode 100644 index 1a6e928..0000000 --- a/libarchive/libarchive-2.5.5/tar/write.c +++ /dev/null @@ -1,1438 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.70 2008/05/26 17:10:10 kientzle Exp $"); - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_ACL_H -#include <sys/acl.h> -#endif -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_ATTR_XATTR_H -#include <attr/xattr.h> -#endif -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_EXT2FS_EXT2_FS_H -#include <ext2fs/ext2_fs.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_FNMATCH_H -#include <fnmatch.h> -#endif -#ifdef HAVE_GRP_H -#include <grp.h> -#endif -#ifdef HAVE_LIMITS_H -#include <limits.h> -#endif -#ifdef HAVE_LINUX_FS_H -#include <linux/fs.h> /* for Linux file flags */ -#endif -#ifdef HAVE_PWD_H -#include <pwd.h> -#endif -#include <stdio.h> -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "bsdtar.h" -#include "tree.h" - -/* Fixed size of uname/gname caches. */ -#define name_cache_size 101 - -static const char * const NO_NAME = "(noname)"; - -struct archive_dir_entry { - struct archive_dir_entry *next; - time_t mtime_sec; - int mtime_nsec; - char *name; -}; - -struct archive_dir { - struct archive_dir_entry *head, *tail; -}; - -struct name_cache { - int probes; - int hits; - size_t size; - struct { - id_t id; - const char *name; - } cache[name_cache_size]; -}; - -static void add_dir_list(struct bsdtar *bsdtar, const char *path, - time_t mtime_sec, int mtime_nsec); -static int append_archive(struct bsdtar *, struct archive *, - struct archive *ina); -static int append_archive_filename(struct bsdtar *, - struct archive *, const char *fname); -static void archive_names_from_file(struct bsdtar *bsdtar, - struct archive *a); -static int archive_names_from_file_helper(struct bsdtar *bsdtar, - const char *line); -static int copy_file_data(struct bsdtar *bsdtar, - struct archive *a, struct archive *ina); -static void create_cleanup(struct bsdtar *); -static void free_cache(struct name_cache *cache); -static const char * lookup_gname(struct bsdtar *bsdtar, gid_t gid); -static int lookup_gname_helper(struct bsdtar *bsdtar, - const char **name, id_t gid); -static const char * lookup_uname(struct bsdtar *bsdtar, uid_t uid); -static int lookup_uname_helper(struct bsdtar *bsdtar, - const char **name, id_t uid); -static int new_enough(struct bsdtar *, const char *path, - const struct stat *); -static void setup_acls(struct bsdtar *, struct archive_entry *, - const char *path); -static void setup_xattrs(struct bsdtar *, struct archive_entry *, - const char *path); -static void test_for_append(struct bsdtar *); -static void write_archive(struct archive *, struct bsdtar *); -static void write_entry(struct bsdtar *, struct archive *, - const struct stat *, const char *pathname, - const char *accpath); -static void write_entry_backend(struct bsdtar *, struct archive *, - struct archive_entry *, int); -static int write_file_data(struct bsdtar *, struct archive *, - int fd); -static void write_hierarchy(struct bsdtar *, struct archive *, - const char *); - -void -tar_mode_c(struct bsdtar *bsdtar) -{ - struct archive *a; - int r; - - if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) - bsdtar_errc(bsdtar, 1, 0, "no files or directories specified"); - - /* We want to catch SIGINFO and SIGUSR1. */ - siginfo_init(bsdtar); - - a = archive_write_new(); - - /* Support any format that the library supports. */ - if (bsdtar->create_format == NULL) { - r = archive_write_set_format_pax_restricted(a); - bsdtar->create_format = "pax restricted"; - } else { - r = archive_write_set_format_by_name(a, bsdtar->create_format); - } - if (r != ARCHIVE_OK) { - fprintf(stderr, "Can't use format %s: %s\n", - bsdtar->create_format, - archive_error_string(a)); - usage(bsdtar); - } - - /* - * If user explicitly set the block size, then assume they - * want the last block padded as well. Otherwise, use the - * default block size and accept archive_write_open_file()'s - * default padding decisions. - */ - if (bsdtar->bytes_per_block != 0) { - archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); - archive_write_set_bytes_in_last_block(a, - bsdtar->bytes_per_block); - } else - archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK); - - if (bsdtar->compress_program) { - archive_write_set_compression_program(a, bsdtar->compress_program); - } else { - switch (bsdtar->create_compression) { - case 0: - archive_write_set_compression_none(a); - break; -#ifdef HAVE_LIBBZ2 - case 'j': case 'y': - archive_write_set_compression_bzip2(a); - break; -#endif -#ifdef HAVE_LIBZ - case 'z': - archive_write_set_compression_gzip(a); - break; -#endif - case 'Z': - archive_write_set_compression_compress(a); - break; - default: - bsdtar_errc(bsdtar, 1, 0, - "Unrecognized compression option -%c", - bsdtar->create_compression); - } - } - - r = archive_write_open_file(a, bsdtar->filename); - if (r != ARCHIVE_OK) - bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); - - write_archive(a, bsdtar); - - if (bsdtar->option_totals) { - fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", - (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); - } - - archive_write_finish(a); - - /* Restore old SIGINFO + SIGUSR1 handlers. */ - siginfo_done(bsdtar); -} - -/* - * Same as 'c', except we only support tar or empty formats in - * uncompressed files on disk. - */ -void -tar_mode_r(struct bsdtar *bsdtar) -{ - off_t end_offset; - int format; - struct archive *a; - struct archive_entry *entry; - int r; - - /* Sanity-test some arguments and the file. */ - test_for_append(bsdtar); - - /* We want to catch SIGINFO and SIGUSR1. */ - siginfo_init(bsdtar); - - format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; - - bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT, 0666); - if (bsdtar->fd < 0) - bsdtar_errc(bsdtar, 1, errno, - "Cannot open %s", bsdtar->filename); - - a = archive_read_new(); - archive_read_support_compression_all(a); - archive_read_support_format_tar(a); - archive_read_support_format_gnutar(a); - r = archive_read_open_fd(a, bsdtar->fd, 10240); - if (r != ARCHIVE_OK) - bsdtar_errc(bsdtar, 1, archive_errno(a), - "Can't read archive %s: %s", bsdtar->filename, - archive_error_string(a)); - while (0 == archive_read_next_header(a, &entry)) { - if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { - archive_read_finish(a); - close(bsdtar->fd); - bsdtar_errc(bsdtar, 1, 0, - "Cannot append to compressed archive."); - } - /* Keep going until we hit end-of-archive */ - format = archive_format(a); - } - - end_offset = archive_read_header_position(a); - archive_read_finish(a); - - /* Re-open archive for writing */ - a = archive_write_new(); - archive_write_set_compression_none(a); - /* - * Set the format to be used for writing. To allow people to - * extend empty files, we need to allow them to specify the format, - * which opens the possibility that they will specify a format that - * doesn't match the existing format. Hence, the following bit - * of arcane ugliness. - */ - - if (bsdtar->create_format != NULL) { - /* If the user requested a format, use that, but ... */ - archive_write_set_format_by_name(a, - bsdtar->create_format); - /* ... complain if it's not compatible. */ - format &= ARCHIVE_FORMAT_BASE_MASK; - if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK) - && format != ARCHIVE_FORMAT_EMPTY) { - bsdtar_errc(bsdtar, 1, 0, - "Format %s is incompatible with the archive %s.", - bsdtar->create_format, bsdtar->filename); - } - } else { - /* - * Just preserve the current format, with a little care - * for formats that libarchive can't write. - */ - if (format == ARCHIVE_FORMAT_TAR_GNUTAR) - /* TODO: When gtar supports pax, use pax restricted. */ - format = ARCHIVE_FORMAT_TAR_USTAR; - if (format == ARCHIVE_FORMAT_EMPTY) - format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; - archive_write_set_format(a, format); - } - lseek(bsdtar->fd, end_offset, SEEK_SET); /* XXX check return val XXX */ - archive_write_open_fd(a, bsdtar->fd); /* XXX check return val XXX */ - - write_archive(a, bsdtar); /* XXX check return val XXX */ - - if (bsdtar->option_totals) { - fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", - (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); - } - - archive_write_finish(a); - close(bsdtar->fd); - bsdtar->fd = -1; -} - -void -tar_mode_u(struct bsdtar *bsdtar) -{ - off_t end_offset; - struct archive *a; - struct archive_entry *entry; - int format; - struct archive_dir_entry *p; - struct archive_dir archive_dir; - - bsdtar->archive_dir = &archive_dir; - memset(&archive_dir, 0, sizeof(archive_dir)); - - format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; - - /* Sanity-test some arguments and the file. */ - test_for_append(bsdtar); - - /* We want to catch SIGINFO and SIGUSR1. */ - siginfo_init(bsdtar); - - bsdtar->fd = open(bsdtar->filename, O_RDWR); - if (bsdtar->fd < 0) - bsdtar_errc(bsdtar, 1, errno, - "Cannot open %s", bsdtar->filename); - - a = archive_read_new(); - archive_read_support_compression_all(a); - archive_read_support_format_tar(a); - archive_read_support_format_gnutar(a); - if (archive_read_open_fd(a, bsdtar->fd, - bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block : - DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { - bsdtar_errc(bsdtar, 1, 0, - "Can't open %s: %s", bsdtar->filename, - archive_error_string(a)); - } - - /* Build a list of all entries and their recorded mod times. */ - while (0 == archive_read_next_header(a, &entry)) { - if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { - archive_read_finish(a); - close(bsdtar->fd); - bsdtar_errc(bsdtar, 1, 0, - "Cannot append to compressed archive."); - } - add_dir_list(bsdtar, archive_entry_pathname(entry), - archive_entry_mtime(entry), - archive_entry_mtime_nsec(entry)); - /* Record the last format determination we see */ - format = archive_format(a); - /* Keep going until we hit end-of-archive */ - } - - end_offset = archive_read_header_position(a); - archive_read_finish(a); - - /* Re-open archive for writing. */ - a = archive_write_new(); - archive_write_set_compression_none(a); - /* - * Set format to same one auto-detected above, except that - * we don't write GNU tar format, so use ustar instead. - */ - if (format == ARCHIVE_FORMAT_TAR_GNUTAR) - format = ARCHIVE_FORMAT_TAR_USTAR; - archive_write_set_format(a, format); - if (bsdtar->bytes_per_block != 0) { - archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); - archive_write_set_bytes_in_last_block(a, - bsdtar->bytes_per_block); - } else - archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK); - lseek(bsdtar->fd, end_offset, SEEK_SET); - ftruncate(bsdtar->fd, end_offset); - archive_write_open_fd(a, bsdtar->fd); - - write_archive(a, bsdtar); - - if (bsdtar->option_totals) { - fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", - (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); - } - - archive_write_finish(a); - close(bsdtar->fd); - bsdtar->fd = -1; - - while (bsdtar->archive_dir->head != NULL) { - p = bsdtar->archive_dir->head->next; - free(bsdtar->archive_dir->head->name); - free(bsdtar->archive_dir->head); - bsdtar->archive_dir->head = p; - } - bsdtar->archive_dir->tail = NULL; -} - - -/* - * Write user-specified files/dirs to opened archive. - */ -static void -write_archive(struct archive *a, struct bsdtar *bsdtar) -{ - const char *arg; - struct archive_entry *entry, *sparse_entry; - - if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) - bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver"); - archive_entry_linkresolver_set_strategy(bsdtar->resolver, - archive_format(a)); - - if (bsdtar->names_from_file != NULL) - archive_names_from_file(bsdtar, a); - - while (*bsdtar->argv) { - arg = *bsdtar->argv; - if (arg[0] == '-' && arg[1] == 'C') { - arg += 2; - if (*arg == '\0') { - bsdtar->argv++; - arg = *bsdtar->argv; - if (arg == NULL) { - bsdtar_warnc(bsdtar, 1, 0, - "Missing argument for -C"); - bsdtar->return_value = 1; - return; - } - } - set_chdir(bsdtar, arg); - } else { - if (*arg != '/' && (arg[0] != '@' || arg[1] != '/')) - do_chdir(bsdtar); /* Handle a deferred -C */ - if (*arg == '@') { - if (append_archive_filename(bsdtar, a, - arg + 1) != 0) - break; - } else - write_hierarchy(bsdtar, a, arg); - } - bsdtar->argv++; - } - - entry = NULL; - archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); - while (entry != NULL) { - int fd = -1; - write_entry_backend(bsdtar, a, entry, fd); - archive_entry_free(entry); - entry = NULL; - archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); - } - - create_cleanup(bsdtar); - if (archive_write_close(a)) { - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); - bsdtar->return_value = 1; - } -} - -/* - * Archive names specified in file. - * - * Unless --null was specified, a line containing exactly "-C" will - * cause the next line to be a directory to pass to chdir(). If - * --null is specified, then a line "-C" is just another filename. - */ -void -archive_names_from_file(struct bsdtar *bsdtar, struct archive *a) -{ - bsdtar->archive = a; - - bsdtar->next_line_is_dir = 0; - process_lines(bsdtar, bsdtar->names_from_file, - archive_names_from_file_helper); - if (bsdtar->next_line_is_dir) - bsdtar_errc(bsdtar, 1, errno, - "Unexpected end of filename list; " - "directory expected after -C"); -} - -static int -archive_names_from_file_helper(struct bsdtar *bsdtar, const char *line) -{ - if (bsdtar->next_line_is_dir) { - set_chdir(bsdtar, line); - bsdtar->next_line_is_dir = 0; - } else if (!bsdtar->option_null && strcmp(line, "-C") == 0) - bsdtar->next_line_is_dir = 1; - else { - if (*line != '/') - do_chdir(bsdtar); /* Handle a deferred -C */ - write_hierarchy(bsdtar, bsdtar->archive, line); - } - return (0); -} - -/* - * Copy from specified archive to current archive. Returns non-zero - * for write errors (which force us to terminate the entire archiving - * operation). If there are errors reading the input archive, we set - * bsdtar->return_value but return zero, so the overall archiving - * operation will complete and return non-zero. - */ -static int -append_archive_filename(struct bsdtar *bsdtar, struct archive *a, - const char *filename) -{ - struct archive *ina; - int rc; - - if (strcmp(filename, "-") == 0) - filename = NULL; /* Library uses NULL for stdio. */ - - ina = archive_read_new(); - archive_read_support_format_all(ina); - archive_read_support_compression_all(ina); - if (archive_read_open_file(ina, filename, 10240)) { - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(ina)); - bsdtar->return_value = 1; - return (0); - } - - rc = append_archive(bsdtar, a, ina); - - if (archive_errno(ina)) { - bsdtar_warnc(bsdtar, 0, "Error reading archive %s: %s", - filename, archive_error_string(ina)); - bsdtar->return_value = 1; - } - archive_read_finish(ina); - - return (rc); -} - -static int -append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) -{ - struct archive_entry *in_entry; - int e; - - while (0 == archive_read_next_header(ina, &in_entry)) { - if (!new_enough(bsdtar, archive_entry_pathname(in_entry), - archive_entry_stat(in_entry))) - continue; - if (excluded(bsdtar, archive_entry_pathname(in_entry))) - continue; - if (bsdtar->option_interactive && - !yes("copy '%s'", archive_entry_pathname(in_entry))) - continue; - if (bsdtar->verbose) - safe_fprintf(stderr, "a %s", - archive_entry_pathname(in_entry)); - siginfo_setinfo(bsdtar, "copying", - archive_entry_pathname(in_entry), - archive_entry_size(in_entry)); - siginfo_printinfo(bsdtar, 0); - - e = archive_write_header(a, in_entry); - if (e != ARCHIVE_OK) { - if (!bsdtar->verbose) - bsdtar_warnc(bsdtar, 0, "%s: %s", - archive_entry_pathname(in_entry), - archive_error_string(a)); - else - fprintf(stderr, ": %s", archive_error_string(a)); - } - if (e == ARCHIVE_FATAL) - exit(1); - - if (e >= ARCHIVE_WARN) { - if (archive_entry_size(in_entry) == 0) - archive_read_data_skip(ina); - else if (copy_file_data(bsdtar, a, ina)) - exit(1); - } - - if (bsdtar->verbose) - fprintf(stderr, "\n"); - } - - /* Note: If we got here, we saw no write errors, so return success. */ - return (0); -} - -/* Helper function to copy data between archives. */ -static int -copy_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) -{ - char buff[64*1024]; - ssize_t bytes_read; - ssize_t bytes_written; - off_t progress = 0; - - bytes_read = archive_read_data(ina, buff, sizeof(buff)); - while (bytes_read > 0) { - siginfo_printinfo(bsdtar, progress); - - bytes_written = archive_write_data(a, buff, bytes_read); - if (bytes_written < bytes_read) { - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); - return (-1); - } - progress += bytes_written; - bytes_read = archive_read_data(ina, buff, sizeof(buff)); - } - - return (0); -} - -/* - * Add the file or dir hierarchy named by 'path' to the archive - */ -static void -write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) -{ - struct tree *tree; - char symlink_mode = bsdtar->symlink_mode; - dev_t first_dev = 0; - int dev_recorded = 0; - int tree_ret; -#ifdef __linux - int fd, r; - unsigned long fflags; -#endif - - tree = tree_open(path); - - if (!tree) { - bsdtar_warnc(bsdtar, errno, "%s: Cannot open", path); - bsdtar->return_value = 1; - return; - } - - while ((tree_ret = tree_next(tree))) { - const char *name = tree_current_path(tree); - const struct stat *st = NULL, *lst = NULL; - int descend; - - if (tree_ret == TREE_ERROR_DIR) - bsdtar_warnc(bsdtar, errno, "%s: Couldn't visit directory", name); - if (tree_ret != TREE_REGULAR) - continue; - lst = tree_current_lstat(tree); - if (lst == NULL) { - /* Couldn't lstat(); must not exist. */ - bsdtar_warnc(bsdtar, errno, "%s: Cannot stat", name); - - /* - * Report an error via the exit code if the failed - * path is a prefix of what the user provided via - * the command line. (Testing for string equality - * here won't work due to trailing '/' characters.) - */ - if (memcmp(name, path, strlen(name)) == 0) - bsdtar->return_value = 1; - - continue; - } - if (S_ISLNK(lst->st_mode)) - st = tree_current_stat(tree); - /* Default: descend into any dir or symlink to dir. */ - /* We'll adjust this later on. */ - descend = 0; - if ((st != NULL) && S_ISDIR(st->st_mode)) - descend = 1; - if ((lst != NULL) && S_ISDIR(lst->st_mode)) - descend = 1; - - /* - * If user has asked us not to cross mount points, - * then don't descend into into a dir on a different - * device. - */ - if (!dev_recorded) { - first_dev = lst->st_dev; - dev_recorded = 1; - } - if (bsdtar->option_dont_traverse_mounts) { - if (lst != NULL && lst->st_dev != first_dev) - descend = 0; - } - - /* - * If this file/dir is flagged "nodump" and we're - * honoring such flags, skip this file/dir. - */ -#ifdef HAVE_CHFLAGS - if (bsdtar->option_honor_nodump && - (lst->st_flags & UF_NODUMP)) - continue; -#endif - -#ifdef __linux - /* - * Linux has a nodump flag too but to read it - * we have to open() the file/dir and do an ioctl on it... - */ - if (bsdtar->option_honor_nodump && - ((fd = open(name, O_RDONLY|O_NONBLOCK)) >= 0) && - ((r = ioctl(fd, EXT2_IOC_GETFLAGS, &fflags)), - close(fd), r) >= 0 && - (fflags & EXT2_NODUMP_FL)) - continue; -#endif - - /* - * If this file/dir is excluded by a filename - * pattern, skip it. - */ - if (excluded(bsdtar, name)) - continue; - - /* - * If the user vetoes this file/directory, skip it. - */ - if (bsdtar->option_interactive && - !yes("add '%s'", name)) - continue; - - /* - * If this is a dir, decide whether or not to recurse. - */ - if (bsdtar->option_no_subdirs) - descend = 0; - - /* - * Distinguish 'L'/'P'/'H' symlink following. - */ - switch(symlink_mode) { - case 'H': - /* 'H': After the first item, rest like 'P'. */ - symlink_mode = 'P'; - /* 'H': First item (from command line) like 'L'. */ - /* FALLTHROUGH */ - case 'L': - /* 'L': Do descend through a symlink to dir. */ - /* 'L': Archive symlink to file as file. */ - lst = tree_current_stat(tree); - /* If stat fails, we have a broken symlink; - * in that case, archive the link as such. */ - if (lst == NULL) - lst = tree_current_lstat(tree); - break; - default: - /* 'P': Don't descend through a symlink to dir. */ - if (!S_ISDIR(lst->st_mode)) - descend = 0; - /* 'P': Archive symlink to file as symlink. */ - /* lst = tree_current_lstat(tree); */ - break; - } - - if (descend) - tree_descend(tree); - - /* - * Write the entry. Note that write_entry() handles - * pathname editing and newness testing. - */ - write_entry(bsdtar, a, lst, name, - tree_current_access_path(tree)); - } - tree_close(tree); -} - -/* - * Backend for write_entry. - */ -static void -write_entry_backend(struct bsdtar *bsdtar, struct archive *a, - struct archive_entry *entry, int fd) -{ - int e; - - if (fd == -1 && archive_entry_size(entry) > 0) { - const char *pathname = archive_entry_sourcepath(entry); - fd = open(pathname, O_RDONLY); - if (fd == -1) { - if (!bsdtar->verbose) - bsdtar_warnc(bsdtar, errno, - "%s: could not open file", pathname); - else - fprintf(stderr, ": %s", strerror(errno)); - return; - } - } - - e = archive_write_header(a, entry); - if (e != ARCHIVE_OK) { - if (!bsdtar->verbose) - bsdtar_warnc(bsdtar, 0, "%s: %s", - archive_entry_pathname(entry), - archive_error_string(a)); - else - fprintf(stderr, ": %s", archive_error_string(a)); - } - - if (e == ARCHIVE_FATAL) - exit(1); - - /* - * If we opened a file earlier, write it out now. Note that - * the format handler might have reset the size field to zero - * to inform us that the archive body won't get stored. In - * that case, just skip the write. - */ - if (e >= ARCHIVE_WARN && fd >= 0 && archive_entry_size(entry) > 0) { - if (write_file_data(bsdtar, a, fd)) - exit(1); - close(fd); - } -} - -/* - * Add a single filesystem object to the archive. - */ -static void -write_entry(struct bsdtar *bsdtar, struct archive *a, const struct stat *st, - const char *pathname, const char *accpath) -{ - struct archive_entry *entry, *sparse_entry; - int fd; -#ifdef __linux - int r; - unsigned long stflags; -#endif - static char linkbuffer[PATH_MAX+1]; - - fd = -1; - entry = archive_entry_new(); - - archive_entry_set_pathname(entry, pathname); - archive_entry_copy_sourcepath(entry, accpath); - - /* - * Rewrite the pathname to be archived. If rewrite - * fails, skip the entry. - */ - if (edit_pathname(bsdtar, entry)) - goto abort; - - /* - * In -u mode, check that the file is newer than what's - * already in the archive; in all modes, obey --newerXXX flags. - */ - if (!new_enough(bsdtar, archive_entry_pathname(entry), st)) - goto abort; - - /* Display entry as we process it. This format is required by SUSv2. */ - if (bsdtar->verbose) - safe_fprintf(stderr, "a %s", archive_entry_pathname(entry)); - - /* Read symbolic link information. */ - if ((st->st_mode & S_IFMT) == S_IFLNK) { - int lnklen; - - lnklen = readlink(accpath, linkbuffer, PATH_MAX); - if (lnklen < 0) { - if (!bsdtar->verbose) - bsdtar_warnc(bsdtar, errno, - "%s: Couldn't read symbolic link", - pathname); - else - safe_fprintf(stderr, - ": Couldn't read symbolic link: %s", - strerror(errno)); - goto cleanup; - } - linkbuffer[lnklen] = 0; - archive_entry_set_symlink(entry, linkbuffer); - } - - /* Look up username and group name. */ - archive_entry_set_uname(entry, lookup_uname(bsdtar, st->st_uid)); - archive_entry_set_gname(entry, lookup_gname(bsdtar, st->st_gid)); - -#ifdef HAVE_CHFLAGS - if (st->st_flags != 0) - archive_entry_set_fflags(entry, st->st_flags, 0); -#endif - -#ifdef __linux - if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) && - ((fd = open(accpath, O_RDONLY|O_NONBLOCK)) >= 0) && - ((r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags)), close(fd), (fd = -1), r) >= 0 && - stflags) { - archive_entry_set_fflags(entry, stflags, 0); - } -#endif - - archive_entry_copy_stat(entry, st); - setup_acls(bsdtar, entry, accpath); - setup_xattrs(bsdtar, entry, accpath); - - /* Non-regular files get archived with zero size. */ - if (!S_ISREG(st->st_mode)) - archive_entry_set_size(entry, 0); - - /* Record what we're doing, for the benefit of SIGINFO / SIGUSR1. */ - siginfo_setinfo(bsdtar, "adding", archive_entry_pathname(entry), - archive_entry_size(entry)); - archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); - - /* Handle SIGINFO / SIGUSR1 request if one was made. */ - siginfo_printinfo(bsdtar, 0); - - while (entry != NULL) { - write_entry_backend(bsdtar, a, entry, fd); - fd = -1; - archive_entry_free(entry); - entry = sparse_entry; - sparse_entry = NULL; - } - -cleanup: - if (bsdtar->verbose) - fprintf(stderr, "\n"); - -abort: - if (fd >= 0) - close(fd); - - archive_entry_free(entry); -} - - -/* Helper function to copy file to archive, with stack-allocated buffer. */ -static int -write_file_data(struct bsdtar *bsdtar, struct archive *a, int fd) -{ - char buff[64*1024]; - ssize_t bytes_read; - ssize_t bytes_written; - off_t progress = 0; - - /* XXX TODO: Allocate buffer on heap and store pointer to - * it in bsdtar structure; arrange cleanup as well. XXX */ - - bytes_read = read(fd, buff, sizeof(buff)); - while (bytes_read > 0) { - siginfo_printinfo(bsdtar, progress); - - bytes_written = archive_write_data(a, buff, bytes_read); - if (bytes_written < 0) { - /* Write failed; this is bad */ - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); - return (-1); - } - if (bytes_written < bytes_read) { - /* Write was truncated; warn but continue. */ - bsdtar_warnc(bsdtar, 0, - "Truncated write; file may have grown while being archived."); - return (0); - } - progress += bytes_written; - bytes_read = read(fd, buff, sizeof(buff)); - } - return 0; -} - - -static void -create_cleanup(struct bsdtar *bsdtar) -{ - free_cache(bsdtar->uname_cache); - bsdtar->uname_cache = NULL; - free_cache(bsdtar->gname_cache); - bsdtar->gname_cache = NULL; -} - -#ifdef HAVE_POSIX_ACL -static void setup_acl(struct bsdtar *bsdtar, - struct archive_entry *entry, const char *accpath, - int acl_type, int archive_entry_acl_type); - -static void -setup_acls(struct bsdtar *bsdtar, struct archive_entry *entry, - const char *accpath) -{ - archive_entry_acl_clear(entry); - - setup_acl(bsdtar, entry, accpath, - ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - /* Only directories can have default ACLs. */ - if (S_ISDIR(archive_entry_mode(entry))) - setup_acl(bsdtar, entry, accpath, - ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); -} - -static void -setup_acl(struct bsdtar *bsdtar, struct archive_entry *entry, - const char *accpath, int acl_type, int archive_entry_acl_type) -{ - acl_t acl; - acl_tag_t acl_tag; - acl_entry_t acl_entry; - acl_permset_t acl_permset; - int s, ae_id, ae_tag, ae_perm; - const char *ae_name; - - /* Retrieve access ACL from file. */ - acl = acl_get_file(accpath, acl_type); - if (acl != NULL) { - s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); - while (s == 1) { - ae_id = -1; - ae_name = NULL; - - acl_get_tag_type(acl_entry, &acl_tag); - if (acl_tag == ACL_USER) { - ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry); - ae_name = lookup_uname(bsdtar, ae_id); - ae_tag = ARCHIVE_ENTRY_ACL_USER; - } else if (acl_tag == ACL_GROUP) { - ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry); - ae_name = lookup_gname(bsdtar, ae_id); - ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - } else if (acl_tag == ACL_MASK) { - ae_tag = ARCHIVE_ENTRY_ACL_MASK; - } else if (acl_tag == ACL_USER_OBJ) { - ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - } else if (acl_tag == ACL_GROUP_OBJ) { - ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - } else if (acl_tag == ACL_OTHER) { - ae_tag = ARCHIVE_ENTRY_ACL_OTHER; - } else { - /* Skip types that libarchive can't support. */ - continue; - } - - acl_get_permset(acl_entry, &acl_permset); - ae_perm = 0; - /* - * acl_get_perm() is spelled differently on different - * platforms; see bsdtar_platform.h for details. - */ - if (ACL_GET_PERM(acl_permset, ACL_EXECUTE)) - ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE; - if (ACL_GET_PERM(acl_permset, ACL_READ)) - ae_perm |= ARCHIVE_ENTRY_ACL_READ; - if (ACL_GET_PERM(acl_permset, ACL_WRITE)) - ae_perm |= ARCHIVE_ENTRY_ACL_WRITE; - - archive_entry_acl_add_entry(entry, - archive_entry_acl_type, ae_perm, ae_tag, - ae_id, ae_name); - - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - } - acl_free(acl); - } -} -#else -static void -setup_acls(struct bsdtar *bsdtar, struct archive_entry *entry, - const char *accpath) -{ - (void)bsdtar; - (void)entry; - (void)accpath; -} -#endif - -#if HAVE_LISTXATTR && HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR - -static void -setup_xattr(struct bsdtar *bsdtar, struct archive_entry *entry, - const char *accpath, const char *name) -{ - size_t size; - void *value = NULL; - char symlink_mode = bsdtar->symlink_mode; - - if (symlink_mode == 'H') - size = getxattr(accpath, name, NULL, 0); - else - size = lgetxattr(accpath, name, NULL, 0); - - if (size == -1) { - bsdtar_warnc(bsdtar, errno, "Couldn't get extended attribute"); - return; - } - - if (size > 0 && (value = malloc(size)) == NULL) { - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); - return; - } - - if (symlink_mode == 'H') - size = getxattr(accpath, name, value, size); - else - size = lgetxattr(accpath, name, value, size); - - if (size == -1) { - bsdtar_warnc(bsdtar, errno, "Couldn't get extended attribute"); - return; - } - - archive_entry_xattr_add_entry(entry, name, value, size); - - free(value); -} - -/* - * Linux extended attribute support - */ -static void -setup_xattrs(struct bsdtar *bsdtar, struct archive_entry *entry, - const char *accpath) -{ - char *list, *p; - size_t list_size; - char symlink_mode = bsdtar->symlink_mode; - - if (symlink_mode == 'H') - list_size = listxattr(accpath, NULL, 0); - else - list_size = llistxattr(accpath, NULL, 0); - - if (list_size == -1) { - bsdtar_warnc(bsdtar, errno, - "Couldn't list extended attributes"); - return; - } else if (list_size == 0) - return; - - if ((list = malloc(list_size)) == NULL) { - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); - return; - } - - if (symlink_mode == 'H') - list_size = listxattr(accpath, list, list_size); - else - list_size = llistxattr(accpath, list, list_size); - - if (list_size == -1) { - bsdtar_warnc(bsdtar, errno, - "Couldn't list extended attributes"); - free(list); - return; - } - - for (p = list; (p - list) < list_size; p += strlen(p) + 1) { - if (strncmp(p, "system.", 7) == 0 || - strncmp(p, "xfsroot.", 8) == 0) - continue; - - setup_xattr(bsdtar, entry, accpath, p); - } - - free(list); -} - -#else - -/* - * Generic (stub) extended attribute support. - */ -static void -setup_xattrs(struct bsdtar *bsdtar, struct archive_entry *entry, - const char *accpath) -{ - (void)bsdtar; /* UNUSED */ - (void)entry; /* UNUSED */ - (void)accpath; /* UNUSED */ -} - -#endif - -static void -free_cache(struct name_cache *cache) -{ - size_t i; - - if (cache != NULL) { - for (i = 0; i < cache->size; i++) { - if (cache->cache[i].name != NULL && - cache->cache[i].name != NO_NAME) - free((void *)(uintptr_t)cache->cache[i].name); - } - free(cache); - } -} - -/* - * Lookup uid/gid from uname/gname, return NULL if no match. - */ -static const char * -lookup_name(struct bsdtar *bsdtar, struct name_cache **name_cache_variable, - int (*lookup_fn)(struct bsdtar *, const char **, id_t), id_t id) -{ - struct name_cache *cache; - const char *name; - int slot; - - - if (*name_cache_variable == NULL) { - *name_cache_variable = malloc(sizeof(struct name_cache)); - if (*name_cache_variable == NULL) - bsdtar_errc(bsdtar, 1, ENOMEM, "No more memory"); - memset(*name_cache_variable, 0, sizeof(struct name_cache)); - (*name_cache_variable)->size = name_cache_size; - } - - cache = *name_cache_variable; - cache->probes++; - - slot = id % cache->size; - if (cache->cache[slot].name != NULL) { - if (cache->cache[slot].id == id) { - cache->hits++; - if (cache->cache[slot].name == NO_NAME) - return (NULL); - return (cache->cache[slot].name); - } - if (cache->cache[slot].name != NO_NAME) - free((void *)(uintptr_t)cache->cache[slot].name); - cache->cache[slot].name = NULL; - } - - if (lookup_fn(bsdtar, &name, id) == 0) { - if (name == NULL || name[0] == '\0') { - /* Cache the negative response. */ - cache->cache[slot].name = NO_NAME; - cache->cache[slot].id = id; - } else { - cache->cache[slot].name = strdup(name); - if (cache->cache[slot].name != NULL) { - cache->cache[slot].id = id; - return (cache->cache[slot].name); - } - /* - * Conveniently, NULL marks an empty slot, so - * if the strdup() fails, we've just failed to - * cache it. No recovery necessary. - */ - } - } - return (NULL); -} - -static const char * -lookup_uname(struct bsdtar *bsdtar, uid_t uid) -{ - return (lookup_name(bsdtar, &bsdtar->uname_cache, - &lookup_uname_helper, (id_t)uid)); -} - -static int -lookup_uname_helper(struct bsdtar *bsdtar, const char **name, id_t id) -{ - struct passwd *pwent; - - (void)bsdtar; /* UNUSED */ - - errno = 0; - pwent = getpwuid((uid_t)id); - if (pwent == NULL) { - *name = NULL; - if (errno != 0) - bsdtar_warnc(bsdtar, errno, "getpwuid(%d) failed", id); - return (errno); - } - - *name = pwent->pw_name; - return (0); -} - -static const char * -lookup_gname(struct bsdtar *bsdtar, gid_t gid) -{ - return (lookup_name(bsdtar, &bsdtar->gname_cache, - &lookup_gname_helper, (id_t)gid)); -} - -static int -lookup_gname_helper(struct bsdtar *bsdtar, const char **name, id_t id) -{ - struct group *grent; - - (void)bsdtar; /* UNUSED */ - - errno = 0; - grent = getgrgid((gid_t)id); - if (grent == NULL) { - *name = NULL; - if (errno != 0) - bsdtar_warnc(bsdtar, errno, "getgrgid(%d) failed", id); - return (errno); - } - - *name = grent->gr_name; - return (0); -} - -/* - * Test if the specified file is new enough to include in the archive. - */ -int -new_enough(struct bsdtar *bsdtar, const char *path, const struct stat *st) -{ - struct archive_dir_entry *p; - - /* - * If this file/dir is excluded by a time comparison, skip it. - */ - if (bsdtar->newer_ctime_sec > 0) { - if (st->st_ctime < bsdtar->newer_ctime_sec) - return (0); /* Too old, skip it. */ - if (st->st_ctime == bsdtar->newer_ctime_sec - && ARCHIVE_STAT_CTIME_NANOS(st) - <= bsdtar->newer_ctime_nsec) - return (0); /* Too old, skip it. */ - } - if (bsdtar->newer_mtime_sec > 0) { - if (st->st_mtime < bsdtar->newer_mtime_sec) - return (0); /* Too old, skip it. */ - if (st->st_mtime == bsdtar->newer_mtime_sec - && ARCHIVE_STAT_MTIME_NANOS(st) - <= bsdtar->newer_mtime_nsec) - return (0); /* Too old, skip it. */ - } - - /* - * In -u mode, we only write an entry if it's newer than - * what was already in the archive. - */ - if (bsdtar->archive_dir != NULL && - bsdtar->archive_dir->head != NULL) { - for (p = bsdtar->archive_dir->head; p != NULL; p = p->next) { - if (pathcmp(path, p->name)==0) - return (p->mtime_sec < st->st_mtime || - (p->mtime_sec == st->st_mtime && - p->mtime_nsec - < ARCHIVE_STAT_MTIME_NANOS(st))); - } - } - - /* If the file wasn't rejected, include it. */ - return (1); -} - -/* - * Add an entry to the dir list for 'u' mode. - * - * XXX TODO: Make this fast. - */ -static void -add_dir_list(struct bsdtar *bsdtar, const char *path, - time_t mtime_sec, int mtime_nsec) -{ - struct archive_dir_entry *p; - - /* - * Search entire list to see if this file has appeared before. - * If it has, override the timestamp data. - */ - p = bsdtar->archive_dir->head; - while (p != NULL) { - if (strcmp(path, p->name)==0) { - p->mtime_sec = mtime_sec; - p->mtime_nsec = mtime_nsec; - return; - } - p = p->next; - } - - p = malloc(sizeof(*p)); - if (p == NULL) - bsdtar_errc(bsdtar, 1, ENOMEM, "Can't read archive directory"); - - p->name = strdup(path); - if (p->name == NULL) - bsdtar_errc(bsdtar, 1, ENOMEM, "Can't read archive directory"); - p->mtime_sec = mtime_sec; - p->mtime_nsec = mtime_nsec; - p->next = NULL; - if (bsdtar->archive_dir->tail == NULL) { - bsdtar->archive_dir->head = bsdtar->archive_dir->tail = p; - } else { - bsdtar->archive_dir->tail->next = p; - bsdtar->archive_dir->tail = p; - } -} - -void -test_for_append(struct bsdtar *bsdtar) -{ - struct stat s; - - if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) - bsdtar_errc(bsdtar, 1, 0, "no files or directories specified"); - if (bsdtar->filename == NULL) - bsdtar_errc(bsdtar, 1, 0, "Cannot append to stdout."); - - if (bsdtar->create_compression != 0) - bsdtar_errc(bsdtar, 1, 0, - "Cannot append to %s with compression", bsdtar->filename); - - if (stat(bsdtar->filename, &s) != 0) - return; - - if (!S_ISREG(s.st_mode) && !S_ISBLK(s.st_mode)) - bsdtar_errc(bsdtar, 1, 0, - "Cannot append to %s: not a regular file.", - bsdtar->filename); -} |
