33 Commits

Author SHA1 Message Date
Sergey Poznyakoff
aea443b9e8 Version 1.26
* NEWS, configure.ac: Update.
* po/POTFILES.in: Remove paxexit.c (see bb971a1e).
2011-03-12 12:20:07 +02:00
Paul Eggert
881e5626c5 --atime-preserve=replace: fix correctness and performance bugs
reported by Eric Blake in
<http://lists.gnu.org/archive/html/bug-tar/2011-03/msg00000.html>.
* src/compare.c (diff_file): Do not restore atime of size-zero files.
* src/create.c (dump_file0): Likewise.  Also, do not restore atime
when fd is zero, because that indicates a file we haven't opened.
2011-03-07 15:40:56 -08:00
Paul Eggert
67ae04ba31 * doc/tar.texi: Adjust example commands and output for accuracy.
The original problem was reported by Michael Witten in
<http://lists.gnu.org/archive/html/bug-tar/2011-02/msg00033.html>.
2011-02-22 16:41:10 -08:00
Paul Eggert
2807513841 tar: if (p) free (p); -> free (p);
There is no longer (since SunOS 4) any need to guard against
free (NULL), so replace each "if (p) free (p);" with "free (p);".
From Jim Meyering in
<http://lists.gnu.org/archive/html/bug-tar/2011-01/msg00026.html>.
* src/incremen.c (scan_directory, read_directory_file): As above.
(try_purge_directory): Likewise.
* src/list.c (read_header): Likewise.
* src/misc.c (assign_string): Likewise.
2011-02-16 13:47:28 -08:00
Sergey Poznyakoff
bb0af96c54 Correctly store long sparse file names in PAX archives.
* src/sparse.c (pax_dump_header_1): Make sure the created header name is
shorter than NAME_FIELD_SIZE bytes.
* tests/sparse04.at: New testcase.
* tests/Makefile.am (TESTSUITE_AT): Add sparse04.at.
* tests/testsuite.at: Include sparse04.at.
* NEWS: Update.
2010-12-14 15:27:55 +02:00
Paul Eggert
ec586b37e0 tests: make the truncate test smaller and less buggy (tiny change)
Reported by Solar Designer in
<http://lists.gnu.org/archive/html/bug-tar/2010-12/msg00003.html>.
* tests/truncate.at: Use a smaller test case, and make its
race condition less likely.
2010-12-06 14:27:29 -08:00
Paul Eggert
a7fc5ecead tests: skip SIGPIPE-dependent tests in environments ignoring SIGPIPE
Problem reported by Sven Joachim in
<http://lists.gnu.org/archive/html/bug-tar/2010-11/msg00043.html>.
* tests/remfiles01.at: Use AT_SIGPIPE_PREREQ.
* tests/sigpipe.at: Likewise.
* tests/testsuite.at (AT_SIGPIPE_PREREQ): New macro.
2010-11-26 19:36:05 -08:00
Paul Eggert
649b747913 tar: work around NetBSD and Tru64 symlink incompatibility with POSIX
Problem reported by Bruno Haible in
<http://lists.gnu.org/archive/html/bug-gnulib/2010-11/msg00306.html>.
* src/extract.c (maybe_recoverable):  Also treat EFTYPE (if defined)
and ENOTSUP like ELOOP.
2010-11-24 23:08:07 -08:00
Paul Eggert
bb971a1e8a tar: adjust to paxutils change: paxexit.c -> paxexit-status.c
* lib/Makefile.am (libtar_a_SOURCES): paxexit.c renamed to
paxexit-status.c.
2010-11-23 21:41:50 -08:00
Paul Eggert
50a57a0147 tar: remove unused function dir_removed_diag
* src/common.h (dir_removed_diag): Remove unused decl.
* src/misc.c (dir_removed_diag): Remove unused function.
2010-11-23 17:56:58 -08:00
Paul Eggert
1584b72ff2 tar: work around FreeBSD symlink incompatibility with POSIX
* src/extract.c (maybe_recoverable): Treat EMLINK like ELOOP, for
FreeBSD.  Problem reported by Christian Weisgerber in
<http://lists.gnu.org/archive/html/bug-tar/2010-11/msg00080.html>.
2010-11-23 12:58:09 -08:00
Paul Eggert
065cf0958c * src/names.c: tar: fix bug with --one-file-system --listed-incremental
Problem (and idea for fix) reported by Martin Weigel
<http://lists.gnu.org/archive/html/bug-tar/2010-11/msg00071.html>.
* src/common.h (is_individual_file): Remove decl.
* src/create.c (dump_file0): Replace "is_individual_file (p)"
with "top_level".
* src/incremen.c (procdir): Replace "!is_individual_file
(name_buffer)" with "st->parent".  Fix bug with --one-file-system
and --listed-incremental.
* src/names.c (individual_file_table, register_individual_file):
(is_individual_file): Remove.  All uses removed.
2010-11-22 22:51:29 -08:00
Paul Eggert
2a55b4b037 tests: new test listed04 for --one-file-system --listed-incremental
* tests/Makefile.am (TESTSUITE_AT): Add listed04.at.
* tests/listed04.at: New file.
* tests/testsuite.at: Include it.
2010-11-22 17:59:21 -08:00
Paul Eggert
27225be1a3 scripts: fix option parsing
Problem reported by Dennis Wydra in
<http://lists.gnu.org/archive/html/bug-tar/2010-11/msg00082.html>.
* scripts/backup.in: Accept "-l LEVEL".  Be more systematic about
backslashes inside ``; it shouldn't matter for modern shells but
it might matter for older ones.
* scripts/restore.in: Likewise.
* scripts/backup.in: Adjust implementation of -t/--time to match
the new implementation of -l/--level.
2010-11-22 15:18:41 -08:00
Sergey Poznyakoff
73d0d1a0f8 Issue a warning if the archive being compared contais transformed file names.
* src/common.h (transform_program_p): New proto.
* src/transform.c (transform_program_p): New function.
* src/compare.c (verify_volume): Warn if the archive contains
transformed file names.
2010-11-15 11:22:27 +02:00
Sergey Poznyakoff
ff2bc5c0a1 Minor change.
* doc/tar.texi: Reword the description of decompress-program.
2010-11-15 11:21:45 +02:00
Paul Eggert
24214ca5d5 tar: fix --verify option, which broke in 1.24
* NEWS: Document this.
* src/compare.c (verify_volume): Decode the header before invoking
diff_archive, as diff_archive no longer does this as of the
2010-06-28 commit.  Also, don't try to invoke diff_archive on a
zero block.
* tests/Makefile.am (TESTSUITE_AT): Add verify.at.
* tests/testsuite.at: Include verify.at.
* tests/verify.at: New file.
2010-11-15 00:08:27 -08:00
Paul Eggert
777042e024 Merge branch 'master' of ssh://git.sv.gnu.org/srv/git/tar 2010-11-08 11:14:28 -08:00
Jim Meyering
1801399830 tests: avoid spurious failure when VERSION_CONTROL envvar is set
* tests/backup01.at: Unset VERSION_CONTROL.  Otherwise,
when set to e.g., 'always', it would cause this test to fail.
2010-11-08 11:13:39 -08:00
Sergey Poznyakoff
ecd700fbfb Version 1.25
* configure.ac: Version 1.25
* NEWS: Describe the changes.
2010-11-07 16:04:48 +02:00
Sergey Poznyakoff
f1fed3996a Run alternative decompression programs if the principal one is not available.
Some compression programs are able to handle various compression formats
(e.g. `gzip' can decompress files created by `compress', `xz' is able
to handle lzma, etc.)  Tar tries to use such programs for decompression
if the principal decompressor cannot be started.

* src/buffer.c (compress_type): Swap ct_none and ct_tar.
(archive_compression_type): New static variable.
(zip_magic): Remove program and option fields.
(zip_program): New structure and static.
(compress_program): Remove macro.
(find_zip_program): New static function.
(first_decompress_program,next_decompress_program): New functions.
(open_compressed_archive): Set archive_compression_type instead of
use_compress_program_option.
* src/common.h (first_decompress_program)
(next_decompress_program): New functions.
(WARN_DECOMPRESS_PROGRAM): New flag.
(WARN_VERBOSE_WARNINGS): Include WARN_DECOMPRESS_PROGRAM.
* src/warning.c (warning_args): Add "decompress-program".
(warning_types): Add WARN_DECOMPRESS_PROGRAM.
* src/system.c (run_decompress_program): New function.
(sys_child_open_for_uncompress): Use run_decompress_program
instead of calling execlp directly.
2010-11-05 10:09:51 +02:00
Paul Eggert
b32edff5aa tests: fix some issues with signals, timestamps, "test" typo
* tests/extrac17.at: Add --warning=no-timestamp, to avoid
bogus warning due to NFS clock skew.
* tests/remfiles01.at: Discard diagnostics that some shells
generate about broken pipes.
* tests/sigpipe.at: Likewise.
* tests/remfiles01.at: Fix typo: "test $EC" was written where
"test $EC -ne 0" was intended.
2010-11-02 01:05:16 -07:00
Sergey Poznyakoff
3913675640 Fix extraction of device nodes.
* src/extract.c (extract_node): Do not mask out node type.
The bug was introduced in commit ea964cce.
2010-11-01 15:05:25 +02:00
Paul Eggert
b8feb2b142 tar: don't cross struct member boundaries with OLDGNU_MAGIC
* src/create.c (write_gnu_long_link, start_header): Access
header->buffer + offsetof (struct posix_header, magic), instead of
header->header.magic, when reading or writing the OLDGNU_MAGIC
pattern.  The code violates the C standard without this change,
and GCC warns about this if fortify checking is enabled.  It's not
a bug on traditional (i.e., non-debugging) platforms, but it does
violate the C standard so it should be fixed.  Problem originally
reported by John Emil Karlson in
<http://lists.gnu.org/archive/html/bug-tar/2010-04/msg00023.html>.
* src/list.c (decode_header): Likewise.
2010-10-27 22:31:16 -07:00
Paul Eggert
3fe59ed5ef tests: port to sh variants that squirrel away file descriptors
OpenBSD /bin/sh, and some other sh variants, squirrel away file
descriptors before closing them.  For example, for "cat 3<&-" they
first dup file descriptor 3 to a fd that is 10 or greater, then
close 3 (because if "cat" had been a builtin command like ":" then
they would have wanted to avoid the fork and restore the fd after
":" finished); and they treat ordinary (forking) commands the same
as builtin commands.  This approach fails after "ulimit -n 10".
Work around this deficiency by closing the file descriptors before
invoking ulimit.  Problem reported by Christian Weisgerber in
<http://lists.gnu.org/archive/html/bug-tar/2010-10/msg00041.html>;
solution suggested by Jilles Tjoelker in
<http://article.gmane.org/gmane.comp.shells.dash/415>.

* tests/extrac11.at (scarce file descriptors): Close file
descriptors before invoking ulimit -n.
2010-10-27 20:25:56 -07:00
Sergey Poznyakoff
5af29cb944 Transform file names when updating and appendig to archives.
This complements 28e91b48.

* src/common.h (transform_stat_info): New prototype.
* src/list.c (transform_stat_info): Remove static qualifier.
* src/update.c (update_archive): Call transform_stat_info.
* tests/Makefile.am (TESTSUITE_AT): Add append03.at
* tests/testsuite.at: Include append03.at
2010-10-27 14:07:46 +03:00
Paul Eggert
7dd57ebdfa tests: port to Solaris diff
* tests/extrac13.at: Don't assume that "diff -c" outputs nothing
when there are no differences.  This is not true on Solaris,
where it outputs "No differences encounted".
2010-10-26 18:13:03 -07:00
Paul Eggert
e23d123b93 tar: fix -x --overwrite bug (no --dereference, ! O_NOFOLLOW)
This bug was discovered on Solaris 8.  On older hosts lacking
O_NOFOLLOW, tar -x --overwrite (without --dereference) follows
symbolic links, causing the "extract over symlinks" test to fail.

* src/extract.c (open_output_file): If O_NOFOLLOW is needed but
does not work, check for a symlink separately.
2010-10-26 17:58:53 -07:00
Paul Eggert
6398c7a79c tar: don't use "((" in shell scripts
* tests/extrac11.at: Replace "((" with "( (" in shell scripts, as
"((" is not portable to the Korn shell, and POSIX 1003.1-2008 says
that "((" is not portable.
2010-10-26 15:04:56 -07:00
Sergey Poznyakoff
28e91b48f6 Make sure name matching occurs before name transformation.
The commit 9c194c99 altered that order.

* src/list.c (transform_stat_info): New function.  Split off from
decode_header.
(read_and): Call transform_stat_info right before do_something,
and after deciding if we should proceed with this member name,
so that name matching occurs before name transformation.

* tests/extrac17.at: New file.
* tests/Makefile.am (TESTSUITE_AT): Add extrac17.at
* tests/testsuite.at: Include extrac17.at.
2010-10-26 22:29:02 +03:00
Paul Eggert
3c0bedd494 tar: don't assume stdin is open when testing fd limits
* tests/extrac11.at: Redirect stdin from /dev/null, in case
the parent 'make' is running with stdin closed.
2010-10-26 11:33:38 -07:00
Sergey Poznyakoff
c520964e84 Further fixes in bootstrap.
* bootstrap: Restore the default for gnulib_path
(symlink_to_dir): Re-apply 67cad07.
2010-10-26 16:48:40 +03:00
Paul Eggert
acb77ac5bd tar: fix bug with -C and extracting directories
Problem reported by Denis Excoffier in
<http://lists.gnu.org/archive/html/bug-tar/2010-10/msg00034.html>.

* src/extract.c (extract_dir): Use mkdirat, not mkdir.
* tests/extrac16.at: New file, to test for this bug.
* tests/Makefile.am (TESTSUITE_AT): Add it.
* tests/testsuite.at: Include it.

This file is a placeholder. It will be replaced with the actual ChangeLog
by make dist.  Run make ChangeLog if you wish to create it earlier.
2010-10-25 20:21:06 -07:00
36 changed files with 716 additions and 240 deletions

51
NEWS
View File

@@ -1,6 +1,55 @@
GNU tar NEWS - User visible changes. 2010-10-24
GNU tar NEWS - User visible changes. 2011-03-12
Please send GNU tar bug reports to <bug-tar@gnu.org>
version 1.26 - Sergey Poznyakoff, 2011-03-12
* Bugfixes
** Fix the --verify option, which broke in version 1.24.
** Fix storing long sparse file names in PAX archives.
** Fix correctness of --atime-preserve=replace
tar --atime-preserve=replace no longer tries to restore atime of
zero-sized files.
** Work around POSIX incompatibilities on FreeBSD, NetBSD and Tru64
** Fix bug with --one-file-system --listed-incremental
When invoked with these two options, tar 1.25 would add only the
top-level directory to the archive, but not its contents.
version 1.25 - Sergey Poznyakoff, 2010-11-07
* Fix extraction of empty directories with the -C option in effect.
* Fix extraction of device nodes.
* Make sure name matching occurs before eventual name transformation.
Tar 1.24 changed the ordering of name matching and name transformation
so that the former saw already transformed file names. This made it
impossible to match file names in certain cases. It is fixed now.
* Fix the behavior of tar -x --overwrite on hosts lacking O_NOFOLLOW.
* Improve the testsuite.
* Alternative decompression programs.
If extraction from a compressed archive fails because the corresponding
compression program is not installed and the following two conditions
are met, tar retries extraction using an alternative decompressor:
1. Another compression program supported by tar is able to handle this
compression format.
2. The compression program was not explicitly requested in the command
line by the use of such options as -z, -j, etc.
For example, if `compress' is not available, tar will try `gzip'.
version 1.24 - Sergey Poznyakoff, 2010-10-24

View File

@@ -464,8 +464,7 @@ git_modules_config () {
}
gnulib_path=`git_modules_config submodule.gnulib.path`
: ${gnulib_path=gnulib}
: ${gnulib_path:=gnulib}
# Get gnulib files.
case ${GNULIB_SRCDIR--} in
@@ -623,6 +622,7 @@ symlink_to_dir()
/*) ;;
*)
case /$dst/ in
/./*) ;;
*//* | */../* | */./* | /*/*/*/*/*/)
echo >&2 "$0: invalid symlink calculation: $src -> $dst"
exit 1;;

View File

@@ -19,7 +19,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
AC_INIT([GNU tar], [1.24], [bug-tar@gnu.org])
AC_INIT([GNU tar], [1.26], [bug-tar@gnu.org])
AC_CONFIG_SRCDIR([src/tar.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])

View File

@@ -1022,13 +1022,12 @@ suffixes explained above:
@smallexample
@group
V--------- 0/0 1536 2006-06-09 13:07 MyVolume--Volume Header--
-rw-r--r-- gray/staff 456783 2006-06-09 12:06 aspic--Continued at
byte 32456--
-rw-r--r-- gray/staff 62373 2006-06-09 12:06 apple
lrwxrwxrwx gray/staff 0 2006-06-09 13:01 angst -> apple
-rw-r--r-- gray/staff 35793 2006-06-09 12:06 blues
hrw-r--r-- gray/staff 0 2006-06-09 12:06 music link to blues
V--------- 0/0 1536 2006-06-09 13:07 MyVolume--Volume Header--
-rw-r--r-- gray/staff 456783 2006-06-09 12:06 aspic--Continued at byte 32456--
-rw-r--r-- gray/staff 62373 2006-06-09 12:06 apple
lrwxrwxrwx gray/staff 0 2006-06-09 13:01 angst -> apple
-rw-r--r-- gray/staff 35793 2006-06-09 12:06 blues
hrw-r--r-- gray/staff 0 2006-06-09 12:06 music link to blues
@end group
@end smallexample
@@ -1421,7 +1420,7 @@ above would look like:
@smallexample
$ @kbd{tar --list --verbose --file=collection.tar folk}
-rw-r--r-- myself user 62 1990-05-23 10:55 folk
-rw-r--r-- myself/user 62 1990-05-23 10:55 folk
@end smallexample
@cindex listing member and file names
@@ -1513,11 +1512,11 @@ $ @kbd{tar --list --verbose --file=music.tar practice}
@command{tar} responds:
@smallexample
drwxrwxrwx myself user 0 1990-05-31 21:49 practice/
-rw-r--r-- myself user 42 1990-05-21 13:29 practice/blues
-rw-r--r-- myself user 62 1990-05-23 10:55 practice/folk
-rw-r--r-- myself user 40 1990-05-21 13:30 practice/jazz
-rw-r--r-- myself user 10240 1990-05-31 21:49 practice/collection.tar
drwxrwxrwx myself/user 0 1990-05-31 21:49 practice/
-rw-r--r-- myself/user 42 1990-05-21 13:29 practice/blues
-rw-r--r-- myself/user 62 1990-05-23 10:55 practice/folk
-rw-r--r-- myself/user 40 1990-05-21 13:30 practice/jazz
-rw-r--r-- myself/user 10240 1990-05-31 21:49 practice/collection.tar
@end smallexample
When you use a directory name as a file name argument, @command{tar} acts on
@@ -1567,9 +1566,9 @@ $ @kbd{tar -xvf collection.tar}
produces this:
@smallexample
-rw-r--r-- me user 28 1996-10-18 16:31 jazz
-rw-r--r-- me user 21 1996-09-23 16:44 blues
-rw-r--r-- me user 20 1996-09-23 16:44 folk
-rw-r--r-- me/user 28 1996-10-18 16:31 jazz
-rw-r--r-- me/user 21 1996-09-23 16:44 blues
-rw-r--r-- me/user 20 1996-09-23 16:44 folk
@end smallexample
@node extracting files
@@ -1683,8 +1682,8 @@ in the example below:
@smallexample
$ @kbd{tar -xvvf music.tar practice/folk practice/jazz}
-rw-r--r-- me user 28 1996-10-18 16:31 practice/jazz
-rw-r--r-- me user 20 1996-09-23 16:44 practice/folk
-rw-r--r-- me/user 28 1996-10-18 16:31 practice/jazz
-rw-r--r-- me/user 20 1996-09-23 16:44 practice/folk
@end smallexample
@noindent
@@ -4166,6 +4165,23 @@ Disable all warning messages.
@cindex @samp{Ignoring unknown extended header keyword `%s'}, warning message
@item unknown-keyword
@samp{Ignoring unknown extended header keyword `%s'}
@kwindex decompress-program
@item decompress-program
Controls verbose description of failures occurring when trying to run
alternative decompressor programs (@pxref{alternative decompression
programs}). This warning is disabled by default (unless
@option{--verbose} is used). A common example of what you can get
when using this warning is:
@smallexample
$ @kbd{tar --warning=decompress-program -x -f archive.Z}
tar (child): cannot run compress: No such file or directory
tar (child): trying gzip
@end smallexample
This means that @command{tar} first tried to decompress
@file{archive.Z} using @command{compress}, and, when that
failed, switched to @command{gzip}.
@end table
@subheading Keywords controlling incremental extraction:
@@ -4517,10 +4533,10 @@ If you now use the @option{--list} (@option{-t}) operation, you will see that
@smallexample
$ @kbd{tar --list --file=collection.tar}
-rw-r--r-- me user 28 1996-10-18 16:31 jazz
-rw-r--r-- me user 21 1996-09-23 16:44 blues
-rw-r--r-- me user 20 1996-09-23 16:44 folk
-rw-r--r-- me user 20 1996-09-23 16:44 rock
-rw-r--r-- me/user 28 1996-10-18 16:31 jazz
-rw-r--r-- me/user 21 1996-09-23 16:44 blues
-rw-r--r-- me/user 20 1996-09-23 16:44 folk
-rw-r--r-- me/user 20 1996-09-23 16:44 rock
@end smallexample
@node multiple
@@ -4564,11 +4580,11 @@ list the contents of the archive:
@smallexample
$ @kbd{tar --list --verbose --file=collection.tar}
-rw-r--r-- me user 28 1996-10-18 16:31 jazz
-rw-r--r-- me user 21 1996-09-23 16:44 blues
-rw-r--r-- me user 20 1996-09-23 16:44 folk
-rw-r--r-- me user 20 1996-09-23 16:44 rock
-rw-r--r-- me user 58 1996-10-24 18:30 blues
-rw-r--r-- me/user 28 1996-10-18 16:31 jazz
-rw-r--r-- me/user 21 1996-09-23 16:44 blues
-rw-r--r-- me/user 20 1996-09-23 16:44 folk
-rw-r--r-- me/user 20 1996-09-23 16:44 rock
-rw-r--r-- me/user 58 1996-10-24 18:30 blues
@end smallexample
@noindent
@@ -4584,7 +4600,7 @@ the following example:
@smallexample
$ @kbd{tar --extract -vv --occurrence --file=collection.tar blues}
-rw-r--r-- me user 21 1996-09-23 16:44 blues
-rw-r--r-- me/user 21 1996-09-23 16:44 blues
@end smallexample
@xref{Writing}, for more information on @option{--extract} and
@@ -4711,11 +4727,11 @@ contain what they are supposed to:
@smallexample
$ @kbd{tar -tvf bluesrock.tar}
-rw-r--r-- melissa user 105 1997-01-21 19:42 blues
-rw-r--r-- melissa user 33 1997-01-20 15:34 rock
-rw-r--r-- melissa/user 105 1997-01-21 19:42 blues
-rw-r--r-- melissa/user 33 1997-01-20 15:34 rock
$ @kbd{tar -tvf jazzfolk.tar}
-rw-r--r-- melissa user 20 1996-09-23 16:44 folk
-rw-r--r-- melissa user 65 1997-01-30 14:15 jazz
-rw-r--r-- melissa/user 20 1996-09-23 16:44 folk
-rw-r--r-- melissa/user 65 1997-01-30 14:15 jazz
@end smallexample
We can concatenate these two archives with @command{tar}:
@@ -8755,6 +8771,24 @@ certain compression formats. If this approach fails, @command{tar}
falls back to using archive name suffix to determine its format
(@pxref{auto-compress}, for a list of recognized suffixes).
@anchor{alternative decompression programs}
@cindex alternative decompression programs
Some compression programs are able to handle different compression
formats. @GNUTAR{} uses this, if the principal decompressor for the
given format is not available. For example, if @command{compress} is
not installed, @command{tar} will try to use @command{gzip}. As of
version @value{VERSION} the following alternatives are
tried@footnote{To verbosely trace the decompressor selection, use the
@option{--warning=decompress-program} option
(@pxref{warnings,decompress-program}).}:
@multitable @columnfractions 0.3 0.3 0.3
@headitem Format @tab Main decompressor @tab Alternatives
@item compress @tab compress @tab gzip
@item lzma @tab lzma @tab xz
@item bzip2 @tab bzip2 @tab lbzip2
@end multitable
The only case when you have to specify a decompression option while
reading the archive is when reading from a pipe or from a tape drive
that does not support random access. However, in this case @GNUTAR{}
@@ -9352,9 +9386,9 @@ once. For example, consider the following two files:
@smallexample
@group
$ ls
-rw-r--r-- 2 gray staff 4 2007-10-30 15:11 one
-rw-r--r-- 2 gray staff 4 2007-10-30 15:11 jeden
$ ls -l
-rw-r--r-- 2 gray staff 4 2007-10-30 15:11 one
-rw-r--r-- 2 gray staff 4 2007-10-30 15:11 jeden
@end group
@end smallexample
@@ -11516,8 +11550,8 @@ explicitly marked as in the example below:
@smallexample
@group
$ @kbd{tar --verbose --list --file=iamanarchive}
V--------- 0 0 0 1992-03-07 12:01 iamalabel--Volume Header--
-rw-r--r-- ringo user 40 1990-05-21 13:30 iamafilename
V--------- 0/0 0 1992-03-07 12:01 iamalabel--Volume Header--
-rw-r--r-- ringo/user 40 1990-05-21 13:30 iamafilename
@end group
@end smallexample

View File

@@ -30,7 +30,7 @@ INCLUDES = -I$(top_srcdir)/gnu -I../ -I../gnu
noinst_HEADERS = system.h system-ioctl.h rmt.h paxlib.h stdopen.h
libtar_a_SOURCES = \
paxerror.c paxexit.c paxlib.h paxnames.c \
paxerror.c paxexit-status.c paxlib.h paxnames.c \
prepargs.c prepargs.h \
rtapelib.c \
rmt.h \

View File

@@ -37,7 +37,6 @@ gnu/version-etc.c
gnu/xalloc-die.c
lib/paxerror.c
lib/paxexit.c
lib/paxnames.c
lib/rtapelib.c

View File

@@ -72,8 +72,9 @@ do
--l=*|--le=*|--lev=*|--leve=*|--level=*)
DUMP_LEVEL=$optarg
;;
-l?*) DUMP_LEVEL=`expr $option : '-l\(.*\)'`;;
-l|--l|--le|--lev|--leve|--level)
prev=$option
prev=--level
;;
--verb=*|--verbo=*|--verbos=*|--verbose=*)
VERBOSE=$optarg
@@ -81,14 +82,13 @@ do
-v|--verb|--verbo|--verbos|--verbose)
VERBOSE=100
;;
-v*) VERBOSE=`expr $option : "-v\(.*\)"`;;
-v*) VERBOSE=`expr $option : '-v\(.*\)'`;;
--t=*|--ti=*|--tim=*|--time=*)
TIME=$optarg
;;
-t) prev=--t;;
-t*) TIME=`expr $option : "-t\(.*\)"`;;
--t|--ti|--tim|--time)
prev=$option
-t?*) TIME=`expr $option : '-t\(.*\)'`;;
-t|--t|--ti|--tim|--time)
prev=--time
;;
-V|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "backup (@PACKAGE_NAME@) @VERSION@"

View File

@@ -60,8 +60,9 @@ do
--l=*|--le=*|--lev=*|--leve=*|--level=*)
DUMP_LEVEL=$optarg
;;
-l?*) DUMP_LEVEL=`expr $option : '-l\(.*\)'`;;
-l|--l|--le|--lev|--leve|--level)
prev=$option
prev=--level
;;
--verb=*|--verbo=*|--verbos=*|--verbose=*)
VERBOSE=$optarg
@@ -69,7 +70,7 @@ do
-v|--verb|--verbo|--verbos|--verbose)
VERBOSE=100
;;
-v*) VERBOSE=`expr $option : "-v\(.*\)"`;;
-v*) VERBOSE=`expr $option : '-v\(.*\)'`;;
-V|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "restore (@PACKAGE_NAME@) @VERSION@"
license

View File

@@ -261,8 +261,8 @@ compute_duration ()
/* Compression detection */
enum compress_type {
ct_tar, /* Plain tar file */
ct_none, /* Unknown compression type */
ct_tar, /* Plain tar file */
ct_compress,
ct_gzip,
ct_bzip2,
@@ -272,31 +272,102 @@ enum compress_type {
ct_xz
};
static enum compress_type archive_compression_type = ct_none;
struct zip_magic
{
enum compress_type type;
size_t length;
char const *magic;
};
struct zip_program
{
enum compress_type type;
char const *program;
char const *option;
};
static struct zip_magic const magic[] = {
{ ct_tar },
{ ct_none, },
{ ct_compress, 2, "\037\235", COMPRESS_PROGRAM, "-Z" },
{ ct_gzip, 2, "\037\213", GZIP_PROGRAM, "-z" },
{ ct_bzip2, 3, "BZh", BZIP2_PROGRAM, "-j" },
{ ct_lzip, 4, "LZIP", LZIP_PROGRAM, "--lzip" },
{ ct_lzma, 6, "\xFFLZMA", LZMA_PROGRAM, "--lzma" },
{ ct_lzop, 4, "\211LZO", LZOP_PROGRAM, "--lzop" },
{ ct_xz, 6, "\xFD" "7zXZ", XZ_PROGRAM, "-J" },
{ ct_tar },
{ ct_compress, 2, "\037\235" },
{ ct_gzip, 2, "\037\213" },
{ ct_bzip2, 3, "BZh" },
{ ct_lzip, 4, "LZIP" },
{ ct_lzma, 6, "\xFFLZMA" },
{ ct_lzop, 4, "\211LZO" },
{ ct_xz, 6, "\xFD" "7zXZ" },
};
#define NMAGIC (sizeof(magic)/sizeof(magic[0]))
#define compress_option(t) magic[t].option
#define compress_program(t) magic[t].program
static struct zip_program zip_program[] = {
{ ct_compress, COMPRESS_PROGRAM, "-Z" },
{ ct_compress, GZIP_PROGRAM, "-z" },
{ ct_gzip, GZIP_PROGRAM, "-z" },
{ ct_bzip2, BZIP2_PROGRAM, "-j" },
{ ct_bzip2, "lbzip2", "-j" },
{ ct_lzip, LZIP_PROGRAM, "--lzip" },
{ ct_lzma, LZMA_PROGRAM, "--lzma" },
{ ct_lzma, XZ_PROGRAM, "-J" },
{ ct_lzop, LZOP_PROGRAM, "--lzop" },
{ ct_xz, XZ_PROGRAM, "-J" },
{ ct_none }
};
static struct zip_program const *
find_zip_program (enum compress_type type, int *pstate)
{
int i;
for (i = *pstate; zip_program[i].type != ct_none; i++)
{
if (zip_program[i].type == type)
{
*pstate = i + 1;
return zip_program + i;
}
}
*pstate = i;
return NULL;
}
const char *
first_decompress_program (int *pstate)
{
struct zip_program const *zp;
if (use_compress_program_option)
return use_compress_program_option;
if (archive_compression_type == ct_none)
return NULL;
*pstate = 0;
zp = find_zip_program (archive_compression_type, pstate);
return zp ? zp->program : NULL;
}
const char *
next_decompress_program (int *pstate)
{
struct zip_program const *zp;
if (use_compress_program_option)
return NULL;
zp = find_zip_program (archive_compression_type, pstate);
return zp ? zp->program : NULL;
}
static const char *
compress_option (enum compress_type type)
{
struct zip_program const *zp;
int i = 0;
zp = find_zip_program (type, &i);
return zp ? zp->option : NULL;
}
/* Check if the file ARCHIVE is a compressed archive. */
static enum compress_type
@@ -395,7 +466,7 @@ open_compressed_archive (void)
break;
default:
use_compress_program_option = compress_program (type);
archive_compression_type = type;
break;
}
}

View File

@@ -440,6 +440,9 @@ void mv_size_left (off_t size);
void buffer_write_global_xheader (void);
const char *first_decompress_program (int *pstate);
const char *next_decompress_program (int *pstate);
/* Module create.c. */
enum dump_status
@@ -550,6 +553,7 @@ extern size_t recent_long_link_blocks;
void decode_header (union block *header, struct tar_stat_info *stat_info,
enum archive_format *format_pointer, int do_user_group);
void transform_stat_info (int typeflag, struct tar_stat_info *stat_info);
char const *tartime (struct timespec t, bool full_time);
#define OFF_FROM_HEADER(where) off_from_header (where, sizeof (where))
@@ -628,8 +632,6 @@ void seek_diag_details (char const *name, off_t offset);
void stat_diag (char const *name);
void file_removed_diag (const char *name, bool top_level,
void (*diagfn) (char const *name));
void dir_removed_diag (char const *name, bool top_level,
void (*diagfn) (char const *name));
void write_error_details (char const *name, size_t status, size_t size);
void write_fatal (char const *name) __attribute__ ((noreturn));
void write_fatal_details (char const *name, ssize_t status, size_t size)
@@ -676,7 +678,6 @@ bool excluded_name (char const *name);
void add_avoided_name (char const *name);
bool is_avoided_name (char const *name);
bool is_individual_file (char const *name);
bool contains_dot_dot (char const *name);
@@ -775,6 +776,7 @@ void set_transform_expr (const char *expr);
bool transform_name (char **pinput, int type);
bool transform_name_fp (char **pinput, int type,
char *(*fun)(char *, void *), void *);
bool transform_program_p (void);
/* Module suffix.c */
void set_compression_program_by_suffix (const char *name, const char *defprog);
@@ -804,10 +806,12 @@ void checkpoint_run (bool do_write);
#define WARN_UNKNOWN_CAST 0x00010000
#define WARN_UNKNOWN_KEYWORD 0x00020000
#define WARN_XDEV 0x00040000
#define WARN_DECOMPRESS_PROGRAM 0x00080000
/* The warnings composing WARN_VERBOSE_WARNINGS are enabled by default
in verbose mode */
#define WARN_VERBOSE_WARNINGS (WARN_RENAME_DIRECTORY|WARN_NEW_DIRECTORY)
#define WARN_VERBOSE_WARNINGS (WARN_RENAME_DIRECTORY|WARN_NEW_DIRECTORY|\
WARN_DECOMPRESS_PROGRAM)
#define WARN_ALL (~WARN_VERBOSE_WARNINGS)
void set_warning_option (const char *arg);

View File

@@ -234,7 +234,8 @@ diff_file (void)
else
read_and_process (&current_stat_info, process_rawdata);
if (atime_preserve_option == replace_atime_preserve)
if (atime_preserve_option == replace_atime_preserve
&& stat_data.st_size != 0)
{
struct timespec atime = get_stat_atime (&stat_data);
if (set_file_atime (diff_handle, chdir_fd, file_name, atime)
@@ -512,13 +513,22 @@ diff_archive (void)
void
verify_volume (void)
{
int may_fail = 0;
if (removed_prefixes_p ())
{
WARN((0, 0,
_("Archive contains file names with leading prefixes removed.")));
WARN((0, 0,
_("Verification may fail to locate original files.")));
may_fail = 1;
}
if (transform_program_p ())
{
WARN((0, 0,
_("Archive contains transformed file names.")));
may_fail = 1;
}
if (may_fail)
WARN((0, 0,
_("Verification may fail to locate original files.")));
if (!diff_buffer)
diff_init ();
@@ -611,8 +621,10 @@ verify_volume (void)
(0, 0, _("A lone zero block at %s"),
STRINGIFY_BIGINT (current_block_ordinal (), buf)));
}
continue;
}
decode_header (current_header, &current_stat_info, &current_format, 1);
diff_archive ();
tar_stat_destroy (&current_stat_info);
}

View File

@@ -562,7 +562,8 @@ write_gnu_long_link (struct tar_stat_info *st, const char *p, char type)
GNAME_TO_CHARS (tmpname, header->header.gname);
free (tmpname);
strcpy (header->header.magic, OLDGNU_MAGIC);
strcpy (header->buffer + offsetof (struct posix_header, magic),
OLDGNU_MAGIC);
header->header.typeflag = type;
finish_header (st, header, -1);
@@ -899,7 +900,8 @@ start_header (struct tar_stat_info *st)
case OLDGNU_FORMAT:
case GNU_FORMAT: /*FIXME?*/
/* Overwrite header->header.magic and header.version in one blow. */
strcpy (header->header.magic, OLDGNU_MAGIC);
strcpy (header->buffer + offsetof (struct posix_header, magic),
OLDGNU_MAGIC);
break;
case POSIX_FORMAT:
@@ -1676,9 +1678,9 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
put in the archive.
This check is omitted if incremental_option is set *and* the
requested file is not explicitely listed in the command line. */
requested file is not explicitly listed in the command line. */
if (!(incremental_option && !is_individual_file (p))
if (! (incremental_option && ! top_level)
&& !S_ISDIR (st->stat.st_mode)
&& OLDER_TAR_STAT_TIME (*st, m)
&& (!after_date_option || OLDER_TAR_STAT_TIME (*st, c)))
@@ -1795,6 +1797,7 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
set_exit_status (TAREXIT_DIFFERS);
}
else if (atime_preserve_option == replace_atime_preserve
&& fd && (is_dir || original_size != 0)
&& set_file_atime (fd, parentfd, name, st->atime) != 0)
utime_error (p);
}

View File

@@ -609,6 +609,18 @@ maybe_recoverable (char *file_name, bool regular, bool *interdir_made)
switch (e)
{
case ELOOP:
/* With open ("symlink", O_NOFOLLOW|...), POSIX says errno == ELOOP,
but some operating systems do not conform to the standard. */
#ifdef EFTYPE
/* NetBSD uses errno == EFTYPE; see <http://gnats.netbsd.org/43154>. */
case EFTYPE:
#endif
/* FreeBSD 8.1 uses errno == EMLINK. */
case EMLINK:
/* Tru64 5.1B uses errno == ENOTSUP. */
case ENOTSUP:
if (! regular
|| old_files_option != OVERWRITE_OLD_FILES || dereference_option)
break;
@@ -777,7 +789,7 @@ extract_dir (char *file_name, int typeflag)
for (;;)
{
status = mkdir (file_name, mode);
status = mkdirat (chdir_fd, file_name, mode);
if (status == 0)
{
current_mode = mode & ~ current_umask;
@@ -864,6 +876,20 @@ open_output_file (char const *file_name, int typeflag, mode_t mode,
}
}
/* If O_NOFOLLOW is needed but does not work, check for a symlink
separately. There's a race condition, but that cannot be avoided
on hosts lacking O_NOFOLLOW. */
if (! O_NOFOLLOW && overwriting_old_files && ! dereference_option)
{
struct stat st;
if (fstatat (chdir_fd, file_name, &st, AT_SYMLINK_NOFOLLOW) == 0
&& S_ISLNK (st.st_mode))
{
errno = ELOOP;
return -1;
}
}
fd = openat (chdir_fd, file_name, openflag, mode);
if (0 <= fd)
{
@@ -1191,7 +1217,7 @@ static int
extract_node (char *file_name, int typeflag)
{
bool interdir_made = false;
mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
mode_t mode = (current_stat_info.stat.st_mode & (MODE_RWX | S_IFBLK | S_IFCHR)
& ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0));
while (mknodat (chdir_fd, file_name, mode, current_stat_info.stat.st_rdev)

View File

@@ -426,7 +426,6 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
{
struct directory *directory;
struct stat *stat_data = &st->stat;
dev_t device = st->parent ? st->parent->stat.st_dev : 0;
bool nfs = NFS_FILE_STAT (*stat_data);
if ((directory = find_directory (name_buffer)) != NULL)
@@ -540,11 +539,8 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
}
}
/* If the directory is on another device and --one-file-system was given,
omit it... */
if (one_file_system_option && device != stat_data->st_dev
/* ... except if it was explicitely given in the command line */
&& !is_individual_file (name_buffer))
if (one_file_system_option && st->parent
&& stat_data->st_dev != st->parent->stat.st_dev)
/* FIXME:
WARNOPT (WARN_XDEV,
(0, 0,
@@ -783,8 +779,7 @@ scan_directory (struct tar_stat_info *st)
namebuf_free (nbuf);
if (dirp)
free (dirp);
free (dirp);
return directory;
}
@@ -1352,8 +1347,7 @@ read_directory_file (void)
if (ferror (listed_incremental_stream))
read_error (listed_incremental_option);
if (buf)
free (buf);
free (buf);
}
/* Output incremental data for the directory ENTRY to the file DATA.
@@ -1664,8 +1658,7 @@ try_purge_directory (char const *directory_name)
{
const char *entry;
struct stat st;
if (p)
free (p);
free (p);
p = new_name (directory_name, cur);
if (deref_stat (p, &st) != 0)

View File

@@ -75,6 +75,66 @@ base64_init (void)
base64_map[(int) base_64_digits[i]] = i;
}
static char *
decode_xform (char *file_name, void *data)
{
int type = *(int*)data;
switch (type)
{
case XFORM_SYMLINK:
/* FIXME: It is not quite clear how and to which extent are the symbolic
links subject to filename transformation. In the absence of another
solution, symbolic links are exempt from component stripping and
name suffix normalization, but subject to filename transformation
proper. */
return file_name;
case XFORM_LINK:
file_name = safer_name_suffix (file_name, true, absolute_names_option);
break;
case XFORM_REGFILE:
file_name = safer_name_suffix (file_name, false, absolute_names_option);
break;
}
if (strip_name_components)
{
size_t prefix_len = stripped_prefix_len (file_name,
strip_name_components);
if (prefix_len == (size_t) -1)
prefix_len = strlen (file_name);
file_name += prefix_len;
}
return file_name;
}
static bool
transform_member_name (char **pinput, int type)
{
return transform_name_fp (pinput, type, decode_xform, &type);
}
void
transform_stat_info (int typeflag, struct tar_stat_info *stat_info)
{
if (typeflag == GNUTYPE_VOLHDR)
/* Name transformations don't apply to volume headers. */
return;
transform_member_name (&stat_info->file_name, XFORM_REGFILE);
switch (typeflag)
{
case SYMTYPE:
transform_member_name (&stat_info->link_name, XFORM_SYMLINK);
break;
case LNKTYPE:
transform_member_name (&stat_info->link_name, XFORM_LINK);
}
}
/* Main loop for reading an archive. */
void
read_and (void (*do_something) (void))
@@ -135,7 +195,8 @@ read_and (void (*do_something) (void))
continue;
}
}
transform_stat_info (current_header->header.typeflag,
&current_stat_info);
(*do_something) ();
continue;
@@ -372,15 +433,13 @@ read_header (union block **return_block, struct tar_stat_info *info,
if (header->header.typeflag == GNUTYPE_LONGNAME)
{
if (next_long_name)
free (next_long_name);
free (next_long_name);
next_long_name = header_copy;
next_long_name_blocks = size / BLOCKSIZE;
}
else
{
if (next_long_link)
free (next_long_link);
free (next_long_link);
next_long_link = header_copy;
next_long_link_blocks = size / BLOCKSIZE;
}
@@ -439,8 +498,7 @@ read_header (union block **return_block, struct tar_stat_info *info,
struct posix_header const *h = &header->header;
char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1];
if (recent_long_name)
free (recent_long_name);
free (recent_long_name);
if (next_long_name)
{
@@ -471,8 +529,7 @@ read_header (union block **return_block, struct tar_stat_info *info,
assign_string (&info->file_name, name);
info->had_trailing_slash = strip_trailing_slashes (info->file_name);
if (recent_long_link)
free (recent_long_link);
free (recent_long_link);
if (next_long_link)
{
@@ -495,47 +552,6 @@ read_header (union block **return_block, struct tar_stat_info *info,
}
}
static char *
decode_xform (char *file_name, void *data)
{
int type = *(int*)data;
switch (type)
{
case XFORM_SYMLINK:
/* FIXME: It is not quite clear how and to which extent are the symbolic
links subject to filename transformation. In the absence of another
solution, symbolic links are exempt from component stripping and
name suffix normalization, but subject to filename transformation
proper. */
return file_name;
case XFORM_LINK:
file_name = safer_name_suffix (file_name, true, absolute_names_option);
break;
case XFORM_REGFILE:
file_name = safer_name_suffix (file_name, false, absolute_names_option);
break;
}
if (strip_name_components)
{
size_t prefix_len = stripped_prefix_len (file_name,
strip_name_components);
if (prefix_len == (size_t) -1)
prefix_len = strlen (file_name);
file_name += prefix_len;
}
return file_name;
}
static bool
transform_member_name (char **pinput, int type)
{
return transform_name_fp (pinput, type, decode_xform, &type);
}
#define ISOCTAL(c) ((c)>='0'&&(c)<='7')
/* Decode things from a file HEADER block into STAT_INFO, also setting
@@ -572,7 +588,9 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
else
format = USTAR_FORMAT;
}
else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0)
else if (strcmp (header->buffer + offsetof (struct posix_header, magic),
OLDGNU_MAGIC)
== 0)
format = hbits ? OLDGNU_FORMAT : GNU_FORMAT;
else
format = V7_FORMAT;
@@ -655,23 +673,9 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
|| stat_info->dumpdir)
stat_info->is_dumpdir = true;
}
if (header->header.typeflag == GNUTYPE_VOLHDR)
/* Name transformations don't apply to volume headers. */
return;
transform_member_name (&stat_info->file_name, XFORM_REGFILE);
switch (header->header.typeflag)
{
case SYMTYPE:
transform_member_name (&stat_info->link_name, XFORM_SYMLINK);
break;
case LNKTYPE:
transform_member_name (&stat_info->link_name, XFORM_LINK);
}
}
/* Convert buffer at WHERE0 of size DIGS from external format to
uintmax_t. DIGS must be positive. If TYPE is nonnull, the data
are of type TYPE. The buffer must represent a value in the range

View File

@@ -37,8 +37,7 @@
void
assign_string (char **string, const char *value)
{
if (*string)
free (*string);
free (*string);
*string = value ? xstrdup (value) : 0;
}
@@ -856,21 +855,6 @@ file_removed_diag (const char *name, bool top_level,
diagfn (name);
}
void
dir_removed_diag (const char *name, bool top_level,
void (*diagfn) (char const *name))
{
if (!top_level && errno == ENOENT)
{
WARNOPT (WARN_FILE_REMOVED,
(0, 0, _("%s: Directory removed before we read it"),
quotearg_colon (name)));
set_exit_status (TAREXIT_DIFFERS);
}
else
diagfn (name);
}
void
write_fatal_details (char const *name, ssize_t status, size_t size)
{

View File

@@ -47,8 +47,6 @@ static char *cached_no_such_gname;
static uid_t cached_no_such_uid;
static gid_t cached_no_such_gid;
static void register_individual_file (char const *name);
/* Given UID, find the corresponding UNAME. */
void
uid_to_uname (uid_t uid, char **uname)
@@ -360,8 +358,6 @@ name_next_elt (int change_dirs)
{
if (unquote_option)
unquote_string (name_buffer);
if (incremental_option)
register_individual_file (name_buffer);
entry.type = ep->type;
entry.v.name = name_buffer;
return &entry;
@@ -1151,28 +1147,6 @@ excluded_name (char const *name)
{
return excluded_file_name (excluded, name + FILE_SYSTEM_PREFIX_LEN (name));
}
static Hash_table *individual_file_table;
static void
register_individual_file (char const *name)
{
struct stat st;
if (deref_stat (name, &st) != 0)
return; /* Will be complained about later */
if (S_ISDIR (st.st_mode))
return;
hash_string_insert (&individual_file_table, name);
}
bool
is_individual_file (char const *name)
{
return hash_string_lookup (individual_file_table, name);
}
/* Return the size of the prefix of FILE_NAME that is removed after

View File

@@ -991,7 +991,7 @@ pax_dump_header_1 (struct tar_sparse_file *file)
off_t size = 0;
struct sp_array *map = file->stat_info->sparse_map;
char *save_file_name = file->stat_info->file_name;
#define COPY_STRING(b,dst,src) do \
{ \
char *endp = b->buffer + BLOCKSIZE; \
@@ -1029,8 +1029,11 @@ pax_dump_header_1 (struct tar_sparse_file *file)
xheader_store ("GNU.sparse.name", file->stat_info, NULL);
xheader_store ("GNU.sparse.realsize", file->stat_info, NULL);
file->stat_info->file_name = xheader_format_name (file->stat_info,
"%d/GNUSparseFile.%p/%f", 0);
file->stat_info->file_name =
xheader_format_name (file->stat_info, "%d/GNUSparseFile.%p/%f", 0);
/* Make sure the created header name is shorter than NAME_FIELD_SIZE: */
if (strlen (file->stat_info->file_name) > NAME_FIELD_SIZE)
file->stat_info->file_name[NAME_FIELD_SIZE] = 0;
blk = start_header (file->stat_info);
/* Store the effective (shrunken) file size */

View File

@@ -455,6 +455,29 @@ sys_child_open_for_compress (void)
wait_for_grandchild (grandchild_pid);
}
static void
run_decompress_program (void)
{
int i;
const char *p, *prog = NULL;
for (p = first_decompress_program (&i); p; p = next_decompress_program (&i))
{
if (prog)
{
WARNOPT (WARN_DECOMPRESS_PROGRAM,
(0, errno, _("cannot run %s"), prog));
WARNOPT (WARN_DECOMPRESS_PROGRAM,
(0, 0, _("trying %s"), p));
}
prog = p;
execlp (p, p, "-d", NULL);
}
if (!prog)
FATAL_ERROR ((0, 0, _("unable to run decompression program")));
exec_fatal (prog);
}
/* Set ARCHIVE for uncompressing, then reading an archive. */
pid_t
sys_child_open_for_uncompress (void)
@@ -501,9 +524,7 @@ sys_child_open_for_uncompress (void)
open_fatal (archive_name_array[0]);
xdup2 (archive, STDIN_FILENO);
priv_set_restore_linkdir ();
execlp (use_compress_program_option, use_compress_program_option,
"-d", (char *) 0);
exec_fatal (use_compress_program_option);
run_decompress_program ();
}
/* We do need a grandchild tar. */
@@ -520,9 +541,7 @@ sys_child_open_for_uncompress (void)
xdup2 (child_pipe[PREAD], STDIN_FILENO);
xclose (child_pipe[PWRITE]);
priv_set_restore_linkdir ();
execlp (use_compress_program_option, use_compress_program_option,
"-d", (char *) 0);
exec_fatal (use_compress_program_option);
run_decompress_program ();
}
/* The child tar is still here! */

View File

@@ -628,3 +628,9 @@ transform_name (char **pinput, int type)
{
return transform_name_fp (pinput, type, NULL, NULL);
}
bool
transform_program_p (void)
{
return transform_head != NULL;
}

View File

@@ -130,6 +130,8 @@ update_archive (void)
decode_header (current_header, &current_stat_info,
&current_format, 0);
transform_stat_info (current_header->header.typeflag,
&current_stat_info);
archive_format = current_format;
if (subcommand_option == UPDATE_SUBCOMMAND

View File

@@ -41,6 +41,7 @@ static char const *const warning_args[] = {
"unknown-cast",
"unknown-keyword",
"xdev",
"decompress-program",
NULL
};
@@ -64,7 +65,8 @@ static int warning_types[] = {
WARN_TIMESTAMP,
WARN_UNKNOWN_CAST,
WARN_UNKNOWN_KEYWORD,
WARN_XDEV
WARN_XDEV,
WARN_DECOMPRESS_PROGRAM
};
ARGMATCH_VERIFY (warning_args, warning_types);

View File

@@ -52,6 +52,7 @@ TESTSUITE_AT = \
append.at\
append01.at\
append02.at\
append03.at\
backup01.at\
chtype.at\
comprec.at\
@@ -82,6 +83,8 @@ TESTSUITE_AT = \
extrac13.at\
extrac14.at\
extrac15.at\
extrac16.at\
extrac17.at\
filerem01.at\
filerem02.at\
gzip.at\
@@ -107,6 +110,7 @@ TESTSUITE_AT = \
listed01.at\
listed02.at\
listed03.at\
listed04.at\
long01.at\
longv7.at\
lustar01.at\
@@ -142,6 +146,7 @@ TESTSUITE_AT = \
sparse01.at\
sparse02.at\
sparse03.at\
sparse04.at\
sparsemv.at\
sparsemvp.at\
spmvp00.at\
@@ -154,6 +159,7 @@ TESTSUITE_AT = \
volsize.at\
volume.at\
verbose.at\
verify.at\
version.at\
xform-h.at\
xform01.at\

43
tests/append03.at Normal file
View File

@@ -0,0 +1,43 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright (C) 2010 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 3, 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, see <http://www.gnu.org/licenses/>.
AT_SETUP([append with name transformation])
AT_KEYWORDS([append append03])
# Description: Make sure filenames are transformed during append.
AT_TAR_CHECK([
genfile --file file.1
genfile --file file.2
tar -c -f archive --transform 's/file/plik/' file.*
echo Appending
tar -r -f archive --transform 's/file/plik/' -v --show-transformed-names file.1
echo Testing
tar tf archive
],
[0],
[Appending
plik.1
Testing
plik.1
plik.2
plik.1
])
AT_CLEANUP

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2009 Free Software Foundation, Inc.
# Copyright (C) 2009-2010 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
@@ -34,6 +34,7 @@ AT_SETUP([extracting existing dir with --backup])
AT_KEYWORDS([extract backup backup01])
AT_TAR_CHECK([
unset VERSION_CONTROL
mkdir dir1 dir2
echo bla > dir1/file1
tar cf test.tar dir1 dir2

View File

@@ -24,6 +24,7 @@ AT_SETUP([scarce file descriptors])
AT_KEYWORDS([extract extrac11])
AT_TAR_CHECK([
exec </dev/null
dirs='a
a/b
a/b/c
@@ -45,31 +46,37 @@ for dir in $dirs; do
done
done
# Check that "ulimit" itself works.
((ulimit -n 100 &&
tar -cf archive1.tar a 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&- &&
tar -xf archive1.tar -C dest1 a 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&-
) &&
diff -r a dest1/a
# Check that "ulimit" itself works. Close file descriptors before
# invoking ulimit, to work around a bug (or a "feature") in some shells,
# where they squirrel away dups of file descriptors into FD 10 and up
# before closing the originals.
( (exec 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&- &&
ulimit -n 100 &&
tar -cf archive1.tar a &&
tar -xf archive1.tar -C dest1 a
) &&
diff -r a dest1/a
) >/dev/null 2>&1 ||
AT_SKIP_TEST
# Another test that "ulimit" itself works:
# tar should fail when completely starved of file descriptors.
((ulimit -n 4 &&
tar -cf archive2.tar a 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&- &&
tar -xf archive2.tar -C dest2 a 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&-
) &&
diff -r a dest2/a
( (exec 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&- &&
ulimit -n 4 &&
tar -cf archive2.tar a &&
tar -xf archive2.tar -C dest2 a
) &&
diff -r a dest2/a
) >/dev/null 2>&1 &&
AT_SKIP_TEST
# Tar should work when there are few, but enough, file descriptors.
((ulimit -n 10 &&
tar -cf archive3.tar a 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&- &&
tar -xf archive3.tar -C dest3 a 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&-
) &&
diff -r a dest3/a >/dev/null 2>&1
( (exec 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&- &&
ulimit -n 10 &&
tar -cf archive3.tar a &&
tar -xf archive3.tar -C dest3 a
) &&
diff -r a dest3/a >/dev/null 2>&1
) || { diff -r a dest3/a; exit 1; }
],
[0],[],[],[],[],[gnu])

View File

@@ -33,20 +33,20 @@ echo target1 >target1
tar -cf archive.tar -C src . &&
tar -xf archive.tar -C dst1 --warning=no-timestamp &&
diff -c src/file1 dst1/file1 &&
diff -c target1 dst1/target1
diff src/file1 dst1/file1 &&
diff target1 dst1/target1
ln -s target1 dst2/file1
echo target1 >dst2/target1
tar --overwrite -xf archive.tar -C dst2 --warning=no-timestamp &&
diff -c src/file1 dst2/file1 &&
diff -c target1 dst2/target1
diff src/file1 dst2/file1 &&
diff target1 dst2/target1
ln -s target1 dst3/file1
echo target1 >dst3/target1
tar --overwrite -xhf archive.tar -C dst3 --warning=no-timestamp &&
diff -c src/file1 dst3/file1 &&
diff -c src/file1 dst3/target1
diff src/file1 dst3/file1 &&
diff src/file1 dst3/target1
],
[0],[],[],[],[],[gnu])

36
tests/extrac16.at Normal file
View File

@@ -0,0 +1,36 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2010 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 3, 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, see <http://www.gnu.org/licenses/>.
# written by Paul Eggert from a bug report by Denis Excoffier
# <http://lists.gnu.org/archive/html/bug-tar/2010-10/msg00034.html>
# Check extraction of empty directory with -C.
AT_SETUP([extract empty directory with -C])
AT_KEYWORDS([extract extrac16])
AT_TAR_CHECK([
mkdir src src/a src/a/b dest
touch src/a/c
tar -cf archive.tar -C src a &&
tar -xf archive.tar -C dest
],
[0],[],[],[],[],[gnu])
AT_CLEANUP

46
tests/extrac17.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) 2010 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 3, 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, see <http://www.gnu.org/licenses/>.
AT_SETUP([name matching/transformation ordering])
AT_KEYWORDS([extract extrac17])
# Description: Tar 1.24 changed the ordering of name matching and
# name transformation so that the former saw already transformed
# file names (see commit 9c194c99 and exclude06.at). This reverted
# ordering made it impossible to match file names in certain cases.
# In particular, the testcase below would not extract anything.
#
# Reported-by: "Gabor Z. Papp" <gzp@papp.hu>
# References: <x6r5fd9jye@gzp>, <20101026175126.29028@Pirx.gnu.org.ua>
# http://lists.gnu.org/archive/html/bug-tar/2010-10/msg00047.html
AT_TAR_CHECK([
mkdir dir dir/subdir1 dir/subdir2 out
genfile --file dir/subdir1/file1
genfile --file dir/subdir2/file2
tar cf dir.tar dir
tar -x -v -f dir.tar -C out --strip-components=2 --warning=no-timestamp \
dir/subdir1/
],
[0],
[dir/subdir1/file1
])
AT_CLEANUP

47
tests/listed04.at Normal file
View File

@@ -0,0 +1,47 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2010 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 3, 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, see <http://www.gnu.org/licenses/>.
# This checks for the bug reported by Martin Weigel
# <http://lists.gnu.org/archive/html/bug-tar/2010-11/msg00071.html>.
# The test is derived from the ideas in Jean-Louis Martineau's followup email
# <http://lists.gnu.org/archive/html/bug-tar/2010-11/msg00087.html>.
AT_SETUP([--listed-incremental and --one-file-system])
AT_KEYWORDS([listed incremental listed04])
AT_TAR_CHECK([
mkdir dir
echo a >dir/a
echo b >dir/b
tar --one-file-system -cvf archive.tar -g archive.incr dir || exit
tar -tf archive.tar || exit
],
[0],
[dir/
dir/a
dir/b
dir/
dir/a
dir/b
],
[tar: dir: Directory is new
],[],[],[gnu])
AT_CLEANUP

View File

@@ -32,6 +32,7 @@ unset TAR_OPTIONS
AT_CHECK([
AT_UNPRIVILEGED_PREREQ
AT_GZIP_PREREQ
AT_SIGPIPE_PREREQ
AT_SORT_PREREQ
mkdir dir
@@ -47,14 +48,16 @@ mkdir c
# or
# tar: Child returned status 2
tar -c -f a -z --remove-files b c 2>err
# Discard diagnostics that some shells generate about broken pipes,
# and discard all of tar's diagnostics except for the ones saying "(child)".
# Gzip's exit code is propagated to the shell. Usually it is 141.
# Convert all non-zero exits to 2 to make it predictable.
(tar -c -f a -z --remove-files b c 2>err || (exit 2) ) 2>/dev/null
EC=$?
sed -n '/(child)/p' err >&2
rm err
find . | sort
# Gzip exit code is propagated to the shell. Usually it is
# 141. We convert all non-zero exits to 2 to make it predictable.
test $EC && exit 2
exit $EC
],
[2],
[.

View File

@@ -26,13 +26,16 @@ AT_KEYWORDS([sigpipe])
# <20100319184141.GC30047@wo.int.altlinux.org>
AT_CHECK([
AT_SIGPIPE_PREREQ
genfile --length 2048 --file first
genfile --length 2048 --file second
genfile --length 2049 --file third
tar cf archive first second third
tar tf archive | :
# Discard diagnostics that some shells generate about broken pipes.
(tar tf archive 2>&3 | :) 3>&2 2>/dev/null
],
[0])

47
tests/sparse04.at Normal file
View File

@@ -0,0 +1,47 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright (C) 2010 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 3, 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([storing long sparse file names])
AT_KEYWORDS([sparse sparse04])
# Description: Tar versions from 1.15.92 to 1.25 would incorrectly
# store sparse file names longer than 100 characters in pax mode.
# Namely, the `path' keyword of the produced PAX header would contain the
# crafted name of the header itself, instead of that of the file.
# Reported by: Kamil Dudka <kdudka@redhat.com>
# References: <201011250026.44908.kdudka@redhat.com>,
# http://lists.gnu.org/archive/html/bug-tar/2010-11/msg00099.html
m4_define([NAME_111],
[123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960])
AT_TAR_CHECK([
genfile --sparse --file NAME_111 --block-size 512 8M A || AT_SKIP_TEST
tar -c --sparse --posix NAME_111 | tar t
],
[0],
[NAME_111
],
[],
[],
[],
[pax])
AT_CLEANUP

View File

@@ -1,7 +1,8 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 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
@@ -80,6 +81,13 @@ m4_define([AT_GZIP_PREREQ],[
cat /dev/null | m4_if([$1],[],gzip,[$1]) - > /dev/null 2>&1 || AT_SKIP_TEST
])
dnl AT_SIGPIPE_PREREQ - Skip test unless SIGPIPE handling is the default
m4_define([AT_SIGPIPE_PREREQ],[
case `(cat "$at_myself" 2>&3 | :) 3>&1 >/dev/null` in #(
?*) AT_SKIP_TEST;;
esac
])
dnl AT_SORT_PREREQ - Skip test if sort utility outputs unwanted data on stderr
m4_define([AT_SORT_PREREQ],[
test -z "`sort < /dev/null 2>&1`" || AT_SKIP_TEST
@@ -121,6 +129,7 @@ m4_include([verbose.at])
m4_include([append.at])
m4_include([append01.at])
m4_include([append02.at])
m4_include([append03.at])
m4_include([xform-h.at])
m4_include([xform01.at])
@@ -154,6 +163,8 @@ m4_include([extrac12.at])
m4_include([extrac13.at])
m4_include([extrac14.at])
m4_include([extrac15.at])
m4_include([extrac16.at])
m4_include([extrac17.at])
m4_include([label01.at])
m4_include([label02.at])
@@ -171,6 +182,7 @@ m4_include([incr02.at])
m4_include([listed01.at])
m4_include([listed02.at])
m4_include([listed03.at])
m4_include([listed04.at])
m4_include([incr03.at])
m4_include([incr04.at])
m4_include([incr05.at])
@@ -220,6 +232,7 @@ m4_include([shortrec.at])
m4_include([sparse01.at])
m4_include([sparse02.at])
m4_include([sparse03.at])
m4_include([sparse04.at])
m4_include([sparsemv.at])
m4_include([spmvp00.at])
m4_include([spmvp01.at])
@@ -229,6 +242,8 @@ m4_include([update.at])
m4_include([update01.at])
m4_include([update02.at])
m4_include([verify.at])
m4_include([volume.at])
m4_include([volsize.at])

View File

@@ -30,13 +30,12 @@ AT_SETUP([truncate])
AT_KEYWORDS([truncate filechange])
AT_TAR_CHECK([
genfile --file foo --length 50000k
genfile --file foo --length 200k
genfile --file baz
genfile --run --checkpoint 10 --length 49995k --truncate foo -- tar --checkpoint -vcf bar foo baz
genfile --run --checkpoint 10 --length 195k --truncate foo -- tar --checkpoint --checkpoint-action=echo --checkpoint-action=sleep=1 -vcf bar foo baz
echo Exit status: $?
echo separator
sleep 1
genfile --file foo --seek 49995k --length 5k --pattern=zeros
genfile --file foo --seek 195k --length 5k --pattern=zeros
tar dvf bar],
[1],
[foo

37
tests/verify.at Normal file
View File

@@ -0,0 +1,37 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2010 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 3, 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.
# Check that tar --verify works.
# Problem reported by Gilles Espinasse in
# <http://lists.gnu.org/archive/html/bug-tar/2010-11/msg00065.html>.
AT_SETUP([verify])
AT_KEYWORDS([verify])
AT_TAR_CHECK([
touch foo
tar -cvf archive.tar --verify foo
],
[0],
[foo
Verify foo
])
AT_CLEANUP