43 Commits

Author SHA1 Message Date
Sergey Poznyakoff
e5ef01710a Fix wording 2006-12-08 16:59:56 +00:00
Sergey Poznyakoff
e70e63612a Update 2006-12-08 16:45:34 +00:00
Sergey Poznyakoff
28b26242c7 Add paxutils files to dot_ignore. 2006-12-08 16:45:09 +00:00
Sergey Poznyakoff
6b279a6f8c Update 2006-12-08 13:40:15 +00:00
Sergey Poznyakoff
079f2d6807 Raise version number to 1.16.1 2006-12-08 13:40:07 +00:00
Sergey Poznyakoff
b09417ca8d (slurp): Create .(cvs|git)ignore if not present 2006-12-08 13:39:58 +00:00
Sergey Poznyakoff
b15e3f1bbd Remove autogenerated files 2006-12-08 12:42:32 +00:00
Sergey Poznyakoff
1616b1d1b4 Update 2006-12-07 14:35:13 +00:00
Sergey Poznyakoff
f23bc997fd Update 2006-12-07 14:34:48 +00:00
Sergey Poznyakoff
8ec119a27f Update 2006-12-07 14:34:28 +00:00
Sergey Poznyakoff
e35d05b1d2 Use genfile instead of dd, because on some systems /dev/zero is not available. 2006-12-07 14:34:15 +00:00
Sergey Poznyakoff
cdb77dcd7b (extract_file): Call skip_member if open fails.
Patch proposed by Jan-Benedict Glaw <jbglaw@lug-owl.de>
2006-12-07 14:33:54 +00:00
Sergey Poznyakoff
9bf87b195e (dump_dir0): Move checks for exclude tags to
dump_file0.
(dump_dir): Move calls to ensure_slash to dump_file0
2006-12-07 14:33:42 +00:00
Sergey Poznyakoff
643e3f2441 Update documentation of --exclude-tag 2006-12-07 14:33:30 +00:00
Sergey Poznyakoff
6e75833cb7 (distclean-local): Fixed 2006-12-07 14:33:17 +00:00
Paul Eggert
908d78d208 * NEWS: Fix some race conditions with tar -x --same-owner.
* src/extract.c (ARCHIVED_PERMSTATS): Add a comment saying that
S_IRWXG | S_IRWXO might be masked out.
(set_mode): Set the mode if some bits were masked out originally.
(set_stat): Don't chmod before chown, as that might temporarily
grant permissions that we don't want to grant.  The chmod was
there only to work around broken hosts, so add a comment advising
users not to use those broken hosts instead.
(repair_delayed_set_stat, extract_dir):
Remember to mask out current umask before inverting permissions.
(extract_dir): If the owner might change, or if the mode has
special bits, create the directory 700 at first, but restore it later.
(open_output_file): New arg mode; all uses changed.
(extract_file, extract_node, extract_fifo): If the owner might
change, omit group and other bits at first, but restore them after
changing the owner.
2006-12-04 21:35:56 +00:00
Paul Eggert
192f55e2a0 * doc/tar.texi (Long Options): Remove doubled word. 2006-12-04 09:33:31 +00:00
Sergey Poznyakoff
9d99fd13cd Update 2006-11-30 09:54:07 +00:00
Sergey Poznyakoff
07902e9f9a (xheader_read): Remove unused variable 2006-11-30 09:53:20 +00:00
Sergey Poznyakoff
0c94a109b9 Update 2006-11-30 09:42:59 +00:00
Sergey Poznyakoff
27094c4fc3 Implement --update-po and .bootstrap 2006-11-30 09:42:12 +00:00
Sergey Poznyakoff
5aca761e1b Remove src/mangle.c 2006-11-30 09:41:50 +00:00
Sergey Poznyakoff
cc82db7f2d (exclude): Document --exclude-tag 2006-11-30 09:41:42 +00:00
Sergey Poznyakoff
137ebf41fd (dump_dir0): Implement --exclude-tag option 2006-11-30 09:40:47 +00:00
Paul Eggert
49ea4c5057 * NEWS: Remove support for mangled names.
* doc/tar.texi (verbose tutorial): Likewise.
* src/Makefile.am (tar_SOURCES): Remove mangle.c.
* src/common.h (extract_mangle): Remove decl.
* src/extract.c (extract_mangle_wrapper): Remove.
(prepare_to_extract): Remove support for mangled names.
* src/list.c (read_and, print_header): Likewise.
* src/mangle.c: Remove.
* src/tar.h (GNUTYPE_NAMES): Remove.
2006-11-30 06:39:29 +00:00
Paul Eggert
409bddf38c * lib/.cvsignore: Add fstatat.c, gnulib.mk, openat-proc.c, same-inode.h, stat_.h,
tempname.c, tempname.h, uinttostr.c.
2006-11-30 06:27:24 +00:00
Paul Eggert
c930802f31 Port to latest gnulib. There were a lot of changes, so the
simplest way to get this up and running was to switch to coreutils
bootstrap procedure.  I noticed one feature missing after this
merge: the ability to update a single .po file.  I can add that
later if need be.
* README-cvs, bootstrap.conf: New files.
* lib/.cvsignore: Remove Makefile.am, printf-parse.c, vasnprintf.c.
* lib/printf-parse.c, lib/vasnprintf.c: New files, from coreutils,
to override gnulib, so that we don't need xsize.h.
* bootstrap: Replace with coreutils bootstrap, except add support
for paxutils.
* configure.ac (gl_USE_SYSTEM_EXTENSIONS): Remove, as gl_EARLY now
does this.
(gl_EARLY, gl_INIT): Add.
(tar_GNULIB): Remove.
* gnulib.modules: Add configmake.
* lib/Makefile.tmpl: Remove, replacing with....
* lib/Makefile.am: New file.
* src/Makefile.am (tar.o): Remove dependency: Automake does this
for us.
* src/tar.c: Include <configmake.h> and <rmt-command.h>, not
<localedir.h>.
2006-11-30 00:14:10 +00:00
Paul Eggert
ca14885884 Remove trailing white space. 2006-11-29 18:28:45 +00:00
Paul Eggert
01d6188297 Remove trailing white space. 2006-11-29 18:16:27 +00:00
Paul Eggert
759c5208c5 Remove trailing white space. 2006-11-29 18:11:34 +00:00
Sergey Poznyakoff
8457e06b99 Do not depend on command timing. 2006-11-13 10:42:19 +00:00
Sergey Poznyakoff
8719c4f680 Update 2006-11-13 10:41:47 +00:00
Sergey Poznyakoff
574022ab78 Do not use 'k' modifier in dd options. 2006-11-13 10:41:34 +00:00
Sergey Poznyakoff
304d8b9f0c (start_header): Pass mtime as a call-specific data to xheader_store. 2006-11-13 10:39:51 +00:00
Sergey Poznyakoff
6712656eb2 (mtime_coder): Treat non-null data as a pointer to struct timespec, overriding st->mtime 2006-11-13 10:39:15 +00:00
Sergey Poznyakoff
415d9c9e15 Update copyright year 2006-11-01 00:30:45 +00:00
Sergey Poznyakoff
1a8141ab8a Update 2006-11-01 00:24:44 +00:00
Sergey Poznyakoff
023c766600 Do not assume tar's default archive is stdout 2006-11-01 00:24:19 +00:00
Sergey Poznyakoff
fdb46aa2e2 Add more keywords 2006-11-01 00:24:09 +00:00
Sergey Poznyakoff
2504e7d3ae Add new test cases. 2006-11-01 00:23:52 +00:00
Sergey Poznyakoff
b0765e257c (enum read_file_list_state.file_list_skip): New value
(read_name_from_file): Skip zero-length entries
2006-11-01 00:23:24 +00:00
Sergey Poznyakoff
73d4c40a87 Update 2006-10-31 20:19:30 +00:00
Sergey Poznyakoff
7aed52718f Call last_component instead of base_name. The latter returns a malloced string since 2006-03-11. 2006-10-31 20:18:50 +00:00
37 changed files with 2740 additions and 671 deletions

124
ChangeLog
View File

@@ -1,3 +1,127 @@
2006-12-08 Sergey Poznyakoff <gray@gnu.org.ua>
* bootstrap: Add paxutils files to dot_ignore.
* configure.ac: Raise version number to 1.16.1
* bootstrap (slurp): Create .(cvs|git)ignore if not present
* po/.cvsignore, m4/.cvsignore: Remove automatically generated
files.
2006-12-07 Sergey Poznyakoff <gray@gnu.org.ua>
* NEWS: Update
* Makefile.am (distclean-local): Fixed
* doc/tar.texi: Update documentation of --exclude-tag
* src/create.c (dump_dir0): Move checks for exclude tags to
dump_file0.
(dump_dir): Move calls to ensure_slash to dump_file0
* src/extract.c (extract_file): Call skip_member if open fails.
Patch proposed by Jan-Benedict Glaw <jbglaw@lug-owl.de>
* tests/truncate.at: Use genfile instead of dd, because on some
systems /dev/zero is not available.
2006-12-04 Paul Eggert <eggert@cs.ucla.edu>
* NEWS: Fix some race conditions with tar -x --same-owner.
* src/extract.c (ARCHIVED_PERMSTATS): Add a comment saying that
S_IRWXG | S_IRWXO might be masked out.
(set_mode): Set the mode if some bits were masked out originally.
(set_stat): Don't chmod before chown, as that might temporarily
grant permissions that we don't want to grant. The chmod was
there only to work around broken hosts, so add a comment advising
users not to use those broken hosts instead.
(repair_delayed_set_stat, extract_dir):
Remember to mask out current umask before inverting permissions.
(extract_dir): If the owner might change, or if the mode has
special bits, create the directory 700 at first, but restore it later.
(open_output_file): New arg mode; all uses changed.
(extract_file, extract_node, extract_fifo): If the owner might
change, omit group and other bits at first, but restore them after
changing the owner.
2006-12-04 Jim Meyering <jim@meyering.net>
* doc/tar.texi (Long Options): Remove doubled word.
2006-11-30 Sergey Poznyakoff <gray@gnu.org.ua>
* src/xheader.c (xheader_read): Remove unused variable
* po/POTFILES.in: Remove src/mangle.c
* bootstrap: Implement --update-po and .bootstrap
* src/create.c (dump_dir0): Implement --exclude-tag option
* src/tar.c: Likewise
* doc/tar.texi (exclude): Document --exclude-tag
2006-11-29 Paul Eggert <eggert@cs.ucla.edu>
* NEWS: Remove support for mangled names.
* doc/tar.texi (verbose tutorial): Likewise.
* src/Makefile.am (tar_SOURCES): Remove mangle.c.
* src/common.h (extract_mangle): Remove decl.
* src/extract.c (extract_mangle_wrapper): Remove.
(prepare_to_extract): Remove support for mangled names.
* src/list.c (read_and, print_header): Likewise.
* src/mangle.c: Remove.
* src/tar.h (GNUTYPE_NAMES): Remove.
Port to latest gnulib. There were a lot of changes, so the
simplest way to get this up and running was to switch to coreutils
bootstrap procedure. I noticed one feature missing after this
merge: the ability to update a single .po file. I can add that
later if need be.
* README-cvs, bootstrap.conf: New files.
* lib/.cvsignore: Remove Makefile.am, printf-parse.c, vasnprintf.c.
Add fstatat.c, gnulib.mk, openat-proc.c, same-inode.h, stat_.h,
tempname.c, tempname.h, uinttostr.c.
* lib/printf-parse.c, lib/vasnprintf.c: New files, from coreutils,
to override gnulib, so that we don't need xsize.h.
* bootstrap: Replace with coreutils bootstrap, except add support
for paxutils.
* configure.ac (gl_USE_SYSTEM_EXTENSIONS): Remove, as gl_EARLY now
does this.
(gl_EARLY, gl_INIT): Add.
(tar_GNULIB): Remove.
* gnulib.modules: Add configmake.
* lib/Makefile.tmpl: Remove, replacing with....
* lib/Makefile.am: New file.
* src/Makefile.am (tar.o): Remove dependency: Automake does this
for us.
* src/tar.c: Include <configmake.h> and <rmt-command.h>, not
<localedir.h>.
2006-11-13 Sergey Poznyakoff <gray@gnu.org.ua>
* src/xheader.c (mtime_coder): Treat non-null data as a pointer to
struct timespec, overriding st->mtime
* src/create.c (start_header): Pass mtime as a call-specific data
to xheader_store.
* tests/truncate.at: Do not use 'k' modifier in dd options.
* tests/append02.at: Do not depend on command timing.
2006-11-01 Sergey Poznyakoff <gray@gnu.org.ua>
* src/tar.c (enum read_file_list_state.file_list_skip): New value
(read_name_from_file): Skip zero-length entries
* tests/T-empty.at: New test case
* tests/T-null.at: New test case
* tests/extrac07.at: New test case
* tests/Makefile.am: Add new test cases.
* tests/testsuite.at: Add new test cases.
* tests/extrac02.at: Add more keywords
* tests/extrac04.at: Likewise
* tests/extrac06.at: Likewise
* tests/shortrec.at: Do not assume tar's default archive is stdout
2006-10-31 Sergey Poznyakoff <gray@gnu.org.ua>
* src/extract.c, src/xheader.c: Call last_component instead of
base_name. The latter returns a malloced string since 2006-03-11.
2006-10-21 Sergey Poznyakoff <gray@gnu.org.ua>
* NEWS, configure.ac: Version 1.16

View File

@@ -28,4 +28,4 @@ dist-hook:
GZIP=$(GZIP_ENV) gzip -c > $(distdir).cpio.gz
distclean-local:
-rm -f $(PACKAGE)-$(VERSION).cpio.gz
-rm -f $(distdir).cpio.gz

42
NEWS
View File

@@ -1,6 +1,30 @@
GNU tar NEWS - User visible changes.
Please send GNU tar bug reports to <bug-tar@gnu.org>
version 1.16.1
* New option --exclude-tag allows to specify "exclusion tag files", i.e.
files whose presence in a directory means that the directory should not
be archived.
* The --exclude-cache option excludes directories that contain the
CACHEDIR.TAG file from being archived. Previous versions excluded
directory contents only, while the directories themselves were
still added to the archive.
* Support for reading ustar type 'N' header logical records has been removed.
This GNU extension was generated only by very old versions of GNU 'tar'.
Unfortunately its implementation had security holes; see
<http://archives.neohapsis.com/archives/fulldisclosure/2006-11/0344.html>.
We don't expect that any tar archives in practical use have type 'N'
records, but if you have one and you trust its contents, you can
decode it with GNU tar 1.16 or earlier.
* Race conditions have been fixed that in some cases briefly allowed
files extracted by 'tar -x --same-owner' (or plain 'tar -x', when
running as root) to be accessed by users that they shouldn't have been.
version 1.16 - Sergey Poznyakoff, 2006-10-21
* After creating an archive, tar exits with code 1 if some files were
@@ -8,7 +32,7 @@ changed while being read. Previous versions exited with code 2 (fatal
error), and only if some files were truncated while being archived.
* New option --mtime allows to set modification times for all archive
members during creation.
members during creation.
* Bug fixes
** Avoid running off file descriptors when using multiple -C options.
@@ -34,14 +58,14 @@ no longer uses globbing by default. For example, the above invocation
is now interpreted as a request to extract from the archive the file
named '*.c'.
To treat member names as globbing patterns, use --wildcards option.
To treat member names as globbing patterns, use --wildcards option.
If you wish tar to mimic the behavior of versions up to 1.15.90,
add --wildcards to the value of the environment variable TAR_OPTIONS.
The exact way in which tar interprets member names is controlled by the
following command line options:
--wildcards use wildcards
--wildcards use wildcards
--anchored patterns match file name start
--ignore-case ignore case
--wildcards-match-slash wildcards match `/'
@@ -49,7 +73,7 @@ following command line options:
Each of these options has a '--no-' counterpart that disables its
effect (e.g. --no-wildcards).
These options affect both the interpretation of member names from
These options affect both the interpretation of member names from
command line and that of the exclusion patterns (given with --exclude
and --exclude-from options). The defaults are:
@@ -65,7 +89,7 @@ case-sensitive matching for the rest of command line, one could write:
** Short option -l is now an alias of --check-links option, which complies
with UNIX98. This ends the transition period started with version 1.14.
* New features
** New option --transform allows to transform file names before storing them
@@ -80,19 +104,19 @@ will add 'prefix/' to all file names stored in foo.tar.
versions it worked only with --extract.
** New option --show-transformed-names enables display of transformed file
or archive. It generalizes --show-stored-names option, introduced in
1.15.90. In particular, when creating an archive in verbose mode, it lists
or archive. It generalizes --show-stored-names option, introduced in
1.15.90. In particular, when creating an archive in verbose mode, it lists
member names as stored in the archive, i.e., with any eventual prefixes
removed and file name transformations applied. The option is useful,
for example, while comparing `tar cv' and `tar tv' outputs.
** New incremental snapshot file format keeps information about file names
** New incremental snapshot file format keeps information about file names
as well as that about directories.
** The --checkpoint option takes an optional argument specifying the number
of records between the two successive checkpoints. Optional dot
starting the argument intructs tar to print dots instead of textual
checkpoints.
checkpoints.
** The --totals option can be used with any tar operation (previous versions
understood it only with --create). If an argument to this option is

70
README-cvs Normal file
View File

@@ -0,0 +1,70 @@
-*- outline -*-
These notes intend to help people working on the CVS version of
this package.
* Requirements
Only the sources are installed in the CVS repository (to ease the
maintenance, merges etc.), therefore you will have to get the latest
stable versions of the maintainer tools we depend upon, including:
- Automake <http://www.gnu.org/software/automake/>
- Autoconf <http://www.gnu.org/software/autoconf/>
- Bison <http://www.gnu.org/software/bison/>
- Gettext <http://www.gnu.org/software/gettext/>
- Gzip <http://www.gnu.org/software/gzip/>
- Tar <http://www.gnu.org/software/tar/>
- Wget <http://www.gnu.org/software/wget/>
As of this writing, the latest stable version of Gzip is 1.2.4 but we
suggest using test version 1.3.5 (or later, if one becomes available).
Valgrind <http://valgrind.org/> is also highly recommended, if
Valgrind supports your architecture.
Only building the initial full source tree will be a bit painful,
later, a plain `cvs update -P && make' should be sufficient.
* First CVS checkout
Obviously, if you are reading these notes, you did manage to check out
this package from CVS. The next step is to get other files needed to
build, which are extracted from other source packages:
$ ./bootstrap
And there you are! Just
$ ./configure
$ make
$ make check
At this point, there should be no difference between your local copy,
and the CVS master copy:
$ cvs diff
should output no difference.
Enjoy!
-----
Copyright (C) 2002, 2003, 2004, 2005, 2006 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.

734
bootstrap
View File

@@ -21,10 +21,8 @@
# Written by Paul Eggert and Sergey Poznyakoff.
package=tar
# Translation Project URL, for the registry of all projects.
TP_URL='http://www.iro.umontreal.ca/translation/registry.cgi?domain='
nl='
'
# Ensure file names are sorted consistently across platforms.
# Also, ensure diagnostics are in English, e.g., "wget --help" below.
@@ -32,75 +30,186 @@ LC_ALL=C
export LC_ALL
usage() {
cat <<EOF
usage: $0 [--gnulib-srcdir=DIR][--paxutils-srcdir=DIR][--cvs-auth=AUTH-METHOD][--cvs-user=USERNAME][--no-po]
Options are:
--paxutils-srcdir=DIRNAME Specify the local directory where paxutils
sources reside. Use this if you already
have paxutils sources on your machine, and
do not want to waste your bandwidth dowloading
them again.
--gnulib-srcdir=DIRNAME Specify the local directory where gnulib
sources reside. Use this if you already
have gnulib sources on your machine, and
do not want to waste your bandwidth dowloading
them again.
--cvs-auth=METHOD Set the CVS access method used for downloading
gnulib files. METHOD is one of the keywords
accepted by cvs -d option (see info cvs
repository).
--cvs-user=USERNAME Set the CVS username to be used when accessing
the gnulib repository.
--no-po Do not download po files.
--update-po[=LANG] Update po file(s) and exit.
echo >&2 "\
Usage: $0 [OPTION]...
Bootstrap this package from the checked-out sources.
If the file \`.bootstrap' exists in the current working directory, its
contents is read, comments and empty lines removed, shell variables expanded
and the result is prepended to the command line options.
Options:
--paxutils-srcdir=DIRNAME Specify the local directory where paxutils
sources reside. Use this if you already
have paxutils sources on your machine, and
do not want to waste your bandwidth dowloading
them again.
--gnulib-srcdir=DIRNAME Specify the local directory where gnulib
sources reside. Use this if you already
have gnulib sources on your machine, and
do not want to waste your bandwidth dowloading
them again.
--copy Copy files instead of creating symbolic links.
--force Attempt to bootstrap even if the sources seem
not to have been checked out.
--skip-po Do not download po files.
--update-po[=LANG] Update po file(s) and exit.
--cvs-user=USERNAME Set the CVS username to be used when accessing
the gnulib repository.
Running without arguments will suffice in most cases. It is equivalent
to
If the file bootstrap.conf exists in the current working directory, its
contents are read as shell variables to configure the bootstrap.
./bootstrap --cvs-auth=pserver
Local defaults can be provided by placing the file \`.bootstrap' in the
current working directory. The file is read after bootstrap.conf, comments
and empty lines are removed, shell variables expanded and the result is
prepended to the command line options.
EOF
Running without arguments will suffice in most cases.
"
}
# Read configuration file
checkout() {
if [ ! -d $1 ]; then
echo "$0: getting $1 files..."
case ${CVS_AUTH-pserver} in
pserver)
CVS_PREFIX=':pserver:anonymous@';;
ssh)
CVS_PREFIX="$CVS_USER${CVS_USER+@}";;
*)
echo "$0: $CVS_AUTH: Unknown CVS access method" >&2
exit 1;;
esac
case $CVS_RSH in
'') CVS_RSH=ssh; export CVS_RSH;;
esac
trap "cleanup $1" 1 2 13 15
cvs -z3 -q -d ${CVS_PREFIX}cvs.savannah.gnu.org:/cvsroot/"$1" co $1 ||
cleanup $1
trap - 1 2 13 15
fi
}
cleanup() {
status=$?
rm -fr $1
exit $status
}
# Configuration.
# List of gnulib modules needed.
gnulib_modules=
# Any gnulib files needed that are not in modules.
gnulib_files=
# Translation Project URL, for the registry of all projects
# and for the translation-team master directory.
TP_URL='http://www.iro.umontreal.ca/translation/registry.cgi?domain='
TP_PO_URL='http://www.iro.umontreal.ca/translation/teams/PO/'
extract_package_name='
/^AC_INIT(/{
/.*,.*,.*,/{
s///
s/[][]//g
p
q
}
s/AC_INIT(\[*//
s/]*,.*//
s/^GNU //
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
s/[^A-Za-z0-9_]/-/g
p
}
'
package=`sed -n "$extract_package_name" configure.ac` || exit
# Extra files from gnulib, which override files from other sources.
gnulib_extra_files='
build-aux/announce-gen
build-aux/install-sh
build-aux/missing
build-aux/mdate-sh
build-aux/texinfo.tex
build-aux/depcomp
build-aux/config.guess
build-aux/config.sub
doc/INSTALL
'
# Other locale categories that need message catalogs.
EXTRA_LOCALE_CATEGORIES=
# Additional xgettext options to use. Use "\\\newline" to break lines.
XGETTEXT_OPTIONS='\\\
--flag=_:1:pass-c-format\\\
--flag=N_:1:pass-c-format\\\
--flag=error:3:c-format --flag=error_at_line:5:c-format\\\
'
# Files we don't want to import.
excluded_files=
# File that should exist in the top directory of a checked out hierarchy,
# but not in a distribution tarball.
CVS_only_file=README-cvs
# Whether to use copies instead of symlinks.
copy=false
# Override the default configuration, if necessary.
test -r bootstrap.conf && . ./bootstrap.conf
# Read local configuration file
if [ -r .bootstrap ]; then
echo "$0: Reading configuration file .bootstrap"
eval set -- "`sed 's/#.*$//;/^$/d' .bootstrap | tr '\n' ' '` $*"
fi
# Translate configuration into internal form.
# Parse options.
DOWNLOAD_PO=yes
for option
do
case $option in
--help)
usage
exit;;
--gnulib-srcdir=*)
GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
--paxutils-srcdir=*)
PAXUTILS_SRCDIR=`expr "$option" : '--paxutils-srcdir=\(.*\)'`;;
--cvs-auth=*)
CVS_AUTH=`expr "$option" : '--cvs-auth=\(.*\)'`;;
--gnulib-srcdir=*)
GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
--cvs-user=*)
CVS_USER=`expr "$option" : '--cvs-user=\(.*\)'`;;
--no-po)
DOWNLOAD_PO=no;;
--skip-po | --no-po) # --no-po is for compatibility with 'tar' tradition.
DOWNLOAD_PO=skip;;
--update-po=*)
DOWNLOAD_PO=`expr "$option" : '--update-po=\(.*\)'`;;
--update-po)
DOWNLOAD_PO=only;;
--force)
CVS_only_file=;;
--copy)
copy=true;;
*)
echo >&2 "$0: $option: unknown option"
exit 1;;
esac
done
if test -n "$CVS_only_file" && test ! -r "$CVS_only_file"; then
echo "$0: Bootstrapping from a non-checked-out distribution is risky." >&2
exit 1
fi
echo "$0: Bootstrapping CVS $package..."
# Get translations.
get_translations() {
@@ -108,141 +217,105 @@ get_translations() {
domain=$2
po_file=$3
echo "$0: getting translations into $subdir for $domain..."
case $WGET_COMMAND in
'')
echo "$0: wget not available; skipping translations";;
?*)
echo "$0: getting ${po_file:-translations} into $subdir for $domain..." &&
case $po_file in
'') (cd $subdir && rm -f dummy `ls | sed -n '/\.gmo$/p; /\.po/p'`);;
esac &&
$WGET_COMMAND -O "$subdir/$domain.html" "$TP_URL$domain" &&
case $po_file in
'') (cd $subdir && rm -f dummy `ls | sed -n '/\.gmo$/p; /\.po/p'`);;
sed -n 's|.*"http://[^"]*/translation/teams/PO/\([^/"]*\)/'"$domain"'-\([^/"]*\)\.[^."]*\.po".*|\1.\2|p' <"$subdir/$domain.html" |
sort -k 1,1 -k 2,2n -k2,2 -k3,3n -k3,3 -k4,4n -k4,4 -k5,5n -k5.5 |
awk -F. '
{ if (lang && $1 != lang) print lang, ver }
{ lang = $1; ver = substr($0, index($0, ".") + 1) }
END { if (lang) print lang, ver }
' | awk -v domain="$domain" -v po_file="$po_file" -v subdir="$subdir" '
{
lang = $1
if (po_file && po_file != (lang ".po")) next
ver = $2
urlfmt = ""
printf "{ $WGET_COMMAND -O %s/%s.po '\'"$TP_PO_URL"'/%s/%s-%s.%s.po'\'' &&\n", subdir, lang, lang, domain, ver, lang
printf " msgfmt -c -o /dev/null %s/%s.po || {\n", subdir, lang
printf " echo >&2 '\'"$0"': omitting translation for %s'\''\n", lang
printf " rm -f %s/%s.po; }; } &&\n", subdir, lang
}
END { print ":" }
' | WGET_COMMAND="$WGET_COMMAND" sh;;
esac &&
$WGET_COMMAND -O "$subdir/$domain.html" "$TP_URL$domain" &&
sed -n 's|.*"http://[^"]*/translation/teams/PO/\([^/"]*\)/'"$domain"'-\([^/"]*\)\.[^."]*\.po".*|\1.\2|p' <"$subdir/$domain.html" |
sort -k 1,1 -k 2,2n -k2,2 -k3,3n -k3,3 -k4,4n -k4,4 -k5,5n -k5.5 |
awk -F. '
{ if (lang && $1 != lang) print lang, ver }
{ lang = $1; ver = substr($0, index($0, ".") + 1) }
END { if (lang) print lang, ver }
' |
awk -v domain="$domain" -v po_file="$po_file" -v subdir="$subdir" '
{
lang = $1
if (po_file && po_file != (lang ".po")) next
# Work around bugs in translations uncovered by gettext 0.15.
# This workaround can be removed once the translations are fixed.
if (lang == "hu" || lang == "zh_TW") next
ver = $2
urlfmt = ""
printf "$WGET_COMMAND -O %s/%s.po 'http://www.iro.umontreal.ca/translation/teams/PO/%s/%s-%s.%s.po' &&\n", subdir, lang, lang, domain, ver, lang
}
END { print ":" }
' |
sh &&
ls "$subdir"/*.po | sed 's|.*/||; s|\.po$||' >"$subdir/LINGUAS" &&
rm "$subdir/$domain.html"
ls "$subdir"/*.po 2>/dev/null |
sed 's|.*/||; s|\.po$||' >"$subdir/LINGUAS" &&
rm -f "$subdir/$domain.html"
}
update_po() {
if [ $# = 1 ]; then
case $1 in
*.po) POFILE=$1;;
*) POFILE=${1}.po;;
esac
get_translations po $package "$POFILE"
else
get_translations po $package
fi
}
case $DOWNLOAD_PO in
no) ;;
case `wget --help` in
*'--no-cache'*)
WGET_COMMAND='wget -nv --no-cache';;
*'--cache=on/off'*)
WGET_COMMAND='wget -nv --cache=off';;
*'--non-verbose'*)
WGET_COMMAND='wget -nv';;
*)
case `wget --help` in
*'--no-cache'*)
no_cache='--no-cache';;
*'--cache=on/off'*)
no_cache='--cache=off';;
*)
no_cache='';;
esac
WGET_COMMAND="wget -nv $no_cache"
export WGET_COMMAND
WGET_COMMAND='';;
esac
case $DOWNLOAD_PO in
only) update_po
exit
;;
no|yes) ;;
*) update_po $DOWNLOAD_PO
exit
'skip')
;;
'')
get_translations po $package || exit
;;
'only')
get_translations po $package
exit
;;
*.po)
get_translations po $package "$DOWNLOAD_PO"
exit
;;
*)
get_translations po $package "${DOWNLOAD_PO}.po"
exit
esac
# Get paxutils files.
echo "$0: Bootstrapping CVS $package..."
build_cvs_prefix() {
CVS_PREFIX=:${1}:
if [ "${2}" != - ]; then
CVS_PREFIX=${CVS_PREFIX}${2}@
fi
if [ "$1" = "ext" ]; then
if [ -z "${CVS_RSH}" ]; then
CVS_RSH=ssh
export CVS_RSH
fi
fi
}
# checkout package
checkout() {
if [ ! -d $1 ]; then
echo "$0: getting $1 files..."
trap exit 1 2 13 15
trap 'rm -fr $1; exit 1' 0
case "${CVS_AUTH-pserver}" in
pserver) build_cvs_prefix pserver ${CVS_USER:-anonymous}
;;
gserver|server)
build_cvs_prefix $CVS_AUTH ${CVS_USER--}
;;
ext) build_cvs_prefix $CVS_AUTH ${CVS_USER--}
;;
*) echo "$0: Unknown CVS access method" >&2
exit 1;;
esac
cvs -q -d ${CVS_PREFIX}cvs.sv.gnu.org:/cvsroot/$1 co $1 || exit
trap - 0
fi
}
gnulib_modules=
newline='
'
get_modules() {
new_gnulib_modules=`sed '/^[ ]*#/d; /^[ ]*$/d' $*`
case $gnulib_modules,$new_gnulib_modules in
?*,?*) new_gnulib_modules=$newline$new_gnulib_modules;;
esac
gnulib_modules=$gnulib_modules$new_gnulib_modules
}
# Get paxutils files
case ${PAXUTILS_SRCDIR--} in
-) checkout paxutils
PAXUTILS_SRCDIR=paxutils
esac
if [ -r $PAXUTILS_SRCDIR/gnulib.modules ]; then
get_modules $PAXUTILS_SRCDIR/gnulib.modules
gnulib_modules=`
(echo "$gnulib_modules"; grep '^[^#]' $PAXUTILS_SRCDIR/gnulib.modules) |
sort -u
`
fi
ignore_file_list=
cleanup_ifl() {
test -n "$ignore_file_list" && rm -f $ignore_file_list
}
trap 'cleanup_ifl' 1 2 3 15
# ignorefile DIR FILE
# add FILE to the temporary ignorelist in the directory DIR
ignorefile() {
file=$1/.ignore.$$
echo "$2" >> $file
if `echo $ignore_list | grep -qv $file`; then
ignore_file_list="$ignore_file_list
$file"
fi
}
# copy_files srcdir dstdir
copy_files() {
for file in `cat $1/DISTFILES`
@@ -259,6 +332,7 @@ copy_files() {
fi
echo "$0: Copying file $1/$file to $2/$dst"
cp -p $1/$file $2/$dst
ignorefile $2 $dst
done
}
@@ -269,6 +343,7 @@ echo "$0: Creating m4/paxutils.m4"
echo "AC_DEFUN([${package}_PAXUTILS],["
cat ${PAXUTILS_SRCDIR}/m4/DISTFILES | sed '/^#/d;s/\(.*\)\.m4/pu_\1/' | tr a-z A-Z
echo "])") > ./m4/paxutils.m4
ignorefile m4 paxutils.m4
if [ -d rmt ]; then
:
@@ -286,111 +361,237 @@ copy_files ${PAXUTILS_SRCDIR}/paxlib lib pax
# Get gnulib files.
case ${GNULIB_SRCDIR--} in
-) checkout gnulib
GNULIB_SRCDIR=gnulib
-)
checkout gnulib
GNULIB_SRCDIR=gnulib
esac
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
<$gnulib_tool || exit
get_modules gnulib.modules
symlink_to_gnulib()
{
src=$GNULIB_SRCDIR/$1
dst=${2-$1}
gnulib_modules=`echo "$gnulib_modules" | sort -u`
previous_gnulib_modules=
while [ "$gnulib_modules" != "$previous_gnulib_modules" ]; do
previous_gnulib_modules=$gnulib_modules
gnulib_modules=`
(echo "$gnulib_modules"
for gnulib_module in $gnulib_modules; do
$gnulib_tool --extract-dependencies $gnulib_module
done) | sort -u
`
test -f "$src" && {
if $copy; then
{
test ! -h "$dst" || {
echo "$0: rm -f $dst" &&
rm -f "$dst"
}
} &&
test -f "$dst" &&
cmp -s "$src" "$dst" || {
echo "$0: cp -fp $src $dst" &&
cp -fp "$src" "$dst"
}
else
test -h "$dst" &&
src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
test "$src_i" = "$dst_i" || {
dot_dots=
case $src in
/*) ;;
*)
case /$dst/ in
*//* | */../* | */./* | /*/*/*/*/*/)
echo >&2 "$0: invalid symlink calculation: $src -> $dst"
exit 1;;
/*/*/*/*/) dot_dots=../../../;;
/*/*/*/) dot_dots=../../;;
/*/*/) dot_dots=../;;
esac;;
esac
echo "$0: ln -fs $dot_dots$src $dst" &&
ln -fs "$dot_dots$src" "$dst"
}
fi
}
}
cp_mark_as_generated()
{
cp_src=$1
cp_dst=$2
if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
symlink_to_gnulib "$cp_dst"
else
case $cp_dst in
*.[ch]) c1='/* '; c2=' */';;
*.texi) c1='@c '; c2= ;;
*.m4|*/Make*|Make*) c1='# ' ; c2= ;;
*) c1= ; c2= ;;
esac
if test -z "$c1"; then
cmp -s "$cp_src" "$cp_dst" || {
echo "$0: cp -f $cp_src $cp_dst" &&
cp -f "$cp_src" "$cp_dst"
}
else
# Copy the file first to get proper permissions if it
# doesn't already exist. Then overwrite the copy.
cp "$cp_src" "$cp_dst-t" &&
(
echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
cat "$cp_src"
) > $cp_dst-t &&
if cmp -s "$cp_dst-t" "$cp_dst"; then
rm -f "$cp_dst-t"
else
echo "$0: cp $cp_src $cp_dst # with edits" &&
mv -f "$cp_dst-t" "$cp_dst"
fi
fi
fi
}
version_controlled_file() {
dir=$1
file=$2
found=no
if test -d CVS; then
grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
grep '^/[^/]*/[0-9]' > /dev/null && found=yes
elif test -d .git; then
git-rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
else
echo "$0: no version control for $dir/$file?" >&2
fi
test $found = yes
}
slurp() {
for dir in . `(cd $1 && find * -type d -print)`; do
copied=
sep=
for file in `ls $1/$dir`; do
test -d $1/$dir/$file && continue
for excluded_file in $excluded_files; do
test "$dir/$file" = "$excluded_file" && continue 2
done
if test $file = Makefile.am; then
copied=$copied${sep}gnulib.mk; sep=$nl
remove_intl='/^[^#].*\/intl/s/^/#/'
sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/gnulib.mk || {
echo "$0: Copying $1/$dir/$file to $dir/gnulib.mk ..." &&
rm -f $dir/gnulib.mk &&
sed "$remove_intl" $1/$dir/$file >$dir/gnulib.mk
}
elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
version_controlled_file $dir $file; then
echo "$0: $dir/$file overrides $1/$dir/$file"
else
copied=$copied$sep$file; sep=$nl
if test $file = gettext.m4; then
echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
rm -f $dir/$file
sed '
/^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
AC_DEFUN([AM_INTL_SUBDIR], [
/^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
$a\
AC_DEFUN([gl_LOCK_EARLY], [])
' $1/$dir/$file >$dir/$file
else
cp_mark_as_generated $1/$dir/$file $dir/$file
fi
fi || exit
done
if test -n "$copied"; then
copied="Makefile
Makefile.in
$copied"
if test -d CVS; then
dot_ig=.cvsignore
else
dor_ig=.gitignore
fi
ig=$dir/$dot_ig
if [ -f $dir/.ignore.$$ ]; then
tfile=$dir/.ignore.$$
else
tfile=
fi
if test -f $ig; then
echo "$copied" | sort -u - $ig | cmp -s - $ig ||
echo "$copied" | sort -u - $ig $tfile -o $ig
else
copied="$dot_ig
$copied"
if [ "$dir" = "po" ]; then
copied="LINGUAS
Makevars
POTFILES
*.mo
*.gmo
*.po
remove-potcdate.sed
stamp-po
$package.pot
$copied"
fi
echo "$copied" | sort -u - $tfile -o $ig
fi || exit
fi
done
}
# Create boot temporary directories to import from gnulib and gettext.
bt='.#bootmp'
bt2=${bt}2
rm -fr $bt $bt2 &&
mkdir $bt $bt2 || exit
# Import from gnulib.
test -d build-aux || {
echo "$0: mkdir build-aux ..." &&
mkdir build-aux
} || exit
gnulib_tool_options="\
--import\
--no-changelog\
--aux-dir $bt/build-aux\
--doc-base $bt/doc\
--lib lib$package\
--m4-base $bt/m4/\
--source-base $bt/lib/\
--tests-base $bt/tests\
--local-dir gl\
"
echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
$gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
slurp $bt || exit
for file in $gnulib_files; do
symlink_to_gnulib $file || exit
done
gnulib_files=`
(for gnulib_module in $gnulib_modules; do
$gnulib_tool --extract-filelist $gnulib_module
done) | sort -u
`
gnulib_dirs=`echo "$gnulib_files" | sed 's,/[^/]*$,,' | sort -u`
mkdir -p $gnulib_dirs || exit
# Import from gettext.
for gnulib_file in $gnulib_files; do
dest=$gnulib_file
rm -f $dest &&
echo "$0: Copying file $GNULIB_SRCDIR/$gnulib_file" &&
cp -p $GNULIB_SRCDIR/$gnulib_file $dest || exit
done
echo "$0: (cd $bt2; autopoint) ..."
cp configure.ac $bt2 &&
(cd $bt2 && autopoint && rm configure.ac) &&
slurp $bt2 $bt || exit
# This suppresses a bogus diagnostic
# "warning: macro `AM_LANGINFO_CODESET' not found in library".
echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
sed '
/^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
AC_DEFUN([AM_INTL_SUBDIR], [])
/^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
' m4/gettext.m4 >m4/gettext_gl.m4 || exit
rm -fr $bt $bt2 || exit
echo "$0: Creating m4/gnulib.m4"
(echo "# This file is generated automatically. Please, do not edit."
echo "#"
echo "AC_DEFUN([${package}_GNULIB],["
for gnulib_module in $gnulib_modules; do
echo "# $gnulib_module"
$gnulib_tool --extract-autoconf-snippet $gnulib_module
done | sed '/AM_GNU_GETTEXT/d'
echo "])") > ./m4/gnulib.m4
echo "$0: Creating lib/Makefile.am"
(echo "# This file is generated automatically. Do not edit!"
cat lib/Makefile.tmpl
for gnulib_module in $gnulib_modules; do
echo "# $gnulib_module"
$gnulib_tool --extract-automake-snippet $gnulib_module
done | sed "s/lib_SOURCES/lib${package}_a_SOURCES/g" ) > lib/Makefile.am
# Get translations.
if test "$DOWNLOAD_PO" = "yes"; then
update_po
fi
# Reconfigure, getting other files.
echo "$0: autopoint --force ..."
autopoint --force || exit
# We don't need intl, so remove it.
intl_files_to_remove='
intl
m4/gettext.m4
m4/glibc2.m4
m4/intdiv0.m4
m4/intmax.m4
m4/lcmessage.m4
m4/lock.m4
m4/printf-posix.m4
m4/visibility.m4
'
echo $0: rm -fr $intl_files_to_remove ...
rm -fr $intl_files_to_remove || exit
# Undo changes to gnulib files that autoreconf made.
for gnulib_file in $gnulib_files; do
test ! -f $gnulib_file || cmp -s $gnulib_file $GNULIB_SRCDIR/$gnulib_file || {
rm -f $gnulib_file &&
echo "$0: Copying file $GNULIB_SRCDIR/$gnulib_file again" &&
cp -p $GNULIB_SRCDIR/$gnulib_file $gnulib_file || exit
}
done
# Make sure aclocal.m4 is not older than input files.
sleep 1
for command in \
'aclocal --force -I m4' \
'autoconf --force' \
@@ -402,25 +603,46 @@ do
done
# Get some extra files from gnulib, overriding existing files.
for file in $gnulib_extra_files; do
case $file in
*/INSTALL) dst=INSTALL;;
*) dst=$file;;
esac
symlink_to_gnulib $file $dst || exit
done
# Create gettext configuration.
echo "$0: Creating po/Makevars from po/Makevars.template ..."
rm -f po/Makevars
sed '
/^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
/^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
/^XGETTEXT_OPTIONS *=/{
s/$/ \\/
a\
--flag=_:1:pass-c-format \\\
--flag=N_:1:pass-c-format \\\
--flag=error:3:c-format --flag=error_at_line:5:c-format \\\
--flag=asnprintf:3:c-format --flag=vasnprintf:3:c-format \\\
--flag=argp_error:2:c-format \\\
--flag=__argp_error:2:c-format \\\
--flag=argp_failure:4:c-format \\\
--flag=__argp_failure:4:c-format \\\
--flag=argp_fmtstream_printf:2:c-format \\\
--flag=__argp_fmtstream_printf:2:c-format
'"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
}
' po/Makevars.template >po/Makevars
if test -d runtime-po; then
# Similarly for runtime-po/Makevars, but not quite the same.
rm -f runtime-po/Makevars
sed '
/^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
/^subdir *=.*/s/=.*/= runtime-po/
/^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
/^XGETTEXT_OPTIONS *=/{
s/$/ \\/
a\
'"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
}
' <po/Makevars.template >runtime-po/Makevars
# Copy identical files from po to runtime-po.
(cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
fi
cleanup_ifl
echo "$0: done. Now you can run './configure'."

61
bootstrap.conf Normal file
View File

@@ -0,0 +1,61 @@
# Bootstrap configuration.
# Copyright (C) 2006 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.
# We don't need these modules, even though gnulib-tool mistakenly
# includes them because of gettext dependencies.
avoided_gnulib_modules='
--avoid=lock
--avoid=size_max
--avoid=xsize
'
# gnulib modules used by this package.
gnulib_modules="$avoided_gnulib_modules
`grep '^[^#]' gnulib.modules`
"
# Additional xgettext options to use. Use "\\\newline" to break lines.
XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
--flag=_:1:pass-c-format\\\
--flag=N_:1:pass-c-format\\\
--flag=error:3:c-format --flag=error_at_line:5:c-format\\\
--flag=asnprintf:3:c-format --flag=vasnprintf:3:c-format\\\
--flag=argp_error:2:c-format\\\
--flag=__argp_error:2:c-format\\\
--flag=argp_failure:4:c-format\\\
--flag=__argp_failure:4:c-format\\\
--flag=argp_fmtstream_printf:2:c-format\\\
--flag=__argp_fmtstream_printf:2:c-format\\\
'
# Gettext supplies these files, but we don't need them since
# we don't have an intl subdirectory.
excluded_files='
m4/glibc2.m4
m4/intdiv0.m4
m4/lcmessage.m4
m4/lock.m4
m4/printf-posix.m4
m4/size_max.m4
m4/uintmax_t.m4
m4/ulonglong.m4
m4/visibility.m4
m4/xsize.m4
'

View File

@@ -18,18 +18,19 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
AC_INIT([GNU tar], [1.16], [bug-tar@gnu.org])
AC_INIT([GNU tar], [1.16.1], [bug-tar@gnu.org])
AC_CONFIG_SRCDIR([src/tar.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h:config.hin])
AC_PREREQ([2.60])
AM_INIT_AUTOMAKE([1.9 gnits tar-ustar dist-bzip2 dist-shar std-options])
gl_USE_SYSTEM_EXTENSIONS
AC_PROG_CC
AC_EXEEXT
AC_PROG_RANLIB
AC_PROG_YACC
gl_EARLY
AC_SYS_LARGEFILE
AC_ISC_POSIX
AC_C_INLINE
@@ -82,7 +83,7 @@ AC_CHECK_TYPE(ino_t, unsigned)
gt_TYPE_SSIZE_T
# gnulib modules
tar_GNULIB
gl_INIT
# paxutils modules
tar_PAXUTILS
@@ -213,7 +214,7 @@ AC_CHECK_TYPE(iconv_t,:,
# Gettext.
AM_GNU_GETTEXT([external], [need-formatstring-macros])
AM_GNU_GETTEXT_VERSION([0.15])
AM_GNU_GETTEXT_VERSION([0.16])
# Initialize the test suite.
AC_CONFIG_TESTDIR(tests)

View File

@@ -20,7 +20,7 @@
@include rendition.texi
@include value.texi
@defcodeindex op
@defcodeindex op
@c Put everything in one index (arbitrarily chosen to be the concept index).
@syncodeindex fn cp
@@ -898,7 +898,7 @@ clear, and we will give many examples both using and not using
@option{--verbose} to show the differences.
Each instance of @option{--verbose} on the command line increases the
verbosity level by one, so if you need more details on the output,
verbosity level by one, so if you need more details on the output,
specify it twice.
When reading archives (@option{--list}, @option{--extract},
@@ -911,7 +911,7 @@ In contrast, when writing archives (@option{--create}, @option{--append},
default. So, a single @option{--verbose} option shows the file names
being added to the archive, while two @option{--verbose} options
enable the full listing.
For example, to create an archive in verbose mode:
@smallexample
@@ -998,13 +998,7 @@ The archive member is a GNU @dfn{volume header} (@pxref{Tape Files}).
Encountered only at the beginning of a multi-volume archive
(@pxref{Using Multiple Tapes}). This archive member is a continuation
from the previous volume. The number @var{n} gives the offset where
the original file was split.
@item --Mangled file names--
This archive member contains @dfn{mangled file names} declarations,
a special member type that was used by early versions of @GNUTAR{}.
You probably will never encounter this, unless you are reading a very
old archive.
the original file was split.
@item unknown file type @var{c}
An archive member of unknown type. @var{c} is the type character from
@@ -1378,7 +1372,7 @@ particular archive contains. You can use the @option{--list}
appear in the archive, as well as various attributes of the files at
the time they were archived. For example, you can examine the archive
@file{collection.tar} that you created in the last section with the
command,
command,
@smallexample
$ @kbd{tar --list --file=collection.tar}
@@ -1580,7 +1574,7 @@ mistakenly deleted one of the files you had placed in the archive
@file{collection.tar} earlier (say, @file{blues}), you can extract it
from the archive without changing the archive's structure. Its
contents will be identical to the original file @file{blues} that you
deleted.
deleted.
First, make sure you are in the @file{practice} directory, and list the
files in the directory. Now, delete the file, @samp{blues}, and list
@@ -1630,7 +1624,7 @@ Here, @option{--wildcards} instructs @command{tar} to treat
command line arguments as globbing patterns and @option{--no-anchored}
informs it that the patterns apply to member names after any @samp{/}
delimiter. The use of globbing patterns is discussed in detail in
@xref{wildcards}.
@xref{wildcards}.
You can extract a file to standard output by combining the above options
with the @option{--to-stdout} (@option{-O}) option (@pxref{Writing to Standard
@@ -2000,7 +1994,7 @@ Some options @emph{may} take an argument. Such options may have at
most long and short forms, they do not have old style equivalent. The
rules for specifying an argument for such options are stricter than
those for specifying mandatory arguments. Please, pay special
attention to them.
attention to them.
@menu
* Long Options:: Long Option Style
@@ -2015,7 +2009,7 @@ attention to them.
Each option has at least one @dfn{long} (or @dfn{mnemonic}) name starting with two
dashes in a row, e.g., @option{--list}. The long names are more clear than
their corresponding short or old names. It sometimes happens that a
single long option has many different different names which are
single long option has many different names which are
synonymous, such as @option{--compare} and @option{--diff}. In addition,
long option names can be given unique abbreviations. For example,
@option{--cre} can be used in place of @option{--create} because there is no
@@ -2453,7 +2447,7 @@ total number of hard links for the file, a warning message will be
output @footnote{Earlier versions of @GNUTAR{} understood @option{-l} as a
synonym for @option{--one-file-system}. The current semantics, which
complies to UNIX98, was introduced with version
1.15.91. @xref{Changes}, for more information.}.
1.15.91. @xref{Changes}, for more information.}.
@opsummary{compress}
@opsummary{uncompress}
@@ -2511,6 +2505,11 @@ patterns in the file @var{file}. @xref{exclude}.
Automatically excludes all directories
containing a cache directory tag. @xref{exclude}.
@opsummary{exclude-tag}
@item --exclude-tag=@var{file}
Exclude all directories, containing file named @var{file}. @xref{exclude}.
@opsummary{file}
@item --file=@var{archive}
@itemx -f @var{archive}
@@ -2596,7 +2595,7 @@ options to @command{tar} and exit. @xref{help}.
@opsummary{ignore-case}
@item --ignore-case
Ignore case when matching member or file names with
patterns. @xref{controlling pattern-matching}.
patterns. @xref{controlling pattern-matching}.
@opsummary{ignore-command-error}
@item --ignore-command-error
@@ -2908,7 +2907,7 @@ discussion, @xref{transform}.
To see transformed member names in verbose listings, use
@option{--show-transformed-names} option
(@pxref{show-transformed-names}).
(@pxref{show-transformed-names}).
@opsummary{quote-chars}
@item --quote-chars=@var{string}
@@ -3297,7 +3296,7 @@ them with the equivalent long option.
@item -m @tab @ref{--touch}.
@item -o @tab When creating, @ref{--no-same-owner}, when extracting ---
@ref{--portability}.
@ref{--portability}.
The later usage is deprecated. It is retained for compatibility with
the earlier versions of @GNUTAR{}. In the future releases
@@ -3433,7 +3432,7 @@ values in the form of @command{tar} command line options:
@smallexample
@group
@kbd{tar --show-defaults}
--format=gnu -f- -b20 --quoting-style=escape
--format=gnu -f- -b20 --quoting-style=escape
--rmt-command=/etc/rmt --rsh-command=/usr/bin/rsh
@end group
@end smallexample
@@ -3548,14 +3547,14 @@ statistics is to be printed:
Print statistics upon delivery of signal @var{signo}. Valid arguments
are: @code{SIGHUP}, @code{SIGQUIT}, @code{SIGINT}, @code{SIGUSR1} and
@code{SIGUSR2}. Shortened names without @samp{SIG} prefix are also
accepted.
accepted.
@end table
Both forms of @option{--totals} option can be used simultaneously.
Thus, @kbd{tar -x --totals --totals=USR1} instructs @command{tar} to
extract all members from its default archive and print statistics
after finishing the extraction, as well as when receiving signal
@code{SIGUSR1}.
@code{SIGUSR1}.
@anchor{Progress information}
@cindex Progress information
@@ -3960,7 +3959,7 @@ archive in the order in which they were archived. Thus, when the
archive is extracted, a file archived later in time will replace a
file of the same name which was archived earlier, even though the
older version of the file will remain in the archive unless you delete
all versions of the file.
all versions of the file.
Supposing you change the file @file{blues} and then append the changed
version to @file{collection.tar}. As you saw above, the original
@@ -4272,7 +4271,7 @@ tar: funk not found in archive
The spirit behind the @option{--compare} (@option{--diff},
@option{-d}) option is to check whether the archive represents the
current state of files on disk, more than validating the integrity of
the archive media. For this later goal, @xref{verify}.
the archive media. For this later goal, @xref{verify}.
@node create options
@section Options Used by @option{--create}
@@ -4679,7 +4678,7 @@ Use in conjunction with @option{--extract} (@option{--get}, @option{-x}).
To set the modes (access permissions) of extracted files to those
recorded for those files in the archive, use @option{--same-permissions}
in conjunction with the @option{--extract} (@option{--get},
@option{-x}) operation.
@option{-x}) operation.
@table @option
@opindex preserve-permissions
@@ -6170,7 +6169,7 @@ can be inhibited by using the @option{--force-local} option.
When the archive is being created to @file{/dev/null}, @GNUTAR{}
tries to minimize input and output operations. The Amanda backup
system, when used with @GNUTAR{}, has an initial sizing pass which
uses this feature.
uses this feature.
@node Selecting Archive Members
@section Selecting Archive Members
@@ -6198,9 +6197,9 @@ name, replacing @dfn{escape sequences} according to the following
table:
@multitable @columnfractions 0.20 0.60
@headitem Escape @tab Replaced with
@headitem Escape @tab Replaced with
@item \a @tab Audible bell (ASCII 7)
@item \b @tab Backspace (ASCII 8)
@item \b @tab Backspace (ASCII 8)
@item \f @tab Form feed (ASCII 12)
@item \n @tab New line (ASCII 10)
@item \r @tab Carriage return (ASCII 13)
@@ -6256,7 +6255,7 @@ By default, @command{tar} takes file names from the command line. However,
there are other ways to specify file or member names, or to modify the
manner in which @command{tar} selects the files or members upon which to
operate. In general, these methods work both for specifying the names
of files and archive members.
of files and archive members.
@node files
@section Reading Names from a File
@@ -6268,7 +6267,7 @@ Instead of giving the names of files or archive members on the command
line, you can put the names into a file, and then use the
@option{--files-from=@var{file-of-names}} (@option{-T
@var{file-of-names}}) option to @command{tar}. Give the name of the
file which contains the list of files to include as the argument to
file which contains the list of files to include as the argument to
@option{--files-from}. In the list, the file names should be separated by
newlines. You will frequently use this option when you have generated
the list of files to archive with the @command{find} utility.
@@ -6397,7 +6396,7 @@ The @option{--null} option causes
@option{--files-from=@var{file-of-names}} (@option{-T @var{file-of-names}})
to read file names terminated by a @code{NUL} instead of a newline, so
files whose names contain newlines can be archived using
@option{--files-from}.
@option{--files-from}.
@table @option
@opindex null
@@ -6448,7 +6447,7 @@ Causes @command{tar} to ignore files that match the @var{pattern}.
@findex exclude
The @option{--exclude=@var{pattern}} option prevents any file or
member whose name matches the shell wildcard (@var{pattern}) from
being operated on.
being operated on.
For example, to create an archive with all the contents of the directory
@file{src} except for files whose names end in @file{.o}, use the
command @samp{tar -cf src.tar --exclude='*.o' src}.
@@ -6487,6 +6486,38 @@ Various applications write cache directory tags into directories they
use to hold regenerable, non-precious data, so that such data can be
more easily excluded from backups.
@findex exclude-tag
Another option, @option{--exclude-tag}, provides a generalization of
this concept. It takes a single argument, a file name to look for.
Any directory that contains this file will be excluded from the dump.
@table @option
@opindex exclude-tag
@item --exclude-tag=@var{file}
Causes @command{tar} to ignore directories containing @var{file}.
Multiple @option{--exclude-tag} options can be given.
@end table
For example:
@smallexample
$ @kbd{find dir}
dir
dir/blues
dir/jazz
dir/folk
dir/folk/tagfile
$ @kbd{tar -cf archive.tar --exclude-tag=tagfile -v}
dir/
dir/blues
dir/jazz
./tar: dir/folk/: contains a cache directory tag tagfile; not dumped
$ @kbd{tar -tf archive.tar}
dir/
dir/blues
dir/jazz
@end smallexample
@menu
* problems with exclude::
@end menu
@@ -6546,7 +6577,7 @@ might fail.
@item
@FIXME{The change in semantics must have occurred before 1.11,
so I doubt if it is worth mentioning at all. Anyway, should at
least specify in which version the semantics changed.}
least specify in which version the semantics changed.}
In earlier versions of @command{tar}, what is now the
@option{--exclude-from} option was called @option{--exclude} instead.
Now, @option{--exclude} applies to patterns listed on the command
@@ -6631,7 +6662,7 @@ There are no inclusion members in create mode (@option{--create} and
command line refer to @emph{files}, not archive members.
By default, inclusion members are compared with archive members
literally @footnote{Notice that earlier @GNUTAR{} versions used
literally @footnote{Notice that earlier @GNUTAR{} versions used
globbing for inclusion members, which contradicted to UNIX98
specification and was not documented. @xref{Changes}, for more
information on this and other changes.} and exclusion members are
@@ -6659,7 +6690,7 @@ This behavior can be altered by using the following options:
@table @option
@opindex wildcards
@item --wildcards
Treat all member names as wildcards.
Treat all member names as wildcards.
@opindex no-wildcards
@item --no-wildcards
@@ -6842,7 +6873,7 @@ Quoting styles:
No quoting, display each character as is:
@smallexample
@group
@group
$ @kbd{tar tf arch.tar --quoting-style=literal}
./
./a space
@@ -6985,7 +7016,7 @@ quoting style would not quote them.
@end table
For example, using @samp{escape} quoting (compare with the usual
escape listing above):
escape listing above):
@smallexample
@group
@@ -7058,7 +7089,7 @@ $ @kbd{tar -xf usr.tar --strip=2 usr/include/stdlib.h}
The option @option{--strip=2} instructs @command{tar} to strip the
two leading components (@file{usr/} and @file{include/}) off the file
name.
name.
If you add to the above invocation @option{--verbose} (@option{-v})
option, you will note that the verbose listing still contains the
@@ -7154,7 +7185,7 @@ follows the GNU @command{sed} implementation in this regard, so
the interaction is defined to be: ignore matches before the
@var{number}th, and then match and replace all matches from the
@var{number}th on.
@end table
Any delimiter can be used in lieue of @samp{/}, the only requirement being
@@ -7222,7 +7253,7 @@ $ @kbd{tar -cf arch.tar --transform='s,^usr/,var/,' \
If both @option{--strip-components} and @option{--transform} are used
together, then @option{--transform} is applied first, and the required
number of components is then stripped from its result.
@node after
@section Operating Only on New Files
@UNREVISED
@@ -7907,7 +7938,7 @@ implement your own filters, not necessarily dealing with
compression/decompression. For example, suppose you wish to implement
PGP encryption on top of compression, using @command{gpg} (@pxref{Top,
gpg, gpg ---- encryption and signing tool, gpg, GNU Privacy Guard
Manual}). The following script does that:
Manual}). The following script does that:
@smallexample
@group
@@ -7960,9 +7991,9 @@ The above is based on the following discussion:
that capability. Supposing I were to actually do such a thing and
get it (apparently) working, do you accept contributed changes to
utilities like that? (Leigh Clayton @file{loc@@soliton.com}, May 1995).
Isn't that exactly the role of the
@option{--use-compress-prog=@var{program}} option?
@option{--use-compress-prog=@var{program}} option?
I never tried it myself, but I suspect you may want to write a
@var{prog} script or program able to filter stdin to stdout to
way you want. It should recognize the @option{-d} option, for when
@@ -8010,7 +8041,7 @@ has no effect on extraction.
Consider using @option{--sparse} when performing file system backups,
to avoid archiving the expanded forms of files stored sparsely in the
system.
system.
Even if your system has no sparse files currently, some may be
created in the future. If you use @option{--sparse} while making file
@@ -8058,7 +8089,7 @@ formats}. A sparse format is identified by its @dfn{number},
consisting, as usual of two decimal numbers, delimited by a dot. By
default, format @samp{1.0} is used. If, for some reason, you wish to
use an earlier format, you can select it using
@option{--sparse-version} option.
@option{--sparse-version} option.
@table @option
@opindex sparse-version
@@ -8136,7 +8167,7 @@ separately. If it can't find a user name (because the user id is not
in @file{/etc/passwd}), then it does not write one. When restoring,
it tries to look the name (if one was written) up in
@file{/etc/passwd}. If it fails, then it uses the user id stored in
the archive instead.
the archive instead.
@opindex no-same-owner
@item --no-same-owner
@@ -8367,7 +8398,7 @@ Starting from version 1.14 @GNUTAR{} features full support for
A @acronym{POSIX} conformant archive will be created if @command{tar}
was given @option{--format=posix} (@option{--format=pax}) option. No
special option is required to read and extract from a @acronym{POSIX}
archive.
archive.
@menu
* PAX keywords:: Controlling Extended Header Keywords.
@@ -8570,7 +8601,7 @@ extract archives containing GNU-specific members using some
third-party @command{tar} implementation or an older version of
@GNUTAR{}. Of course your best bet is to have @GNUTAR{} installed,
but if it is for some reason impossible, this section will explain
how to cope without it.
how to cope without it.
When we speak about @dfn{GNU-specific} members we mean two classes of
them: members split between the volumes of a multi-volume archive and
@@ -8677,7 +8708,7 @@ more warnings and more files generated on your disk, e.g.:
@group
$ @kbd{tar xf vol-1.tar}
var/PaxHeaders.27962/longfile: Unknown file type 'x', extracted as
normal file
normal file
Unexpected EOF in archive
$ @kbd{tar xf vol-2.tar}
tmp/GlobalHead.27962.1: Unknown file type 'g', extracted as normal file
@@ -8714,7 +8745,7 @@ version 1.0}@footnote{@xref{PAX 1}.}, which are the easiest to expand.
The condensed file will contain both file map and file data, so no
additional data will be needed to restore it. If the original file
name was @file{@var{dir}/@var{name}}, then the condensed file will be
named @file{@var{dir}/@/GNUSparseFile.@var{n}/@/@var{name}}, where
named @file{@var{dir}/@/GNUSparseFile.@var{n}/@/@var{name}}, where
@var{n} is a decimal number@footnote{technically speaking, @var{n} is a
@dfn{process ID} of the @command{tar} process which created the
archive (@pxref{PAX keywords}).}.
@@ -8822,10 +8853,10 @@ expanding sparse version 1.0 members, use of extended headers is
mandatory when expanding sparse members in older sparse formats: v.0.0
and v.0.1 (The sparse formats are described in detail in @ref{Sparse
Formats}.) So, for this format, the question is: how to obtain
extended headers from the archive?
extended headers from the archive?
If you use a @command{tar} implementation that does not support PAX
format, extended headers for each member will be extracted as a
format, extended headers for each member will be extracted as a
separate file. If we represent the member name as
@file{@var{dir}/@var{name}}, then the extended header file will be
named @file{@var{dir}/@/PaxHeaders.@var{n}/@/@var{name}}, where
@@ -8836,7 +8867,7 @@ does support PAX headers, because in this case you will have to
manually extract the headers. We recommend the following algorithm:
@enumerate 1
@item
@item
Consult the documentation of your @command{tar} implementation for an
option that prints @dfn{block numbers} along with the archive
listing (analogous to @GNUTAR{}'s @option{-R} option). For example,
@@ -8868,7 +8899,7 @@ block 897: 65391 -rw-r--r-- gray/users Jun 24 20:06 2006 README
@item
Let @var{size} be the size of the sparse member, @var{Bs} be its block number
and @var{Bn} be the block number of the next member.
Compute:
Compute:
@smallexample
@var{N} = @var{Bs} - @var{Bn} - @var{size}/512 - 2
@@ -9912,7 +9943,7 @@ on several media volumes of fixed size. Although in this section we will
often call @samp{volume} a @dfn{tape}, there is absolutely no
requirement for multi-volume archives to be stored on tapes. Instead,
they can use whatever media type the user finds convenient, they can
even be located on files.
even be located on files.
When creating a multi-volume archive, @GNUTAR{} continues to fill
current volume until it runs out of space, then it switches to
@@ -9920,7 +9951,7 @@ next volume (usually the operator is queried to replace the tape on
this point), and continues working on the new volume. This operation
continues until all requested files are dumped. If @GNUTAR{} detects
end of media while dumping a file, such a file is archived in split
form. Some very big files can even be split across several volumes.
form. Some very big files can even be split across several volumes.
Each volume is itself a valid @GNUTAR{} archive, so it can be read
without any special options. Consequently any file member residing
@@ -9998,7 +10029,7 @@ $ @kbd{tar --create --tape-length=41943040 --file=/dev/tape @var{files}}
When @GNUTAR{} comes to the end of a storage media, it asks you to
change the volume. The built-in prompt for POSIX locale
is@footnote{If you run @GNUTAR{} under a different locale, the
translation to the locale's language will be used.}:
translation to the locale's language will be used.}:
@smallexample
Prepare volume #@var{n} for `@var{archive}' and hit return:
@@ -10053,7 +10084,7 @@ the number used in the prompt.)
If you want more elaborate behavior than this, you can write a special
@dfn{new volume script}, that will be responsible for changing the
volume, and instruct @command{tar} to use it instead of its normal
prompting procedure:
prompting procedure:
@table @option
@item --info-script=@var{script-name}
@@ -10117,7 +10148,7 @@ $ @kbd{tar cMff /dev/tape0 /dev/tape1 @var{files}}
@end smallexample
The second method is to use the @samp{n} response to the tape-change
prompt.
prompt.
Finally, the most flexible approach is to use a volume script, that
writes new archive name to the file descriptor #3. For example, the

View File

@@ -6,6 +6,7 @@ argmatch
argp
backupfile
closeout
configmake
dirname
error
exclude

View File

@@ -1,6 +1,5 @@
.deps
Makefile
Makefile.am
Makefile.in
__fpending.c
__fpending.h
@@ -63,6 +62,7 @@ fnmatch.c
fnmatch.h
fnmatch_.h
fnmatch_loop.c
fstatat.c
ftruncate.c
full-write.c
full-write.h
@@ -84,6 +84,7 @@ getpagesize.h
gettext.h
gettime.c
gettimeofday.c
gnulib.mk
hash.c
hash.h
human.c
@@ -124,6 +125,7 @@ offtostr.c
open-safer.c
openat-die.c
openat-priv.h
openat-proc.c
openat.c
openat.h
paxerror.c
@@ -133,7 +135,6 @@ paxnames.c
pipe-safer.c
printf-args.c
printf-args.h
printf-parse.c
printf-parse.h
quote.c
quote.h
@@ -157,6 +158,7 @@ safe-read.c
safe-read.h
safe-write.c
safe-write.h
same-inode.h
save-cwd.c
save-cwd.h
savedir.c
@@ -166,6 +168,7 @@ setenv.h
size_max.h
stat-macros.h
stat-time.h
stat_.h
stdbool.h
stdbool_.h
stdint.h
@@ -196,9 +199,12 @@ sysexit_.h
sysexits.h
system-ioctl.h
system.h
tempname.c
tempname.h
time_r.c
time_r.h
timespec.h
uinttostr.c
umaxtostr.c
unistd--.h
unistd-safer.h
@@ -209,7 +215,6 @@ unsetenv.c
utime.c
utimens.c
utimens.h
vasnprintf.c
vasnprintf.h
verify.h
version-etc-fsf.c

41
lib/Makefile.am Normal file
View File

@@ -0,0 +1,41 @@
# Makefile for GNU tar library. -*- Makefile -*-
# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004,
# 2005, 2006 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 of the License, 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 St, Fifth Floor, Boston, MA 02110-1301 USA
include gnulib.mk
rmt-command.h : Makefile
rm -f $@-t $@
echo "#ifndef DEFAULT_RMT_COMMAND" >> $@-t
echo "# define DEFAULT_RMT_COMMAND \"$(DEFAULT_RMT_DIR)/`echo rmt | sed '$(transform)'`$(EXEEXT)\"" >> $@-t
echo "#endif" >> $@-t
mv $@-t $@
BUILT_SOURCES += rmt-command.h
CLEANFILES += rmt-command.h rmt-command.h-t
noinst_HEADERS += system.h system-ioctl.h rmt.h paxlib.h stdopen.h
libtar_a_SOURCES += \
paxerror.c paxexit.c paxlib.h paxnames.c \
prepargs.c prepargs.h \
rtapelib.c \
rmt.h \
stdopen.c stdopen.h \
system.h system-ioctl.h
libtar_a_LIBADD += $(LIBOBJS)
libtar_a_DEPENDENCIES += $(LIBOBJS)

View File

@@ -1,56 +0,0 @@
# Makefile for GNU tar library. -*- Makefile -*-
# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004,
# 2005, 2006 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.
noinst_LIBRARIES = libtar.a
noinst_HEADERS = system.h system-ioctl.h localedir.h rmt.h paxlib.h stdopen.h
libtar_a_SOURCES = prepargs.c prepargs.h rtapelib.c paxerror.c paxexit.c paxnames.c stdopen.c
localedir = $(datadir)/locale
DISTCLEANFILES = localedir.h
localedir.h : Makefile
echo '#define LOCALEDIR "$(localedir)"' >$@
echo "#ifndef DEFAULT_RMT_COMMAND" >> $@
echo "# define DEFAULT_RMT_COMMAND \"$(DEFAULT_RMT_DIR)/`echo rmt | sed '$(transform)'`$(EXEEXT)\"" >> $@
echo "#endif" >> $@
rtapelib.o: localedir.h
libtar_a_LIBADD = $(LIBOBJS) $(ALLOCA)
libtar_a_DEPENDENCIES = $(libtar_a_LIBADD)
BUILT_SOURCES =
AM_CPPFLAGS =
EXTRA_DIST = Makefile.tmpl
MAINTAINERCLEANFILES =
MOSTLYCLEANFILES =
lib_OBJECTS = $(libtar_a_OBJECTS)
# Special rule for getdate
#
# Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule.
$(srcdir)/getdate.c: getdate.y
cd $(srcdir) && \
$(YACC) $(YFLAGS) getdate.y && \
mv -f y.tab.c getdate.c
SUFFIXES = .o .c .h
CLEANFILES =
# gnulib modules

535
lib/printf-parse.c Normal file
View File

@@ -0,0 +1,535 @@
/* Formatted output to strings.
Copyright (C) 1999-2000, 2002-2004, 2006 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. */
#include <config.h>
/* Specification. */
#if WIDE_CHAR_VERSION
# include "wprintf-parse.h"
#else
# include "printf-parse.h"
#endif
/* Get size_t, NULL. */
#include <stddef.h>
/* Get intmax_t. */
#if HAVE_STDINT_H_WITH_UINTMAX
# include <stdint.h>
#endif
#if HAVE_INTTYPES_H_WITH_UINTMAX
# include <inttypes.h>
#endif
/* malloc(), realloc(), free(). */
#include <stdlib.h>
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
#if WIDE_CHAR_VERSION
# define PRINTF_PARSE wprintf_parse
# define CHAR_T wchar_t
# define DIRECTIVE wchar_t_directive
# define DIRECTIVES wchar_t_directives
#else
# define PRINTF_PARSE printf_parse
# define CHAR_T char
# define DIRECTIVE char_directive
# define DIRECTIVES char_directives
#endif
#ifdef STATIC
STATIC
#endif
int
PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
{
const CHAR_T *cp = format; /* pointer into format */
size_t arg_posn = 0; /* number of regular arguments consumed */
size_t d_allocated; /* allocated elements of d->dir */
size_t a_allocated; /* allocated elements of a->arg */
size_t max_width_length = 0;
size_t max_precision_length = 0;
d->count = 0;
d_allocated = 1;
d->dir = malloc (d_allocated * sizeof (DIRECTIVE));
if (d->dir == NULL)
/* Out of memory. */
return -1;
a->count = 0;
a_allocated = 0;
a->arg = NULL;
#define REGISTER_ARG(_index_,_type_) \
{ \
size_t n = (_index_); \
if (n >= a_allocated) \
{ \
size_t memory_size; \
argument *memory; \
\
a_allocated *= 2; \
if (a_allocated <= n) \
a_allocated = n + 1; \
if (SIZE_MAX / sizeof (argument) < a_allocated) \
/* Overflow, would lead to out of memory. */ \
goto error; \
memory_size = a_allocated * sizeof (argument); \
memory = (a->arg \
? realloc (a->arg, memory_size) \
: malloc (memory_size)); \
if (memory == NULL) \
/* Out of memory. */ \
goto error; \
a->arg = memory; \
} \
while (a->count <= n) \
a->arg[a->count++].type = TYPE_NONE; \
if (a->arg[n].type == TYPE_NONE) \
a->arg[n].type = (_type_); \
else if (a->arg[n].type != (_type_)) \
/* Ambiguous type for positional argument. */ \
goto error; \
}
while (*cp != '\0')
{
CHAR_T c = *cp++;
if (c == '%')
{
size_t arg_index = ARG_NONE;
DIRECTIVE *dp = &d->dir[d->count];/* pointer to next directive */
/* Initialize the next directive. */
dp->dir_start = cp - 1;
dp->flags = 0;
dp->width_start = NULL;
dp->width_end = NULL;
dp->width_arg_index = ARG_NONE;
dp->precision_start = NULL;
dp->precision_end = NULL;
dp->precision_arg_index = ARG_NONE;
dp->arg_index = ARG_NONE;
/* Test for positional argument. */
if (*cp >= '0' && *cp <= '9')
{
const CHAR_T *np;
for (np = cp; *np >= '0' && *np <= '9'; np++)
;
if (*np == '$')
{
size_t n = 0;
for (np = cp; *np >= '0' && *np <= '9'; np++)
if (n < SIZE_MAX / 10)
n = 10 * n + (*np - '0');
else
/* n too large for memory. */
goto error;
if (n == 0)
/* Positional argument 0. */
goto error;
arg_index = n - 1;
cp = np + 1;
}
}
/* Read the flags. */
for (;;)
{
if (*cp == '\'')
{
dp->flags |= FLAG_GROUP;
cp++;
}
else if (*cp == '-')
{
dp->flags |= FLAG_LEFT;
cp++;
}
else if (*cp == '+')
{
dp->flags |= FLAG_SHOWSIGN;
cp++;
}
else if (*cp == ' ')
{
dp->flags |= FLAG_SPACE;
cp++;
}
else if (*cp == '#')
{
dp->flags |= FLAG_ALT;
cp++;
}
else if (*cp == '0')
{
dp->flags |= FLAG_ZERO;
cp++;
}
else
break;
}
/* Parse the field width. */
if (*cp == '*')
{
dp->width_start = cp;
cp++;
dp->width_end = cp;
if (max_width_length < 1)
max_width_length = 1;
/* Test for positional argument. */
if (*cp >= '0' && *cp <= '9')
{
const CHAR_T *np;
for (np = cp; *np >= '0' && *np <= '9'; np++)
;
if (*np == '$')
{
size_t n = 0;
for (np = cp; *np >= '0' && *np <= '9'; np++)
if (n < SIZE_MAX / 10)
n = 10 * n + (*np - '0');
else
/* n too large for memory. */
goto error;
if (n == 0)
/* Positional argument 0. */
goto error;
dp->width_arg_index = n - 1;
cp = np + 1;
}
}
if (dp->width_arg_index == ARG_NONE)
{
dp->width_arg_index = arg_posn++;
if (dp->width_arg_index == ARG_NONE)
/* arg_posn wrapped around. */
goto error;
}
REGISTER_ARG (dp->width_arg_index, TYPE_INT);
}
else if (*cp >= '0' && *cp <= '9')
{
size_t width_length;
dp->width_start = cp;
for (; *cp >= '0' && *cp <= '9'; cp++)
;
dp->width_end = cp;
width_length = dp->width_end - dp->width_start;
if (max_width_length < width_length)
max_width_length = width_length;
}
/* Parse the precision. */
if (*cp == '.')
{
cp++;
if (*cp == '*')
{
dp->precision_start = cp - 1;
cp++;
dp->precision_end = cp;
if (max_precision_length < 2)
max_precision_length = 2;
/* Test for positional argument. */
if (*cp >= '0' && *cp <= '9')
{
const CHAR_T *np;
for (np = cp; *np >= '0' && *np <= '9'; np++)
;
if (*np == '$')
{
size_t n = 0;
for (np = cp; *np >= '0' && *np <= '9'; np++)
if (n < SIZE_MAX / 10)
n = 10 * n + (*np - '0');
else
/* n too large for memory. */
goto error;
if (n == 0)
/* Positional argument 0. */
goto error;
dp->precision_arg_index = n - 1;
cp = np + 1;
}
}
if (dp->precision_arg_index == ARG_NONE)
{
dp->precision_arg_index = arg_posn++;
if (dp->precision_arg_index == ARG_NONE)
/* arg_posn wrapped around. */
goto error;
}
REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
}
else
{
size_t precision_length;
dp->precision_start = cp - 1;
for (; *cp >= '0' && *cp <= '9'; cp++)
;
dp->precision_end = cp;
precision_length = dp->precision_end - dp->precision_start;
if (max_precision_length < precision_length)
max_precision_length = precision_length;
}
}
{
arg_type type;
/* Parse argument type/size specifiers. */
{
int flags = 0;
for (;;)
{
if (*cp == 'h')
{
flags |= (1 << (flags & 1));
cp++;
}
else if (*cp == 'L')
{
flags |= 4;
cp++;
}
else if (*cp == 'l')
{
flags += 8;
cp++;
}
#ifdef HAVE_INTMAX_T
else if (*cp == 'j')
{
if (sizeof (intmax_t) > sizeof (long))
{
/* intmax_t = long long */
flags += 16;
}
else if (sizeof (intmax_t) > sizeof (int))
{
/* intmax_t = long */
flags += 8;
}
cp++;
}
#endif
else if (*cp == 'z' || *cp == 'Z')
{
/* 'z' is standardized in ISO C 99, but glibc uses 'Z'
because the warning facility in gcc-2.95.2 understands
only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */
if (sizeof (size_t) > sizeof (long))
{
/* size_t = long long */
flags += 16;
}
else if (sizeof (size_t) > sizeof (int))
{
/* size_t = long */
flags += 8;
}
cp++;
}
else if (*cp == 't')
{
if (sizeof (ptrdiff_t) > sizeof (long))
{
/* ptrdiff_t = long long */
flags += 16;
}
else if (sizeof (ptrdiff_t) > sizeof (int))
{
/* ptrdiff_t = long */
flags += 8;
}
cp++;
}
else
break;
}
/* Read the conversion character. */
c = *cp++;
switch (c)
{
case 'd': case 'i':
#ifdef HAVE_LONG_LONG
if (flags >= 16 || (flags & 4))
type = TYPE_LONGLONGINT;
else
#endif
if (flags >= 8)
type = TYPE_LONGINT;
else if (flags & 2)
type = TYPE_SCHAR;
else if (flags & 1)
type = TYPE_SHORT;
else
type = TYPE_INT;
break;
case 'o': case 'u': case 'x': case 'X':
#ifdef HAVE_LONG_LONG
if (flags >= 16 || (flags & 4))
type = TYPE_ULONGLONGINT;
else
#endif
if (flags >= 8)
type = TYPE_ULONGINT;
else if (flags & 2)
type = TYPE_UCHAR;
else if (flags & 1)
type = TYPE_USHORT;
else
type = TYPE_UINT;
break;
case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
case 'a': case 'A':
#ifdef HAVE_LONG_DOUBLE
if (flags >= 16 || (flags & 4))
type = TYPE_LONGDOUBLE;
else
#endif
type = TYPE_DOUBLE;
break;
case 'c':
if (flags >= 8)
#ifdef HAVE_WINT_T
type = TYPE_WIDE_CHAR;
#else
goto error;
#endif
else
type = TYPE_CHAR;
break;
#ifdef HAVE_WINT_T
case 'C':
type = TYPE_WIDE_CHAR;
c = 'c';
break;
#endif
case 's':
if (flags >= 8)
#ifdef HAVE_WCHAR_T
type = TYPE_WIDE_STRING;
#else
goto error;
#endif
else
type = TYPE_STRING;
break;
#ifdef HAVE_WCHAR_T
case 'S':
type = TYPE_WIDE_STRING;
c = 's';
break;
#endif
case 'p':
type = TYPE_POINTER;
break;
case 'n':
#ifdef HAVE_LONG_LONG
if (flags >= 16 || (flags & 4))
type = TYPE_COUNT_LONGLONGINT_POINTER;
else
#endif
if (flags >= 8)
type = TYPE_COUNT_LONGINT_POINTER;
else if (flags & 2)
type = TYPE_COUNT_SCHAR_POINTER;
else if (flags & 1)
type = TYPE_COUNT_SHORT_POINTER;
else
type = TYPE_COUNT_INT_POINTER;
break;
case '%':
type = TYPE_NONE;
break;
default:
/* Unknown conversion character. */
goto error;
}
}
if (type != TYPE_NONE)
{
dp->arg_index = arg_index;
if (dp->arg_index == ARG_NONE)
{
dp->arg_index = arg_posn++;
if (dp->arg_index == ARG_NONE)
/* arg_posn wrapped around. */
goto error;
}
REGISTER_ARG (dp->arg_index, type);
}
dp->conversion = c;
dp->dir_end = cp;
}
d->count++;
if (d->count >= d_allocated)
{
DIRECTIVE *memory;
if (SIZE_MAX / (2 * sizeof (DIRECTIVE)) < d_allocated)
/* Overflow, would lead to out of memory. */
goto error;
d_allocated *= 2;
memory = realloc (d->dir, d_allocated * sizeof (DIRECTIVE));
if (memory == NULL)
/* Out of memory. */
goto error;
d->dir = memory;
}
}
}
d->dir[d->count].dir_start = cp;
d->max_width_length = max_width_length;
d->max_precision_length = max_precision_length;
return 0;
error:
if (a->arg)
free (a->arg);
if (d->dir)
free (d->dir);
return -1;
}
#undef DIRECTIVES
#undef DIRECTIVE
#undef CHAR_T
#undef PRINTF_PARSE

918
lib/vasnprintf.c Normal file
View File

@@ -0,0 +1,918 @@
/* vsprintf with automatic memory allocation.
Copyright (C) 1999, 2002-2006 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. */
/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
This must come before <config.h> because <config.h> may include
<features.h>, and once <features.h> has been included, it's too late. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
#include <config.h>
#ifndef IN_LIBINTL
# include <alloca.h>
#endif
/* Specification. */
#if WIDE_CHAR_VERSION
# include "vasnwprintf.h"
#else
# include "vasnprintf.h"
#endif
#include <stdio.h> /* snprintf(), sprintf() */
#include <stdlib.h> /* abort(), malloc(), realloc(), free() */
#include <string.h> /* memcpy(), strlen() */
#include <errno.h> /* errno */
#include <limits.h> /* CHAR_BIT, INT_MAX */
#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
#if WIDE_CHAR_VERSION
# include "wprintf-parse.h"
#else
# include "printf-parse.h"
#endif
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
#ifndef EOVERFLOW
# define EOVERFLOW E2BIG
#endif
#ifdef HAVE_WCHAR_T
# ifdef HAVE_WCSLEN
# define local_wcslen wcslen
# else
/* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
a dependency towards this library, here is a local substitute.
Define this substitute only once, even if this file is included
twice in the same compilation unit. */
# ifndef local_wcslen_defined
# define local_wcslen_defined 1
static size_t
local_wcslen (const wchar_t *s)
{
const wchar_t *ptr;
for (ptr = s; *ptr != (wchar_t) 0; ptr++)
;
return ptr - s;
}
# endif
# endif
#endif
#if WIDE_CHAR_VERSION
# define VASNPRINTF vasnwprintf
# define CHAR_T wchar_t
# define DIRECTIVE wchar_t_directive
# define DIRECTIVES wchar_t_directives
# define PRINTF_PARSE wprintf_parse
# define USE_SNPRINTF 1
# if HAVE_DECL__SNWPRINTF
/* On Windows, the function swprintf() has a different signature than
on Unix; we use the _snwprintf() function instead. */
# define SNPRINTF _snwprintf
# else
/* Unix. */
# define SNPRINTF swprintf
# endif
#else
# define VASNPRINTF vasnprintf
# define CHAR_T char
# define DIRECTIVE char_directive
# define DIRECTIVES char_directives
# define PRINTF_PARSE printf_parse
# define USE_SNPRINTF (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF)
# if HAVE_DECL__SNPRINTF
/* Windows. */
# define SNPRINTF _snprintf
# else
/* Unix. */
# define SNPRINTF snprintf
# endif
#endif
CHAR_T *
VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args)
{
DIRECTIVES d;
arguments a;
if (PRINTF_PARSE (format, &d, &a) < 0)
{
errno = EINVAL;
return NULL;
}
#define CLEANUP() \
free (d.dir); \
if (a.arg) \
free (a.arg);
if (printf_fetchargs (args, &a) < 0)
{
CLEANUP ();
errno = EINVAL;
return NULL;
}
{
size_t buf_neededlength;
CHAR_T *buf;
CHAR_T *buf_malloced;
const CHAR_T *cp;
size_t i;
DIRECTIVE *dp;
/* Output string accumulator. */
CHAR_T *result;
size_t allocated;
size_t length;
/* Allocate a small buffer that will hold a directive passed to
sprintf or snprintf. */
buf_neededlength = 7 + d.max_width_length + d.max_precision_length + 6;
#if HAVE_ALLOCA
if (buf_neededlength < 4000 / sizeof (CHAR_T))
{
buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
buf_malloced = NULL;
}
else
#endif
{
if (SIZE_MAX / sizeof (CHAR_T) < buf_neededlength)
goto out_of_memory_1;
buf = (CHAR_T *) malloc (buf_neededlength * sizeof (CHAR_T));
if (buf == NULL)
goto out_of_memory_1;
buf_malloced = buf;
}
if (resultbuf != NULL)
{
result = resultbuf;
allocated = *lengthp;
}
else
{
result = NULL;
allocated = 0;
}
length = 0;
/* Invariants:
result is either == resultbuf or == NULL or malloc-allocated.
If length > 0, then result != NULL. */
/* Ensures that allocated >= length + extra. Aborts through a jump to
out_of_memory if size is too big. */
#define ENSURE_ALLOCATION(extra) \
{ \
size_t needed = length + (extra); \
if (needed < length) \
goto out_of_memory; \
if (needed > allocated) \
{ \
size_t memory_size; \
CHAR_T *memory; \
\
allocated = (allocated > 0 ? 2 * allocated : 12); \
if (needed > allocated) \
allocated = needed; \
if (SIZE_MAX / sizeof (CHAR_T) < allocated) \
goto out_of_memory; \
memory_size = allocated * sizeof (CHAR_T); \
if (result == resultbuf || result == NULL) \
memory = (CHAR_T *) malloc (memory_size); \
else \
memory = (CHAR_T *) realloc (result, memory_size); \
if (memory == NULL) \
goto out_of_memory; \
if (result == resultbuf && length > 0) \
memcpy (memory, result, length * sizeof (CHAR_T)); \
result = memory; \
} \
}
for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
{
if (cp != dp->dir_start)
{
size_t n = dp->dir_start - cp;
ENSURE_ALLOCATION (n);
memcpy (result + length, cp, n * sizeof (CHAR_T));
length += n;
}
if (i == d.count)
break;
/* Execute a single directive. */
if (dp->conversion == '%')
{
if (!(dp->arg_index == ARG_NONE))
abort ();
ENSURE_ALLOCATION (1);
result[length] = '%';
length += 1;
}
else
{
if (!(dp->arg_index != ARG_NONE))
abort ();
if (dp->conversion == 'n')
{
switch (a.arg[dp->arg_index].type)
{
case TYPE_COUNT_SCHAR_POINTER:
*a.arg[dp->arg_index].a.a_count_schar_pointer = length;
break;
case TYPE_COUNT_SHORT_POINTER:
*a.arg[dp->arg_index].a.a_count_short_pointer = length;
break;
case TYPE_COUNT_INT_POINTER:
*a.arg[dp->arg_index].a.a_count_int_pointer = length;
break;
case TYPE_COUNT_LONGINT_POINTER:
*a.arg[dp->arg_index].a.a_count_longint_pointer = length;
break;
#ifdef HAVE_LONG_LONG
case TYPE_COUNT_LONGLONGINT_POINTER:
*a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
break;
#endif
default:
abort ();
}
}
else
{
arg_type type = a.arg[dp->arg_index].type;
CHAR_T *p;
unsigned int prefix_count;
int prefixes[2];
#if !USE_SNPRINTF
size_t tmp_length;
CHAR_T tmpbuf[700];
CHAR_T *tmp;
/* Allocate a temporary buffer of sufficient size for calling
sprintf. */
{
size_t width;
size_t precision;
width = 0;
if (dp->width_start != dp->width_end)
{
if (dp->width_arg_index != ARG_NONE)
{
int arg;
if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
abort ();
arg = a.arg[dp->width_arg_index].a.a_int;
width = (arg < 0 ? (unsigned int) (-arg) : arg);
}
else
{
const CHAR_T *digitp = dp->width_start;
do
{
size_t w_tmp = width * 10 + (*digitp++ - '0');
if (SIZE_MAX / 10 < width || w_tmp < width)
goto out_of_memory;
width = w_tmp;
}
while (digitp != dp->width_end);
}
}
precision = 6;
if (dp->precision_start != dp->precision_end)
{
if (dp->precision_arg_index != ARG_NONE)
{
int arg;
if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
abort ();
arg = a.arg[dp->precision_arg_index].a.a_int;
precision = (arg < 0 ? 0 : arg);
}
else
{
const CHAR_T *digitp = dp->precision_start + 1;
precision = 0;
while (digitp != dp->precision_end)
{
size_t p1 = 10 * precision + (*digitp++ - '0');
precision = ((SIZE_MAX / 10 < precision
|| p1 < precision)
? SIZE_MAX : p1);
}
}
}
switch (dp->conversion)
{
case 'd': case 'i': case 'u':
# ifdef HAVE_LONG_LONG
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Multiply by 2, as an estimate for FLAG_GROUP. */
/* Add 1, to account for a leading sign. */
tmp_length = (tmp_length < SIZE_MAX / 2
? 2 * tmp_length + 1
: SIZE_MAX);
break;
case 'o':
# ifdef HAVE_LONG_LONG
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Add 1, to account for a leading sign. */
tmp_length += (tmp_length < SIZE_MAX);
break;
case 'x': case 'X':
# ifdef HAVE_LONG_LONG
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Add 2, to account for a leading sign or alternate form. */
if (tmp_length <= SIZE_MAX / 2)
tmp_length *= 2;
break;
case 'f': case 'F':
# ifdef HAVE_LONG_DOUBLE
if (type == TYPE_LONGDOUBLE)
tmp_length =
(unsigned int) (LDBL_MAX_EXP
* 0.30103 /* binary -> decimal */
* 2 /* estimate for FLAG_GROUP */
)
+ 1 /* turn floor into ceil */
+ 10; /* sign, decimal point etc. */
else
# endif
tmp_length =
(unsigned int) (DBL_MAX_EXP
* 0.30103 /* binary -> decimal */
* 2 /* estimate for FLAG_GROUP */
)
+ 1 /* turn floor into ceil */
+ 10; /* sign, decimal point etc. */
tmp_length += precision;
if (tmp_length < precision)
goto out_of_memory;
break;
case 'e': case 'E': case 'g': case 'G':
case 'a': case 'A':
tmp_length =
12; /* sign, decimal point, exponent etc. */
tmp_length += precision;
if (tmp_length < precision)
goto out_of_memory;
break;
case 'c':
# if defined HAVE_WINT_T && !WIDE_CHAR_VERSION
if (type == TYPE_WIDE_CHAR)
tmp_length = MB_CUR_MAX;
else
# endif
tmp_length = 1;
break;
case 's':
# ifdef HAVE_WCHAR_T
if (type == TYPE_WIDE_STRING)
{
tmp_length =
local_wcslen (a.arg[dp->arg_index].a.a_wide_string);
# if !WIDE_CHAR_VERSION
if (SIZE_MAX / MB_CUR_MAX < tmp_length)
goto out_of_memory;
tmp_length *= MB_CUR_MAX;
# endif
}
else
# endif
tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
break;
case 'p':
tmp_length =
(unsigned int) (sizeof (void *) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1 /* turn floor into ceil */
+ 2; /* account for leading 0x */
break;
default:
abort ();
}
if (tmp_length < width)
tmp_length = width;
tmp_length++; /* account for trailing NUL */
if (!tmp_length)
goto out_of_memory;
}
if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
tmp = tmpbuf;
else
{
if (SIZE_MAX / sizeof (CHAR_T) < tmp_length)
/* Overflow, would lead to out of memory. */
goto out_of_memory;
tmp = (CHAR_T *) malloc (tmp_length * sizeof (CHAR_T));
if (tmp == NULL)
/* Out of memory. */
goto out_of_memory;
}
#endif
/* Construct the format string for calling snprintf or
sprintf. */
p = buf;
*p++ = '%';
if (dp->flags & FLAG_GROUP)
*p++ = '\'';
if (dp->flags & FLAG_LEFT)
*p++ = '-';
if (dp->flags & FLAG_SHOWSIGN)
*p++ = '+';
if (dp->flags & FLAG_SPACE)
*p++ = ' ';
if (dp->flags & FLAG_ALT)
*p++ = '#';
if (dp->flags & FLAG_ZERO)
*p++ = '0';
if (dp->width_start != dp->width_end)
{
size_t n = dp->width_end - dp->width_start;
memcpy (p, dp->width_start, n * sizeof (CHAR_T));
p += n;
}
if (dp->precision_start != dp->precision_end)
{
size_t n = dp->precision_end - dp->precision_start;
memcpy (p, dp->precision_start, n * sizeof (CHAR_T));
p += n;
}
switch (type)
{
#ifdef HAVE_LONG_LONG
case TYPE_LONGLONGINT:
case TYPE_ULONGLONGINT:
*p++ = 'l';
/*FALLTHROUGH*/
#endif
case TYPE_LONGINT:
case TYPE_ULONGINT:
#ifdef HAVE_WINT_T
case TYPE_WIDE_CHAR:
#endif
#ifdef HAVE_WCHAR_T
case TYPE_WIDE_STRING:
#endif
*p++ = 'l';
break;
#ifdef HAVE_LONG_DOUBLE
case TYPE_LONGDOUBLE:
*p++ = 'L';
break;
#endif
default:
break;
}
*p = dp->conversion;
#if USE_SNPRINTF
p[1] = '%';
p[2] = 'n';
p[3] = '\0';
#else
p[1] = '\0';
#endif
/* Construct the arguments for calling snprintf or sprintf. */
prefix_count = 0;
if (dp->width_arg_index != ARG_NONE)
{
if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
abort ();
prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
}
if (dp->precision_arg_index != ARG_NONE)
{
if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
abort ();
prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
}
#if USE_SNPRINTF
/* Prepare checking whether snprintf returns the count
via %n. */
ENSURE_ALLOCATION (1);
result[length] = '\0';
#endif
for (;;)
{
size_t maxlen;
int count;
int retcount;
maxlen = allocated - length;
count = -1;
retcount = 0;
#if USE_SNPRINTF
# define SNPRINTF_BUF(arg) \
switch (prefix_count) \
{ \
case 0: \
retcount = SNPRINTF (result + length, maxlen, buf, \
arg, &count); \
break; \
case 1: \
retcount = SNPRINTF (result + length, maxlen, buf, \
prefixes[0], arg, &count); \
break; \
case 2: \
retcount = SNPRINTF (result + length, maxlen, buf, \
prefixes[0], prefixes[1], arg, \
&count); \
break; \
default: \
abort (); \
}
#else
# define SNPRINTF_BUF(arg) \
switch (prefix_count) \
{ \
case 0: \
count = sprintf (tmp, buf, arg); \
break; \
case 1: \
count = sprintf (tmp, buf, prefixes[0], arg); \
break; \
case 2: \
count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
arg); \
break; \
default: \
abort (); \
}
#endif
switch (type)
{
case TYPE_SCHAR:
{
int arg = a.arg[dp->arg_index].a.a_schar;
SNPRINTF_BUF (arg);
}
break;
case TYPE_UCHAR:
{
unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
SNPRINTF_BUF (arg);
}
break;
case TYPE_SHORT:
{
int arg = a.arg[dp->arg_index].a.a_short;
SNPRINTF_BUF (arg);
}
break;
case TYPE_USHORT:
{
unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
SNPRINTF_BUF (arg);
}
break;
case TYPE_INT:
{
int arg = a.arg[dp->arg_index].a.a_int;
SNPRINTF_BUF (arg);
}
break;
case TYPE_UINT:
{
unsigned int arg = a.arg[dp->arg_index].a.a_uint;
SNPRINTF_BUF (arg);
}
break;
case TYPE_LONGINT:
{
long int arg = a.arg[dp->arg_index].a.a_longint;
SNPRINTF_BUF (arg);
}
break;
case TYPE_ULONGINT:
{
unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
SNPRINTF_BUF (arg);
}
break;
#ifdef HAVE_LONG_LONG
case TYPE_LONGLONGINT:
{
long long int arg = a.arg[dp->arg_index].a.a_longlongint;
SNPRINTF_BUF (arg);
}
break;
case TYPE_ULONGLONGINT:
{
unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
SNPRINTF_BUF (arg);
}
break;
#endif
case TYPE_DOUBLE:
{
double arg = a.arg[dp->arg_index].a.a_double;
SNPRINTF_BUF (arg);
}
break;
#ifdef HAVE_LONG_DOUBLE
case TYPE_LONGDOUBLE:
{
long double arg = a.arg[dp->arg_index].a.a_longdouble;
SNPRINTF_BUF (arg);
}
break;
#endif
case TYPE_CHAR:
{
int arg = a.arg[dp->arg_index].a.a_char;
SNPRINTF_BUF (arg);
}
break;
#ifdef HAVE_WINT_T
case TYPE_WIDE_CHAR:
{
wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
SNPRINTF_BUF (arg);
}
break;
#endif
case TYPE_STRING:
{
const char *arg = a.arg[dp->arg_index].a.a_string;
SNPRINTF_BUF (arg);
}
break;
#ifdef HAVE_WCHAR_T
case TYPE_WIDE_STRING:
{
const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
SNPRINTF_BUF (arg);
}
break;
#endif
case TYPE_POINTER:
{
void *arg = a.arg[dp->arg_index].a.a_pointer;
SNPRINTF_BUF (arg);
}
break;
default:
abort ();
}
#if USE_SNPRINTF
/* Portability: Not all implementations of snprintf()
are ISO C 99 compliant. Determine the number of
bytes that snprintf() has produced or would have
produced. */
if (count >= 0)
{
/* Verify that snprintf() has NUL-terminated its
result. */
if (count < maxlen && result[length + count] != '\0')
abort ();
/* Portability hack. */
if (retcount > count)
count = retcount;
}
else
{
/* snprintf() doesn't understand the '%n'
directive. */
if (p[1] != '\0')
{
/* Don't use the '%n' directive; instead, look
at the snprintf() return value. */
p[1] = '\0';
continue;
}
else
{
/* Look at the snprintf() return value. */
if (retcount < 0)
{
/* HP-UX 10.20 snprintf() is doubly deficient:
It doesn't understand the '%n' directive,
*and* it returns -1 (rather than the length
that would have been required) when the
buffer is too small. */
size_t bigger_need =
(allocated > 12 ? allocated : 12);
ENSURE_ALLOCATION (bigger_need);
continue;
}
else
count = retcount;
}
}
#endif
/* Attempt to handle failure. */
if (count < 0)
{
if (!(result == resultbuf || result == NULL))
free (result);
if (buf_malloced != NULL)
free (buf_malloced);
CLEANUP ();
errno = EINVAL;
return NULL;
}
#if !USE_SNPRINTF
if (count >= tmp_length)
/* tmp_length was incorrectly calculated - fix the
code above! */
abort ();
#endif
/* Make room for the result. */
if (count >= maxlen)
{
/* Need at least count bytes. But allocate
proportionally, to avoid looping eternally if
snprintf() reports a too small count. */
ENSURE_ALLOCATION (count < allocated
? allocated : count);
#if USE_SNPRINTF
continue;
#endif
}
#if USE_SNPRINTF
/* The snprintf() result did fit. */
#else
/* Append the sprintf() result. */
memcpy (result + length, tmp, count * sizeof (CHAR_T));
if (tmp != tmpbuf)
free (tmp);
#endif
length += count;
break;
}
}
}
}
/* Add the final NUL. */
ENSURE_ALLOCATION (1);
result[length] = '\0';
if (result != resultbuf && length + 1 < allocated)
{
/* Shrink the allocated memory if possible. */
CHAR_T *memory;
memory = (CHAR_T *) realloc (result, (length + 1) * sizeof (CHAR_T));
if (memory != NULL)
result = memory;
}
if (buf_malloced != NULL)
free (buf_malloced);
CLEANUP ();
*lengthp = length;
if (length > INT_MAX)
goto length_overflow;
return result;
length_overflow:
/* We could produce such a big string, but its length doesn't fit into
an 'int'. POSIX says that snprintf() fails with errno = EOVERFLOW in
this case. */
if (result != resultbuf)
free (result);
errno = EOVERFLOW;
return NULL;
out_of_memory:
if (!(result == resultbuf || result == NULL))
free (result);
if (buf_malloced != NULL)
free (buf_malloced);
out_of_memory_1:
CLEANUP ();
errno = ENOMEM;
return NULL;
}
}
#undef SNPRINTF
#undef USE_SNPRINTF
#undef PRINTF_PARSE
#undef DIRECTIVES
#undef DIRECTIVE
#undef CHAR_T
#undef VASNPRINTF

View File

@@ -1,3 +0,0 @@
Makefile
Makefile.in
*.m4

View File

@@ -1,21 +0,0 @@
index.html
*.po
LINGUAS
Makefile.in.in
Makevars
Makevars.template
Rules-quot
boldquot.sed
en@boldquot.header
en@quot.header
insert-header.sin
quot.sed
remove-potcdate.sin
Makefile.in
POTFILES
Makefile
tar.pot
remove-potcdate.sed
*.gmo
*.mo
stamp-po

View File

@@ -46,7 +46,6 @@ src/delete.c
src/extract.c
src/incremen.c
src/list.c
src/mangle.c
src/misc.c
src/names.c
src/tar.c

View File

@@ -1,7 +1,7 @@
# Makefile for GNU tar sources.
# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003 Free
# Software Foundation, Inc.
# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2006
# 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
@@ -30,7 +30,6 @@ tar_SOURCES = \
xheader.c\
incremen.c\
list.c\
mangle.c\
misc.c\
names.c\
sparse.c\
@@ -40,9 +39,7 @@ tar_SOURCES = \
update.c\
utf8.c
INCLUDES = -I$(top_srcdir)/lib -I../ -I../lib
tar.o: ../lib/localedir.h
INCLUDES = -I$(top_srcdir)/lib -I../ -I../lib
LDADD = ../lib/libtar.a $(LIBINTL) $(LIBICONV)

View File

@@ -254,7 +254,7 @@ GLOBAL bool show_omitted_dirs_option;
GLOBAL bool sparse_option;
GLOBAL unsigned tar_sparse_major;
GLOBAL unsigned tar_sparse_minor;
GLOBAL bool starting_file_option;
/* Specified maximum byte length of each tape volume (multiple of 1024). */
@@ -296,7 +296,7 @@ GLOBAL int archive;
/* Nonzero when outputting to /dev/null. */
GLOBAL bool dev_null_output;
/* Timestamps: */
/* Timestamps: */
GLOBAL struct timespec start_time; /* when we started execution */
GLOBAL struct timespec volume_start_time; /* when the current volume was
opened*/
@@ -546,10 +546,6 @@ enum read_header tar_checksum (union block *header, bool silent);
void skip_file (off_t size);
void skip_member (void);
/* Module mangle.c. */
void extract_mangle (void);
/* Module misc.c. */
void assign_string (char **dest, const char *src);
@@ -727,5 +723,3 @@ bool utf8_convert (bool to_utf, char const *input, char **output);
void set_transform_expr (const char *expr);
bool transform_name (char **pinput);
bool transform_name_fp (char **pinput, char *(*fun)(char *));

View File

@@ -33,6 +33,65 @@ struct link
size_t nlink;
char name[1];
};
struct exclude_tag
{
const char *name;
size_t length;
struct exclude_tag *next;
};
static struct exclude_tag *exclude_tags;
void
add_exclude_tag (const char *name)
{
struct exclude_tag *tag = xmalloc (sizeof tag[0]);
tag->next = exclude_tags;
tag->name = name;
tag->length = strlen (name);
exclude_tags = tag;
}
static bool
check_exclude_tags (char *dirname)
{
static char *tagname;
static size_t tagsize;
struct exclude_tag *tag;
size_t dlen = strlen (dirname);
char *nptr = NULL;
char *ret = NULL;
for (tag = exclude_tags; tag; tag = tag->next)
{
size_t size = dlen + tag->length + 1;
if (size > tagsize)
{
tagsize = size;
tagname = xrealloc (tagname, tagsize);
}
if (!nptr)
{
strcpy (tagname, dirname);
nptr = tagname + dlen;
}
strcpy (nptr, tag->name);
if (access (tagname, F_OK) == 0)
{
if (verbose_option)
WARN ((0, 0,
_("%s: contains a cache directory tag %s; not dumped"),
quotearg_colon (dirname),
quotearg_n (1, tag->name)));
return true;
}
}
return false;
}
/* The maximum uintmax_t value that can be represented with DIGITS digits,
assuming that each digit is BITS_PER_DIGIT wide. */
@@ -742,7 +801,7 @@ start_header (struct tar_stat_info *st)
{
if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec
|| mtime.tv_nsec != 0)
xheader_store ("mtime", st, NULL);
xheader_store ("mtime", st, &mtime);
if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec)
mtime.tv_sec = 0;
}
@@ -983,6 +1042,7 @@ dump_regular_file (int fd, struct tar_stat_info *st)
return dump_status_ok;
}
/* Look in directory DIRNAME for a cache directory tag file
with the magic name "CACHEDIR.TAG" and a standard header,
as described at:
@@ -1000,7 +1060,7 @@ check_cache_directory (char *dirname)
static char tagname[] = "CACHEDIR.TAG";
char *tagpath;
int fd;
int tag_present = false;
bool tag_present = false;
tagpath = xmalloc (strlen (dirname) + strlen (tagname) + 1);
strcpy (tagpath, dirname);
@@ -1113,17 +1173,7 @@ dump_dir0 (char *directory,
quotearg_colon (st->orig_file_name)));
return;
}
if (exclude_caches_option
&& check_cache_directory(st->orig_file_name))
{
if (verbose_option)
WARN ((0, 0,
_("%s: contains a cache directory tag; not dumped"),
quotearg_colon (st->orig_file_name)));
return;
}
{
char const *entry;
size_t entry_len;
@@ -1174,9 +1224,6 @@ dump_dir (int fd, struct tar_stat_info *st, int top_level, dev_t parent_device)
return false;
}
ensure_slash (&st->orig_file_name);
ensure_slash (&st->file_name);
dump_dir0 (directory, st, top_level, parent_device);
free (directory);
@@ -1497,6 +1544,22 @@ dump_file0 (struct tar_stat_info *st, const char *p,
if (is_dir)
{
ensure_slash (&st->orig_file_name);
ensure_slash (&st->file_name);
if (exclude_caches_option
&& check_cache_directory (st->orig_file_name))
{
if (verbose_option)
WARN ((0, 0,
_("%s: contains a cache directory tag; not dumped"),
quotearg_colon (st->orig_file_name)));
return;
}
if (check_exclude_tags (st->orig_file_name))
return;
ok = dump_dir (fd, st, top_level, parent_device);
/* dump_dir consumes FD if successful. */

View File

@@ -37,7 +37,8 @@ enum permstatus
/* This file may have existed already; its permissions are unknown. */
UNKNOWN_PERMSTATUS,
/* This file was created using the permissions from the archive. */
/* This file was created using the permissions from the archive,
except with S_IRWXG | S_IRWXO masked out if 0 < same_owner_option. */
ARCHIVED_PERMSTATUS,
/* This is an intermediate directory; the archive did not specify
@@ -149,12 +150,15 @@ set_mode (char const *file_name,
{
mode = stat_info->st_mode;
/* If we created the file and it has a usual mode, then its mode
is normally set correctly already. But on many hosts, some
/* If we created the file and it has a mode that we set already
with O_CREAT, then its mode is often set correctly already.
But if we are changing ownership, the mode's group and and
other permission bits were omitted originally, so it's less
likely that the mode is OK now. Also, on many hosts, some
directories inherit the setgid bits from their parents, so we
we must set directories' modes explicitly. */
if (permstatus == ARCHIVED_PERMSTATUS
&& ! (mode & ~ MODE_RWX)
if ((permstatus == ARCHIVED_PERMSTATUS
&& ! (mode & ~ (0 < same_owner_option ? S_IRWXU : MODE_RWX)))
&& typeflag != DIRTYPE
&& typeflag != GNUTYPE_DUMPDIR)
return;
@@ -217,7 +221,7 @@ check_time (char const *file_name, struct timespec t)
/* Restore stat attributes (owner, group, mode and times) for
FILE_NAME, using information given in *ST.
If CUR_INFO is nonzero, *CUR_INFO is the
file's currernt status.
file's current status.
If not restoring permissions, invert the
INVERT_PERMISSIONS bits from the file's current permissions.
PERMSTATUS specifies the status of the file's permissions.
@@ -265,11 +269,11 @@ set_stat (char const *file_name,
}
/* Some systems allow non-root users to give files away. Once this
done, it is not possible anymore to change file permissions, so we
have to set permissions prior to possibly giving files away. */
set_mode (file_name, &st->stat, cur_info,
invert_permissions, permstatus, typeflag);
done, it is not possible anymore to change file permissions.
However, setting file permissions now would be incorrect, since
they would apply to the wrong user, and there would be a race
condition. So, don't use systems that allow non-root users to
give files away. */
}
if (0 < same_owner_option && permstatus != INTERDIR_PERMSTATUS)
@@ -278,29 +282,36 @@ set_stat (char const *file_name,
the symbolic link itself. In this case, a mere chown would change
the attributes of the file the symbolic link is pointing to, and
should be avoided. */
int chown_result = 1;
if (typeflag == SYMTYPE)
{
#if HAVE_LCHOWN
if (lchown (file_name, st->stat.st_uid, st->stat.st_gid) < 0)
chown_error_details (file_name,
st->stat.st_uid, st->stat.st_gid);
chown_result = lchown (file_name, st->stat.st_uid, st->stat.st_gid);
#endif
}
else
{
if (chown (file_name, st->stat.st_uid, st->stat.st_gid) < 0)
chown_error_details (file_name,
st->stat.st_uid, st->stat.st_gid);
/* On a few systems, and in particular, those allowing to give files
away, changing the owner or group destroys the suid or sgid bits.
So let's attempt setting these bits once more. */
if (st->stat.st_mode & (S_ISUID | S_ISGID | S_ISVTX))
set_mode (file_name, &st->stat, 0,
invert_permissions, permstatus, typeflag);
chown_result = chown (file_name, st->stat.st_uid, st->stat.st_gid);
}
if (chown_result == 0)
{
/* Changing the owner can flip st_mode bits in some cases, so
ignore cur_info if it might be obsolete now. */
if (cur_info
&& cur_info->st_mode & S_IXUGO
&& cur_info->st_mode & (S_ISUID | S_ISGID))
cur_info = NULL;
}
else if (chown_result < 0)
chown_error_details (file_name,
st->stat.st_uid, st->stat.st_gid);
}
if (typeflag != SYMTYPE)
set_mode (file_name, &st->stat, cur_info,
invert_permissions, permstatus, typeflag);
}
/* Remember to restore stat attributes (owner, group, mode and times)
@@ -374,7 +385,8 @@ repair_delayed_set_stat (char const *dir,
data->atime = current_stat_info.atime;
data->mtime = current_stat_info.mtime;
data->invert_permissions =
(MODE_RWX & (current_stat_info.stat.st_mode ^ st.st_mode));
((current_stat_info.stat.st_mode ^ st.st_mode)
& MODE_RWX & ~ current_umask);
data->permstatus = ARCHIVED_PERMSTATUS;
return;
}
@@ -626,8 +638,9 @@ extract_dir (char *file_name, int typeflag)
else if (typeflag == GNUTYPE_DUMPDIR)
skip_member ();
mode = (current_stat_info.stat.st_mode |
(we_are_root ? 0 : MODE_WXUSR)) & MODE_RWX;
mode = current_stat_info.stat.st_mode | (we_are_root ? 0 : MODE_WXUSR);
if (0 < same_owner_option || current_stat_info.stat.st_mode & ~ MODE_RWX)
mode &= S_IRWXU;
while ((status = mkdir (file_name, mode)))
{
@@ -670,7 +683,8 @@ extract_dir (char *file_name, int typeflag)
{
if (status == 0)
delay_set_stat (file_name, &current_stat_info,
MODE_RWX & (mode ^ current_stat_info.stat.st_mode),
((mode ^ current_stat_info.stat.st_mode)
& MODE_RWX & ~ current_umask),
ARCHIVED_PERMSTATUS);
else /* For an already existing directory, invert_perms must be 0 */
delay_set_stat (file_name, &current_stat_info,
@@ -682,14 +696,13 @@ extract_dir (char *file_name, int typeflag)
static int
open_output_file (char *file_name, int typeflag)
open_output_file (char *file_name, int typeflag, mode_t mode)
{
int fd;
int openflag = (O_WRONLY | O_BINARY | O_CREAT
| (old_files_option == OVERWRITE_OLD_FILES
? O_TRUNC
: O_EXCL));
mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask;
#if O_CTG
/* Contiguous files (on the Masscomp) have to specify the size in
@@ -728,6 +741,9 @@ extract_file (char *file_name, int typeflag)
size_t count;
size_t written;
int interdir_made = 0;
mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask;
mode_t invert_permissions =
0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0;
/* FIXME: deal with protection issues. */
@@ -745,11 +761,12 @@ extract_file (char *file_name, int typeflag)
else
{
do
fd = open_output_file (file_name, typeflag);
fd = open_output_file (file_name, typeflag, mode ^ invert_permissions);
while (fd < 0 && maybe_recoverable (file_name, &interdir_made));
if (fd < 0)
{
skip_member ();
open_error (file_name);
return 1;
}
@@ -810,7 +827,7 @@ extract_file (char *file_name, int typeflag)
if (to_command_option)
sys_wait_command ();
else
set_stat (file_name, &current_stat_info, NULL, 0,
set_stat (file_name, &current_stat_info, NULL, invert_permissions,
(old_files_option == OVERWRITE_OLD_FILES ?
UNKNOWN_PERMSTATUS : ARCHIVED_PERMSTATUS),
typeflag);
@@ -871,7 +888,7 @@ create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made)
if (h && ! h->after_links
&& strncmp (file_name, h->file_name, h->file_name_len) == 0
&& ISSLASH (file_name[h->file_name_len])
&& (base_name (file_name) == file_name + h->file_name_len + 1))
&& (last_component (file_name) == file_name + h->file_name_len + 1))
{
do
{
@@ -988,16 +1005,19 @@ extract_node (char *file_name, int typeflag)
{
int status;
int interdir_made = 0;
mode_t mode = current_stat_info.stat.st_mode & ~ current_umask;
mode_t invert_permissions =
0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0;
do
status = mknod (file_name, current_stat_info.stat.st_mode,
status = mknod (file_name, mode ^ invert_permissions,
current_stat_info.stat.st_rdev);
while (status && maybe_recoverable (file_name, &interdir_made));
if (status != 0)
mknod_error (file_name);
else
set_stat (file_name, &current_stat_info, NULL, 0,
set_stat (file_name, &current_stat_info, NULL, invert_permissions,
ARCHIVED_PERMSTATUS, typeflag);
return status;
}
@@ -1009,13 +1029,16 @@ extract_fifo (char *file_name, int typeflag)
{
int status;
int interdir_made = 0;
mode_t mode = current_stat_info.stat.st_mode & ~ current_umask;
mode_t invert_permissions =
0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0;
while ((status = mkfifo (file_name, current_stat_info.stat.st_mode)))
while ((status = mkfifo (file_name, mode)) != 0)
if (!maybe_recoverable (file_name, &interdir_made))
break;
if (status == 0)
set_stat (file_name, &current_stat_info, NULL, 0,
set_stat (file_name, &current_stat_info, NULL, invert_permissions,
ARCHIVED_PERMSTATUS, typeflag);
else
mkfifo_error (file_name);
@@ -1023,13 +1046,6 @@ extract_fifo (char *file_name, int typeflag)
}
#endif
static int
extract_mangle_wrapper (char *file_name, int typeflag)
{
extract_mangle ();
return 0;
}
static int
extract_volhdr (char *file_name, int typeflag)
{
@@ -1121,10 +1137,6 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
*fun = extract_volhdr;
break;
case GNUTYPE_NAMES:
*fun = extract_mangle_wrapper;
break;
case GNUTYPE_MULTIVOL:
ERROR ((0, 0,
_("%s: Cannot extract -- file is continued from another volume"),
@@ -1331,10 +1343,10 @@ rename_directory (char *src, char *dst)
e = errno;
}
break;
case EXDEV:
/* FIXME: Fall back to recursive copying */
default:
break;
}
@@ -1346,7 +1358,7 @@ rename_directory (char *src, char *dst)
}
return true;
}
void
fatal_exit (void)
{

View File

@@ -107,7 +107,6 @@ read_and (void (*do_something) (void))
{
case GNUTYPE_VOLHDR:
case GNUTYPE_MULTIVOL:
case GNUTYPE_NAMES:
break;
case DIRTYPE:
@@ -1047,10 +1046,6 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
modes[0] = 'M';
break;
case GNUTYPE_NAMES:
modes[0] = 'N';
break;
case GNUTYPE_LONGNAME:
case GNUTYPE_LONGLINK:
modes[0] = 'L';
@@ -1234,10 +1229,6 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
uintbuf));
fprintf (stdlis, _("--Continued at byte %s--\n"), size);
break;
case GNUTYPE_NAMES:
fprintf (stdlis, _("--Mangled file names--\n"));
break;
}
}
fflush (stdlis);

View File

@@ -1,121 +0,0 @@
/* Encode long filenames for GNU tar.
Copyright 1988, 92, 94, 96, 97, 99, 2000 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. */
#include <system.h>
#include "common.h"
#include <quotearg.h>
struct mangled
{
struct mangled *next;
int type;
char mangled[NAME_FIELD_SIZE];
char *linked_to;
char normal[1];
};
/* Extract a GNUTYPE_NAMES record contents. It seems that such are
not produced anymore by GNU tar, but we leave the reading code
around nevertheless, for salvaging old tapes. */
void
extract_mangle (void)
{
off_t size = current_stat_info.stat.st_size;
char *buffer = xmalloc ((size_t) (size + 1));
char *copy = buffer;
char *cursor = buffer;
if (size != (size_t) size || size == (size_t) -1)
xalloc_die ();
buffer[size] = '\0';
while (size > 0)
{
union block *block = find_next_block ();
size_t available;
if (!block)
{
ERROR ((0, 0, _("Unexpected EOF in mangled names")));
return;
}
available = available_space_after (block);
if (available > size)
available = size;
memcpy (copy, block->buffer, available);
copy += available;
size -= available;
set_next_block_after ((union block *) (block->buffer + available - 1));
}
while (*cursor)
{
char *next_cursor;
char *name;
char *name_end;
next_cursor = strchr (cursor, '\n');
*next_cursor++ = '\0';
if (!strncmp (cursor, "Rename ", 7))
{
name = cursor + 7;
name_end = strchr (name, ' ');
while (strncmp (name_end, " to ", 4))
{
name_end++;
name_end = strchr (name_end, ' ');
}
*name_end = '\0';
if (next_cursor[-2] == '/')
next_cursor[-2] = '\0';
unquote_string (name_end + 4);
if (rename (name, name_end + 4))
ERROR ((0, errno, _("%s: Cannot rename to %s"),
quotearg_colon (name), quote_n (1, name_end + 4)));
else if (verbose_option)
WARN ((0, 0, _("Renamed %s to %s"), name, name_end + 4));
}
#ifdef HAVE_SYMLINK
else if (!strncmp (cursor, "Symlink ", 8))
{
name = cursor + 8;
name_end = strchr (name, ' ');
while (strncmp (name_end, " to ", 4))
{
name_end++;
name_end = strchr (name_end, ' ');
}
*name_end = '\0';
unquote_string (name);
unquote_string (name_end + 4);
if (symlink (name, name_end + 4)
&& (unlink (name_end + 4) || symlink (name, name_end + 4)))
ERROR ((0, errno, _("%s: Cannot symlink to %s"),
quotearg_colon (name), quote_n (1, name_end + 4)));
else if (verbose_option)
WARN ((0, 0, _("Symlinked %s to %s"), name, name_end + 4));
}
#endif
else
ERROR ((0, 0, _("Unknown demangling command %s"), cursor));
cursor = next_cursor;
}
}

View File

@@ -41,10 +41,11 @@
#include <argmatch.h>
#include <closeout.h>
#include <configmake.h>
#include <exitfail.h>
#include <getdate.h>
#include <localedir.h>
#include <rmt.h>
#include <rmt-command.h>
#include <prepargs.h>
#include <quotearg.h>
#include <version-etc.h>
@@ -254,6 +255,7 @@ enum
DELETE_OPTION,
EXCLUDE_CACHES_OPTION,
EXCLUDE_OPTION,
EXCLUDE_TAG_OPTION,
FORCE_LOCAL_OPTION,
GROUP_OPTION,
HANG_OPTION,
@@ -603,6 +605,8 @@ static struct argp_option options[] = {
N_("exclude patterns listed in FILE"), GRID+1 },
{"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
N_("exclude directories containing a cache tag"), GRID+1 },
{"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
N_("exclude directories containing FILE"), GRID+1 },
{"no-recursion", NO_RECURSION_OPTION, 0, 0,
N_("avoid descending automatically in directories"), GRID+1 },
{"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0,
@@ -953,7 +957,8 @@ enum read_file_list_state /* Result of reading file name from the list file */
{
file_list_success, /* OK, name read successfully */
file_list_end, /* End of list file */
file_list_zero /* Zero separator encountered where it should not */
file_list_zero, /* Zero separator encountered where it should not */
file_list_skip /* Empty (zero-length) entry encountered, skip it */
};
/* Read from FP a sequence of characters up to FILENAME_TERMINATOR and put them
@@ -971,13 +976,15 @@ read_name_from_file (FILE *fp, struct obstack *stk)
{
/* We have read a zero separator. The file possibly is
zero-separated */
/* FATAL_ERROR((0, 0, N_("file name contains null character"))); */
return file_list_zero;
}
obstack_1grow (stk, c);
counter++;
}
if (counter == 0 && c != EOF)
return file_list_skip;
obstack_1grow (stk, 0);
return (counter == 0 && c == EOF) ? file_list_end : file_list_success;
@@ -1058,31 +1065,42 @@ update_argv (const char *filename, struct argp_state *state)
open_fatal (filename);
}
while ((read_state = read_name_from_file (fp, &argv_stk)) == file_list_success)
count++;
if (read_state == file_list_zero)
while ((read_state = read_name_from_file (fp, &argv_stk)) != file_list_end)
{
size_t size;
switch (read_state)
{
case file_list_success:
count++;
break;
WARN ((0, 0, N_("%s: file name read contains nul character"),
quotearg_colon (filename)));
case file_list_end: /* won't happen, just to pacify gcc */
break;
/* Prepare new stack contents */
size = obstack_object_size (&argv_stk);
p = obstack_finish (&argv_stk);
for (; size > 0; size--, p++)
if (*p)
obstack_1grow (&argv_stk, *p);
else
obstack_1grow (&argv_stk, '\n');
obstack_1grow (&argv_stk, 0);
count = 1;
case file_list_zero:
{
size_t size;
/* Read rest of files using new filename terminator */
filename_terminator = 0;
while (read_name_from_file (fp, &argv_stk) == file_list_success)
count++;
WARN ((0, 0, N_("%s: file name read contains nul character"),
quotearg_colon (filename)));
/* Prepare new stack contents */
size = obstack_object_size (&argv_stk);
p = obstack_finish (&argv_stk);
for (; size > 0; size--, p++)
if (*p)
obstack_1grow (&argv_stk, *p);
else
obstack_1grow (&argv_stk, '\n');
obstack_1grow (&argv_stk, 0);
count = 1;
/* Read rest of files using new filename terminator */
filename_terminator = 0;
break;
}
case file_list_skip:
break;
}
}
if (!is_stdin)
@@ -1492,6 +1510,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
exclude_caches_option = true;
break;
case EXCLUDE_TAG_OPTION:
add_exclude_tag (arg);
break;
case FORCE_LOCAL_OPTION:
force_local_option = true;
break;
@@ -2332,7 +2354,7 @@ main (int argc, char **argv)
if (stdlis == stdout)
close_stdout ();
else if (ferror (stderr) || fclose (stderr) != 0)
else if (ferror (stderr) || fclose (stderr) != 0)
exit_status = TAREXIT_FAILURE;
return exit_status;

View File

@@ -165,6 +165,7 @@ struct oldgnu_header
'A' Solaris Access Control List
'E' Solaris Extended Attribute File
'I' Inode only, as in 'star'
'N' Obsolete GNU tar, for file names that do not fit into the main header.
'X' POSIX 1003.1-2001 eXtended (VU version) */
/* This is a dir entry that contains the names of files that were in the
@@ -180,9 +181,6 @@ struct oldgnu_header
/* This is the continuation of a file that began on another volume. */
#define GNUTYPE_MULTIVOL 'M'
/* For storing filenames that do not fit into the main header. */
#define GNUTYPE_NAMES 'N'
/* This is for sparse files. */
#define GNUTYPE_SPARSE 'S'
@@ -320,5 +318,3 @@ union block
struct star_in_header star_in_header;
struct star_ext_header star_ext_header;
};

View File

@@ -264,7 +264,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
case 'f':
if (st)
{
base = base_name (st->orig_file_name);
base = last_component (st->orig_file_name);
len += strlen (base) - 2;
}
break;
@@ -647,12 +647,10 @@ void
xheader_read (union block *p, size_t size)
{
size_t j = 0;
size_t nblocks;
free (extended_header.buffer);
size += BLOCKSIZE;
extended_header.size = size;
nblocks = (size + BLOCKSIZE - 1) / BLOCKSIZE;
extended_header.buffer = xmalloc (size + 1);
extended_header.buffer[size] = '\0';
@@ -1094,9 +1092,10 @@ ctime_decoder (struct tar_stat_info *st,
static void
mtime_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data __attribute__ ((unused)))
struct xheader *xhdr, void const *data)
{
code_time (st->mtime, keyword, xhdr);
const struct timespec mtime = data ? *(struct timespec *) data : st->mtime;
code_time (mtime, keyword, xhdr);
}
static void

View File

@@ -46,6 +46,8 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
## ------------ ##
TESTSUITE_AT = \
T-empty.at\
T-null.at\
testsuite.at\
append.at\
append01.at\
@@ -63,6 +65,7 @@ TESTSUITE_AT = \
extrac04.at\
extrac05.at\
extrac06.at\
extrac07.at\
gzip.at\
grow.at\
incremental.at\

52
tests/T-empty.at Normal file
View File

@@ -0,0 +1,52 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2006 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.
# Tar 1.16 coredumped if a filelist file contained empty (zero-length)
# entries
# Reported by: Karl Berry <karl@freefriends.org>
# References: <200610301353.k9UDr1O30680@f7.net>
AT_SETUP([files-from: empty entries])
AT_KEYWORDS([files-from empty])
AT_DATA([file-list],
[jeden
dwa
trzy
])
AT_TAR_CHECK([
AT_SORT_PREREQ
genfile --file jeden
genfile --file dwa
genfile --file trzy
tar cfvT archive ../file-list | sort
],
[0],
[dwa
jeden
trzy
],
[],[],[],[ustar]) # Testing one format is enough
AT_CLEANUP

46
tests/T-null.at Normal file
View File

@@ -0,0 +1,46 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2006 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.
AT_SETUP([files-from: 0-separated file without -0])
AT_KEYWORDS([files-from null])
AT_TAR_CHECK([
AT_SORT_PREREQ
echo dwa > temp
echo trzy >> temp
cat temp | tr '\n' '\0' > temp1
echo jeden > file-list
cat temp1 >> file-list
genfile -f "jeden
dwa"
genfile -f trzy
tar cfTv archive file-list | sort
],
[0],
[jeden\ndwa
trzy
],
[tar: file-list: file name read contains nul character
],[],[ustar]) # Testing one format is enough
AT_CLEANUP

View File

@@ -44,19 +44,22 @@ AT_TAR_CHECK([
genfile --file file1
genfile --file file2
# Make sure file timestamps in the archive will not differ
MTIME="--mtime=@0"
# For PAX archives, we need to make sure extended header names are
# reproducible.
# reproducible and that their contents won't change with time
if test $[]TEST_TAR_FORMAT = posix; then
TAR_OPTIONS="$TAR_OPTIONS --pax-option=exthdr.name=%d/PaxHeaders/%f"
TAR_OPTIONS="$TAR_OPTIONS --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=mtime,delete=atime,delete=ctime"
fi
echo Creating archive.1
tar cf archive.1 file1 file2
tar $MTIME -cf archive.1 file1 file2
echo Creating archive.2
tar cfT archive.2 /dev/null
tar rf archive.2 file1
tar rf archive.2 file2
tar $MTIME -cf archive.2 -T /dev/null
tar $MTIME -rf archive.2 file1
tar $MTIME -rf archive.2 file2
echo Comparing archives
cmp archive.1 archive.2

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2004 Free Software Foundation, Inc.
# Copyright (C) 2004, 2006 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
@@ -21,7 +21,7 @@
# Could not extract symlinks over an existing file.
AT_SETUP([extracting symlinks over an existing file])
AT_KEYWORDS([extract extract02])
AT_KEYWORDS([extract extract02 symlink])
# FIXME: Skip if symlinks are not supported on the system

View File

@@ -21,7 +21,7 @@
# Check for fnmatch problems in glibc 2.1.95.
AT_SETUP([extract + fnmatch])
AT_KEYWORDS([extract extract04])
AT_KEYWORDS([extract extract04 fnmatch])
AT_TAR_CHECK([
AT_SORT_PREREQ

View File

@@ -31,7 +31,7 @@
#
AT_SETUP([mode of extracted directories])
AT_KEYWORDS([extract extract06])
AT_KEYWORDS([extract extract06 directory mode])
AT_TAR_CHECK([

56
tests/extrac07.at Normal file
View File

@@ -0,0 +1,56 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2006 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.
# Tar 1.16 failed to extract archives that have symlinks
# in read-only directories.
#
# Reported-by: Eelco Dolstra <eelco@cs.uu.nl>
# References: <45475D78.8050708@cs.uu.nl>
AT_SETUP([extracting symlinks to a read-only dir])
AT_KEYWORDS([extract extract07 read-only symlink])
AT_TAR_CHECK([
echo Prepare the directory
mkdir dir
genfile -f foo
cd dir
ln -s ../foo .
cd ..
chmod -w dir
echo Create the archive
tar cf archive dir || exit 1
echo Extract
mkdir out
tar -C out -xvf archive
],
[0],
[Prepare the directory
Create the archive
Extract
dir/
dir/foo
],[],[],[ustar]) # Testing one format is enough
AT_CLEANUP

View File

@@ -28,7 +28,7 @@ AT_KEYWORDS([shortrec.at])
AT_TAR_CHECK([
mkdir directory
(cd directory && touch a b c d e f g h i j k l m n o p q r)
tar -c -b 1 directory | tar -t -f - >/dev/null
tar -c -b 1 -f - directory | tar -t -f - >/dev/null
tar -c -b 1 -f archive directory
tar -t -f archive >/dev/null
tar -t -f - < archive >/dev/null

View File

@@ -100,6 +100,9 @@ m4_include([pipe.at])
m4_include([options.at])
m4_include([options02.at])
m4_include([T-empty.at])
m4_include([T-null.at])
m4_include([indexfile.at])
m4_include([verbose.at])
@@ -119,6 +122,7 @@ m4_include([extrac03.at])
m4_include([extrac04.at])
m4_include([extrac05.at])
m4_include([extrac06.at])
m4_include([extrac07.at])
m4_include([gzip.at])

View File

@@ -36,7 +36,7 @@ genfile --run 'tar -vcf bar foo baz' --checkpoint 10 --length 49995k --truncate
echo Exit status: $?
echo separator
sleep 1
dd if=/dev/zero of=foo bs=1k seek=49995 count=5 >/dev/null 2>&1
genfile --file foo --seek 49995k --length 5k --pattern=zeros
tar dvf bar],
[1],
[foo