127 Commits

Author SHA1 Message Date
Sergey Poznyakoff
20b55f0679 Version 1.29 2016-05-16 11:51:12 +03:00
Sergey Poznyakoff
35b292ac4b Minor fix
* src/names.c (new_name): rename to make_file_name. All uses changed.
2016-05-16 11:50:19 +03:00
Sergey Poznyakoff
61cd3fd268 Fix argument handling when running external commands.
* src/system.c (xexec): Use sh -c to run the command.  This fixed
bug introduced by 7b5e80396 (tar 1.27)
* doc/tar.texi: Fix checkpoint examples: (1) $TAR_FILENAME
is not available when creating archive and (2) --checkpoint
can't be used as abbreviation of --checkpoint-action
2016-04-14 11:51:38 +03:00
Sergey Poznyakoff
3010818f36 Remove iotty test
The auxiliary utility ttyemu proved to be unreliable.  Given existing
differences between pty implementations and termios ioctls on various
platforms, writing it in a portable way requires effort disproportional
to its actual purpose.

* configure.ac: Remove check for grantpt
* gnulib.modules: Remove posix_openpt, ptsname, and unlockpt
* tests/Makefile.am (TESTSUITE_AT): Remove iotty.at
(check_PROGRAMS): Remove ttyemu.
* tests/testsuite.at: Remove iotty.at
* tests/iotty.at: Remove.
* tests/ttyemu.c: Remove.
2016-04-06 08:34:55 +03:00
Pavel Raiskup
733e2741b1 xattrs: fix build on Darwin
Be careful to define HAVE_XATTRS when not all needed xattr-related
functions are properly defined either in libc or libattr.

Reported independently by Denis Excoffier and Dominyk Tille.

* acinclude.m4 (TAR_HEADERS_ATTR_XATTR_H): Check for each xattr
function separately.  Don't AC_CHECK_LIB (LIBS is filled by
AC_SEARCH_LIBS when necessary).
* src/Makefile.am: The LDADD -lattr was redundant.
2016-04-05 17:55:19 +03:00
Sergey Poznyakoff
195a25316c Remove --preserve option
* src/tar.c: Remove --preserve option
* NEWS: Update.
* doc/tar.texi: Update.
2016-03-24 08:39:52 +02:00
Sergey Poznyakoff
74e3b497c4 Fix testcase
* tests/time02.at: Sort tar -d output
2016-03-24 08:38:38 +02:00
Sergey Poznyakoff
29f652871e Update THANKS file 2016-03-24 07:30:16 +02:00
Jeremy Bobbio
13d04fe6ae New option --clamp-mtime
The new `--clamp-mtime` option will change the behavior of `--mtime` to only
use the time specified if the file mtime is newer than the given time.
The `--clamp-mtime` option can only be used together with `--mtime`.

Typical use case is to make builds reproducible: to loose less
information, it's better to keep the original date of an archive, except for
files modified during the build process. In that case, using a reference
(and thus reproducible) timestamps for the latter is good enough. See
<https://wiki.debian.org/ReproducibleBuilds> for more information.

Patch submitted by Jeremy Bobbio and
Daniel Kahn Gillmor <dkg@fifthhorseman.net>

* doc/tar.1: Document --clamp-mtime
* doc/tar.texi: Likewise.

* src/common.h (set_mtime_option_mode): New enum
(set_mtime_option): Change type to enum set_mtime_option_mode.
(NEWER_OPTION_INITIALIZED): Rename to NEWER_OPTION_INITIALIZED.
* src/create.c (start_header): Set mtime depending on set_mtime_option.
* src/tar.c (options,parse_opt): New option --clamp-mtime
(decode_options): Initialize mtime_option

* tests/time02.at: New testcase.
* tests/Makefile.am: Add new testcase
* tests/testsuite.at: Likewise.
2016-03-24 07:26:27 +02:00
Sergey Poznyakoff
8d31493c99 Acknowledgments
* THANKS: Add Dagobert Michelsen
2016-03-21 20:46:19 +02:00
Sergey Poznyakoff
752b447f3e Fix the testsuite
* tests/sparse06.at: Don't use timeout: depending on the filesystem
mounted, current LA and lots of other factors, creation of archive can
take much more time than the expected 2 seconds.
2016-03-21 20:33:26 +02:00
Sergey Poznyakoff
a3aa7003ea Fix ckmtime
* gnulib.modules: Use timespec-sub
* tests/ckmtime.c: Use second resolution.
2016-03-21 13:35:32 +02:00
Sergey Poznyakoff
143dc63ffa Fix the testsuite
* tests/sparse05.at: Use autom4te magic to generate mapfile,
instead of the shell command seq, which is not always available.
* tests/listed03.at: Skip the test if xgetcwd fails.
* tests/ckmtime.c: New file.
* tests/Makefile.am: Build ckmtime
* tests/testsuite.at (AT_CHECK_TIMESTAMP): Check whether newly created
files have timestamps consistent with the creation time.  Skip the test
if not.
* tests/incr01.at: Use AT_CHECK_TIMESTAMP
* tests/incr02.at: Likewise.
* tests/incr03.at: Likewise.
* tests/incr04.at: Likewise.
* tests/incr05.at: Likewise.
* tests/incr06.at: Likewise.
* tests/incr07.at: Likewise.
* tests/incr08.at: Likewise.
* tests/incr09.at: Likewise.
* tests/incr10.at: Likewise.
* tests/incr11.at: Likewise.
* tests/incremental.at: Likewise.
* tests/listed01.at: Likewise.
* tests/listed02.at: Likewise.
* tests/listed04.at: Likewise.
* tests/listed05.at: Likewise.
2016-03-20 23:11:27 +02:00
Sergey Poznyakoff
c0fb0740fa Testsuite fixes.
* paxutils: Update.
* src/unlink.c (flush_deferred_unlinks): OpenSolaris sets EEXIST
instead of ENOTEMPTY if trying to remove a non-empty directory.
* tests/numeric.at: Avoid using awk -v: some older awks don't support
that option.  Also fix environment variable usage.
* tests/onetop05.at: Skip test if unable to set initial directory
mode bits.
* tests/sparse06.at: Use --quiet option.
2016-03-18 22:18:58 +02:00
Sergey Poznyakoff
6ac0dd1d73 Revise docs 2016-03-18 14:27:27 +02:00
Sergey Poznyakoff
160fb9abd2 Fix build with --enable-gcc-warnings
* configure.ac: Disable stack-protector warnings
2016-03-18 13:08:39 +02:00
Sergey Poznyakoff
f6ad0e4af2 Improve testsuite
* tests/iotty.at: Skip test if ttyemu can't do its job
2016-03-17 14:22:35 +02:00
Sergey Poznyakoff
e4b246c14a Document xattrs, ACL and SELinux-related options.
* doc/tar.1: Document all options.
* doc/tar.texi: Likewise.
2016-03-16 20:08:00 +02:00
Sergey Poznyakoff
2a7c84b4a9 Fix appending to archive with changed blocking factor.
* src/buffer.c (flush_archive): If previous reading attempt resulted
in short read, correctly use the remaining record space.
(backspace_output): Fix position calculation (still has to be
improved).

* tests/append05.at: New test case.
* tests/Makefile.am: Add new test.
* tests/testsuite.at: Likewise.
2016-03-15 00:02:40 +02:00
Sergey Poznyakoff
da7845c656 Fix coredump on parsing invalid traditional option
* src/tar.c (find_argp_option): Fix loop termination condition.
2016-03-14 13:13:04 +02:00
Sergey Poznyakoff
8980ecd62d Update copyright years 2016-01-20 11:29:17 +02:00
Sergey Poznyakoff
63f2e969dd Allow escaped delimiters in transform expressions.
Patch provided by Charles McGarvey and Flavio Poletti.

* src/transform.c (parse_transform_expr): Allow escaped delimiters
in transform expressions.
* tests/xform02.at: New test case.
* tests/Makefile.am: Add xform02.at
* tests/testsuite.at: Include xform02.at
* THANKS: Update.
2016-01-20 11:16:02 +02:00
Sergey Poznyakoff
445293654d Fix eventual dereference of uninitialized pointer.
* src/exclist.c (hg_initfn): Initialize hgopt.
2015-12-17 16:04:40 +02:00
Pavel Raiskup
b5f581e637 sparse: fix use of indeterminate value
* src/xheader.c (sparse_map_decoder): Move 'e' up from loop-block.
2015-12-17 16:01:18 +02:00
Sergey Poznyakoff
0f26331b17 fix a typo
* doc/tar.texi (Incremental Dumps): Add missing --file to the
'--list' example.
2015-12-11 15:21:04 +02:00
Sergey Poznyakoff
196fef9b40 Minor fixes.
* doc/tar.texi: Document position-sensitive options in a
separate subsection.
* src/names.c (names_argp,names_argp_children): Explicitly initialize
all members.
2015-12-11 14:19:44 +02:00
Sergey Poznyakoff
68dd249987 Minor fix 2015-12-11 01:10:43 +02:00
Sergey Poznyakoff
4cf2af4500 Fix handling of filename-selection options.
Filename-selection options are --wildcards, --recursive, etc. (see
names.c for a complete list).  These options are position-sensitive,
i.e. each such option affects all filenames and filename-selection
options that appear after it until eventually cancelled by a
corresponding counterpart option.

These options can appear in "file-from" file lists, which means that
they cannot be handled right away, but instead should be put on
the "name_elt" list and processed sequentionally, as file name arguments
are.

* src/common.h (warn_regex_usage): Remove.
(name_add_name): Change signature.
(name_add_dir, name_add_file): Remove prototypes.
* src/names.c (name_add_option, name_add_dir)
(name_add_file): Static functions.
(names_options, is_file_selection_option, names_parse_opt): Static functions.
(names_argp_children): New variable.
(NELT_NAME, NELT_CHDIR)
(NELT_FILE, NELT_NOOP): Redefine as enum nelt_type.
(NELT_FMASK): Remove.
(NELT_OPTION): New constant.
(name_elt) <type>: Change type.
<v.opt>: New member.
(name_elt_alloc_matflags): Remove.
(name_add_name): Take one argument.
(name_add_option): New static function.
(name_add_file): Take one argument.
(read_next_name): Use filename_terminator and
verbatim_files_from_option to initialize file.term and file.verbatim.
* src/tar.c: Move handling of filename-selection options to names.c

* tests/T-dir00.at: Fix typo.
* tests/T-recurse.at: Remove expected failure.
2015-12-11 00:50:23 +02:00
Pavel Raiskup
cadc43ace5 better test --{,no-}recursion options
* tests/recurs02.at: Also test --list mode.
* tests/T-recurse.at: New test case.  Test that -T option works
correctly together with --{,no-}recursion.
* tests/Makefile.am: Mention new test T-recurse.at.
* tests/testsuite.at: Likewise.
2015-12-10 14:55:34 +02:00
Pavel Raiskup
239441b5df Bugfix
* src/buffer.c (try_new_volume): Warn if user supplied malformed
tar archive.
Consistently use WARN (instead of ERROR) when reporting.
2015-12-06 22:14:23 +02:00
Sergey Poznyakoff
0a93c16c62 Fix segfault when extracting from a multi-volume archive.
Fix suggested by Pavel Raiskup.

* src/buffer.c (try_new_volume): Fix dereferencing NULL pointer.
* tests/multiv09.at: New testcase.
* tests/Makefile.am: Add new testcase.
* tests/testsuite.at: Likewise.
2015-12-06 22:02:16 +02:00
Sergey Poznyakoff
5dd490e7f1 Fix NEWS 2015-12-06 21:20:48 +02:00
Pavel Raiskup
68e9ab4966 numeric-owner: print big UID/GID correctly
* src/list.c (simple_print_header): Do not parse ustar header
for UID/GID again (tar_stat_info has already been correctly
filled with respect to possible uid/gid extended headers).
* tests/numeric.at: New testcase for --numeric-owner option.
* tests/Makefile.am: Add new testcase.
* tests/testsuite.at: Likewise.
2015-12-06 21:18:51 +02:00
Sergey Poznyakoff
b684326e69 Use SEEK_HOLE for hole detection
Based on patch by Pavel Raiskup.

Use SEEK_HOLE/SEEK_DATA feature of lseek on systems that support
it.  This can make archiving of sparse files much faster.

Implement the --hole-detection option to allow users to select
hole-detection method.

* src/common.h (hole_detection_method): New enum.
(hole_detection): New global.
* src/sparse.c  (sparse_scan_file_wholesparse): New function as a
method for detecting sparse files without any data.
(sparse_scan_file_raw): Rename from sparse_scan_file; with edits.
(sparse_scan_file_seek): New function.
(sparse_scan_file): Reimplement function.
* src/tar.c: New option --hole-detection

* tests/checkseekhole.c: New file.
* tests/.gitignore: Mention two test binaries.
* tests/Makefile.am: Add new tests.
* tests/testsuite.at (AT_SEEKHOLE_PREREQ): New macro.
Include sparse06.at.
* tests/sparse06.at: New test case.
* tests/sparse02.at: Force raw hole-detection method.
* tests/sparsemv.at: Likewise.
* tests/sparsemvp.at: Likewise.

* doc/tar.1: Document --hole-detection option.
* doc/tar.texi: Document hole-detection algorithms and
command-line options.
* NEWS: Document hole-detection.
2015-12-06 00:14:55 +02:00
Sergey Poznyakoff
589ba77faf Catch compressor execution errors.
* src/misc.c (write_fatal_details): Move to buffer.c
* src/buffer.c (write_fatal_details): Close the archive and wait for
the compressor program to terminate in order to catch eventual execution
errors.
* src/system.c (sys_child_open_for_compress): Ignore SIGPIPE so tar will
not silently terminate when unable to write to the compressor.
* tests/comperr.at: New file.
* tests/Makefile.am: Add comperr.at
* tests/testsuite.at: Include comperr.at
2015-12-05 16:54:26 +02:00
Sergey Poznyakoff
6ea9e62bb3 Upgrade paxutils 2015-12-05 08:48:03 +02:00
Sergey Poznyakoff
d02c81df15 Fix extraction from concatenated incremental archives with renamed directories.
Complements 15c02c2b.

* src/extract.c (delayed_set_stat): Change type of file_name.
(delay_set_stat): Allocate file_name member.
(free_delayed_set_stat): Free file_name.
(fixup_delayed_set_stat): New function.
(rename_directory): Call fixup_delayed_set_stat on success.

* tests/incr11.at: New testcase.
* tests/incr10.at: Improve description.
* tests/Makefile.am: Add incr11.at
* tests/testsuite.at: Add incr11.at
2015-11-29 21:11:08 +02:00
Sergey Poznyakoff
e426787454 Fix bug in the inplementation of --one-top-level.
When extracting an archive that contains './' with the --one-top-level option,
the mode and ownership of '.' would be incorrectly applied to the current
working directory, instead of the requested top-level directory.

* src/list.c (enforce_one_top_level): Map '.' to the top-level
directory.
* tests/Makefile.am: Add onetop05.at
* tests/testsuite.at: Include onetop05.at.
* tests/onetop05.at: New file.
* tests/onetop01.at: Fix keywords.
* tests/onetop02.at: Likewise.
* tests/onetop03.at: Likewise.
* tests/onetop04.at: Likewise.
2015-11-21 21:56:49 +02:00
Sergey Poznyakoff
e6fcc73efa Work around unlinkat bug on FreeBSD and GNU/Hurd
* src/unlink.c (dunlink_insert): New function.
(flush_deferred_unlinks): Skip cwds and nonempty directories
at the first pass.  If force is requested, run a second pass
removing them.
(queue_deferred_unlink): Make sure current working directory
entries are sorted in descending order by the value of dir_idx.
This makes sure they will be removed in right order, which works
around unlinkat bug on FreeBSD and GNU/Hurd.
* tests/remfiles08b.at: Remove expected failure.
* tests/remfiles09b.at: Likewise.
2015-11-11 13:01:45 +02:00
Sergey Poznyakoff
6167c23e22 Fix coredump on FreeBSD when TAR_OPTIONS is set
* src/tar.c (parse_default_options): Use program_name instead of
program_invocation_short_name.  On some systems the latter is NULL when
the function is called, which causes coredumps.
(tar_set_quoting_style): Likewise.
* src/names.c: Likewise.
2015-11-10 18:25:47 +02:00
Sergey Poznyakoff
5e2a1d5b38 Use sort in T-dir tests. 2015-11-02 13:54:26 +02:00
Sergey Poznyakoff
4aebc943bb Fix distclean in tests/
* tests/Makefile.am: Remove "download"
2015-11-02 13:19:36 +02:00
Sergey Poznyakoff
1a615a41f5 New options: --owner-map and --group-map.
* NEWS: Update.
* doc/tar.1: Document --owner-map and --group-map
* doc/tar.texi: Likewise.

* src/map.c: New file.
* src/Makefile.am: Add map.c
* src/common.h (owner_map_read, owner_map_translate)
(group_map_read, group_map_translate): New protos.
* src/create.c (start_header): Use owner_map_translate
and group_map_translate to optionally translate user/group names/ids.
* src/tar.c: New options --owner-map and --group-map.

* tests/map.at: New file.
* tests/Makefile.am: Add map.at
* tests/testsuite.at: Include map.at.
2015-11-02 13:00:39 +02:00
Kir Kolyshkin
cdf41c383f doc: fix font and spelling typos
* doc/tar.1: Fix font and spelling typos in man page.
Copyright-paperwork-exempt: yes
2015-09-24 09:22:51 -07:00
Paul Eggert
a65086c71c Fix problems caught by static checking
Most of these can be caught by configuring with --enable-gcc-warnings.
Problem reported by Pavel Raiskup in:
http://lists.gnu.org/archive/html/bug-tar/2015-09/msg00001.html
* src/buffer.c (format_total_stats):
Prefer pointer to const when it’s OK to use const.
(default_total_format): Now const.
* src/buffer.c (default_total_format):
* src/exclist.c (excfile_head, excfile_tail, vcs_ignore_files):
* src/misc.c (namebuf_add_dir, namebuf_finish):
* src/tar.c (verbatim_files_from_option, option_set_in_cl)
(optloc_eq, set_old_files_option):
Now static.
* src/common.h: Adjust to match the other changes described here.
* src/exclist.c (info_cleanup_exclist):
* src/tar.c (argp_program_version, argp_program_bug_address):
Remove; unused.
(parse_default_options): Define via prototype instead of old style.
(parse_default_options, decode_options):
Fill out incomplete initializers.
2015-09-24 08:32:15 -07:00
Sergey Poznyakoff
ae23a57d70 Improve option sanity checking
Any two conflicting options are reported only if they both occur in
the command line.  Otherwise, options defined in the command line
silently override those set in the TAR_OPTIONS environment variable.

* src/common.h (option_source): New enum.
(option_locus): New struct.
* src/names.c (name_elt): New member: line.
(name_add_file): Initialize line.
(read_name_from_file): Keep track of input line number for diagnostic
purposes.
(handle_option): Take a pointer to struct name_elt as 2nd parameter;
pass locus info to more_options().
* src/tar.c (tar_args): New member: loc.
(option_class): New enum.
(optloc_save,optloc_lookup)
(option_set_in_cl,optloc_eq): New functions.
(set_use_compress_program_option): Take into account option location.
(set_old_files_option): New function.
(parse_opt): Keep track of option locations.
(more_options): Improve error reporting.
(parse_default_options): New function.
(decode_options): Parse TAR_OPTION and command line separately.
Options from the latter silently override those from the former.

* lib/prepargs.c: Remove.
* lib/prepargs.h: Remove.
* lib/Makefile.am: Update.
2015-08-31 08:37:46 +03:00
Sergey Poznyakoff
c440a92627 Improve check-full
* tests/atlocal.in: Download external archives to $abs_builddir/download.
(tarball_prereq): Create destination directory if necessary.
* tests/.gitignore: Add download
2015-08-24 13:05:52 +03:00
Sergey Poznyakoff
aa9676dcad Fix check-full
* tests/atlocal.in (TAR_DATA_URL): Berlios is dead.  Get
test archives from gnu.org.ua
2015-08-24 12:50:49 +03:00
Sergey Poznyakoff
6cb94e37a9 Include gnulib and paxutils as submodules.
* .gitmodules: New file.
* README-alpha: Update.
* README-hacking: Update.
* bootstrap: Install slightly modified version from the gnulib repo.
* bootstrap.conf: Add paxutils-related stuff.
* .gitignore: Update.
* doc/.gitignore: Update.
* po/.gitignore: Update.
* gnu/Makefile.am
2015-08-24 11:52:14 +03:00
Sergey Poznyakoff
232a7258c3 Update docs.
* doc/tar.1: Document --verbatim-files-from option.
2015-08-24 09:29:04 +03:00
Sergey Poznyakoff
429bd311b7 Add missing VCS files to --exclude-vcs list
* src/tar.c (vcs_file_table): Add .gitmodules and .gitattributes
* doc/tar.texi: Update.
2015-08-20 17:52:20 +03:00
Sergey Poznyakoff
eb621c67cf Options to control option handling in file lists.
The --verbatim-files-from option disables option handling in
file lists.  The --no-verbatim-files-from reverts its effect.

The --null option implies --verbatim-files-from.  This restores
the documented behavior, broken by 26538c9b.

* src/common.h (verbatim_files_from_option): New global.
* src/names.c (name_elt): New member: file.verbatim
(name_add_file): Take 'verbatim' state as its third parameter.
(read_next_name): Don't call handle_option if file.verbatim
is set.
* src/tar.c: New options --verbatim-files-from and
--no-verbatim-files-from.

* doc/tar.texi: Document --verbatim-files-from and
--no-verbatim-files-from options.
* NEWS: Update.
* configure.ac: Version 1.28.90

* tests/T-null2.at: New testcase.
* tests/Makefile.am: Update.
* tests/testsuite.at: Update.
2015-08-03 16:47:22 +03:00
Anders Jonsson
21f86195b7 Fix typos (preceeded etc.)
Copyright-paperwork-exempt: yes
2015-07-25 08:47:25 -07:00
Paul Eggert
fe3b106cb3 tar: fix symlink race and symlink transform bug
Problem reported by Tobias Stoeckmann in:
http://lists.gnu.org/archive/html/bug-tar/2015-07/msg00004.html
* gnulib.modules: Add areadlinkat-with-size.
* src/create.c: Include areadlink.h.
(dump_file0): Use areadlinkat_with_size, rather than trying to do
it by hand, incorrectly.  This also avoids assumption that
the symlink contents fit on the stack.  Also, use the transformed
link name, not the original link name, when deciding whether the
name is long enough to require writing a long link.
2015-07-13 09:53:56 -07:00
Paul Eggert
3828942550 tar: port -d to longer symlinks
* src/compare.c (diff_symlink):
Don't use alloca on symlink length; it might be too big for the stack.
Don't assume that readlinkat's return value fits in 'int'.
Prefer memcmp to strncmp where either will do.
2015-07-13 09:53:56 -07:00
Paul Eggert
d95457e007 tar: port to recent gnulib
* gnulib.modules: Remove 'acl' and add 'file-has-acl'.
2015-07-13 09:53:56 -07:00
Paul Eggert
da06935f6e tar: pacify GCC 5.1 -Wformat-signedness
* lib/wordsplit.c (struct wordsplit_node.flags):
Now unsigned, so that 'printf ("%x", p->flags)' doesn't provoke GCC.
* src/incremen.c (read_num, dumpdir_ok):
Don't printf an int with %x or %o.
2015-07-13 09:53:55 -07:00
Sergey Poznyakoff
15c02c2b9d Fix extraction from concatenated incremental archives.
* src/common.h (remove_delayed_set_stat): New proto.
* src/extract.c (free_delayed_set_stat)
(remove_delayed_set_stat): New function.
(apply_nonancestor_delayed_set_stat): Use free_delayed_set_stat.
* src/misc.c (safer_rmdir): Remove delayed_set_stat entry
corresponding to the removed directory.
* tests/incr10.at: New test case.
* tests/Makefile.am: Add new test.
* tests/testsuite.at: Likewise.
2015-04-16 13:02:10 +03:00
Sergey Poznyakoff
0c4aa85e6c Fix make installcheck
Make installcheck would fail unless make check had been run before it.
Reported by Erik Brangs <erik.brangs@gmx.de>

* tests/Makefile.am (installcheck-local): Depend on $(check_PROGRAMS)
2015-04-10 11:35:44 +03:00
Paul Eggert
731b7b07de tar: don't assume GZIP
* Makefile.am (dist-hook): Port to gzip implementations that
warn about nontrivial settings in the GZIP environment var.
2015-03-17 22:56:01 -07:00
Paul Eggert
4eb1484dce tar: don't suggest GZIP
* doc/tar.texi (gzip): Don't suggest using the GZIP environment
variable, as it will be deprecated in the next gzip release.
2015-03-17 10:46:51 -07:00
Sergey Poznyakoff
1847ec67ce Improve compression format recognition
Some comressed archives can pass the checksum test, which makes tar
treat them as uncompressed archives.

* src/buffer.c (check_compressed_archive): Test the checksum only
if the block we read looks like a valid tar header (i.e. has
a magic string).
2015-02-19 17:00:58 +02:00
Paul Eggert
9c2b57232e tar: port xattr-at.c to Solaris 10
* lib/xattr-at.c (setxattrat, lsetxattrat, getxattrat, lgetxattrat)
(listxattrat, llistxattrat): Compile only if HAVE_XATTRS, so that
the code doesn't call functions that are not declared.
2015-01-05 20:24:42 -08:00
Paul Eggert
55fb2fc38f tar: port wordsplit attribute to Sun C
Reported by Ted Carr in:
http://lists.gnu.org/archive/html/bug-tar/2015-01/msg00002.html
* lib/wordsplit.h (__WORDSPLIT_ATTRIBUTE_FORMAT):
New macro, taken from Gnulib.
(struct wordsplit): Use it.
* lib/wordsplit.c (_wsplt_error): Use it.
2015-01-05 20:09:09 -08:00
Sergey Poznyakoff
5a9ac8312e Silent a cc warning
* src/xheader.c (xheader_string_end): Make sure pointer
arithmetics applies on char*.
2014-12-17 08:37:14 +02:00
Paul Eggert
7bf812579c tar: port ISFOUND, WASFOUND to C89
Problem reported by Romano Maspero in:
http://lists.gnu.org/archive/html/bug-tar/2014-12/msg00010.html
* src/common.h (ISFOUND, WASFOUND): Port to C89.
2014-12-11 19:02:43 -08:00
Sergey Poznyakoff
1209e0ebff Fix tar -c -l file file
When the same file is added several times to the archive, count
correctly the number of hard links.  See also 37ddfb0b.

* src/create.c (dump_hard_link): Don't decrease nlink if it is 0.
* tests/link04.at: Test -cl options.
2014-12-10 04:34:02 +02:00
Sergey Poznyakoff
e7b6f8e3ae Honor the pax-option overrides when creating archive.
Changes proposed by Denis Excoffier.

* NEWS: Fix typos.
* doc/tar.texi: Fix typos.  Improve recipe for creation of binary
equivalent archives.
* src/create.c (write_extended): Use the value of the
--mtime option (if specified) as the default for exthdr.mtime.
* src/xheader.c (xheader_store): Create the header if at least
one override is supplied in --pax-option.
2014-11-07 13:15:54 +02:00
Sergey Poznyakoff
586a6263e9 Add testcase for the previous commit.
* tests/sparse05.at: New file.
* tests/Makefile.am: Add sparse05.at
* tests/testsuite.at: Include sparse05.at
2014-11-07 11:47:44 +02:00
Pavel Raiskup
ec94fbdf45 Fix bug in sparse file listing
List posix archives containing sparse files >8GB correctly and do not fail.
This fixes also bug in format of listing for sparse files >8GB - now the
real size is printed instead of the effective one (this is not strictly
posix format related).

* src/list.c: Remove redundant assignment.
* src/tar.h: Add new 'real_size' and 'real_size_set' fields in
  tar_stat_info struct.
* src/xheader.c: Correctly handle (especially sparse) file sizes directly in
  xheader_decode().
2014-11-07 10:21:41 +02:00
Sergey Poznyakoff
c48f4e8f6c Fix a typo 2014-10-15 14:20:07 +03:00
Sergey Poznyakoff
e7c99a4dd1 Fix README
Remove the reference to PORTS
2014-10-01 23:19:02 +03:00
Sergey Poznyakoff
e9ddc08da0 Bugfixes.
* doc/tar.1: Fix typo in font spec.
* src/tar.c (sort_mode_arg, sort_mode_flag): Protect "inode"
(SAVEDIR_SORT_INODE) with D_INO_IN_DIRENT
2014-09-25 00:22:16 +03:00
Sergey Poznyakoff
163e96a0e6 Bugfix: entries read from the -T file did not get proper matching_flag.
* src/common.h (name_add_file): Change signature.
* src/names.c (name_elt_alloc_matflags): New function.
(name_add_name): Use name_elt_alloc_matflags.
(name_add_file): Take matching flags as third argument.
(read_next_name): Remove trailing slashes.
* src/tar.c (parse_opt): Pass matching_flags to name_add_file.

* tests/T-dir00.at: New file.
* tests/T-dir01.at: New file.
* tests/Makefile.am: Add new testcases.
* tests/testsuite.at: Likewise.
2014-09-18 23:01:22 +03:00
Sergey Poznyakoff
0e0a852e91 Improve documentation.
* doc/tar.1: Document --skip-old-files and --warning=existing-file
* doc/tar.texi: Document --warning=existing-file
2014-08-16 09:42:25 +03:00
Sergey Poznyakoff
b500277de7 Version 1.28 2014-07-27 23:45:19 +03:00
Nathan Stratton Treadway
002bf86821 Minor change in docstrings.
nor ch#
2014-07-27 23:31:26 +03:00
Nathan Stratton Treadway
fcde08534b Restructure the remfiles testsuite. 2014-07-27 23:27:28 +03:00
Sergey Poznyakoff
a5db4ba5cb Don't build ttyemu and run tty I/O test if grantpt is not available.
* configure.ac (TAR_COND_GRANTPT): Define conditional depending
on whether grantpt is available.
* gnulib.modules: Remove grantpt. It relies upon a helper binary
pt_chown which it installs and which is useless in the testsuite.
* tests/Makefile.am [TAR_COND_GRANTPT]: Build ttyemu
* tests/iotty.at: Skip test if ttyemu is not build.
* tests/ttyemu.c (noecho): Fix error message
(main): Use TIOCSCTTY if it is defined.
2014-07-22 04:29:25 +03:00
Benno Schulenberg
20ab569dc3 Fix a typo and some wordings in the documentation.
* doc/tar.texi: Fix some missing articles, and make it clearer
that "any" does not mean "anything" but "either of the two".
2014-07-22 03:37:41 +03:00
Nathan Stratton Treadway
f86e0605d0 Fix the testsuite
* tests/incr07.at: Don't assume case-sensitive filesystem.
2014-07-22 03:34:20 +03:00
Paul Eggert
4423e1743e tar: minor fixups related to recent checkpoint.c change
* src/checkpoint.c (getwidth, format_checkpoint_string):
Use long and strtol, not int, to avoid overflow issues.
(getwidth): Don't assume termios.h defines TIOCGWINSZ,
as it doesn't on some older hosts.
2014-07-10 22:35:05 -07:00
Sergey Poznyakoff
8d087fbb0b Bugfixes
* gnulib.modules: Add faccessat
* src/checkpoint.c: Include termios.h
2014-07-11 08:09:30 +03:00
Nathan Stratton Treadway
dc72f4d114 tar: document xgetcwd test case better
* src/misc.c (normalize_filename): Add commentary for clarity.
* tests/extrac09.at: Retitle test case and add comments for clarity.
2014-06-28 23:57:58 -07:00
Sergey Poznyakoff
576e99a21c Fix typos in ChangeLog
* ChangeLog.CVS: Fix typos.
* ChangeLog.amend: New file.
* Makefile.am: Define changelog_amend_file.
2014-06-24 11:53:35 +03:00
Paul Eggert
fc58a8bd98 tar: do not dereference NULL pointer with '--remove-files .'
Problem reported by Thorsten Hirsch in:
http://lists.gnu.org/archive/html/bug-tar/2014-04/msg00011.html
* src/unlink.c (flush_deferred_unlinks):
Do not attempt to find the parent of "." when "." is
at the top level.
* tests/remfiles10.at: New file.
* tests/Makefile.am (TESTSUITE_AT):
* tests/testsuite.at: Add it.
2014-04-29 14:22:59 -07:00
Sergey Poznyakoff
7808b6981b Refuse to write archive contents to a tty.
* NEWS: Update.
* src/buffer.c (_open_archive): Refuse to write to a tty.
* tests/iotty.at: Test output to a tty.
2014-03-27 07:06:02 +02:00
Vitezslav Cizek
852895847f fix an eternal loop in handle_option
* src/names.c (handle_option): increment loop counter
2014-03-26 23:01:22 +02:00
Sergey Poznyakoff
b0902369e7 Fail if archive comes from a terminal.
Based on patch from Pavel Raiskup <praiskup@redhat.com>.

* gnulib.modules: Add new modules.
* src/buffer.c (_open_archive): Refuse to read archive from a tty.
* tests/Makefile.am (TESTSUITE_AT): Add iotty.at
(check_PROGRAMS): New program ttyemu
* tests/testsuite.at: Include iotty.at
* tests/iotty.at: New file.
* tests/ttyemu.c: New file.
2014-03-20 19:46:30 +02:00
Paul Eggert
da546e69af tar: port to Solaris 9
Problem reported by Jesse C in:
http://lists.gnu.org/archive/html/bug-tar/2014-03/msg00034.html
* gnulib.modules: Add strtoimax and strtoumax, since tar invokes
these functions directly and they don't exist on Solaris 9.
2014-03-12 21:02:06 -07:00
Sergey Poznyakoff
f24b30ec8c Test the --[no-]recursive options (see commit 2bd9c153_.
* tests/recurs02.at: New test case.
* tests/Makefile.am: Add new file.
* tests/testsuite.at: Add new file.
2014-02-25 10:38:06 +02:00
Sergey Poznyakoff
93906c238d Support exclusion patterns from various VCS ignore lists.
* src/Makefile.am (tar_SOURCES): Add exclist.c
* src/common.h (EXCL_DEFAULT, EXCL_RECURSIVE)
(EXCL_NON_RECURSIVE): New flags.
(excfile_add, info_attach_exclist)
(info_cleanup_exclist,info_free_exclist)
(exclude_vcs_ignores): New prototypes.
* src/create.c (dump_dir0): Call info_attach_exclist.
* src/exclist.c: New file.
* src/incremen.c (scan_directory): Call info_attach_exclist.
* src/names.c (excluded_name): Moved to exclist.c. Change signature.
All uses updated.
* src/tar.c: New options: --exclude-ignore, --exclude-ignore-recursive
and --exclude-vcs-ignores.
(tar_stat_destroy): Free exclist.
* src/tar.h (tar_stat_info): New member exclude_list.

* NEWS: Document new exclusion options.
* doc/tar.texi: Likewise.
* doc/tar.1: Likewise.
2014-02-22 08:13:30 +02:00
Sergey Poznyakoff
9df17e6005 Fix in testsuite
* acls03.at: Fix improper invocation of setfacl.
2014-02-14 13:03:58 +02:00
Pavel Raiskup
efbf4cce0b testsuite: add test for buggy default ACLs
* tests/Makefile.am: Mention acls03.at.
* tests/testsuite.at: Likewise.
* tests/acls03.at: New testcase.
2014-02-14 12:38:25 +02:00
Pavel Raiskup
7fe7adcbb9 acls: bugfix for default ACLs extraction
When --acls option is on (regardless of tarball contents or
tarball format), we should explicitly set OR delete default ACLs
for extracted directories.  Prior to this update, we always
created arbitrary default ACLs based standard file permissions.

* configure.ac (with_posix_acls): Check also for acl_free and
acl_delete_def_file to mark IEEE 1003.1e ACLs as supported.
* src/xattrs.c (acl_delete_def_file_at): New function.
(xattrs__acls_set): Do not treat acls_option at all;  Delete
default ACLs if appropriate.

References:
http://www.mail-archive.com/bug-tar@gnu.org/msg04355.html
Thanks: Juan J. Martínez and Mark Steinborn
2014-02-14 12:38:20 +02:00
Pavel Raiskup
8e10d93d01 tar: imply --xattrs when --xattrs-{inc,exc}lude used
Options --xattrs-include=MASK and --xattrs-exclude=MASK now turn
on the --xattrs option.

Fix also bug in printing in xattrs.c - don't print when option is
negative.

* src/tar.c (set_xattr_option): New static function.
(parse_opt): Call new function when --xatrrs, --xattrs-include or
--xattrs-exclude option is used.
* src/xattrs.c (xattrs_print, xattrs_print_char): Expect positive
values in options.
2014-02-14 12:32:34 +02:00
Sergey Poznyakoff
3cb4693c65 THANKS: Add Anthony G. Basile. 2014-02-14 11:02:40 +02:00
Sergey Poznyakoff
48a546b02c Use correct headers/libraries when providing xattr support
See https://savannah.gnu.org/patch/index.php?8252. Patch provided
by Anthony G. Basile.

* acinclude.m4 (TAR_HEADERS_ATTR_XATTR_H): Look for <sys/xattr.h>
first and then for <attr/xattr.h>.  Link against libattr.so if
needed.
* lib/xattr-at.h: Include sys/xattr.h or attr/xattr.h, depending
on which one is detected.
* src/Makefile.am [TAR_LIB_ATTR] (tar_LDADD): Link against -lattr.
2014-02-14 10:55:26 +02:00
Sergey Poznyakoff
46da9968df Minor change
* src/tar.c (decode_options): Silently ignore --one-top-level
if used with a non-reading command.
2014-02-14 10:44:19 +02:00
Sergey Poznyakoff
29a6964af3 New option --sort=ORDER
This option makes tar sort the entries of directories that will be
added to an archive according to ORDER (none, name, or order).

Based on proposition by Dick Streefland (https://savannah.gnu.org/patch/?7892).

* src/common.h (savedir_sort_order): New global.
* src/create.c: Pass savedir_sort_order to streamsavedir.
* src/misc.c: Likewise.
* src/tar.c: New option --sort.

* NEWS: Update.
* doc/tar.texi: Document the --sort option.
* doc/tar.1: Likewise.
2014-02-14 00:26:49 +02:00
Sergey Poznyakoff
62497f0e26 Fix the testsuite
* tests/opcomp01.at: Update expected error messages.
* tests/opcomp03.at: Likewise.
2014-02-13 23:58:35 +02:00
Sergey Poznyakoff
c86b0c2149 Fix --one-top-level used together with --list.
* src/extract.c: Move one_top_level stuff to tar.c (decode_options).
* src/tar.c (option_conflict_error): New function.
(decode_options): Use option_conflict_error to complain about
conflicting options in a uniform manner.
Process one_top_level options here.
(request_stdin): Fix error message.
* tests/onetop04.at: New testcase: check --one-top-level with --list.
* tests/Makefile.am: Add new testcase.
* tests/testsuite.at: Add new testcase.
2014-02-13 19:17:27 +02:00
Sergey Poznyakoff
8b6a1a5990 Fix NEWS
* NEWS: Remove duplicate description of the --one-top-level option.
2014-02-13 10:29:19 +02:00
Sergey Poznyakoff
8cfcbfddd4 configure.ac: look for host-prefixed ar
See https://savannah.gnu.org/patch/?8183
2014-02-12 15:07:13 +02:00
Sergey Poznyakoff
e9e94531f0 Bugfix
* src/suffix.c (find_compression_suffix): Fix eventual coredump.
2014-02-10 19:51:55 +02:00
Sergey Poznyakoff
288dd472e3 Fix docs. 2014-02-10 18:46:24 +02:00
Sergey Poznyakoff
8706301479 Update docs.
* NEWS: Document --one-top-level
* THANKS: Mention Connor Behan
2014-02-10 18:29:39 +02:00
Sergey Poznyakoff
45ccda1193 Update copyright years. 2014-01-30 13:54:15 +02:00
Sergey Poznyakoff
1689ed4388 Improve one-top-level functionality
Make sure the changes become visible with --show-transformed-names.

* src/common.h (strip_compression_suffix): New function.
(one_top_level): Rename to one_top_level_dir. All uses changed.
* src/extract.c (extr_init): Use strip_compression_suffix.
Bail out if unable to determine top-level directory.
(maybe_prepend_name): Remove. All uses removed.
* src/tar.c (options): --one-top-level takes optional argument.
(parse_opt): Handle it.
* src/list.c (enforce_one_top_level): New function.
(transform_stat_info): Call enforce_one_top_level if required.
* src/suffix.c (compression_suffixes): List "tar" (no compression);
terminate with NULL entry.
(find_compression_suffix): New static.
(strip_compression_suffix): New function.

* doc/tar.1: Update.
* doc/tar.texi: Update.

* tests/onetop01.at: New testcase.
* tests/onetop02.at: New testcase.
* tests/onetop03.at: New testcase.
* tests/Makefile.am: Add new testcases.
* tests/testsuite.at: Likewise.
2014-01-28 12:35:39 +02:00
Connor Behan
2af87fa277 Detect tarbombs while extracting
* src/common.h (one_top_level_option): New global.
(one_top_level): New global.
* src/extract.c (extr_init): If one_top_level_option is set, determine
the name one_top_level that might have to be prepended.
(extract_archive): If one_top_level_option is set, prepend one_top_level
to all names that don't already start with it.
* src/tar.c (ONE_TOP_LEVEL_OPTION): New contant.
(options): New option --one-top-level.
(parse_opt): Handle this option.
(decode_options): Make it conflict with --absolute-names.
2014-01-27 14:42:09 +02:00
Sergey Poznyakoff
95a51b93d0 Don't install rmt.8 if rmt is not built.
* doc/Makefile.am [PU_RMT_COND]: Define RMT_8
(dist_man_MANS): use RMT_8 instead of the hardcoded rmt.8
2014-01-27 14:32:46 +02:00
Sergey Poznyakoff
f504821589 Provide tar(1) and rmt(8) manpages.
* NEWS: Update.
* doc/Makefile.am: Add manpages.
* doc/tar.1: New file.

* src/tar.c (tar_help_filter): Handle LZOP_OPTION.
2014-01-27 13:20:11 +02:00
Sergey Poznyakoff
a09e840507 Make sure transformed file names retain trailing slash in listing.
* src/list.c (simple_print_header): Print trailing slash
if using the transformed name.
Use had_trailing_slash instead of analyzing last byte if temp_name
2014-01-23 18:04:36 +02:00
Sergey Poznyakoff
eb7e2aa933 checkpoint actions: further improvements.
* NEWS: Update.
* doc/tar.texi: Update.
* src/buffer.c (print_stats): Avoid use of additional string buffer.
Allow for text to be NULL.
Call gettext if it is not.
(format_total_stats): Don't use gettext when calling print_stats.
* src/checkpoint.c (def_format): Change default format.
(format_checkpoint_string): Implement optional arguments for
T conversion.
(finish_checkpoint_actions): Rename to checkpoint_flush_actions,
make extern.  All uses changed.
* src/common.h (checkpoint_flush_actions): New proto.
* src/tar.c (main): Set error_hook
2014-01-22 17:35:43 +02:00
Sergey Poznyakoff
717a07e208 Improve checkpoint interface.
* src/buffer.c (format_total_stats): The format arg is const
All uses updated.
(default_total_format): const
* src/checkpoint.c (tty, tty_cleanup): New static.
(format_checkpoint_string): New "canned" format %c
(checkpoint_finish): New function.
* src/common.h (checkpoint_finish): New proto.
* src/tar.c (main): Call checkpoint_finish.`
2014-01-22 07:28:02 +02:00
Sergey Poznyakoff
f0a1f78196 Implement statistics display in checkpoint actions.
* NEWS: Update.
* configure.ac: Version 1.27.90
* gnulib.modules: Add fprintftime.
* doc/tar.texi: Document the "totals" action and new format specifiers
for echo and ttyout checkpoint actions.
* src/buffer.c (compute_duration): Return computed value.
(print_stats): Don't print trailing newline.  Return number of
characters output.
(format_total_stats): New function.
(print_total_stats): Rewrite via format_total_stats.
* src/checkpoint.c (checkpoint_opcode) <cop_totals>: New opcode.
(checkpoint_compile_action): Handle cop_totals.
(expand_checkpoint_string): Remove.
(format_checkpoint_string): New function to be used instead of
expand_checkpoint_string.  All callers updated.
* src/common.h (TF_READ,TF_WRITE)
(TF_DELETED): New constants.
(format_total_stats,print_total_stats): New protos.
2014-01-21 17:57:46 +02:00
Sergey Poznyakoff
7f21a4d3f5 Remove shar archives from distribution.
These are going to phase out in automake 2.0
2014-01-10 11:37:50 +02:00
Sergey Poznyakoff
2bd9c15391 Fix the use of --no-recursion and --recursion options.
Each option remains in effect until cancelled by the next ocurrence
of its counterpart, as stated in the documentation.

* src/names.c (name_next_elt): Restore recursion_option from the
value of matching_flags.
2014-01-10 00:14:53 +02:00
Sergey Poznyakoff
481572c63f Minor bugfixes
* src/compare.c (diff_dumpdir): Close descriptor if fstat failed.
(diff_multivol): Make sure the descriptor is closed and eventual
errors reported if lseek fails.
Both reported by Jiri Kukacka.
2014-01-09 17:24:21 +02:00
Paul Eggert
47da28892e tar: work aruond IBM XL C bug
* src/incremen.c (show_snapshot_field_ranges)
(write_directory_file_entry): Use simpler array size expression,
one that evaluates to the same value.  This works around a compiler
bug with IBM XL C.  Problem reported by Yannick Bergeron in
<http://lists.gnu.org/archive/html/bug-tar/2014-01/msg00009.html>.
2014-01-07 11:16:23 -08:00
Paul Eggert
5c5f62e0dc tar: update ancient configure cruft
* configure.ac: Use AC_PROG_CC_STDC, not just AC_PROG_CC.
Remove obsolete macros AC_ISC_POSIX, AC_HEADER_SYS_WAIT,
AC_HEADER_DIRENT, AC_HEADER_STAT, AC_HEADER_STDC, AC_TYPE_SIGNAL,
AC_TYPE_SIZE_T.
* lib/prepargs.c (IN_CTYPE_DOMAIN): Remove.  All uses removed.
* src/list.c (from_header): Use isspace, not ISSPACE.
* src/system.c (pipe_handler, sys_exec_info_script):
* src/tar.c (sigstat):
Use void, not RETSIGTYPE.
2014-01-03 11:48:57 -08:00
Sergey Poznyakoff
49f3145092 Version 1.27.1 2013-11-17 18:37:50 +02:00
Sergey Poznyakoff
ca8cb48d02 Fix star compatibility (sparse headers)
* src/sparse.c (star_get_sparse_info): Update file->dumped_size
2013-11-17 17:35:01 +02:00
Sergey Poznyakoff
b4afdd0e28 Fix GNU long link header.
* src/create.c (write_gnu_long_link): Set timestamp to
0 for backward compatibility.  Bug reported by David Barri.
* THANKS: Update.
2013-11-17 17:31:41 +02:00
Sergey Poznyakoff
6e8bca8b56 Fix unquoting of input file names.
* src/names.c (read_next_name): Unquote file names coming from the
-T argument.  Bug reported by Nicolas Dudebout.
* THANKS: Update.
2013-11-17 17:27:53 +02:00
Paul Eggert
00054440c7 build: fix bug where 'configure --with-posix-acls' disables ACLs
Reported by Lars Wendler in
<http://lists.gnu.org/archive/html/bug-tar/2013-10/msg00022.html>.
* configure.ac (with_posix_acls): Fix typo.
2013-10-23 18:38:56 -07:00
Paul Eggert
a2e0cd0c05 Fix core dump on Solaris 10 when "." isn't readable.
Reported by Peter Kruse in
<http://lists.gnu.org/archive/html/bug-tar/2013-10/msg00017.html>.
This doesn't fix all the Solaris 10 test failures, just the core dump.
* src/common.h, src/misc.c (tar_getcdpath): Now static.
* src/misc.c (normalize_filename): Report a fatal error
if cdpath is null, since we don't know the absolute name
of the working directory in that case.  FIXME: there should
be no need to know absolute file names.
(chdir_arg): Simplify wd allocation.
Don't assume that xgetcwd returns non-null.
2013-10-22 19:17:23 -07:00
296 changed files with 7742 additions and 2011 deletions

7
.gitignore vendored
View File

@@ -23,13 +23,8 @@ config.h.in
config.log
config.status
configure
gnu/*.h
gnu/*/
gnu/.gitignore
gnu/charset.alias
gnulib
gnu
libtool
m4
paxutils
rmt
stamp-h1

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "gnulib"]
path = gnulib
url = git://git.sv.gnu.org/gnulib.git
[submodule "paxutils"]
path = paxutils
url = git://git.sv.gnu.org/paxutils.git

View File

@@ -3186,7 +3186,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
Reported by Jeffrey Goldberg.
* rmt.h (_remdev): A filename is not remote if the colon is
preceeded by a slash, to take care of `/:/' which is a shorthand
preceded by a slash, to take care of `/:/' which is a shorthand
for `/.../<CELL-NAME>/fs' on OSF's Distributing Computing
Environment (DCE) and Distributed File System (DFS).
Reported by Travis L. Priest.

View File

@@ -1028,7 +1028,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
this has undefined behavior. Likewise for assigning arbitrary
uintmax_t values to other types.
(read_negative_num, read_unsigned_num, read_timespec):
New functions, to check input values a bit more carefuly.
New functions, to check input values a bit more carefully.
(read_num): Use read_unsigned_num. New arg MAX_VAL;
all callers changed.
(read_incr_db_2): Use these new functions.
@@ -1208,7 +1208,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* src/delete.c: Remove second argument from calls to name_scan
* src/update.c: Likewise
* src/incremen.c (procdir): Use is_individual_file to check for
files explicitely specified in the command line. Fixes bug
files explicitly specified in the command line. Fixes bug
reported by Dat Head on 19 Jun 2006 (descending into mountpoints
with --one-file-system in use)
* src/misc.c (maybe_backup_file): Second argument is bool
@@ -1267,7 +1267,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* src/delete.c (records_skipped): Remove static qualifier, the
variable is used by print_total_stats in buffer.c
* src/extract.c (check_time): Use volume_start_time when checking
for timestamp plausability.
for timestamp plausibility.
* src/tar.c: (options, parse_opt): Allow for optional argument to
the --totals option, which specifies a signal upon delivery of which
the statistics must be output.
@@ -1325,7 +1325,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* src/transform.c (set_transform_expr,_transform_name_to_obstack):
Implement NUMBER flag.
(add_char_segment): Fix length assignement
(add_char_segment): Fix length assignment
* doc/tar.texi: Update
@@ -1382,7 +1382,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* doc/tar.texi: Update
* configure.ac (AM_INIT_AUTOMAKE): Use tar-ustar option. Raise
version requirement to 1.9
* src/common.h (struct name): Refactured
* src/common.h (struct name): Refactored
(warn_regex_usage): New variable.
(dump_file): First argument is const char*.
(name_init,name_add): Removed
@@ -1757,13 +1757,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* src/common.h (struct name): New member `explicit'. Remove unused
member `isdir'.
* src/incremen.c (procdir): If name_scan() returns something,
check if it was explicitely given in the command line
check if it was explicitly given in the command line
* src/names.c (addname,add_hierarchy_to_namelist): Initialize
explicit member appropriately.
* src/incremen.c (procdir): If --one-file-system is given and a
directory is found to be on another device, *and* this directory
is explicitely given in the command line, then do not omit it.
is explicitly given in the command line, then do not omit it.
2005-12-11 Sergey Poznyakoff <gray@gnu.org.ua>
@@ -1798,7 +1798,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
(mode_to_chars, off_to_chars, size_to_chars, time_to_chars)
(uid_to_chars, uintmax_to_chars): Return bool
(to_chars): Return bool
(start_header): Check return values of convertion routines. Fail
(start_header): Check return values of conversion routines. Fail
if unable to store data in the header.
2005-12-07 Sergey Poznyakoff <gray@gnu.org.ua>
@@ -2098,13 +2098,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
archives.
* src/incremen.c (dumpdir_size, get_gnu_dumpdir): New functions.
(purge_directory): Use stat_info.dumpdir instead of getting its
value explicitely.
value explicitly.
* src/list.c (list_archive): Handle incremental backups in pax
format.
(decode_header): Initialize stat_info.dumpdir
* src/sparse.c (sparse_diff_file): Bugfix: set seekable.
(pax_dump_header): Store sparse map in GNU.sparse.map. If this
variable has been explicitely deleted, use GNU.sparse.offset/
variable has been explicitly deleted, use GNU.sparse.offset/
GNU.sparse.numbytes variables.
* src/tar.c (decode_options): Incremental options are allowed with
--format=pax
@@ -2182,7 +2182,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* bootstrap: Fix quoting in help output.
(update_po): Use backward-compatible wget option --cache instead
of deprecated -C to accomodate for wget 1.10.
of deprecated -C to accommodate for wget 1.10.
Changes proposed by Eric Blake
* THANKS: Add Eric Blake
@@ -2733,7 +2733,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* src/list.c: Likewise
* tests/multiv03.at: Modified to match the new behavior
* tests/multiv04.at: New file. Test splittind directory members between
* tests/multiv04.at: New file. Test splitting directory members between
the archive volumes.
* tests/Makefile.am: Add multiv04.at
* tests/testsuite.at: Likewise.
@@ -4487,7 +4487,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* src/create.c: Do not zero-terminate name field if
the name is exactly 100 characters long.
(write_ustar_long_name): Fixed cheking for unsplittable
(write_ustar_long_name): Fixed checking for unsplittable
names.
2003-11-14 Sergey Poznyakoff <gray@Mirddin.farlep.net>
@@ -5184,7 +5184,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
interface.
(child_open_for_compress): Do not increase size to BLOCKSIZE.
(open_archive): Open index file name.
Strip trailing slahes from file names.
Strip trailing slashes from file names.
(flush_write): Set size to 0 if not saving names.
(flush_write, flush_read): Use safer_name_suffix rather than
inline code.
@@ -6017,7 +6017,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
(decode_options): Dates that look like an absolute path name,
or that start with '.', are presumed to be file names whose
dates are taken.
Remove 'I' as an aliase for 'T'.
Remove 'I' as an alias for 'T'.
Update copyright.
* src/extract.c (<time.h>): Do not include; system.h now does this.

70
ChangeLog.amend Normal file
View File

@@ -0,0 +1,70 @@
# Fix typos in tar ChangeLog entries generated from git log
f24b30ec8ca1851b7bd14694241de3b38194c99c
s/commit 2bd9c153_\./commit 2bd9c153)./
29a6964af3e1baabe978ce608e0466e1250d08ab
s/ORDER \(none, name, or order\)\./ORDER (none, name, or inode)./
2af87fa2776c8125a587a9b0c2c4fae3bf921ff7
s/contant\./content./
2bd9c15391b0bd6ef0bff76aebf09cfb53003199
s/ocurrence/occurrence/
47da28892e6860a3a6fc06745f640e3bb878c757
s/aruond/around/
f7077dd38b018f19d3a5c7df6accc6b07b8a2356
s/absoulte/absolute/
28b44aaacb45680aa6640e0a6d7ceab04cfdbf11
s/warniing/warning/
47560a0498bde20621ce4e367b1d68bf8cd8f1a3
s/interacton/interaction/
26538c9bfc5fd726d625bef5fa3f08212d50173a
s/consuption/consumption/;
s/misfunctioned/malfunctioned/;
s/misssing/missing/;
696338043e52f440853e1143c52b81b41cd59723
s/suuport/support/
643a8844a578ff146cfe746fe6091d29502b6c40
s/incrfental/incremental/;
s/afterwards/afterward/;
03858cf583ce299b836d8a848967ce290a6bf303
s/Peformance/Performance/
fa307a665545753b6729191fd2559ce872fa470a
s/filags/flags/
73d0d1a0f883be5f67534362c99382f1eae8d178
s/contais/contains/
5af29cb944c84e2d539ce9df527d63c29f6012b9
s/appendig/appending/
7dd57ebdfa9ac0d2af4622449f45b5025f6c184f
s/encounted/encountered/
ecbcb7b6d74c2d69386c8d7e435486a4690c9993
s/inadvertantly/inadvertently/
4dfcd6c054a5e9e1a371c822a3be90564dd9b690
s/succesfully/successfully/

View File

@@ -1,7 +1,7 @@
# Main Makefile for GNU tar.
# Copyright 1994-1997, 1999-2001, 2003, 2007, 2009, 2013 Free Software
# Foundation, Inc.
# Copyright 1994-1997, 1999-2001, 2003, 2007, 2009, 2013-2014, 2016 Free
# Software Foundation, Inc.
# This file is part of GNU tar.
@@ -26,7 +26,7 @@ dist-hook:
$(MAKE) changelog_dir=$(distdir) ChangeLog
-rm -f $(distdir).cpio
find $(distdir) | cpio -Hcrc -o | \
GZIP=$(GZIP_ENV) gzip -c > $(distdir).cpio.gz
eval GZIP= gzip $(GZIP_ENV) -c > $(distdir).cpio.gz
distclean-local:
-rm -f $(distdir).cpio.gz
@@ -36,3 +36,4 @@ include Make.rules
gen_start_date = 2009-03-06
prev_change_log = ChangeLog.CVS
changelog_dir = .
changelog_amend_file=ChangeLog.amend

170
NEWS
View File

@@ -1,6 +1,168 @@
GNU tar NEWS - User visible changes. 2013-10-05
GNU tar NEWS - User visible changes. 2016-05-16
Please send GNU tar bug reports to <bug-tar@gnu.org>
version 1.29 - Sergey Poznyakoff, 2016-05-16
* New options: --verbatim-files-from, --no-verbatim-files-from
The --verbatim-files-from option instructs tar to treat each line read
from a file list as a file name, even if it starts with a dash.
File lists are supplied with the --files-from (-T) option. By
default, each line read from a file list is first stripped off the
leading and trailing whitespace and, if the result begins with a dash,
it is treated as tar command line option.
Use the --verbatim-files-from option to disable this special handling.
This facilitates the use of tar with file lists created automatically
(e.g. by find(1) command).
This option affects all --files-from options that occur after it in
the command line. Its effect is reverted by the
--no-verbatim-files-from option.
* --null option reads file names verbatim
The --null option implies --verbatim-files-from. I.e. each line
read from null-delimited file lists is treated as a file name.
This restores the documented behavior, which was broken in version
1.27.
* New options: --owner-map=FILE and --group-map=FILE
These two options provide fine-grained control over what user/group
names (or IDs) should be mapped when adding files to archive.
For both options, FILE is a plain text file with user or group
mappings. Empty lines are ignored. Comments are introduced with
# sign (unless quoted) and extend to the end of the corresponding
line. Each non-empty line defines translation for a single UID (GID).
It must consist of two fields, delimited by any amount of whitespace:
OLDNAME NEWNAME[:NEWID]
OLDNAME is either a valid user (group) name or a ID prefixed with +. Unless
NEWID is supplied, NEWNAME must also be either a valid name or a
+ID. Otherwise, both NEWNAME and NEWID need not be listed in the
system user database.
* New option --clamp-mtime
The new --clamp-mtime option changes the behavior of --mtime to only
use the time specified if the file mtime is newer than the given time.
The --clamp-mtime option can only be used together with --mtime.
Typical use case is to make builds reproducible: to loose less
information, it's better to keep the original date of an archive,
except for files modified during the build process. In that case, using
reference (and thus reproducible) timestamps for the latter is good
enough.
See <https://wiki.debian.org/ReproducibleBuilds> for more information.
* Deprecated --preserve option removed
* Sparse file detection
Tar now uses SEEK_DATA/SEEK_HOLE on systems that support it. This
allows for considerable speed-up in sparse-file detection.
New option --hole-detection is provided, that allows the user to
select the algorithm used for hole detection. Available arguments
are:
--hole-detection=seek
Use lseek(2) SEEK_DATA and SEEK_HOLE "whence" parameters.
--hole-detection=raw
Scan entire file before storing it to determine where holes
are located.
The default is to use "seek" whenever possible, and fall back to
"raw" otherwise.
version 1.28, 2014-07-28
* New checkpoint action: totals
The --checkpoint-action=totals option instructs tar to output the
total number of bytes transferred at each checkpoint.
* Extended checkpoint format specification.
New conversion specifiers are implemented. Some of them take
optional arguments, supplied in curly braces between the percent
sign and the specifier letter.
%d - Number of seconds since tar started.
%{r,w,d}T - I/O totals; optional arguments supply prefixes
to be used before number of bytes read, written and
deleted, correspondingly.
%{FMT}t - Current local time using FMT as strftime(3) format.
If {FMT} is omitted, use %c.
%{N}* - Pad output with spaces to the Nth column, or to the
current screen width, if {N} is not given.
%c - A shortcut for "%{%Y-%m-%d %H:%M:%S}t: %ds, %{read,wrote}T%*\r"
* New option --one-top-level
The option --one-top-level tells tar to extract all files into a
subdirectory named by the base name of the archive (minus standard
compression suffixes recognizable by --auto-compress). When used with
an argument, as in --one-top-level=DIR, the files are extracted into the
supplied DIRectory. This ensures that no archive members are
extracted outside of the specified directory, even if the archive is
crafted so as to put them elsewhere.
* New option --sort
The --sort=ORDER option instructs tar to sort directory entries
according to ORDER. It takes effect when creating archives.
Available ORDERs are: none (the default), name and inode. The
latter may be absent, if the underlying system does not provide
the necessary information.
Using --sort=name ensures the member ordering in the created archive
is uniform and reproducible. Using --sort=inode reduces the number
of disk seeks made when creating the archive and thus can considerably
speed up archivation.
* New exclusion options
--exclude-ignore=FILE Before dumping a directory check if it
contains FILE, and if so read exclude
patterns for this directory from FILE.
--exclude-ignore-recursive=FILE
Same as above, but the exclusion patterns
read from FILE remain in effect for any
subdirectory, recursively.
--exclude-vcs-ignores Read exclude tags from VCS ignore files,
where such files exist. Supported VCS's
are: CVS, Git, Bazaar, Mercurial.
* Tar refuses to read input from and write output to a tty device.
* Manpages
This release includes official tar(1) and rmt(8) manpages.
Distribution maintainers are kindly asked to use these instead of the
home-made pages they have been providing so far.
version 1.27.1 - Sergey Poznyakoff, 2013-11-17
* Bug fixes
* Fix unquoting of file names obtained via the -T option.
* Fix GNU long link header timestamp (backward compatibility).
* Fix extracting sparse members from star archives.
version 1.27 - Sergey Poznyakoff, 2013-10-05
@@ -289,7 +451,7 @@ Modification times in ustar header blocks of extended headers
are set to mtimes of the corresponding archive members. This
can be overridden by the
--pax-opion='exthdr.mtime=STRING'
--pax-option='exthdr.mtime=STRING'
command line option. The STRING is either number of seconds since
the Epoch or a "Time reference" (see below).
@@ -299,7 +461,7 @@ headers are set to the time when tar was invoked.
This can be overridden by the
--pax-opion='globexthdr.mtime=STRING'
--pax-option='globexthdr.mtime=STRING'
command line option. The STRING is either number of seconds since
the Epoch or a "Time reference" (see below).
@@ -1425,7 +1587,7 @@ Versions 1.07 back to 1.00 by Jay Fenlason.
Copyright 1994-2001, 2003-2010, 2013 Free Software Foundation, Inc.
Copyright 1994-2001, 2003-2010, 2013-2016 Free Software Foundation, Inc.
This file is part of GNU tar.

5
README
View File

@@ -23,7 +23,6 @@ GNU 'tar' is derived from John Gilmore's public domain 'tar'.
See file 'ABOUT-NLS' for how to customize this program to your language.
See file 'COPYING' for copying conditions.
See file 'INSTALL' for compilation and installation instructions.
See file 'PORTS' for various ports of GNU tar to non-Unix systems.
See file 'NEWS' for a list of major changes in the current release.
See file 'THANKS' for a list of contributors.
@@ -222,8 +221,8 @@ and share your findings by writing to <bug-tar@gnu.org>.
* Copying
Copyright 1990-1992, 1994, 1997-2001, 2003-2004, 2007, 2012-2013 Free
Software Foundation, Inc.
Copyright 1990-1992, 1994, 1997-2001, 2003-2004, 2007, 2012-2014, 2016
Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -23,46 +23,20 @@ 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.
Before building the package, run "bootstrap". It obtains various
additional files from the CVS repository and the Translation Project
site and prepares the source directory for building.
Before building the package, run "bootstrap". It will obtain gnulib
and paxutils files from their Git repositories on Savannah. Then, it will
fetch the po files from tar page at Translation Project, and, finally, it
will start autoconfiguration process. Simply running bootstrap without
arguments should do in most cases.
When run without arguments, bootstrap will try to obtain gnulib and
paxutils files from their corresponding CVS repositories on Savannah
using anonymous SSH access. Then, it will fetch the po files from tar
page at Translation Project, and, finally, it will start autoconfiguration
process. Simply running it without arguments should do in most cases.
Several options allow to control the behavior of bootstrap:
--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.
--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.
--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.
Notice also that when using CVS authentication method "ext", bootstrap
will set the variable CVS_RSH to "ssh", unless it is already set to
some other value.
Bootstrap reads its configuration from file bootstrap.conf located on the
top of tar source tree. Several options are provided that modify its
behavior. Run 'bootstrap --help' for a list.
Copyright 2001, 2003-2005, 2007, 2013 Free Software Foundation, Inc.
Copyright 2001, 2003-2005, 2007, 2013-2016 Free Software Foundation,
Inc.
This file is part of GNU tar.

View File

@@ -12,7 +12,6 @@ version.
- Autoconf <http://www.gnu.org/software/autoconf/>
- M4 <http://www.gnu.org/software/m4/>
- Texinfo <http://www.gnu.org/software/texinfo>
- Gnulib <http://www.gnu.org/software/gnulib>
- Git <http://git.or.cz>
* Bootstrapping
@@ -33,23 +32,14 @@ Once done, proceed as described in the file README (section
INSTALLATION).
Normally you will have to run bootstrap only once. However, if you
intend to hack on GNU tar, you might need to run it again later. In
this case, you will probably want to save some time and bandwidth by
avoiding downloading the same files again. If so, create in GNU tar
root directory the file named '.bootstrap' with the following
contents:
--gnulib-srcdir=$HOME/gnulib
Replace '$HOME/gnulib' with the actual directory where the Gnulib
sources reside.
For more information about 'bootstrap', run 'bootstrap --help'.
intend to hack on GNU tar, you might need to run it again later.
There are lots of options that you may find useful in this case.
See 'bootstrap --help' for a detailed list.
* Copyright information
Copyright 2007-2009, 2013 Free Software Foundation, Inc.
Copyright 2007-2009, 2013-2016 Free Software Foundation, Inc.
This file is part of GNU tar.

11
THANKS
View File

@@ -36,6 +36,7 @@ Andrew Torda torda@igc.chem.ethz.ch
Andrey A. Chernov ache@astral.msk.su
Andy Gay andy@rdl.co.uk
Antonio Jose Coutinho ajc@di.uminho.pt
Anthony G. Basile blueness@gentoo.org
Ariel Faigon ariel@engr.sgi.com
Arne Wichmann aw@math.uni-sb.de
Arnold Robbins arnold@gnu.org
@@ -77,6 +78,7 @@ Cesar Romani romani@ifm.uni-hamburg.de
Chad Hurwitz churritz@cts.com
Chance Reschke creschke@usra.edu
Charles Fu ccwf@klab.caltech.edu
Charles McGarvey chazmcgarvey@brokenzipper.com
Charles Lopes Charles.Lopes@infm.ulst.ac.uk
Charles M. Hannum mycroft@gnu.org
Chip Salzenberg tct!chip
@@ -101,10 +103,12 @@ Claude Scarpelli claude@genethon.fr
Claus Heine Claus_Heine@ac2.maus.de
Cliff Krumvieda cliff@cs.cornell.edu
Clinton Carr clint@netcom.com
Connor Behan connor.behan@gmail.com
Conrad Hughes chughes@maths.tcd.ie
Constantin Belous const@cris.net
Coranth Gryphon gryphon@bur.visidyne.com
Cyril Strejc strejc@unicontrols.cz
Dagobert Michelsen dam@opencsw.org
Dale R. Worley worley@world.std.com
Dale Wiles wiles@geordi.calspan.com
Dan Bloch dan@transarc.com
@@ -112,6 +116,7 @@ Dan Drake dan@dandrake.org
Dan Reish dreish@izzy.net
Daniel Hagerty hag@gnu.org
Daniel Quinlan quinlan@pathname.com
Daniel Kahn Gillmor dkg@fifthhorseman.net
Daniel R. Guilderson d.guilderson@ma30.bull.com
Daniel S. Barclay daniel@compass-da.com
Daniel Trinkle trinkle@cs.purdue.edu
@@ -119,6 +124,7 @@ Danny R. Johnston danny@cs.weber.edu
Dave Barr barr@math.psu.edu
Dave Gentzel gentzel@nova.enet.dec.com
Dave Gregorich dtg@ipac.caltech.edu
David Barri japgolly@gmail.com
David Brown davidb@davidb.org
David J. MacKenzie djm@uunet.uu.net
David Johnson David.W.Johnson@colorado.edu
@@ -137,6 +143,7 @@ Demizu Noritoshi nori-d@is.aist-nara.ac.jp
Denis Excoffier denis.excoffier@free.fr
Denis Fortin fortin@acm.org
Dennis Pixton dennis@math.binghamton.edu
Derek Terveer dt@hawkmoon.mn.org
Dick Streefland dicks@tasking.nl
Dietmar Braun dietmar@highway.bertelsmann.de
Dimitri Bougoulias opus@hol.gr
@@ -169,6 +176,7 @@ Erik D. Frederick edf@deckard.mc.duke.edu
Esa Karell karell@cs.helsinki.fi
Ezra Peisach epeisach@mit.edu
Fabio d'Alessi cars@civ.bio.unipd.it
Flavio Poletti polettix@gmail.com
Frank Heckenbach frank@g-n-u.de
Frank Koenen koenfr@lidp.com
Franz-Werner Gergen gergen@edvulx.mpi-stuttgart.mpg.de
@@ -199,6 +207,7 @@ Helmut Waitzmann Helmut.Waitzmann@web.de
Henrik Bakman hb@csd.uu.se
Hernan Prieto Schmidt hernan@pea.usp.br
Hiroyuki Bessho bsh@grotto.iijnet.or.jp
Holger Levsen holger@layer-acht.org
Holger Teutsch holger@hotbso.rhein-main.de
Hugh Secker-Walker hugh@ear.mit.edu
Hunyue Yau hunyue.yau@picksys.com
@@ -237,6 +246,7 @@ Jeffrey Goldberg J.Goldberg@cranfield.ac.uk
Jeffrey Mark Siskind Qobi@emba.uvm.edu
Jeffrey W. Parker jwpkr@mcs.com
Jens Henrik Jensen recjhl@mediator.uni-c.dk
Jérémy Bobbio lunar@debian.org
Jim Blandy jimb@totoro.cs.oberlin.edu
Jim Clausing jac@postbox.acs.ohio-state.edu
Jim Farrell jwf@platinum.com
@@ -368,6 +378,7 @@ Neil Faulks neil@dcs.kcl.ac.uk
Neil Jerram nj104@cus.cam.ac.uk
Nelson H.F. Beebe beebe@math.utah.edu
Nick Barron nikb@cix.compulink.co.uk
Nicolas Dudebout nicolas.dudebout@gmail.com
Noah Friedman friedman@gnu.org
Noel Cragg noel@red-bean.com
Norbert Kiesel norbert@rwthi3.informatik.rwth-aachen.de

3
TODO
View File

@@ -45,7 +45,8 @@ Suggestions for improving GNU tar.
* Copyright notice
Copyright 2003, 2004, 2007, 2013 Free Software Foundation, Inc.
Copyright 2003-2004, 2007, 2013-2014, 2016 Free Software Foundation,
Inc.
This file is part of GNU tar.

View File

@@ -1,6 +1,6 @@
dnl Special Autoconf macros for GNU tar -*- autoconf -*-
dnl Copyright 2009, 2013 Free Software Foundation, Inc.
dnl Copyright 2009, 2013-2014, 2016 Free Software Foundation, Inc.
dnl
dnl This file is part of GNU tar.
dnl
@@ -37,18 +37,26 @@ AC_DEFUN([TAR_HEADERS_ATTR_XATTR_H],
[], [with_xattrs=maybe]
)
AC_CHECK_HEADERS([attr/xattr.h])
AM_CONDITIONAL([TAR_COND_XATTR_H],[test "$ac_cv_header_attr_xattr_h" = yes])
if test "$ac_cv_header_attr_xattr_h" = yes; then
AC_CHECK_FUNCS(getxattr fgetxattr lgetxattr \
setxattr fsetxattr lsetxattr \
listxattr flistxattr llistxattr,
# only when functions are present
AC_DEFINE([HAVE_ATTR_XATTR_H], [1],
[define to 1 if we have <attr/xattr.h> header])
if test "$with_xattrs" != no; then
AC_DEFINE([HAVE_XATTRS],,[Define when we have working linux xattrs.])
fi
)
# First check for <sys/xattr.h>
AC_CHECK_HEADERS([sys/xattr.h])
AM_CONDITIONAL([TAR_COND_XATTR_H],[test "$ac_cv_header_sys_xattr_h" = yes])
if test "$ac_cv_header_sys_xattr_h" != yes; then
AC_CHECK_HEADERS([attr/xattr.h])
AM_CONDITIONAL([TAR_COND_XATTR_H],[test "$ac_cv_header_attr_xattr_h" = yes])
fi
if test "$with_xattrs" != no; then
for i in getxattr fgetxattr lgetxattr \
setxattr fsetxattr lsetxattr \
listxattr flistxattr llistxattr
do
AC_SEARCH_LIBS($i, attr)
eval found=\$ac_cv_search_$i
test "$found" = "no" && break
done
if test "$found" != no; then
AC_DEFINE([HAVE_XATTRS],,[Define when we have working linux xattrs.])
fi
fi
])

942
bootstrap

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
# Bootstrap configuration for GNU tar.
# Copyright 2006-2009, 2013 Free Software Foundation, Inc.
# Copyright 2006-2009, 2013-2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -26,10 +26,6 @@ avoided_gnulib_modules='
--avoid=lock
'
# 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'\\\
@@ -71,3 +67,60 @@ test -f ChangeLog || cat > ChangeLog <<EOT
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.
EOT
git submodule init
git submodule update
PAXUTILS=paxutils
# gnulib modules used by this package.
gnulib_modules="$avoided_gnulib_modules
`grep -h '^[^#]' gnulib.modules $PAXUTILS/gnulib.modules`
"
# copy_files srcdir dstdir
copy_files() {
for file in `cat $1/DISTFILES`
do
case $file in
"#*") continue;;
esac
dst=`echo $file | sed 's^.*/^^'`
if [ $# -eq 3 ]; then
case $dst in
${3}*) ;;
*) dst=${3}$dst;;
esac
fi
if [ "$2" = '.' ]; then
ln -sf $1/$file $2
else
symlink_to_dir "$1" "$file" "$2/$dst" || exit
fi
# FIXME ignorefile $2 $dst
done
}
# Import from paxutils
copy_files ${PAXUTILS} .
copy_files ${PAXUTILS}/am m4
echo "$0: Creating m4/paxutils.m4"
(echo "# This file is generated automatically. Please, do not edit."
echo "#"
echo "AC_DEFUN([${package}_PAXUTILS],["
cat ${PAXUTILS}/am/DISTFILES | sed '/^#/d;s/\(.*\)\.m4/pu_\1/' | tr a-z A-Z
echo "])") > ./m4/paxutils.m4
#FIXME ignorefile m4 paxutils.m4
if [ -d rmt ]; then
:
else
mkdir rmt
fi
for dir in doc rmt lib tests
do
copy_files ${PAXUTILS}/$dir $dir
done
copy_files ${PAXUTILS}/paxlib lib pax

View File

@@ -1,6 +1,6 @@
# Configure template for GNU tar. -*- autoconf -*-
# Copyright 1991, 1994-2010, 2013 Free Software Foundation, Inc.
# Copyright 1991, 1994-2010, 2013-2016 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -17,24 +17,24 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_INIT([GNU tar], [1.27], [bug-tar@gnu.org])
AC_INIT([GNU tar], [1.29], [bug-tar@gnu.org])
AC_CONFIG_SRCDIR([src/tar.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
AC_PREREQ([2.63])
AM_INIT_AUTOMAKE([1.11 gnits tar-ustar dist-bzip2 dist-xz dist-shar std-options silent-rules])
AM_INIT_AUTOMAKE([1.11 gnits tar-ustar dist-bzip2 dist-xz std-options silent-rules])
# Enable silent rules by default:
AM_SILENT_RULES([yes])
AC_PROG_CC
AC_PROG_CC_STDC
AC_EXEEXT
AC_PROG_RANLIB
AC_PROG_YACC
gl_EARLY
AC_CHECK_TOOLS([AR], [ar])
AC_SYS_LARGEFILE
AC_ISC_POSIX
AC_C_INLINE
AC_CHECK_HEADERS_ONCE(fcntl.h linux/fd.h memory.h net/errno.h \
@@ -49,12 +49,7 @@ AC_CHECK_HEADERS([sys/buf.h], [], [],
#include <sys/param.h>
#endif])
AC_HEADER_SYS_WAIT
AC_HEADER_DIRENT
AC_HEADER_MAJOR
AC_HEADER_STAT
AC_HEADER_STDC
AC_MSG_CHECKING([for st_fstype string in struct stat])
AC_CACHE_VAL(diff_cv_st_fstype_string,
@@ -74,11 +69,13 @@ fi
AC_ARG_WITH([posix-acls],
AS_HELP_STRING([--without-posix-acls],
[do not use POSIX.1e access control lists]),
[with_posix_acls=no])
[],
[with_posix_acls=yes])
if test "x$with_posix_acls" != "xno"; then
AC_CHECK_HEADERS(sys/acl.h,, [with_posix_acls=no])
for tar_acl_func in acl_get_file acl_get_fd acl_set_file acl_set_fd \
acl_to_text acl_from_text; do \
acl_to_text acl_from_text acl_delete_def_file \
acl_free; do \
test "x$with_posix_acls" = xno && break
AC_SEARCH_LIBS([$tar_acl_func], [acl pacl], [], [with_posix_acls=no])
done
@@ -90,11 +87,9 @@ else
export enable_acl=no
fi
AC_TYPE_SIGNAL
AC_TYPE_MODE_T
AC_TYPE_PID_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_UID_T
AC_CHECK_TYPE(major_t, , AC_DEFINE(major_t, int,
[Type of major device numbers.]))
@@ -155,6 +150,7 @@ if test "$gl_gcc_warnings" = yes; then
nw="$nw -Winline" # It's OK to not inline.
nw="$nw -Wstrict-overflow" # It's OK to optimize strictly.
nw="$nw -Wsuggest-attribute=pure" # Too many warnings for now.
nw="$nw -Wstack-protector"
gl_MANYWARN_ALL_GCC([ws])
gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw])
@@ -165,9 +161,10 @@ if test "$gl_gcc_warnings" = yes; then
gl_WARN_ADD([-Wno-type-limits]) # It's OK to optimize based on types.
gl_WARN_ADD([-Wno-unused-parameter]) # Too many warnings for now
gl_WARN_ADD([-Wno-format-nonliteral])
gl_WARN_ADD([-fdiagnostics-show-option])
gl_WARN_ADD([-funit-at-a-time])
AC_SUBST([WARN_CFLAGS])

View File

@@ -1,5 +1,5 @@
%%comments:
Copyright 2004, 2013 Free Software Foundation, Inc.
Copyright 2004, 2013-2014 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or

2
doc/.gitignore vendored
View File

@@ -1,7 +1,6 @@
genfile.texi
header.texi
manual
parse-datetime.texi
stamp-vti
tar.aux
tar.cp
@@ -24,3 +23,4 @@ tar.toc
tar.tp
tar.vr
version.texi
/parse-datetime.texi

View File

@@ -1,7 +1,7 @@
# Makefile for GNU tar documentation.
# Copyright 1994-1997, 1999-2001, 2003, 2006-2007, 2013 Free Software
# Foundation, Inc.
# Copyright 1994-1997, 1999-2001, 2003, 2006-2007, 2013-2014, 2016 Free
# Software Foundation, Inc.
# This file is part of GNU tar.
@@ -32,7 +32,13 @@ tar_TEXINFOS = \
snapshot.texi\
sparse.texi\
value.texi
EXTRA_DIST = gendocs_template mastermenu.el texify.sed untabify.el
dist_man_MANS=tar.1 $(RMT_8)
if PU_RMT_COND
RMT_8=rmt.8
endif
EXTRA_DIST = gendocs_template mastermenu.el texify.sed untabify.el rmt.8
# The rendering level is anyone of PUBLISH, DISTRIB or PROOF.
# Just call 'make RENDITION=PROOF [target]' if you want PROOF rendition.

View File

@@ -1,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2006, 2007 Free Software Foundation, Inc.
@c Copyright (C) 2006-2007, 2014, 2016 Free Software Foundation, Inc.
@c Written by Sergey Poznyakoff
@c This file is distributed under GFDL 1.1 or any later version
@c published by the Free Software Foundation.

View File

@@ -5,7 +5,8 @@
@c hence no sectioning command or @node.
@display
Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
Copyright @copyright{} 2000-2002, 2007-2008, 2014, 2016 Free Software
Foundation, Inc.
@uref{http://fsf.org/}
Everyone is permitted to copy and distribute verbatim copies

View File

@@ -106,7 +106,7 @@ Please send broken links and other corrections (or suggestions) to
</p>
<p>
Copyright 2004, 2013 Free Software Foundation, Inc.,
Copyright 2004, 2013-2014, 2016 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02111, USA
<br />
Verbatim copying and distribution of this entire article is

View File

@@ -1,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2006 Free Software Foundation, Inc.
@c Copyright (C) 2006, 2014, 2016 Free Software Foundation, Inc.
@c This file is distributed under GFDL 1.1 or any later version
@c published by the Free Software Foundation.

View File

@@ -1,6 +1,6 @@
;;; mastermenu.el --- Redefinition of texinfo-master-menu-list
;; Copyright 2006-2007, 2013 Free Software Foundation, Inc.
;; Copyright 2006-2007, 2013-2014, 2016 Free Software Foundation, Inc.
;; Author: Sergey Poznyakoff
;; Maintainer: bug-tar@gnu.org

View File

@@ -1,6 +1,6 @@
@c This is part of GNU tar manual.
@c Copyright 1992, 1994-1997, 1999-2004, 2006, 2013 Free Software
@c Foundation, Inc.
@c Copyright 1992, 1994-1997, 1999-2004, 2006, 2013-2014, 2016 Free
@c Software Foundation, Inc.
@c See file tar.texi for copying conditions.
@c This file contains support for 'renditions' by Fran@,{c}ois Pinard

View File

@@ -1,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2005, 2007 Free Software Foundation, Inc.
@c Copyright (C) 2005, 2007, 2014, 2016 Free Software Foundation, Inc.
@c Written by Sergey Poznyakoff
@c This file is distributed under GFDL 1.1 or any later version
@c published by the Free Software Foundation.
@@ -116,7 +116,7 @@ epoch. These are followed by arbitrary number of directory records.
particular directory. Parts of a directory record are delimited with
@acronym{ASCII} 0 characters. The following table describes each
part. The @dfn{Number} type in this table stands for a decimal integer
in @acronym{ASCII} notation. (Negative values are preceeded with a "-"
in @acronym{ASCII} notation. (Negative values are preceded with a "-"
character, while positive values have no leading punctuation.)
@multitable @columnfractions 0.25 0.15 0.6

View File

@@ -1,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2006 Free Software Foundation, Inc.
@c Copyright (C) 2006, 2014, 2016 Free Software Foundation, Inc.
@c This file is distributed under GFDL 1.1 or any later version
@c published by the Free Software Foundation.

View File

@@ -1,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2007 Free Software Foundation, Inc.
@c Copyright (C) 2007, 2014, 2016 Free Software Foundation, Inc.
@c This file is distributed under GFDL 1.1 or any later version
@c published by the Free Software Foundation.

1319
doc/tar.1 Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
# Copyright 2006-2007, 2013 Free Software Foundation, Inc.
# Copyright 2006-2007, 2013-2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -1,5 +1,6 @@
@c This is part of GNU tar manual.
@c Copyright 1992, 1994-1997, 1999-2006, 2013 Free Software Foundation, Inc.
@c Copyright 1992, 1994-1997, 1999-2006, 2013-2014, 2016 Free Software
@c Foundation, Inc.
@c See file tar.texi for copying conditions.
@macro GNUTAR

View File

@@ -1,3 +0,0 @@
# Make the subset of Gnulib that GNU tar needs.
include gnulib.mk
AM_CFLAGS += $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS)

1
gnulib Submodule

Submodule gnulib added at 1029a81122

View File

@@ -1,7 +1,7 @@
# List of gnulib modules needed for GNU tar.
# A module name per line. Empty lines and comments are ignored.
# Copyright 2005-2010, 2012-2013 Free Software Foundation, Inc.
# Copyright 2005-2010, 2012-2014 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -18,8 +18,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
acl
alloca
areadlinkat-with-size
argmatch
argp
argp-version-etc
@@ -31,13 +31,16 @@ error
exclude
extern-inline
exitfail
faccessat
fchmodat
fchownat
fcntl-h
fdopendir
fdutimensat
file-has-acl
fileblocks
fnmatch-gnu
fprintftime
fseeko
fstatat
full-write
@@ -82,10 +85,13 @@ stdint
stpcpy
strdup-posix
strerror
strtoimax
strtol
strtoul
strtoumax
symlinkat
timespec
timespec-sub
unlinkat
unlinkdir
unlocked-io

View File

@@ -1,7 +1,7 @@
# Makefile for GNU tar library. -*- Makefile -*-
# Copyright 1994-1997, 1999-2001, 2003-2007, 2009-2010, 2013 Free
# Software Foundation, Inc.
# Copyright 1994-1997, 1999-2001, 2003-2007, 2009-2010, 2013-2014, 2016
# Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -41,7 +41,6 @@ noinst_HEADERS = \
libtar_a_SOURCES = \
paxerror.c paxexit-status.c paxlib.h paxnames.c \
prepargs.c prepargs.h \
rtapelib.c \
rmt.h \
stdopen.c stdopen.h \

View File

@@ -1,5 +1,5 @@
/* Replacement <attr/xattr.h> for platforms that lack it.
Copyright 2012-2013 Free Software Foundation, Inc.
Copyright 2012-2014, 2016 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

View File

@@ -1,93 +0,0 @@
/* Parse arguments from a string and prepend them to an argv.
Copyright 1999-2001, 2007, 2013 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 <eggert@twinsun.com>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "prepargs.h"
#include <sys/types.h>
#include <xalloc.h>
#if HAVE_STRING_H
# include <string.h>
#endif
#include <ctype.h>
/* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given
as an argument to <ctype.h> macros like "isspace". */
#ifdef STDC_HEADERS
# define IN_CTYPE_DOMAIN(c) 1
#else
# define IN_CTYPE_DOMAIN(c) ((c) <= 0177)
#endif
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
/* Find the white-space-separated options specified by OPTIONS, and
using BUF to store copies of these options, set ARGV[0], ARGV[1],
etc. to the option copies. Return the number N of options found.
Do not set ARGV[N]. If ARGV is null, do not store ARGV[0]
etc. Backslash can be used to escape whitespace (and backslashes). */
static int
prepend_args (char const *options, char *buf, char **argv)
{
char const *o = options;
char *b = buf;
int n = 0;
for (;;)
{
while (ISSPACE ((unsigned char) *o))
o++;
if (!*o)
return n;
if (argv)
argv[n] = b;
n++;
do
if ((*b++ = *o++) == '\\' && *o)
b[-1] = *o++;
while (*o && ! ISSPACE ((unsigned char) *o));
*b++ = '\0';
}
}
/* Prepend the whitespace-separated options in OPTIONS to the argument
vector of a main program with argument count *PARGC and argument
vector *PARGV. */
void
prepend_default_options (char const *options, int *pargc, char ***pargv)
{
if (options)
{
char *buf = xmalloc (strlen (options) + 1);
int prepended = prepend_args (options, buf, (char **) 0);
int argc = *pargc;
char * const *argv = *pargv;
char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
*pargc = prepended + argc;
*pargv = pp;
*pp++ = *argv++;
pp += prepend_args (options, buf, pp);
while ((*pp++ = *argv++))
continue;
}
}

View File

@@ -1,3 +0,0 @@
/* Parse arguments from a string and prepend them to an argv. */
void prepend_default_options (char const *, int *, char ***);

View File

@@ -1,6 +1,6 @@
/* stdopen.c - ensure that the three standard file descriptors are in use
Copyright 2005, 2007, 2013 Free Software Foundation, Inc.
Copyright 2005, 2007, 2013-2014, 2016 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

View File

@@ -1,5 +1,5 @@
/* wordsplit - a word splitter
Copyright (C) 2009-2013 Free Software Foundation, Inc.
Copyright (C) 2009-2014, 2016 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
@@ -61,7 +61,7 @@ _wsplt_alloc_die (struct wordsplit *wsp)
abort ();
}
static void __attribute__ ((__format__ (__printf__, 1, 2)))
static void __WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2))
_wsplt_error (const char *fmt, ...)
{
va_list ap;
@@ -221,7 +221,7 @@ struct wordsplit_node
{
struct wordsplit_node *prev; /* Previous element */
struct wordsplit_node *next; /* Next element */
int flags; /* Node flags */
unsigned flags; /* Node flags */
union
{
struct

View File

@@ -1,5 +1,5 @@
/* wordsplit - a word splitter
Copyright (C) 2009-2013 Free Software Foundation, Inc.
Copyright (C) 2009-2014, 2016 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
@@ -22,6 +22,12 @@
#include <stddef.h>
#if 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
#else
# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) /* empty */
#endif
struct wordsplit
{
size_t ws_wordc;
@@ -34,9 +40,9 @@ struct wordsplit
const char *ws_escape;
void (*ws_alloc_die) (struct wordsplit * wsp);
void (*ws_error) (const char *, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
__WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2));
void (*ws_debug) (const char *, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
__WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2));
const char **ws_env;
const char *(*ws_getvar) (const char *, size_t, void *);

View File

@@ -1,7 +1,7 @@
/* openat-style fd-relative functions for operating with extended file
attributes.
Copyright 2012-2013 Free Software Foundation, Inc.
Copyright 2012-2014, 2016 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
@@ -31,6 +31,8 @@
#include "openat-priv.h"
#ifdef HAVE_XATTRS
/* setxattrat */
#define AT_FUNC_NAME setxattrat
#define AT_FUNC_F1 setxattr
@@ -108,3 +110,5 @@
#undef AT_FUNC_RESULT
#undef AT_FUNC_POST_FILE_PARAM_DECLS
#undef AT_FUNC_POST_FILE_ARGS
#endif /* HAVE_XATTRS */

View File

@@ -1,7 +1,7 @@
/* Prototypes for openat-style fd-relative functions for operating with
extended file attributes.
Copyright 2012-2013 Free Software Foundation, Inc.
Copyright 2012-2014, 2016 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
@@ -20,7 +20,15 @@
#define XATTRS_AT_H
#include <sys/types.h>
#include <attr/xattr.h>
#if defined(HAVE_SYS_XATTR_H)
# include <sys/xattr.h>
#elif defined(HAVE_ATTR_XATTR_H)
# include <attr/xattr.h>
#endif
#ifndef ENOATTR
# define ENOATTR ENODATA /* No such attribute */
#endif
/* These are the dir-fd-relative variants of the functions without the
"at" suffix. For example, setxattrat (AT_FDCWD, path, name, value, size,

1
paxutils Submodule

Submodule paxutils added at ec72abd9dd

2
po/.gitignore vendored
View File

@@ -1,3 +1,5 @@
/Makevars.template~
/Makefile.in.in~
*.gmo
*.mo
*.po

View File

@@ -1,7 +1,7 @@
# List of files which contain translatable strings.
# Copyright 1996, 1999-2000, 2003-2005, 2007, 2013 Free Software
# Foundation, Inc.
# Copyright 1996, 1999-2000, 2003-2005, 2007, 2013-2014, 2016 Free
# Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -1,6 +1,7 @@
# Make GNU tar scripts.
# Copyright 2004, 2006, 2007, 2013 Free Software Foundation, Inc.
# Copyright 2004, 2006-2007, 2013-2014, 2016 Free Software Foundation,
# Inc.
# This file is part of GNU tar.

View File

@@ -82,7 +82,7 @@ SLEEP_MESSAGE="`awk '
}' /dev/null`"
# Copyright 2004, 2007, 2013 Free Software Foundation, Inc.
# Copyright 2004, 2007, 2013-2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -1,7 +1,7 @@
#! /bin/sh
# Make backups.
# Copyright 2004-2006, 2013 Free Software Foundation, Inc.
# Copyright 2004-2006, 2013-2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -8,7 +8,8 @@
# interested parties that a tape for the next volume of the backup needs to
# be put in the tape drive.
# Copyright 2004-2005, 2010, 2012-2013 Free Software Foundation, Inc.
# Copyright 2004-2005, 2010, 2012-2014, 2016 Free Software Foundation,
# Inc.
# This file is part of GNU tar.

View File

@@ -1,7 +1,7 @@
#! /bin/sh
# Restore backups.
# Copyright 2004, 2006, 2013 Free Software Foundation, Inc.
# Copyright 2004, 2006, 2013-2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -1,6 +1,6 @@
#! /usr/bin/perl -w
# Display and edit the 'dev' field in tar's snapshots
# Copyright 2007, 2011, 2013 Free Software Foundation, Inc.
# Copyright 2007, 2011, 2013-2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -3,7 +3,8 @@
# concatenates a GNU tar multi-volume archive into a single tar archive.
# Author: Bruno Haible <bruno@clisp.org>, Sergey Poznyakoff <gray@gnu.org.ua>
# Copyright 2004-2005, 2010, 2013 Free Software Foundation, Inc.
# Copyright 2004-2005, 2010, 2013-2014, 2016 Free Software Foundation,
# Inc.
# This file is part of GNU tar.

View File

@@ -1,7 +1,8 @@
/* xsparse - expands compressed sparse file images extracted from GNU tar
archives.
Copyright 2006, 2007, 2010, 2013 Free Software Foundation, Inc.
Copyright 2006-2007, 2010, 2013-2014, 2016 Free Software Foundation,
Inc.
This file is part of GNU tar.

View File

@@ -1,7 +1,7 @@
# Makefile for GNU tar sources.
# Copyright 1994-1997, 1999-2001, 2003, 2006-2007, 2009, 2013 Free
# Software Foundation, Inc.
# Copyright 1994-1997, 1999-2001, 2003, 2006-2007, 2009, 2013-2014, 2016
# Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -28,10 +28,12 @@ tar_SOURCES = \
create.c\
delete.c\
exit.c\
exclist.c\
extract.c\
xheader.c\
incremen.c\
list.c\
map.c\
misc.c\
names.c\
sparse.c\

View File

@@ -1,5 +1,5 @@
/* Long integers, for GNU tar.
Copyright 1999, 2007, 2013 Free Software Foundation, Inc.
Copyright 1999, 2007, 2013-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -1,7 +1,7 @@
/* Buffer management for tar.
Copyright 1988, 1992-1994, 1996-1997, 1999-2010, 2013 Free Software
Foundation, Inc.
Copyright 1988, 1992-1994, 1996-1997, 1999-2010, 2013-2014, 2016 Free
Software Foundation, Inc.
This file is part of GNU tar.
@@ -247,7 +247,7 @@ set_volume_start_time (void)
last_stat_time = volume_start_time;
}
void
double
compute_duration (void)
{
struct timespec now;
@@ -255,6 +255,7 @@ compute_duration (void)
duration += ((now.tv_sec - last_stat_time.tv_sec)
+ (now.tv_nsec - last_stat_time.tv_nsec) / 1e9);
gettime (&last_stat_time);
return duration;
}
@@ -390,7 +391,10 @@ check_compressed_archive (bool *pshort)
/* Restore global values */
read_full_records = sfr;
if (tar_checksum (record_start, true) == HEADER_SUCCESS)
if ((strcmp (record_start->header.magic, TMAGIC) == 0 ||
strcmp (record_start->buffer + offsetof (struct posix_header, magic),
OLDGNU_MAGIC) == 0) &&
tar_checksum (record_start, true) == HEADER_SUCCESS)
/* Probably a valid header */
return ct_tar;
@@ -488,64 +492,98 @@ open_compressed_archive (void)
return archive;
}
static void
static int
print_stats (FILE *fp, const char *text, tarlong numbytes)
{
char bytes[sizeof (tarlong) * CHAR_BIT];
char abbr[LONGEST_HUMAN_READABLE + 1];
char rate[LONGEST_HUMAN_READABLE + 1];
int n = 0;
int human_opts = human_autoscale | human_base_1024 | human_SI | human_B;
sprintf (bytes, TARLONG_FORMAT, numbytes);
fprintf (fp, "%s: %s (%s, %s/s)\n",
text, bytes,
human_readable (numbytes, abbr, human_opts, 1, 1),
(0 < duration && numbytes / duration < (uintmax_t) -1
? human_readable (numbytes / duration, rate, human_opts, 1, 1)
: "?"));
if (text && text[0])
n += fprintf (fp, "%s: ", gettext (text));
return n + fprintf (fp, TARLONG_FORMAT " (%s, %s/s)",
numbytes,
human_readable (numbytes, abbr, human_opts, 1, 1),
(0 < duration && numbytes / duration < (uintmax_t) -1
? human_readable (numbytes / duration, rate, human_opts, 1, 1)
: "?"));
}
void
print_total_stats (void)
/* Format totals to file FP. FORMATS is an array of strings to output
before each data item (bytes read, written, deleted, in that order).
EOR is a delimiter to output after each item (used only if deleting
from the archive), EOL is a delimiter to add at the end of the output
line. */
int
format_total_stats (FILE *fp, char const *const *formats, int eor, int eol)
{
int n;
switch (subcommand_option)
{
case CREATE_SUBCOMMAND:
case CAT_SUBCOMMAND:
case UPDATE_SUBCOMMAND:
case APPEND_SUBCOMMAND:
/* Amanda 2.4.1p1 looks for "Total bytes written: [0-9][0-9]*". */
print_stats (stderr, _("Total bytes written"),
prev_written + bytes_written);
n = print_stats (fp, formats[TF_WRITE],
prev_written + bytes_written);
break;
case DELETE_SUBCOMMAND:
{
char buf[UINTMAX_STRSIZE_BOUND];
print_stats (stderr, _("Total bytes read"),
records_read * record_size);
print_stats (stderr, _("Total bytes written"),
prev_written + bytes_written);
fprintf (stderr, _("Total bytes deleted: %s\n"),
STRINGIFY_BIGINT ((records_read - records_skipped)
* record_size
- (prev_written + bytes_written), buf));
n = print_stats (fp, formats[TF_READ],
records_read * record_size);
fputc (eor, fp);
n++;
n += print_stats (fp, formats[TF_WRITE],
prev_written + bytes_written);
fputc (eor, fp);
n++;
if (formats[TF_DELETED] && formats[TF_DELETED][0])
n += fprintf (fp, "%s: ", gettext (formats[TF_DELETED]));
n += fprintf (fp, "%s",
STRINGIFY_BIGINT ((records_read - records_skipped)
* record_size
- (prev_written + bytes_written), buf));
}
break;
case EXTRACT_SUBCOMMAND:
case LIST_SUBCOMMAND:
case DIFF_SUBCOMMAND:
print_stats (stderr, _("Total bytes read"),
records_read * record_size);
n = print_stats (fp, _(formats[TF_READ]),
records_read * record_size);
break;
default:
abort ();
}
if (eol)
{
fputc (eol, fp);
n++;
}
return n;
}
static char const *const default_total_format[] = {
N_("Total bytes read"),
/* Amanda 2.4.1p1 looks for "Total bytes written: [0-9][0-9]*". */
N_("Total bytes written"),
N_("Total bytes deleted")
};
void
print_total_stats (void)
{
format_total_stats (stderr, default_total_format, '\n', '\n');
}
/* Compute and return the block ordinal at current_block. */
@@ -633,6 +671,22 @@ init_buffer (void)
record_end = record_start + blocking_factor;
}
static void
check_tty (enum access_mode mode)
{
/* Refuse to read archive from and write it to a tty. */
if (strcmp (archive_name_array[0], "-") == 0
&& isatty (mode == ACCESS_READ ? STDIN_FILENO : STDOUT_FILENO))
{
FATAL_ERROR ((0, 0,
mode == ACCESS_READ
? _("Refusing to read archive contents from terminal "
"(missing -f option?)")
: _("Refusing to write archive contents to terminal "
"(missing -f option?)")));
}
}
/* Open an archive file. The argument specifies whether we are
reading or writing, or both. */
static void
@@ -653,6 +707,7 @@ _open_archive (enum access_mode wanted_access)
/* When updating the archive, we start with reading. */
access_mode = wanted_access == ACCESS_UPDATE ? ACCESS_READ : wanted_access;
check_tty (access_mode);
read_full_records = read_full_records_option;
@@ -696,7 +751,6 @@ _open_archive (enum access_mode wanted_access)
enum compress_type type;
archive = STDIN_FILENO;
type = check_compressed_archive (&shortfile);
if (type != ct_tar && type != ct_none)
FATAL_ERROR ((0, 0,
@@ -929,18 +983,28 @@ short_read (size_t status)
void
flush_archive (void)
{
size_t buffer_level = current_block->buffer - record_start->buffer;
record_start_block += record_end - record_start;
current_block = record_start;
record_end = record_start + blocking_factor;
size_t buffer_level;
if (access_mode == ACCESS_READ && time_to_start_writing)
{
access_mode = ACCESS_WRITE;
time_to_start_writing = false;
backspace_output ();
if (record_end - record_start < blocking_factor)
{
memset (record_end, 0,
(blocking_factor - (record_end - record_start))
* BLOCKSIZE);
record_end = record_start + blocking_factor;
return;
}
}
buffer_level = current_block->buffer - record_start->buffer;
record_start_block += record_end - record_start;
current_block = record_start;
record_end = record_start + blocking_factor;
switch (access_mode)
{
case ACCESS_READ:
@@ -980,7 +1044,7 @@ backspace_output (void)
/* Seek back to the beginning of this record and start writing there. */
position -= record_size;
position -= record_end->buffer - record_start->buffer;
if (position < 0)
position = 0;
if (rmtlseek (archive, position, SEEK_SET) != position)
@@ -1061,6 +1125,16 @@ close_archive (void)
bufmap_free (NULL);
}
void
write_fatal_details (char const *name, ssize_t status, size_t size)
{
write_error_details (name, status, size);
if (rmtclose (archive) != 0)
close_error (*archive_name_cursor);
sys_wait_for_child (child_pid, false);
fatal_exit ();
}
/* Called to initialize the global volume number. */
void
init_volume_number (void)
@@ -1355,7 +1429,10 @@ try_new_volume (void)
header = find_next_block ();
if (!header)
return false;
{
WARN ((0, 0, _("This does not look like a tar archive")));
return false;
}
switch (header->header.typeflag)
{
@@ -1365,7 +1442,7 @@ try_new_volume (void)
if (read_header (&header, &dummy, read_header_x_global)
!= HEADER_SUCCESS_EXTENDED)
{
ERROR ((0, 0, _("This does not look like a tar archive")));
WARN ((0, 0, _("This does not look like a tar archive")));
return false;
}
@@ -1394,7 +1471,7 @@ try_new_volume (void)
break;
default:
ERROR ((0, 0, _("This does not look like a tar archive")));
WARN ((0, 0, _("This does not look like a tar archive")));
return false;
}
break;
@@ -1429,8 +1506,14 @@ try_new_volume (void)
if (bufmap_head)
{
uintmax_t s;
if (!continued_file_name
|| strcmp (continued_file_name, bufmap_head->file_name))
if (!continued_file_name)
{
WARN ((0, 0, _("%s is not continued on this volume"),
quote (bufmap_head->file_name)));
return false;
}
if (strcmp (continued_file_name, bufmap_head->file_name))
{
if ((archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
&& strlen (bufmap_head->file_name) >= NAME_FIELD_SIZE

View File

@@ -1,6 +1,6 @@
/* Checkpoint management for tar.
Copyright 2007, 2013 Free Software Foundation, Inc.
Copyright 2007, 2013-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -19,6 +19,10 @@
#include <system.h>
#include "common.h"
#include "wordsplit.h"
#include <sys/ioctl.h>
#include <termios.h>
#include "fprintftime.h"
enum checkpoint_opcode
{
@@ -27,7 +31,8 @@ enum checkpoint_opcode
cop_echo,
cop_ttyout,
cop_sleep,
cop_exec
cop_exec,
cop_totals
};
struct checkpoint_action
@@ -110,6 +115,8 @@ checkpoint_compile_action (const char *str)
act = alloc_action (cop_sleep);
act->v.time = n;
}
else if (strcmp (str, "totals") == 0)
alloc_action (cop_totals);
else
FATAL_ERROR ((0, 0, _("%s: unknown checkpoint action"), str));
}
@@ -128,68 +135,211 @@ checkpoint_finish_compile (void)
checkpoint_option = DEFAULT_CHECKPOINT;
}
static char *
expand_checkpoint_string (const char *input, bool do_write, unsigned cpn)
static const char *checkpoint_total_format[] = {
"R",
"W",
"D"
};
static long
getwidth (FILE *fp)
{
const char *opstr = do_write ? gettext ("write") : gettext ("read");
size_t opstrlen = strlen (opstr);
char uintbuf[UINTMAX_STRSIZE_BOUND];
char *cps = STRINGIFY_BIGINT (cpn, uintbuf);
size_t cpslen = strlen (cps);
const char *ip;
char *op;
char *output;
size_t outlen = strlen (input); /* Initial guess */
char const *columns;
/* Fix the initial length guess */
for (ip = input; (ip = strchr (ip, '%')) != NULL; )
#ifdef TIOCGWINSZ
struct winsize ws;
if (ioctl (fileno (fp), TIOCGWINSZ, &ws) == 0 && 0 < ws.ws_col)
return ws.ws_col;
#endif
columns = getenv ("COLUMNS");
if (columns)
{
switch (ip[1])
{
case 'u':
outlen += cpslen - 2;
break;
case 's':
outlen += opstrlen - 2;
}
ip++;
long int col = strtol (columns, NULL, 10);
if (0 < col)
return col;
}
output = xmalloc (outlen + 1);
for (ip = input, op = output; *ip; )
return 80;
}
static char *
getarg (const char *input, const char ** endp, char **argbuf, size_t *arglen)
{
if (input[0] == '{')
{
char *p = strchr (input + 1, '}');
if (p)
{
size_t n = p - input;
if (n > *arglen)
{
*arglen = n;
*argbuf = xrealloc (*argbuf, *arglen);
}
n--;
memcpy (*argbuf, input + 1, n);
(*argbuf)[n] = 0;
*endp = p + 1;
return *argbuf;
}
}
*endp = input;
return NULL;
}
static int tty_cleanup;
static const char *def_format =
"%{%Y-%m-%d %H:%M:%S}t: %ds, %{read,wrote}T%*\r";
static int
format_checkpoint_string (FILE *fp, size_t len,
const char *input, bool do_write,
unsigned cpn)
{
const char *opstr = do_write ? gettext ("write") : gettext ("read");
char uintbuf[UINTMAX_STRSIZE_BOUND];
char *cps = STRINGIFY_BIGINT (cpn, uintbuf);
const char *ip;
static char *argbuf = NULL;
static size_t arglen = 0;
char *arg = NULL;
if (!input)
{
if (do_write)
/* TRANSLATORS: This is a "checkpoint of write operation",
*not* "Writing a checkpoint".
E.g. in Spanish "Punto de comprobaci@'on de escritura",
*not* "Escribiendo un punto de comprobaci@'on" */
input = gettext ("Write checkpoint %u");
else
/* TRANSLATORS: This is a "checkpoint of read operation",
*not* "Reading a checkpoint".
E.g. in Spanish "Punto de comprobaci@'on de lectura",
*not* "Leyendo un punto de comprobaci@'on" */
input = gettext ("Read checkpoint %u");
}
for (ip = input; *ip; ip++)
{
if (*ip == '%')
{
switch (*++ip)
if (*++ip == '{')
{
arg = getarg (ip, &ip, &argbuf, &arglen);
if (!arg)
{
fputc ('%', fp);
fputc (*ip, fp);
len += 2;
continue;
}
}
switch (*ip)
{
case 'c':
len += format_checkpoint_string (fp, len, def_format, do_write,
cpn);
break;
case 'u':
op = stpcpy (op, cps);
fputs (cps, fp);
len += strlen (cps);
break;
case 's':
op = stpcpy (op, opstr);
fputs (opstr, fp);
len += strlen (opstr);
break;
case 'd':
len += fprintf (fp, "%.0f", compute_duration ());
break;
case 'T':
{
const char **fmt = checkpoint_total_format, *fmtbuf[3];
struct wordsplit ws;
compute_duration ();
if (arg)
{
ws.ws_delim = ",";
if (wordsplit (arg, &ws, WRDSF_NOVAR | WRDSF_NOCMD |
WRDSF_QUOTE | WRDSF_DELIM))
ERROR ((0, 0, _("cannot split string '%s': %s"),
arg, wordsplit_strerror (&ws)));
else
{
int i;
for (i = 0; i < ws.ws_wordc; i++)
fmtbuf[i] = ws.ws_wordv[i];
for (; i < 3; i++)
fmtbuf[i] = NULL;
fmt = fmtbuf;
}
}
len += format_total_stats (fp, fmt, ',', 0);
if (arg)
wordsplit_free (&ws);
}
break;
case 't':
{
struct timeval tv;
struct tm *tm;
const char *fmt = arg ? arg : "%c";
gettimeofday (&tv, NULL);
tm = localtime (&tv.tv_sec);
len += fprintftime (fp, fmt, tm, 0, tv.tv_usec * 1000);
}
break;
case '*':
{
long w = arg ? strtol (arg, NULL, 10) : getwidth (fp);
for (; w > len; len++)
fputc (' ', fp);
}
break;
default:
*op++ = '%';
*op++ = *ip;
fputc ('%', fp);
fputc (*ip, fp);
len += 2;
break;
}
ip++;
arg = NULL;
}
else
*op++ = *ip++;
{
fputc (*ip, fp);
if (*ip == '\r')
{
len = 0;
tty_cleanup = 1;
}
else
len++;
}
}
*op = 0;
return output;
fflush (fp);
return len;
}
static FILE *tty = NULL;
static void
run_checkpoint_actions (bool do_write)
{
struct checkpoint_action *p;
FILE *tty = NULL;
for (p = checkpoint_action; p; p = p->next)
{
@@ -212,26 +362,10 @@ run_checkpoint_actions (bool do_write)
case cop_echo:
{
char *tmp;
const char *str = p->v.command;
if (!str)
{
if (do_write)
/* TRANSLATORS: This is a "checkpoint of write operation",
*not* "Writing a checkpoint".
E.g. in Spanish "Punto de comprobaci@'on de escritura",
*not* "Escribiendo un punto de comprobaci@'on" */
str = gettext ("Write checkpoint %u");
else
/* TRANSLATORS: This is a "checkpoint of read operation",
*not* "Reading a checkpoint".
E.g. in Spanish "Punto de comprobaci@'on de lectura",
*not* "Leyendo un punto de comprobaci@'on" */
str = gettext ("Read checkpoint %u");
}
tmp = expand_checkpoint_string (str, do_write, checkpoint);
WARN ((0, 0, "%s", tmp));
free (tmp);
int n = fprintf (stderr, "%s: ", program_name);
format_checkpoint_string (stderr, n, p->v.command, do_write,
checkpoint);
fputc ('\n', stderr);
}
break;
@@ -239,13 +373,8 @@ run_checkpoint_actions (bool do_write)
if (!tty)
tty = fopen ("/dev/tty", "w");
if (tty)
{
char *tmp = expand_checkpoint_string (p->v.command, do_write,
checkpoint);
fprintf (tty, "%s", tmp);
fflush (tty);
free (tmp);
}
format_checkpoint_string (tty, 0, p->v.command, do_write,
checkpoint);
break;
case cop_sleep:
@@ -257,10 +386,37 @@ run_checkpoint_actions (bool do_write)
archive_name_cursor[0],
checkpoint);
break;
case cop_totals:
compute_duration ();
print_total_stats ();
}
}
}
void
checkpoint_flush_actions (void)
{
struct checkpoint_action *p;
for (p = checkpoint_action; p; p = p->next)
{
switch (p->opcode)
{
case cop_ttyout:
if (tty && tty_cleanup)
{
long w = getwidth (tty);
while (w--)
fputc (' ', tty);
fputc ('\r', tty);
fflush (tty);
}
break;
default:
/* nothing */;
}
}
if (tty)
fclose (tty);
}
void
@@ -269,3 +425,14 @@ checkpoint_run (bool do_write)
if (checkpoint_option && !(++checkpoint % checkpoint_option))
run_checkpoint_actions (do_write);
}
void
checkpoint_finish (void)
{
if (checkpoint_option)
{
checkpoint_flush_actions ();
if (tty)
fclose (tty);
}
}

View File

@@ -1,6 +1,6 @@
/* Common declarations for the tar program.
Copyright 1988, 1992-1994, 1996-1997, 1999-2010, 2012-2013 Free
Copyright 1988, 1992-1994, 1996-1997, 1999-2010, 2012-2016 Free
Software Foundation, Inc.
This file is part of GNU tar.
@@ -211,13 +211,20 @@ GLOBAL bool multi_volume_option;
do not get archived (also see after_date_option above). */
GLOBAL struct timespec newer_mtime_option;
/* If true, override actual mtime (see below) */
GLOBAL bool set_mtime_option;
/* Value to be put in mtime header field instead of the actual mtime */
enum set_mtime_option_mode
{
USE_FILE_MTIME,
FORCE_MTIME,
CLAMP_MTIME,
};
/* Override actual mtime if set to FORCE_MTIME or CLAMP_MTIME */
GLOBAL enum set_mtime_option_mode set_mtime_option;
/* Value to use when forcing or clamping the mtime header field. */
GLOBAL struct timespec mtime_option;
/* Return true if newer_mtime_option is initialized. */
#define NEWER_OPTION_INITIALIZED(opt) (0 <= (opt).tv_nsec)
/* Return true if mtime_option or newer_mtime_option is initialized. */
#define TIME_OPTION_INITIALIZED(opt) (0 <= (opt).tv_nsec)
/* Return true if the struct stat ST's M time is less than
newer_mtime_option. */
@@ -235,6 +242,10 @@ GLOBAL bool numeric_owner_option;
GLOBAL bool one_file_system_option;
/* Create a top-level directory for extracting based on the archive name. */
GLOBAL bool one_top_level_option;
GLOBAL char *one_top_level_dir;
/* Specified value to be put into tar file in place of stat () results, or
just null and -1 if such an override should not take place. */
GLOBAL char const *owner_name_option;
@@ -276,6 +287,15 @@ GLOBAL bool sparse_option;
GLOBAL unsigned tar_sparse_major;
GLOBAL unsigned tar_sparse_minor;
enum hole_detection_method
{
HOLE_DETECTION_DEFAULT,
HOLE_DETECTION_RAW,
HOLE_DETECTION_SEEK
};
GLOBAL enum hole_detection_method hole_detection;
GLOBAL bool starting_file_option;
/* Specified maximum byte length of each tape volume (multiple of 1024). */
@@ -382,6 +402,8 @@ GLOBAL dev_t root_device;
/* Unquote filenames */
GLOBAL bool unquote_option;
GLOBAL int savedir_sort_order;
/* Show file or archive names after transformation.
In particular, when creating archive in verbose mode, list member names
as stored in the archive */
@@ -393,9 +415,8 @@ GLOBAL bool show_transformed_names_option;
set for incremental archives. */
GLOBAL bool delay_directory_restore_option;
/* Warn about implicit use of the wildcards in command line arguments.
(Default for tar prior to 1.15.91, but changed afterwards */
GLOBAL bool warn_regex_usage;
/* When set, tar will not refuse to create empty archives */
GLOBAL bool files_from_option;
/* Declarations for each module. */
@@ -427,7 +448,7 @@ size_t available_space_after (union block *pointer);
off_t current_block_ordinal (void);
void close_archive (void);
void closeout_volume_number (void);
void compute_duration (void);
double compute_duration (void);
union block *find_next_block (void);
void flush_read (void);
void flush_write (void);
@@ -444,6 +465,12 @@ void archive_read_error (void);
off_t seek_archive (off_t size);
void set_start_time (void);
#define TF_READ 0
#define TF_WRITE 1
#define TF_DELETED 2
int format_total_stats (FILE *fp, char const *const *formats, int eor, int eol);
void print_total_stats (void);
void mv_begin_write (const char *file_name, off_t totsize, off_t sizeleft);
void mv_begin_read (struct tar_stat_info *st);
@@ -511,6 +538,8 @@ void extract_archive (void);
void extract_finish (void);
bool rename_directory (char *src, char *dst);
void remove_delayed_set_stat (const char *fname);
/* Module delete.c. */
void delete_archive_members (void);
@@ -606,10 +635,7 @@ typedef struct namebuf *namebuf_t;
namebuf_t namebuf_create (const char *dir);
void namebuf_free (namebuf_t buf);
char *namebuf_name (namebuf_t buf, const char *name);
void namebuf_add_dir (namebuf_t buf, const char *name);
char *namebuf_finish (namebuf_t buf);
const char *tar_getcdpath (int);
const char *tar_dirname (void);
/* Represent N using a signed integer I such that (uintmax_t) I == N.
@@ -712,9 +738,7 @@ void uid_to_uname (uid_t uid, char **uname);
int uname_to_uid (char const *uname, uid_t *puid);
void name_init (void);
void name_add_name (const char *name, int matching_flags);
void name_add_dir (const char *name);
void name_add_file (const char *name, int term);
void name_add_name (const char *name);
void name_term (void);
const char *name_next (int change_dirs);
void name_gather (void);
@@ -728,21 +752,21 @@ void collect_and_sort_names (void);
struct name *name_scan (const char *name);
struct name const *name_from_list (void);
void blank_name_list (void);
char *new_name (const char *dir_name, const char *name);
char *make_file_name (const char *dir_name, const char *name);
size_t stripped_prefix_len (char const *file_name, size_t num);
bool all_names_found (struct tar_stat_info *st);
bool excluded_name (char const *name);
void add_avoided_name (char const *name);
bool is_avoided_name (char const *name);
bool contains_dot_dot (char const *name);
#define ISFOUND(c) ((occurrence_option == 0) ? (c)->found_count : \
(c)->found_count == occurrence_option)
#define WASFOUND(c) ((occurrence_option == 0) ? (c)->found_count : \
(c)->found_count >= occurrence_option)
#define ISFOUND(c) (occurrence_option == 0 \
? (c)->found_count != 0 \
: (c)->found_count == occurrence_option)
#define WASFOUND(c) (occurrence_option == 0 \
? (c)->found_count != 0 \
: (c)->found_count >= occurrence_option)
/* Module tar.c. */
@@ -760,7 +784,26 @@ const char *subcommand_string (enum subcommand c);
void set_exit_status (int val);
void request_stdin (const char *option);
void more_options (int argc, char **argv);
/* Where an option comes from: */
enum option_source
{
OPTS_ENVIRON, /* Environment variable TAR_OPTIONS */
OPTS_COMMAND_LINE, /* Command line */
OPTS_FILE /* File supplied by --files-from */
};
/* Option location */
struct option_locus
{
enum option_source source; /* Option origin */
char const *name; /* File or variable name */
size_t line; /* Number of input line if source is OPTS_FILE */
struct option_locus *prev; /* Previous occurrence of the option of same
class */
};
void more_options (int argc, char **argv, struct option_locus *loc);
/* Module update.c. */
@@ -851,11 +894,14 @@ bool transform_program_p (void);
/* Module suffix.c */
void set_compression_program_by_suffix (const char *name, const char *defprog);
char *strip_compression_suffix (const char *name);
/* Module checkpoint.c */
void checkpoint_compile_action (const char *str);
void checkpoint_finish_compile (void);
void checkpoint_run (bool do_write);
void checkpoint_finish (void);
void checkpoint_flush_actions (void);
/* Module warning.c */
#define WARN_ALONE_ZERO_BLOCK 0x00000001
@@ -907,4 +953,22 @@ void finish_deferred_unlinks (void);
/* Module exit.c */
extern void (*fatal_exit_hook) (void);
/* Module exclist.c */
#define EXCL_DEFAULT 0x00
#define EXCL_RECURSIVE 0x01
#define EXCL_NON_RECURSIVE 0x02
void excfile_add (const char *name, int flags);
void info_attach_exclist (struct tar_stat_info *dir);
void info_free_exclist (struct tar_stat_info *dir);
bool excluded_name (char const *name, struct tar_stat_info *st);
void exclude_vcs_ignores (void);
/* Module map.c */
void owner_map_read (char const *name);
int owner_map_translate (uid_t uid, uid_t *new_uid, char const **new_name);
void group_map_read (char const *file);
int group_map_translate (gid_t gid, gid_t *new_gid, char const **new_name);
_GL_INLINE_HEADER_END

View File

@@ -1,7 +1,7 @@
/* Diff files from a tar archive.
Copyright 1988, 1992-1994, 1996-1997, 1999-2001, 2003-2007,
2009-2010, 2012-2013 Free Software Foundation, Inc.
2009-2010, 2012-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -270,11 +270,12 @@ diff_link (void)
static void
diff_symlink (void)
{
char buf[1024];
size_t len = strlen (current_stat_info.link_name);
char *linkbuf = alloca (len + 1);
char *linkbuf = len < sizeof buf ? buf : xmalloc (len + 1);
int status = readlinkat (chdir_fd, current_stat_info.file_name,
linkbuf, len + 1);
ssize_t status = readlinkat (chdir_fd, current_stat_info.file_name,
linkbuf, len + 1);
if (status < 0)
{
@@ -285,8 +286,11 @@ diff_symlink (void)
report_difference (&current_stat_info, NULL);
}
else if (status != len
|| strncmp (current_stat_info.link_name, linkbuf, len) != 0)
|| memcmp (current_stat_info.link_name, linkbuf, len) != 0)
report_difference (&current_stat_info, _("Symlink differs"));
if (linkbuf != buf)
free (linkbuf);
}
#endif
@@ -371,7 +375,10 @@ diff_dumpdir (struct tar_stat_info *dir)
if (fd < 0)
diag = open_diag;
else if (fstat (fd, &dir->stat))
diag = stat_diag;
{
diag = stat_diag;
close (fd);
}
else
dir->fd = fd;
if (diag)
@@ -439,10 +446,9 @@ diff_multivol (void)
{
seek_error_details (current_stat_info.file_name, offset);
report_difference (&current_stat_info, NULL);
return;
}
read_and_process (&current_stat_info, process_rawdata);
else
read_and_process (&current_stat_info, process_rawdata);
status = close (fd);
if (status != 0)

View File

@@ -1,7 +1,7 @@
/* Create a tar archive.
Copyright 1985, 1992-1994, 1996-1997, 1999-2001, 2003-2007,
2009-2010, 2012-2013 Free Software Foundation, Inc.
2009-2010, 2012-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -22,6 +22,7 @@
#include <system.h>
#include <areadlink.h>
#include <quotearg.h>
#include "common.h"
@@ -543,7 +544,7 @@ write_gnu_long_link (struct tar_stat_info *st, const char *p, char type)
union block *header;
char *tmpname;
header = start_private_header ("././@LongLink", size, start_time.tv_sec);
header = start_private_header ("././@LongLink", size, 0);
uid_to_uname (0, &tmpname);
UNAME_TO_CHARS (tmpname, header->header.uname);
free (tmpname);
@@ -706,7 +707,7 @@ write_extended (bool global, struct tar_stat_info *st, union block *old_header)
{
type = XHDTYPE;
p = xheader_xhdr_name (st);
t = st->stat.st_mtime;
t = set_mtime_option ? mtime_option.tv_sec : st->stat.st_mtime;
}
xheader_write (type, p, t, &st->xhdr);
free (p);
@@ -740,17 +741,17 @@ union block *
start_header (struct tar_stat_info *st)
{
union block *header;
char const *uname = NULL;
char const *gname = NULL;
header = write_header_name (st);
if (!header)
return NULL;
/* Override some stat fields, if requested to do so. */
owner_map_translate (st->stat.st_uid, &st->stat.st_uid, &uname);
group_map_translate (st->stat.st_gid, &st->stat.st_gid, &gname);
if (owner_option != (uid_t) -1)
st->stat.st_uid = owner_option;
if (group_option != (gid_t) -1)
st->stat.st_gid = group_option;
if (mode_option)
st->stat.st_mode =
((st->stat.st_mode & ~MODE_ALL)
@@ -822,7 +823,24 @@ start_header (struct tar_stat_info *st)
}
{
struct timespec mtime = set_mtime_option ? mtime_option : st->mtime;
struct timespec mtime;
switch (set_mtime_option)
{
case USE_FILE_MTIME:
mtime = st->mtime;
break;
case FORCE_MTIME:
mtime = mtime_option;
break;
case CLAMP_MTIME:
mtime = timespec_cmp (st->mtime, mtime_option) > 0
? mtime_option : st->mtime;
break;
}
if (archive_format == POSIX_FORMAT)
{
if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec
@@ -909,13 +927,13 @@ start_header (struct tar_stat_info *st)
}
else
{
if (owner_name_option)
st->uname = xstrdup (owner_name_option);
if (uname)
st->uname = xstrdup (uname);
else
uid_to_uname (st->stat.st_uid, &st->uname);
if (group_name_option)
st->gname = xstrdup (group_name_option);
if (gname)
st->gname = xstrdup (gname);
else
gid_to_gname (st->stat.st_gid, &st->gname);
@@ -1113,6 +1131,8 @@ dump_dir0 (struct tar_stat_info *st, char const *directory)
if (!blk)
return;
info_attach_exclist (st);
if (incremental_option && archive_format != POSIX_FORMAT)
blk->header.typeflag = GNUTYPE_DUMPDIR;
else /* if (standard_option) */
@@ -1210,7 +1230,7 @@ dump_dir0 (struct tar_stat_info *st, char const *directory)
name_buf = xrealloc (name_buf, name_size + 1);
}
strcpy (name_buf + name_len, entry);
if (!excluded_name (name_buf))
if (!excluded_name (name_buf, st))
dump_file (st, entry, name_buf);
}
@@ -1288,7 +1308,7 @@ get_directory_entries (struct tar_stat_info *st)
while (! (st->dirstream = fdopendir (st->fd)))
if (! open_failure_recover (st))
return 0;
return streamsavedir (st->dirstream);
return streamsavedir (st->dirstream, savedir_sort_order);
}
/* Dump the directory ST. Return true if successful, false (emitting
@@ -1339,12 +1359,12 @@ create_archive (void)
collect_and_sort_names ();
while ((p = name_from_list ()) != NULL)
if (!excluded_name (p->name))
if (!excluded_name (p->name, NULL))
dump_file (0, p->name, p->name);
blank_name_list ();
while ((p = name_from_list ()) != NULL)
if (!excluded_name (p->name))
if (!excluded_name (p->name, NULL))
{
struct tar_stat_info st;
size_t plen = strlen (p->name);
@@ -1358,7 +1378,7 @@ create_archive (void)
if (! ISSLASH (buffer[plen - 1]))
buffer[plen++] = DIRECTORY_SEPARATOR;
tar_stat_init (&st);
q = directory_contents (gnu_list_name->directory);
q = directory_contents (p->directory);
if (q)
while (*q)
{
@@ -1401,7 +1421,7 @@ create_archive (void)
{
const char *name;
while ((name = name_next (1)) != NULL)
if (!excluded_name (name))
if (!excluded_name (name, NULL))
dump_file (0, name, name);
}
@@ -1470,8 +1490,8 @@ dump_hard_link (struct tar_stat_info *st)
/* We found a link. */
char const *link_name = safer_name_suffix (duplicate->name, true,
absolute_names_option);
duplicate->nlink--;
if (duplicate->nlink)
duplicate->nlink--;
block_ordinal = current_block_ordinal ();
assign_string (&st->link_name, link_name);
@@ -1835,22 +1855,17 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
#ifdef HAVE_READLINK
else if (S_ISLNK (st->stat.st_mode))
{
char *buffer;
int size;
size_t linklen = st->stat.st_size;
if (linklen != st->stat.st_size || linklen + 1 == 0)
xalloc_die ();
buffer = (char *) alloca (linklen + 1);
size = readlinkat (parentfd, name, buffer, linklen + 1);
if (size < 0)
st->link_name = areadlinkat_with_size (parentfd, name, st->stat.st_size);
if (!st->link_name)
{
if (errno == ENOMEM)
xalloc_die ();
file_removed_diag (p, top_level, readlink_diag);
return;
}
buffer[size] = '\0';
assign_string (&st->link_name, buffer);
transform_name (&st->link_name, XFORM_SYMLINK);
if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT)
< strlen (st->link_name))
write_long_link (st);
xattrs_selinux_get (parentfd, name, st, 0);

View File

@@ -1,7 +1,7 @@
/* Delete entries from a tar archive.
Copyright 1988, 1992, 1994, 1996-1997, 2000-2001, 2003-2006, 2010,
2013 Free Software Foundation, Inc.
2013-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.

329
src/exclist.c Normal file
View File

@@ -0,0 +1,329 @@
/* Per-directory exclusion files for tar.
Copyright 2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.
GNU tar 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 of the License, or
(at your option) any later version.
GNU tar 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/>.
*/
#include <system.h>
#include <quotearg.h>
#include <fnmatch.h>
#include <wordsplit.h>
#include "common.h"
typedef void (*add_fn) (struct exclude *, char const *, int, void *);
struct vcs_ignore_file
{
char const *filename;
int flags;
add_fn addfn;
void *(*initfn) (void *);
void *data;
};
static struct vcs_ignore_file *get_vcs_ignore_file (const char *name);
struct excfile
{
struct excfile *next;
int flags;
char name[1];
};
static struct excfile *excfile_head, *excfile_tail;
void
excfile_add (const char *name, int flags)
{
struct excfile *p = xmalloc (sizeof (*p) + strlen (name));
p->next = NULL;
p->flags = flags;
strcpy (p->name, name);
if (excfile_tail)
excfile_tail->next = p;
else
excfile_head = p;
excfile_tail = p;
}
struct exclist
{
struct exclist *next, *prev;
int flags;
struct exclude *excluded;
};
void
info_attach_exclist (struct tar_stat_info *dir)
{
struct excfile *file;
struct exclist *head = NULL, *tail = NULL, *ent;
struct vcs_ignore_file *vcsfile;
if (dir->exclude_list)
return;
for (file = excfile_head; file; file = file->next)
{
if (faccessat (dir ? dir->fd : chdir_fd, file->name, F_OK, 0) == 0)
{
FILE *fp;
struct exclude *ex = NULL;
int fd = subfile_open (dir, file->name, O_RDONLY);
if (fd == -1)
{
open_error (file->name);
continue;
}
fp = fdopen (fd, "r");
if (!fp)
{
ERROR ((0, errno, _("%s: fdopen failed"), file->name));
close (fd);
continue;
}
if (!ex)
ex = new_exclude ();
vcsfile = get_vcs_ignore_file (file->name);
if (vcsfile->initfn)
vcsfile->data = vcsfile->initfn (vcsfile->data);
if (add_exclude_fp (vcsfile->addfn, ex, fp,
EXCLUDE_WILDCARDS|EXCLUDE_ANCHORED, '\n',
vcsfile->data))
{
int e = errno;
FATAL_ERROR ((0, e, "%s", quotearg_colon (file->name)));
}
fclose (fp);
ent = xmalloc (sizeof (*ent));
ent->excluded = ex;
ent->flags = file->flags == EXCL_DEFAULT
? file->flags : vcsfile->flags;
ent->prev = tail;
ent->next = NULL;
if (tail)
tail->next = ent;
else
head = ent;
tail = ent;
}
}
dir->exclude_list = head;
}
void
info_free_exclist (struct tar_stat_info *dir)
{
struct exclist *ep = dir->exclude_list;
while (ep)
{
struct exclist *next = ep->next;
free_exclude (ep->excluded);
free (ep);
ep = next;
}
dir->exclude_list = NULL;
}
/* Return nonzero if file NAME is excluded. */
bool
excluded_name (char const *name, struct tar_stat_info *st)
{
struct exclist *ep;
const char *rname = NULL;
char *bname = NULL;
bool result;
int nr = 0;
name += FILE_SYSTEM_PREFIX_LEN (name);
/* Try global exclusion list first */
if (excluded_file_name (excluded, name))
return true;
if (!st)
return false;
for (result = false; st && !result; st = st->parent, nr = EXCL_NON_RECURSIVE)
{
for (ep = st->exclude_list; ep; ep = ep->next)
{
if (ep->flags & nr)
continue;
if ((result = excluded_file_name (ep->excluded, name)))
break;
if (!rname)
{
rname = name;
/* Skip leading ./ */
while (*rname == '.' && ISSLASH (rname[1]))
rname += 2;
}
if ((result = excluded_file_name (ep->excluded, rname)))
break;
if (!bname)
bname = base_name (name);
if ((result = excluded_file_name (ep->excluded, bname)))
break;
}
}
free (bname);
return result;
}
static void
cvs_addfn (struct exclude *ex, char const *pattern, int options, void *data)
{
struct wordsplit ws;
size_t i;
if (wordsplit (pattern, &ws,
WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_SQUEEZE_DELIMS))
return;
for (i = 0; i < ws.ws_wordc; i++)
add_exclude (ex, ws.ws_wordv[i], options);
wordsplit_free (&ws);
}
static void
git_addfn (struct exclude *ex, char const *pattern, int options, void *data)
{
while (isspace (*pattern))
++pattern;
if (*pattern == 0 || *pattern == '#')
return;
if (*pattern == '\\' && pattern[1] == '#')
++pattern;
add_exclude (ex, pattern, options);
}
static void
bzr_addfn (struct exclude *ex, char const *pattern, int options, void *data)
{
while (isspace (*pattern))
++pattern;
if (*pattern == 0 || *pattern == '#')
return;
if (*pattern == '!')
{
if (*++pattern == '!')
++pattern;
else
options |= EXCLUDE_INCLUDE;
}
/* FIXME: According to the docs, globbing patterns are rsync-style,
and regexps are perl-style. */
if (strncmp (pattern, "RE:", 3) == 0)
{
pattern += 3;
options &= ~EXCLUDE_WILDCARDS;
options |= EXCLUDE_REGEX;
}
add_exclude (ex, pattern, options);
}
static void *
hg_initfn (void *data)
{
static int hg_options;
int *hgopt = data ? data : &hg_options;
*hgopt = EXCLUDE_REGEX;
return hgopt;
}
static void
hg_addfn (struct exclude *ex, char const *pattern, int options, void *data)
{
int *hgopt = data;
size_t len;
while (isspace (*pattern))
++pattern;
if (*pattern == 0 || *pattern == '#')
return;
if (strncmp (pattern, "syntax:", 7) == 0)
{
for (pattern += 7; isspace (*pattern); ++pattern)
;
if (strcmp (pattern, "regexp") == 0)
/* FIXME: Regexps must be perl-style */
*hgopt = EXCLUDE_REGEX;
else if (strcmp (pattern, "glob") == 0)
*hgopt = EXCLUDE_WILDCARDS;
/* Ignore unknown syntax */
return;
}
len = strlen(pattern);
if (pattern[len-1] == '/')
{
char *p;
--len;
p = xmalloc (len+1);
memcpy (p, pattern, len);
p[len] = 0;
pattern = p;
exclude_add_pattern_buffer (ex, p);
options |= FNM_LEADING_DIR|EXCLUDE_ALLOC;
}
add_exclude (ex, pattern,
((*hgopt == EXCLUDE_REGEX)
? (options & ~EXCLUDE_WILDCARDS)
: (options & ~EXCLUDE_REGEX)) | *hgopt);
}
static struct vcs_ignore_file vcs_ignore_files[] = {
{ ".cvsignore", EXCL_NON_RECURSIVE, cvs_addfn, NULL, NULL },
{ ".gitignore", 0, git_addfn, NULL, NULL },
{ ".bzrignore", 0, bzr_addfn, NULL, NULL },
{ ".hgignore", 0, hg_addfn, hg_initfn, NULL },
{ NULL, 0, git_addfn, NULL, NULL }
};
static struct vcs_ignore_file *
get_vcs_ignore_file (const char *name)
{
struct vcs_ignore_file *p;
for (p = vcs_ignore_files; p->filename; p++)
if (strcmp (p->filename, name) == 0)
break;
return p;
}
void
exclude_vcs_ignores (void)
{
struct vcs_ignore_file *p;
for (p = vcs_ignore_files; p->filename; p++)
excfile_add (p->filename, EXCL_DEFAULT);
}

View File

@@ -1,6 +1,6 @@
/* Exit from GNU tar.
Copyright 2009, 2013 Free Software Foundation, Inc.
Copyright 2009, 2013-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -1,7 +1,7 @@
/* Extract files from a tar archive.
Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2013
Free Software Foundation, Inc.
Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2014,
2016 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -109,7 +109,7 @@ struct delayed_set_stat
struct xattr_array *xattr_map;
/* Length and contents of name. */
size_t file_name_len;
char file_name[1];
char *file_name;
};
static struct delayed_set_stat *delayed_set_stat_head;
@@ -441,9 +441,7 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
mode_t mode, int atflag)
{
size_t file_name_len = strlen (file_name);
struct delayed_set_stat *data =
xmalloc (offsetof (struct delayed_set_stat, file_name)
+ file_name_len + 1);
struct delayed_set_stat *data = xmalloc (sizeof (*data));
data->next = delayed_set_stat_head;
data->mode = mode;
if (st)
@@ -456,6 +454,7 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
data->mtime = st->mtime;
}
data->file_name_len = file_name_len;
data->file_name = xstrdup (file_name);
data->current_mode = current_mode;
data->current_mode_mask = current_mode_mask;
data->interdir = ! st;
@@ -537,6 +536,56 @@ repair_delayed_set_stat (char const *dir,
quotearg_colon (dir)));
}
static void
free_delayed_set_stat (struct delayed_set_stat *data)
{
free (data->file_name);
xheader_xattr_free (data->xattr_map, data->xattr_map_size);
free (data->cntx_name);
free (data->acls_a_ptr);
free (data->acls_d_ptr);
free (data);
}
void
remove_delayed_set_stat (const char *fname)
{
struct delayed_set_stat *data, *next, *prev = NULL;
for (data = delayed_set_stat_head; data; data = next)
{
next = data->next;
if (chdir_current == data->change_dir
&& strcmp (data->file_name, fname) == 0)
{
free_delayed_set_stat (data);
if (prev)
prev->next = next;
else
delayed_set_stat_head = next;
return;
}
else
prev = data;
}
}
static void
fixup_delayed_set_stat (char const *src, char const *dst)
{
struct delayed_set_stat *data;
for (data = delayed_set_stat_head; data; data = data->next)
{
if (chdir_current == data->change_dir
&& strcmp (data->file_name, src) == 0)
{
free (data->file_name);
data->file_name = xstrdup (dst);
data->file_name_len = strlen (dst);
return;
}
}
}
/* After a file/link/directory creation has failed, see if
it's because some required directory was not present, and if so,
create all required directories. Return zero if all the required
@@ -846,11 +895,7 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
}
delayed_set_stat_head = data->next;
xheader_xattr_free (data->xattr_map, data->xattr_map_size);
free (data->cntx_name);
free (data->acls_a_ptr);
free (data->acls_d_ptr);
free (data);
free_delayed_set_stat (data);
}
}
@@ -1741,7 +1786,9 @@ extract_finish (void)
bool
rename_directory (char *src, char *dst)
{
if (renameat (chdir_fd, src, chdir_fd, dst) != 0)
if (renameat (chdir_fd, src, chdir_fd, dst) == 0)
fixup_delayed_set_stat (src, dst);
else
{
int e = errno;
bool interdir_made;

View File

@@ -1,7 +1,7 @@
/* GNU dump extensions to tar.
Copyright 1988, 1992-1994, 1996-1997, 1999-2001, 2003-2009, 2013
Free Software Foundation, Inc.
Copyright 1988, 1992-1994, 1996-1997, 1999-2001, 2003-2009,
2013-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -734,6 +734,8 @@ scan_directory (struct tar_stat_info *st)
if (! dirp)
savedir_error (dir);
info_attach_exclist (st);
tmp = xstrdup (dir);
zap_slashes (tmp);
@@ -759,10 +761,10 @@ scan_directory (struct tar_stat_info *st)
entry = dumpdir_next (itr))
{
char *full_name = namebuf_name (nbuf, entry + 1);
if (*entry == 'I') /* Ignored entry */
*entry = 'N';
else if (excluded_name (full_name))
else if (excluded_name (full_name, st))
*entry = 'N';
else
{
@@ -792,7 +794,7 @@ scan_directory (struct tar_stat_info *st)
diag = stat_diag;
}
}
if (diag)
{
file_removed_diag (full_name, false, diag);
@@ -806,7 +808,7 @@ scan_directory (struct tar_stat_info *st)
else if (directory->children == ALL_CHILDREN)
pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
*entry = 'D';
stsub.parent = st;
procdir (full_name, &stsub, pd_flag, entry);
restore_parent_fd (&stsub);
@@ -823,7 +825,7 @@ scan_directory (struct tar_stat_info *st)
*entry = 'N';
else
*entry = 'Y';
tar_stat_destroy (&stsub);
}
}
@@ -832,7 +834,7 @@ scan_directory (struct tar_stat_info *st)
else if (directory->tagfile)
maketagdumpdir (directory);
}
namebuf_free (nbuf);
free (dirp);
@@ -1153,11 +1155,14 @@ read_num (FILE *fp, char const *fieldname,
}
if (c)
FATAL_ERROR ((0, 0,
_("%s: byte %s: %s %s followed by invalid byte 0x%02x"),
quotearg_colon (listed_incremental_option),
offtostr (ftello (fp), offbuf),
fieldname, buf, c));
{
unsigned uc = c;
FATAL_ERROR ((0, 0,
_("%s: byte %s: %s %s followed by invalid byte 0x%02x"),
quotearg_colon (listed_incremental_option),
offtostr (ftello (fp), offbuf),
fieldname, buf, uc));
}
*pval = strtosysint (buf, NULL, min_val, max_val);
conversion_errno = errno;
@@ -1296,8 +1301,8 @@ void
show_snapshot_field_ranges (void)
{
struct field_range const *p;
char minbuf[max (SYSINT_BUFSIZE, INT_BUFSIZE_BOUND (intmax_t))];
char maxbuf[max (SYSINT_BUFSIZE, INT_BUFSIZE_BOUND (uintmax_t))];
char minbuf[SYSINT_BUFSIZE];
char maxbuf[SYSINT_BUFSIZE];
printf("This tar's snapshot file field ranges are\n");
printf (" (%-15s => [ %s, %s ]):\n\n", "field name", "min", "max");
@@ -1406,7 +1411,7 @@ write_directory_file_entry (void *entry, void *data)
if (DIR_IS_FOUND (directory))
{
char buf[max (SYSINT_BUFSIZE, INT_BUFSIZE_BOUND (intmax_t))];
char buf[SYSINT_BUFSIZE];
char const *s;
s = DIR_IS_NFS (directory) ? "1" : "0";
@@ -1539,9 +1544,10 @@ dumpdir_ok (char *dumpdir)
{
if (expect && *p != expect)
{
unsigned char uc = *p;
ERROR ((0, 0,
_("Malformed dumpdir: expected '%c' but found %#3o"),
expect, *p));
expect, uc));
return false;
}
switch (*p)
@@ -1576,7 +1582,7 @@ dumpdir_ok (char *dumpdir)
if (expect != 'T')
{
ERROR ((0, 0,
_("Malformed dumpdir: 'T' not preceeded by 'R'")));
_("Malformed dumpdir: 'T' not preceded by 'R'")));
return false;
}
if (p[1] == 0 && !has_tempdir)
@@ -1706,7 +1712,7 @@ try_purge_directory (char const *directory_name)
const char *entry;
struct stat st;
free (p);
p = new_name (directory_name, cur);
p = make_file_name (directory_name, cur);
if (deref_stat (p, &st) != 0)
{

View File

@@ -1,7 +1,7 @@
/* List a tar archive, with support routines for reading a tar archive.
Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2013
Free Software Foundation, Inc.
Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2016 Free
Software Foundation, Inc.
This file is part of GNU tar.
@@ -115,6 +115,32 @@ transform_member_name (char **pinput, int type)
return transform_name_fp (pinput, type, decode_xform, &type);
}
static void
enforce_one_top_level (char **pfile_name)
{
char *file_name = *pfile_name;
char *p;
for (p = file_name; *p && (ISSLASH (*p) || *p == '.'); p++)
;
if (*p)
{
int pos = strlen (one_top_level_dir);
if (strncmp (p, one_top_level_dir, pos) == 0)
{
if (ISSLASH (p[pos]) || p[pos] == 0)
return;
}
*pfile_name = make_file_name (one_top_level_dir, file_name);
normalize_filename_x (*pfile_name);
}
else
*pfile_name = xstrdup (one_top_level_dir);
free (file_name);
}
void
transform_stat_info (int typeflag, struct tar_stat_info *stat_info)
{
@@ -132,6 +158,9 @@ transform_stat_info (int typeflag, struct tar_stat_info *stat_info)
case LNKTYPE:
transform_member_name (&stat_info->link_name, XFORM_LINK);
}
if (one_top_level_option)
enforce_one_top_level (&current_stat_info.file_name);
}
/* Main loop for reading an archive. */
@@ -166,7 +195,7 @@ read_and (void (*do_something) (void))
decode_header (current_header, &current_stat_info,
&current_format, 1);
if (! name_match (current_stat_info.file_name)
|| (NEWER_OPTION_INITIALIZED (newer_mtime_option)
|| (TIME_OPTION_INITIALIZED (newer_mtime_option)
/* FIXME: We get mtime now, and again later; this causes
duplicate diagnostics if header.mtime is bogus. */
&& ((mtime.tv_sec
@@ -176,7 +205,8 @@ read_and (void (*do_something) (void))
mtime.tv_nsec = 0,
current_stat_info.mtime = mtime,
OLDER_TAR_STAT_TIME (current_stat_info, m)))
|| excluded_name (current_stat_info.file_name))
|| excluded_name (current_stat_info.file_name,
current_stat_info.parent))
{
switch (current_header->header.typeflag)
{
@@ -194,6 +224,7 @@ read_and (void (*do_something) (void))
continue;
}
}
transform_stat_info (current_header->header.typeflag,
&current_stat_info);
(*do_something) ();
@@ -660,7 +691,6 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
}
}
stat_info->archive_file_size = stat_info->stat.st_size;
xheader_decode (stat_info);
if (sparse_member_p (stat_info))
@@ -723,7 +753,7 @@ from_header (char const *where0, size_t digs, char const *type,
type));
return -1;
}
if (!ISSPACE ((unsigned char) *where))
if (!isspace ((unsigned char) *where))
break;
where++;
}
@@ -861,7 +891,7 @@ from_header (char const *where0, size_t digs, char const *type,
value = -value;
}
if (where != lim && *where && !ISSPACE ((unsigned char) *where))
if (where != lim && *where && !isspace ((unsigned char) *where))
{
if (type)
{
@@ -1111,7 +1141,10 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
if (verbose_option <= 1)
{
/* Just the fax, mam. */
fprintf (stdlis, "%s\n", quotearg (temp_name));
fputs (quotearg (temp_name), stdlis);
if (show_transformed_names_option && st->had_trailing_slash)
fputc ('/', stdlis);
fputc ('\n', stdlis);
}
else
{
@@ -1138,9 +1171,7 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
case GNUTYPE_SPARSE:
case REGTYPE:
case AREGTYPE:
modes[0] = '-';
if (temp_name[strlen (temp_name) - 1] == '/')
modes[0] = 'd';
modes[0] = st->had_trailing_slash ? 'd' : '-';
break;
case LNKTYPE:
modes[0] = 'h';
@@ -1188,18 +1219,7 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
&& !numeric_owner_option)
user = st->uname;
else
{
/* Try parsing it as an unsigned integer first, and as a
uid_t if that fails. This method can list positive user
ids that are too large to fit in a uid_t. */
uintmax_t u = from_header (blk->header.uid,
sizeof blk->header.uid, 0,
0, UINTMAX_MAX,
false, false);
user = (u != -1
? STRINGIFY_BIGINT (u, uform)
: imaxtostr (UID_FROM_HEADER (blk->header.uid), uform));
}
user = STRINGIFY_BIGINT (st->stat.st_uid, uform);
if (st->gname
&& st->gname[0]
@@ -1207,18 +1227,7 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
&& !numeric_owner_option)
group = st->gname;
else
{
/* Try parsing it as an unsigned integer first, and as a
gid_t if that fails. This method can list positive group
ids that are too large to fit in a gid_t. */
uintmax_t g = from_header (blk->header.gid,
sizeof blk->header.gid, 0,
0, UINTMAX_MAX,
false, false);
group = (g != -1
? STRINGIFY_BIGINT (g, gform)
: imaxtostr (GID_FROM_HEADER (blk->header.gid), gform));
}
group = STRINGIFY_BIGINT (st->stat.st_gid, gform);
/* Format the file size or major/minor device numbers. */
@@ -1251,6 +1260,8 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
datewidth, time_stamp);
fprintf (stdlis, " %s", quotearg (temp_name));
if (show_transformed_names_option && st->had_trailing_slash)
fputc ('/', stdlis);
switch (blk->header.typeflag)
{

283
src/map.c Normal file
View File

@@ -0,0 +1,283 @@
/* Owner/group mapping for tar
Copyright 2015-2016 Free Software Foundation, Inc.
This file is part of GNU tar.
GNU tar 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 of the License, or
(at your option) any later version.
GNU tar 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/>. */
#include <system.h>
#include "common.h"
#include "wordsplit.h"
#include <hash.h>
#include <pwd.h>
struct mapentry
{
uintmax_t orig_id;
uintmax_t new_id;
char *new_name;
};
static size_t
map_hash (void const *entry, size_t nbuckets)
{
struct mapentry const *map = entry;
return map->orig_id % nbuckets;
}
static bool
map_compare (void const *entry1, void const *entry2)
{
struct mapentry const *map1 = entry1;
struct mapentry const *map2 = entry2;
return map1->orig_id == map2->orig_id;
}
static int
parse_id (uintmax_t *retval,
char const *arg, char const *what, uintmax_t maxval,
char const *file, unsigned line)
{
uintmax_t v;
char *p;
errno = 0;
v = strtoumax (arg, &p, 10);
if (*p || errno)
{
error (0, 0, _("%s:%u: invalid %s: %s"), file, line, what, arg);
return -1;
}
if (v > maxval)
{
error (0, 0, _("%s:%u: %s out of range: %s"), file, line, what, arg);
return -1;
}
*retval = v;
return 0;
}
static void
map_read (Hash_table **ptab, char const *file,
uintmax_t (*name_to_id) (char const *), char const *what,
uintmax_t maxval)
{
FILE *fp;
char *buf = NULL;
size_t bufsize = 0;
ssize_t n;
struct wordsplit ws;
int wsopt;
unsigned line;
int err = 0;
fp = fopen (file, "r");
if (!fp)
open_fatal (file);
ws.ws_comment = "#";
wsopt = WRDSF_COMMENT | WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_SQUEEZE_DELIMS
| WRDSF_QUOTE;
line = 0;
while ((n = getline (&buf, &bufsize, fp)) > 0)
{
struct mapentry *ent;
uintmax_t orig_id, new_id;
char *name = NULL;
char *colon;
++line;
if (wordsplit (buf, &ws, wsopt))
FATAL_ERROR ((0, 0, _("%s:%u: cannot split line: %s"),
file, line, wordsplit_strerror (&ws)));
wsopt |= WRDSF_REUSE;
if (ws.ws_wordc == 0)
continue;
if (ws.ws_wordc != 2)
{
error (0, 0, _("%s:%u: malformed line"), file, line);
err = 1;
continue;
}
if (ws.ws_wordv[0][0] == '+')
{
if (parse_id (&orig_id, ws.ws_wordv[0]+1, what, maxval, file, line))
{
err = 1;
continue;
}
}
else if (name_to_id)
{
orig_id = name_to_id (ws.ws_wordv[0]);
if (orig_id == UINTMAX_MAX)
{
error (0, 0, _("%s:%u: can't obtain %s of %s"),
file, line, what, ws.ws_wordv[0]);
err = 1;
continue;
}
}
colon = strchr (ws.ws_wordv[1], ':');
if (colon)
{
if (colon > ws.ws_wordv[1])
name = ws.ws_wordv[1];
*colon++ = 0;
if (parse_id (&new_id, colon, what, maxval, file, line))
{
err = 1;
continue;
}
}
else if (ws.ws_wordv[1][0] == '+')
{
if (parse_id (&new_id, ws.ws_wordv[1], what, maxval, file, line))
{
err = 1;
continue;
}
}
else
{
name = ws.ws_wordv[1];
new_id = name_to_id (ws.ws_wordv[1]);
if (new_id == UINTMAX_MAX)
{
error (0, 0, _("%s:%u: can't obtain %s of %s"),
file, line, what, ws.ws_wordv[1]);
err = 1;
continue;
}
}
ent = xmalloc (sizeof (*ent));
ent->orig_id = orig_id;
ent->new_id = new_id;
ent->new_name = name ? xstrdup (name) : NULL;
if (!((*ptab
|| (*ptab = hash_initialize (0, 0, map_hash, map_compare, 0)))
&& hash_insert (*ptab, ent)))
xalloc_die ();
}
if (wsopt & WRDSF_REUSE)
wordsplit_free (&ws);
fclose (fp);
if (err)
FATAL_ERROR ((0, 0, _("errors reading map file")));
}
/* UID translation */
static Hash_table *owner_map;
static uintmax_t
name_to_uid (char const *name)
{
struct passwd *pw = getpwnam (name);
return pw ? pw->pw_uid : UINTMAX_MAX;
}
void
owner_map_read (char const *file)
{
map_read (&owner_map, file, name_to_uid, "UID", TYPE_MAXIMUM (uid_t));
}
int
owner_map_translate (uid_t uid, uid_t *new_uid, char const **new_name)
{
int rc = 1;
if (owner_map)
{
struct mapentry ent, *res;
ent.orig_id = uid;
res = hash_lookup (owner_map, &ent);
if (res)
{
*new_uid = res->new_id;
*new_name = res->new_name;
return 0;
}
}
if (owner_option != (uid_t) -1)
{
*new_uid = owner_option;
rc = 0;
}
if (owner_name_option)
{
*new_name = owner_name_option;
rc = 0;
}
return rc;
}
/* GID translation */
static Hash_table *group_map;
static uintmax_t
name_to_gid (char const *name)
{
struct group *gr = getgrnam (name);
return gr ? gr->gr_gid : UINTMAX_MAX;
}
void
group_map_read (char const *file)
{
map_read (&group_map, file, name_to_gid, "GID", TYPE_MAXIMUM (gid_t));
}
int
group_map_translate (gid_t gid, gid_t *new_gid, char const **new_name)
{
int rc = 1;
if (group_map)
{
struct mapentry ent, *res;
ent.orig_id = gid;
res = hash_lookup (group_map, &ent);
if (res)
{
*new_gid = res->new_id;
*new_name = res->new_name;
return 0;
}
}
if (group_option != (uid_t) -1)
{
*new_gid = group_option;
rc = 0;
}
if (group_name_option)
{
*new_name = group_name_option;
rc = 0;
}
return rc;
}

View File

@@ -1,7 +1,7 @@
/* Miscellaneous functions, not really specific to GNU tar.
Copyright 1988, 1992, 1994-1997, 1999-2001, 2003-2007, 2009-2010,
2012-2013 Free Software Foundation, Inc.
2012-2014, 2016 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
@@ -29,6 +29,10 @@
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
#endif
static void namebuf_add_dir (namebuf_t, char const *);
static char *namebuf_finish (namebuf_t);
static const char *tar_getcdpath (int);
/* Handling strings. */
@@ -230,7 +234,7 @@ zap_slashes (char *name)
/* Normalize FILE_NAME by removing redundant slashes and "."
components, including redundant trailing slashes.
Leave ".." alone, as it may be significant in the presence
Leave ".." alone, as it may be significant in the presence
of symlinks and on platforms where "/.." != "/".
Destructive version: modifies its argument. */
@@ -286,11 +290,14 @@ normalize_filename (int cdidx, const char *name)
this following approach may lead to situations where the same
file or directory is processed twice under different absolute
paths without that duplication being detected. Perhaps we
should use dev+ino pairs instead of names? */
should use dev+ino pairs instead of names? (See listed03.at for
a related test case.) */
const char *cdpath = tar_getcdpath (cdidx);
size_t copylen;
bool need_separator;
if (!cdpath)
call_arg_fatal ("getcwd", ".");
copylen = strlen (cdpath);
need_separator = ! (DOUBLE_SLASH_IS_DISTINCT_ROOT
&& copylen == 2 && ISSLASH (cdpath[1]));
@@ -581,7 +588,12 @@ safer_rmdir (const char *file_name)
return -1;
}
return unlinkat (chdir_fd, file_name, AT_REMOVEDIR);
if (unlinkat (chdir_fd, file_name, AT_REMOVEDIR) == 0)
{
remove_delayed_set_stat (file_name);
return 0;
}
return -1;
}
/* Remove FILE_NAME, returning 1 on success. If FILE_NAME is a directory,
@@ -645,7 +657,7 @@ remove_any_file (const char *file_name, enum remove_option option)
(entrylen = strlen (entry)) != 0;
entry += entrylen + 1)
{
char *file_name_buffer = new_name (file_name, entry);
char *file_name_buffer = make_file_name (file_name, entry);
int r = remove_any_file (file_name_buffer,
RECURSIVE_REMOVE_OPTION);
int e = errno;
@@ -834,10 +846,11 @@ struct wd
{
/* The directory's name. */
char const *name;
/* "absolute" path representing this directory; in the contrast to
/* "Absolute" path representing this directory; in the contrast to
the real absolute pathname, it can contain /../ components (see
normalize_filename_x for the reason of it). */
char *abspath;
normalize_filename_x for the reason of it). It is NULL if the
absolute path could not be determined. */
char *abspath;
/* If nonzero, the file descriptor of the directory, or AT_FDCWD if
the working directory. If zero, the directory needs to be opened
to be used. */
@@ -879,15 +892,13 @@ chdir_count (void)
int
chdir_arg (char const *dir)
{
char *absdir;
if (wd_count == wd_alloc)
{
if (wd_alloc == 0)
{
wd_alloc = 2;
wd = xmalloc (sizeof *wd * wd_alloc);
}
else
wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
wd_alloc = 2;
wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
if (! wd_count)
{
@@ -909,18 +920,22 @@ chdir_arg (char const *dir)
return wd_count - 1;
}
wd[wd_count].name = dir;
/* if the given name is an absolute path, then use that path
to represent this working directory; otherwise, construct
a path based on the previous -C option's absolute path */
if (IS_ABSOLUTE_FILE_NAME (wd[wd_count].name))
wd[wd_count].abspath = xstrdup (wd[wd_count].name);
else
/* If the given name is absolute, use it to represent this directory;
otherwise, construct a name based on the previous -C option. */
if (IS_ABSOLUTE_FILE_NAME (dir))
absdir = xstrdup (dir);
else if (wd[wd_count - 1].abspath)
{
namebuf_t nbuf = namebuf_create (wd[wd_count - 1].abspath);
namebuf_add_dir (nbuf, wd[wd_count].name);
wd[wd_count].abspath = namebuf_finish (nbuf);
namebuf_add_dir (nbuf, dir);
absdir = namebuf_finish (nbuf);
}
else
absdir = 0;
wd[wd_count].name = dir;
wd[wd_count].abspath = absdir;
wd[wd_count].fd = 0;
return wd_count++;
}
@@ -1007,7 +1022,7 @@ tar_dirname (void)
chdir_args() has never been called, so we simply return the
process's actual cwd. (Note that in this case IDX is ignored,
since it should always be 0.) */
const char *
static const char *
tar_getcdpath (int idx)
{
if (!wd)
@@ -1098,13 +1113,6 @@ file_removed_diag (const char *name, bool top_level,
diagfn (name);
}
void
write_fatal_details (char const *name, ssize_t status, size_t size)
{
write_error_details (name, status, size);
fatal_exit ();
}
/* Fork, aborting if unsuccessful. */
pid_t
xfork (void)
@@ -1189,7 +1197,7 @@ namebuf_name (namebuf_t buf, const char *name)
return buf->buffer;
}
void
static void
namebuf_add_dir (namebuf_t buf, const char *name)
{
static char dirsep[] = { DIRECTORY_SEPARATOR, 0 };
@@ -1202,11 +1210,11 @@ namebuf_add_dir (namebuf_t buf, const char *name)
buf->dir_length += strlen (name);
}
char *
static char *
namebuf_finish (namebuf_t buf)
{
char *res = buf->buffer;
if (ISSLASH (buf->buffer[buf->dir_length - 1]))
buf->buffer[buf->dir_length] = 0;
free (buf);
@@ -1232,7 +1240,7 @@ tar_savedir (const char *name, int must_exist)
open_error (name);
}
else if (! ((dir = fdopendir (fd))
&& (ret = streamsavedir (dir))))
&& (ret = streamsavedir (dir, savedir_sort_order))))
savedir_error (name);
if (dir ? closedir (dir) != 0 : 0 <= fd && close (fd) != 0)

View File

@@ -1,7 +1,7 @@
/* Various processing of names.
Copyright 1988, 1992, 1994, 1996-2001, 2003-2007, 2009, 2013 Free
Software Foundation, Inc.
Copyright 1988, 1992, 1994, 1996-2001, 2003-2007, 2009, 2013-2016
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
@@ -26,6 +26,401 @@
#include "common.h"
static void name_add_option (int option, const char *arg);
static void name_add_dir (const char *name);
static void name_add_file (const char *name);
enum
{
EXCLUDE_BACKUPS_OPTION = 256,
EXCLUDE_CACHES_OPTION,
EXCLUDE_CACHES_UNDER_OPTION,
EXCLUDE_CACHES_ALL_OPTION,
EXCLUDE_OPTION,
EXCLUDE_IGNORE_OPTION,
EXCLUDE_IGNORE_RECURSIVE_OPTION,
EXCLUDE_TAG_OPTION,
EXCLUDE_TAG_UNDER_OPTION,
EXCLUDE_TAG_ALL_OPTION,
EXCLUDE_VCS_OPTION,
EXCLUDE_VCS_IGNORES_OPTION,
IGNORE_CASE_OPTION,
NO_IGNORE_CASE_OPTION,
ANCHORED_OPTION,
NO_ANCHORED_OPTION,
RECURSION_OPTION,
NO_RECURSION_OPTION,
UNQUOTE_OPTION,
NO_UNQUOTE_OPTION,
NO_VERBATIM_FILES_FROM_OPTION,
NO_WILDCARDS_MATCH_SLASH_OPTION,
NO_WILDCARDS_OPTION,
NULL_OPTION,
NO_NULL_OPTION,
VERBATIM_FILES_FROM_OPTION,
WILDCARDS_MATCH_SLASH_OPTION,
WILDCARDS_OPTION
};
static struct argp_option names_options[] = {
#define GRID 100
{NULL, 0, NULL, 0,
N_("Local file name selection:"), GRID },
{"add-file", ARGP_KEY_ARG, N_("FILE"), 0,
N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 },
{"directory", 'C', N_("DIR"), 0,
N_("change to directory DIR"), GRID+1 },
{"files-from", 'T', N_("FILE"), 0,
N_("get names to extract or create from FILE"), GRID+1 },
{"null", NULL_OPTION, 0, 0,
N_("-T reads null-terminated names; implies --verbatim-files-from"),
GRID+1 },
{"no-null", NO_NULL_OPTION, 0, 0,
N_("disable the effect of the previous --null option"), GRID+1 },
{"unquote", UNQUOTE_OPTION, 0, 0,
N_("unquote input file or member names (default)"), GRID+1 },
{"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
N_("do not unquote input file or member names"), GRID+1 },
{"verbatim-files-from", VERBATIM_FILES_FROM_OPTION, 0, 0,
N_("-T reads file names verbatim (no option handling)"), GRID+1 },
{"no-verbatim-files-from", NO_VERBATIM_FILES_FROM_OPTION, 0, 0,
N_("-T treats file names starting with dash as options (default)"),
GRID+1 },
{"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0,
N_("exclude files, given as a PATTERN"), GRID+1 },
{"exclude-from", 'X', N_("FILE"), 0,
N_("exclude patterns listed in FILE"), GRID+1 },
{"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
N_("exclude contents of directories containing CACHEDIR.TAG, "
"except for the tag file itself"), GRID+1 },
{"exclude-caches-under", EXCLUDE_CACHES_UNDER_OPTION, 0, 0,
N_("exclude everything under directories containing CACHEDIR.TAG"),
GRID+1 },
{"exclude-caches-all", EXCLUDE_CACHES_ALL_OPTION, 0, 0,
N_("exclude directories containing CACHEDIR.TAG"), GRID+1 },
{"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
N_("exclude contents of directories containing FILE, except"
" for FILE itself"), GRID+1 },
{"exclude-ignore", EXCLUDE_IGNORE_OPTION, N_("FILE"), 0,
N_("read exclude patterns for each directory from FILE, if it exists"),
GRID+1 },
{"exclude-ignore-recursive", EXCLUDE_IGNORE_RECURSIVE_OPTION, N_("FILE"), 0,
N_("read exclude patterns for each directory and its subdirectories "
"from FILE, if it exists"), GRID+1 },
{"exclude-tag-under", EXCLUDE_TAG_UNDER_OPTION, N_("FILE"), 0,
N_("exclude everything under directories containing FILE"), GRID+1 },
{"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION, N_("FILE"), 0,
N_("exclude directories containing FILE"), GRID+1 },
{"exclude-vcs", EXCLUDE_VCS_OPTION, NULL, 0,
N_("exclude version control system directories"), GRID+1 },
{"exclude-vcs-ignores", EXCLUDE_VCS_IGNORES_OPTION, NULL, 0,
N_("read exclude patterns from the VCS ignore files"), GRID+1 },
{"exclude-backups", EXCLUDE_BACKUPS_OPTION, NULL, 0,
N_("exclude backup and lock files"), GRID+1 },
{"recursion", RECURSION_OPTION, 0, 0,
N_("recurse into directories (default)"), GRID+1 },
{"no-recursion", NO_RECURSION_OPTION, 0, 0,
N_("avoid descending automatically in directories"), GRID+1 },
#undef GRID
#define GRID 120
{NULL, 0, NULL, 0,
N_("File name matching options (affect both exclude and include patterns):"),
GRID },
{"anchored", ANCHORED_OPTION, 0, 0,
N_("patterns match file name start"), GRID+1 },
{"no-anchored", NO_ANCHORED_OPTION, 0, 0,
N_("patterns match after any '/' (default for exclusion)"), GRID+1 },
{"ignore-case", IGNORE_CASE_OPTION, 0, 0,
N_("ignore case"), GRID+1 },
{"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0,
N_("case sensitive matching (default)"), GRID+1 },
{"wildcards", WILDCARDS_OPTION, 0, 0,
N_("use wildcards (default for exclusion)"), GRID+1 },
{"no-wildcards", NO_WILDCARDS_OPTION, 0, 0,
N_("verbatim string matching"), GRID+1 },
{"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
N_("wildcards match '/' (default for exclusion)"), GRID+1 },
{"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
N_("wildcards do not match '/'"), GRID+1 },
#undef GRID
{NULL}
};
static bool
is_file_selection_option (int key)
{
struct argp_option *p;
for (p = names_options;
!(p->name == NULL && p->key == 0 && p->doc == NULL); p++)
if (p->key == key)
return true;
return false;
}
/* Either NL or NUL, as decided by the --null option. */
static char filename_terminator = '\n';
/* Treat file names read from -T input verbatim */
static bool verbatim_files_from_option;
static error_t
names_parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case 'C':
name_add_dir (arg);
break;
case 'T':
name_add_file (arg);
/* Indicate we've been given -T option. This is for backward
compatibility only, so that `tar cfT archive /dev/null will
succeed */
files_from_option = true;
break;
default:
if (is_file_selection_option (key))
name_add_option (key, arg);
else
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Wildcard matching settings */
enum wildcards
{
default_wildcards, /* For exclusion == enable_wildcards,
for inclusion == disable_wildcards */
disable_wildcards,
enable_wildcards
};
static enum wildcards wildcards = default_wildcards;
/* Wildcard settings (--wildcards/--no-wildcards) */
static int matching_flags = 0;
/* exclude_fnmatch options */
static int include_anchored = EXCLUDE_ANCHORED;
/* Pattern anchoring options used for file inclusion */
#define EXCLUDE_OPTIONS \
(((wildcards != disable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
| matching_flags \
| recursion_option)
#define INCLUDE_OPTIONS \
(((wildcards == enable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
| include_anchored \
| matching_flags \
| recursion_option)
static char const * const vcs_file_table[] = {
/* CVS: */
"CVS",
".cvsignore",
/* RCS: */
"RCS",
/* SCCS: */
"SCCS",
/* SVN: */
".svn",
/* git: */
".git",
".gitignore",
".gitattributes",
".gitmodules",
/* Arch: */
".arch-ids",
"{arch}",
"=RELEASE-ID",
"=meta-update",
"=update",
/* Bazaar */
".bzr",
".bzrignore",
".bzrtags",
/* Mercurial */
".hg",
".hgignore",
".hgtags",
/* darcs */
"_darcs",
NULL
};
static char const * const backup_file_table[] = {
".#*",
"*~",
"#*#",
NULL
};
static void
add_exclude_array (char const * const * fv, int opts)
{
int i;
for (i = 0; fv[i]; i++)
add_exclude (excluded, fv[i], opts);
}
static void
handle_file_selection_option (int key, const char *arg)
{
switch (key)
{
case EXCLUDE_BACKUPS_OPTION:
add_exclude_array (backup_file_table, EXCLUDE_WILDCARDS);
break;
case EXCLUDE_OPTION:
add_exclude (excluded, arg, EXCLUDE_OPTIONS);
break;
case EXCLUDE_CACHES_OPTION:
add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents,
cachedir_file_p);
break;
case EXCLUDE_CACHES_UNDER_OPTION:
add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under,
cachedir_file_p);
break;
case EXCLUDE_CACHES_ALL_OPTION:
add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all,
cachedir_file_p);
break;
case EXCLUDE_IGNORE_OPTION:
excfile_add (arg, EXCL_NON_RECURSIVE);
break;
case EXCLUDE_IGNORE_RECURSIVE_OPTION:
excfile_add (arg, EXCL_RECURSIVE);
break;
case EXCLUDE_TAG_OPTION:
add_exclusion_tag (arg, exclusion_tag_contents, NULL);
break;
case EXCLUDE_TAG_UNDER_OPTION:
add_exclusion_tag (arg, exclusion_tag_under, NULL);
break;
case EXCLUDE_TAG_ALL_OPTION:
add_exclusion_tag (arg, exclusion_tag_all, NULL);
break;
case EXCLUDE_VCS_OPTION:
add_exclude_array (vcs_file_table, 0);
break;
case EXCLUDE_VCS_IGNORES_OPTION:
exclude_vcs_ignores ();
break;
case RECURSION_OPTION:
recursion_option = FNM_LEADING_DIR;
break;
case NO_RECURSION_OPTION:
recursion_option = 0;
break;
case UNQUOTE_OPTION:
unquote_option = true;
break;
case NO_UNQUOTE_OPTION:
unquote_option = false;
break;
case NULL_OPTION:
filename_terminator = '\0';
verbatim_files_from_option = true;
break;
case NO_NULL_OPTION:
filename_terminator = '\n';
verbatim_files_from_option = false;
break;
case 'X':
if (add_exclude_file (add_exclude, excluded, arg, EXCLUDE_OPTIONS, '\n')
!= 0)
{
int e = errno;
FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
}
break;
case ANCHORED_OPTION:
matching_flags |= EXCLUDE_ANCHORED;
break;
case NO_ANCHORED_OPTION:
include_anchored = 0; /* Clear the default for comman line args */
matching_flags &= ~ EXCLUDE_ANCHORED;
break;
case IGNORE_CASE_OPTION:
matching_flags |= FNM_CASEFOLD;
break;
case NO_IGNORE_CASE_OPTION:
matching_flags &= ~ FNM_CASEFOLD;
break;
case WILDCARDS_OPTION:
wildcards = enable_wildcards;
break;
case NO_WILDCARDS_OPTION:
wildcards = disable_wildcards;
break;
case WILDCARDS_MATCH_SLASH_OPTION:
matching_flags &= ~ FNM_FILE_NAME;
break;
case NO_WILDCARDS_MATCH_SLASH_OPTION:
matching_flags |= FNM_FILE_NAME;
break;
case VERBATIM_FILES_FROM_OPTION:
verbatim_files_from_option = true;
break;
case NO_VERBATIM_FILES_FROM_OPTION:
verbatim_files_from_option = false;
break;
default:
FATAL_ERROR ((0, 0, "unhandled positional option %d", key));
}
}
static struct argp names_argp = {
names_options,
names_parse_opt,
NULL,
NULL,
NULL,
NULL,
NULL
};
struct argp_child names_argp_children[] = {
{ &names_argp, 0, "", 0 },
{ NULL }
};
/* User and group names. */
/* Make sure you link with the proper libraries if you are running the
@@ -210,26 +605,36 @@ static struct name *nametail; /* end of name list */
/* A name_list element contains entries of three types: */
#define NELT_NAME 0 /* File name */
#define NELT_CHDIR 1 /* Change directory request */
#define NELT_FMASK 2 /* Change fnmatch options request */
#define NELT_FILE 3 /* Read file names from that file */
#define NELT_NOOP 4 /* No operation */
enum nelt_type
{
NELT_NAME, /* File name */
NELT_CHDIR, /* Change directory request */
NELT_FILE, /* Read file names from that file */
NELT_NOOP, /* No operation */
NELT_OPTION /* Filename-selection option */
};
struct name_elt /* A name_array element. */
{
struct name_elt *next, *prev;
char type; /* Element type, see NELT_* constants above */
enum nelt_type type; /* Element type, see NELT_* constants above */
union
{
const char *name; /* File or directory name */
int matching_flags;/* fnmatch options if type == NELT_FMASK */
struct /* File, if type == NELT_FILE */
{
const char *name;/* File name */
size_t line; /* Input line number */
int term; /* File name terminator in the list */
bool verbatim; /* Verbatim handling of file names: no white-space
trimming, no option processing */
FILE *fp;
} file;
struct
{
int option;
char const *arg;
} opt; /* NELT_OPTION */
} v;
};
@@ -276,27 +681,29 @@ name_list_advance (void)
free (elt);
}
/* Add to name_array the file NAME with fnmatch options MATCHING_FLAGS */
/* Add to name_array the file NAME with fnmatch options MATFLAGS */
void
name_add_name (const char *name, int matching_flags)
name_add_name (const char *name)
{
static int prev_flags = 0; /* FIXME: Or EXCLUDE_ANCHORED? */
struct name_elt *ep = name_elt_alloc ();
if (prev_flags != matching_flags)
{
ep->type = NELT_FMASK;
ep->v.matching_flags = matching_flags;
prev_flags = matching_flags;
ep = name_elt_alloc ();
}
ep->type = NELT_NAME;
ep->v.name = name;
name_count++;
}
static void
name_add_option (int option, const char *arg)
{
struct name_elt *elt = name_elt_alloc ();
elt->type = NELT_OPTION;
elt->v.opt.option = option;
elt->v.opt.arg = arg;
}
/* Add to name_array a chdir request for the directory NAME */
void
static void
name_add_dir (const char *name)
{
struct name_elt *ep = name_elt_alloc ();
@@ -304,13 +711,14 @@ name_add_dir (const char *name)
ep->v.name = name;
}
void
name_add_file (const char *name, int term)
static void
name_add_file (const char *name)
{
struct name_elt *ep = name_elt_alloc ();
ep->type = NELT_FILE;
ep->v.file.name = name;
ep->v.file.term = term;
ep->v.file.line = 0;
ep->v.file.fp = NULL;
}
@@ -389,6 +797,15 @@ add_file_id (const char *filename)
file_id_list = p;
return 0;
}
/* Chop trailing slashes. */
static void
chopslash (char *str)
{
char *p = str + strlen (str) - 1;
while (p > str && ISSLASH (*p))
*p-- = '\0';
}
enum read_file_list_state /* Result of reading file name from the list file */
{
@@ -409,6 +826,7 @@ read_name_from_file (struct name_elt *ent)
FILE *fp = ent->v.file.fp;
int term = ent->v.file.term;
++ent->v.file.line;
for (c = getc (fp); c != EOF && c != term; c = getc (fp))
{
if (counter == name_buffer_length)
@@ -428,18 +846,19 @@ read_name_from_file (struct name_elt *ent)
if (counter == name_buffer_length)
name_buffer = x2realloc (name_buffer, &name_buffer_length);
name_buffer[counter] = 0;
chopslash (name_buffer);
return (counter == 0 && c == EOF) ? file_list_end : file_list_success;
}
static int
handle_option (const char *str)
handle_option (const char *str, struct name_elt const *ent)
{
struct wordsplit ws;
int i;
struct option_locus loc;
while (*str && isspace (*str))
;
++str;
if (*str != '-')
return 1;
@@ -447,8 +866,11 @@ handle_option (const char *str)
if (wordsplit (str, &ws, WRDSF_DEFFLAGS|WRDSF_DOOFFS))
FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
str, wordsplit_strerror (&ws)));
ws.ws_wordv[0] = program_invocation_short_name;
more_options (ws.ws_wordc+ws.ws_offs, ws.ws_wordv);
ws.ws_wordv[0] = (char *) program_name;
loc.source = OPTS_FILE;
loc.name = ent->v.file.name;
loc.line = ent->v.file.line;
more_options (ws.ws_wordc+ws.ws_offs, ws.ws_wordv, &loc);
for (i = 0; i < ws.ws_wordc+ws.ws_offs; i++)
ws.ws_wordv[i] = NULL;
@@ -476,6 +898,8 @@ read_next_name (struct name_elt *ent, struct name_elt *ret)
if ((ent->v.file.fp = fopen (ent->v.file.name, "r")) == NULL)
open_fatal (ent->v.file.name);
}
ent->v.file.term = filename_terminator;
ent->v.file.verbatim = verbatim_files_from_option;
}
while (1)
@@ -492,7 +916,9 @@ read_next_name (struct name_elt *ent, struct name_elt *ret)
ent->v.file.term = 0;
/* fall through */
case file_list_success:
if (handle_option (name_buffer) == 0)
if (unquote_option)
unquote_string (name_buffer);
if (!ent->v.file.verbatim && handle_option (name_buffer, ent) == 0)
{
name_list_adjust ();
return 1;
@@ -516,7 +942,6 @@ copy_name (struct name_elt *ep)
{
const char *source;
size_t source_len;
char *cursor;
source = ep->v.name;
source_len = strlen (source);
@@ -534,24 +959,17 @@ copy_name (struct name_elt *ep)
name_buffer = xmalloc(name_buffer_length + 2);
}
strcpy (name_buffer, source);
/* Zap trailing slashes. */
cursor = name_buffer + strlen (name_buffer) - 1;
while (cursor > name_buffer && ISSLASH (*cursor))
*cursor-- = '\0';
chopslash (name_buffer);
}
static int matching_flags; /* exclude_fnmatch options */
/* Get the next NELT_NAME element from name_array. Result is in
static storage and can't be relied upon across two calls.
If CHANGE_DIRS is true, treat any entries of type NELT_CHDIR as
the request to change to the given directory.
Entries of type NELT_FMASK cause updates of the matching_flags
value. */
*/
static struct name_elt *
name_next_elt (int change_dirs)
{
@@ -566,11 +984,6 @@ name_next_elt (int change_dirs)
name_list_advance ();
break;
case NELT_FMASK:
matching_flags = ep->v.matching_flags;
name_list_advance ();
continue;
case NELT_FILE:
if (read_next_name (ep, &entry) == 0)
return &entry;
@@ -592,6 +1005,11 @@ name_next_elt (int change_dirs)
entry.v.name = name_buffer;
name_list_advance ();
return &entry;
case NELT_OPTION:
handle_file_selection_option (ep->v.opt.option, ep->v.opt.arg);
name_list_advance ();
continue;
}
}
@@ -637,7 +1055,7 @@ name_gather (void)
buffer->change_dir = change_dir;
buffer->next = 0;
buffer->found_count = 0;
buffer->matching_flags = matching_flags;
buffer->matching_flags = INCLUDE_OPTIONS;
buffer->directory = NULL;
buffer->parent = NULL;
buffer->cmdline = true;
@@ -679,7 +1097,7 @@ addname (char const *string, int change_dir, bool cmdline, struct name *parent)
name->prev = nametail;
name->next = NULL;
name->found_count = 0;
name->matching_flags = matching_flags;
name->matching_flags = INCLUDE_OPTIONS;
name->change_dir = change_dir;
name->directory = NULL;
name->parent = parent;
@@ -814,7 +1232,10 @@ regex_usage_warning (const char *name)
{
static int warned_once = 0;
if (warn_regex_usage && fnmatch_pattern_has_wildcards (name, 0))
/* Warn about implicit use of the wildcards in command line arguments.
(Default for tar prior to 1.15.91, but changed afterwards) */
if (wildcards == default_wildcards
&& fnmatch_pattern_has_wildcards (name, 0))
{
warned_once = 1;
WARN ((0, 0,
@@ -1355,27 +1776,21 @@ blank_name_list (void)
name->found_count = 0;
}
/* Yield a newly allocated file name consisting of FILE_NAME concatenated to
NAME, with an intervening slash if FILE_NAME does not already end in one. */
/* Yield a newly allocated file name consisting of DIR_NAME concatenated to
NAME, with an intervening slash if DIR_NAME does not already end in one. */
char *
new_name (const char *file_name, const char *name)
make_file_name (const char *directory_name, const char *name)
{
size_t file_name_len = strlen (file_name);
size_t namesize = strlen (name) + 1;
int slash = file_name_len && ! ISSLASH (file_name[file_name_len - 1]);
char *buffer = xmalloc (file_name_len + slash + namesize);
memcpy (buffer, file_name, file_name_len);
buffer[file_name_len] = '/';
memcpy (buffer + file_name_len + slash, name, namesize);
size_t dirlen = strlen (directory_name);
size_t namelen = strlen (name) + 1;
int slash = dirlen && ! ISSLASH (directory_name[dirlen - 1]);
char *buffer = xmalloc (dirlen + slash + namelen);
memcpy (buffer, directory_name, dirlen);
buffer[dirlen] = '/';
memcpy (buffer + dirlen + slash, name, namelen);
return buffer;
}
/* Return nonzero if file NAME is excluded. */
bool
excluded_name (char const *name)
{
return excluded_file_name (excluded, name + FILE_SYSTEM_PREFIX_LEN (name));
}
/* Return the size of the prefix of FILE_NAME that is removed after

View File

@@ -1,6 +1,6 @@
/* Functions for dealing with sparse files
Copyright 2003-2007, 2010, 2013 Free Software Foundation, Inc.
Copyright 2003-2007, 2010, 2013-2016 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
@@ -208,9 +208,9 @@ sparse_add_map (struct tar_stat_info *st, struct sp_array const *sp)
st->sparse_map_avail = avail + 1;
}
/* Scan the sparse file and create its map */
/* Scan the sparse file byte-by-byte and create its map. */
static bool
sparse_scan_file (struct tar_sparse_file *file)
sparse_scan_file_raw (struct tar_sparse_file *file)
{
struct tar_stat_info *st = file->stat_info;
int fd = file->fd;
@@ -221,41 +221,38 @@ sparse_scan_file (struct tar_sparse_file *file)
st->archive_file_size = 0;
if (ST_NBLOCKS (st->stat) == 0)
offset = st->stat.st_size;
else
if (!tar_sparse_scan (file, scan_begin, NULL))
return false;
while ((count = blocking_read (fd, buffer, sizeof buffer)) != 0
&& count != SAFE_READ_ERROR)
{
if (!tar_sparse_scan (file, scan_begin, NULL))
return false;
/* Analyze the block. */
if (zero_block_p (buffer, count))
{
if (sp.numbytes)
{
sparse_add_map (st, &sp);
sp.numbytes = 0;
if (!tar_sparse_scan (file, scan_block, NULL))
return false;
}
}
else
{
if (sp.numbytes == 0)
sp.offset = offset;
sp.numbytes += count;
st->archive_file_size += count;
if (!tar_sparse_scan (file, scan_block, buffer))
return false;
}
while ((count = blocking_read (fd, buffer, sizeof buffer)) != 0
&& count != SAFE_READ_ERROR)
{
/* Analyze the block. */
if (zero_block_p (buffer, count))
{
if (sp.numbytes)
{
sparse_add_map (st, &sp);
sp.numbytes = 0;
if (!tar_sparse_scan (file, scan_block, NULL))
return false;
}
}
else
{
if (sp.numbytes == 0)
sp.offset = offset;
sp.numbytes += count;
st->archive_file_size += count;
if (!tar_sparse_scan (file, scan_block, buffer))
return false;
}
offset += count;
}
offset += count;
}
/* save one more sparse segment of length 0 to indicate that
the file ends with a hole */
if (sp.numbytes == 0)
sp.offset = offset;
@@ -264,6 +261,114 @@ sparse_scan_file (struct tar_sparse_file *file)
return tar_sparse_scan (file, scan_end, NULL);
}
static bool
sparse_scan_file_wholesparse (struct tar_sparse_file *file)
{
struct tar_stat_info *st = file->stat_info;
struct sp_array sp = {0, 0};
/* Note that this function is called only for truly sparse files of size >= 1
block size (checked via ST_IS_SPARSE before). See the thread
http://www.mail-archive.com/bug-tar@gnu.org/msg04209.html for more info */
if (ST_NBLOCKS (st->stat) == 0)
{
st->archive_file_size = 0;
sp.offset = st->stat.st_size;
sparse_add_map (st, &sp);
return true;
}
return false;
}
#ifdef SEEK_HOLE
/* Try to engage SEEK_HOLE/SEEK_DATA feature. */
static bool
sparse_scan_file_seek (struct tar_sparse_file *file)
{
struct tar_stat_info *st = file->stat_info;
int fd = file->fd;
struct sp_array sp = {0, 0};
off_t offset = 0;
off_t data_offset;
off_t hole_offset;
st->archive_file_size = 0;
for (;;)
{
/* locate first chunk of data */
data_offset = lseek (fd, offset, SEEK_DATA);
if (data_offset == (off_t)-1)
/* ENXIO == EOF; error otherwise */
{
if (errno == ENXIO)
{
/* file ends with hole, add one more empty chunk of data */
sp.numbytes = 0;
sp.offset = st->stat.st_size;
sparse_add_map (st, &sp);
return true;
}
return false;
}
hole_offset = lseek (fd, data_offset, SEEK_HOLE);
/* according to specs, if FS does not fully support
SEEK_DATA/SEEK_HOLE it may just implement kind of "wrapper" around
classic lseek() call. We must detect it here and try to use other
hole-detection methods. */
if (offset == 0 /* first loop */
&& data_offset == 0
&& hole_offset == st->stat.st_size)
{
lseek (fd, 0, SEEK_SET);
return false;
}
sp.offset = data_offset;
sp.numbytes = hole_offset - data_offset;
sparse_add_map (st, &sp);
st->archive_file_size += sp.numbytes;
offset = hole_offset;
}
return true;
}
#endif
static bool
sparse_scan_file (struct tar_sparse_file *file)
{
/* always check for completely sparse files */
if (sparse_scan_file_wholesparse (file))
return true;
switch (hole_detection)
{
case HOLE_DETECTION_DEFAULT:
case HOLE_DETECTION_SEEK:
#ifdef SEEK_HOLE
if (sparse_scan_file_seek (file))
return true;
#else
if (hole_detection == HOLE_DETECTION_SEEK)
WARN((0, 0,
_("\"seek\" hole detection is not supported, using \"raw\".")));
/* fall back to "raw" for this and all other files */
hole_detection = HOLE_DETECTION_RAW;
#endif
case HOLE_DETECTION_RAW:
if (sparse_scan_file_raw (file))
return true;
}
return false;
}
static struct tar_sparse_optab const oldgnu_optab;
static struct tar_sparse_optab const star_optab;
static struct tar_sparse_optab const pax_optab;
@@ -809,6 +914,7 @@ star_get_sparse_info (struct tar_sparse_file *file)
set_next_block_after (h);
for (i = 0; i < SPARSES_IN_STAR_EXT_HEADER && rc == add_ok; i++)
rc = oldgnu_add_sparse (file, &h->star_ext_header.sp[i]);
file->dumped_size += BLOCKSIZE;
}
if (rc == add_fail)

View File

@@ -1,5 +1,5 @@
/* This file is part of GNU tar.
Copyright 2007, 2009, 2013 Free Software Foundation, Inc.
Copyright 2007, 2009, 2013-2014, 2016 Free Software Foundation, Inc.
Written by Sergey Poznyakoff.
@@ -29,6 +29,7 @@ struct compression_suffix
static struct compression_suffix compression_suffixes[] = {
#define __CAT2__(a,b) a ## b
#define S(s,p) #s, sizeof (#s) - 1, __CAT2__(p,_PROGRAM)
{ "tar", 3, NULL },
{ S(gz, GZIP) },
{ S(tgz, GZIP) },
{ S(taz, GZIP) },
@@ -44,33 +45,43 @@ static struct compression_suffix compression_suffixes[] = {
{ S(lzo, LZOP) },
{ S(xz, XZ) },
{ S(txz, XZ) }, /* Slackware */
{ NULL }
#undef S
#undef __CAT2__
};
static int nsuffixes = sizeof (compression_suffixes) /
sizeof (compression_suffixes[0]);
static const char *
find_compression_program (const char *name, const char *defprog)
static struct compression_suffix const *
find_compression_suffix (const char *name, size_t *ret_len)
{
char *suf = strrchr (name, '.');
if (suf)
{
int i;
size_t len;
struct compression_suffix *p;
suf++;
len = strlen (suf);
for (i = 0; i < nsuffixes; i++)
for (p = compression_suffixes; p->suffix; p++)
{
if (compression_suffixes[i].length == len
&& memcmp (compression_suffixes[i].suffix, suf, len) == 0)
return compression_suffixes[i].program;
if (p->length == len && memcmp (p->suffix, suf, len) == 0)
{
if (ret_len)
*ret_len = strlen (name) - len - 1;
return p;
}
}
}
return NULL;
}
static const char *
find_compression_program (const char *name, const char *defprog)
{
struct compression_suffix const *p = find_compression_suffix (name, NULL);
if (p)
return p->program;
return defprog;
}
@@ -81,3 +92,23 @@ set_compression_program_by_suffix (const char *name, const char *defprog)
if (program)
use_compress_program_option = program;
}
char *
strip_compression_suffix (const char *name)
{
char *s = NULL;
size_t len;
if (find_compression_suffix (name, &len))
{
if (strncmp (name + len - 4, ".tar", 4) == 0)
len -= 4;
if (len == 0)
return NULL;
s = xmalloc (len + 1);
memcpy (s, name, len);
s[len] = 0;
}
return s;
}

View File

@@ -1,6 +1,7 @@
/* System-dependent calls for tar.
Copyright 2003-2008, 2010, 2013 Free Software Foundation, Inc.
Copyright 2003-2008, 2010, 2013-2014, 2016 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
@@ -26,13 +27,14 @@
static _Noreturn void
xexec (const char *cmd)
{
struct wordsplit ws;
char *argv[4];
ws.ws_env = (const char **) environ;
if (wordsplit (cmd, &ws, (WRDSF_DEFFLAGS | WRDSF_ENV) & ~WRDSF_NOVAR))
FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
cmd, wordsplit_strerror (&ws)));
execvp (ws.ws_wordv[0], ws.ws_wordv);
argv[0] = (char *) "/bin/sh";
argv[1] = (char *) "-c";
argv[2] = (char *) cmd;
argv[3] = NULL;
execv ("/bin/sh", argv);
exec_fatal (cmd);
}
@@ -330,6 +332,7 @@ sys_child_open_for_compress (void)
pid_t grandchild_pid;
pid_t child_pid;
signal (SIGPIPE, SIG_IGN);
xpipe (parent_pipe);
child_pid = xfork ();
@@ -720,7 +723,7 @@ stat_to_env (char *name, char type, struct tar_stat_info *st)
}
static pid_t global_pid;
static RETSIGTYPE (*pipe_handler) (int sig);
static void (*pipe_handler) (int sig);
int
sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
@@ -788,7 +791,7 @@ sys_exec_info_script (const char **archive_name, int volume_number)
pid_t pid;
char uintbuf[UINTMAX_STRSIZE_BOUND];
int p[2];
static RETSIGTYPE (*saved_handler) (int sig);
static void (*saved_handler) (int sig);
xpipe (p);
saved_handler = signal (SIGPIPE, SIG_IGN);

795
src/tar.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* GNU tar Archive Format description.
Copyright 1988-1989, 1991-1997, 2000-2001, 2003-2007, 2012-2013
Copyright 1988-1989, 1991-1997, 2000-2001, 2003-2007, 2012-2014, 2016
Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -327,6 +327,10 @@ struct tar_stat_info
size_t sparse_map_size; /* Size of the sparse map */
struct sp_array *sparse_map;
off_t real_size; /* The real size of sparse file */
int real_size_set; /* True when GNU.sparse.realsize is set in
archived file */
size_t xattr_map_size; /* Size of the xattr map */
struct xattr_array *xattr_map;
@@ -358,6 +362,9 @@ struct tar_stat_info
It is negative if it could not be reopened after it was closed.
Negate it to find out what errno was when the reopen failed. */
int fd;
/* Exclusion list */
struct exclist *exclude_list;
};
union block

View File

@@ -1,5 +1,5 @@
/* This file is part of GNU tar.
Copyright 2006-2008, 2013 Free Software Foundation, Inc.
Copyright 2006-2008, 2013-2014, 2016 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
@@ -378,13 +378,15 @@ parse_transform_expr (const char *expr)
break;
default:
/* Try to be nice */
{
char buf[2];
buf[0] = '\\';
buf[1] = *cur;
add_literal_segment (tf, buf, buf + 2);
}
if (*cur == delim)
add_char_segment (tf, delim);
else
{
char buf[2];
buf[0] = '\\';
buf[1] = *cur;
add_literal_segment (tf, buf, buf + 2);
}
cur++;
break;
}

View File

@@ -1,6 +1,6 @@
/* Unlink files.
Copyright 2009, 2013 Free Software Foundation, Inc.
Copyright 2009, 2013-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -32,6 +32,10 @@ struct deferred_unlink
entry got added to the queue */
};
#define IS_CWD(p) \
((p)->is_dir \
&& ((p)->file_name[0] == 0 || strcmp ((p)->file_name, ".") == 0))
/* The unlink queue */
static struct deferred_unlink *dunlink_head, *dunlink_tail;
@@ -60,6 +64,24 @@ dunlink_alloc (void)
return p;
}
static void
dunlink_insert (struct deferred_unlink *anchor, struct deferred_unlink *p)
{
if (anchor)
{
p->next = anchor->next;
anchor->next = p;
}
else
{
p->next = dunlink_head;
dunlink_head = p;
}
if (!p->next)
dunlink_tail = p;
dunlink_count++;
}
static void
dunlink_reclaim (struct deferred_unlink *p)
{
@@ -86,15 +108,15 @@ flush_deferred_unlinks (bool force)
{
const char *fname;
if (p->file_name[0] == 0 ||
strcmp (p->file_name, ".") == 0)
if (p->dir_idx && IS_CWD (p))
{
fname = tar_dirname ();
chdir_do (p->dir_idx - 1);
prev = p;
p = next;
continue;
}
else
fname = p->file_name;
if (unlinkat (chdir_fd, fname, AT_REMOVEDIR) != 0)
{
switch (errno)
@@ -102,16 +124,16 @@ flush_deferred_unlinks (bool force)
case ENOENT:
/* nothing to worry about */
break;
case EEXIST:
/* OpenSolaris >=10 sets EEXIST instead of ENOTEMPTY
if trying to remove a non-empty directory */
case ENOTEMPTY:
if (!force)
{
/* Keep the record in list, in the hope we'll
be able to remove it later */
prev = p;
p = next;
continue;
}
/* fall through */
/* Keep the record in list, in the hope we'll
be able to remove it later */
prev = p;
p = next;
continue;
default:
rmdir_error (fname);
}
@@ -138,6 +160,34 @@ flush_deferred_unlinks (bool force)
}
if (!dunlink_head)
dunlink_tail = NULL;
else if (force)
{
for (p = dunlink_head; p; )
{
struct deferred_unlink *next = p->next;
const char *fname;
chdir_do (p->dir_idx);
if (p->dir_idx && IS_CWD (p))
{
fname = tar_dirname ();
chdir_do (p->dir_idx - 1);
}
else
fname = p->file_name;
if (unlinkat (chdir_fd, fname, AT_REMOVEDIR) != 0)
{
if (errno != ENOENT)
rmdir_error (fname);
}
dunlink_reclaim (p);
dunlink_count--;
p = next;
}
dunlink_head = dunlink_tail = NULL;
}
chdir_do (saved_chdir);
}
@@ -145,6 +195,7 @@ void
finish_deferred_unlinks (void)
{
flush_deferred_unlinks (true);
while (dunlink_avail)
{
struct deferred_unlink *next = dunlink_avail->next;
@@ -170,10 +221,17 @@ queue_deferred_unlink (const char *name, bool is_dir)
p->is_dir = is_dir;
p->records_written = records_written;
if (dunlink_tail)
dunlink_tail->next = p;
if (IS_CWD (p))
{
struct deferred_unlink *q, *prev;
for (q = dunlink_head, prev = NULL; q; prev = q, q = q->next)
if (IS_CWD (q) && q->dir_idx < p->dir_idx)
break;
if (q)
dunlink_insert (prev, p);
else
dunlink_insert (dunlink_tail, p);
}
else
dunlink_head = p;
dunlink_tail = p;
dunlink_count++;
dunlink_insert (dunlink_tail, p);
}

View File

@@ -1,7 +1,7 @@
/* Update a tar archive.
Copyright 1988, 1992, 1994, 1996-1997, 1999-2001, 2003-2005, 2007, 2010,
2013 Free Software Foundation, Inc.
Copyright 1988, 1992, 1994, 1996-1997, 1999-2001, 2003-2005, 2007,
2010, 2013-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -216,7 +216,7 @@ update_archive (void)
while ((p = name_from_list ()) != NULL)
{
char *file_name = p->name;
if (excluded_name (file_name))
if (excluded_name (file_name, NULL))
continue;
if (interactive_option && !confirm ("add", file_name))
continue;

View File

@@ -1,6 +1,7 @@
/* Charset handling for GNU tar.
Copyright 2004, 2006-2007, 2013 Free Software Foundation, Inc.
Copyright 2004, 2006-2007, 2013-2014, 2016 Free Software Foundation,
Inc.
This file is part of GNU tar.

View File

@@ -1,6 +1,6 @@
/* Warnings for GNU tar.
Copyright 2009, 2012-2013 Free Software Foundation, Inc.
Copyright 2009, 2012-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -1,6 +1,6 @@
/* Support for extended attributes.
Copyright (C) 2006-2013 Free Software Foundation, Inc.
Copyright (C) 2006-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -61,6 +61,7 @@ static struct
static acl_t acl_get_file_at (int, const char *, acl_type_t);
static int acl_set_file_at (int, const char *, acl_type_t, acl_t);
static int file_has_acl_at (int, char const *, struct stat const *);
static int acl_delete_def_file_at (int, char const *);
/* acl_get_file_at */
#define AT_FUNC_NAME acl_get_file_at
@@ -88,6 +89,17 @@ static int file_has_acl_at (int, char const *, struct stat const *);
#undef AT_FUNC_POST_FILE_PARAM_DECLS
#undef AT_FUNC_POST_FILE_ARGS
/* acl_delete_def_file_at */
#define AT_FUNC_NAME acl_delete_def_file_at
#define AT_FUNC_F1 acl_delete_def_file
#define AT_FUNC_POST_FILE_PARAM_DECLS
#define AT_FUNC_POST_FILE_ARGS
#include "at-func.c"
#undef AT_FUNC_NAME
#undef AT_FUNC_F1
#undef AT_FUNC_POST_FILE_PARAM_DECLS
#undef AT_FUNC_POST_FILE_ARGS
/* gnulib file_has_acl_at */
#define AT_FUNC_NAME file_has_acl_at
#define AT_FUNC_F1 file_has_acl
@@ -187,7 +199,8 @@ fixup_extra_acl_fields (char *ptr)
return ptr;
}
/* "system.posix_acl_access" */
/* Set the "system.posix_acl_access/system.posix_acl_default" extended
attribute. Called only when acls_option > 0. */
static void
xattrs__acls_set (struct tar_stat_info const *st,
char const *file_name, int type,
@@ -199,15 +212,23 @@ xattrs__acls_set (struct tar_stat_info const *st,
{
/* assert (strlen (ptr) == len); */
ptr = fixup_extra_acl_fields (ptr);
acl = acl_from_text (ptr);
acls_option = 1;
}
else if (acls_option > 0)
acl = perms2acl (st->stat.st_mode);
else if (def)
{
/* No "default" IEEE 1003.1e ACL set for directory. At this moment,
FILE_NAME may already have inherited default acls from parent
directory; clean them up. */
if (acl_delete_def_file_at (chdir_fd, file_name))
WARNOPT (WARN_XATTR_WRITE,
(0, errno,
_("acl_delete_def_file_at: Cannot drop default POSIX ACLs "
"for file '%s'"),
file_name));
return;
}
else
return; /* don't call acl functions unless we first hit an ACL, or
--acls was passed explicitly */
acl = perms2acl (st->stat.st_mode);
if (!acl)
{
@@ -695,7 +716,7 @@ xattrs_print_char (struct tar_stat_info const *st, char *output)
if (selinux_context_option > 0 && st->cntx_name)
*output = '.';
if (acls_option && (st->acls_a_len || st->acls_d_len))
if (acls_option > 0 && (st->acls_a_len || st->acls_d_len))
*output = '+';
}
@@ -706,11 +727,11 @@ xattrs_print (struct tar_stat_info const *st)
return;
/* selinux */
if (selinux_context_option && st->cntx_name)
if (selinux_context_option > 0 && st->cntx_name)
fprintf (stdlis, " s: %s\n", st->cntx_name);
/* acls */
if (acls_option && (st->acls_a_len || st->acls_d_len))
if (acls_option > 0 && (st->acls_a_len || st->acls_d_len))
{
fprintf (stdlis, " a: ");
acls_one_line ("", ',', st->acls_a_ptr, st->acls_a_len);
@@ -719,7 +740,7 @@ xattrs_print (struct tar_stat_info const *st)
}
/* xattrs */
if (xattrs_option && st->xattr_map_size)
if (xattrs_option > 0 && st->xattr_map_size)
{
int i;

View File

@@ -1,6 +1,6 @@
/* Support for extended attributes.
Copyright (C) 2006-2013 Free Software Foundation, Inc.
Copyright (C) 2006-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -1,6 +1,7 @@
/* POSIX extended headers for tar.
Copyright (C) 2003-2007, 2009-2010, 2012-2013 Free Software Foundation, Inc.
Copyright (C) 2003-2007, 2009-2010, 2012-2014, 2016 Free Software
Foundation, Inc.
This file is part of GNU tar.
@@ -754,6 +755,16 @@ xheader_decode (struct tar_stat_info *st)
continue;
}
run_override_list (keyword_override_list, st);
/* The archived (effective) file size is always set directly in tar header
field, possibly overridden by "size" extended header - in both cases,
result is now decoded in st->stat.st_size */
st->archive_file_size = st->stat.st_size;
/* The real file size (given by stat()) may be redefined for sparse
files in "GNU.sparse.realsize" extended header */
if (st->real_size_set)
st->stat.st_size = st->real_size;
}
static void
@@ -802,11 +813,11 @@ xheader_store (char const *keyword, struct tar_stat_info *st,
t = locate_handler (keyword);
if (!t || !t->coder)
return;
if (xheader_keyword_deleted_p (keyword)
|| xheader_keyword_override_p (keyword))
if (xheader_keyword_deleted_p (keyword))
return;
xheader_init (&st->xhdr);
t->coder (st, keyword, &st->xhdr, data);
if (!xheader_keyword_override_p (keyword))
t->coder (st, keyword, &st->xhdr, data);
}
void
@@ -1016,7 +1027,7 @@ xheader_string_end (struct xheader *xhdr, char const *keyword)
}
x_obstack_blank (xhdr, p);
x_obstack_1grow (xhdr, '\n');
cp = obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
cp = (char*) obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
memmove (cp + p, cp, xhdr->string_length);
cp = stpcpy (cp, np);
*cp++ = ' ';
@@ -1359,7 +1370,10 @@ sparse_size_decoder (struct tar_stat_info *st,
{
uintmax_t u;
if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
st->stat.st_size = u;
{
st->real_size_set = 1;
st->real_size = u;
}
}
static void
@@ -1442,13 +1456,13 @@ sparse_map_decoder (struct tar_stat_info *st,
size_t size __attribute__((unused)))
{
int offset = 1;
struct sp_array e;
st->sparse_map_avail = 0;
while (1)
{
intmax_t u;
char *delim;
struct sp_array e;
if (!ISDIGIT (*arg))
{

4
tests/.gitignore vendored
View File

@@ -8,3 +8,7 @@ argcv.c
argcv.h
genfile.c
genfile
download
ttyemu
checkseekhole
ckmtime

View File

@@ -1,6 +1,6 @@
# Makefile for GNU tar regression tests.
# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2013 Free Software
# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2015 Free Software
# This file is part of GNU tar.
@@ -43,9 +43,13 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
TESTSUITE_AT = \
T-cd.at\
T-dir00.at\
T-dir01.at\
T-empty.at\
T-null.at\
T-null2.at\
T-rec.at\
T-recurse.at\
T-zfile.at\
T-nonl.at\
T-mult.at\
@@ -56,9 +60,11 @@ TESTSUITE_AT = \
append02.at\
append03.at\
append04.at\
append05.at\
backup01.at\
chtype.at\
comprec.at\
comperr.at\
delete01.at\
delete02.at\
delete03.at\
@@ -114,6 +120,8 @@ TESTSUITE_AT = \
incr07.at\
incr08.at\
incr09.at\
incr10.at\
incr11.at\
indexfile.at\
ignfail.at\
label01.at\
@@ -135,6 +143,7 @@ TESTSUITE_AT = \
lustar01.at\
lustar02.at\
lustar03.at\
map.at\
multiv01.at\
multiv02.at\
multiv03.at\
@@ -143,7 +152,14 @@ TESTSUITE_AT = \
multiv06.at\
multiv07.at\
multiv08.at\
multiv09.at\
numeric.at\
old.at\
onetop01.at\
onetop02.at\
onetop03.at\
onetop04.at\
onetop05.at\
opcomp01.at\
opcomp02.at\
opcomp03.at\
@@ -155,6 +171,7 @@ TESTSUITE_AT = \
owner.at\
pipe.at\
recurse.at\
recurs02.at\
rename01.at\
rename02.at\
rename03.at\
@@ -181,6 +198,7 @@ TESTSUITE_AT = \
remfiles09a.at\
remfiles09b.at\
remfiles09c.at\
remfiles10.at\
same-order01.at\
same-order02.at\
shortfile.at\
@@ -191,12 +209,15 @@ TESTSUITE_AT = \
sparse02.at\
sparse03.at\
sparse04.at\
sparse05.at\
sparse06.at\
sparsemv.at\
sparsemvp.at\
spmvp00.at\
spmvp01.at\
spmvp10.at\
time01.at\
time02.at\
truncate.at\
update.at\
update01.at\
@@ -208,6 +229,7 @@ TESTSUITE_AT = \
version.at\
xform-h.at\
xform01.at\
xform02.at\
star/gtarfail.at\
star/gtarfail2.at\
star/multi-fail.at\
@@ -221,10 +243,14 @@ TESTSUITE_AT = \
xattr05.at\
acls01.at\
acls02.at\
acls03.at\
selnx01.at\
selacl01.at\
capabs_raw01.at
distclean-local:
-rm -rf download
TESTSUITE = $(srcdir)/testsuite
AUTOTEST = $(AUTOM4TE) --language=autotest
@@ -247,7 +273,7 @@ check-full:
#check_SCRIPTS = tar
# Run the test suite on the *installed* tree.
installcheck-local:
installcheck-local: $(check_PROGRAMS)
$(SHELL) $(TESTSUITE) $(TESTSUITEFLAGS) AUTOTEST_PATH=$(exec_prefix)/bin
@@ -255,9 +281,10 @@ installcheck-local:
## genfile ##
## ------------ ##
check_PROGRAMS = genfile
check_PROGRAMS = genfile checkseekhole ckmtime
genfile_SOURCES = genfile.c argcv.c argcv.h
checkseekhole_SOURCES = checkseekhole.c
localedir = $(datadir)/locale
AM_CPPFLAGS = \

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2013 Free Software Foundation, Inc.
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
#
# This file is part of GNU tar.
#

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

@@ -0,0 +1,46 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.
# GNU tar 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 of the License, or
# (at your option) any later version.
# GNU tar 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/>.
# Tar 1.27 and 1.28 did not extract files under directory members listed
# in the file read by --file-from.
#
# Reported-by: Jean-Louis Martineau <martineau@zmanda.com>
# References: <541AE02C.2050008@zmanda.com>,
# http://lists.gnu.org/archive/html/bug-tar/2014-09/msg00006.html
AT_SETUP([recursive extraction from --files-from])
AT_KEYWORDS([files-from extract T-dir T-dir00])
AT_TAR_CHECK([
AT_SORT_PREREQ
mkdir dir
genfile -f dir/file1
genfile -f dir/file2
tar cf archive dir
rm -rf dir
echo dir > list
tar xfTv archive list | sort
],
[0],
[dir/
dir/file1
dir/file2
])
AT_CLEANUP

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

@@ -0,0 +1,46 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.
# GNU tar 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 of the License, or
# (at your option) any later version.
# GNU tar 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/>.
# Tar 1.27 and 1.28 did not remove trailing slashes from file names
# obtained with the --file-from option.
#
# Reported-by: Jean-Louis Martineau <martineau@zmanda.com>
# References: <541AE02C.2050008@zmanda.com>,
# http://lists.gnu.org/archive/html/bug-tar/2014-09/msg00006.html
AT_SETUP([trailing slash in --files-from])
AT_KEYWORDS([files-from extract T-dir T-dir01])
AT_TAR_CHECK([
AT_SORT_PREREQ
mkdir dir
genfile -f dir/file1
genfile -f dir/file2
tar cf archive dir
rm -rf dir
echo dir/ > list
tar xfTv archive list | sort
],
[0],
[dir/
dir/file1
dir/file2
])
AT_CLEANUP

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright 2006-2007, 2013 Free Software Foundation, Inc.
# Copyright 2006-2007, 2013-2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2013 Free Software Foundation, Inc.
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
#
# This file is part of GNU tar.
#

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2013 Free Software Foundation, Inc.
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
#
# This file is part of GNU tar.
#

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2013 Free Software Foundation, Inc.
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
#
# This file is part of GNU tar.
#

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright 2006-2007, 2013 Free Software Foundation, Inc.
# Copyright 2006-2007, 2013-2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.

43
tests/T-null2.at Normal file
View File

@@ -0,0 +1,43 @@
# This file is part of test suite for GNU tar. -*- Autotest -*-
# Copyright 2015-2016 Free Software Foundation, Inc.
#
# GNU tar 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 of the License, or
# (at your option) any later version.
#
# GNU tar 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([--null enables verbatim reading])
AT_KEYWORDS([files-from null T-null2 T-verbatim])
# According to the docs, --null should read each line from the file
# list verbatim. This feature was broken by commit 26538c9b (tar version
# 1.27).
AT_TAR_CHECK([
AT_DATA([file-list],[a
-b
--c d
])
genfile -f a
genfile -f -b
genfile -f '--c d'
cat file-list | tr '\n' '\0' | tar -c -f archive -v --null -T -
],
[0],
[a
-b
--c d
],
[],[],[],[ustar]) # Testing one format is enough
AT_CLEANUP

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2013 Free Software Foundation, Inc.
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
#
# This file is part of GNU tar.
#

90
tests/T-recurse.at Normal file
View File

@@ -0,0 +1,90 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright 2015-2016 Free Software Foundation, Inc.
# This file is part of GNU tar.
# GNU tar 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 of the License, or
# (at your option) any later version.
# GNU tar 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/>.
# Description: Test interaction of --recursion and --no-recursion options
# together with --files-from option. This is complementary to recurs02.at test
# case. References:
# <alpine.LSU.2.11.1502201029580.29773@nerf60.vanv.qr>
# http://lists.gnu.org/archive/html/bug-tar/2015-06/msg00006.html
AT_SETUP([files-from & recurse: toggle])
AT_KEYWORDS([recurse T-recurse files-from])
AT_TAR_CHECK([
mkdir directory1 directory2
touch directory1/file directory2/file
AT_DATA([F1],[--no-recursion
directory1/
--recursion
directory2/
])
AT_DATA([F2A],[directory1/
])
AT_DATA([F2B],[directory2/
])
a=archive
tar cf "$a" --files-from F1
tar tf "$a"
a=archive2
tar cf "$a" --no-recursion -T F2A --recursion -T F2B
tar tf "$a"
],
[0],
[directory1/
directory2/
directory2/file
directory1/
directory2/
directory2/file
])
AT_CLEANUP
AT_SETUP([toggle --recursion (not) from -T])
AT_KEYWORDS([recurse T-recurse T-recurse2 files-from])
AT_TAR_CHECK([
mkdir directory1 directory2
touch directory1/file directory2/file
AT_DATA([F1],[--no-recursion
directory1/
])
AT_DATA([F2],[directory2/
])
tar cf archive -T F1 --recursion -T F2
tar tf archive
],
[0],
[directory1/
directory2/
directory2/file
])
AT_CLEANUP

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2013 Free Software Foundation, Inc.
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
#
# This file is part of GNU tar.
#

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2011, 2013 Free Software Foundation, Inc.
# Copyright 2011, 2013-2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2011, 2013 Free Software Foundation, Inc.
# Copyright 2011, 2013-2014, 2016 Free Software Foundation, Inc.
# This file is part of GNU tar.

Some files were not shown because too many files have changed in this diff Show More