218 Commits

Author SHA1 Message Date
Sergey Poznyakoff
e545d446df Version 1.35 2023-07-18 09:38:30 +03:00
Sergey Poznyakoff
e7a5e12445 Use full-read instead of safe-read
This helps handle archiving on certain filesystems where read()
returns less bytes than requested when reading from a regular
file.

References:

  https://savannah.gnu.org/bugs/index.php?64426
  https://lists.gnu.org/archive/html/bug-tar/2021-07/msg00001.html

* gnulib.modules: Add full-read.
* src/common.h: Include full-read.h
* src/misc.c: Use full_read.
* src/sparse.c: Likewise.
* src/update.c: Likewise.
2023-07-17 17:07:12 +03:00
Sergey Poznyakoff
31f68bbe2a Fix typo in comments
This and the bug fixed by the previous commit were reported by
Benno Schulenberg.
2023-07-11 09:16:15 +03:00
Sergey Poznyakoff
10954cf163 Fix --update --wildcards
* src/common.h (name): New field: is_wildcard.
(name_scan): Change protoype.
* src/delete.c: Update calls to name_scan.
* src/names.c (addname, add_starting_file): Initialize is_wildcard.
(namelist_match): Take two arguments.  If second one is true, return
only exact matches.
(name_scan): Likewise.  All callers updated.
(name_from_list): Skip patterns.
* src/update.c (remove_exact_name): New function.
(update_archive): Do not remove matching name, if it is a pattern.
Instead, add a new entry with the matching file name.

* tests/update04.at: New test.
* tests/Makefile.am: Add new test.
* tests/testsuite.at: Include new test.

* NEWS: Update.
2023-07-10 21:25:30 +03:00
Benno Schulenberg
b3a71dbdb9 Various fixes in the documentation
* doc/tar.1: Add missing dots, use plural when necessary,
tweak a wording.  Remove an incorrect observation, three times.
Add some missing articles, correct some formatting,
and expand the opaque descriptions of two options.
* doc/tar.texi: Drop a stray `cd` command from an example.
Correct two cross references, correct the paragraph
about the manpage, and unbreak a URL.
* src/names.c: Correct and shorten an error message: "non-optional"
means "mandatory", but "non-option" is what was meant.  And the
phrase "in archive create or update mode" was both unneeded and
incomplete.
* tests/positional01.at: Change expected error text.
* tests/positional02.at: Likewise.
* tests/positional03.at: Likewise.
2023-07-10 12:33:34 +03:00
Paul Eggert
cf16a23945 build: update gnulib submodule to latest 2023-06-28 17:43:48 -07:00
Paul Eggert
d6a60bba76 tar: extract delayed links in order
Extract delayed links in tar file order, rather than
in hash table order with modifications.
This is simpler and more likely to use the kernel’s
cached filesystem data, assuming related delayed links
are nearby in the tar file.
* src/extract.c (struct delayed_link.has_predecessor):
Remove.  All uses removed.
(delayed_link_head, delayed_link_tail): New static vars.
This resurrects delayed_link_head’s old function
except that the linked list is now in forward order, not reverse.
(find_delayed_link_source): Now simply returns bool,
since the callers no longer need the pointer.
(create_placeholder_file):
Put the delayed link at the end of the linked list.
Omit no-longer-needed last arg.  All callers changed.
(apply_delayed_links): Simplify now that we can just iterate
through the delayed_link_head list.
2023-06-25 14:28:36 -07:00
Paul Eggert
2ccd643d01 tar: make safe for -Wunused-parameter
This also ports to C23 [[maybe_unused]].
* configure.ac (WARN_CFLAGS): Do not add -Wno-unused-parameter.
Add MAYBE_UNUSED where needed in source code.
Also, put it at the front where C23 requires it.
2023-06-25 14:28:36 -07:00
Paul Eggert
fdff045d4b * po/.gitignore: Omit redundant *~ entries. 2023-06-25 14:28:36 -07:00
Paul Eggert
90cceec4bb tar: omit unnecessary freeing
* src/tar.c (main): Omit unnecessary freeing.
2023-06-25 14:28:36 -07:00
Sergey Poznyakoff
826c5eb64e Make sure each delayed link entry is visited once
* src/extract.c (create_placeholder_file): Use FLEXNSIZEOF (overlooked
by c542d3d0c8)
(apply_delayed_links): Don't follow the "next" chain after its entries
have been applied.
2023-06-18 09:20:28 +03:00
Paul Eggert
2096772fbe Omit unnecessary freeing
* src/extract.c (apply_delayed_link): Don’t bother to
free memory, as we’re about to exit.
2023-06-17 00:37:43 -07:00
Paul Eggert
c542d3d0c8 Port to strict C99 struct hack
Portability bug caught by GCC 13 -fstrict-flex-arrays.
* gnulib.modules: Add flexmember.
* src/create.c (struct link):
* src/exclist.c (struct excfile):
* src/extract.c (struct delayed_link, struct string_list):
Include <flexmember.h>.  Use FLEXIBLE_ARRAY_MEMBER, for
portability to strict C99 or later.  All storage
allocations changed to use FLEXNSIZEOF.
2023-06-16 17:12:40 -07:00
Paul Eggert
4c7a3798d8 Use Gnulib ‘dup2’ module
This simplifies code that would otherwise use dup and close.
* gnulib.modules: Add dup2.
* src/system.c: Add #pragma to pacify GCC 13.
(xdup2): Simplify by using dup2.
2023-06-16 17:12:40 -07:00
Paul Eggert
5d6736e394 Use Gnulib ‘free-posix’ module
Paxutils uses it so we should too.
* gnulib.modules: Add ‘free-posix’.
* src/misc.c (remove_any_file): Assume ‘free’ keeps errno.
2023-06-16 17:12:39 -07:00
Paul Eggert
9ee30c9804 * buffer.c: work around GCC bug 109856 2023-06-16 17:12:39 -07:00
Paul Eggert
4695adfd59 Recommend Y2038 safety 2023-06-16 17:12:39 -07:00
Paul Eggert
a484178a18 build: update gnulib and paxutils submodules to latest 2023-06-16 17:12:39 -07:00
Paul Eggert
e39b93d822 * .gitignore: Add slash, as bootstrap does this now. 2023-06-16 17:12:39 -07:00
Paul Eggert
8ccfc4e416 Sync bootstrap from Gnulib 2023-06-16 17:12:39 -07:00
Pavel Raiskup
e7987b72c6 Comment a bit on the xattr extraction logic
* src/extract.c (extract_file): Document why we pre-create with S_IWUSR.
(set_xattr): Drop the INVERT_PERMISSIONS doc leftover.
2023-06-06 12:37:06 +03:00
Pavel Raiskup
06805b9281 Fix --xattr-include='*' documentation
* doc/tar.texi (Extended File Attributes): The default extraction
pattern consists of just 'user.*' namespace only.  While on it, try
to explain the reasons for this default behavior.
2023-06-06 12:34:08 +03:00
Sergey Poznyakoff
5461025569 Honor --numeric-owner when storing ACL entries
Based on patch from Fabian Grünbichler <f.gruenbichler@proxmox.com>

* src/xattrs.c (acls_get_text): New function.  If given --numeric-owner,
use acl_to_any_text to convert ACL to textual representation.  Print
warning if that function is not available.
(xattrs__acls_get_a, xattrs__acls_get_d): Use acls_get_text.
2023-05-18 13:35:50 +03:00
Sergey Poznyakoff
3f2b847ddd Upgrade paxutils to d50ea31268
This fixes two bugs related to remote archives:

1. Access from unprivileged user accounts.
2. Malfunctioning seek (L) command.
2023-05-18 11:44:50 +03:00
Sergey Poznyakoff
6af0596726 Don't copy DISTFILES during bootstrapping
DISTFILES are necessary only during bootstrapping and should not be
distributed.

This partially reverts commit 9f0e54ab2.
2023-05-18 08:43:04 +03:00
Benno Schulenberg
204b414d11 Add missing option to manpage and remove duplicate operation
* doc/tar.1: Add needed option -f after operation -A, sort operation -t
  alphabetically, add --file after --concatenate, consistently use long
  option --file in the GNU-style section, and delete duplicate --update.
* doc/tar.texi: Add small missing word, and lowercase a letter.
2023-05-01 20:31:47 +03:00
Sergey Poznyakoff
6a1581240b Change some wording in doc/intern.texi 2023-04-18 11:15:44 +03:00
Anton Makrushin
4f814e0e4c Exclude VCS directory with writing from an archive
See https://savannah.gnu.org/bugs/?62859
2023-04-18 10:50:57 +03:00
Sergey Poznyakoff
4177c98bcc Detect EOF when deleting from archive.
See https://savannah.gnu.org/bugs/?63823

* src/delete.c (flush_file): Break the loop on EOF.
* tests/delete06.at: New test.
* tests/Makefile.am: Add new test.
* tests/testsuite.at: Likewise.
2023-02-21 14:00:32 +02:00
Sergey Poznyakoff
5e8a915b16 Changes in extended header decoder
* src/xheader.c (decode_time): Fix error detection.
(raw_path_decoder): Ignore empty paths.
2023-02-11 14:21:05 +02:00
Sergey Poznyakoff
edf38d13a4 Prevent dead loop in extract_file
* src/extract.c (maybe_recoverable): If make_directories indicates
success, suppose some intermediate directories have been made, even
if in fact they have not.  That's necessary to avoid dead loops when
maybe_recoverable is called with the same arguments again.
2023-02-11 13:03:23 +02:00
Sergey Poznyakoff
3da78400ea Fix boundary checking in base-256 decoder
* src/list.c (from_header): Base-256 encoding is at least 2 bytes
long.
2023-02-11 11:59:52 +02:00
Paul Eggert
02402920f8 Adjust to Gnulib macro renaming
* src/Makefile.am, tests/Makefile.am (LDADD):
Gnulib renamed LIB_HAS_ACL to FILE_HAS_ACL_LIB.
2023-01-06 12:50:36 -08:00
Paul Eggert
021845e54d build: update gnulib, paxutils submodules to latest 2023-01-06 12:50:36 -08:00
Paul Eggert
0f289d7238 Go back to single-file bootstrap
Gnulib now supports a single-file bootstrap with --pull
and --gen options, in place of the three files
autopull.sh, autogen.sh, bootstrap-funclib.sh.
This keeps the top level a bit cleaner.
* bootstrap: Sync from Gnulib build-aux/bootstrap
instead of from top/bootstrap.
* autopull.sh, autogen.sh, bootstrap-funclib.sh: Remove.
2023-01-06 12:50:36 -08:00
Paul Eggert
71d1619abd Fix ‘assume’ include
* src/tar.c: Include verify.h, needed for ‘assume’.
2023-01-06 12:50:36 -08:00
Paul Eggert
719d3b44b7 Update copyright years
UPDATE_COPYRIGHT_USE_INTERVALS=1 \
gnulib/build-aux/update-copyright \
  $(git ls-files | sed -e '/^gnulib$/d
                           /^paxutils$/d
			   /^COPYING$/d
			   /\/fdl.texi$/d')
2023-01-06 12:50:36 -08:00
Sergey Poznyakoff
a65f01ac35 Optionally warn about missing zero blocks at the end of the archive
(In response to savannah bug #63574)

* doc/intern.texi: Document actual tar behaviour in regard to
missing end-of-file marker.
* doc/tar.texi: Rewrite the "warnings" section.  Document
--warning=missing-zero-blocks
* src/common.h (WARN_MISSING_ZERO_BLOCKS): New constant.
(WARN_ALL): Include all warning bits.
* src/list.c (read_and): If EOF is reached without seeing end-of-file
blocks and the "missing-zero-blocks" warning is requested, warn about
the fact.
* src/warning.c: New warnings: "missing-zero-blocks", "verbose".
(warning_option): Change definition to reflect changes in common.h
2022-12-29 17:42:04 +02:00
Sergey Poznyakoff
2cde05fa10 Fix example use of find command in documentation 2022-12-27 13:02:05 +02:00
Sergey Poznyakoff
e89c7a45eb Fix savannah bug #63567
* src/buffer.c (short_read): Increase records_read only if a full
record has been read.
2022-12-26 23:46:15 +02:00
Paul Eggert
24c8306965 Fix -Af F bug when F is not a regular file
Problem reported by Boris Gjenero in:
https://lists.gnu.org/r/bug-tar/2022-11/msg00001.html
* src/update.c (append_file): Don’t assume that FILE_NAME is a
regular file whose size can be determined before reading.
Instead, simply read from the file until its end is reached.
2022-11-03 23:07:38 -07:00
Paul Eggert
ba26ec86e2 Fix README-* files
README-alpha is for alpha releases, which are not from Git or CVS, so
omit mention of that.  I'm not sure we'll ever do alpha releases, but
if we do, README-alpha assumes the tarballs are already bit.

Update README-hacking with info that was mistakenly put into
README-alpha.  Also mention Bison, needed for parse-date.y.
2022-11-03 22:58:27 -07:00
Paul Eggert
de64229632 Fix undefined behavior on bad extended header
* src/xheader.c (locate_handler): Avoid undefined behavior
if strlen(keyword) < kwlen.
2022-10-27 13:20:38 -07:00
Sergey Poznyakoff
17debecd73 Fix savannah bug #63123
The bug was introduced by commit 79d1ac38c1, which didn't take into
account all the consequences of returning RECOVER_OK on EEXIST, in
particular interactions with the delayed_set_stat logic.

The commit 79d1ac38c1 is reverted (the bug it was intended to fix
was actually fixed by 79a442d7b0).  Instead:

* src/extract.c (maybe_recoverable): Don't call maybe_recoverable
if EEXIST is reported when UNLINK_FIRST_OLD_FILES option is set.
2022-10-22 19:59:04 +03:00
Sergey Poznyakoff
02f9af1b8d Fix savannah bug #63250
* src/buffer.c (magic): Add signature of LZMA files produced by xz.
2022-10-22 11:14:53 +03:00
Paul Eggert
87f9e42108 Mention previous bug fix 2022-10-07 15:55:44 -07:00
Paul Eggert
0f0722df45 tests: check for recently-fixed bug
* tests/exclude17.at: New file.
* tests/testsuite.at (AT_CHECK_TIMESTAMP): Add it.
2022-10-07 15:25:36 -07:00
Aurélien Martin
7324326b1d tar: fix --exclude-vcs-ignores memory
The function frees the patterns' wordsplit structure without asking
add_exclude to reallocate the strings.  In many cases, this leads to
each file name in the directory being checked against the memory
location where it just got reallocated.
* src/exclist.c: Use EXCLUDE_ALLOC.
Copyright-paperwork-exempt: Yes
2022-10-07 15:25:36 -07:00
Paul Eggert
705bb09317 build: update submodules to latest
* src/common.h: Include <inttostr.h> since paxutils no longer does.
(STRINGIFY_BIGINT): New macro, copied from older paxutils.
(UINTMAX_STRSIZE_BOUND): New constant, also from older paxutils.
2022-09-10 18:54:21 -05:00
Paul Eggert
4ba281eca3 Fix bootstrap.conf when no paxutils
* bootstrap.conf: Don’t assume the paxutils subdirectory already
exists, when bootstrapping.
2022-09-10 18:54:21 -05:00
Paul Eggert
bc277c7069 Fix data loss when acting as filter
This bug was introduced by the recent lseek-related changes.
* src/delete.c (delete_archive_members):
* src/update.c (update_archive):
Copy the member if acting as a filter, rather than lseeking over
it, which is possible if stdin is a regular file.
* src/list.c (skim_file, skim_member):
* src/sparse.c (sparse_skim_file):
New functions, for copying when a filter.
* src/list.c (skip_file): Remove; replaced with skim_file.
All callers changed.
(skip_member): Reimplement in terms of skim_member.
* src/sparse.c (sparse_skip_file):
Remove; replaced with sparse_skim_file.  All callers changed.
* src/update.c (acting_as_filter): New static var.
(update_archive): Set it; this is like delete.c.
* tests/delete01.at (deleting a member after a big one):
* tests/delete02.at (deleting a member from stdin archive):
Also test filter case.
2022-09-03 18:23:11 -05:00
Paul Eggert
f8e14746d2 Fix --delete bug with short reads
* gnulib.modules: Add idx.
* src/common.h: Include idx.h.
* src/delete.c (move_archive): Don’t botch short reads.
2022-09-02 16:33:47 -05:00
Paul Eggert
35d9845d5d Do not diagnose same xattr file twice
* src/extract.c (set_xattr): Simplify, by having it do only
the mknodat and xattrs_xattrs_set, rather than also
trying to recover from failure.  Caller simplified too.
* tests/xattr07.at (xattrs: xattrs and --skip-old-files):
Adjust test to match fixed behavior.
2022-08-26 16:39:16 -05:00
Paul Eggert
0b74885e81 Fix bug with -x --xattr read-only files
Problem reported by Kevin Raymond in:
https://bugzilla.redhat.com/show_bug.cgi?id=1886540
* src/extract.c (open_output_file): If we already created the
empty file, do not open with O_EXCL, or with O_CREAT or O_TRUNC
for that matter.  Instead, use only O_NOFOLLOW to avoid some
races.  When estimating current mode, use openflag & O_EXCL rather
than overwriting_old_files.
(extract_file): Also invert S_IWUSR if it’s not set.
* tests/xattr08.at: New test.
* tests/Makefile.am, tests/testsuite.at: Add it.
2022-08-26 16:39:16 -05:00
Paul Eggert
258d1c44e5 Avoid quadratic behavior with delayed links
Do this by searching a hash table instead of a linked list.
Problem reported by Martin Dørum in https://mort.coffee/home/tar/
via Gavin Smith in:
https://lists.gnu.org/r/bug-tar/2022-07/msg00003.html
* src/extract.c: Include hash.h.
Improve performance a bit on non-birthtime hosts
(struct delayed_link.has_predecessor): New member.
(delayed_link_head): Remove, replacing with ...
(delayed_link_table): ... this new variable.  All uses
of linked list replaced with hash table.
(dl_hash, dl_compare): New functions for hash table.
(create_placeholder_file): Initialize has_predecessor.
(apply_delayed_link): New function, with body taken from
most of the old apply_delayed_link.
(apply_delayed_links): Use it.  Respect has_predecessor.
Don’t bother freeing as we are about to exit.
2022-08-15 00:07:39 -07:00
Paul Eggert
e49537dcdf Improve performance a bit on non-birthtime hosts
* src/extract.c (HAVE_BIRTHTIME, BIRTHTIME_EQ): New macros.
(struct delayed_link, create_placeholder_file, extract_link)
(apply_delayed_links): Avoid unnecessary work on platforms
like GNU/Linux that lack birthtime.
2022-08-15 00:07:39 -07:00
Paul Eggert
66be5a789e Avoid excess lseek etc.
* src/buffer.c, src/delete.c: Do not include system-ioctl.h.
* src/buffer.c (guess_seekable_archive): Remove.  This is now done
by get_archive_status, in a different way.
(get_archive_status): New function that gets archive_stat
unless remote, and sets seekable_archive etc.
(_open_archive): Prefer bool for boolean.
(_open_archive, new_volume): Get archive status consistently
by calling get_archive_status in both places.
* src/buffer.c (backspace_output):
* src/compare.c (verify_volume):
* src/delete.c (move_archive):
Let mtioseek worry about mtio.
* src/common.h (archive_stat): New global, replacing ar_dev and
ar_ino.  All uses changed.
* src/delete.c (move_archive): Check for integer overflow.
Also report overflow if the archive position would go negative.
* src/system.c: Include system-ioctl.h, for MTIOCTOP etc.
(mtioseek): New function, which also checks for integer overflow.
(sys_save_archive_dev_ino): Remove.
(archive_stat): Now
(sys_get_archive_stat): Also initialize mtioseekable_archive.
(sys_file_is_archive): Don’t return true if the archive is /dev/null
since it’s not a problem in that case.
(sys_detect_dev_null_output): Cache dev_null_stat.

doc: omit MS-DOS mentions in doc
It’s really FAT32 we’re worried about now, not MS-DOS.
And doschk is no longer a GNU program.
2022-08-15 00:07:39 -07:00
Paul Eggert
badd509078 Omit MS-DOS mentions in doc
It’s really FAT32 we’re worried about now, not MS-DOS.
And doschk is no longer a GNU program.
2022-08-15 00:07:39 -07:00
Paul Eggert
4e9e55fbf9 Work around GCC bug 106436
* src/tar.c (optloc_eq): Use ‘assume’ to pacify GCC bug.
2022-07-25 09:44:00 -07:00
Paul Eggert
fffc6149fd Avoid unlikely crash when xasprintf returns 0
Problem caught by GCC 12.
* src/tar.c (easprintf): New static function, which never returns
a null pointer.  All uses of xasprintf replaced by uses of this
function.
2022-07-25 09:44:00 -07:00
Paul Eggert
8ed180b03c Update .gitignore
* .gitignore: Redo for current sources.
2022-07-25 09:44:00 -07:00
Paul Eggert
131ceea7a5 Fix minor type confusion
* src/tar.c (decode_options): Don’t assign ‘false’ to a pointer.
2022-07-25 09:44:00 -07:00
Paul Eggert
4986147986 Work around GCC bug 106428
* src/names.c (read_next_name): Reword and clarify
to avoid GCC bug 106428.
2022-07-25 09:44:00 -07:00
Paul Eggert
e5aac38c80 Work around GCC bug 106427
* lib/wordsplit.c (coalesce_segment): Reword to avoid
GCC bug 106427.
2022-07-25 09:44:00 -07:00
Paul Eggert
5c4f8cadbd Adjust to Gnulib bootstrap revamp
* autogen.sh, autopull.sh, bootstrap-funclib.sh:
New files, copied from gnulib/top.
* bootstrap: Copy from gnulib/top/bootstrap (as opposed
to copying from gnulib/build-aux/bootstrap, as we used to).
* bootstrap.conf (bootstrap_post_pull_hook)
(bootstrap_post_import_hook): New functions.
Move commands into these functions as needed.
2022-07-24 11:46:56 -07:00
Paul Eggert
496cf61638 * doc/tar.1: Fix --xattrs-exclude typo. 2022-07-11 10:35:30 -05:00
Paul Eggert
d935dc7d1c Avoid EOVERFLOW problems in some symlink tests
* src/extract.c (is_directory_link): New arg ST.  Caller changed.
(is_directory_link, open_output_file):
Use readlinkat, not fstatat, to determine whether a string
names a symlink.  This avoids EOVERFLOW issues.
(extract_dir): Avoid duplicate calls to fstatat when
keep_directory_symlink_option && fstatat_flags == 0
and the file is a symlink to an existing file.
2022-06-13 17:03:49 -07:00
Paul Eggert
9f0e54ab2f Fix ‘make dist-xz’ bug
Problem reported by Pavel Raiskup in:
https://lists.gnu.org/r/bug-tar/2022-06/msg00014.html
* bootstrap.conf (copy_files): Also copy DISTFILES.
2022-06-13 16:50:11 -07:00
Paul Eggert
c7b69f05bc Fix commentary in new test case 2022-06-13 14:56:45 -07:00
Paul Eggert
4eb9d052b2 Fix doc -c typo
https://lists.gnu.org/r/bug-tar/2022-06/msg00006.html
* doc/tar.texi (Extended File Attributes): Fix typo.
2022-06-12 20:33:27 -07:00
Paul Eggert
5209d1dfe0 Update to current Autoconf & Gettext
* acinclude.m4, configure.ac:
Use AS_HELP_STRING, not AC_HELP_STRING.
* bootstrap: Sync from Gnulib.
* configure.ac: Require Autoconf 2.71 and Gettext 0.21.
Use AC_PROG_CC, not AC_PROG_CC_STDC.
Prefer AC_COMPILE_IFELSE to AC_TRY_COMPILE.
Use AC_CONFIG_FILES.
* gnulib.modules: Use gettext-h, not gettext.
2022-06-12 18:19:46 -07:00
Paul Eggert
b2ed3caefe build: update gnulib and paxutils submodules to latest 2022-06-12 18:19:46 -07:00
James Abbatiello
79d1ac38c1 tar: fix race condition
Problem reported in:
https://lists.gnu.org/r/bug-tar/2022-03/msg00000.html
* src/extract.c (make_directories): Retry the file creation as
long as the directory exists, regardless of whether tar itself
created the directory.
Copyright-paperwork-exempt: Yes
2022-06-10 18:26:37 -07:00
Paul Eggert
79a442d7b0 tar: fix race condition
Problem reported by James Abbatiello in:
https://lists.gnu.org/r/bug-tar/2022-03/msg00000.html
* src/extract.c (make_directories): Do not assume that when
mkdirat fails with errno == EEXIST that there is an existing file
that can be statted.  It could be a dangling symlink.  Instead,
wait until the end and stat it.
2022-06-10 18:26:37 -07:00
Paul Eggert
7a37621e5b test: new test extrac25.at
* tests/Makefile.am (TESTSUITE_AT): Add extrac25.at.
* tests/extrac25.at: New file.
* tests/testsuite.at: Include it.
2022-06-10 18:26:37 -07:00
Paul Eggert
c1027eb5ae Warn “file changed as we read it” less often
* src/create.c (dump_file0): Remove an fstatat call that is
unnecessary because the file wasn’t read so we can treat the first
fstatat as atomic.  Warn “file changed” when the file’s size,
mtime, user ID, group ID, or mode changes, instead of when the
file’s size or ctime changes.  Also, when such a change happens,
do not change exit status if --ignore-failed-read.  Finally, don’t
attempt to change atime back if it didn’t change.
2022-06-09 15:50:42 -07:00
Paul Eggert
bc7e758b27 Modernize NEWS hook to current Emacs 2022-06-09 15:50:42 -07:00
Paul Eggert
de72aa0cd6 doc: fix abrupt sentence in HTML
Typo reported by Jackson Dougherty in:
https://lists.gnu.org/r/bug-tar/2022-05/msg00000.html
* doc/tar.texi: Don’t assume that tex and info are the only two
formats.
2022-05-03 15:26:23 -07:00
Paul Eggert
eeda008a59 tar: revamp "file is the archive" diagnostic
* src/create.c (dump_file0): For clarity, change diagnostic
wording from "file is the archive; not dumped" to "archive cannot
contain itself; not dumped".  All test cases and documentation changed.
2022-02-15 17:42:51 -08:00
Sergey Poznyakoff
5c713540e3 Update copyright years 2022-01-02 10:25:29 +02:00
Paul Eggert
88ccec5d6c Copy COPYING and fdl.texi from upstream 2021-12-13 18:47:21 -08:00
Paul Eggert
399c08b3bf Format ` and ' more nicely in doc
Use @documentencoding and set txicodequoteundirected and
txicodequotebacktick to get nicer-looking quoting in the manual.
2021-12-13 18:47:21 -08:00
Paul Eggert
7f8fe36040 Don’t recommend delete=mtime
That stops working after the year 2242.
2021-12-13 18:47:21 -08:00
Paul Eggert
b846956c60 More reproducible tarball doc
* doc/tar.texi (PAX keywords): Improve discussion of how
to generate reproducible tarballs.
2021-12-13 12:43:58 -08:00
Sergey Poznyakoff
ac119c80e4 Raise version number 2021-12-13 16:14:26 +02:00
Paul Eggert
d43adc97d6 .gitignore maintenance (some automated) 2021-12-13 00:44:57 -08:00
Paul Eggert
1f73735ba0 bootstrap: copy from Gnulib 2021-12-13 00:44:57 -08:00
Paul Eggert
39cd8c6586 build: update gnulib and paxutils submodules to latest 2021-12-13 00:44:57 -08:00
Paul Eggert
84a08f530d Add NEWS items for changes since 1.34 2021-12-13 00:44:57 -08:00
Paul Eggert
c366383852 Omit unnecessary devmajor and devminor setting
* src/create.c (dump_file0): Omit redundant setting of devmajor
and devminor; start_header already does this.
2021-12-13 00:44:57 -08:00
Paul Eggert
738de9ecde Omit devmajor and devminor for non-special files
* src/create.c (start_header): Leave the devmajor and devminor
fields empty for files that are not character and block special
devices, even when the archive format is pax, ustar or v7.
This avoids generating irrelevant differences which helps with
reproducible builds, and is more compatible with what Solaris 10
tar does.
2021-12-13 00:44:57 -08:00
Paul Eggert
771ca7b686 Use ‘bool’ in create.c
* src/create.c: Prefer ‘bool’, ‘true’, ‘false’ for booleans.
2021-12-13 00:44:57 -08:00
Paul Eggert
8184adddab * gnulib.modules: Add year2038. 2021-10-13 14:46:10 -07:00
Paul Eggert
7868054c03 build: improve build-from-git for older GCCs
configure.ac: Bump GCC version from 4.6 to 11.2 when deciding whether
to default to enabling GCC warnings when --enable-gcc-warnings is not
specified, as older GCCs can generate too many false alarms.  From
a suggestion by Christian Schoenebeck.
2021-09-20 13:11:36 -07:00
Paul Eggert
4f3824743f Simplify wordsplit code a bit
These changes pacify gcc -Wanalyzer-null-dereference on x86-64 gcc
11.2.1 20210728 (Red Hat 11.2.1-1).
* lib/wordsplit.c (wsnode_tail): Remove unnecessary test.
(coalesce_segment): Coalesce calls to wsnode_len.
2021-09-19 07:36:36 -07:00
Paul Eggert
c5b86d7672 build: document WERROR_CFLAGS
* README-hacking: Mention 'make WERROR_CFLAGS='.
2021-09-18 08:16:04 -07:00
Paul Eggert
c0bf6a723b build: update paxutils submodule to latest 2021-09-17 12:57:14 -07:00
Paul Eggert
b44c612f5d build: update gnulib submodule to latest
* src/common.h (get_directory_entries):
Add _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE.
Problem found by gcc -Wsuggest-attribute=malloc and
current Gnulib.
2021-09-17 12:57:14 -07:00
Paul Eggert
066f7729e0 Pacify gcc -Warray-parameter
* src/common.h (code_timespec): Declare sbuf arg to be an array,
to be consistent with definition.
2021-09-17 12:57:14 -07:00
Paul Eggert
7958eb97e6 Fix null rereference if low-memory
* src/incremen.c (read_incr_db_01): Use xstrdup not strdup.
Problem found by gcc -Wanalyzer-possible-null-argument.
2021-09-17 12:57:14 -07:00
Sergey Poznyakoff
66262c10d1 Provide functions for manipulating arrays of extended attributes
* src/common.h (xheader_xattr_free,xheader_xattr_copy): Remove protos.
(xattr_map_init,xattr_map_copy)
(xattr_map_add,xattr_map_free): New protos.
* src/tar.h (xattr_map): New struct.
(tar_stat_info): Replace xattr_map_size and xattr_map with one
field: xattr_map.
* src/xattrs.c (XATTRS_PREFIX,XATTRS_PREFIX_LEN): New defines.
(xheader_xattr_init,xattr_map_init)
(xattr_map_free,xattr_map_add)
(xheader_xattr_add,xattr_map_copy): New functions.
All uses changed.
* src/create.c (start_header): Update to use struct xattr_map.
* src/extract.c: Update to use struct xattr_map.
* src/tar.c: Likewise.
* src/xheader.c (xheader_xattr_init,xheader_xattr_free)
(xheader_xattr_add,xheader_xattr_copy): Remove.
(xattr_coder,xattr_decoder): Use xattr_map_ functions.
2021-09-02 21:01:58 +03:00
Sergey Poznyakoff
a339f05cd2 Fix handling of extended header prefixes
* src/xheader.c (locate_handler): Recognize prefix keywords only
when followed by a dot.
(xattr_decoder): Use xmalloc/xstrdup instead of alloc
2021-08-28 17:40:57 +03:00
Sergey Poznyakoff
cc8f5f78b2 Handle invalid sparse entries in pax header
* src/sparse.c (pax_decode_header): Check if sp.offset+sp.numbytes
falls within the reported file size.  Check for possible integer
overflow.
2021-08-28 14:15:25 +03:00
Sergey Poznyakoff
193eb8f81d transform: fix replacement of particular pattern instance
This fixes handling of expressions like 's/s/@/2'

Fix suggested by Anthony Heading.

* src/transform.c (_single_transform_name_to_obstack): Avoid duplicating
initial prefix if replace is not needed.
2021-08-28 09:57:26 +03:00
Samanta Navarro
93082d6eb8 Fix crash on invalid command line argument
The copy_string_unquote function does not handle arguments which only
consist of a single quote. A string is only quoted if two quoting
characters exist.

How to reproduce:

tar --checkpoint-action exec=\"
2021-07-01 09:52:42 +03:00
Sergey Poznyakoff
e5bc23efcc Fix the use of options with trailing slash in files-from list
* src/names.c (read_name_from_file): Do not remove trailing slash
here, since name_buffer might contain an option (e.g. -C /).
(read_next_name): Remove trailing slash when we're sure we're dealing
with a file name.
See 163e96a0.
2021-07-01 09:38:35 +03:00
Sergey Poznyakoff
12d67f44de Minor fix
* scripts/backup-specs: Set standard paths for rsh (patch#9275).
2021-06-01 19:02:42 +03:00
Samanta Navarro
3730dddb3f Fix typos
Typos found with codespell
2021-06-01 18:54:07 +03:00
Samanta Navarro
8e82f367d4 Minor changes.
* src/xheader.c (decode_record): Fix format specification.
(xattr_encode_keyword): Allocate space for terminating \0.
2021-06-01 18:49:28 +03:00
Sergey Poznyakoff
66b59fccb1 Fix gendocs_template 2021-03-24 20:56:54 +02:00
Paul Eggert
91c031678d Tune for single-threaded tar
This takes advantage of recent optimizations in Gnulib
for single-threaded programs.
* configure.ac (GNULIB_EXCLUDE_SINGLE_THREAD)
(GNULIB_MBRTOWC_SINGLE_THREAD, GNULIB_REGEX_SINGLE_THREAD)
(GNULIB_WCHAR_SINGLE_LOCALE): Define.
2021-03-07 18:30:08 -08:00
Paul Eggert
5227d66b3c Port linking to AIX 7.1
* src/Makefile.am (LDADD): Remove, folding into tar_LDADD.
* src/Makefile.am (tar_LDADD), tests/Makefile.am (LDADD):
Add the libraries gnulib-tool currently recommends: LIB_ACL,
LIB_CLOCK_GETTIME, LIB_GETRANDOM, LIB_HARD_LOCALE, LIB_HAS_ACL,
LIB_MBRTOWC, LIB_SETLOCALE_NULL.  Otherwise, tar won’t link on AIX
7.1 with xlc because the -lpthread option is missing.
2021-03-07 18:30:08 -08:00
Paul Eggert
f51461d8be Port xattr-at.h to AIX 7.1
* lib/xattr-at.h: Include <errno.h> before testing whether
ENOATTR is defined.
2021-03-07 18:30:08 -08:00
Paul Eggert
6efa8de409 build: update gnulib submodule to latest 2021-03-07 18:30:08 -08:00
Sergey Poznyakoff
c67d223854 Fix building the online version of the manual.
* doc/Makefile.am (GENDOCS): Use the version from the tar repository.
(manual): Set the DISTRIN rendition.
(manual-rebuild): New goal.
* doc/README.manual: New file. Instructions for maintainers on how to
update web documentation.
* doc/gendocs.sh: A version from gnulib fixed as per
https://lists.gnu.org/archive/html/bug-gnulib/2021-03/msg00002.html.
* doc/gendocs_template: Updated version from gnulib.
* doc/intern.texi: Fix the use of UNREVISED.
* doc/tar.texi: Fix the use of GNUTAR.
2021-03-01 20:44:31 +02:00
Paul Eggert
55f2a0772e Fix unlikely uninitalized var bug with sparse file
* src/sparse.c (sparse_extract_file): Set *SIZE to
stat.st_size so that the caller does not use *SIZE
when uninitalized.  Problem found with GCC 10 and
--enable-gcc-warnings CFLAGS='-O2 -flto -fanalyzer'.
2021-03-01 00:18:44 -08:00
Paul Eggert
daf634c44e Pacify --enable-gcc-warnings -flto -fanalyzer
With GCC 10.2.1, ‘./configure --enable-gcc-warnings CFLAGS='-O2
-flto -fanalyzer' issued a false alarm about uninitialized
variable use.  Pacify GCC by using a variant of the code.
* src/buffer.c (zip_program): Omit last placeholder entry.
(n_zip_programs): New constant.
(find_zip_program): Use it instead of placeholder.
(first_decompress_program): Set *PSTATE to maximum value
if skipping the table.  This avoids confusing gcc -flto
into thinking *PSTATE is used uninitialized.
(next_decompress_program): Simplify now that *PSTATE is maximal
when skipping.
2021-03-01 00:18:44 -08:00
Paul Eggert
5f8f129415 Pacify clang for unreachable ‘return’
* src/sparse.c (sparse_scan_file_seek): Omit unreachable statement.
2021-03-01 00:18:44 -08:00
Paul Eggert
dc101747e8 Pacify clang char conversion
* src/create.c (to_chars): Pacify ‘clang’ about assigning
128 to ‘char’.
2021-03-01 00:18:44 -08:00
Paul Eggert
7fb1b6877f Omit most uses of ‘inline’
With today’s compilers ‘inline’ is typically not needed for
performance (at least the way GNU Tar uses it) and it gets in the
way of portability.
* configure.ac: Omit AC_C_INLINE; no longer needed here.
* lib/attr-xattr.in.h (setxattr, lsetxattr, fsetxattr, getxattr)
(lgetxattr, fgetxattr, listxattr, llistxattr, flistxattr):
* lib/wordsplit.c (skip_delim_internal, skip_delim)
(skip_delim_real, exptab_matches):
* src/delete.c (flush_file):
* src/extract.c (safe_dir_mode):
* src/misc.c (ptr_align):
Now just static, not static inline.
* lib/wordsplit.h (wordsplit_getwords): Remove; no longer used.
* src/common.h (name_more_files): Now COMMON_INLINE, not
extern inline - which is not portable according to C99,
the way we were using it.
2021-03-01 00:18:44 -08:00
Paul Eggert
f4e2411bf5 maint: port better to non-GCC compilers
This can be helpful in porting to compilers like Oracle Developer
Studio that support some but not all GCC attributes.
* lib/wordsplit.c (FALLTHROUGH): Remove; now done by attribute.h.
* lib/wordsplit.h (__WORDSPLIT_ATTRIBUTE_FORMAT): Remove;
all uses replaced by ATTRIBUTE_FORMAT.
* lib/wordsplit.h, src/buffer.c, src/common.h, src/compare.c:
* src/sparse.c, src/system.c, src/xheader.c:
Prefer ATTRIBUTE_FORMAT, MAYBE_UNUSED, _Noreturn, etc. to
__attribute__.
2021-03-01 00:18:44 -08:00
Paul Eggert
ace146f6a4 Update paxutils from upstream 2021-03-01 00:18:43 -08:00
Paul Eggert
df6de51574 maint: 1.34 announcement update
Hand-install 1.34 changes into master.
Evidently these changes were not pushed to savannah,
before I installed further changes today.
2021-02-27 18:40:49 -08:00
Paul Eggert
8378991cba maint: port to Fedora 33
Fedora 33 uses GCC 10.2.1, which is a bit pickier.
* configure.ac: Do not use -Wsystem-headers, as this
runs afoul of netdb.h on Fedora 33.
* gnulib.modules: Add ‘attribute’.
* lib/wordsplit.c (wsnode_new): Return the newly allocated
pointer instead of a boolean, to pacify GCC 10.2.1 which otherwise
complains about use of possibly-null pointers.  All uses changed.
* src/buffer.c (try_new_volume): Don’t assume find_next_block succeeds.
(_write_volume_label): Pacify GCC 10.2.1 with an ‘assume’, since
LABEL must be nonnull here.
* src/common.h (FALLTHROUGH): Remove; now in attribute.h.
Include attribute.h, for ATTRIBUTE_NONNULL.
* src/misc.c (assign_string_or_null): New function,
taking over the old role of assign_string.
(assign_string): Assume VALUE is non-null.
(assign_null): New function, taking over the old
role of assign_string when its VALUE was nonnull.
All callers of assign_string changed to use these functions.
(assign_string_n): Clear *STRING if VALUE is null,
to fix a potential double-free.
2021-02-27 16:42:49 -08:00
Paul Eggert
fa6d317bc7 Update gnulib and paxutils from upstream 2021-02-27 16:42:49 -08:00
Pavel Raiskup
beeb19f927 xattrs: fix capabilities root test
Related discussion in the Fedora pull-request:
https://src.fedoraproject.org/rpms/tar/pull-request/8

* tests/capabs_raw01.at: Newer systems (currently e.g. Fedora 34)
print getcap output in format CAP=VAL, not CAP+VAL.
2021-02-08 17:50:31 +02:00
Sergey Poznyakoff
553210d5ad Gracefully handle duplicate symlinks when extracting
If the archive being extracted contains multiple copies
of the same symlink, extract only the first of them and
skip the rest.  The use case is described in

https://lists.gnu.org/archive/html/bug-tar/2021-01/msg00026.html

The bug was introduced by 2d3396c3ea.

* src/extract.c (create_placeholder_file): If placeholder already
exists and is registered in the delayed_link list, return immediately.
2021-02-08 16:15:22 +02:00
Sergey Poznyakoff
ee2ec5ff19 Fix savannah bug #60002
Bug was introduced by commit 34d15af1.

* src/extract.c (prepare_to_extract): When extracting over pipe,
process only regular files.
* tests/extrac24.at: New test case.
* tests/Makefile.am: Add new test case.
* tests/testsuite.at: Likewise.
2021-02-04 16:51:38 +02:00
Sergey Poznyakoff
d9d4435692 Fix memory leak in read_header
Bug reported in https://savannah.gnu.org/bugs/?59897

* src/list.c (read_header): Don't return directly from the loop.
Instead set the status and break.  Return the status.  Free
next_long_name and next_long_link before returning.
2021-01-17 20:41:11 +02:00
Sergey Poznyakoff
2251317e3f Fix improper argument reference.
(bug introduced by 1ff0b63f)

* src/tar.c (parse_default_options): Pass args as is to the argp_parse.
2021-01-17 19:02:47 +02:00
Sergey Poznyakoff
972bebf07e Fix regression itroduced by 66162927.
* src/misc.c (chdir_arg): Initialize the abspath field to NULL.
(tar_getcdpath): Actually initialize the abspath field here.
2021-01-16 14:38:28 +02:00
Sergey Poznyakoff
8e2898ab11 Fixes in the delete_archive_members function
* src/delete.c (delete_archive_members): Clean-up the code. Avoid
entering the loop from the middle.  Free the memory allocated for
current_stat_info.
2021-01-14 09:00:12 +02:00
Sergey Poznyakoff
0b43ea2906 Use stdopen from gnulib
* gnulib.modules: Request stdopen
* lib/Makefile.am: Remove stdopen.c and stdopen.h
* lib/stdopen.c: Remove.
* lib/stdopen.h: Remove.
* src/tar.c: stdopen returns 0 on success.
2021-01-08 18:50:57 +02:00
Sergey Poznyakoff
e4d1edadef Actually prefer /dev/full over /dev/null as a replacement for stdin
* lib/stdopen.c (stdopen): Fix improper condition.
Avoid leaking extra file descriptor.
* src/tar.c (main): Set name of the stdout for diagnostics.
Bail out if stdopen fails.
2021-01-08 17:46:32 +02:00
Sergey Poznyakoff
0836a51147 Version 1.33
* NEWS: Update.
* configure.ac: Raise version number. Require automake 1.15 and
autoconf 2.64.
* gnulib: pull v0.1-4333-g30820c2
* src/names.c: Use hash_remove instead of the deprecated hash_delete.
2021-01-07 16:33:49 +02:00
Sergey Poznyakoff
afa743ac23 Update copyright years 2021-01-06 17:55:16 +02:00
Sergey Poznyakoff
01dd89c121 Fix typo in the manpage
* doc/tar.1: Fix description of the --newer option
2020-07-13 09:01:29 +03:00
Pavel Raiskup
1263f9bc1d Bugfix --sparse --diff mode
Originally reported in:
https://bugzilla.redhat.com/show_bug.cgi?id=1853469

* src/sparse.c (check_data_region): Only compare the part of buffer
really fed by safe_read(), not whole rdsize.
2020-07-10 09:06:42 +03:00
Sergey Poznyakoff
1ff0b63f48 Accept only position-sensitive (file-selection) options in file list files.
Using such options as -f, -z, etc. is senseless in the file list file
and bypasses the option consistency checks in decode_options.  Therefore,
only options related to file selection (a.k.a position-sensitive options)
are allowed in files.

* doc/tar.texi: Document changes.
* src/common.h (tar_args): Move from tar.c
(TAR_ARGS_INITIALIZER): New macro.
* src/names.c: Declare option group identifiers as an enum.
(names_parse_opt): Special handling for ARGP_KEY_ERROR.
(names_argp): Remove static qualifier.
(names_argp_children): Remove.
* src/tar.c: Declare option group identifiers as an enum.
(parse_opt): Special handling for ARGP_KEY_INIT.
(argp_children): New static variable.
(args): Remove static variable.
(more_options): Allow only options from names_argp.
(parse_default_options): Take a pointer to struct tar_args as argument.
Replace the loc member during the call to argp_parse and restore it
afterwards.
(decode_options): Use automatic variable for args.
2020-06-24 16:43:26 +03:00
Sergey Poznyakoff
34d15af170 Fix the logic of prepare_to_extract.
* src/extract.c (prepare_to_extract): Return true to proceed with
the extraction, and false to skip the current member.  If extracting
over a pipe, skip unlinking logic.
(extract_archive): Update accordingly.
2020-06-22 22:17:46 +03:00
Sergey Poznyakoff
63712973c7 Make sure link counting works for file names supplied with -T
* src/common.h (name_count): Remove extern.
(files_count): New enum.
(filename_args): New extern.
* src/names.c (name_count): Remove.
(files_count): New variable.
(name_add_name,name_add_file): Update filename_args.
* src/create.c (create_archive): Set trivial_link_count depending on
the filename_args.
2020-06-15 21:10:46 +03:00
Alfred M. Szmidt
d9ec6f04e2 Remove freemanuals.texi
* doc/Makefile.am (tar_TEXINFOS): Remove freemanuals.texi.
* doc/freemanuals.texi: Delete file.
* doc/tar.texi (Free Software Needs Free Documentation): Remove
appendix.
2020-06-10 21:56:54 +03:00
Sergey Poznyakoff
b5418cd393 Fix typo in docs 2020-06-03 10:55:51 +03:00
Sergey Poznyakoff
615732a804 Bugfix
* src/sparse.c (sparse_diff_file): Fix return value.
2020-06-03 09:31:41 +03:00
Paul Eggert
dd1a6bd37a tar: avoid read overrun
Problem reported by Timotej Kapus in:
https://lists.gnu.org/r/bug-tar/2020-05/msg00001.html
* src/transform.c (parse_transform_expr):
Diagnose ‘--transform='s'’ instead of continuing past '\0'.
2020-05-19 11:52:26 -07:00
Sergey Poznyakoff
41654f91f0 Fix handling of linked rename chains in incremental backups
* src/incremen.c: Change the meaning of the DIRF_RENAMED flag.  Now it
marks a directory which is the last one in a chain of renames.
Regular renamed directories are recognized by their orig member being
non-NULL.  Directories marked with DIRF_RENAMED start encoding of renames.
(procdir): Clear DIRF_RENAMED flag on directories which are origins for
renames.
(makedumpdir): Use the orig member to check if the directory is a
result of a rename.
(store_rename): Move the check for DIR_IS_RENAMED to the caller. Don't
clear the DIRF_RENAMED, it is not needed any more.

* tests/rename06.at: New test.
* tests/Makefile.am: Add rename06.at
* tests/testsuite.at: Likewise.
2020-02-15 11:09:18 +02:00
Sergey Poznyakoff
8d90723d30 Update copyright years 2020-02-08 13:21:13 +02:00
Sergey Poznyakoff
14d8fc718f Fix the --no-overwrite-dir option
Given this option, tar failed to preserve permissions of empty directories
and to create files under directories owned by the current user that did
not have the S_IWUSR bit set.

* src/extract.c (fd_chmod): Rename to fd_i_chmod.
(fd_chmod): New function.
(safe_dir_mode): New function.
(extract_dir): Special handling for existing directories in
--no-overwrite-dir mode.
* tests/extrac23.at: New file.
* tests/Makefile.am: Add new test case.
* tests/testsuite.at: Likewise.
2020-02-08 13:08:20 +02:00
Sergey Poznyakoff
883cc555df Wildcards in exclude-vcs-ignore mode should not match slash
* src/exclist.c (info_attach_exclist): Use the FNM_FILE_NAME flag.
2019-12-03 09:55:02 +02:00
Sergey Poznyakoff
e1005b385d Version 1.32.90 2019-11-27 18:51:58 +02:00
Sergey Poznyakoff
14f00a2c7a Testsuite fixes
* tests/sparse06.at: Skip the test if genfile is unable to create
sparse files.
* tests/sptrcreat.at: Likewise.
* tests/sptrdiff00.at: Likewise.
* tests/sptrdiff01.at: Likewise.
2019-11-25 08:01:04 +02:00
Sergey Poznyakoff
f122fc94a7 Another testsuite fix.
* tests/extrac11.at: Skip test if ulimit fails.
2019-11-14 07:58:17 +02:00
Sergey Poznyakoff
b31afe7cf0 Testsuite fix.
* tests/remfiles10.at: Don't expect EINVAL when trying to remove
CWD.
2019-11-13 08:37:41 +02:00
Sergey Poznyakoff
ea6f84dd40 Consistently use x2realloc for buffer reallocation
* src/create.c (create_archive): Use x2realloc
* src/names.c (copy_name)
(add_hierarchy_to_namelist): Use x2realloc
2019-08-25 14:41:17 +03:00
Sergey Poznyakoff
2d3396c3ea Fix extraction of symbolic links hardlinked to another symbolic links
* src/extract.c (create_placeholder_file): Take additional argument:
the delayed_link entry after which to the newly created one.
(extract_link): Create a placeholder file if the target link name
exists in the delayed_link list.
2019-08-18 23:40:54 +03:00
Sergey Poznyakoff
d70b8b3b39 Fix --delay-directory-restore on archives with reversed member ordering.
* src/extract.c (find_direct_ancestor): Remove useless test.
(delay_set_stat): If the file name being added is already in
the list, update stored data instead of creating a new entry.
This works for archives with reversed order of members.
* tests/extrac22.at: New testcase.
* tests/Makefile.am: Add new testcase.
* tests/testsuite.at: Include new testcase.
2019-04-11 13:45:32 +03:00
Sergey Poznyakoff
c445d99d4f Minor change
* scripts/backup.in: Fix typo
2019-03-28 14:01:58 +02:00
Sergey Poznyakoff
2c9730357f Typesetting fixes in the manpage
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2019-03-28 13:58:44 +02:00
Zachary Vance
ef0f882382 POSIX extended format headers do not include PID by default
The intent is to make binary-equivalent PAX archives easy to create.  If
POSIXLY_CORRECT is set, the POSIX standard default is used, which embeds
the pid.

* src/common.h (posixly_correct): New global.
* src/tar.c (decode_options): Detect the POSIXLY_CORRECT environment
variable.
* src/buffer.c (add_chunk_header): Change filenames of multipart files to
omit the pid.
* src/xheader.c (HEADER_TEMPLATE): New macro.
(xheader_xhdr_name, xheader_ghdr_name): Use HEADER_TEMPLATE to select
the template for the POSIX extended header name.
* doc/tar.texi: Document the change.

Signed-off-by: Zachary Vance <za3k@za3k.com>
2019-03-28 13:37:07 +02:00
Sergey Poznyakoff
66162927eb Check return value from xgetcwd
* src/misc.c (chdir_arg,tar_getcdpath): Check for non-NULL
return from xgetcwd. The function returns NULL for any
error originating from getcwd.
2019-03-03 09:02:20 +02:00
Sergey Poznyakoff
44cfdfb8b6 Version 1.32 2019-02-23 14:54:53 +02:00
Sergey Poznyakoff
97d8951536 Minor fixes in docs.
* doc/tar.1: Remove description of the --preserve option
Document verbosity levels.
* doc/tar.texi: Fix description of the -o option.
2019-02-04 21:30:00 +02:00
Daniel Le
bf5d66109c Fix typos in the documentation
Short option "t" was mistranslated to "--test" instead of "--list" in commit
67cad0792b.
2019-01-15 15:29:03 +02:00
Sergey Poznyakoff
bd1b0fc97c Fix build on AIX
* src/unlink.c (flush_deferred_unlinks): Avoid possible duplicate case
(if ENOTEMPTY==EEXIST)
2019-01-15 15:21:03 +02:00
Sergey Poznyakoff
a7289daf5c Version 1.31.90 2019-01-15 14:38:02 +02:00
Sergey Poznyakoff
72506bddee Ensure gnu format when running checkpoint tests 2019-01-14 23:32:15 +02:00
Sergey Poznyakoff
a311b908c0 Fix compression tests
Existing compression tests used tar with compiled-in defaults. However,
some of the defaults are sure to create archives that are not byte-to-byte
reproducible (e.g. DEFAULT_ARCHIVE_FORMAT=POSIX, because the name field
in posix extended headers uses PID of the creating process by default).
Moreover, some compressors (e.g. gzip) store current timestamp in
the file header when compressing from stdin, so that using cmp on the
two created archives as the tests did is error-prone. Another problem
is that the tests implicitly assumed that tar uses archive suffix to
recognize its format when extracting, which isn't the case. Finally,
there's hardly any reason in using sed to create m4 sources, when
everything can be achieved by m4 itself.

* tests/Makefile.am: Remove generation of compress-*.at files.
* tests/compress.at.in: Remove.
* tests/compress.m4: New file.
* tests/testsuite.at: Include compress.m4, use TAR_CHECK_COMPRESS to
check compression options.
2019-01-14 18:55:43 +02:00
Sergey Poznyakoff
cb07844454 Fix possible NULL dereference (savannah bug #55369)
* src/sparse.c (pax_decode_header): Check return from find_next_block.
2019-01-14 15:22:09 +02:00
Sergey Poznyakoff
2f5a57be4b Fix compilation without iconv. 2019-01-14 14:46:43 +02:00
Sergey Poznyakoff
3da8c2850d Fix iconv usage.
Patch by Christian Weisgerber.

* src/utf8.c (utf8_convert): non-zero return from iconv means failure.
2019-01-14 13:59:39 +02:00
Pavel Raiskup
c697d62598 tests: fix numeric.at for BSD
While creating file, BSD kernels inherit the group ownership from
parent directory.
http://lists.gnu.org/archive/html/bug-tar/2016-06/msg00000.html

* tests/numeric.at: Attempt to 'chown' the newly created directory
to proper group (at least on affected machines that command is
expected to succeed).
2019-01-14 12:54:29 +02:00
Sergey Poznyakoff
b0930da045 Fix typo in manpage. 2019-01-14 12:48:16 +02:00
Sergey Poznyakoff
f86722c34c Fix expected output in dirrem tests.
In both tests, the "file changed as we read it" warning might be
produced for dir/sub, depending on the ctime resolution and timing.
The problem was fixed by 64b43fdf70, but regressed
after e7cd377f78, which removed 1 second
delays between each pair of checkpoints. Since the presense or absense
of this warning is irrelevant for the test, it is now suppressed.

* tests/dirrem01.at: Suppress the file-changed warning.
* tests/dirrem02.at: Likewise.
2019-01-14 12:26:59 +02:00
Sergey Poznyakoff
aa0684ce90 Fix the use of --checkpoint without explicit --checkpoint-action
* src/checkpoint.c (checkpoint_finish_compile): Set default action,
if necessary.
* tests/checkpoint/defaults.at: New testcase.
* tests/checkpoint/dot-compat.at: New testcase.
* tests/checkpoint/dot-int.at: New testcase.
* tests/checkpoint/dot.at: New testcase.
* tests/checkpoint/interval.at: New testcase.
* tests/Makefile.am: Add new testcases.
* tests/testsuite.at Include new testcases.
2019-01-12 10:24:47 +02:00
Sergey Poznyakoff
85c005ee13 Remove erroneous abort() call
The call was introduced by commit ccef8581. It caused tar to abort
on perfectly normal operations, like untarring archives containing
./ with the -U option,

See http://lists.gnu.org/archive/html/bug-tar/2019-01/msg00019.html
for details.

* src/extract.c (maybe_recoverable): Remove misplaced call to abort().
2019-01-10 18:18:49 +02:00
Sergey Poznyakoff
2684c88a49 Version 1.31 2019-01-02 20:20:28 +02:00
Sergey Poznyakoff
1ed62596cf Fix the difflink test
Hardlinking a symlink produces hardlink on BSD and symlink
on GNU/Linux. Avoid the ambiguity.

* tests/difflink.at: Create hard link from a regular file.
2018-12-28 17:53:35 +02:00
Sergey Poznyakoff
9d1993f651 Work over a bug in gnulib error()
The error() function from glibc correctly prefixes each message it
prints with program_name as set by set_program_name. However, its
replacement from gnulib, which is linked in on systems where this
function is not available, prints the name returned by getprogname()
instead. Due to this messages output by tar subprocess (which sets its
program name to 'tar (child)') become indiscernible from those printed
by the main process. In particular, this breaks the remfiles01.at and
remfiles02.at test cases.

* configure.ac: Define ENABLE_ERROR_PRINT_PROGNAME if using
gnulib error().
* src/tar.c [ENABLE_ERROR_PRINT_PROGNAME] (tar_print_progname): New function.
(main) [ENABLE_ERROR_PRINT_PROGNAME]: Set error_print_progname.
2018-12-28 17:49:08 +02:00
Sergey Poznyakoff
e7cd377f78 Implement the "wait" checkpoint action.
This action instructs tar to pause until given signal is delivered.
The newer genfile tool uses this action for communication between
genfile and tar in exec mode. This eliminates race conitions and
speeds up the tests based on exec mode.

* doc/tar.texi: Document changes.
* paxutils: Upgrade.
* src/checkpoint.c: Implement the wait action.
* src/common.h (decode_signal): New proto.
* src/tar.c (decode_signal): New function.
(set_stat_signal): Rewrite.
* tests/dirrem01.at: Adjust genfile and tar command line arguments
to use the new feature.
* tests/dirrem02.at: Likewise.
* tests/filerem01.at: Likewise.
* tests/filerem02.at: Likewise.
* tests/grow.at: Likewise.
* tests/sptrcreat.at: Likewise.
* tests/sptrdiff00.at: Likewise.
* tests/sptrdiff01.at: Likewise.
* tests/truncate.at: Likewise.
2018-12-28 13:27:02 +02:00
Sergey Poznyakoff
c15c42ccd1 Fix CVE-2018-20482
* NEWS: Update.
* src/sparse.c (sparse_dump_region): Handle short read condition.
(sparse_extract_region,check_data_region): Fix dumped_size calculation.
Handle short read condition.
(pax_decode_header): Fix dumped_size calculation.
* tests/Makefile.am: Add new testcases.
* tests/testsuite.at: Likewise.

* tests/sptrcreat.at: New file.
* tests/sptrdiff00.at: New file.
* tests/sptrdiff01.at: New file.
2018-12-27 17:53:38 +02:00
Sergey Poznyakoff
3c2a2cd94d Disallow modifications to the global pax extended header in update mode.
Updating global headers in update mode is not possible, because:

1) If the original archive was not in PAX format, writing the
global header would overwrite first member header (and eventually
data blocks) in the archive.
2) Otherwise, using the --pax-option can make the updated header
occupy more blocks than the original one, which would lead to the
same effect as in 1.

This also fixes
  http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00007.html

* src/xheader.c (xheader_forbid_global): New function.
* src/common.h (xheader_forbid_global): New prototype.
* src/update.c (update_archive): Use xheader_forbid_global, instead
of trying to write global extended header record.
2018-12-21 14:39:49 +02:00
Sergey Poznyakoff
ea3aea06f1 Bugfix
Bug reported in
  http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00014.html

* src/names.c (collect_and_sort_names): Fix iteration over namelist.
2018-12-21 13:54:12 +02:00
Sergey Poznyakoff
983a82a376 Fix semantics of -K used together with explicit member names.
This also fixes the bug reported in
  http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00012.html

* src/common.h (starting_file_option): Describe the variable.
* src/names.c (add_starting_file): New function.
(name_match): Ignore everything before the member indicated by the
--starting-file option
* src/tar.c: Use add_starting_file to handle the -K option.
2018-12-21 13:54:11 +02:00
Sergey Poznyakoff
916fe62ae9 Fix error handling when reading incremental snapshots
Bug reported in
  http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00008.html

* incremen.c (read_incr_db_01): Don't try to continue after errors.
2018-12-21 13:54:11 +02:00
Sergey Poznyakoff
99d415e190 Reject pax options starting with equals sign
Bug reported in
  http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00010.html

* xheader.c (xheader_set_keyword_equal): Bail out if the keyword starts
with =
2018-12-21 13:54:11 +02:00
Sergey Poznyakoff
c7c59b57fa Fix buffer overflow
Bug reported in
  http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00011.html

* src/xheader.c (xheader_format_name): fix length calculation
2018-12-21 13:54:11 +02:00
Sergey Poznyakoff
eae48289c0 Fix improper memory access
Bug reported in
  http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00009.html

* src/transform.c (parse_transform_expr): Check if re is not empty
before accessing its last byte.
2018-12-21 13:54:11 +02:00
Sergey Poznyakoff
62c0c3a780 Fix parsing of ACLs
Text returned by acl_to_text can contain comments (introduced by #).
Strip comments and horizontal tabs prior to storing ACLs in PAX
headers.

* src/xattrs.c (xattrs_acls_cleanup): New function.
(xattrs__acls_get_a,xattrs__acls_get_d): Use xattrs_acls_cleanup.
2018-11-24 22:10:53 +02:00
Sergey Poznyakoff
ba472050da Don't try to read past the end of header string fields
* src/common.h (assign_string_n): New proto.
(ASSIGN_STRING_N): New macro.
* src/misc.c (assign_string_n): New function.
* gnulib.modules: Add strnlen.
* src/buffer.c: Use assign_string_n where appropriate.
* src/list.c: Likewise.
2018-11-24 17:57:32 +02:00
Sergey Poznyakoff
f6e2860e8a Fix verbose ACL listing
* src/xattrs.c (acls_one_line): Advance pos.
(xattrs_print): Insert a comma between ACL and default ACL if both
are non-empty.
2018-11-12 09:17:25 +02:00
Paul Eggert
2777a2bfd9 tar: fix numbered backup bug
* src/misc.c (maybe_backup_file): Pass chdir_fd, not AT_FDCWD,
to find_backup_file_name.  This fixes a bug whereby the wrong
backup file name was chosen for numbered backups.
2018-10-28 16:24:05 -07:00
Paul Eggert
9fc1cb40f9 * src/tar.c (expand_pax_option): Pacify recent GCC. 2018-10-28 16:08:59 -07:00
Paul Eggert
6238296458 build: update gnulib submodule to latest
* src/misc.c (maybe_backup_file): Adjust to Gnulib change.
2018-10-28 16:08:59 -07:00
Sergey Poznyakoff
9042dfc4b1 Minor fixes in wordsplit.c 2018-08-02 16:36:48 +03:00
Paul Eggert
016d6d27d1 build: update gnulib submodule to latest 2018-08-02 00:12:46 -07:00
Sergey Poznyakoff
e54741745c Silence gcc warnings in wordsplit 2018-07-31 16:05:28 +03:00
Sergey Poznyakoff
110e3bd7a6 Fix double-free introduced by 577dc345
* src/utf8.c (utf8_convert): Don't store freed value in *output
2018-07-31 15:57:11 +03:00
Pavel Raiskup
c1b569d9d6 Report race on systems without O_DIRECTORY
* src/names.c (collect_and_sort_names): Report ENOTDIR after
successful fstat() but !S_ISDIR.
2018-07-31 12:13:48 +03:00
Pavel Raiskup
577dc34565 Avoid some resource leaks
* src/incremen.c (store_rename): Free temp_name, leaked before for
each renamed directory with --listed-incremental.
* src/transform.c (add_literal_segment): Tighten arguments by
const.
(parse_transform_expr): Free 'str', leaked storage for each
--transform option before.
* src/utf8.c (utf8_convert): Deallocate buffer for failed iconv()
call so callers don't have to.
2018-07-31 12:06:09 +03:00
Sergey Poznyakoff
c7b3f0217f Sync wordsplit and paxutils with the most recent versions 2018-07-31 11:56:44 +03:00
Paul Eggert
e81c89ddd6 * doc/tar.1: Fix font typo noted by esr. 2018-06-13 15:07:32 -07:00
Paul Eggert
07b0026e5d * doc/tar.1: Don't refer to nonexistent tar(5). 2018-05-16 09:03:47 -07:00
Jim Meyering
b531801d6f --one-top-level: avoid a heap-buffer-overflow
* NEWS: Mention this.
* src/suffix.c (strip_compression_suffix): Fix string comparison guard.
Without this change, some ASAN-enabled test runs would fail with the
following.  Also, strip an additional .tar suffix only if the just-
stripped suffix did not match /^\.t/".

==30815==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000002ed at pc 0x00000049d1f4 bp 0x7ffeb5906d50 sp 0x7ffeb5906500
READ of size 1 at 0x6020000002ed thread T0
SCARINESS: 12 (1-byte-read-heap-buffer-overflow)
    #0 0x49d1f3 in __interceptor_strncmp /j/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:407
    #1 0x5670f3 in strip_compression_suffix /j/tar/src/suffix.c:107
    #2 0x575788 in decode_options /j/tar/src/tar.c:2545
    #3 0x5760c0 in main /j/tar/src/tar.c:2708
    #4 0x7f105090df29 in __libc_start_main ../csu/libc-start.c:308
    #5 0x408629 in _start (/j/tar/src/tar+0x408629)

0x6020000002ed is located 3 bytes to the left of 6-byte region [0x6020000002f0,0x6020000002f6)
allocated by thread T0 here:
    #0 0x4d0710 in __interceptor_malloc /j/gcc/libsanitizer/asan/asan_malloc_linux.cc:86
    #1 0x4908ad in __interceptor_strndup /j/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:326
    #2 0x5cbcbd in xstrndup /j/tar/gnu/xstrndup.c:32
    #3 0x5a325b in base_name /j/tar/gnu/basename.c:57
    #4 0x575772 in decode_options /j/tar/src/tar.c:2544
    #5 0x5760c0 in main /j/tar/src/tar.c:2708
    #6 0x7f105090df29 in __libc_start_main ../csu/libc-start.c:308
2018-04-13 11:05:01 +03:00
Andrew Hounsell
f563b896cc Tiny fix
* doc/snapshot.texi: Fix a typo
* scripts/tar-snapshot-edit: Fix a typo
2018-04-07 11:07:57 +03:00
Jim Meyering
c90c6fee01 tests: avoid test failure with non-ancient autoconf
Running "make check" would fail with this:
  T-nonl.at:30: error: m4_divert_push: cannot change diversion
  to `GROW' inside m4_expand
* tests/T-nonl.at: Use printf in place of AS_ECHO_N.
These days, printf should work for everyone.
2018-04-07 10:58:00 +03:00
Jim Meyering
0a0242582f maint: avoid -Wstringop-truncation warnings from upcoming GCC8
* src/create.c (start_private_header, start_header): Convert
trivial uses of strncpy to memcpy, to avoid warnings like this:
In function 'strncpy',
    inlined from 'start_private_header' at create.c:522:3:
/usr/include/bits/string_fortified.h:106:10: warning: \
  '__builtin_strncpy' output truncated before terminating nul \
  copying 2 bytes from a string of the same length \
  [-Wstringop-truncation]
2018-04-07 10:38:31 +03:00
Jim Meyering
2baa531ce5 maint: avoid -Wstringop-truncation warnings upcoming GCC8
* src/buffer.c (gnu_add_multi_volume_header): Convert a use of
strncpy to memcpy, to avoid this warning:
In function 'strncpy',
    inlined from 'gnu_add_multi_volume_header' at buffer.c:1782:3,
    ...
/usr/include/bits/string_fortified.h:106:10: error: '__builtin_strncpy'\
   specified bound 100 equals destination size \
   [-Werror=stringop-truncation]
2018-04-07 10:37:16 +03:00
Jim Meyering
ccef8581b8 maint: avoid warnings from upcoming GCC8
* src/transform.c (_single_transform_name_to_obstack): Mark with
FALLTHROUGH statement rather than /* FALL THROUGH */ comment.
Only the former works with gcc-8.
* src/extract.c (maybe_recoverable): Call abort to tell gcc-8 that
this code is unreachable.
2018-04-07 10:36:23 +03:00
Sergey Poznyakoff
2d00d8b321 Rewrite struct tm formatting
* src/list.c (tartime): Use strftime instead of manually formatting
fields of the struct tm. This should also suppress some gcc warnings.
2018-04-07 10:33:27 +03:00
Jim Meyering
e8c3f4860d tests: add coverage for new --zstd and all other compression tools
* tests/compress.at.in: New file: template from which each
per-compression-tool test is derived.
* tests/Makefile.am (TESTSUITE_AT): Add it.
(EXTRA_DIST): Add compress.at.in.
(compress-*.at): New rules to generate a file/tests for each compression tool.
* tests/testsuite.at (Compression): Add each of these generated
files in a new section.
* tests/.gitignore: Ignore the new generated files.
2018-04-07 10:32:38 +03:00
Aaron Schrab
00f03498a9 Fix typo 2018-03-18 12:06:36 +02:00
Sergey Poznyakoff
688924d2a8 Version 1.30.90
* NEWS: Update.
* configure.ac: Update.
* THANKS: Add Adam Borowski.
2018-03-18 10:38:16 +02:00
Adam Borowski
3d45373d3b Add support for zstd compression
* configure.ac (zstd): Register compression program.
* doc/tar.1: Mention --zstd.
* doc/tar.texi: Document zstd support.
* src/buffer.c: Register zstd compression.
* src/suffix.c: Add suffixes zst and tzst.
* src/tar.c: New compression option --zstd.
2018-03-18 10:24:13 +02:00
Pavel Raiskup
64b43fdf70 tests: fix race in dirrem01 and dirrem02
Previously the '--checkpoint-action=echo' was triggered after
'--checkpoint-action=sleep=1' - so the order of events *usually*
was (for --format='gnu'):

  ...
  1. checkpoint handler before write of 'dir/sub' member
  2. one-second delay
  3. stderr write: 'tar: Write checkpoint 3'
  4. write the member 'dir/sub' into the archive
  5. check that the member's ctime has not been changed
  6. genfile's detecting 'Write checkpoint', doing unlink
  ...

But sometimes, the genfile was fast enough to win the race and
unlinked the directory before the member was written into the
archive (IOW, the order was 1-2-3-6-4-5).  This led to the
occasional warning 'tar: dir/sub: file changed as we read it'.

Swap the order of 'sleep=1' and 'echo' actions so the genfile
utility has (hopefully) enough time to do the unlink before
writing the file into the archive (enforce 1-2-3-6-4-5 order).

* tests/dirrem01.at: Swap 'sleep=1' and 'echo' actions.
* tests/dirrem02.at: Likewise.
2018-03-18 08:33:03 +02:00
Sergey Poznyakoff
7b8efcc7cb Fix typos in the docs 2018-03-13 22:20:53 +02:00
Sergey Poznyakoff
c13401c0a7 Provide a way to skip tests that create very large files
Define environment variable TARTEST_SKIP_LARGE_FILES=1 in order
to skip tests that require lots of disk space.

* tests/testsuite.at (AT_SKIP_LARGE_FILES): New macro.
* tests/sparse03.at: Mark test with AT_SKIP_LARGE_FILES.
* tests/sparse05.at: Likewise.
* tests/star/pax-big-10g.at: Likewise.
* tests/star/ustar-big-2g.at: Likewise.
* tests/star/ustar-big-8g.at: Likewise.
2018-03-13 21:58:37 +02:00
Sergey Poznyakoff
847a36f064 Testsuite bugfix
* tests/difflink.at: Define order of files within tested archive.
2018-03-13 09:59:11 +02:00
Sergey Poznyakoff
2b7fc4aee9 testsuite: account for absolute file names starting with double slash
* tests/incr08.at: Absolute file names can start with //
* tests/xform03.at: Likewise.
2018-03-13 08:08:44 +02:00
333 changed files with 7856 additions and 4021 deletions

46
.gitignore vendored
View File

@@ -1,30 +1,32 @@
*.a
*.[aios]
*.[gx]z
*.bz2
*.cache
*.diff
*.la
*.lo
*.o
*.orig
*.patch
*.rej
*.so
*DISTFILES
*~
.bootstrap
.deps
.emacs*
.libs
ABOUT-NLS
ChangeLog
INSTALL
Make.rules
.gdbinit
/.bootstrap
/ABOUT-NLS
/ChangeLog
/INSTALL
/Make.rules
/aclocal.m4
/build-aux/
/conf*
!/configure.ac
/gnu/
/m4/
/rmt/
/stamp-h1
Makefile
Makefile.in
aclocal.m4
autom4te.cache
build-aux
build-aux/
config.h
config.h.in
config.log
config.status
configure
gnu
libtool
m4
rmt
stamp-h1
TAGS

View File

@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
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/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View File

@@ -2,7 +2,7 @@ Currently there is just one ChangeLog file for tar, but
there used to be separate ChangeLog files for each subdirectory.
This file records what used to be in those separate files.
Copyright 1989-1997, 2013 Free Software Foundation, Inc.
Copyright 1989-1997, 2013, 2023 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -2,7 +2,8 @@ Currently the ChangeLog is generated automatically from the Git
revision history, but from 1997 to 2009 the ChangeLog file was
maintained by hand, under CVS. This file records the older log.
Copyright 1997-2001, 2003-2009, 2013 Free Software Foundation, Inc.
Copyright 1997-2001, 2003-2009, 2013, 2023 Free Software Foundation,
Inc.
This file is part of GNU tar.

View File

@@ -1,7 +1,6 @@
# Main Makefile for GNU tar.
# Copyright 1994-1997, 1999-2001, 2003, 2007, 2009, 2013-2014, 2016-2017
# Free Software Foundation, Inc.
# Copyright 1994-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.

153
NEWS
View File

@@ -1,5 +1,150 @@
GNU tar NEWS - User visible changes. 2017-12-17
GNU tar NEWS - User visible changes. 2023-07-18
Please send GNU tar bug reports to <bug-tar@gnu.org>
version 1.35 - Sergey Poznyakoff, 2023-07-18
* Fail when building GNU tar, if the platform supports 64-bit time_t
but the build uses only 32-bit time_t.
* Leave the devmajor and devminor fields empty (rather than zero) for
non-special files, as this is more compatible with traditional tar.
* Bug fixes
** Fix interaction of --update with --wildcards.
** When extracting archives into an empty directory, do not create
hard links to files outside that directory.
** Handle partial reads from regular files.
** Warn "file changed as we read it" less often.
Formerly, tar warned if the file's size or ctime changed.
However, this generated a false positive if tar read a file
while another process hard-linked to it, changing its ctime.
Now, tar warns if the file's size, mtime, user ID, group ID,
or mode changes. Although neither heuristic is perfect,
the new one should work better in practice.
** Fix --ignore-failed-read to ignore file-changed read errors
as far as exit status is concerned. You can now suppress file-changed
issues entirely with --ignore-failed-read --warning=no-file-changed.
** Fix --remove-files to not remove a file that changed while we read it.
** Fix --atime-preserve=replace to not fail if there was no need to replace,
either because we did not read the file, or the atime did not change.
** Fix race when creating a parent directory while another process is
also doing so.
** Fix handling of prefix keywords not followed by "." in pax headers.
** Fix handling of out-of-range sparse entries in pax headers.
** Fix handling of --transform='s/s/@/2'.
** Fix treatment of options ending in / in files-from list.
** Fix crash on 'tar --checkpoint-action exec=\"'.
** Fix low-memory crash when reading incremental dumps.
** Fix --exclude-vcs-ignores memory allocation misuse.
version 1.34 - Sergey Poznyakoff, 2021-02-13
* Fix extraction over pipe (savannah bug #60002)
* Fix memory leak in read_header (savannah bug #59897)
* Fix extraction when . and .. are unreadable
See https://lists.gnu.org/archive/html/bug-tar/2021-01/msg00012.html
* Gracefully handle duplicate symlinks when extracting
See https://lists.gnu.org/archive/html/bug-tar/2021-01/msg00026.html
* Re-initialize supplementary groups when switching to user privileges
version 1.33 - Sergey Poznyakoff, 2021-01-07
* POSIX extended format headers do not include PID by default
The intent is to make binary-equivalent PAX archives easy to create. If
POSIXLY_CORRECT is set, the POSIX standard default is used, which embeds
the pid.
* --delay-directory-restore works for archives with reversed member ordering
* Fix extraction of a symbolic link hardlinked to another symbolic link
* Wildcards in exclude-vcs-ignore mode don't match slash
* Fix the --no-overwrite-dir option
Given this option, previous versions of tar failed to preserve
permissions of empty directories and to create files under directories
owned by the current user that did not have the S_IWUSR bit set.
* Fix handling of chained renames in incremental backups
* Link counting works for file names supplied with -T
* Accept only position-sensitive (file-selection) options in file list files.
Using such options as -f, -z, etc. is senseless in a file list file and
bypasses option consistency checks in decode_options. Therefore,
only options related to file selection (a.k.a position-sensitive options)
are allowed in file list files.
version 1.32 - Sergey Poznyakoff, 2019-02-23
* Fix the use of --checkpoint without explicit --checkpoint-action
* Fix extraction with the -U option
See http://lists.gnu.org/archive/html/bug-tar/2019-01/msg00015.html,
for details
* Fix iconv usage on BSD-based systems
* Fix possible NULL dereference (savannah bug #55369)
* Improve the testsuite
version 1.31 - Sergey Poznyakoff, 2019-01-02
* Fix heap-buffer-overrun with --one-top-level.
Bug introduced with the addition of that option in 1.28.
* Support for zstd compression
New option '--zstd' instructs tar to use zstd as compression program.
When listing, extractng and comparing, zstd compressed archives are
recognized automatically.
When '-a' option is in effect, zstd compression is selected if the
destination archive name ends in '.zst' or '.tzst'.
* The -K option interacts properly with member names given in the command line
Names of members to extract can be specified along with the "-K NAME"
option. In this case, tar will extract NAME and those of named members
that appear in the archive after it, which is consistent with the
semantics of the option.
Previous versions of tar extracted NAME, those of named members that
appeared before it, and everything after it.
* Fix CVE-2018-20482
When creating archives with the --sparse option, previous versions of
tar would loop endlessly if a sparse file had been truncated while
being archived.
version 1.30 - Sergey Poznyakoff, 2017-12-17
@@ -42,7 +187,7 @@ causing subsequent link extractions in that directory to fail.
This new warning control option suppresses warning messages about
unreadable files and directories. It has effect only if used together
with the --ignore-failed-read option.
with the --ignore-failed-read option.
* The --warnings=none option now suppresses all warnings
@@ -1641,7 +1786,7 @@ Versions 1.07 back to 1.00 by Jay Fenlason.
Copyright 1994-2001, 2003-2010, 2013-2017 Free Software Foundation, Inc.
Copyright 1994-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -1661,7 +1806,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
Local variables:
mode: outline
paragraph-separate: "[ ]*$"
eval: (add-hook 'write-file-hooks 'time-stamp)
eval: (add-hook 'write-file-functions #'time-stamp nil t)
time-stamp-start: "changes. "
time-stamp-format: "%:y-%02m-%02d"
time-stamp-end: "\n"

3
README
View File

@@ -221,8 +221,7 @@ and share your findings by writing to <bug-tar@gnu.org>.
* Copying
Copyright 1990-1992, 1994, 1997-2001, 2003-2004, 2007, 2012-2014,
2016-2017 Free Software Foundation, Inc.
Copyright 1990-2023 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -3,40 +3,9 @@ This is GNU tar.
This is a *pre-release* version, and not ready for production use yet.
Please send comments and problem reports to <bug-tar@gnu.org>.
If you have taken the sources from CVS you will need the following
packages (or later) to build GNU tar. We don't make any extra effort
to accommodate older versions of these packages, so please make sure
that you have the latest stable version.
- Automake <http://www.gnu.org/software/automake/>
- Autoconf <http://www.gnu.org/software/autoconf/>
- Bison <http://www.gnu.org/software/bison/>
- Gettext <http://www.gnu.org/software/gettext/>
- Gzip <http://www.gnu.org/software/gzip/>
- M4 <http://www.gnu.org/software/m4/>
- Texinfo <http://www.gnu.org/software/texinfo>
- Wget <http://www.gnu.org/software/wget/>
As of this writing, the latest stable version of Gzip is 1.2.4 but we
suggest using test version 1.3.5 (or later, if one becomes available).
Valgrind <http://valgrind.org/> is also highly recommended, if
Valgrind supports your architecture.
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.
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-2017 Free Software Foundation,
Inc.
Copyright 2001-2023 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -8,11 +8,22 @@ tar. We do not make any efforts to accommodate older versions of
these packages, so please make sure that you have the latest stable
version.
- Automake <http://www.gnu.org/software/automake/>
- Autoconf <http://www.gnu.org/software/autoconf/>
- Automake <http://www.gnu.org/software/automake/>
- Bison <http://www.gnu.org/software/bison/>
- M4 <http://www.gnu.org/software/m4/>
- Texinfo <http://www.gnu.org/software/texinfo>
- Gettext <http://www.gnu.org/software/gettext/>
- Git <http://git.or.cz>
- Gzip <http://www.gnu.org/software/gzip/>
- Texinfo <http://www.gnu.org/software/texinfo>
- Wget <http://www.gnu.org/software/wget/>
Up-to-date compilers and libraries are also recommended, for better
static checking. You may be able to use an older compiler by building
with 'make WERROR_CFLAGS='; if so, don't worry about its false alarms.
Valgrind <http://valgrind.org/> is also highly recommended, if
Valgrind supports your architecture.
* Bootstrapping
@@ -34,12 +45,26 @@ 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.
There are lots of options that you may find useful in this case.
See 'bootstrap --help' for a detailed list.
See './bootstrap --help' for a detailed list.
Bootstrapping obtains Gnulib and Paxutils files from their Git
repositories on Savannah. Then, it fetches translations from the
Translation Project, and, finally, it builds files useful for
configuration. Simply running ./bootstrap without arguments should do
in most cases.
The file bootstrap.conf contains bootstrapping configuration.
Several options are provided that modify its behavior.
Run './bootstrap --help' for a list.
To only fetch auxiliary files from the network, run './bootstrap --pull'.
To only generate files such as 'configure', without accessing the
network, run './bootstrap --gen'.
* Copyright information
Copyright 2007-2009, 2013-2017 Free Software Foundation, Inc.
Copyright 2007-2023 Free Software Foundation, Inc.
This file is part of GNU tar.

2
THANKS
View File

@@ -8,6 +8,7 @@ list of these people. Help me keep it complete and exempt of errors.
See various ChangeLogs for a detailed description of contributions.
Aage Robeck aagero@ifi.uio.no
Adam Borowski kilobyte@angband.pl
Adye, TJ (Tim) T.J.Adye@rl.ac.uk
Akiko Matsushita matusita@sra.co.jp
Alan Bawden Alan@lcs.mit.edu
@@ -94,6 +95,7 @@ Christian Laubscher christian.laubscher@tiscalinet.ch
Christian T. Dum ctd@mpe-garching.mpg.de
Christian von Roques roques@pond.sub.org
Christian Wetzel wetzel@phoenix-pacs.de
Christian Weisgerber naddy@mips.inka.de
Christoph Litauer litauer@mailhost.uni-koblenz.de
Christophe Colle colle@krtkg1.rug.ac.be
Christophe Kalt Christophe.Kalt@kbcfp.com

3
TODO
View File

@@ -45,8 +45,7 @@ Suggestions for improving GNU tar.
* Copyright notice
Copyright 2003-2004, 2007, 2013-2014, 2016-2017 Free Software
Foundation, Inc.
Copyright 2003-2023 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-2014, 2016-2017 Free Software Foundation, Inc.
dnl Copyright 2009-2023 Free Software Foundation, Inc.
dnl
dnl This file is part of GNU tar.
dnl
@@ -21,7 +21,7 @@ AC_DEFUN([TAR_COMPR_PROGRAM],[
m4_pushdef([tar_compr_define],translit($1,[a-z+-],[A-ZX_])[_PROGRAM])
m4_pushdef([tar_compr_var],[tar_cv_compressor_]translit($1,[+-],[x_]))
AC_ARG_WITH($1,
AC_HELP_STRING([--with-]$1[=PROG],
AS_HELP_STRING([--with-]$1[=PROG],
[use PROG as ]$1[ compressor program]),
[tar_compr_var=${withval}],
[tar_compr_var=m4_if($2,,$1,$2)])

1704
bootstrap

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,6 @@
# Bootstrap configuration for GNU tar.
# Copyright 2006-2009, 2013-2014, 2016-2017 Free Software Foundation,
# Inc.
# Copyright 2006-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -61,21 +60,19 @@ if [ -r .bootstrap ]; then
eval set -- "`sed 's/#.*$//;/^$/d' .bootstrap | tr '\n' ' '` $*"
fi
test -d m4 || mkdir m4
test -d $source_base || mkdir $source_base
bootstrap_post_pull_hook() {
mkdir -p m4 $source_base
git submodule init
git submodule update
}
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.
# getopt-gnu is for paxutils.
gnulib_modules="$avoided_gnulib_modules
`grep -h '^[^#]' gnulib.modules $PAXUTILS/gnulib.modules`
`grep -h '^[^#]' gnulib.modules`
getopt-gnu
"
# copy_files srcdir dstdir
@@ -101,27 +98,30 @@ copy_files() {
done
}
# Import from paxutils
copy_files ${PAXUTILS} .
copy_files ${PAXUTILS}/am m4
bootstrap_post_import_hook() {
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
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
if [ -d rmt ]; then
:
else
mkdir rmt
fi
# Import from paxutils
copy_files ${PAXUTILS} .
copy_files ${PAXUTILS}/am m4
for dir in doc rmt lib tests
do
copy_files ${PAXUTILS}/$dir $dir
done
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
copy_files ${PAXUTILS}/paxlib lib pax
mkdir -p rmt
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-2017 Free Software Foundation, Inc.
# Copyright 1991, 1994-2010, 2013-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -17,17 +17,17 @@
# 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.30], [bug-tar@gnu.org])
AC_INIT([GNU tar], [1.35], [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 std-options silent-rules])
AC_PREREQ([2.71])
AM_INIT_AUTOMAKE([1.15 gnits tar-ustar dist-bzip2 dist-xz std-options silent-rules])
# Enable silent rules by default:
AM_SILENT_RULES([yes])
AC_PROG_CC_STDC
AC_PROG_CC
AC_EXEEXT
AC_PROG_RANLIB
AC_PROG_YACC
@@ -35,7 +35,6 @@ gl_EARLY
AC_CHECK_TOOLS([AR], [ar])
AC_SYS_LARGEFILE
AC_C_INLINE
AC_CHECK_HEADERS_ONCE(fcntl.h linux/fd.h memory.h net/errno.h \
sgtty.h string.h \
@@ -53,10 +52,14 @@ AC_HEADER_MAJOR
AC_MSG_CHECKING([for st_fstype string in struct stat])
AC_CACHE_VAL(diff_cv_st_fstype_string,
[AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/stat.h>], [struct stat s; s.st_fstype[0] = 'x';],
diff_cv_st_fstype_string=yes,
diff_cv_st_fstype_string=no)])
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <sys/types.h>
#include <sys/stat.h>
]],
[[struct stat s; s.st_fstype[0] = 'x';]])],
[diff_cv_st_fstype_string=yes],
[diff_cv_st_fstype_string=no])])
AC_MSG_RESULT($diff_cv_st_fstype_string)
if test $diff_cv_st_fstype_string = yes; then
AC_DEFINE(HAVE_ST_FSTYPE_STRING, 1,
@@ -102,6 +105,32 @@ gt_TYPE_SSIZE_T
# gnulib modules
gl_INIT
AC_DEFINE([GNULIB_EXCLUDE_SINGLE_THREAD], [1],
[Define if all programs in this package call functions of the Gnulib
'exclude' module only from a single thread.])
AC_DEFINE([GNULIB_MBRTOWC_SINGLE_THREAD], [1],
[Define if all programs in this package call functions of the Gnulib
'mbtowc' module only from a single thread.])
AC_DEFINE([GNULIB_REGEX_SINGLE_THREAD], [1],
[Define if all programs in this package call functions of the Gnulib
'regex' module only from a single thread.])
AC_DEFINE([GNULIB_WCHAR_SINGLE_LOCALE], [1],
[Define if all programs in this package call locale-sensitive functions
like mbrtowc only after setting the locale, and never change the
locale once set.])
if test $ac_cv_lib_error_at_line = no; then
# This means that the error() function is not present in libc, so
# the one from gnulib will be used instead. This function precedes
# error messages it prints with the program name as returned by getprogname()
# call, instead of using the name set by set_program_name.
# Install workaround.
AC_DEFINE([ENABLE_ERROR_PRINT_PROGNAME],[1],
[Enable the use of error_print_progname to print program name with error messages.
See comment to function tar_print_progname in src/tar.c])
fi
# paxutils modules
tar_PAXUTILS
@@ -133,7 +162,7 @@ AC_ARG_ENABLE([gcc-warnings],
gl_gcc_warnings=$enableval],
[gl_gcc_warnings=no
if test -d "$srcdir"/.git; then
gl_GCC_VERSION_IFELSE([4], [6], [gl_gcc_warnings=yes])
gl_GCC_VERSION_IFELSE([11], [2], [gl_gcc_warnings=yes])
fi]
)
@@ -150,6 +179,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 -Wsystem-headers" # Don't let system headers trigger warnings
nw="$nw -Wstack-protector"
gl_MANYWARN_ALL_GCC([ws])
@@ -159,12 +189,11 @@ if test "$gl_gcc_warnings" = yes; then
done
gl_WARN_ADD([-Wno-sign-compare]) # Too many warnings for now
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])
@@ -250,6 +279,7 @@ TAR_COMPR_PROGRAM(lzip)
TAR_COMPR_PROGRAM(lzma)
TAR_COMPR_PROGRAM(lzop)
TAR_COMPR_PROGRAM(xz)
TAR_COMPR_PROGRAM(zstd)
AC_MSG_CHECKING(for default archive format)
@@ -343,7 +373,7 @@ AC_CHECK_TYPE(iconv_t,:,
# Gettext.
AM_GNU_GETTEXT([external], [need-formatstring-macros])
AM_GNU_GETTEXT_VERSION([0.16])
AM_GNU_GETTEXT_VERSION([0.21])
# Initialize the test suite.
AC_CONFIG_TESTDIR(tests)
@@ -353,8 +383,8 @@ AM_MISSING_PROG([AUTOM4TE], [autom4te])
AC_SUBST(BACKUP_LIBEXEC_SCRIPTS)
AC_SUBST(BACKUP_SBIN_SCRIPTS)
AC_ARG_ENABLE(backup-scripts,
AC_HELP_STRING([--enable-backup-scripts],
[Create and install backup and restore scripts]),
AS_HELP_STRING([--enable-backup-scripts],
[Create and install backup and restore scripts]),
[case $enableval in
yes) BACKUP_LIBEXEC_SCRIPTS='$(BACKUP_LIBEXEC_SCRIPTS_LIST)'
BACKUP_SBIN_SCRIPTS='$(BACKUP_SBIN_SCRIPTS_LIST)'
@@ -368,7 +398,7 @@ else
BACKUP_SED_COND='/^\#IF_DATE_FORMAT_OK/,/^\#ELSE_DATE_FORMAT_OK/d;/^\#ENDIF_DATE_FORMAT_OK/d'
fi
AC_OUTPUT([Makefile\
AC_CONFIG_FILES([Makefile\
doc/Makefile\
gnu/Makefile\
lib/Makefile\
@@ -376,3 +406,4 @@ AC_OUTPUT([Makefile\
scripts/Makefile\
rmt/Makefile\
src/Makefile])
AC_OUTPUT

View File

@@ -1,5 +1,5 @@
%%comments:
Copyright 2004, 2013-2014 Free Software Foundation, Inc.
Copyright 2004-2023 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

1
doc/.gitignore vendored
View File

@@ -24,3 +24,4 @@ tar.tp
tar.vr
version.texi
/parse-datetime.texi
/rmt.8

View File

@@ -1,7 +1,6 @@
# Makefile for GNU tar documentation.
# Copyright 1994-1997, 1999-2001, 2003, 2006-2007, 2013-2014, 2016-2017
# Free Software Foundation, Inc.
# Copyright 1994-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -23,7 +22,6 @@ tar_TEXINFOS = \
dumpdir.texi\
tar-snapshot-edit.texi\
fdl.texi\
freemanuals.texi\
genfile.texi\
header.texi\
intern.texi\
@@ -140,9 +138,9 @@ check-docs:
clean-local:
rm -rf manual
GENDOCS=gendocs.sh
GENDOCS=$(srcdir)/gendocs.sh
TEXI2DVI=texi2dvi -t '@set $(RENDITION)' -E
TEXI2DVI=texi2dvi -E
# Make sure you set TEXINPUTS
# Usual value is:
@@ -150,5 +148,8 @@ TEXI2DVI=texi2dvi -t '@set $(RENDITION)' -E
manual:
TEXINPUTS=$(srcdir):$(top_srcdir)/build-tex:$(TEXINPUTS) \
MAKEINFO="$(MAKEINFO) $(MAKEINFOFLAGS)" \
TEXI2DVI="$(TEXI2DVI) -t @finalout" \
TEXI2DVI="$(TEXI2DVI) -t '@set DISTRIB' -t @finalout" \
$(GENDOCS) --texi2html tar 'GNU tar manual'
manual-rebuild: clean-local manual

91
doc/README.manual Normal file
View File

@@ -0,0 +1,91 @@
* Overview
This file is a short instruction for maintainers on how to create and
publish the online version of the Tar Manual.
In the sections below we assume that the tar project has been properly
cloned from the git repo, bootstrapped and configured. We also assume
that top-level directory of the project is the current local directory.
* Creating the web manual
To create the online version of the documentation, run
make -C doc manual-rebuild
This will create the directory doc/manual populated with the tar
documentation files in various formats. If the doc/manual directory
already exists, it will be removed prior to rebuilding.
The command produces very copious output. We advise you to examine it
closely to make sure no error messages slip your attention.
For the completeness sake, there are two more Makefile goals related
to the online manual:
** make -C doc clean-local
Removes the doc/manual directory, if it exists.
** make -C doc manual
Builds the doc/manual, unless it already exists.
* CVS Repository
The online tar manual[1] is a part of tar web pages[2] and is
traditionally maintained in the CVS repository[3]. To publish the
generated documentation, you will need first to check out tar web
pages from the CVS. To do so, run
cvs -z3 -d:ext:<username>@cvs.savannah.gnu.org:/web/tar co tar
where <username> is your user name on Savannah. For the rest of this
document we will assume that the checked out version of the tar web
pages resides in the ~/websrc/tar directory.
If you have already checked out the web pages, be sure to update them
before publishing:
cd ~/websrc/tar
cvs update
* Publishing
To publish the created manual, change to the tar top-level directory
and run:
rsync -avz --exclude CVS --delete manual ~/websrc/tar
This will synchronize the newly created manual pages with the content
of the CVS sandbox. Then, change to the ~/websrc/tar directory and
schedule any removed files for removal and any new files for addition
to the repository:
cvs diff --brief 2>&1 | sed -n 's/.*cannot find //p' | xargs cvs rm
cvs diff --brief 2>&1 | sed -n 's/^? //p' | xargs cvs add
Then commit your changes:
cvs commit
Once the changes are committed to CVS a job is scheduled on the server,
which synchronizes them with the content of the directory served by
the httpd daemon. Normally such synchronization happens within
several seconds from the commit.
For more information about CVS, please see its documentation[4].
* References
[1] https://www.gnu.org/software/tar/manual/
[2] https://www.gnu.org/software/tar/
[3] https://web.cvs.savannah.gnu.org/viewvc/tar/
[4] https://www.nongnu.org/cvs/#documentation
Local Variables:
mode: outline
paragraph-separate: "[ ]*$"
version-control: never
End:

View File

@@ -1,6 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2006-2007, 2014, 2016-2017 Free Software Foundation,
@c Inc.
@c Copyright (C) 2006--2023 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,9 +5,9 @@
@c hence no sectioning command or @node.
@display
Copyright @copyright{} 2000-2002, 2007-2008, 2014, 2016-2017 Free
Software Foundation, Inc.
@uref{http://fsf.org/}
Copyright @copyright{} 2000--2002, 2007--2008, 2022 Free Software
Foundation, Inc.
@uref{https://fsf.org/}
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -98,7 +98,7 @@ format, SGML or XML using a publicly available
DTD, and standard-conforming simple HTML,
PostScript or PDF designed for human modification. Examples
of transparent image formats include PNG, XCF and
JPG. Opaque formats include proprietary formats that can be
JPG@. Opaque formats include proprietary formats that can be
read and edited only by proprietary word processors, SGML or
XML for which the DTD and/or processing tools are
not generally available, and the machine-generated HTML,
@@ -415,7 +415,7 @@ The Free Software Foundation may publish new, revised versions
of the GNU Free Documentation License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns. See
@uref{http://www.gnu.org/copyleft/}.
@uref{https://www.gnu.org/licenses/}.
Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
@@ -482,7 +482,7 @@ license notices just after the title page:
@end smallexample
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
replace the ``with@dots{}Texts.'' line with this:
replace the ``with@dots{}Texts.''@: line with this:
@smallexample
@group
@@ -504,4 +504,3 @@ to permit their use in free software.
@c Local Variables:
@c ispell-local-pdict: "ispell-dict"
@c End:

View File

@@ -1,89 +0,0 @@
@cindex free documentation
The biggest deficiency in the free software community today is not in
the software---it is the lack of good free documentation that we can
include with the free software. Many of our most important
programs do not come with free reference manuals and free introductory
texts. Documentation is an essential part of any software package;
when an important free software package does not come with a free
manual and a free tutorial, that is a major gap. We have many such
gaps today.
Consider Perl, for instance. The tutorial manuals that people
normally use are non-free. How did this come about? Because the
authors of those manuals published them with restrictive terms---no
copying, no modification, source files not available---which exclude
them from the free software world.
That wasn't the first time this sort of thing happened, and it was far
from the last. Many times we have heard a GNU user eagerly describe a
manual that he is writing, his intended contribution to the community,
only to learn that he had ruined everything by signing a publication
contract to make it non-free.
Free documentation, like free software, is a matter of freedom, not
price. The problem with the non-free manual is not that publishers
charge a price for printed copies---that in itself is fine. (The Free
Software Foundation sells printed copies of manuals, too.) The
problem is the restrictions on the use of the manual. Free manuals
are available in source code form, and give you permission to copy and
modify. Non-free manuals do not allow this.
The criteria of freedom for a free manual are roughly the same as for
free software. Redistribution (including the normal kinds of
commercial redistribution) must be permitted, so that the manual can
accompany every copy of the program, both on-line and on paper.
Permission for modification of the technical content is crucial too.
When people modify the software, adding or changing features, if they
are conscientious they will change the manual too---so they can
provide accurate and clear documentation for the modified program. A
manual that leaves you no choice but to write a new manual to document
a changed version of the program is not really available to our
community.
Some kinds of limits on the way modification is handled are
acceptable. For example, requirements to preserve the original
author's copyright notice, the distribution terms, or the list of
authors, are ok. It is also no problem to require modified versions
to include notice that they were modified. Even entire sections that
may not be deleted or changed are acceptable, as long as they deal
with nontechnical topics (like this one). These kinds of restrictions
are acceptable because they don't obstruct the community's normal use
of the manual.
However, it must be possible to modify all the @emph{technical}
content of the manual, and then distribute the result in all the usual
media, through all the usual channels. Otherwise, the restrictions
obstruct the use of the manual, it is not free, and we need another
manual to replace it.
Please spread the word about this issue. Our community continues to
lose manuals to proprietary publishing. If we spread the word that
free software needs free reference manuals and free tutorials, perhaps
the next person who wants to contribute by writing documentation will
realize, before it is too late, that only free manuals contribute to
the free software community.
If you are writing documentation, please insist on publishing it under
the GNU Free Documentation License or another free documentation
license. Remember that this decision requires your approval---you
don't have to let the publisher decide. Some commercial publishers
will use a free license if you insist, but they will not propose the
option; it is up to you to raise the issue and say firmly that this is
what you want. If the publisher you are dealing with refuses, please
try other publishers. If you're not sure whether a proposed license
is free, write to @email{licensing@@gnu.org}.
You can encourage commercial publishers to sell more free, copylefted
manuals and tutorials by buying them, and particularly by buying
copies from the publishers that paid for their writing or for major
improvements. Meanwhile, try to avoid buying non-free documentation
at all. Check the distribution terms of a manual before you buy it,
and insist that whoever seeks your business must respect your freedom.
Check the history of the book, and try reward the publishers that have
paid or pay the authors to work on it.
The Free Software Foundation maintains a list of free documentation
published by other publishers, at
@url{http://www.fsf.org/doc/other-free-books.html}.

512
doc/gendocs.sh Executable file
View File

@@ -0,0 +1,512 @@
#!/bin/sh -e
# gendocs.sh -- generate a GNU manual in many formats. This script is
# mentioned in maintain.texi. See the help message below for usage details.
scriptversion=2021-03-01.13
# Copyright 2003-2023 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 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Original author: Mohit Agarwal.
# Send bug reports and any other correspondence to bug-gnulib@gnu.org.
#
# The latest version of this script, and the companion template, is
# available from the Gnulib repository:
#
# https://git.savannah.gnu.org/cgit/gnulib.git/tree/build-aux/gendocs.sh
# https://git.savannah.gnu.org/cgit/gnulib.git/tree/doc/gendocs_template
# TODO:
# - image importing was only implemented for HTML generated by
# makeinfo. But it should be simple enough to adjust.
# - images are not imported in the source tarball. All the needed
# formats (PDF, PNG, etc.) should be included.
prog=`basename "$0"`
srcdir=`pwd`
scripturl="https://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/gendocs.sh"
templateurl="https://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/gendocs_template"
: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="}
: ${MAKEINFO="makeinfo"}
: ${TEXI2DVI="texi2dvi"}
: ${DOCBOOK2HTML="docbook2html"}
: ${DOCBOOK2PDF="docbook2pdf"}
: ${DOCBOOK2TXT="docbook2txt"}
: ${GENDOCS_TEMPLATE_DIR="."}
: ${PERL='perl'}
: ${TEXI2HTML="texi2html"}
unset CDPATH
unset use_texi2html
MANUAL_TITLE=
PACKAGE=
EMAIL=webmasters@gnu.org # please override with --email
commonarg= # passed to all makeinfo/texi2html invcations.
dirargs= # passed to all tools (-I dir).
dirs= # -I directories.
htmlarg="--css-ref=/software/gnulib/manual.css -c TOP_NODE_UP_URL=/manual"
default_htmlarg=true
infoarg=--no-split
generate_ascii=true
generate_html=true
generate_info=true
generate_tex=true
outdir=manual
source_extra=
split=node
srcfile=
texarg="-t @finalout"
version="gendocs.sh $scriptversion
Copyright 2021 Free Software Foundation, Inc.
There is NO warranty. You may redistribute this software
under the terms of the GNU General Public License.
For more information about these matters, see the files named COPYING."
usage="Usage: $prog [OPTION]... PACKAGE MANUAL-TITLE
Generate output in various formats from PACKAGE.texinfo (or .texi or
.txi) source. See the GNU Maintainers document for a more extensive
discussion:
https://www.gnu.org/prep/maintain_toc.html
Options:
--email ADR use ADR as contact in generated web pages; always give this.
-s SRCFILE read Texinfo from SRCFILE, instead of PACKAGE.{texinfo|texi|txi}
-o OUTDIR write files into OUTDIR, instead of manual/.
-I DIR append DIR to the Texinfo search path.
--common ARG pass ARG in all invocations.
--html ARG pass ARG to makeinfo or texi2html for HTML targets,
instead of '$htmlarg'.
--info ARG pass ARG to makeinfo for Info, instead of --no-split.
--no-ascii skip generating the plain text output.
--no-html skip generating the html output.
--no-info skip generating the info output.
--no-tex skip generating the dvi and pdf output.
--source ARG include ARG in tar archive of sources.
--split HOW make split HTML by node, section, chapter; default node.
--tex ARG pass ARG to texi2dvi for DVI and PDF, instead of -t @finalout.
--texi2html use texi2html to make HTML target, with all split versions.
--docbook convert through DocBook too (xml, txt, html, pdf).
--help display this help and exit successfully.
--version display version information and exit successfully.
Simple example: $prog --email bug-gnu-emacs@gnu.org emacs \"GNU Emacs Manual\"
Typical sequence:
cd PACKAGESOURCE/doc
wget \"$scripturl\"
wget \"$templateurl\"
$prog --email BUGLIST MANUAL \"GNU MANUAL - One-line description\"
Output will be in a new subdirectory \"manual\" (by default;
use -o OUTDIR to override). Move all the new files into your web CVS
tree, as explained in the Web Pages node of maintain.texi.
Please use the --email ADDRESS option so your own bug-reporting
address will be used in the generated HTML pages.
MANUAL-TITLE is included as part of the HTML <title> of the overall
manual/index.html file. It should include the name of the package being
documented. manual/index.html is created by substitution from the file
$GENDOCS_TEMPLATE_DIR/gendocs_template. (Feel free to modify the
generic template for your own purposes.)
If you have several manuals, you'll need to run this script several
times with different MANUAL values, specifying a different output
directory with -o each time. Then write (by hand) an overall index.html
with links to them all.
If a manual's Texinfo sources are spread across several directories,
first copy or symlink all Texinfo sources into a single directory.
(Part of the script's work is to make a tar.gz of the sources.)
As implied above, by default monolithic Info files are generated.
If you want split Info, or other Info options, use --info to override.
You can set the environment variables MAKEINFO, TEXI2DVI, TEXI2HTML,
and PERL to control the programs that get executed, and
GENDOCS_TEMPLATE_DIR to control where the gendocs_template file is
looked for. With --docbook, the environment variables DOCBOOK2HTML,
DOCBOOK2PDF, and DOCBOOK2TXT are also consulted.
By default, makeinfo and texi2dvi are run in the default (English)
locale, since that's the language of most Texinfo manuals. If you
happen to have a non-English manual and non-English web site, see the
SETLANG setting in the source.
Email bug reports or enhancement requests to bug-gnulib@gnu.org.
"
while test $# -gt 0; do
case $1 in
-s) shift; srcfile=$1;;
-o) shift; outdir=$1;;
-I) shift; dirargs="$dirargs -I '$1'"; dirs="$dirs $1";;
--common) shift; commonarg=$1;;
--docbook) docbook=yes;;
--email) shift; EMAIL=$1;;
--html) shift; default_htmlarg=false; htmlarg=$1;;
--info) shift; infoarg=$1;;
--no-ascii) generate_ascii=false;;
--no-html) generate_ascii=false;;
--no-info) generate_info=false;;
--no-tex) generate_tex=false;;
--source) shift; source_extra=$1;;
--split) shift; split=$1;;
--tex) shift; texarg=$1;;
--texi2html) use_texi2html=1;;
--help) echo "$usage"; exit 0;;
--version) echo "$version"; exit 0;;
-*)
echo "$0: Unknown option \`$1'." >&2
echo "$0: Try \`--help' for more information." >&2
exit 1;;
*)
if test -z "$PACKAGE"; then
PACKAGE=$1
elif test -z "$MANUAL_TITLE"; then
MANUAL_TITLE=$1
else
echo "$0: extra non-option argument \`$1'." >&2
exit 1
fi;;
esac
shift
done
# makeinfo uses the dirargs, but texi2dvi doesn't.
commonarg=" $dirargs $commonarg"
# For most of the following, the base name is just $PACKAGE
base=$PACKAGE
if $default_htmlarg && test -n "$use_texi2html"; then
# The legacy texi2html doesn't support TOP_NODE_UP_URL
htmlarg="--css-ref=/software/gnulib/manual.css"
fi
if test -n "$srcfile"; then
# but here, we use the basename of $srcfile
base=`basename "$srcfile"`
case $base in
*.txi|*.texi|*.texinfo) base=`echo "$base"|sed 's/\.[texinfo]*$//'`;;
esac
PACKAGE=$base
elif test -s "$srcdir/$PACKAGE.texinfo"; then
srcfile=$srcdir/$PACKAGE.texinfo
elif test -s "$srcdir/$PACKAGE.texi"; then
srcfile=$srcdir/$PACKAGE.texi
elif test -s "$srcdir/$PACKAGE.txi"; then
srcfile=$srcdir/$PACKAGE.txi
else
echo "$0: cannot find .texinfo or .texi or .txi for $PACKAGE in $srcdir." >&2
exit 1
fi
if test ! -r $GENDOCS_TEMPLATE_DIR/gendocs_template; then
echo "$0: cannot read $GENDOCS_TEMPLATE_DIR/gendocs_template." >&2
echo "$0: it is available from $templateurl." >&2
exit 1
fi
# Function to return size of $1 in something resembling kilobytes.
calcsize()
{
size=`ls -ksl $1 | awk '{print $1}'`
echo $size
}
# copy_images OUTDIR HTML-FILE...
# -------------------------------
# Copy all the images needed by the HTML-FILEs into OUTDIR.
# Look for them in . and the -I directories; this is simpler than what
# makeinfo supports with -I, but hopefully it will suffice.
copy_images()
{
local odir
odir=$1
shift
$PERL -n -e "
BEGIN {
\$me = '$prog';
\$odir = '$odir';
@dirs = qw(. $dirs);
}
" -e '
/<img src="(.*?)"/g && ++$need{$1};
END {
#print "$me: @{[keys %need]}\n"; # for debugging, show images found.
FILE: for my $f (keys %need) {
for my $d (@dirs) {
if (-f "$d/$f") {
use File::Basename;
my $dest = dirname ("$odir/$f");
#
use File::Path;
-d $dest || mkpath ($dest)
|| die "$me: cannot mkdir $dest: $!\n";
#
use File::Copy;
copy ("$d/$f", $dest)
|| die "$me: cannot copy $d/$f to $dest: $!\n";
next FILE;
}
}
die "$me: $ARGV: cannot find image $f\n";
}
}
' -- "$@" || exit 1
}
case $outdir in
/*) abs_outdir=$outdir;;
*) abs_outdir=$srcdir/$outdir;;
esac
echo "Making output for $srcfile"
echo " in `pwd`"
mkdir -p "$outdir/"
#
if $generate_info; then
cmd="$SETLANG $MAKEINFO -o $PACKAGE.info $commonarg $infoarg \"$srcfile\""
echo "Generating info... ($cmd)"
rm -f $PACKAGE.info* # get rid of any strays
eval "$cmd"
tar czf "$outdir/$PACKAGE.info.tar.gz" $PACKAGE.info*
ls -l "$outdir/$PACKAGE.info.tar.gz"
info_tgz_size=`calcsize "$outdir/$PACKAGE.info.tar.gz"`
# do not mv the info files, there's no point in having them available
# separately on the web.
fi # end info
#
if $generate_tex; then
cmd="$SETLANG $TEXI2DVI $dirargs $texarg \"$srcfile\""
printf "\nGenerating dvi... ($cmd)\n"
eval "$cmd"
# compress/finish dvi:
gzip -f -9 $PACKAGE.dvi
dvi_gz_size=`calcsize $PACKAGE.dvi.gz`
mv $PACKAGE.dvi.gz "$outdir/"
ls -l "$outdir/$PACKAGE.dvi.gz"
cmd="$SETLANG $TEXI2DVI --pdf $dirargs $texarg \"$srcfile\""
printf "\nGenerating pdf... ($cmd)\n"
eval "$cmd"
pdf_size=`calcsize $PACKAGE.pdf`
mv $PACKAGE.pdf "$outdir/"
ls -l "$outdir/$PACKAGE.pdf"
fi # end tex (dvi + pdf)
#
if $generate_ascii; then
opt="-o $PACKAGE.txt --no-split --no-headers $commonarg"
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
printf "\nGenerating ascii... ($cmd)\n"
eval "$cmd"
ascii_size=`calcsize $PACKAGE.txt`
gzip -f -9 -c $PACKAGE.txt >"$outdir/$PACKAGE.txt.gz"
ascii_gz_size=`calcsize "$outdir/$PACKAGE.txt.gz"`
mv $PACKAGE.txt "$outdir/"
ls -l "$outdir/$PACKAGE.txt" "$outdir/$PACKAGE.txt.gz"
fi
#
if $generate_html; then
# Split HTML at level $1. Used for texi2html.
html_split()
{
opt="--split=$1 --node-files $commonarg $htmlarg"
cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html $opt \"$srcfile\""
printf "\nGenerating html by $1... ($cmd)\n"
eval "$cmd"
split_html_dir=$PACKAGE.html
(
cd ${split_html_dir} || exit 1
if [ ! -f index.html ]; then
ln -sf ${PACKAGE}.html index.html
fi
tar -czf "$abs_outdir/${PACKAGE}.html_$1.tar.gz" -- *.html
)
eval html_$1_tgz_size=`calcsize "$outdir/${PACKAGE}.html_$1.tar.gz"`
rm -f "$outdir"/html_$1/*.html
mkdir -p "$outdir/html_$1/"
mv ${split_html_dir}/*.html "$outdir/html_$1/"
rmdir ${split_html_dir}
}
if test -z "$use_texi2html"; then
opt="--no-split --html -o $PACKAGE.html $commonarg $htmlarg"
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
printf "\nGenerating monolithic html... ($cmd)\n"
rm -rf $PACKAGE.html # in case a directory is left over
eval "$cmd"
html_mono_size=`calcsize $PACKAGE.html`
gzip -f -9 -c $PACKAGE.html >"$outdir/$PACKAGE.html.gz"
html_mono_gz_size=`calcsize "$outdir/$PACKAGE.html.gz"`
copy_images "$outdir/" $PACKAGE.html
mv $PACKAGE.html "$outdir/"
ls -l "$outdir/$PACKAGE.html" "$outdir/$PACKAGE.html.gz"
# Before Texinfo 5.0, makeinfo did not accept a --split=HOW option,
# it just always split by node. So if we're splitting by node anyway,
# leave it out.
if test "x$split" = xnode; then
split_arg=
else
split_arg=--split=$split
fi
#
opt="--html -o $PACKAGE.html $split_arg $commonarg $htmlarg"
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
printf "\nGenerating html by $split... ($cmd)\n"
eval "$cmd"
split_html_dir=$PACKAGE.html
copy_images $split_html_dir/ $split_html_dir/*.html
(
cd $split_html_dir || exit 1
tar -czf "$abs_outdir/$PACKAGE.html_$split.tar.gz" -- *
)
eval \
html_${split}_tgz_size=`calcsize "$outdir/$PACKAGE.html_$split.tar.gz"`
rm -rf "$outdir/html_$split/"
mv $split_html_dir "$outdir/html_$split/"
du -s "$outdir/html_$split/"
ls -l "$outdir/$PACKAGE.html_$split.tar.gz"
else # use texi2html:
opt="--output $PACKAGE.html $commonarg $htmlarg"
cmd="$SETLANG $TEXI2HTML $opt \"$srcfile\""
printf "\nGenerating monolithic html with texi2html... ($cmd)\n"
rm -rf $PACKAGE.html # in case a directory is left over
eval "$cmd"
html_mono_size=`calcsize $PACKAGE.html`
gzip -f -9 -c $PACKAGE.html >"$outdir/$PACKAGE.html.gz"
html_mono_gz_size=`calcsize "$outdir/$PACKAGE.html.gz"`
mv $PACKAGE.html "$outdir/"
html_split node
html_split chapter
html_split section
fi
fi # end html
#
printf "\nMaking .tar.gz for sources...\n"
d=`dirname $srcfile`
(
cd "$d"
srcfiles=`ls -d *.texinfo *.texi *.txi *.eps $source_extra 2>/dev/null` || true
tar czfh "$abs_outdir/$PACKAGE.texi.tar.gz" $srcfiles
ls -l "$abs_outdir/$PACKAGE.texi.tar.gz"
)
texi_tgz_size=`calcsize "$outdir/$PACKAGE.texi.tar.gz"`
#
# Do everything again through docbook.
if test -n "$docbook"; then
opt="-o - --docbook $commonarg"
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\" >${srcdir}/$PACKAGE-db.xml"
printf "\nGenerating docbook XML... ($cmd)\n"
eval "$cmd"
docbook_xml_size=`calcsize $PACKAGE-db.xml`
gzip -f -9 -c $PACKAGE-db.xml >"$outdir/$PACKAGE-db.xml.gz"
docbook_xml_gz_size=`calcsize "$outdir/$PACKAGE-db.xml.gz"`
mv $PACKAGE-db.xml "$outdir/"
split_html_db_dir=html_node_db
opt="$commonarg -o $split_html_db_dir"
cmd="$DOCBOOK2HTML $opt \"${outdir}/$PACKAGE-db.xml\""
printf "\nGenerating docbook HTML... ($cmd)\n"
eval "$cmd"
(
cd ${split_html_db_dir} || exit 1
tar -czf "$abs_outdir/${PACKAGE}.html_node_db.tar.gz" -- *.html
)
html_node_db_tgz_size=`calcsize "$outdir/${PACKAGE}.html_node_db.tar.gz"`
rm -f "$outdir"/html_node_db/*.html
mkdir -p "$outdir/html_node_db"
mv ${split_html_db_dir}/*.html "$outdir/html_node_db/"
rmdir ${split_html_db_dir}
cmd="$DOCBOOK2TXT \"${outdir}/$PACKAGE-db.xml\""
printf "\nGenerating docbook ASCII... ($cmd)\n"
eval "$cmd"
docbook_ascii_size=`calcsize $PACKAGE-db.txt`
mv $PACKAGE-db.txt "$outdir/"
cmd="$DOCBOOK2PDF \"${outdir}/$PACKAGE-db.xml\""
printf "\nGenerating docbook PDF... ($cmd)\n"
eval "$cmd"
docbook_pdf_size=`calcsize $PACKAGE-db.pdf`
mv $PACKAGE-db.pdf "$outdir/"
fi
#
printf "\nMaking index.html for $PACKAGE...\n"
if test -z "$use_texi2html"; then
CONDS="/%%IF *HTML_SECTION%%/,/%%ENDIF *HTML_SECTION%%/d;\
/%%IF *HTML_CHAPTER%%/,/%%ENDIF *HTML_CHAPTER%%/d"
else
# should take account of --split here.
CONDS="/%%ENDIF.*%%/d;/%%IF *HTML_SECTION%%/d;/%%IF *HTML_CHAPTER%%/d"
fi
curdate=`$SETLANG date '+%B %d, %Y'`
sed \
-e "s!%%TITLE%%!$MANUAL_TITLE!g" \
-e "s!%%EMAIL%%!$EMAIL!g" \
-e "s!%%PACKAGE%%!$PACKAGE!g" \
-e "s!%%DATE%%!$curdate!g" \
-e "s!%%HTML_MONO_SIZE%%!$html_mono_size!g" \
-e "s!%%HTML_MONO_GZ_SIZE%%!$html_mono_gz_size!g" \
-e "s!%%HTML_NODE_TGZ_SIZE%%!$html_node_tgz_size!g" \
-e "s!%%HTML_SECTION_TGZ_SIZE%%!$html_section_tgz_size!g" \
-e "s!%%HTML_CHAPTER_TGZ_SIZE%%!$html_chapter_tgz_size!g" \
-e "s!%%INFO_TGZ_SIZE%%!$info_tgz_size!g" \
-e "s!%%DVI_GZ_SIZE%%!$dvi_gz_size!g" \
-e "s!%%PDF_SIZE%%!$pdf_size!g" \
-e "s!%%ASCII_SIZE%%!$ascii_size!g" \
-e "s!%%ASCII_GZ_SIZE%%!$ascii_gz_size!g" \
-e "s!%%TEXI_TGZ_SIZE%%!$texi_tgz_size!g" \
-e "s!%%DOCBOOK_HTML_NODE_TGZ_SIZE%%!$html_node_db_tgz_size!g" \
-e "s!%%DOCBOOK_ASCII_SIZE%%!$docbook_ascii_size!g" \
-e "s!%%DOCBOOK_PDF_SIZE%%!$docbook_pdf_size!g" \
-e "s!%%DOCBOOK_XML_SIZE%%!$docbook_xml_size!g" \
-e "s!%%DOCBOOK_XML_GZ_SIZE%%!$docbook_xml_gz_size!g" \
-e "s,%%SCRIPTURL%%,$scripturl,g" \
-e "s!%%SCRIPTNAME%%!$prog!g" \
-e "$CONDS" \
$GENDOCS_TEMPLATE_DIR/gendocs_template >"$outdir/index.html"
echo "Done, see $outdir/ subdirectory for new files."
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

174
doc/gendocs_template Executable file → Normal file
View File

@@ -1,125 +1,101 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- $Id: gendocs_template,v 1.5 2007/10/30 14:58:52 gray Exp $ -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<!--#include virtual="/server/header.html" -->
<!-- Parent-Version: 1.78 -->
<head>
<title>%%TITLE%% - GNU Project - Free Software Foundation (FSF)</title>
<meta http-equiv="content-type" content='text/html; charset=utf-8' />
<link rel="stylesheet" type="text/css" href="/gnu.css" />
<link rev="made" href="mailto:gray@gnu.org" />
<link rel="icon" type="image/png" href="/graphics/gnu-head-icon.png" />
</head>
<!--
Copyright (C) 2006-2023 Free Software Foundation, Inc.
<!-- This document is in XML, and xhtml 1.0 -->
<!-- Please make sure to properly nest your tags -->
<!-- and ensure that your final document validates -->
<!-- consistent with W3C xhtml 1.0 and CSS standards -->
<!-- See validator.w3.org -->
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without any warranty.
-->
<body>
<h3>%%TITLE%%</h3>
<title>%%TITLE%% - GNU Project - Free Software Foundation</title>
<!--#include virtual="/server/banner.html" -->
<h2>%%TITLE%%</h2>
<address>Free Software Foundation</address>
<address>last updated %%DATE%%</address>
<p>
<a href="/graphics/gnu-head.jpg">
<img src="/graphics/gnu-head-sm.jpg"
alt=" [image of the head of a GNU] "
width="129" height="122" />
</a>
</p>
<hr />
<p>The manual for %%PACKAGE%% is available in the following formats:</p>
<p>This manual (%%PACKAGE%%) is available in the following formats:</p>
<ul>
<li><a href="%%PACKAGE%%.html">HTML
(%%HTML_MONO_SIZE%%K bytes)</a> - entirely on one web page.</li>
<li><a href="html_node/index.html">HTML</a> - with one web page per
node.</li>
<li><a href="%%PACKAGE%%.html">HTML
(%%HTML_MONO_SIZE%%K bytes)</a> - entirely on one web page.</li>
<li><a href="html_node/index.html">HTML</a> - with one web page per
node.</li>
%%IF HTML_SECTION%%
<li><a href="html_section/index.html">HTML</a> - with one web page per
section.</li>
<li><a href="html_section/index.html">HTML</a> - with one web page per
section.</li>
%%ENDIF HTML_SECTION%%
%%IF HTML_CHAPTER%%
<li><a href="html_chapter/index.html">HTML</a> - with one web page per
chapter.</li>
<li><a href="html_chapter/index.html">HTML</a> - with one web page per
chapter.</li>
%%ENDIF HTML_CHAPTER%%
<li><a href="%%PACKAGE%%.html.gz">HTML compressed
(%%HTML_MONO_GZ_SIZE%%K gzipped characters)</a> - entirely on
one web page.</li>
<li><a href="%%PACKAGE%%.html_node.tar.gz">HTML compressed
(%%HTML_NODE_TGZ_SIZE%%K gzipped tar file)</a> -
with one web page per node.</li>
<li><a href="%%PACKAGE%%.html.gz">HTML compressed
(%%HTML_MONO_GZ_SIZE%%K gzipped characters)</a> - entirely on
one web page.</li>
<li><a href="%%PACKAGE%%.html_node.tar.gz">HTML compressed
(%%HTML_NODE_TGZ_SIZE%%K gzipped tar file)</a> -
with one web page per node.</li>
%%IF HTML_SECTION%%
<li><a href="%%PACKAGE%%.html_section.tar.gz">HTML compressed
(%%HTML_SECTION_TGZ_SIZE%%K gzipped tar file)</a> -
with one web page per section.</li>
<li><a href="%%PACKAGE%%.html_section.tar.gz">HTML compressed
(%%HTML_SECTION_TGZ_SIZE%%K gzipped tar file)</a> -
with one web page per section.</li>
%%ENDIF HTML_SECTION%%
%%IF HTML_CHAPTER%%
<li><a href="%%PACKAGE%%.html_chapter.tar.gz">HTML compressed
(%%HTML_CHAPTER_TGZ_SIZE%%K gzipped tar file)</a> -
with one web page per chapter.</li>
<li><a href="%%PACKAGE%%.html_chapter.tar.gz">HTML compressed
(%%HTML_CHAPTER_TGZ_SIZE%%K gzipped tar file)</a> -
with one web page per chapter.</li>
%%ENDIF HTML_CHAPTER%%
<li><a href="%%PACKAGE%%.info.tar.gz">Info document
(%%INFO_TGZ_SIZE%%K characters gzipped tar file)</a>.</li>
<li><a href="%%PACKAGE%%.txt">ASCII text
(%%ASCII_SIZE%%K characters)</a>.</li>
<li><a href="%%PACKAGE%%.txt.gz">ASCII text compressed
(%%ASCII_GZ_SIZE%%K gzipped characters)</a>.</li>
<li><a href="%%PACKAGE%%.dvi.gz">TeX dvi file
(%%DVI_GZ_SIZE%%K characters gzipped)</a>.</li>
<li><a href="%%PACKAGE%%.ps.gz">PostScript file
(%%PS_GZ_SIZE%%K characters gzipped)</a>.</li>
<li><a href="%%PACKAGE%%.pdf">PDF file
(%%PDF_SIZE%%K characters)</a>.</li>
<li><a href="%%PACKAGE%%.texi.tar.gz">Texinfo source
(%%TEXI_TGZ_SIZE%%K characters gzipped tar file)</a></li>
<li><a href="%%PACKAGE%%.info.tar.gz">Info document
(%%INFO_TGZ_SIZE%%K bytes gzipped tar file)</a>.</li>
<li><a href="%%PACKAGE%%.txt">ASCII text
(%%ASCII_SIZE%%K bytes)</a>.</li>
<li><a href="%%PACKAGE%%.txt.gz">ASCII text compressed
(%%ASCII_GZ_SIZE%%K bytes gzipped)</a>.</li>
<li><a href="%%PACKAGE%%.dvi.gz">TeX dvi file
(%%DVI_GZ_SIZE%%K bytes gzipped)</a>.</li>
<li><a href="%%PACKAGE%%.pdf">PDF file
(%%PDF_SIZE%%K bytes)</a>.</li>
<li><a href="%%PACKAGE%%.texi.tar.gz">Texinfo source
(%%TEXI_TGZ_SIZE%%K bytes gzipped tar file).</a></li>
</ul>
<p>(This page generated by the <a
href="%%SCRIPTURL%%">%%SCRIPTNAME%%</a> script.)
</p>
<p>You can <a href="https://shop.fsf.org/">buy printed copies of
some manuals</a> (among other items) from the Free Software Foundation;
this helps support FSF activities.</p>
<p>
<a href="http://validator.w3.org/check?uri=referer"><img
src="http://www.w3.org/Icons/valid-xhtml10"
alt="Valid XHTML 1.0!" height="31" width="88" /></a>
</p>
<p>(This page generated by the <a href="%%SCRIPTURL%%">%%SCRIPTNAME%%
script</a>.)</p>
<div class="copyright">
<p>
Return to the <a href="/home.html">GNU Project home page</a>.
</p>
<!-- If needed, change the copyright block at the bottom. In general,
all pages on the GNU web server should have the section about
verbatim copying. Please do NOT remove this without talking
with the webmasters first.
Please make sure the copyright date is consistent with the document
and that it is like this: "2001, 2002", not this: "2001-2002". -->
</div><!-- for id="content", starts in the include above -->
<!--#include virtual="/server/footer.html" -->
<div id="footer">
<div class="unprintable">
<p>
Please send FSF &amp; GNU inquiries to
<a href="mailto:gnu@gnu.org"><em>gnu@gnu.org</em></a>.
There are also <a href="/home.html#ContactInfo">other ways to contact</a>
the FSF.
<br />
Please send broken links and other corrections (or suggestions) to
<a href="mailto:webmasters@gnu.org"><em>webmasters@gnu.org</em></a>.
</p>
<p>
Copyright 2004, 2013-2014, 2016-2017 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02111, USA
<br />
Verbatim copying and distribution of this entire article is
permitted in any medium, provided this notice is preserved.
</p>
<p>
Updated:
<!-- timestamp start -->
$Date: 2007/10/30 14:58:52 $ $Author: gray $
<!-- timestamp end -->
</p>
<p>Please send general FSF &amp; GNU inquiries to
<a href="mailto:gnu@gnu.org">&lt;gnu@gnu.org&gt;</a>.
There are also <a href="/contact/">other ways to contact</a>
the FSF. Broken links and other corrections or suggestions can be sent
to <a href="mailto:%%EMAIL%%">&lt;%%EMAIL%%&gt;</a>.</p>
</div>
<p>Copyright &copy; 2020 Free Software Foundation, Inc.</p>
<p>This page is licensed under a <a rel="license"
href="https://creativecommons.org/licenses/by-nd/3.0/us/">Creative
Commons Attribution-NoDerivs 3.0 United States License</a>.</p>
<!--#include virtual="/server/bottom-notes.html" -->
</div>
</div>
</body>
</html>

View File

@@ -1,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2006, 2014, 2016-2017 Free Software Foundation, Inc.
@c Copyright (C) 2006--2023 Free Software Foundation, Inc.
@c This file is distributed under GFDL 1.1 or any later version
@c published by the Free Software Foundation.
@@ -13,7 +13,7 @@
@node Standard
@unnumberedsec Basic Tar Format
@UNREVISED
@UNREVISED{}
While an archive may contain many files, the archive itself is a
single ordinary file. Like any other file, an archive file can be
@@ -51,7 +51,10 @@ of the file. At the end of the archive file there are two 512-byte blocks
filled with binary zeros as an end-of-file marker. A reasonable system
should write such end-of-file marker at the end of an archive, but
must not assume that such a block exists when reading an archive. In
particular @GNUTAR{} always issues a warning if it does not encounter it.
particular, @GNUTAR{} does not treat missing end-of-file marker as an
error and silently ignores the fact. You can instruct it to issue
a warning, however, by using the @option{--warning=missing-zero-blocks}
option (@pxref{General Warnings, missing-zero-blocks}).
The blocks may be @dfn{blocked} for physical I/O operations.
Each record of @var{n} blocks (where @var{n} is set by the
@@ -111,8 +114,9 @@ The @code{uid} and @code{gid} fields are the numeric user and group
not support numeric user or group @acronym{ID}s, these fields should
be ignored.
The @code{size} field is the size of the file in bytes; linked files
are archived with this field specified as zero.
The @code{size} field is the size of the file in bytes; for archive
members that are symbolic or hard links to another file, this field
is specified as zero.
The @code{mtime} field represents the data modification time of the file at
the time it was archived. It represents the integer number of
@@ -123,7 +127,7 @@ the simple sum of all bytes in the header block. Each 8-bit
byte in the header is added to an unsigned integer, initialized to
zero, the precision of which shall be no less than seventeen bits.
When calculating the checksum, the @code{chksum} field is treated as
if it were all blanks.
if it were filled with spaces (ASCII 32).
The @code{typeflag} field specifies the type of file archived. If a
particular implementation does not recognize or permit the specified
@@ -266,7 +270,7 @@ IEEE Std 1003.2-1992, pages 380-388 (section 4.48) and pages 936-940
@node Extensions
@unnumberedsec @acronym{GNU} Extensions to the Archive Format
@UNREVISED
@UNREVISED{}
The @acronym{GNU} format uses additional file types to describe new types of
files in an archive. These are listed below.

View File

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

View File

@@ -1,5 +1,5 @@
@c This is part of the GNU tar manual.
@c Copyright (C) 2017 Free Software Foundation, Inc.
@c Copyright (C) 2017--2023 Free Software Foundation, Inc.
@c This file is distributed under GFDL 1.3 or any later version
@c published by the Free Software Foundation.

View File

@@ -1,6 +1,5 @@
@c This is part of GNU tar manual.
@c Copyright 1992, 1994-1997, 1999-2004, 2006, 2013-2014, 2016-2017 Free
@c Software Foundation, Inc.
@c Copyright 1992--2023 Free 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,6 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2005, 2007, 2014, 2016-2017 Free Software Foundation,
@c Inc.
@c Copyright (C) 2005--2023 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.
@@ -147,7 +146,7 @@ is compiled. To see the specific ranges allowed for a particular
@option{--show-snapshot-field-ranges} option:
@smallexample
$ @kbd{tar --show-shapshot-field-ranges}
$ @kbd{tar --show-snapshot-field-ranges}
This tar's snapshot file field ranges are
(field name => [ min, max ]):

View File

@@ -1,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2006, 2014, 2016-2017 Free Software Foundation, Inc.
@c Copyright (C) 2006--2023 Free Software Foundation, Inc.
@c This file is distributed under GFDL 1.1 or any later version
@c published by the Free Software Foundation.
@@ -218,12 +218,12 @@ The real name of the sparse file is stored in the variable
variable @code{GNU.sparse.realsize}.
The sparse map itself is stored in the file data block, preceding the actual
file data. It consists of a series of octal numbers of arbitrary length, delimited
file data. It consists of a series of decimal numbers delimited
by newlines. The map is padded with nulls to the nearest block boundary.
The first number gives the number of entries in the map. Following are map entries,
each one consisting of two numbers giving the offset and size of the
data block it describes.
The first number gives the number of entries in the map. Following are
map entries, each one consisting of two numbers giving the offset and
size of the data block it describes.
The format is designed in such a way that non-posix aware @command{tar}s and @command{tar}s not
supporting @code{GNU.sparse.*} keywords will extract each sparse file

View File

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

154
doc/tar.1
View File

@@ -1,5 +1,5 @@
.\" This file is part of GNU tar. -*- nroff -*-
.\" Copyright 2013-2014, 2016-2017 Free Software Foundation, Inc.
.\" Copyright 2013-2023 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
@@ -13,7 +13,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
.TH TAR 1 "November 16, 2017" "TAR" "GNU TAR Manual"
.TH TAR 1 "July 11, 2022" "TAR" "GNU TAR Manual"
.SH NAME
tar \- an archiving utility
.SH SYNOPSIS
@@ -22,22 +22,22 @@ tar \- an archiving utility
[\fBGnSkUWOmpsMBiajJzZhPlRvwo\fR] [\fIARG\fR...]
.SS UNIX-style usage
.sp
\fBtar\fR \fB\-A\fR [\fIOPTIONS\fR] \fIARCHIVE\fR \fIARCHIVE\fR
\fBtar\fR \fB\-A\fR [\fIOPTIONS\fR] \fB\-f\fR \fIARCHIVE\fR \fIARCHIVE\fR...
.sp
\fBtar\fR \fB\-c\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIFILE\fR...]
.sp
\fBtar\fR \fB\-d\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIFILE\fR...]
.sp
\fBtar\fR \fB\-t\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIMEMBER\fR...]
.sp
\fBtar\fR \fB\-r\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIFILE\fR...]
.sp
\fBtar\fR \fB\-t\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIMEMBER\fR...]
.sp
\fBtar\fR \fB\-u\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIFILE\fR...]
.sp
\fBtar\fR \fB\-x\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIMEMBER\fR...]
.SS GNU-style usage
.sp
\fBtar\fR {\fB\-\-catenate\fR|\fB\-\-concatenate\fR} [\fIOPTIONS\fR] \fIARCHIVE\fR \fIARCHIVE\fR
\fBtar\fR {\fB\-\-catenate\fR|\fB\-\-concatenate\fR} [\fIOPTIONS\fR] \fB\-\-file\fR \fIARCHIVE\fR \fIARCHIVE\fR...
.sp
\fBtar\fR \fB\-\-create\fR [\fB\-\-file\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIFILE\fR...]
.sp
@@ -45,17 +45,15 @@ tar \- an archiving utility
.sp
\fBtar\fR \fB\-\-delete\fR [\fB\-\-file\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIMEMBER\fR...]
.sp
\fBtar\fR \fB\-\-append\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIFILE\fR...]
\fBtar\fR \fB\-\-append\fR [\fB\-\-file\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIFILE\fR...]
.sp
\fBtar\fR \fB\-\-list\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIMEMBER\fR...]
\fBtar\fR \fB\-\-list\fR [\fB\-\-file\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIMEMBER\fR...]
.sp
\fBtar\fR \fB\-\-test\-label\fR [\fB\-\-file\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fILABEL\fR...]
.sp
\fBtar\fR \fB\-\-update\fR [\fB\-\-file\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIFILE\fR...]
.sp
\fBtar\fR \fB\-\-update\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIFILE\fR...]
.sp
\fBtar\fR {\fB\-\-extract\fR|\fB\-\-get\fR} [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIMEMBER\fR...]
\fBtar\fR {\fB\-\-extract\fR|\fB\-\-get\fR} [\fB\-\-file\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIMEMBER\fR...]
.SH NOTE
This manpage is a short description of GNU \fBtar\fR. For a detailed
discussion, including examples and usage recommendations, refer to the
@@ -74,7 +72,7 @@ You can also view the manual using the info mode in
or find it in various formats online at
.PP
.RS +4
.B http://www.gnu.org/software/tar/manual
.B https://www.gnu.org/software/tar/manual
.RE
.PP
If any discrepancies occur between this manpage and the
@@ -97,8 +95,8 @@ In
the first argument is a cluster of option letters and all subsequent
arguments supply arguments to those options that require them. The
arguments are read in the same order as the option letters. Any
command line words that remain after all options has been processed
are treated as non-optional arguments: file or archive member names.
command line words that remain after all options have been processed
are treated as non-option arguments: file or archive member names.
.PP
For example, the \fBc\fR option requires creating the archive, the
\fBv\fR option requests the verbose operation, and the \fBf\fR option
@@ -107,25 +105,25 @@ The following command, written in the traditional style, instructs tar
to store all files from the directory
.B /etc
into the archive file
.B etc.tar
.BR etc.tar ,
verbosely listing the files being archived:
.PP
.EX
.B tar cfv a.tar /etc
tar cfv etc.tar /etc
.EE
.PP
In
.BR "UNIX " or " short-option style" ,
each option letter is prefixed with a single dash, as in other command
line utilities. If an option takes argument, the argument follows it,
line utilities. If an option takes an argument, the argument follows it,
either as a separate command line word, or immediately following the
option. However, if the option takes an \fBoptional\fR argument, the
argument must follow the option letter without any intervening
whitespace, as in \fB\-g/tmp/snar.db\fR.
.PP
Any number of options not taking arguments can be
clustered together after a single dash, e.g. \fB\-vkp\fR. Options
that take arguments (whether mandatory or optional), can appear at
clustered together after a single dash, e.g. \fB\-vkp\fR. An option
that takes an argument (whether mandatory or optional) can appear at
the end of such a cluster, e.g. \fB\-vkpf a.tar\fR.
.PP
The example command above written in the
@@ -133,9 +131,11 @@ The example command above written in the
could look like:
.PP
.EX
.B tar -cvf a.tar /etc
tar -cvf etc.tar /etc
.EE
or
.B tar -c -v -f a.tar /etc
.EX
tar -c -v -f etc.tar /etc
.EE
.PP
In
@@ -152,11 +152,11 @@ method.
Here are several ways of writing the example command in this style:
.PP
.EX
.B tar --create --file a.tar --verbose /etc
tar --create --file etc.tar --verbose /etc
.EE
or (abbreviating some options):
.EX
.B tar --cre --file=a.tar --verb /etc
tar --cre --file=etc.tar --verb /etc
.EE
.PP
The options in all three styles can be intermixed, although doing so
@@ -164,17 +164,17 @@ with old options is not encouraged.
.SS Operation mode
The options listed in the table below tell GNU \fBtar\fR what
operation it is to perform. Exactly one of them must be given.
Meaning of non-optional arguments depends on the operation mode
The meaning of non-option arguments depends on the operation mode
requested.
.TP
\fB\-A\fR, \fB\-\-catenate\fR, \fB\-\-concatenate\fR
Append archive to the end of another archive. The arguments are
Append archives to the end of another archive. The arguments are
treated as the names of archives to append. All archives must be of
the same format as the archive they are appended to, otherwise the
resulting archive might be unusable with non-GNU implementations of
\fBtar\fR. Notice also that when more than one archive is given, the
members from archives other than the first one will be accessible in
the resulting archive only if using the \fB\-i\fR
the resulting archive only when using the \fB\-i\fR
(\fB\-\-ignore\-zeros\fR) option.
Compressed archives cannot be concatenated.
@@ -218,7 +218,7 @@ There is no short option equivalent for this option.
.TP
\fB\-u\fR, \fB\-\-update\fR
Append files which are newer than the corresponding copy in the
archive. Arguments have the same meaning as with \fB\-c\fR and
archive. Arguments have the same meaning as with the \fB\-c\fR and
\fB\-r\fR options. Notice, that newer files don't replace their
old archive copies, but instead are appended to the end of archive.
The resulting archive can thus contain several members of the
@@ -230,14 +230,13 @@ they specify names of the archive members to be extracted.
.TP
.TP
\fB\-\-show\-defaults\fR
Show built-in defaults for various \fBtar\fR options and exit. No
arguments are allowed.
Show built-in defaults for various \fBtar\fR options and exit.
.TP
\fB\-?\fR, \fB\-\-help
Display a short option summary and exit. No arguments allowed.
Display a short option summary and exit.
.TP
\fB\-\-usage\fR
Display a list of available options and exit. No arguments allowed.
Display a list of available options and exit.
.TP
\fB\-\-version\fR
Print program version and copyright information and exit.
@@ -249,16 +248,15 @@ Check device numbers when creating incremental archives (default).
.TP
\fB\-g\fR, \fB\-\-listed\-incremental\fR=\fIFILE\fR
Handle new GNU-format incremental backups. \fIFILE\fR is the name of
a \fBsnapshot file\fR, where tar stores additional information which
a \fBsnapshot file\fR, where \fBtar\fR stores additional information which
is used to decide which files changed since the previous incremental
dump and, consequently, must be dumped again. If \fIFILE\fR does not
exist when creating an archive, it will be created and all files will
be added to the resulting archive (the \fBlevel 0\fR dump). To create
incremental archives of non-zero level \fBN\fR, create a copy of the
snapshot file created during the level \fBN-1\fR, and use it as
\fIFILE\fR.
incremental archives of non-zero level \fBN\fR, you need a copy of the
snapshot file created for level \fBN-1\fR, and use it as \fIFILE\fR.
When listing or extracting, the actual contents of \fIFILE\fR is not
When listing or extracting, the actual content of \fIFILE\fR is not
inspected, it is needed only due to syntactical requirements. It is
therefore common practice to use \fB/dev/null\fR in its place.
.TP
@@ -275,7 +273,7 @@ Handle old GNU-format incremental backups.
Do not exit with nonzero on unreadable files.
.TP
\fB\-\-level\fR=\fINUMBER\fR
Set dump level for created listed-incremental archive. Currently only
Set dump level for a created listed-incremental archive. Currently only
\fB\-\-level=0\fR is meaningful: it instructs \fBtar\fR to truncate
the snapshot file before dumping, thereby forcing a level 0 dump.
.TP
@@ -287,7 +285,7 @@ effect only if the archive is open for reading (e.g. with
.B \-\-list
or
.B \-\-extract
options).
options).
.TP
\fB\-\-no\-check\-device\fR
Do not check device numbers when creating incremental archives.
@@ -307,7 +305,7 @@ either on the command line or via the \fB\-T\fR option. The default
Disable the use of some potentially harmful options.
.TP
\fB\-\-sparse\-version\fR=\fIMAJOR\fR[.\fIMINOR\fR]
Set version of the sparse format to use (implies \fB\-\-sparse\fR).
Set which version of the sparse format to use.
This option implies
.BR \-\-sparse .
Valid argument values are
@@ -315,7 +313,7 @@ Valid argument values are
.BR 0.1 ", and"
.BR 1.0 .
For a detailed discussion of sparse formats, refer to the \fBGNU Tar
Manual\fR, appendix \fBD\fR, "\fBSparse Formats\fR". Using \fBinfo\fR
Manual\fR, appendix \fBD\fR, "\fBSparse Formats\fR". Using the \fBinfo\fR
reader, it can be accessed running the following command:
.BR "info tar 'Sparse Formats'" .
.TP
@@ -370,7 +368,6 @@ Verify the archive after writing it.
.SS Output stream selection
.TP
\fB\-\-ignore\-command\-error\fR
.TP
Ignore subprocess exit codes.
.TP
\fB\-\-no\-ignore\-command\-error\fR
@@ -383,7 +380,7 @@ Extract files to standard output.
Pipe extracted files to \fICOMMAND\fR. The argument is the pathname
of an external program, optionally with command line arguments. The
program will be invoked and the contents of the file being extracted
supplied to it on its standard output. Additional data will be
supplied to it on its standard input. Additional data will be
supplied via the following environment variables:
.RS
.TP
@@ -463,16 +460,17 @@ Format of the archive being processed. One of:
.BR posix ,
.BR ustar ,
.BR v7 .
.TP
.B TAR_SUBCOMMAND
A short option (with a leading dash) describing the operation \fBtar\fR is
executing.
executing.
.RE
.SS Handling of file attributes
.TP
\fB\-\-atime\-preserve\fR[=\fIMETHOD\fR]
Preserve access times on dumped files, either by restoring the times
after reading (\fIMETHOD\fR=\fBreplace\fR, this is the default) or by
not setting the times in the first place (\fIMETHOD\fR=\fBsystem\fR)
not setting the times in the first place (\fIMETHOD\fR=\fBsystem\fR).
.TP
\fB\-\-delay\-directory\-restore\fR
Delay setting modification times and permissions of extracted
@@ -560,17 +558,16 @@ As a result, each input file owned by \fIOLDUSR\fR will be
stored in archive with owner name \fINEWUSR\fR and UID \fINEWUID\fR.
.TP
\fB\-p\fR, \fB\-\-preserve\-permissions\fR, \fB\-\-same\-permissions\fR
extract information about file permissions (default for superuser)
.TP
\fB\-\-preserve\fR
Same as both \fB\-p\fR and \fB\-s\fR.
Set permissions of extracted files to those recorded in the archive
(default for superuser).
.TP
\fB\-\-same\-owner\fR
Try extracting files with the same ownership as exists in the archive
(default for superuser).
.TP
\fB\-s\fR, \fB\-\-preserve\-order\fR, \fB\-\-same\-order\fR
Sort names to extract to match archive
Tell \fBtar\fR that the list of file names to process is sorted in the
same order as the files in the archive.
.TP
\fB\-\-sort=\fIORDER\fR
When creating an archive, sort directory entries according to
@@ -610,13 +607,13 @@ Enable extended attributes support.
Disable extended attributes support.
.TP
.BI \-\-xattrs\-exclude= PATTERN
Specify the exclude pattern for xattr keys. \fIPATTERN\fR is a POSIX
regular expression, e.g. \fB\-\-xattrs\-exclude='^user\.'\fR, to exclude
Specify the exclude pattern for xattr keys. \fIPATTERN\fR is a globbing
pattern, e.g. \fB\-\-xattrs\-exclude='user.*'\fR to include only
attributes from the user namespace.
.TP
.BI \-\-xattrs\-include= PATTERN
Specify the include pattern for xattr keys. \fIPATTERN\fR is a POSIX
regular expression.
Specify the include pattern for xattr keys. \fIPATTERN\fR is a globbing
pattern.
.SS Device selection and switching
.TP
\fB\-f\fR, \fB\-\-file\fR=\fIARCHIVE\fR
@@ -694,7 +691,7 @@ executing.
.B TAR_FD
File descriptor which can be used to communicate the new volume name
to
.BR tar .
.BR tar .
.RE
.RS
@@ -732,7 +729,7 @@ When this option is used in conjunction with
.BR \-\-multi\-volume ,
.B tar
will keep track of which volume of a multi-volume archive it is
working in \fIFILE\fR.
working in \fIFILE\fR.
.SS Device blocking
.TP
\fB\-b\fR, \fB\-\-blocking\-factor\fR=\fIBLOCKS\fR
@@ -740,11 +737,11 @@ Set record size to \fIBLOCKS\fRx\fB512\fR bytes.
.TP
\fB\-B\fR, \fB\-\-read\-full\-records\fR
When listing or extracting, accept incomplete input records after
end-of-file marker.
end-of-file marker.
.TP
\fB\-i\fR, \fB\-\-ignore\-zeros\fR
Ignore zeroed blocks in archive. Normally two consecutive 512-blocks
filled with zeroes mean EOF and tar stops reading after encountering
filled with zeroes mean EOF and \fBtar\fR stops reading after encountering
them. This option instructs it to read further and is useful when
reading archives created with the \fB\-A\fR option.
.TP
@@ -783,7 +780,8 @@ Same as \fB\-\-format=v7\fR.
\fB\-\-pax\-option\fR=\fIkeyword\fR[[:]=\fIvalue\fR][,\fIkeyword\fR[[:]=\fIvalue\fR]]...
Control pax keywords when creating \fBPAX\fR archives (\fB\-H
pax\fR). This option is equivalent to the \fB\-o\fR option of the
.BR pax (1) utility.
.BR pax (1)
utility.
.TP
\fB\-\-posix\fR
Same as \fB\-\-format=posix\fR.
@@ -831,6 +829,10 @@ Filter the archive through
\fB\-Z\fR, \fB\-\-compress\fR, \fB\-\-uncompress\fR
Filter the archive through
.BR compress (1).
.TP
\fB\-\-zstd\fR
Filter the archive through
.BR zstd (1).
.SS Local file selection
.TP
\fB\-\-add\-file\fR=\fIFILE\fR
@@ -959,7 +961,7 @@ See also \fB\-\-verbatim\-files\-from\fR.
.TP
\fB\-N\fR, \fB\-\-newer\fR=\fIDATE\fR, \fB\-\-after\-date\fR=\fIDATE\fR
Only store files newer than DATE. If \fIDATE\fR starts with \fB/\fR
or \fB.\fR it is taken to be a file name; the ctime of that file is
or \fB.\fR it is taken to be a file name; the mtime of that file is
used as the date.
.TP
\fB\-\-one\-file\-system\fR
@@ -1008,7 +1010,7 @@ disables this behavior.
This option affects all \fB\-\-files\-from\fR options that occur after
it in the command line. Its effect is reverted by the
\fB\-\-no\-verbatim\-files\-from} option.
\fB\-\-no\-verbatim\-files\-from\fR option.
This option is implied by the \fB\-\-null\fR option.
@@ -1058,7 +1060,8 @@ Display progress messages every \fIN\fRth record (default 10).
Run \fIACTION\fR on each checkpoint.
.TP
\fB\-\-clamp\-mtime\fR
Only set time when the file is more recent than what was given with \-\-mtime.
Only set time when the file is more recent than what was given with
\fB\-\-mtime\fR.
.TP
\fB\-\-full\-time\fR
Print file time to its full resolution.
@@ -1102,7 +1105,7 @@ Show file or archive names after transformation by \fB\-\-strip\fR and
Print total bytes after processing the archive. If \fISIGNAL\fR is
given, print total bytes when this signal is delivered. Allowed
signals are:
.BR SIGHUP ,
.BR SIGHUP ,
.BR SIGQUIT ,
.BR SIGINT ,
.BR SIGUSR1 ", and"
@@ -1113,14 +1116,18 @@ The \fBSIG\fR prefix can be omitted.
Print file modification times in UTC.
.TP
\fB\-v\fR, \fB\-\-verbose\fR
Verbosely list files processed.
Verbosely list files processed. Each instance of this option on the
command line increases the verbosity level by one. The maximum
verbosity level is 3. For a detailed discussion of how various
verbosity levels affect tar's output, please refer to \fBGNU Tar
Manual\fR, subsection 2.5.2 "\fBThe '\-\-verbose' Option\fR".
.TP
\fB\-\-warning\fR=\fIKEYWORD\fR
Enable or disable warning messages identified by \fIKEYWORD\fR. The
messages are suppressed if \fIKEYWORD\fR is prefixed with \fBno\-\fR
and enabled otherwise.
Multiple \fB\-\-warning\fR messages accumulate.
Multiple \fB\-\-warning\fR options accumulate.
Keywords controlling general \fBtar\fR operation:
.RS
@@ -1159,7 +1166,7 @@ Keywords applicable for \fBtar --create\fR:
"%s: file is unchanged; not dumped"
.TP
.B ignore-archive
"%s: file is the archive; not dumped"
"%s: archive cannot contain itself; not dumped"
.TP
.B file-removed
"%s: File removed before we read it"
@@ -1205,7 +1212,7 @@ default (unless \fB\-\-verbose\fR is used). A common example of what
you can get when using this warning is:
.EX
$ \fBtar --warning=decompress-program -x -f archive.Z
$ tar --warning=decompress-program -x -f archive.Z
tar (child): cannot run compress: No such file or directory
tar (child): trying gzip
.EE
@@ -1260,7 +1267,7 @@ as \fB\-\-no\-same\-owner\fR.
.fi
.PP
.SH "RETURN VALUE"
Tar exit code indicates whether it was able to successfully perform
Tar's exit code indicates whether it was able to successfully perform
the requested operation, and if not, what kind of error occurred.
.TP
.B 0
@@ -1268,9 +1275,9 @@ Successful termination.
.TP
.B 1
.I Some files differ.
If tar was invoked with the \fB\-\-compare\fR (\fB\-\-diff\fR, \fB\-d\fR)
If \fBtar\fR was invoked with the \fB\-\-compare\fR (\fB\-\-diff\fR, \fB\-d\fR)
command line option, this means that some files in the archive differ
from their disk counterparts. If tar was given one of the \fB\-\-create\fR,
from their disk counterparts. If \fBtar\fR was given one of the \fB\-\-create\fR,
\fB\-\-append\fR or \fB\-\-update\fR options, this exit code means
that some files were changed while being archived and so the resulting
archive does not contain the exact copy of the file set.
@@ -1296,8 +1303,8 @@ failure during backup to a remote device.
.BR lzop (1),
.BR rmt (8),
.BR symlink (7),
.BR tar (5),
.BR xz (1).
.BR xz (1),
.BR zstd (1).
.PP
Complete \fBtar\fR manual: run
.B info tar
@@ -1309,11 +1316,11 @@ Online copies of \fBGNU tar\fR documentation in various formats can be
found at:
.PP
.in +4
.B http://www.gnu.org/software/tar/manual
.B https://www.gnu.org/software/tar/manual
.SH "BUG REPORTS"
Report bugs to <bug\-tar@gnu.org>.
.SH COPYRIGHT
Copyright \(co 2013 Free Software Foundation, Inc.
Copyright \(co 2023 Free Software Foundation, Inc.
.br
.na
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
@@ -1328,4 +1335,3 @@ There is NO WARRANTY, to the extent permitted by law.
.\" time-stamp-end: "\""
.\" time-stamp-line-limit: 20
.\" end:

File diff suppressed because it is too large Load Diff

View File

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

View File

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

2
gnulib

Submodule gnulib updated: 91e834891d...46f9c21a08

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-2014, 2017 Free Software Foundation, Inc.
# Copyright 2005-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -23,10 +23,12 @@ areadlinkat-with-size
argmatch
argp
argp-version-etc
attribute
backupfile
closeout
configmake
dirname
dup2
error
exclude
extern-inline
@@ -39,8 +41,10 @@ fdopendir
fdutimensat
file-has-acl
fileblocks
flexmember
fnmatch-gnu
fprintftime
free-posix
fseeko
fstatat
full-write
@@ -48,11 +52,12 @@ futimens
getline
getopt-gnu
getpagesize
gettext
gettext-h
gettime
gitlog-to-changelog
hash
human
idx
inttostr
inttypes
lchown
@@ -74,7 +79,7 @@ readlinkat
renameat
root-uid
rpmatch
safe-read
full-read
savedir
selinux-at
setenv
@@ -83,8 +88,10 @@ stat-time
stdbool
stdint
stpcpy
stdopen
strdup-posix
strerror
strnlen
strtoimax
strtol
strtoul
@@ -102,3 +109,4 @@ xalloc-die
xgetcwd
xstrtoumax
xvasprintf
year2038-recommended

View File

@@ -1,7 +1,6 @@
# Makefile for GNU tar library. -*- Makefile -*-
# Copyright 1994-1997, 1999-2001, 2003-2007, 2009-2010, 2013-2014,
# 2016-2017 Free Software Foundation, Inc.
# Copyright 1994-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -33,7 +32,6 @@ AM_CFLAGS = $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS)
noinst_HEADERS = \
paxlib.h\
rmt.h\
stdopen.h\
system.h\
system-ioctl.h\
wordsplit.h\
@@ -43,7 +41,6 @@ libtar_a_SOURCES = \
paxerror.c paxexit-status.c paxlib.h paxnames.c \
rtapelib.c \
rmt.h \
stdopen.c stdopen.h \
system.h system-ioctl.h \
wordsplit.c\
xattr-at.c

View File

@@ -1,5 +1,5 @@
/* Replacement <attr/xattr.h> for platforms that lack it.
Copyright 2012-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 2012-2023 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
@@ -22,39 +22,39 @@
#endif
/* setting */
static inline int setxattr (const char *path, const char *name, const void
*value, size_t size, int flags)
static int setxattr (const char *path, const char *name, const void
*value, size_t size, int flags)
{ errno = ENOTSUP; return -1; }
static inline int lsetxattr (const char *path, const char *name, const void
*value, size_t size, int flags)
static int lsetxattr (const char *path, const char *name, const void
*value, size_t size, int flags)
{ errno = ENOTSUP; return -1; }
static inline int fsetxattr (int filedes, const char *name, const void *value,
size_t size, int flags)
static int fsetxattr (int filedes, const char *name, const void *value,
size_t size, int flags)
{ errno = ENOTSUP; return -1; }
/* getting */
static inline ssize_t getxattr (const char *path, const char *name, void *value,
size_t size)
static ssize_t getxattr (const char *path, const char *name, void *value,
size_t size)
{ errno = ENOTSUP; return -1; }
static inline ssize_t lgetxattr (const char *path, const char *name, void
*value, size_t size)
static ssize_t lgetxattr (const char *path, const char *name, void
*value, size_t size)
{ errno = ENOTSUP; return -1; }
static inline ssize_t fgetxattr (int filedes, const char *name, void *value,
size_t size)
static ssize_t fgetxattr (int filedes, const char *name, void *value,
size_t size)
{ errno = ENOTSUP; return -1; }
/* listing */
static inline ssize_t listxattr (const char *path, char *list, size_t size)
static ssize_t listxattr (const char *path, char *list, size_t size)
{ errno = ENOTSUP; return -1; }
static inline ssize_t llistxattr (const char *path, char *list, size_t size)
static ssize_t llistxattr (const char *path, char *list, size_t size)
{ errno = ENOTSUP; return -1; }
static inline ssize_t flistxattr (int filedes, char *list, size_t size)
static ssize_t flistxattr (int filedes, char *list, size_t size)
{ errno = ENOTSUP; return -1; }
#endif

View File

@@ -1,77 +0,0 @@
/* stdopen.c - ensure that the three standard file descriptors are in use
Copyright 2005, 2007, 2013-2014, 2016-2017 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 and Jim Meyering. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "stdopen.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
/* Try to ensure that all of the standard file numbers (0, 1, 2)
are in use. Without this, each application would have to guard
every call to open, dup, fopen, etc. with tests to ensure they
don't use one of the special file numbers when opening a file.
Return false if at least one of the file descriptors is initially
closed and an attempt to reopen it fails. Otherwise, return true. */
bool
stdopen (void)
{
int fd;
bool ok = true;
for (fd = 0; fd <= 2; fd++)
{
if (fcntl (fd, F_GETFD) < 0)
{
if (errno != EBADF)
ok = false;
else
{
static const int contrary_mode[]
= { O_WRONLY, O_RDONLY, O_RDONLY };
int mode = contrary_mode[fd];
int new_fd;
/* Open /dev/null with the contrary mode so that the typical
read (stdin) or write (stdout, stderr) operation will fail.
With descriptor 0, we can do even better on systems that
have /dev/full, by opening that write-only instead of
/dev/null. The only drawback is that a write-provoked
failure comes with a misleading errno value, ENOSPC. */
if (mode == O_RDONLY
|| (new_fd = open ("/dev/full", mode) != fd))
new_fd = open ("/dev/null", mode);
if (new_fd != fd)
{
if (0 <= new_fd)
close (new_fd);
ok = false;
}
}
}
}
return ok;
}

View File

@@ -1,16 +0,0 @@
#ifndef STDOPEN_H
# define STDOPEN_H 1
# include <stdbool.h>
# ifdef __cplusplus
extern "C" {
# endif
bool stdopen (void);
# ifdef __cplusplus
}
# endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* wordsplit - a word splitter
Copyright (C) 2009-2014, 2016-2017 Free Software Foundation, Inc.
Copyright (C) 2009-2018 Sergey Poznyakoff
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
@@ -12,58 +12,114 @@
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 Sergey Poznyakoff
*/
with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef __WORDSPLIT_H
#define __WORDSPLIT_H
#include <stddef.h>
#include <attribute.h>
#if 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
#else
# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) /* empty */
#endif
typedef struct wordsplit wordsplit_t;
/* Structure used to direct the splitting. Members marked with [Input]
can be defined before calling wordsplit(), those marked with [Output]
provide return values when the function returns. If neither mark is
used, the member is internal and must not be used by the caller.
In the comments below, the identifiers in parentheses indicate bits that
must be set (or unset, if starting with !) in ws_flags (if starting with
WRDSF_) or ws_options (if starting with WRDSO_) to initialize or use the
given member.
If not redefined explicitly, most of them are set to some reasonable
default value upon entry to wordsplit(). */
struct wordsplit
{
size_t ws_wordc;
char **ws_wordv;
size_t ws_offs;
size_t ws_wordn;
int ws_flags;
const char *ws_delim;
const char *ws_comment;
const char *ws_escape;
void (*ws_alloc_die) (struct wordsplit * wsp);
size_t ws_wordc; /* [Output] Number of words in ws_wordv. */
char **ws_wordv; /* [Output] Array of parsed out words. */
size_t ws_offs; /* [Input] (WRDSF_DOOFFS) Number of initial
elements in ws_wordv to fill with NULLs. */
size_t ws_wordn; /* Number of elements ws_wordv can accommodate. */
unsigned ws_flags; /* [Input] Flags passed to wordsplit. */
unsigned ws_options; /* [Input] (WRDSF_OPTIONS)
Additional options. */
size_t ws_maxwords; /* [Input] (WRDSO_MAXWORDS) Return at most that
many words */
size_t ws_wordi; /* [Output] (WRDSF_INCREMENTAL) Total number of
words returned so far */
const char *ws_delim; /* [Input] (WRDSF_DELIM) Word delimiters. */
const char *ws_comment; /* [Input] (WRDSF_COMMENT) Comment characters. */
const char *ws_escape[2]; /* [Input] (WRDSF_ESCAPE) Characters to be escaped
with backslash. */
void (*ws_alloc_die) (wordsplit_t *wsp);
/* [Input] (WRDSF_ALLOC_DIE) Function called when
out of memory. Must not return. */
void (*ws_error) (const char *, ...)
__WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2));
ATTRIBUTE_FORMAT ((printf, 1, 2));
/* [Input] (WRDSF_ERROR) Function used for error
reporting */
void (*ws_debug) (const char *, ...)
__WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2));
ATTRIBUTE_FORMAT ((printf, 1, 2));
/* [Input] (WRDSF_DEBUG) Function used for debug
output. */
const char **ws_env; /* [Input] (WRDSF_ENV, !WRDSF_NOVAR) Array of
environment variables. */
const char **ws_env;
const char *(*ws_getvar) (const char *, size_t, void *);
void *ws_closure;
char **ws_envbuf;
size_t ws_envidx;
size_t ws_envsiz;
const char *ws_input;
size_t ws_len;
size_t ws_endp;
int ws_errno;
int (*ws_getvar) (char **ret, const char *var, size_t len, void *clos);
/* [Input] (WRDSF_GETVAR, !WRDSF_NOVAR) Looks up
the name VAR (LEN bytes long) in the table of
variables and if found returns in memory
location pointed to by RET the value of that
variable. Returns WRDSE_OK (0) on success,
and an error code (see WRDSE_* defines below)
on error. User-specific errors can be returned
by storing the error diagnostic string in RET
and returning WRDSE_USERERR.
Whatever is stored in RET, it must be allocated
using malloc(3). */
void *ws_closure; /* [Input] (WRDSF_CLOSURE) Passed as the CLOS
argument to ws_getvar and ws_command. */
int (*ws_command) (char **ret, const char *cmd, size_t len, char **argv,
void *clos);
/* [Input] (!WRDSF_NOCMD) Returns in the memory
location pointed to by RET the expansion of
the command CMD (LEN bytes long). If WRDSO_ARGV
option is set, ARGV contains CMD split out to
words. Otherwise ARGV is NULL.
See ws_getvar for a discussion of possible
return values. */
const char *ws_input; /* Input string (the S argument to wordsplit. */
size_t ws_len; /* Length of ws_input. */
size_t ws_endp; /* Points past the last processed byte in
ws_input. */
int ws_errno; /* [Output] Error code, if an error occurred. */
char *ws_usererr; /* Points to textual description of
the error, if ws_errno is WRDSE_USERERR. Must
be allocated with malloc(3). */
struct wordsplit_node *ws_head, *ws_tail;
/* Doubly-linked list of parsed out nodes. */
int ws_lvl; /* Invocation nesting level. */
};
/* Wordsplit flags. Only 2 bits of a 32-bit word remain unused.
It is getting crowded... */
/* Initial size for ws_env, if allocated automatically */
#define WORDSPLIT_ENV_INIT 16
/* Wordsplit flags. */
/* Append the words found to the array resulting from a previous
call. */
#define WRDSF_APPEND 0x00000001
/* Insert we_offs initial NULLs in the array ws_wordv.
/* Insert ws_offs initial NULLs in the array ws_wordv.
(These are not counted in the returned ws_wordc.) */
#define WRDSF_DOOFFS 0x00000002
/* Don't do command substitution. Reserved for future use. */
/* Don't do command substitution. */
#define WRDSF_NOCMD 0x00000004
/* The parameter p resulted from a previous call to
wordsplit(), and wordsplit_free() was not called. Reuse the
@@ -71,10 +127,8 @@ struct wordsplit
#define WRDSF_REUSE 0x00000008
/* Print errors */
#define WRDSF_SHOWERR 0x00000010
/* Consider it an error if an undefined shell variable
is expanded. */
/* Consider it an error if an undefined variable is expanded. */
#define WRDSF_UNDEF 0x00000020
/* Don't do variable expansion. */
#define WRDSF_NOVAR 0x00000040
/* Abort on ENOMEM error */
@@ -85,7 +139,7 @@ struct wordsplit
#define WRDSF_SQUOTE 0x00000200
/* Handle double quotes */
#define WRDSF_DQUOTE 0x00000400
/* Handle quotes and escape directives */
/* Handle single and double quotes */
#define WRDSF_QUOTE (WRDSF_SQUOTE|WRDSF_DQUOTE)
/* Replace each input sequence of repeated delimiters with a single
delimiter */
@@ -113,56 +167,97 @@ struct wordsplit
/* Don't split input into words. Useful for side effects. */
#define WRDSF_NOSPLIT 0x00400000
/* Keep undefined variables in place, instead of expanding them to
empty string */
empty strings. */
#define WRDSF_KEEPUNDEF 0x00800000
/* Warn about undefined variables */
#define WRDSF_WARNUNDEF 0x01000000
/* Handle C escapes */
#define WRDSF_CESCAPES 0x02000000
/* ws_closure is set */
#define WRDSF_CLOSURE 0x04000000
/* ws_env is a Key/Value environment, i.e. the value of a variable is
stored in the element that follows its name. */
#define WRDSF_ENV_KV 0x08000000
/* ws_escape is set */
#define WRDSF_ESCAPE 0x10000000
/* Incremental mode */
#define WRDSF_INCREMENTAL 0x20000000
/* Perform pathname and tilde expansion */
#define WRDSF_PATHEXPAND 0x40000000
/* ws_options is initialized */
#define WRDSF_OPTIONS 0x80000000
#define WRDSF_DEFFLAGS \
(WRDSF_NOVAR | WRDSF_NOCMD | \
WRDSF_QUOTE | WRDSF_SQUEEZE_DELIMS | WRDSF_CESCAPES)
#define WRDSE_EOF 0
/* Remove the word that produces empty string after path expansion */
#define WRDSO_NULLGLOB 0x00000001
/* Print error message if path expansion produces empty string */
#define WRDSO_FAILGLOB 0x00000002
/* Allow a leading period to be matched by metacharacters. */
#define WRDSO_DOTGLOB 0x00000004
/* ws_command needs argv parameter */
#define WRDSO_ARGV 0x00000008
/* Keep backslash in unrecognized escape sequences in words */
#define WRDSO_BSKEEP_WORD 0x00000010
/* Handle octal escapes in words */
#define WRDSO_OESC_WORD 0x00000020
/* Handle hex escapes in words */
#define WRDSO_XESC_WORD 0x00000040
/* ws_maxwords field is initialized */
#define WRDSO_MAXWORDS 0x00000080
/* Keep backslash in unrecognized escape sequences in quoted strings */
#define WRDSO_BSKEEP_QUOTE 0x00000100
/* Handle octal escapes in quoted strings */
#define WRDSO_OESC_QUOTE 0x00000200
/* Handle hex escapes in quoted strings */
#define WRDSO_XESC_QUOTE 0x00000400
#define WRDSO_BSKEEP WRDSO_BSKEEP_WORD
#define WRDSO_OESC WRDSO_OESC_WORD
#define WRDSO_XESC WRDSO_XESC_WORD
/* Indices into ws_escape */
#define WRDSX_WORD 0
#define WRDSX_QUOTE 1
/* Set escape option F in WS for words (Q==0) or quoted strings (Q==1) */
#define WRDSO_ESC_SET(ws,q,f) ((ws)->ws_options |= ((f) << 4*(q)))
/* Test WS for escape option F for words (Q==0) or quoted strings (Q==1) */
#define WRDSO_ESC_TEST(ws,q,f) ((ws)->ws_options & ((f) << 4*(q)))
#define WRDSE_OK 0
#define WRDSE_EOF WRDSE_OK
#define WRDSE_QUOTE 1
#define WRDSE_NOSPACE 2
#define WRDSE_NOSUPP 3
#define WRDSE_USAGE 4
#define WRDSE_CBRACE 5
#define WRDSE_UNDEF 6
#define WRDSE_NOINPUT 7
#define WRDSE_USAGE 3
#define WRDSE_CBRACE 4
#define WRDSE_UNDEF 5
#define WRDSE_NOINPUT 6
#define WRDSE_PAREN 7
#define WRDSE_GLOBERR 8
#define WRDSE_USERERR 9
int wordsplit (const char *s, struct wordsplit *p, int flags);
int wordsplit_len (const char *s, size_t len,
struct wordsplit *p, int flags);
void wordsplit_free (struct wordsplit *p);
void wordsplit_free_words (struct wordsplit *ws);
int wordsplit (const char *s, wordsplit_t *ws, unsigned flags);
int wordsplit_len (const char *s, size_t len, wordsplit_t *ws, unsigned flags);
void wordsplit_free (wordsplit_t *ws);
void wordsplit_free_words (wordsplit_t *ws);
void wordsplit_free_envbuf (wordsplit_t *ws);
int wordsplit_get_words (wordsplit_t *ws, size_t *wordc, char ***wordv);
int wordsplit_append (wordsplit_t *wsp, int argc, char **argv);
int wordsplit_c_unquote_char (int c);
int wordsplit_c_quote_char (int c);
size_t wordsplit_c_quoted_length (const char *str, int quote_hex,
int *quote);
void wordsplit_general_unquote_copy (char *dst, const char *src, size_t n,
const char *escapable);
void wordsplit_sh_unquote_copy (char *dst, const char *src, size_t n);
void wordsplit_c_unquote_copy (char *dst, const char *src, size_t n);
size_t wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote);
void wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex);
void wordsplit_perror (struct wordsplit *ws);
const char *wordsplit_strerror (struct wordsplit *ws);
void wordsplit_perror (wordsplit_t *ws);
const char *wordsplit_strerror (wordsplit_t *ws);
void wordsplit_clearerr (wordsplit_t *ws);
#endif

View File

@@ -1,7 +1,7 @@
/* openat-style fd-relative functions for operating with extended file
attributes.
Copyright 2012-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 2012-2023 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,7 +1,7 @@
/* Prototypes for openat-style fd-relative functions for operating with
extended file attributes.
Copyright 2012-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 2012-2023 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
@@ -26,6 +26,7 @@
# include <attr/xattr.h>
#endif
#include <errno.h>
#ifndef ENOATTR
# define ENOATTR ENODATA /* No such attribute */
#endif
@@ -62,7 +63,7 @@ ssize_t getxattrat (int dir_fd, const char *path, const char *name,
ssize_t lgetxattrat (int dir_fd, const char *path, const char *name,
void *value, size_t size);
/* dir-fd-relative listxattr. Obtain the list of extended attrubtes names. For
/* dir-fd-relative listxattr. Obtain the list of extended attributes names. For
more info see the listxattr(2) manpage. */
ssize_t listxattrat (int dir_fd, const char *path, char *list, size_t size);

23
po/.gitignore vendored
View File

@@ -1,24 +1,23 @@
/Makevars.template~
/Makefile.in.in~
/Makefile.in.in
/Makevars.template
/Rules-quot
/boldquot.sed
/en@boldquot.header
/en@quot.header
/insert-header.sin
/quot.sed
/remove-potcdate.sed
/remove-potcdate.sin
*.gmo
*.mo
*.po
*~
.reference
LINGUAS
Makefile
Makefile.in
Makefile.in.in
Makevars
Makevars.template
POTFILES
Rules-quot
boldquot.sed
en@boldquot.header
en@quot.header
insert-header.sed
insert-header.sin
quot.sed
remove-potcdate.sed
remove-potcdate.sin
stamp-po
tar.pot

View File

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

View File

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

View File

@@ -11,12 +11,12 @@ TAR=/bin/tar
# (Optional) Path to rsh binary or its equivalent. You may wish to
# set it to ssh as shown in the example below, to improve security.
# In this case you will have to use public key authentication.
RSH=/usr/local/bin/ssh
RSH=/usr/bin/ssh
# (Optional) Path to rsh binary on remote mashines. This will be
# (Optional) Path to rsh binary on remote machines. This will be
# passed via --rsh-command option to the remote invocation of
# tar
RSH_COMMAND=/usr/local/bin/ssh
RSH_COMMAND=/usr/bin/ssh
# Name of temporary file to hold volume numbers. This needs to be accessible
# by all the machines which have filesystems to be dumped.
@@ -43,7 +43,7 @@ BACKUP_DIRS='remote1:/etc remote1:/var/spool/crontab'
# DIRLIST=/etc/my-backup/dirlist
# List of individual files to be dumped.
# These should be accesible from the machine on which the dump is run.
# These should be accessible from the machine on which the dump is run.
BACKUP_FILES=''
# This list may also be kept in file $SYSCONFDIR/backup/files, the
# format of which is the same as described above. The location of
@@ -82,8 +82,7 @@ SLEEP_MESSAGE="`awk '
}' /dev/null`"
# Copyright 2004, 2007, 2013-2014, 2016-2017 Free Software Foundation,
# Inc.
# Copyright 2004-2023 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
# Copyright 2004-2006, 2013, 2019 Free Software Foundation
# This file is part of GNU tar.
@@ -149,7 +149,7 @@ message 20 "Variables:"
message 20 "BACKUP_DIRS=$BACKUP_DIRS"
message 20 "BACKUP_FILES=$BACKUP_FILES"
# The buch of commands below is run in a subshell for which all output is
# The bunch of commands below is run in a subshell for which all output is
# piped through 'tee' to the logfile. Doing this, instead of having
# multiple pipelines all over the place, is cleaner and allows access to
# the exit value from various commands more easily.

View File

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

View File

@@ -8,8 +8,7 @@
# 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-2014, 2016-2017 Free Software
# Foundation, Inc.
# Copyright 2004-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -1,8 +1,7 @@
#! /bin/sh
# Restore backups.
# Copyright 2004, 2006, 2013-2014, 2016-2017 Free Software Foundation,
# Inc.
# Copyright 2004-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -184,7 +183,7 @@ restore_files()
done
}
# Operation Overwiew:
# Operation Overview:
#
# 1. Determine the time of the last backup
# 2. Create list of incremental listings to process

View File

@@ -1,7 +1,6 @@
#! /usr/bin/perl -w
# Display and edit the 'dev' field in tar's snapshots
# Copyright 2007, 2011, 2013-2014, 2016-2017 Free Software Foundation,
# Inc.
# Copyright 2007-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -409,7 +408,7 @@ sub check_field_values ($) {
}
if ( $msg ne "" ) {
$error_found = 1;
print "\n shapshot file header:\n";
print "\n snapshot file header:\n";
print $msg;
}

View File

@@ -3,8 +3,7 @@
# 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-2014, 2016-2017 Free Software
# Foundation, Inc.
# Copyright 2004-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

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

View File

@@ -1,7 +1,6 @@
# Makefile for GNU tar sources.
# Copyright 1994-1997, 1999-2001, 2003, 2006-2007, 2009, 2013-2014,
# 2016-2017 Free Software Foundation, Inc.
# Copyright 1994-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -50,6 +49,7 @@ tar_SOURCES = \
AM_CPPFLAGS = -I$(top_srcdir)/gnu -I../ -I../gnu -I$(top_srcdir)/lib -I../lib
AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
LDADD = ../lib/libtar.a ../gnu/libgnu.a $(LIBINTL) $(LIBICONV)
tar_LDADD = $(LIBS) $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIB_SELINUX)
tar_LDADD = $(LIBS) ../lib/libtar.a ../gnu/libgnu.a\
$(LIB_ACL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS)\
$(LIB_GETRANDOM) $(LIB_HARD_LOCALE) $(FILE_HAS_ACL_LIB) $(LIB_MBRTOWC)\
$(LIB_SELINUX) $(LIB_SETLOCALE_NULL)

View File

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

View File

@@ -1,7 +1,6 @@
/* Buffer management for tar.
Copyright 1988, 1992-1994, 1996-1997, 1999-2010, 2013-2014, 2016-2017
Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -21,7 +20,6 @@
Written by John Gilmore, on 1985-08-25. */
#include <system.h>
#include <system-ioctl.h>
#include <signal.h>
@@ -29,10 +27,16 @@
#include <fnmatch.h>
#include <human.h>
#include <quotearg.h>
#include <verify.h>
#include "common.h"
#include <rmt.h>
/* Work around GCC bug 109856. */
# if 13 <= __GNUC__
# pragma GCC diagnostic ignored "-Wnull-dereference"
# endif
/* Number of retries before giving up on read. */
#define READ_ERROR_MAX 10
@@ -281,7 +285,8 @@ enum compress_type {
ct_lzip,
ct_lzma,
ct_lzop,
ct_xz
ct_xz,
ct_zstd
};
static enum compress_type archive_compression_type = ct_none;
@@ -308,8 +313,10 @@ static struct zip_magic const magic[] = {
{ ct_bzip2, 3, "BZh" },
{ ct_lzip, 4, "LZIP" },
{ ct_lzma, 6, "\xFFLZMA" },
{ ct_lzma, 3, "\x5d\x00\x00" },
{ ct_lzop, 4, "\211LZO" },
{ ct_xz, 6, "\xFD" "7zXZ" },
{ ct_zstd, 4, "\x28\xB5\x2F\xFD" },
};
#define NMAGIC (sizeof(magic)/sizeof(magic[0]))
@@ -325,15 +332,16 @@ static struct zip_program zip_program[] = {
{ ct_lzma, XZ_PROGRAM, "-J" },
{ ct_lzop, LZOP_PROGRAM, "--lzop" },
{ ct_xz, XZ_PROGRAM, "-J" },
{ ct_none }
{ ct_zstd, ZSTD_PROGRAM, "--zstd" },
};
enum { n_zip_programs = sizeof zip_program / sizeof *zip_program };
static struct zip_program const *
find_zip_program (enum compress_type type, int *pstate)
{
int i;
for (i = *pstate; zip_program[i].type != ct_none; i++)
for (i = *pstate; i < n_zip_programs; i++)
{
if (zip_program[i].type == type)
{
@@ -350,6 +358,8 @@ first_decompress_program (int *pstate)
{
struct zip_program const *zp;
*pstate = n_zip_programs;
if (use_compress_program_option)
return use_compress_program_option;
@@ -366,8 +376,6 @@ next_decompress_program (int *pstate)
{
struct zip_program const *zp;
if (use_compress_program_option)
return NULL;
zp = find_zip_program (archive_compression_type, pstate);
return zp ? zp->program : NULL;
}
@@ -418,37 +426,6 @@ check_compressed_archive (bool *pshort)
return ct_none;
}
/* Guess if the archive is seekable. */
static void
guess_seekable_archive (void)
{
struct stat st;
if (subcommand_option == DELETE_SUBCOMMAND)
{
/* The current code in delete.c is based on the assumption that
skip_member() reads all data from the archive. So, we should
make sure it won't use seeks. On the other hand, the same code
depends on the ability to backspace a record in the archive,
so setting seekable_archive to false is technically incorrect.
However, it is tested only in skip_member(), so it's not a
problem. */
seekable_archive = false;
}
if (seek_option != -1)
{
seekable_archive = !!seek_option;
return;
}
if (!multi_volume_option && !use_compress_program_option
&& fstat (archive, &st) == 0)
seekable_archive = S_ISREG (st.st_mode);
else
seekable_archive = false;
}
/* Open an archive named archive_name_array[0]. Detect if it is
a compressed archive of known type and use corresponding decompression
program if so */
@@ -700,12 +677,41 @@ check_tty (enum access_mode mode)
}
}
/* Fetch the status of the archive, accessed via WANTED_STATUS. */
static void
get_archive_status (enum access_mode wanted_access, bool backed_up_flag)
{
if (!sys_get_archive_stat ())
{
int saved_errno = errno;
if (backed_up_flag)
undo_last_backup ();
errno = saved_errno;
open_fatal (archive_name_array[0]);
}
seekable_archive
= (! (multi_volume_option || use_compress_program_option)
&& (seek_option < 0
? (_isrmt (archive)
|| S_ISREG (archive_stat.st_mode)
|| S_ISBLK (archive_stat.st_mode))
: seek_option));
if (wanted_access != ACCESS_READ)
sys_detect_dev_null_output ();
SET_BINARY_MODE (archive);
}
/* Open an archive file. The argument specifies whether we are
reading or writing, or both. */
static void
_open_archive (enum access_mode wanted_access)
{
int backed_up_flag = 0;
bool backed_up_flag = false;
if (record_size == 0)
FATAL_ERROR ((0, 0, _("Invalid value for record_size")));
@@ -794,15 +800,13 @@ _open_archive (enum access_mode wanted_access)
{
case ACCESS_READ:
archive = open_compressed_archive ();
if (archive >= 0)
guess_seekable_archive ();
break;
case ACCESS_WRITE:
if (backup_option)
{
maybe_backup_file (archive_name_array[0], 1);
backed_up_flag = 1;
backed_up_flag = true;
}
if (verify_option)
archive = rmtopen (archive_name_array[0], O_RDWR | O_CREAT | O_BINARY,
@@ -830,20 +834,7 @@ _open_archive (enum access_mode wanted_access)
break;
}
if (archive < 0
|| (! _isrmt (archive) && !sys_get_archive_stat ()))
{
int saved_errno = errno;
if (backed_up_flag)
undo_last_backup ();
errno = saved_errno;
open_fatal (archive_name_array[0]);
}
sys_detect_dev_null_output ();
sys_save_archive_dev_ino ();
SET_BINARY_MODE (archive);
get_archive_status (wanted_access, backed_up_flag);
switch (wanted_access)
{
@@ -996,7 +987,8 @@ short_read (size_t status)
}
record_end = record_start + (record_size - left) / BLOCKSIZE;
records_read++;
if (left == 0)
records_read++;
}
/* Flush the current buffer to/from the archive. */
@@ -1046,18 +1038,8 @@ flush_archive (void)
static void
backspace_output (void)
{
#ifdef MTIOCTOP
{
struct mtop operation;
operation.mt_op = MTBSR;
operation.mt_count = 1;
if (rmtioctl (archive, MTIOCTOP, (char *) &operation) >= 0)
return;
if (errno == EIO && rmtioctl (archive, MTIOCTOP, (char *) &operation) >= 0)
return;
}
#endif
if (mtioseek (false, -1))
return;
{
off_t position = rmtlseek (archive, (off_t) 0, SEEK_CUR);
@@ -1323,8 +1305,8 @@ new_volume (enum access_mode mode)
if (verify_option)
verify_volume ();
assign_string (&volume_label, NULL);
assign_string (&continued_file_name, NULL);
assign_null (&volume_label);
assign_null (&continued_file_name);
continued_file_size = continued_file_offset = 0;
current_block = record_start;
@@ -1370,7 +1352,6 @@ new_volume (enum access_mode mode)
case ACCESS_READ:
archive = rmtopen (*archive_name_cursor, O_RDONLY, MODE_RW,
rsh_command_option);
guess_seekable_archive ();
break;
case ACCESS_WRITE:
@@ -1395,7 +1376,7 @@ new_volume (enum access_mode mode)
goto tryagain;
}
SET_BINARY_MODE (archive);
get_archive_status (mode, false);
return true;
}
@@ -1500,17 +1481,17 @@ try_new_volume (void)
if (!read_header0 (&dummy))
return false;
tar_stat_destroy (&dummy);
assign_string (&volume_label, current_header->header.name);
ASSIGN_STRING_N (&volume_label, current_header->header.name);
set_next_block_after (header);
header = find_next_block ();
if (header->header.typeflag != GNUTYPE_MULTIVOL)
if (! (header && header->header.typeflag == GNUTYPE_MULTIVOL))
break;
FALLTHROUGH;
case GNUTYPE_MULTIVOL:
if (!read_header0 (&dummy))
return false;
tar_stat_destroy (&dummy);
assign_string (&continued_file_name, current_header->header.name);
ASSIGN_STRING_N (&continued_file_name, current_header->header.name);
continued_file_size =
UINTMAX_FROM_HEADER (current_header->header.size);
continued_file_offset =
@@ -1653,15 +1634,7 @@ match_volume_label (void)
quote (volume_label_option)));
if (label->header.typeflag == GNUTYPE_VOLHDR)
{
if (memchr (label->header.name, '\0', sizeof label->header.name))
assign_string (&volume_label, label->header.name);
else
{
volume_label = xmalloc (sizeof (label->header.name) + 1);
memcpy (volume_label, label->header.name,
sizeof (label->header.name));
volume_label[sizeof (label->header.name)] = 0;
}
ASSIGN_STRING_N (&volume_label, label->header.name);
}
else if (label->header.typeflag == XGLTYPE)
{
@@ -1694,11 +1667,11 @@ _write_volume_label (const char *str)
{
union block *label = find_next_block ();
assume (label);
memset (label, 0, BLOCKSIZE);
strcpy (label->header.name, str);
assign_string (&current_stat_info.file_name,
label->header.name);
assign_string (&current_stat_info.file_name, label->header.name);
current_stat_info.had_trailing_slash =
strip_trailing_slashes (current_stat_info.file_name);
@@ -1738,7 +1711,7 @@ add_chunk_header (struct bufmap *map)
st.stat.st_uid = getuid ();
st.stat.st_gid = getgid ();
st.orig_file_name = xheader_format_name (&st,
"%d/GNUFileParts.%p/%f.%n",
"%d/GNUFileParts/%f.%n",
volno);
st.file_name = st.orig_file_name;
st.archive_file_size = st.stat.st_size = map->sizeleft;
@@ -1768,15 +1741,19 @@ gnu_add_multi_volume_header (struct bufmap *map)
{
int tmp;
union block *block = find_next_block ();
size_t len = strlen (map->file_name);
if (strlen (map->file_name) > NAME_FIELD_SIZE)
WARN ((0, 0,
_("%s: file name too long to be stored in a GNU multivolume header, truncated"),
quotearg_colon (map->file_name)));
if (len > NAME_FIELD_SIZE)
{
WARN ((0, 0,
_("%s: file name too long to be stored in a GNU multivolume header, truncated"),
quotearg_colon (map->file_name)));
len = NAME_FIELD_SIZE;
}
memset (block, 0, BLOCKSIZE);
strncpy (block->header.name, map->file_name, NAME_FIELD_SIZE);
memcpy (block->header.name, map->file_name, len);
block->header.typeflag = GNUTYPE_MULTIVOL;
OFF_TO_CHARS (map->sizeleft, block->header.size);
@@ -1851,7 +1828,7 @@ simple_flush_read (void)
/* Simple flush write (no multi-volume or label extensions) */
static void
simple_flush_write (size_t level __attribute__((unused)))
simple_flush_write (MAYBE_UNUSED size_t level)
{
ssize_t status;

View File

@@ -1,6 +1,6 @@
/* Checkpoint management for tar.
Copyright 2007, 2013-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 2007-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -23,6 +23,7 @@
#include <sys/ioctl.h>
#include <termios.h>
#include "fprintftime.h"
#include <signal.h>
enum checkpoint_opcode
{
@@ -32,7 +33,8 @@ enum checkpoint_opcode
cop_ttyout,
cop_sleep,
cop_exec,
cop_totals
cop_totals,
cop_wait
};
struct checkpoint_action
@@ -43,6 +45,7 @@ struct checkpoint_action
{
time_t time;
char *command;
int signal;
} v;
};
@@ -52,6 +55,16 @@ static unsigned checkpoint;
/* List of checkpoint actions */
static struct checkpoint_action *checkpoint_action, *checkpoint_action_tail;
/* State of the checkpoint system */
enum {
CHKP_INIT, /* Needs initialization */
CHKP_COMPILE, /* Actions are being compiled */
CHKP_RUN /* Actions are being run */
};
static int checkpoint_state;
/* Blocked signals */
static sigset_t sigs;
static struct checkpoint_action *
alloc_action (enum checkpoint_opcode opcode)
{
@@ -71,7 +84,7 @@ copy_string_unquote (const char *str)
char *output = xstrdup (str);
size_t len = strlen (output);
if ((*output == '"' || *output == '\'')
&& output[len-1] == *output)
&& len > 1 && output[len-1] == *output)
{
memmove (output, output+1, len-2);
output[len-2] = 0;
@@ -85,6 +98,12 @@ checkpoint_compile_action (const char *str)
{
struct checkpoint_action *act;
if (checkpoint_state == CHKP_INIT)
{
sigemptyset (&sigs);
checkpoint_state = CHKP_COMPILE;
}
if (strcmp (str, ".") == 0 || strcmp (str, "dot") == 0)
alloc_action (cop_dot);
else if (strcmp (str, "bell") == 0)
@@ -117,6 +136,12 @@ checkpoint_compile_action (const char *str)
}
else if (strcmp (str, "totals") == 0)
alloc_action (cop_totals);
else if (strncmp (str, "wait=", 5) == 0)
{
act = alloc_action (cop_wait);
act->v.signal = decode_signal (str + 5);
sigaddset (&sigs, act->v.signal);
}
else
FATAL_ERROR ((0, 0, _("%s: unknown checkpoint action"), str));
}
@@ -124,15 +149,24 @@ checkpoint_compile_action (const char *str)
void
checkpoint_finish_compile (void)
{
if (checkpoint_option)
if (checkpoint_state == CHKP_INIT
&& checkpoint_option
&& !checkpoint_action)
{
if (!checkpoint_action)
/* Provide a historical default */
checkpoint_compile_action ("echo");
/* Provide a historical default */
checkpoint_compile_action ("echo");
}
if (checkpoint_state == CHKP_COMPILE)
{
sigprocmask (SIG_BLOCK, &sigs, NULL);
if (!checkpoint_option)
/* set default checkpoint rate */
checkpoint_option = DEFAULT_CHECKPOINT;
checkpoint_state = CHKP_RUN;
}
else if (checkpoint_action)
/* Otherwise, set default checkpoint rate */
checkpoint_option = DEFAULT_CHECKPOINT;
}
static const char *checkpoint_total_format[] = {
@@ -390,6 +424,13 @@ run_checkpoint_actions (bool do_write)
case cop_totals:
compute_duration ();
print_total_stats ();
break;
case cop_wait:
{
int n;
sigwait (&sigs, &n);
}
}
}
}

View File

@@ -1,7 +1,6 @@
/* Common declarations for the tar program.
Copyright 1988, 1992-1994, 1996-1997, 1999-2010, 2012-2017 Free
Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -44,24 +43,22 @@
# define GLOBAL extern
#endif
#if 7 <= __GNUC__
# define FALLTHROUGH __attribute__ ((__fallthrough__))
#else
# define FALLTHROUGH ((void) 0)
#endif
#define TAREXIT_SUCCESS PAXEXIT_SUCCESS
#define TAREXIT_DIFFERS PAXEXIT_DIFFERS
#define TAREXIT_FAILURE PAXEXIT_FAILURE
#include "arith.h"
#include <attribute.h>
#include <backupfile.h>
#include <exclude.h>
#include <full-write.h>
#include <idx.h>
#include <inttostr.h>
#include <modechange.h>
#include <quote.h>
#include <safe-read.h>
#include <full-read.h>
#include <stat-time.h>
#include <timespec.h>
#define obstack_chunk_alloc xmalloc
@@ -302,6 +299,10 @@ enum hole_detection_method
GLOBAL enum hole_detection_method hole_detection;
/* The first entry in names.c:namelist specifies the member name to
start extracting from. Set by add_starting_file() upon seeing the
-K option.
*/
GLOBAL bool starting_file_option;
/* Specified maximum byte length of each tape volume (multiple of 1024). */
@@ -337,6 +338,9 @@ GLOBAL const char *volume_label_option;
/* Other global variables. */
/* Force POSIX-compliance */
GLOBAL bool posixly_correct;
/* File descriptor for archive file. */
GLOBAL int archive;
@@ -373,6 +377,7 @@ struct name
char *name; /* File name or globbing pattern */
size_t length; /* cached strlen (name) */
int matching_flags; /* wildcard flags if name is a pattern */
bool is_wildcard; /* true if this is a wildcard pattern */
bool cmdline; /* true if this name was given in the
command line */
@@ -391,9 +396,8 @@ struct name
char *caname; /* canonical name */
};
/* Obnoxious test to see if dimwit is trying to dump the archive. */
GLOBAL dev_t ar_dev;
GLOBAL ino_t ar_ino;
/* Status of archive file, or all zeros if remote. */
GLOBAL struct stat archive_stat;
/* Flags for reading, searching, and fstatatting files. */
GLOBAL int open_read_flags;
@@ -401,6 +405,9 @@ GLOBAL int open_searchdir_flags;
GLOBAL int fstatat_flags;
GLOBAL int seek_option;
/* true if archive if lseek should be used on the archive, 0 if it
should not be used. */
GLOBAL bool seekable_archive;
GLOBAL dev_t root_device;
@@ -463,7 +470,7 @@ void reset_eof (void);
void set_next_block_after (union block *block);
void clear_read_error_count (void);
void xclose (int fd);
void archive_write_error (ssize_t status) __attribute__ ((noreturn));
_Noreturn void archive_write_error (ssize_t status);
void archive_read_error (void);
off_t seek_archive (off_t size);
void set_start_time (void);
@@ -498,7 +505,8 @@ enum dump_status
void add_exclusion_tag (const char *name, enum exclusion_tag_type type,
bool (*predicate) (int));
bool cachedir_file_p (int fd);
char *get_directory_entries (struct tar_stat_info *st);
char *get_directory_entries (struct tar_stat_info *st)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
void create_archive (void);
void pad_archive (off_t size_left);
@@ -610,7 +618,7 @@ uintmax_t uintmax_from_header (const char *buf, size_t size);
void list_archive (void);
void test_archive_label (void);
void print_for_mkdir (char *dirname, int length, mode_t mode);
void print_for_mkdir (char *dirname, mode_t mode);
void print_header (struct tar_stat_info *st, union block *blk,
off_t block_ordinal);
void read_and (void (*do_something) (void));
@@ -618,8 +626,9 @@ enum read_header read_header (union block **return_block,
struct tar_stat_info *info,
enum read_header_mode m);
enum read_header tar_checksum (union block *header, bool silent);
void skip_file (off_t size);
void skim_file (off_t size, bool must_copy);
void skip_member (void);
void skim_member (bool must_copy);
/* Module misc.c. */
@@ -627,7 +636,12 @@ void skip_member (void);
#define max(a, b) ((a) < (b) ? (b) : (a))
char const *quote_n_colon (int n, char const *arg);
void assign_string (char **dest, const char *src);
void assign_string_or_null (char **dest, const char *src)
ATTRIBUTE_NONNULL ((1));
void assign_string (char **dest, const char *src) ATTRIBUTE_NONNULL ((1, 2));
void assign_null (char **dest) ATTRIBUTE_NONNULL ((1));
void assign_string_n (char **string, const char *value, size_t n);
#define ASSIGN_STRING_N(s,v) assign_string_n (s, v, sizeof (v))
int unquote_string (char *str);
char *zap_slashes (char *name);
char *normalize_filename (int cdidx, const char *name);
@@ -662,15 +676,18 @@ represent_uintmax (uintmax_t n)
}
}
#define STRINGIFY_BIGINT(i, b) umaxtostr (i, b)
enum { UINTMAX_STRSIZE_BOUND = INT_BUFSIZE_BOUND (intmax_t) };
enum { SYSINT_BUFSIZE =
max (UINTMAX_STRSIZE_BOUND, INT_BUFSIZE_BOUND (intmax_t)) };
char *sysinttostr (uintmax_t, intmax_t, uintmax_t, char buf[SYSINT_BUFSIZE]);
intmax_t strtosysint (char const *, char **, intmax_t, uintmax_t);
void code_ns_fraction (int ns, char *p);
char const *code_timespec (struct timespec ts, char *sbuf);
enum { BILLION = 1000000000, LOG10_BILLION = 9 };
enum { TIMESPEC_STRSIZE_BOUND =
UINTMAX_STRSIZE_BOUND + LOG10_BILLION + sizeof "-." - 1 };
char const *code_timespec (struct timespec ts,
char sbuf[TIMESPEC_STRSIZE_BOUND]);
struct timespec decode_timespec (char const *, char **, bool);
/* Return true if T does not represent an out-of-range or invalid value. */
@@ -721,9 +738,8 @@ void stat_diag (char const *name);
void file_removed_diag (const char *name, bool top_level,
void (*diagfn) (char const *name));
void write_error_details (char const *name, size_t status, size_t size);
void write_fatal (char const *name) __attribute__ ((noreturn));
void write_fatal_details (char const *name, ssize_t status, size_t size)
__attribute__ ((noreturn));
_Noreturn void write_fatal (char const *name);
_Noreturn void write_fatal_details (char const *name, ssize_t status, size_t size);
pid_t xfork (void);
void xpipe (int fd[2]);
@@ -734,7 +750,21 @@ int set_file_atime (int fd, int parentfd, char const *file,
/* Module names.c. */
extern size_t name_count;
enum files_count
{
FILES_NONE,
FILES_ONE,
FILES_MANY
};
extern enum files_count filename_args;
/* Return true if there are file names in the list */
COMMON_INLINE bool
name_more_files (void)
{
return filename_args != FILES_NONE;
}
extern struct name *gnu_list_name;
void gid_to_gname (gid_t gid, char **gname);
@@ -743,19 +773,19 @@ void uid_to_uname (uid_t uid, char **uname);
int uname_to_uid (char const *uname, uid_t *puid);
void name_init (void);
bool name_more_files (void);
void name_add_name (const char *name);
void name_term (void);
const char *name_next (int change_dirs);
void name_gather (void);
struct name *addname (char const *string, int change_dir,
bool cmdline, struct name *parent);
void add_starting_file (char const *file_name);
void remname (struct name *name);
bool name_match (const char *name);
void names_notfound (void);
void label_notfound (void);
void collect_and_sort_names (void);
struct name *name_scan (const char *name);
struct name *name_scan (const char *name, bool exact);
struct name const *name_from_list (void);
void blank_name_list (void);
char *make_file_name (const char *dir_name, const char *name);
@@ -776,14 +806,14 @@ bool contains_dot_dot (char const *name);
/* Module tar.c. */
void usage (int);
_Noreturn void usage (int);
int confirm (const char *message_action, const char *name);
void tar_stat_init (struct tar_stat_info *st);
bool tar_stat_close (struct tar_stat_info *st);
void tar_stat_destroy (struct tar_stat_info *st);
void usage (int) __attribute__ ((noreturn));
_Noreturn void usage (int);
int tar_timespec_cmp (struct timespec a, struct timespec b);
const char *archive_format_string (enum archive_format fmt);
const char *subcommand_string (enum subcommand c);
@@ -791,6 +821,8 @@ void set_exit_status (int val);
void request_stdin (const char *option);
int decode_signal (const char *);
/* Where an option comes from: */
enum option_source
{
@@ -809,6 +841,24 @@ struct option_locus
class */
};
struct tar_args /* Variables used during option parsing */
{
struct option_locus *loc;
struct textual_date *textual_date; /* Keeps the arguments to --newer-mtime
and/or --date option if they are
textual dates */
bool o_option; /* True if -o option was given */
bool pax_option; /* True if --pax-option was given */
bool compress_autodetect; /* True if compression autodetection should
be attempted when creating archives */
char const *backup_suffix_string; /* --suffix option argument */
char const *version_control_string; /* --backup option argument */
};
#define TAR_ARGS_INITIALIZER(loc) \
{ loc, NULL, false, false, false, NULL, NULL }
void more_options (int argc, char **argv, struct option_locus *loc);
/* Module update.c. */
@@ -829,6 +879,7 @@ void xheader_store (char const *keyword, struct tar_stat_info *st,
void xheader_read (struct xheader *xhdr, union block *header, off_t size);
void xheader_write (char type, char *name, time_t t, struct xheader *xhdr);
void xheader_write_global (struct xheader *xhdr);
void xheader_forbid_global (void);
void xheader_finish (struct xheader *hdr);
void xheader_destroy (struct xheader *hdr);
char *xheader_xhdr_name (struct tar_stat_info *st);
@@ -841,16 +892,19 @@ bool xheader_keyword_deleted_p (const char *kw);
char *xheader_format_name (struct tar_stat_info *st, const char *fmt,
size_t n);
void xheader_xattr_init (struct tar_stat_info *st);
void xheader_xattr_free (struct xattr_array *vals, size_t sz);
void xheader_xattr_copy (const struct tar_stat_info *st,
struct xattr_array **vals, size_t *sz);
void xheader_xattr_add (struct tar_stat_info *st,
const char *key, const char *val, size_t len);
void xattr_map_init (struct xattr_map *map);
void xattr_map_copy (struct xattr_map *dst,
const struct xattr_map *src);
void xattr_map_add (struct xattr_map *map,
const char *key, const char *val, size_t len);
void xattr_map_free (struct xattr_map *xattr_map);
/* Module system.c */
void sys_detect_dev_null_output (void);
void sys_save_archive_dev_ino (void);
void sys_wait_for_child (pid_t, bool);
void sys_spawn_shell (void);
bool sys_compare_uid (struct stat *a, struct stat *b);
@@ -868,10 +922,11 @@ int sys_exec_info_script (const char **archive_name, int volume_number);
void sys_exec_checkpoint_script (const char *script_name,
const char *archive_name,
int checkpoint_number);
bool mtioseek (bool count_files, off_t count);
/* Module compare.c */
void report_difference (struct tar_stat_info *st, const char *message, ...)
__attribute__ ((format (printf, 2, 3)));
ATTRIBUTE_FORMAT ((printf, 2, 3));
/* Module sparse.c */
bool sparse_member_p (struct tar_stat_info *st);
@@ -879,7 +934,7 @@ bool sparse_fixup_header (struct tar_stat_info *st);
enum dump_status sparse_dump_file (int, struct tar_stat_info *st);
enum dump_status sparse_extract_file (int fd, struct tar_stat_info *st,
off_t *size);
enum dump_status sparse_skip_file (struct tar_stat_info *st);
enum dump_status sparse_skim_file (struct tar_stat_info *st, bool must_copy);
bool sparse_diff_file (int, struct tar_stat_info *st);
/* Module utf8.c */
@@ -934,12 +989,13 @@ void checkpoint_flush_actions (void);
#define WARN_XATTR_WRITE 0x00200000
#define WARN_RECORD_SIZE 0x00400000
#define WARN_FAILED_READ 0x00800000
#define WARN_MISSING_ZERO_BLOCKS 0x01000000
/* These warnings are enabled by default in verbose mode: */
#define WARN_VERBOSE_WARNINGS (WARN_RENAME_DIRECTORY|WARN_NEW_DIRECTORY|\
WARN_DECOMPRESS_PROGRAM|WARN_EXISTING_FILE|\
WARN_RECORD_SIZE)
#define WARN_ALL (~WARN_VERBOSE_WARNINGS)
#define WARN_ALL 0xffffffff
void set_warning_option (const char *arg);

View File

@@ -1,7 +1,6 @@
/* Diff files from a tar archive.
Copyright 1988, 1992-1994, 1996-1997, 1999-2001, 2003-2007,
2009-2010, 2012-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -74,8 +73,7 @@ report_difference (struct tar_stat_info *st, const char *fmt, ...)
/* Take a buffer returned by read_and_process and do nothing with it. */
static int
process_noop (size_t size __attribute__ ((unused)),
char *data __attribute__ ((unused)))
process_noop (MAYBE_UNUSED size_t size, MAYBE_UNUSED char *data)
{
return 1;
}
@@ -567,31 +565,12 @@ verify_volume (void)
ioctl (archive, FDFLUSH);
#endif
#ifdef MTIOCTOP
{
struct mtop operation;
int status;
operation.mt_op = MTBSF;
operation.mt_count = 1;
if (status = rmtioctl (archive, MTIOCTOP, (char *) &operation), status < 0)
{
if (errno != EIO
|| (status = rmtioctl (archive, MTIOCTOP, (char *) &operation),
status < 0))
{
#endif
if (rmtlseek (archive, (off_t) 0, SEEK_SET) != 0)
{
/* Lseek failed. Try a different method. */
seek_warn (archive_name_array[0]);
return;
}
#ifdef MTIOCTOP
}
}
}
#endif
if (!mtioseek (true, -1) && rmtlseek (archive, 0, SEEK_SET) != 0)
{
/* Lseek failed. Try a different method. */
seek_warn (archive_name_array[0]);
return;
}
access_mode = ACCESS_READ;
now_verifying = 1;

View File

@@ -1,7 +1,6 @@
/* Create a tar archive.
Copyright 1985, 1992-1994, 1996-1997, 1999-2001, 2003-2007,
2009-2010, 2012-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 1985-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -23,6 +22,7 @@
#include <system.h>
#include <areadlink.h>
#include <flexmember.h>
#include <quotearg.h>
#include "common.h"
@@ -37,7 +37,7 @@ struct link
dev_t dev;
ino_t ino;
nlink_t nlink;
char name[1];
char name[FLEXIBLE_ARRAY_MEMBER];
};
struct exclusion_tag
@@ -175,13 +175,13 @@ tar_name_copy_str (char *dst, const char *src, size_t len)
}
/* Convert NEGATIVE VALUE to a base-256 representation suitable for
tar headers. NEGATIVE is 1 if VALUE was negative before being cast
to uintmax_t, 0 otherwise. Output to buffer WHERE with size SIZE.
tar headers. NEGATIVE is true iff VALUE was negative before being
cast to uintmax_t. Output to buffer WHERE with size SIZE.
The result is undefined if SIZE is 0 or if VALUE is too large to
fit. */
static void
to_base256 (int negative, uintmax_t value, char *where, size_t size)
to_base256 (bool negative, uintmax_t value, char *where, size_t size)
{
uintmax_t v = value;
uintmax_t propagated_sign_bits =
@@ -206,13 +206,13 @@ to_base256 (int negative, uintmax_t value, char *where, size_t size)
#define GNAME_TO_CHARS(name, buf) string_to_chars (name, buf, sizeof (buf))
static bool
to_chars (int negative, uintmax_t value, size_t valsize,
uintmax_t (*substitute) (int *),
to_chars (bool negative, uintmax_t value, size_t valsize,
uintmax_t (*substitute) (bool *),
char *where, size_t size, const char *type);
static bool
to_chars_subst (int negative, int gnu_format, uintmax_t value, size_t valsize,
uintmax_t (*substitute) (int *),
to_chars_subst (bool negative, bool gnu_format, uintmax_t value, size_t valsize,
uintmax_t (*substitute) (bool *),
char *where, size_t size, const char *type)
{
uintmax_t maxval = (gnu_format
@@ -246,7 +246,7 @@ to_chars_subst (int negative, int gnu_format, uintmax_t value, size_t valsize,
if (substitute)
{
int negsub;
bool negsub;
uintmax_t sub = substitute (&negsub) & maxval;
/* NOTE: This is one of the few places where GNU_FORMAT differs from
OLDGNU_FORMAT. The actual differences are:
@@ -273,25 +273,25 @@ to_chars_subst (int negative, int gnu_format, uintmax_t value, size_t valsize,
/* Convert NEGATIVE VALUE (which was originally of size VALSIZE) to
external form, using SUBSTITUTE (...) if VALUE won't fit. Output
to buffer WHERE with size SIZE. NEGATIVE is 1 iff VALUE was
to buffer WHERE with size SIZE. NEGATIVE is true iff VALUE was
negative before being cast to uintmax_t; its original bitpattern
can be deduced from VALSIZE, its original size before casting.
TYPE is the kind of value being output (useful for diagnostics).
Prefer the POSIX format of SIZE - 1 octal digits (with leading zero
digits), followed by '\0'. If this won't work, and if GNU or
OLDGNU format is allowed, use '\200' followed by base-256, or (if
NEGATIVE is nonzero) '\377' followed by two's complement base-256.
NEGATIVE) '\377' followed by two's complement base-256.
If neither format works, use SUBSTITUTE (...) instead. Pass to
SUBSTITUTE the address of an 0-or-1 flag recording whether the
substitute value is negative. */
static bool
to_chars (int negative, uintmax_t value, size_t valsize,
uintmax_t (*substitute) (int *),
to_chars (bool negative, uintmax_t value, size_t valsize,
uintmax_t (*substitute) (bool *),
char *where, size_t size, const char *type)
{
int gnu_format = (archive_format == GNU_FORMAT
|| archive_format == OLDGNU_FORMAT);
bool gnu_format = (archive_format == GNU_FORMAT
|| archive_format == OLDGNU_FORMAT);
/* Generate the POSIX octal representation if the number fits. */
if (! negative && value <= MAX_VAL_WITH_DIGITS (size - 1, LG_8))
@@ -309,7 +309,7 @@ to_chars (int negative, uintmax_t value, size_t valsize,
if (((negative ? -1 - value : value)
<= MAX_VAL_WITH_DIGITS (size - 1, LG_256)))
{
where[0] = negative ? -1 : 1 << (LG_256 - 1);
where[0] = (char) (negative ? -1 : 1 << (LG_256 - 1));
to_base256 (negative, value, where + 1, size - 1);
return true;
}
@@ -322,10 +322,10 @@ to_chars (int negative, uintmax_t value, size_t valsize,
But this is the traditional behavior. */
else if (negative && valsize * CHAR_BIT <= (size - 1) * LG_8)
{
static int warned_once;
static bool warned_once;
if (! warned_once)
{
warned_once = 1;
warned_once = true;
WARN ((0, 0, _("Generating negative octal headers")));
}
where[size - 1] = '\0';
@@ -343,7 +343,7 @@ to_chars (int negative, uintmax_t value, size_t valsize,
}
static uintmax_t
gid_substitute (int *negative)
gid_substitute (bool *negative)
{
gid_t r;
#ifdef GID_NOBODY
@@ -384,7 +384,7 @@ mode_to_chars (mode_t v, char *p, size_t s)
propagate all unknown bits to the external mode.
This matches historical practice.
Otherwise, just copy the bits we know about. */
int negative;
bool negative;
uintmax_t u;
if (S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX
&& S_IRUSR == TUREAD && S_IWUSR == TUWRITE && S_IXUSR == TUEXEC
@@ -399,7 +399,7 @@ mode_to_chars (mode_t v, char *p, size_t s)
}
else
{
negative = 0;
negative = false;
u = ((v & S_ISUID ? TSUID : 0)
| (v & S_ISGID ? TSGID : 0)
| (v & S_ISVTX ? TSVTX : 0)
@@ -429,7 +429,7 @@ time_to_chars (time_t v, char *p, size_t s)
}
static uintmax_t
uid_substitute (int *negative)
uid_substitute (bool *negative)
{
uid_t r;
#ifdef UID_NOBODY
@@ -453,7 +453,7 @@ uid_to_chars (uid_t v, char *p, size_t s)
static bool
uintmax_to_chars (uintmax_t v, char *p, size_t s)
{
return to_chars (0, v, sizeof v, 0, p, s, "uintmax_t");
return to_chars (false, v, sizeof v, 0, p, s, "uintmax_t");
}
static void
@@ -518,8 +518,8 @@ start_private_header (const char *name, size_t size, time_t t)
MODE_TO_CHARS (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, header->header.mode);
UID_TO_CHARS (0, header->header.uid);
GID_TO_CHARS (0, header->header.gid);
strncpy (header->header.magic, TMAGIC, TMAGLEN);
strncpy (header->header.version, TVERSION, TVERSLEN);
memcpy (header->header.magic, TMAGIC, TMAGLEN);
memcpy (header->header.version, TVERSION, TVERSLEN);
return header;
}
@@ -882,12 +882,6 @@ start_header (struct tar_stat_info *st)
if (!MINOR_TO_CHARS (devminor, header->header.devminor))
return NULL;
}
else if (archive_format != GNU_FORMAT && archive_format != OLDGNU_FORMAT)
{
if (!(MAJOR_TO_CHARS (0, header->header.devmajor)
&& MINOR_TO_CHARS (0, header->header.devminor)))
return NULL;
}
if (archive_format == POSIX_FORMAT)
{
@@ -917,8 +911,8 @@ start_header (struct tar_stat_info *st)
case POSIX_FORMAT:
case USTAR_FORMAT:
strncpy (header->header.magic, TMAGIC, TMAGLEN);
strncpy (header->header.version, TVERSION, TVERSLEN);
memcpy (header->header.magic, TMAGIC, TMAGLEN);
memcpy (header->header.version, TVERSION, TVERSLEN);
break;
default:
@@ -967,14 +961,9 @@ start_header (struct tar_stat_info *st)
xheader_store ("RHT.security.selinux", st, NULL);
if (xattrs_option > 0)
{
size_t scan_xattr = 0;
struct xattr_array *xattr_map = st->xattr_map;
while (scan_xattr < st->xattr_map_size)
{
xheader_store (xattr_map[scan_xattr].xkey, st, &scan_xattr);
++scan_xattr;
}
size_t i;
for (i = 0; i < st->xattr_map.xm_size; i++)
xheader_store (st->xattr_map.xm_map[i].xkey, st, &i);
}
}
@@ -1349,15 +1338,15 @@ create_archive (void)
{
struct name const *p;
trivial_link_count = name_count <= 1 && ! dereference_option;
trivial_link_count = filename_args != FILES_MANY && ! dereference_option;
open_archive (ACCESS_WRITE);
buffer_write_global_xheader ();
if (incremental_option)
{
size_t buffer_size = 1000;
char *buffer = xmalloc (buffer_size);
size_t buffer_size = 0;
char *buffer = NULL;
const char *q;
collect_and_sort_names ();
@@ -1372,12 +1361,8 @@ create_archive (void)
{
struct tar_stat_info st;
size_t plen = strlen (p->name);
if (buffer_size <= plen)
{
while ((buffer_size *= 2) <= plen)
continue;
buffer = xrealloc (buffer, buffer_size);
}
while (buffer_size <= plen)
buffer = x2realloc (buffer, &buffer_size);
memcpy (buffer, p->name, plen);
if (! ISSLASH (buffer[plen - 1]))
buffer[plen++] = DIRECTORY_SEPARATOR;
@@ -1408,12 +1393,8 @@ create_archive (void)
}
st.orig_file_name = xstrdup (p->name);
}
if (buffer_size < plen + qlen)
{
while ((buffer_size *=2 ) < plen + qlen)
continue;
buffer = xrealloc (buffer, buffer_size);
}
while (buffer_size < plen + qlen)
buffer = x2realloc (buffer, &buffer_size);
strcpy (buffer + plen, q + 1);
dump_file (&st, q + 1, buffer);
}
@@ -1538,8 +1519,7 @@ file_count_links (struct tar_stat_info *st)
absolute_names_option));
transform_name (&linkname, XFORM_LINK);
lp = xmalloc (offsetof (struct link, name)
+ strlen (linkname) + 1);
lp = xmalloc (FLEXNSIZEOF (struct link, name, strlen (linkname) + 1));
lp->ino = st->stat.st_ino;
lp->dev = st->stat.st_dev;
lp->nlink = st->stat.st_nlink;
@@ -1659,8 +1639,6 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
{
union block *header;
char type;
off_t original_size;
struct timespec original_ctime;
off_t block_ordinal = -1;
int fd = 0;
bool is_dir;
@@ -1703,10 +1681,11 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
return;
}
st->archive_file_size = original_size = st->stat.st_size;
struct stat st1 = st->stat;
st->archive_file_size = st->stat.st_size;
st->atime = get_stat_atime (&st->stat);
st->mtime = get_stat_mtime (&st->stat);
st->ctime = original_ctime = get_stat_ctime (&st->stat);
st->ctime = get_stat_ctime (&st->stat);
#ifdef S_ISHIDDEN
if (S_ISHIDDEN (st->stat.st_mode))
@@ -1743,7 +1722,7 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
if (sys_file_is_archive (st))
{
WARNOPT (WARN_IGNORE_ARCHIVE,
(0, 0, _("%s: file is the archive; not dumped"),
(0, 0, _("%s: archive cannot contain itself; not dumped"),
quotearg_colon (p)));
return;
}
@@ -1756,9 +1735,9 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
if (is_dir || S_ISREG (st->stat.st_mode) || S_ISCTG (st->stat.st_mode))
{
bool ok;
struct stat final_stat;
struct stat st2;
xattrs_acls_get (parentfd, name, st, 0, !is_dir);
xattrs_acls_get (parentfd, name, st, !is_dir);
xattrs_selinux_get (parentfd, name, st, fd);
xattrs_xattrs_get (parentfd, name, st, fd);
@@ -1824,31 +1803,54 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
errno = - parentfd;
ok = false;
}
else
ok = fstatat (parentfd, name, &final_stat, fstatat_flags) == 0;
}
else
ok = fstat (fd, &final_stat) == 0;
ok = fstat (fd, &st2) == 0;
if (! ok)
file_removed_diag (p, top_level, stat_diag);
}
if (ok)
if (ok && fd)
{
if ((timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0
/* Original ctime will change if the file is a directory and
--remove-files is given */
&& !(remove_files_option && is_dir))
|| original_size < final_stat.st_size)
/* Heuristically check whether the file is the same in all
attributes that tar cares about and can easily check.
Although the check is not perfect since it does not
consult file contents, it is typically good enough.
Do not check atime which is saved only to replace it later.
Do not check ctime where changes might be benign (e.g.,
another process creates a hard link to the file). */
/* If the file's user ID, group ID or mode changed, tar may
have output the wrong info for the file. */
ok &= st1.st_uid == st2.st_uid;
ok &= st1.st_gid == st2.st_gid;
ok &= st1.st_mode == st2.st_mode;
/* Likewise for the file's mtime, but skip this check if it
is a directory possibly updated by --remove-files. */
if (! (is_dir && remove_files_option))
ok &= ! timespec_cmp (get_stat_mtime (&st1),
get_stat_mtime (&st2));
/* Likewise for the file's size, but skip this check if it
is a directory as tar does not output directory sizes.
Although dump_regular_file caught regular file shrinkage,
it shouldn't hurt to check for shrinkage again now;
plus, the file may have grown. */
if (!is_dir)
ok &= st1.st_size == st2.st_size;
if (!ok)
{
WARNOPT (WARN_FILE_CHANGED,
(0, 0, _("%s: file changed as we read it"),
quotearg_colon (p)));
set_exit_status (TAREXIT_DIFFERS);
if (! ignore_failed_read_option)
set_exit_status (TAREXIT_DIFFERS);
}
else if (atime_preserve_option == replace_atime_preserve
&& fd && (is_dir || original_size != 0)
&& timespec_cmp (st->atime, get_stat_atime (&st2)) != 0
&& set_file_atime (fd, parentfd, name, st->atime) != 0)
utime_error (p);
}
@@ -1898,21 +1900,21 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
else if (S_ISCHR (st->stat.st_mode))
{
type = CHRTYPE;
xattrs_acls_get (parentfd, name, st, 0, true);
xattrs_acls_get (parentfd, name, st, true);
xattrs_selinux_get (parentfd, name, st, 0);
xattrs_xattrs_get (parentfd, name, st, 0);
}
else if (S_ISBLK (st->stat.st_mode))
{
type = BLKTYPE;
xattrs_acls_get (parentfd, name, st, 0, true);
xattrs_acls_get (parentfd, name, st, true);
xattrs_selinux_get (parentfd, name, st, 0);
xattrs_xattrs_get (parentfd, name, st, 0);
}
else if (S_ISFIFO (st->stat.st_mode))
{
type = FIFOTYPE;
xattrs_acls_get (parentfd, name, st, 0, true);
xattrs_acls_get (parentfd, name, st, true);
xattrs_selinux_get (parentfd, name, st, 0);
xattrs_xattrs_get (parentfd, name, st, 0);
}
@@ -1946,15 +1948,6 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
if (!header)
return;
header->header.typeflag = type;
if (type != FIFOTYPE)
{
MAJOR_TO_CHARS (major (st->stat.st_rdev),
header->header.devmajor);
MINOR_TO_CHARS (minor (st->stat.st_rdev),
header->header.devminor);
}
finish_header (st, header, block_ordinal);
if (remove_files_option)
queue_deferred_unlink (p, false);

View File

@@ -1,7 +1,6 @@
/* Delete entries from a tar archive.
Copyright 1988, 1992, 1994, 1996-1997, 2000-2001, 2003-2006, 2010,
2013-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -19,7 +18,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <system.h>
#include <system-ioctl.h>
#include "common.h"
#include <rmt.h>
@@ -51,41 +49,31 @@ move_archive (off_t count)
if (count == 0)
return;
#ifdef MTIOCTOP
{
struct mtop operation;
if (count < 0
? (operation.mt_op = MTBSR,
operation.mt_count = -count,
operation.mt_count == -count)
: (operation.mt_op = MTFSR,
operation.mt_count = count,
operation.mt_count == count))
{
if (0 <= rmtioctl (archive, MTIOCTOP, (char *) &operation))
return;
if (errno == EIO
&& 0 <= rmtioctl (archive, MTIOCTOP, (char *) &operation))
return;
}
}
#endif /* MTIOCTOP */
{
off_t position0 = rmtlseek (archive, (off_t) 0, SEEK_CUR);
off_t increment = record_size * (off_t) count;
off_t position = position0 + increment;
if (increment / count != record_size
|| (position < position0) != (increment < 0)
|| (position = position < 0 ? 0 : position,
rmtlseek (archive, position, SEEK_SET) != position))
seek_error_details (archive_name_array[0], position);
if (mtioseek (false, count))
return;
}
off_t position0 = rmtlseek (archive, 0, SEEK_CUR), position = 0;
if (0 <= position0)
{
/* Pretend the starting position is at the first record
boundary after POSITION0. This is useful at EOF after
a short read. */
idx_t short_size = position0 % record_size;
idx_t start_offset = short_size ? record_size - short_size : 0;
off_t increment, move_start;
if (INT_MULTIPLY_WRAPV (record_size, count, &increment)
|| INT_ADD_WRAPV (position0, start_offset, &move_start)
|| INT_ADD_WRAPV (move_start, increment, &position)
|| position < 0)
{
ERROR ((0, EOVERFLOW, "lseek: %s", archive_name_array[0]));
return;
}
else if (rmtlseek (archive, position, SEEK_SET) == position)
return;
}
if (!_isrmt (archive))
seek_error_details (archive_name_array[0], position);
}
/* Write out the record which has been filled. If MOVE_BACK_FLAG,
@@ -148,6 +136,26 @@ write_recent_bytes (char *data, size_t bytes)
write_record (1);
}
static void
flush_file (void)
{
off_t blocks_to_skip;
set_next_block_after (current_header);
blocks_to_skip = (current_stat_info.stat.st_size
+ BLOCKSIZE - 1) / BLOCKSIZE;
while (record_end - current_block <= blocks_to_skip)
{
blocks_to_skip -= (record_end - current_block);
flush_archive ();
if (record_end == current_block)
/* Hit EOF */
break;
}
current_block += blocks_to_skip;
}
void
delete_archive_members (void)
{
@@ -156,7 +164,6 @@ delete_archive_members (void)
/* FIXME: Should clean the routine before cleaning these variables :-( */
struct name *name;
off_t blocks_to_skip = 0;
off_t blocks_to_keep = 0;
int kept_blocks_in_record;
@@ -164,11 +171,12 @@ delete_archive_members (void)
open_archive (ACCESS_UPDATE);
acting_as_filter = strcmp (archive_name_array[0], "-") == 0;
/* Skip to the first member that matches the name list. */
do
{
enum read_header status = read_header (&current_header,
&current_stat_info,
read_header_x_raw);
&current_stat_info,
read_header_x_raw);
switch (status)
{
@@ -176,15 +184,15 @@ delete_archive_members (void)
abort ();
case HEADER_SUCCESS:
if ((name = name_scan (current_stat_info.file_name)) == NULL)
if ((name = name_scan (current_stat_info.file_name, false)) == NULL)
{
skip_member ();
skim_member (acting_as_filter);
break;
}
name->found_count++;
if (!ISFOUND(name))
if (!ISFOUND (name))
{
skip_member ();
skim_member (acting_as_filter);
break;
}
FALLTHROUGH;
@@ -244,15 +252,12 @@ delete_archive_members (void)
if (logical_status == HEADER_SUCCESS)
{
/* FIXME: Pheew! This is crufty code! */
logical_status = HEADER_STILL_UNREAD;
goto flush_file;
flush_file ();
}
/* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says:
"delete.c", line 223: warning: loop not entered at top
Reported by Bruno Haible. */
while (1)
/* Skip matching members and move the rest up the archive. */
while (logical_status != HEADER_END_OF_FILE)
{
enum read_header status;
@@ -260,105 +265,108 @@ delete_archive_members (void)
if (current_block == record_end)
flush_archive ();
status = read_header (&current_header, &current_stat_info,
read_header_auto);
read_header_auto);
xheader_decode (&current_stat_info);
if (status == HEADER_ZERO_BLOCK && ignore_zeros_option)
switch (status)
{
set_next_block_after (current_header);
continue;
}
if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK)
{
logical_status = HEADER_END_OF_FILE;
break;
}
case HEADER_STILL_UNREAD:
case HEADER_SUCCESS_EXTENDED:
abort ();
if (status == HEADER_FAILURE)
{
ERROR ((0, 0, _("Deleting non-header from archive")));
set_next_block_after (current_header);
continue;
}
case HEADER_SUCCESS:
/* Found another header. */
xheader_decode (&current_stat_info);
/* Found another header. */
if ((name = name_scan (current_stat_info.file_name)) != NULL)
{
name->found_count++;
if (ISFOUND(name))
if ((name = name_scan (current_stat_info.file_name, false)) != NULL)
{
flush_file:
set_next_block_after (current_header);
blocks_to_skip = (current_stat_info.stat.st_size
+ BLOCKSIZE - 1) / BLOCKSIZE;
while (record_end - current_block <= blocks_to_skip)
name->found_count++;
if (ISFOUND (name))
{
blocks_to_skip -= (record_end - current_block);
flush_archive ();
flush_file ();
break;
}
current_block += blocks_to_skip;
blocks_to_skip = 0;
continue;
}
}
/* Copy header. */
/* Copy header. */
if (current_stat_info.xhdr.size)
{
write_recent_bytes (current_stat_info.xhdr.buffer,
current_stat_info.xhdr.size);
}
else
{
write_recent_blocks (recent_long_name, recent_long_name_blocks);
write_recent_blocks (recent_long_link, recent_long_link_blocks);
}
new_record[new_blocks] = *current_header;
new_blocks++;
blocks_to_keep
= (current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
set_next_block_after (current_header);
if (new_blocks == blocking_factor)
write_record (1);
/* Copy data. */
kept_blocks_in_record = record_end - current_block;
if (kept_blocks_in_record > blocks_to_keep)
kept_blocks_in_record = blocks_to_keep;
while (blocks_to_keep)
{
int count;
if (current_block == record_end)
if (current_stat_info.xhdr.size)
{
flush_read ();
current_block = record_start;
kept_blocks_in_record = blocking_factor;
if (kept_blocks_in_record > blocks_to_keep)
kept_blocks_in_record = blocks_to_keep;
write_recent_bytes (current_stat_info.xhdr.buffer,
current_stat_info.xhdr.size);
}
count = kept_blocks_in_record;
if (blocking_factor - new_blocks < count)
count = blocking_factor - new_blocks;
if (! count)
abort ();
memcpy (new_record + new_blocks, current_block, count * BLOCKSIZE);
new_blocks += count;
current_block += count;
blocks_to_keep -= count;
kept_blocks_in_record -= count;
else
{
write_recent_blocks (recent_long_name,
recent_long_name_blocks);
write_recent_blocks (recent_long_link,
recent_long_link_blocks);
}
new_record[new_blocks] = *current_header;
new_blocks++;
blocks_to_keep
= (current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
set_next_block_after (current_header);
if (new_blocks == blocking_factor)
write_record (1);
/* Copy data. */
kept_blocks_in_record = record_end - current_block;
if (kept_blocks_in_record > blocks_to_keep)
kept_blocks_in_record = blocks_to_keep;
while (blocks_to_keep)
{
int count;
if (current_block == record_end)
{
flush_read ();
current_block = record_start;
kept_blocks_in_record = blocking_factor;
if (kept_blocks_in_record > blocks_to_keep)
kept_blocks_in_record = blocks_to_keep;
}
count = kept_blocks_in_record;
if (blocking_factor - new_blocks < count)
count = blocking_factor - new_blocks;
if (! count)
abort ();
memcpy (new_record + new_blocks, current_block,
count * BLOCKSIZE);
new_blocks += count;
current_block += count;
blocks_to_keep -= count;
kept_blocks_in_record -= count;
if (new_blocks == blocking_factor)
write_record (1);
}
break;
case HEADER_ZERO_BLOCK:
if (ignore_zeros_option)
set_next_block_after (current_header);
else
logical_status = HEADER_END_OF_FILE;
break;
case HEADER_END_OF_FILE:
logical_status = HEADER_END_OF_FILE;
break;
case HEADER_FAILURE:
ERROR ((0, 0, _("Deleting non-header from archive")));
set_next_block_after (current_header);
break;
default:
abort ();
}
tar_stat_destroy (&current_stat_info);
}
if (logical_status == HEADER_END_OF_FILE)

View File

@@ -1,6 +1,6 @@
/* Per-directory exclusion files for tar.
Copyright 2014, 2016-2017 Free Software Foundation, Inc.
Copyright 2014-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -19,6 +19,7 @@
*/
#include <system.h>
#include <quotearg.h>
#include <flexmember.h>
#include <fnmatch.h>
#include <wordsplit.h>
#include "common.h"
@@ -40,7 +41,7 @@ struct excfile
{
struct excfile *next;
int flags;
char name[1];
char name[FLEXIBLE_ARRAY_MEMBER];
};
static struct excfile *excfile_head, *excfile_tail;
@@ -48,7 +49,8 @@ static struct excfile *excfile_head, *excfile_tail;
void
excfile_add (const char *name, int flags)
{
struct excfile *p = xmalloc (sizeof (*p) + strlen (name));
struct excfile *p = xmalloc (FLEXNSIZEOF (struct excfile, name,
strlen (name) + 1));
p->next = NULL;
p->flags = flags;
strcpy (p->name, name);
@@ -104,7 +106,8 @@ info_attach_exclist (struct tar_stat_info *dir)
vcsfile->data = vcsfile->initfn (vcsfile->data);
if (add_exclude_fp (vcsfile->addfn, ex, fp,
EXCLUDE_WILDCARDS|EXCLUDE_ANCHORED, '\n',
FNM_FILE_NAME|EXCLUDE_WILDCARDS|EXCLUDE_ANCHORED,
'\n',
vcsfile->data))
{
int e = errno;
@@ -197,11 +200,13 @@ excluded_name (char const *name, struct tar_stat_info *st)
}
static void
cvs_addfn (struct exclude *ex, char const *pattern, int options, void *data)
cvs_addfn (struct exclude *ex, char const *pattern, int options,
MAYBE_UNUSED void *data)
{
struct wordsplit ws;
size_t i;
options |= EXCLUDE_ALLOC;
if (wordsplit (pattern, &ws,
WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_SQUEEZE_DELIMS))
return;
@@ -211,7 +216,8 @@ cvs_addfn (struct exclude *ex, char const *pattern, int options, void *data)
}
static void
git_addfn (struct exclude *ex, char const *pattern, int options, void *data)
git_addfn (struct exclude *ex, char const *pattern, int options,
MAYBE_UNUSED void *data)
{
while (isspace (*pattern))
++pattern;
@@ -223,7 +229,8 @@ git_addfn (struct exclude *ex, char const *pattern, int options, void *data)
}
static void
bzr_addfn (struct exclude *ex, char const *pattern, int options, void *data)
bzr_addfn (struct exclude *ex, char const *pattern, int options,
MAYBE_UNUSED void *data)
{
while (isspace (*pattern))
++pattern;

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,6 @@
/* GNU dump extensions to tar.
Copyright 1988, 1992-1994, 1996-1997, 1999-2001, 2003-2009,
2013-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -39,7 +38,15 @@ enum children
#define DIRF_FOUND 0x0004 /* directory is found on fs */
#define DIRF_NEW 0x0008 /* directory is new (not found
in the previous dump) */
#define DIRF_RENAMED 0x0010 /* directory is renamed */
#define DIRF_RENAMED 0x0010 /* Last target in a chain of renames */
/* A directory which is renamed from another one is recognized by its
orig member, which is not-NULL. This directory may eventually be
the source for another rename, in which case it will be pointed to by
the orig member of another directory structure. The last directory
in such a chain of renames (the one which is not pointed to by any
other orig) is marked with the DIRF_RENAMED flag. This marks a starting
point from which append_incremental_renames starts encoding renames for
this chain. */
#define DIR_IS_INITED(d) ((d)->flags & DIRF_INIT)
#define DIR_IS_NFS(d) ((d)->flags & DIRF_NFS)
@@ -496,6 +503,7 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
quote_n (1, d->name)));
directory->orig = d;
DIR_SET_FLAG (directory, DIRF_RENAMED);
DIR_CLEAR_FLAG (d, DIRF_RENAMED);
dirlist_replace_prefix (d->name, name_buffer);
}
directory->children = CHANGED_CHILDREN;
@@ -538,6 +546,7 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
quote_n (1, d->name)));
directory->orig = d;
DIR_SET_FLAG (directory, DIRF_RENAMED);
DIR_CLEAR_FLAG (d, DIRF_RENAMED);
dirlist_replace_prefix (d->name, name_buffer);
}
directory->children = CHANGED_CHILDREN;
@@ -650,7 +659,7 @@ makedumpdir (struct directory *directory, const char *dir)
if (directory->children == ALL_CHILDREN)
dump = NULL;
else if (DIR_IS_RENAMED (directory))
else if (directory->orig)
dump = directory->orig->idump ?
directory->orig->idump : directory->orig->dump;
else
@@ -879,43 +888,36 @@ obstack_code_rename (struct obstack *stk, char const *from, char const *to)
static void
store_rename (struct directory *dir, struct obstack *stk)
{
if (DIR_IS_RENAMED (dir))
struct directory *prev, *p;
/* Detect eventual cycles. If the chain forms a cycle, prev points to
the entry DIR is renamed from.*/
for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
;
if (prev == NULL)
{
struct directory *prev, *p;
for (p = dir; p && p->orig; p = p->orig)
obstack_code_rename (stk, p->orig->name, p->name);
}
else
{
char *temp_name;
/* Detect eventual cycles and clear DIRF_RENAMED flag, so these entries
are ignored when hit by this function next time.
If the chain forms a cycle, prev points to the entry DIR is renamed
from. In this case it still retains DIRF_RENAMED flag, which will be
cleared in the 'else' branch below */
for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
/* Break the cycle by using a temporary name for one of its
elements.
First, create a temp name stub entry. */
temp_name = dir_name (dir->name);
obstack_1grow (stk, 'X');
obstack_grow (stk, temp_name, strlen (temp_name) + 1);
if (prev == NULL)
{
for (p = dir; p && p->orig; p = p->orig)
obstack_code_rename (stk, p->orig->name, p->name);
}
else
{
char *temp_name;
obstack_code_rename (stk, dir->name, "");
DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
for (p = dir; p != prev; p = p->orig)
obstack_code_rename (stk, p->orig->name, p->name);
/* Break the cycle by using a temporary name for one of its
elements.
First, create a temp name stub entry. */
temp_name = dir_name (dir->name);
obstack_1grow (stk, 'X');
obstack_grow (stk, temp_name, strlen (temp_name) + 1);
obstack_code_rename (stk, dir->name, "");
for (p = dir; p != prev; p = p->orig)
obstack_code_rename (stk, p->orig->name, p->name);
obstack_code_rename (stk, "", prev->name);
}
obstack_code_rename (stk, "", prev->name);
free (temp_name);
}
}
@@ -941,7 +943,8 @@ append_incremental_renames (struct directory *dir)
size = 0;
for (dp = dirhead; dp; dp = dp->next)
store_rename (dp, &stk);
if (DIR_IS_RENAMED (dp))
store_rename (dp, &stk);
/* FIXME: Is this the right thing to do when DIR is null? */
if (dir && obstack_object_size (&stk) != size)
@@ -990,17 +993,17 @@ read_incr_db_01 (int version, const char *initbuf)
}
else
{
buf = strdup (initbuf);
buf = xstrdup (initbuf);
bufsize = strlen (buf) + 1;
}
newer_mtime_option = decode_timespec (buf, &ebuf, false);
if (! valid_timespec (newer_mtime_option))
ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option),
lineno,
_("Invalid time stamp")));
FATAL_ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option),
lineno,
_("Invalid time stamp")));
else
{
if (version == 1 && *ebuf)
@@ -1042,9 +1045,9 @@ read_incr_db_01 (int version, const char *initbuf)
mtime = decode_timespec (strp, &ebuf, false);
strp = ebuf;
if (!valid_timespec (mtime) || *strp != ' ')
ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option), lineno,
_("Invalid modification time")));
FATAL_ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option), lineno,
_("Invalid modification time")));
errno = 0;
u = strtoumax (strp, &ebuf, 10);
@@ -1052,9 +1055,9 @@ read_incr_db_01 (int version, const char *initbuf)
errno = ERANGE;
if (errno || strp == ebuf || *ebuf != ' ')
{
ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option), lineno,
_("Invalid modification time (nanoseconds)")));
FATAL_ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option), lineno,
_("Invalid modification time (nanoseconds)")));
mtime.tv_nsec = -1;
}
else
@@ -1068,17 +1071,17 @@ read_incr_db_01 (int version, const char *initbuf)
TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t));
strp = ebuf;
if (errno || *strp != ' ')
ERROR ((0, errno, "%s:%ld: %s",
FATAL_ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option), lineno,
_("Invalid device number")));
_("Invalid device number")));
ino = strtosysint (strp, &ebuf,
TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t));
strp = ebuf;
if (errno || *strp != ' ')
ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option), lineno,
_("Invalid inode number")));
FATAL_ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option), lineno,
_("Invalid inode number")));
strp++;
unquote_string (strp);

View File

@@ -1,7 +1,6 @@
/* List a tar archive, with support routines for reading a tar archive.
Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2017 Free
Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -23,7 +22,7 @@
#include <system.h>
#include <inttostr.h>
#include <quotearg.h>
#include <time.h>
#include "common.h"
union block *current_header; /* points to current archive header */
@@ -257,6 +256,13 @@ read_and (void (*do_something) (void))
continue;
case HEADER_END_OF_FILE:
if (!ignore_zeros_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
WARNOPT (WARN_MISSING_ZERO_BLOCKS,
(0, 0, _("Terminating zero blocks missing at %s"),
STRINGIFY_BIGINT (current_block_ordinal (), buf)));
}
if (block_number_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
@@ -409,26 +415,27 @@ read_header (union block **return_block, struct tar_stat_info *info,
enum read_header_mode mode)
{
union block *header;
union block *header_copy;
char *bp;
union block *data_block;
size_t size, written;
union block *next_long_name = 0;
union block *next_long_link = 0;
union block *next_long_name = NULL;
union block *next_long_link = NULL;
size_t next_long_name_blocks = 0;
size_t next_long_link_blocks = 0;
enum read_header status = HEADER_SUCCESS;
while (1)
{
enum read_header status;
header = find_next_block ();
*return_block = header;
if (!header)
return HEADER_END_OF_FILE;
{
status = HEADER_END_OF_FILE;
break;
}
if ((status = tar_checksum (header, false)) != HEADER_SUCCESS)
return status;
break;
/* Good block. Decode file size and return. */
@@ -438,7 +445,10 @@ read_header (union block **return_block, struct tar_stat_info *info,
{
info->stat.st_size = OFF_FROM_HEADER (header->header.size);
if (info->stat.st_size < 0)
return HEADER_FAILURE;
{
status = HEADER_FAILURE;
break;
}
}
if (header->header.typeflag == GNUTYPE_LONGNAME
@@ -448,10 +458,14 @@ read_header (union block **return_block, struct tar_stat_info *info,
|| header->header.typeflag == SOLARIS_XHDTYPE)
{
if (mode == read_header_x_raw)
return HEADER_SUCCESS_EXTENDED;
{
status = HEADER_SUCCESS_EXTENDED;
break;
}
else if (header->header.typeflag == GNUTYPE_LONGNAME
|| header->header.typeflag == GNUTYPE_LONGLINK)
{
union block *header_copy;
size_t name_size = info->stat.st_size;
size_t n = name_size % BLOCKSIZE;
size = name_size + BLOCKSIZE;
@@ -518,7 +532,10 @@ read_header (union block **return_block, struct tar_stat_info *info,
xheader_decode_global (&xhdr);
xheader_destroy (&xhdr);
if (mode == read_header_x_global)
return HEADER_SUCCESS_EXTENDED;
{
status = HEADER_SUCCESS_EXTENDED;
break;
}
}
/* Loop! */
@@ -537,6 +554,7 @@ read_header (union block **return_block, struct tar_stat_info *info,
name = next_long_name->buffer + BLOCKSIZE;
recent_long_name = next_long_name;
recent_long_name_blocks = next_long_name_blocks;
next_long_name = NULL;
}
else
{
@@ -568,6 +586,7 @@ read_header (union block **return_block, struct tar_stat_info *info,
name = next_long_link->buffer + BLOCKSIZE;
recent_long_link = next_long_link;
recent_long_link_blocks = next_long_link_blocks;
next_long_link = NULL;
}
else
{
@@ -579,9 +598,12 @@ read_header (union block **return_block, struct tar_stat_info *info,
}
assign_string (&info->link_name, name);
return HEADER_SUCCESS;
break;
}
}
free (next_long_name);
free (next_long_link);
return status;
}
#define ISOCTAL(c) ((c)>='0'&&(c)<='7')
@@ -631,10 +653,12 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
stat_info->stat.st_mode = mode;
stat_info->mtime.tv_sec = TIME_FROM_HEADER (header->header.mtime);
stat_info->mtime.tv_nsec = 0;
assign_string (&stat_info->uname,
header->header.uname[0] ? header->header.uname : NULL);
assign_string (&stat_info->gname,
header->header.gname[0] ? header->header.gname : NULL);
assign_string_n (&stat_info->uname,
header->header.uname[0] ? header->header.uname : NULL,
sizeof (header->header.uname));
assign_string_n (&stat_info->gname,
header->header.gname[0] ? header->header.gname : NULL,
sizeof (header->header.gname));
xheader_xattr_init (stat_info);
@@ -857,8 +881,9 @@ from_header (char const *where0, size_t digs, char const *type,
where++;
}
}
else if (*where == '\200' /* positive base-256 */
|| *where == '\377' /* negative base-256 */)
else if (where <= lim - 2
&& (*where == '\200' /* positive base-256 */
|| *where == '\377' /* negative base-256 */))
{
/* Parse base-256 output. A nonnegative number N is
represented as (256**DIGS)/2 + N; a negative number -N is
@@ -1049,15 +1074,11 @@ tartime (struct timespec t, bool full_time)
{
if (full_time)
{
sprintf (buffer, "%04ld-%02d-%02d %02d:%02d:%02d",
tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
strftime (buffer, sizeof buffer, "%Y-%m-%d %H:%M:%S", tm);
code_ns_fraction (ns, buffer + strlen (buffer));
}
else
sprintf (buffer, "%04ld-%02d-%02d %02d:%02d",
tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min);
strftime (buffer, sizeof buffer, "%Y-%m-%d %H:%M", tm);
return buffer;
}
@@ -1355,7 +1376,7 @@ print_header (struct tar_stat_info *st, union block *blk,
/* Print a similar line when we make a directory automatically. */
void
print_for_mkdir (char *dirname, int length, mode_t mode)
print_for_mkdir (char *dirname, mode_t mode)
{
char modes[11];
@@ -1378,15 +1399,17 @@ print_for_mkdir (char *dirname, int length, mode_t mode)
}
}
/* Skip over SIZE bytes of data in blocks in the archive. */
/* Skip over SIZE bytes of data in blocks in the archive.
This may involve copying the data.
If MUST_COPY, always copy instead of skipping. */
void
skip_file (off_t size)
skim_file (off_t size, bool must_copy)
{
union block *x;
/* FIXME: Make sure mv_begin_read is always called before it */
if (seekable_archive)
if (seekable_archive && !must_copy)
{
off_t nblk = seek_archive (size);
if (nblk >= 0)
@@ -1413,6 +1436,14 @@ skip_file (off_t size)
NOTE: Current header must be decoded before calling this function. */
void
skip_member (void)
{
skim_member (false);
}
/* Skip the current member in the archive.
If MUST_COPY, always copy instead of skipping. */
void
skim_member (bool must_copy)
{
if (!current_stat_info.skipped)
{
@@ -1422,9 +1453,9 @@ skip_member (void)
mv_begin_read (&current_stat_info);
if (current_stat_info.is_sparse)
sparse_skip_file (&current_stat_info);
sparse_skim_file (&current_stat_info, must_copy);
else if (save_typeflag != DIRTYPE)
skip_file (current_stat_info.stat.st_size);
skim_file (current_stat_info.stat.st_size, must_copy);
mv_end ();
}
@@ -1443,7 +1474,7 @@ test_archive_label (void)
decode_header (current_header,
&current_stat_info, &current_format, 0);
if (current_header->header.typeflag == GNUTYPE_VOLHDR)
assign_string (&volume_label, current_header->header.name);
ASSIGN_STRING_N (&volume_label, current_header->header.name);
if (volume_label)
{

View File

@@ -1,6 +1,6 @@
/* Owner/group mapping for tar
Copyright 2015-2017 Free Software Foundation, Inc.
Copyright 2015-2023 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -1,7 +1,6 @@
/* Miscellaneous functions, not really specific to GNU tar.
Copyright 1988, 1992, 1994-1997, 1999-2001, 2003-2007, 2009-2010,
2012-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 1988-2023 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
@@ -43,11 +42,44 @@ quote_n_colon (int n, char const *arg)
/* Assign STRING to a copy of VALUE if not zero, or to zero. If
STRING was nonzero, it is freed first. */
void
assign_string_or_null (char **string, const char *value)
{
if (value)
assign_string (string, value);
else
assign_null (string);
}
void
assign_string (char **string, const char *value)
{
free (*string);
*string = value ? xstrdup (value) : 0;
*string = xstrdup (value);
}
void
assign_null (char **string)
{
char *old = *string;
*string = NULL;
free (old);
}
void
assign_string_n (char **string, const char *value, size_t n)
{
free (*string);
if (value)
{
size_t l = strnlen (value, n);
char *p = xmalloc (l + 1);
memcpy (p, value, l);
p[l] = 0;
*string = p;
}
else
*string = NULL;
}
#if 0
@@ -301,8 +333,6 @@ normalize_filename (int cdidx, const char *name)
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]));
@@ -665,13 +695,11 @@ remove_any_file (const char *file_name, enum remove_option option)
char *file_name_buffer = make_file_name (file_name, entry);
int r = remove_any_file (file_name_buffer,
RECURSIVE_REMOVE_OPTION);
int e = errno;
free (file_name_buffer);
if (! r)
{
free (directory);
errno = e;
return 0;
}
}
@@ -704,7 +732,7 @@ maybe_backup_file (const char *file_name, bool this_is_the_archive)
possible, real problems are unlikely. Doing any better would require a
convention, GNU-wide, for all programs doing backups. */
assign_string (&after_backup_name, 0);
assign_null (&after_backup_name);
/* Check if we really need to backup the file. */
@@ -727,7 +755,7 @@ maybe_backup_file (const char *file_name, bool this_is_the_archive)
&& (S_ISBLK (file_stat.st_mode) || S_ISCHR (file_stat.st_mode)))
return true;
after_backup_name = find_backup_file_name (file_name, backup_type);
after_backup_name = find_backup_file_name (chdir_fd, file_name, backup_type);
if (! after_backup_name)
xalloc_die ();
@@ -747,7 +775,7 @@ maybe_backup_file (const char *file_name, bool this_is_the_archive)
ERROR ((0, e, _("%s: Cannot rename to %s"),
quotearg_colon (before_backup_name),
quote_n (1, after_backup_name)));
assign_string (&after_backup_name, 0);
assign_null (&after_backup_name);
return false;
}
}
@@ -771,7 +799,7 @@ undo_last_backup (void)
fprintf (stdlis, _("Renaming %s back to %s\n"),
quote_n (0, after_backup_name),
quote_n (1, before_backup_name));
assign_string (&after_backup_name, 0);
assign_null (&after_backup_name);
}
}
@@ -793,7 +821,7 @@ deref_stat (char const *name, struct stat *buf)
size_t
blocking_read (int fd, void *buf, size_t count)
{
size_t bytes = safe_read (fd, buf, count);
size_t bytes = full_read (fd, buf, count);
#if defined F_SETFL && O_NONBLOCK
if (bytes == SAFE_READ_ERROR && errno == EAGAIN)
@@ -801,10 +829,12 @@ blocking_read (int fd, void *buf, size_t count)
int flags = fcntl (fd, F_GETFL);
if (0 <= flags && flags & O_NONBLOCK
&& fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) != -1)
bytes = safe_read (fd, buf, count);
bytes = full_read (fd, buf, count);
}
#endif
if (bytes == 0 && errno != 0)
bytes = SAFE_READ_ERROR;
return bytes;
}
@@ -897,8 +927,6 @@ chdir_count (void)
int
chdir_arg (char const *dir)
{
char *absdir;
if (wd_count == wd_alloc)
{
if (wd_alloc == 0)
@@ -908,7 +936,7 @@ chdir_arg (char const *dir)
if (! wd_count)
{
wd[wd_count].name = ".";
wd[wd_count].abspath = xgetcwd ();
wd[wd_count].abspath = NULL;
wd[wd_count].fd = AT_FDCWD;
wd_count++;
}
@@ -925,22 +953,8 @@ chdir_arg (char const *dir)
return wd_count - 1;
}
/* 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, dir);
absdir = namebuf_finish (nbuf);
}
else
absdir = 0;
wd[wd_count].name = dir;
wd[wd_count].abspath = absdir;
wd[wd_count].abspath = NULL;
wd[wd_count].fd = 0;
return wd_count++;
}
@@ -1034,9 +1048,47 @@ tar_getcdpath (int idx)
{
static char *cwd;
if (!cwd)
cwd = xgetcwd ();
{
cwd = xgetcwd ();
if (!cwd)
call_arg_fatal ("getcwd", ".");
}
return cwd;
}
if (!wd[idx].abspath)
{
int i;
int save_cwdi = chdir_current;
for (i = idx; i >= 0; i--)
if (wd[i].abspath)
break;
while (++i <= idx)
{
chdir_do (i);
if (i == 0)
{
if ((wd[i].abspath = xgetcwd ()) == NULL)
call_arg_fatal ("getcwd", ".");
}
else if (IS_ABSOLUTE_FILE_NAME (wd[i].name))
/* If the given name is absolute, use it to represent this
directory; otherwise, construct a name based on the
previous -C option. */
wd[i].abspath = xstrdup (wd[i].name);
else
{
namebuf_t nbuf = namebuf_create (wd[i - 1].abspath);
namebuf_add_dir (nbuf, wd[i].name);
wd[i].abspath = namebuf_finish (nbuf);
}
}
chdir_do (save_cwdi);
}
return wd[idx].abspath;
}
@@ -1162,7 +1214,7 @@ xpipe (int fd[2])
PTR) through ((char *) PTR + ALIGNMENT - 1) to be addressable
locations. */
static inline void *
static void *
ptr_align (void *ptr, size_t alignment)
{
char *p0 = ptr;

View File

@@ -1,7 +1,6 @@
/* Various processing of names.
Copyright 1988, 1992, 1994, 1996-2001, 2003-2007, 2009, 2013-2017
Free Software Foundation, Inc.
Copyright 1988-2023 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
@@ -63,89 +62,93 @@ enum
WILDCARDS_OPTION
};
enum
{
GRH_LOCAL,
GRID_LOCAL,
GRH_MATCH,
GRID_MATCH,
};
static struct argp_option names_options[] = {
#define GRID 100
{NULL, 0, NULL, 0,
N_("Local file name selection:"), GRID },
N_("Local file name selection:"), GRH_LOCAL },
{"add-file", ADD_FILE_OPTION, N_("FILE"), 0,
N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 },
N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID_LOCAL },
{"directory", 'C', N_("DIR"), 0,
N_("change to directory DIR"), GRID+1 },
N_("change to directory DIR"), GRID_LOCAL },
{"files-from", 'T', N_("FILE"), 0,
N_("get names to extract or create from FILE"), GRID+1 },
N_("get names to extract or create from FILE"), GRID_LOCAL },
{"null", NULL_OPTION, 0, 0,
N_("-T reads null-terminated names; implies --verbatim-files-from"),
GRID+1 },
GRID_LOCAL },
{"no-null", NO_NULL_OPTION, 0, 0,
N_("disable the effect of the previous --null option"), GRID+1 },
N_("disable the effect of the previous --null option"), GRID_LOCAL },
{"unquote", UNQUOTE_OPTION, 0, 0,
N_("unquote input file or member names (default)"), GRID+1 },
N_("unquote input file or member names (default)"), GRID_LOCAL },
{"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
N_("do not unquote input file or member names"), GRID+1 },
N_("do not unquote input file or member names"), GRID_LOCAL },
{"verbatim-files-from", VERBATIM_FILES_FROM_OPTION, 0, 0,
N_("-T reads file names verbatim (no escape or option handling)"), GRID+1 },
N_("-T reads file names verbatim (no escape or option handling)"), GRID_LOCAL },
{"no-verbatim-files-from", NO_VERBATIM_FILES_FROM_OPTION, 0, 0,
N_("-T treats file names starting with dash as options (default)"),
GRID+1 },
GRID_LOCAL },
{"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0,
N_("exclude files, given as a PATTERN"), GRID+1 },
N_("exclude files, given as a PATTERN"), GRID_LOCAL },
{"exclude-from", 'X', N_("FILE"), 0,
N_("exclude patterns listed in FILE"), GRID+1 },
N_("exclude patterns listed in FILE"), GRID_LOCAL },
{"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
N_("exclude contents of directories containing CACHEDIR.TAG, "
"except for the tag file itself"), GRID+1 },
"except for the tag file itself"), GRID_LOCAL },
{"exclude-caches-under", EXCLUDE_CACHES_UNDER_OPTION, 0, 0,
N_("exclude everything under directories containing CACHEDIR.TAG"),
GRID+1 },
GRID_LOCAL },
{"exclude-caches-all", EXCLUDE_CACHES_ALL_OPTION, 0, 0,
N_("exclude directories containing CACHEDIR.TAG"), GRID+1 },
N_("exclude directories containing CACHEDIR.TAG"), GRID_LOCAL },
{"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
N_("exclude contents of directories containing FILE, except"
" for FILE itself"), GRID+1 },
" for FILE itself"), GRID_LOCAL },
{"exclude-ignore", EXCLUDE_IGNORE_OPTION, N_("FILE"), 0,
N_("read exclude patterns for each directory from FILE, if it exists"),
GRID+1 },
GRID_LOCAL },
{"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 },
"from FILE, if it exists"), GRID_LOCAL },
{"exclude-tag-under", EXCLUDE_TAG_UNDER_OPTION, N_("FILE"), 0,
N_("exclude everything under directories containing FILE"), GRID+1 },
N_("exclude everything under directories containing FILE"), GRID_LOCAL },
{"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION, N_("FILE"), 0,
N_("exclude directories containing FILE"), GRID+1 },
N_("exclude directories containing FILE"), GRID_LOCAL },
{"exclude-vcs", EXCLUDE_VCS_OPTION, NULL, 0,
N_("exclude version control system directories"), GRID+1 },
N_("exclude version control system directories"), GRID_LOCAL },
{"exclude-vcs-ignores", EXCLUDE_VCS_IGNORES_OPTION, NULL, 0,
N_("read exclude patterns from the VCS ignore files"), GRID+1 },
N_("read exclude patterns from the VCS ignore files"), GRID_LOCAL },
{"exclude-backups", EXCLUDE_BACKUPS_OPTION, NULL, 0,
N_("exclude backup and lock files"), GRID+1 },
N_("exclude backup and lock files"), GRID_LOCAL },
{"recursion", RECURSION_OPTION, 0, 0,
N_("recurse into directories (default)"), GRID+1 },
N_("recurse into directories (default)"), GRID_LOCAL },
{"no-recursion", NO_RECURSION_OPTION, 0, 0,
N_("avoid descending automatically in directories"), GRID+1 },
#undef GRID
N_("avoid descending automatically in directories"), GRID_LOCAL },
#define GRID 120
{NULL, 0, NULL, 0,
N_("File name matching options (affect both exclude and include patterns):"),
GRID },
GRH_MATCH },
{"anchored", ANCHORED_OPTION, 0, 0,
N_("patterns match file name start"), GRID+1 },
N_("patterns match file name start"), GRID_MATCH },
{"no-anchored", NO_ANCHORED_OPTION, 0, 0,
N_("patterns match after any '/' (default for exclusion)"), GRID+1 },
N_("patterns match after any '/' (default for exclusion)"), GRID_MATCH },
{"ignore-case", IGNORE_CASE_OPTION, 0, 0,
N_("ignore case"), GRID+1 },
N_("ignore case"), GRID_MATCH },
{"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0,
N_("case sensitive matching (default)"), GRID+1 },
N_("case sensitive matching (default)"), GRID_MATCH },
{"wildcards", WILDCARDS_OPTION, 0, 0,
N_("use wildcards (default for exclusion)"), GRID+1 },
N_("use wildcards (default for exclusion)"), GRID_MATCH },
{"no-wildcards", NO_WILDCARDS_OPTION, 0, 0,
N_("verbatim string matching"), GRID+1 },
N_("verbatim string matching"), GRID_MATCH },
{"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
N_("wildcards match '/' (default for exclusion)"), GRID+1 },
N_("wildcards match '/' (default for exclusion)"), GRID_MATCH },
{"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
N_("wildcards do not match '/'"), GRID+1 },
#undef GRID
N_("wildcards do not match '/'"), GRID_MATCH },
{NULL}
};
@@ -197,11 +200,24 @@ names_parse_opt (int key, char *arg, struct argp_state *state)
name_add_name (arg);
break;
case ARGP_KEY_ERROR:
{
struct tar_args *args = state->input;
if (args->loc->source == OPTS_FILE)
{
error (0, 0, _("%s:%lu: unrecognized option"), args->loc->name,
(unsigned long) args->loc->line);
set_exit_status (TAREXIT_FAILURE);
}
return ARGP_ERR_UNKNOWN;
}
default:
if (is_file_selection_option (key))
name_add_option (key, arg);
else
return ARGP_ERR_UNKNOWN;
}
return 0;
}
@@ -332,7 +348,7 @@ handle_file_selection_option (int key, const char *arg)
break;
case EXCLUDE_VCS_OPTION:
add_exclude_array (vcs_file_table, 0);
add_exclude_array (vcs_file_table, FNM_LEADING_DIR);
break;
case EXCLUDE_VCS_IGNORES_OPTION:
@@ -379,7 +395,7 @@ handle_file_selection_option (int key, const char *arg)
break;
case NO_ANCHORED_OPTION:
include_anchored = 0; /* Clear the default for comman line args */
include_anchored = 0; /* Clear the default for command line args */
matching_flags &= ~ EXCLUDE_ANCHORED;
break;
@@ -420,7 +436,7 @@ handle_file_selection_option (int key, const char *arg)
}
}
static struct argp names_argp = {
struct argp names_argp = {
names_options,
names_parse_opt,
NULL,
@@ -430,10 +446,6 @@ static struct argp names_argp = {
NULL
};
struct argp_child names_argp_children[] = {
{ &names_argp, 0, "", 0 },
{ NULL }
};
/* User and group names. */
@@ -652,8 +664,10 @@ struct name_elt /* A name_array element. */
} v;
};
static struct name_elt *name_head;/* store a list of names */
size_t name_count; /* how many of the entries are file names? */
static struct name_elt *name_head; /* store a list of names */
/* how many of the entries are file names? */
enum files_count filename_args = FILES_NONE;
static struct name_elt *
name_elt_alloc (void)
@@ -730,7 +744,7 @@ unconsumed_option_report (void)
{
struct name_elt *elt;
ERROR ((0, 0, _("The following options were used after any non-optional arguments in archive create or update mode. These options are positional and affect only arguments that follow them. Please, rearrange them properly.")));
ERROR ((0, 0, _("The following options were used after non-option arguments. These options are positional and affect only arguments that follow them. Please, rearrange them properly.")));
elt = unconsumed_option_tail;
while (elt->prev)
@@ -785,13 +799,6 @@ name_list_advance (void)
}
}
/* Return true if there are names or options in the list */
bool
name_more_files (void)
{
return name_count > 0;
}
/* Add to name_array the file NAME with fnmatch options MATFLAGS */
void
name_add_name (const char *name)
@@ -800,7 +807,20 @@ name_add_name (const char *name)
ep->type = NELT_NAME;
ep->v.name = name;
name_count++;
switch (filename_args)
{
case FILES_NONE:
filename_args = FILES_ONE;
break;
case FILES_ONE:
filename_args = FILES_MANY;
break;
default:
break;
}
}
static void
@@ -830,7 +850,10 @@ name_add_file (const char *name)
ep->v.file.name = name;
ep->v.file.line = 0;
ep->v.file.fp = NULL;
name_count++;
/* We don't know beforehand how many files are listed.
Assume more than one. */
filename_args = FILES_MANY;
}
/* Names from external name file. */
@@ -957,7 +980,6 @@ 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;
}
@@ -1006,8 +1028,10 @@ read_next_name (struct name_elt *ent, struct name_elt *ret)
name_list_advance ();
return 1;
}
if ((ent->v.file.fp = fopen (ent->v.file.name, "r")) == NULL)
FILE *fp = fopen (ent->v.file.name, "r");
if (!fp)
open_fatal (ent->v.file.name);
ent->v.file.fp = fp;
}
ent->v.file.term = filename_terminator;
ent->v.file.verbatim = verbatim_files_from_option;
@@ -1037,6 +1061,7 @@ read_next_name (struct name_elt *ent, struct name_elt *ret)
return 1;
}
}
chopslash (name_buffer);
ret->type = NELT_NAME;
ret->v.name = name_buffer;
return 0;
@@ -1059,19 +1084,8 @@ copy_name (struct name_elt *ep)
source = ep->v.name;
source_len = strlen (source);
if (name_buffer_length < source_len)
{
do
{
name_buffer_length *= 2;
if (! name_buffer_length)
xalloc_die ();
}
while (name_buffer_length < source_len);
free (name_buffer);
name_buffer = xmalloc(name_buffer_length + 2);
}
while (name_buffer_length <= source_len)
name_buffer = x2realloc(name_buffer, &name_buffer_length);
strcpy (name_buffer, source);
chopslash (name_buffer);
}
@@ -1139,6 +1153,13 @@ name_next (int change_dirs)
return nelt ? nelt->v.name : NULL;
}
static bool
name_is_wildcard (struct name const *name)
{
return (name->matching_flags & EXCLUDE_WILDCARDS) &&
fnmatch_pattern_has_wildcards (name->name, name->matching_flags);
}
/* Gather names in a list for scanning. Could hash them later if we
really care.
@@ -1175,6 +1196,7 @@ name_gather (void)
buffer->directory = NULL;
buffer->parent = NULL;
buffer->cmdline = true;
buffer->is_wildcard = name_is_wildcard (buffer);
namelist = nametail = buffer;
}
@@ -1218,6 +1240,7 @@ addname (char const *string, int change_dir, bool cmdline, struct name *parent)
name->directory = NULL;
name->parent = parent;
name->cmdline = cmdline;
name->is_wildcard = name_is_wildcard (name);
if (nametail)
nametail->next = name;
@@ -1227,16 +1250,46 @@ addname (char const *string, int change_dir, bool cmdline, struct name *parent)
return name;
}
/* Find a match for FILE_NAME (whose string length is LENGTH) in the name
list. */
void
add_starting_file (char const *file_name)
{
struct name *name = make_name (file_name);
if (starting_file_option)
{
struct name *head = namelist;
remname (head);
free_name (head);
}
name->prev = NULL;
name->next = namelist;
namelist = name;
if (!nametail)
nametail = namelist;
name->found_count = 0;
name->matching_flags = INCLUDE_OPTIONS;
name->change_dir = 0;
name->directory = NULL;
name->parent = NULL;
name->cmdline = true;
name->is_wildcard = name_is_wildcard (name);
starting_file_option = true;
}
/* Find a match for FILE_NAME in the name list. If EXACT is true,
look for exact match (no wildcards). */
static struct name *
namelist_match (char const *file_name, size_t length)
namelist_match (char const *file_name, bool exact)
{
struct name *p;
for (p = namelist; p; p = p->next)
{
if (p->name[0]
&& (exact ? !p->is_wildcard : true)
&& exclude_fnmatch (p->name, file_name, p->matching_flags))
return p;
}
@@ -1265,8 +1318,6 @@ remname (struct name *name)
bool
name_match (const char *file_name)
{
size_t length = strlen (file_name);
while (1)
{
struct name *cursor = namelist;
@@ -1282,20 +1333,23 @@ name_match (const char *file_name)
return true;
}
cursor = namelist_match (file_name, length);
cursor = namelist_match (file_name, false);
if (starting_file_option)
{
/* If starting_file_option is set, the head of the list is the name
of the member to start extraction from. Skip the match unless it
is head. */
if (cursor == namelist)
starting_file_option = false;
else
cursor = NULL;
}
if (cursor)
{
if (!(ISSLASH (file_name[cursor->length]) && recursion_option)
|| cursor->found_count == 0)
cursor->found_count++; /* remember it matched */
if (starting_file_option)
{
free (namelist);
namelist = NULL;
nametail = NULL;
}
chdir_do (cursor->change_dir);
/* We got a match. */
return ISFOUND (cursor);
}
@@ -1561,9 +1615,8 @@ add_hierarchy_to_namelist (struct tar_stat_info *st, struct name *name)
size_t name_length = name->length;
size_t allocated_length = (name_length >= NAME_FIELD_SIZE
? name_length + NAME_FIELD_SIZE
: NAME_FIELD_SIZE);
char *namebuf = xmalloc (allocated_length + 1);
/* FIXME: + 2 above? */
: NAME_FIELD_SIZE) + 2;
char *namebuf = xmalloc (allocated_length);
const char *string;
size_t string_length;
int change_dir = name->change_dir;
@@ -1584,18 +1637,10 @@ add_hierarchy_to_namelist (struct tar_stat_info *st, struct name *name)
struct tar_stat_info subdir;
int subfd;
if (allocated_length <= name_length + string_length)
{
do
{
allocated_length *= 2;
if (! allocated_length)
xalloc_die ();
}
while (allocated_length <= name_length + string_length);
namebuf = xrealloc (namebuf, allocated_length + 1);
}
/* need to have at least string_length bytes above the
name_length, this includes the trailing null character */
while (allocated_length < name_length + string_length)
namebuf = x2realloc (namebuf, &allocated_length);
strcpy (namebuf + name_length, string + 1);
np = addname (namebuf, change_dir, false, name);
if (!child_head)
@@ -1767,6 +1812,11 @@ collect_and_sort_names (void)
name->found_count++;
add_hierarchy_to_namelist (&st, name);
}
else
{
errno = ENOTDIR;
open_diag (name->name);
}
}
}
@@ -1791,7 +1841,7 @@ collect_and_sort_names (void)
{
if (p->child)
rebase_child_list (p->child, name);
hash_delete (nametab, name);
hash_remove (nametab, name);
/* FIXME: remove_directory (p->caname); ? */
remname (p);
free_name (p);
@@ -1821,7 +1871,7 @@ collect_and_sort_names (void)
if (listed_incremental_option)
{
for (name = namelist; name && name->name[0] == 0; name++)
for (name = namelist; name && name->name[0] == 0; name = name->next)
;
if (name)
append_incremental_renames (name->directory);
@@ -1832,15 +1882,14 @@ collect_and_sort_names (void)
1. It returns a pointer to the name it matched, and doesn't set FOUND
in structure. The caller will have to do that if it wants to.
2. If the namelist is empty, it returns null, unlike name_match, which
returns TRUE. */
returns TRUE.
3. If EXACT is true, it looks for exact matches only (no wildcards). */
struct name *
name_scan (const char *file_name)
name_scan (const char *file_name, bool exact)
{
size_t length = strlen (file_name);
while (1)
{
struct name *cursor = namelist_match (file_name, length);
struct name *cursor = namelist_match (file_name, exact);
if (cursor)
return cursor;
@@ -1860,9 +1909,10 @@ name_scan (const char *file_name)
}
}
/* This returns a name from the namelist which doesn't have ->found
set. It sets ->found before returning, so successive calls will
find and return all the non-found names in the namelist. */
/* This returns a name from the namelist which is an exact match (i.e.
not a pattern) and doesn't have ->found set. It sets ->found before
returning, so successive calls will find and return all the non-found
names in the namelist. */
struct name *gnu_list_name;
struct name const *
@@ -1871,11 +1921,13 @@ name_from_list (void)
if (!gnu_list_name)
gnu_list_name = namelist;
while (gnu_list_name
&& (gnu_list_name->found_count || gnu_list_name->name[0] == 0))
&& (gnu_list_name->is_wildcard ||
gnu_list_name->found_count || gnu_list_name->name[0] == 0))
gnu_list_name = gnu_list_name->next;
if (gnu_list_name)
{
gnu_list_name->found_count++;
if (!gnu_list_name->is_wildcard)
gnu_list_name->found_count++;
chdir_do (gnu_list_name->change_dir);
return gnu_list_name;
}

View File

@@ -1,6 +1,6 @@
/* Functions for dealing with sparse files
Copyright 2003-2007, 2010, 2013-2017 Free Software Foundation, Inc.
Copyright 2003-2023 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
@@ -335,8 +335,6 @@ sparse_scan_file_seek (struct tar_sparse_file *file)
st->archive_file_size += sp.numbytes;
offset = hole_offset;
}
return true;
}
#endif
@@ -417,7 +415,7 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i)
size_t bytes_read;
blk = find_next_block ();
bytes_read = safe_read (file->fd, blk->buffer, bufsize);
bytes_read = full_read (file->fd, blk->buffer, bufsize);
if (bytes_read == SAFE_READ_ERROR)
{
read_diag_details (file->stat_info->orig_file_name,
@@ -427,6 +425,42 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i)
bufsize);
return false;
}
else if (bytes_read == 0)
{
if (errno != 0)
{
read_diag_details (file->stat_info->orig_file_name,
(file->stat_info->sparse_map[i].offset
+ file->stat_info->sparse_map[i].numbytes
- bytes_left),
bufsize);
return false;
}
else
{
char buf[UINTMAX_STRSIZE_BOUND];
struct stat st;
size_t n;
if (fstat (file->fd, &st) == 0)
n = file->stat_info->stat.st_size - st.st_size;
else
n = file->stat_info->stat.st_size
- (file->stat_info->sparse_map[i].offset
+ file->stat_info->sparse_map[i].numbytes
- bytes_left);
WARNOPT (WARN_FILE_SHRANK,
(0, 0,
ngettext ("%s: File shrank by %s byte; padding with zeros",
"%s: File shrank by %s bytes; padding with zeros",
n),
quotearg_colon (file->stat_info->orig_file_name),
STRINGIFY_BIGINT (n, buf)));
if (! ignore_failed_read_option)
set_exit_status (TAREXIT_DIFFERS);
return false;
}
}
memset (blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read);
bytes_left -= bytes_read;
@@ -464,9 +498,9 @@ sparse_extract_region (struct tar_sparse_file *file, size_t i)
return false;
}
set_next_block_after (blk);
file->dumped_size += BLOCKSIZE;
count = blocking_write (file->fd, blk->buffer, wrbytes);
write_size -= count;
file->dumped_size += count;
mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
file->offset += count;
if (count != wrbytes)
@@ -546,7 +580,10 @@ sparse_extract_file (int fd, struct tar_stat_info *st, off_t *size)
size_t i;
if (!tar_sparse_init (&file))
return dump_status_not_implemented;
{
*size = st->stat.st_size;
return dump_status_not_implemented;
}
file.stat_info = st;
file.fd = fd;
@@ -561,7 +598,7 @@ sparse_extract_file (int fd, struct tar_stat_info *st, off_t *size)
}
enum dump_status
sparse_skip_file (struct tar_stat_info *st)
sparse_skim_file (struct tar_stat_info *st, bool must_copy)
{
bool rc = true;
struct tar_sparse_file file;
@@ -573,7 +610,7 @@ sparse_skip_file (struct tar_stat_info *st)
file.fd = -1;
rc = tar_sparse_decode_header (&file);
skip_file (file.stat_info->archive_file_size - file.dumped_size);
skim_file (file.stat_info->archive_file_size - file.dumped_size, must_copy);
return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short;
}
@@ -590,7 +627,7 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
size_t rdsize = BLOCKSIZE < end - beg ? BLOCKSIZE : end - beg;
char diff_buffer[BLOCKSIZE];
bytes_read = safe_read (file->fd, diff_buffer, rdsize);
bytes_read = full_read (file->fd, diff_buffer, rdsize);
if (bytes_read == SAFE_READ_ERROR)
{
read_diag_details (file->stat_info->orig_file_name,
@@ -598,6 +635,17 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
rdsize);
return false;
}
else if (bytes_read == 0)
{
if (errno != 0)
read_diag_details (file->stat_info->orig_file_name,
beg,
rdsize);
else
report_difference (file->stat_info, _("Size differs"));
return false;
}
if (!zero_block_p (diff_buffer, bytes_read))
{
char begbuf[INT_BUFSIZE_BOUND (off_t)];
@@ -609,6 +657,7 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
beg += bytes_read;
}
return true;
}
@@ -635,7 +684,8 @@ check_data_region (struct tar_sparse_file *file, size_t i)
return false;
}
set_next_block_after (blk);
bytes_read = safe_read (file->fd, diff_buffer, rdsize);
file->dumped_size += BLOCKSIZE;
bytes_read = full_read (file->fd, diff_buffer, rdsize);
if (bytes_read == SAFE_READ_ERROR)
{
read_diag_details (file->stat_info->orig_file_name,
@@ -645,10 +695,21 @@ check_data_region (struct tar_sparse_file *file, size_t i)
rdsize);
return false;
}
file->dumped_size += bytes_read;
else if (bytes_read == 0)
{
if (errno != 0)
read_diag_details (file->stat_info->orig_file_name,
(file->stat_info->sparse_map[i].offset
+ file->stat_info->sparse_map[i].numbytes
- size_left),
rdsize);
else
report_difference (&current_stat_info, _("Size differs"));
return false;
}
size_left -= bytes_read;
mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
if (memcmp (blk->buffer, diff_buffer, rdsize))
if (memcmp (blk->buffer, diff_buffer, bytes_read))
{
report_difference (file->stat_info, _("Contents differ"));
return false;
@@ -666,7 +727,7 @@ sparse_diff_file (int fd, struct tar_stat_info *st)
off_t offset = 0;
if (!tar_sparse_init (&file))
return dump_status_not_implemented;
return false;
file.stat_info = st;
file.fd = fd;
@@ -684,7 +745,7 @@ sparse_diff_file (int fd, struct tar_stat_info *st)
}
if (!rc)
skip_file (file.stat_info->archive_file_size - file.dumped_size);
skim_file (file.stat_info->archive_file_size - file.dumped_size, false);
mv_end ();
tar_sparse_done (&file);
@@ -718,7 +779,7 @@ enum oldgnu_add_status
};
static bool
oldgnu_sparse_member_p (struct tar_sparse_file *file __attribute__ ((unused)))
oldgnu_sparse_member_p (MAYBE_UNUSED struct tar_sparse_file *file)
{
return current_header->header.typeflag == GNUTYPE_SPARSE;
}
@@ -862,7 +923,7 @@ static struct tar_sparse_optab const oldgnu_optab = {
/* Star */
static bool
star_sparse_member_p (struct tar_sparse_file *file __attribute__ ((unused)))
star_sparse_member_p (MAYBE_UNUSED struct tar_sparse_file *file)
{
return current_header->header.typeflag == GNUTYPE_SPARSE;
}
@@ -982,7 +1043,7 @@ static struct tar_sparse_optab const star_optab = {
* 1.0
Starting from this version, the exact sparse format version is specified
explicitely in the header using the following variables:
explicitly in the header using the following variables:
GNU.sparse.major Major version
GNU.sparse.minor Minor version
@@ -1213,6 +1274,7 @@ pax_decode_header (struct tar_sparse_file *file)
union block *blk;
char *p;
size_t i;
off_t start;
#define COPY_BUF(b,buf,src) do \
{ \
@@ -1229,8 +1291,9 @@ pax_decode_header (struct tar_sparse_file *file)
if (src == endp) \
{ \
set_next_block_after (b); \
file->dumped_size += BLOCKSIZE; \
b = find_next_block (); \
if (!b) \
FATAL_ERROR ((0, 0, _("Unexpected EOF in archive"))); \
src = b->buffer; \
endp = b->buffer + BLOCKSIZE; \
} \
@@ -1240,9 +1303,11 @@ pax_decode_header (struct tar_sparse_file *file)
dst[-1] = 0; \
} while (0)
start = current_block_ordinal ();
set_next_block_after (current_header);
file->dumped_size += BLOCKSIZE;
blk = find_next_block ();
if (!blk)
FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
p = blk->buffer;
COPY_BUF (blk,nbuf,p);
if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t)))
@@ -1268,7 +1333,9 @@ pax_decode_header (struct tar_sparse_file *file)
}
sp.offset = u;
COPY_BUF (blk,nbuf,p);
if (!decode_num (&u, nbuf, TYPE_MAXIMUM (off_t)))
if (!decode_num (&u, nbuf, TYPE_MAXIMUM (off_t))
|| INT_ADD_OVERFLOW (sp.offset, u)
|| file->stat_info->stat.st_size < sp.offset + u)
{
ERROR ((0, 0, _("%s: malformed sparse archive member"),
file->stat_info->orig_file_name));
@@ -1278,6 +1345,8 @@ pax_decode_header (struct tar_sparse_file *file)
sparse_add_map (file->stat_info, &sp);
}
set_next_block_after (blk);
file->dumped_size += BLOCKSIZE * (current_block_ordinal () - start);
}
return true;

View File

@@ -1,6 +1,5 @@
/* This file is part of GNU tar.
Copyright 2007, 2009, 2013-2014, 2016-2017 Free Software Foundation,
Inc.
Copyright 2007-2023 Free Software Foundation, Inc.
Written by Sergey Poznyakoff.
@@ -46,6 +45,8 @@ static struct compression_suffix compression_suffixes[] = {
{ S(lzo, LZOP) },
{ S(xz, XZ) },
{ S(txz, XZ) }, /* Slackware */
{ S(zst, ZSTD) },
{ S(tzst, ZSTD) },
{ NULL }
#undef S
#undef __CAT2__
@@ -60,7 +61,7 @@ find_compression_suffix (const char *name, size_t *ret_len)
{
size_t len;
struct compression_suffix *p;
suf++;
len = strlen (suf);
@@ -99,10 +100,14 @@ strip_compression_suffix (const char *name)
{
char *s = NULL;
size_t len;
struct compression_suffix const *p = find_compression_suffix (name, &len);
if (find_compression_suffix (name, &len))
if (p)
{
if (strncmp (name + len - 4, ".tar", 4) == 0)
/* Strip an additional ".tar" suffix, but only if the just-stripped
"outer" suffix did not begin with "t". */
if (len > 4 && strncmp (name + len - 4, ".tar", 4) == 0
&& p->suffix[0] != 't')
len -= 4;
if (len == 0)
return NULL;
@@ -112,4 +117,3 @@ strip_compression_suffix (const char *name)
}
return s;
}

View File

@@ -1,7 +1,6 @@
/* System-dependent calls for tar.
Copyright 2003-2008, 2010, 2013-2014, 2016-2017 Free Software
Foundation, Inc.
Copyright 2003-2023 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
@@ -17,6 +16,7 @@
with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <system.h>
#include <system-ioctl.h>
#include "common.h"
#include <priv-set.h>
@@ -38,6 +38,35 @@ xexec (const char *cmd)
exec_fatal (cmd);
}
/* True if the archive is seekable via ioctl and MTIOCTOP,
or if it is not known whether it is seekable.
False if it is known to be not seekable. */
static bool mtioseekable_archive;
bool
mtioseek (bool count_files, off_t count)
{
if (mtioseekable_archive)
{
#ifdef MTIOCTOP
struct mtop operation;
operation.mt_op = (count_files
? (count < 0 ? MTBSF : MTFSF)
: (count < 0 ? MTBSR : MTFSR));
if (! (count < 0
? INT_SUBTRACT_WRAPV (0, count, &operation.mt_count)
: INT_ADD_WRAPV (count, 0, &operation.mt_count))
&& (0 <= rmtioctl (archive, MTIOCTOP, &operation)
|| (errno == EIO
&& 0 <= rmtioctl (archive, MTIOCTOP, &operation))))
return true;
#endif
mtioseekable_archive = false;
}
return false;
}
#if MSDOS
bool
@@ -52,11 +81,6 @@ sys_file_is_archive (struct tar_stat_info *p)
return false;
}
void
sys_save_archive_dev_ino (void)
{
}
void
sys_detect_dev_null_output (void)
{
@@ -129,31 +153,34 @@ sys_child_open_for_uncompress (void)
extern union block *record_start; /* FIXME */
static struct stat archive_stat; /* stat block for archive file */
bool
sys_get_archive_stat (void)
{
return fstat (archive, &archive_stat) == 0;
bool remote = _isrmt (archive);
mtioseekable_archive = true;
if (!remote && 0 <= archive && fstat (archive, &archive_stat) == 0)
{
if (!S_ISCHR (archive_stat.st_mode))
mtioseekable_archive = false;
return true;
}
else
{
/* FIXME: This memset should not be needed. It is present only
because other parts of tar may incorrectly access
archive_stat even if it's not the archive status. */
memset (&archive_stat, 0, sizeof archive_stat);
return remote;
}
}
bool
sys_file_is_archive (struct tar_stat_info *p)
{
return (ar_dev && p->stat.st_dev == ar_dev && p->stat.st_ino == ar_ino);
}
/* Save archive file inode and device numbers */
void
sys_save_archive_dev_ino (void)
{
if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode))
{
ar_dev = archive_stat.st_dev;
ar_ino = archive_stat.st_ino;
}
else
ar_dev = 0;
return (!dev_null_output && !_isrmt (archive)
&& p->stat.st_dev == archive_stat.st_dev
&& p->stat.st_ino == archive_stat.st_ino);
}
/* Detect if outputting to "/dev/null". */
@@ -161,14 +188,15 @@ void
sys_detect_dev_null_output (void)
{
static char const dev_null[] = "/dev/null";
struct stat dev_null_stat;
static struct stat dev_null_stat;
dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
|| (! _isrmt (archive)
&& S_ISCHR (archive_stat.st_mode)
&& stat (dev_null, &dev_null_stat) == 0
&& archive_stat.st_dev == dev_null_stat.st_dev
&& archive_stat.st_ino == dev_null_stat.st_ino));
&& (dev_null_stat.st_ino != 0
|| stat (dev_null, &dev_null_stat) == 0)
&& archive_stat.st_ino == dev_null_stat.st_ino
&& archive_stat.st_dev == dev_null_stat.st_dev));
}
void
@@ -271,6 +299,11 @@ sys_write_archive_buffer (void)
#define PREAD 0 /* read file descriptor from pipe() */
#define PWRITE 1 /* write file descriptor from pipe() */
/* Work around GCC bug 109839. */
#if 13 <= __GNUC__
# pragma GCC diagnostic ignored "-Wanalyzer-fd-leak"
#endif
/* Duplicate file descriptor FROM into becoming INTO.
INTO is closed first and has to be the next available slot. */
static void
@@ -278,31 +311,17 @@ xdup2 (int from, int into)
{
if (from != into)
{
int status = close (into);
if (status != 0 && errno != EBADF)
if (dup2 (from, into) < 0)
{
int e = errno;
FATAL_ERROR ((0, e, _("Cannot close")));
}
status = dup (from);
if (status != into)
{
if (status < 0)
{
int e = errno;
FATAL_ERROR ((0, e, _("Cannot dup")));
}
abort ();
FATAL_ERROR ((0, e, _("Cannot dup2")));
}
xclose (from);
}
}
static void wait_for_grandchild (pid_t pid) __attribute__ ((__noreturn__));
/* Propagate any failure of the grandchild back to the parent. */
static void
static _Noreturn void
wait_for_grandchild (pid_t pid)
{
int wait_status;
@@ -541,7 +560,7 @@ sys_child_open_for_uncompress (void)
&& !_remdev (archive_name_array[0])
&& is_regular_file (archive_name_array[0]))
{
/* We don't need a grandchild tar. Open the archive and lauch the
/* We don't need a grandchild tar. Open the archive and launch the
uncompressor. */
archive = open (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW);

815
src/tar.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,6 @@
/* GNU tar Archive Format description.
Copyright 1988-1989, 1991-1997, 2000-2001, 2003-2007, 2012-2014,
2016-2017 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -285,6 +284,13 @@ struct xattr_array
size_t xval_len;
};
struct xattr_map
{
struct xattr_array *xm_map;
size_t xm_size; /* Size of the xattr map */
size_t xm_max; /* Max. number of entries in xattr_map */
};
struct tar_stat_info
{
char *orig_file_name; /* name of file read from the archive header */
@@ -335,8 +341,7 @@ struct tar_stat_info
processed pax header parsing. Following 'path'
header (lower priority) will be ignored. */
size_t xattr_map_size; /* Size of the xattr map */
struct xattr_array *xattr_map;
struct xattr_map xattr_map;
/* Extended headers */
struct xheader xhdr;

View File

@@ -1,6 +1,5 @@
/* This file is part of GNU tar.
Copyright 2006-2008, 2013-2014, 2016-2017 Free Software Foundation,
Inc.
Copyright 2006-2023 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
@@ -101,7 +100,7 @@ add_segment (struct transform *tf)
}
static void
add_literal_segment (struct transform *tf, char *str, char *end)
add_literal_segment (struct transform *tf, const char *str, const char *end)
{
size_t len = end - str;
if (len)
@@ -209,6 +208,8 @@ parse_transform_expr (const char *expr)
}
delim = expr[1];
if (!delim)
USAGE_ERROR ((0, 0, _("Invalid transform expression")));
/* Scan regular expression */
for (i = 2; expr[i] && expr[i] != delim; i++)
@@ -273,7 +274,7 @@ parse_transform_expr (const char *expr)
USAGE_ERROR ((0, 0, _("Invalid transform expression: %s"), errbuf));
}
if (str[0] == '^' || str[strlen (str) - 1] == '$')
if (str[0] == '^' || (i > 2 && str[i - 3] == '$'))
tf->transform_type = transform_first;
free (str);
@@ -403,6 +404,7 @@ parse_transform_expr (const char *expr)
cur++;
}
add_literal_segment (tf, beg, cur);
free(str);
return p;
}
@@ -491,9 +493,6 @@ _single_transform_name_to_obstack (struct transform *tf, char *input)
disp = rmp[0].rm_eo;
if (rmp[0].rm_so)
obstack_grow (&stk, input, rmp[0].rm_so);
nmatches++;
if (tf->match_number && nmatches < tf->match_number)
{
@@ -502,6 +501,9 @@ _single_transform_name_to_obstack (struct transform *tf, char *input)
continue;
}
if (rmp[0].rm_so)
obstack_grow (&stk, input, rmp[0].rm_so);
for (segm = tf->repl_head; segm; segm = segm->next)
{
switch (segm->type)
@@ -550,7 +552,7 @@ _single_transform_name_to_obstack (struct transform *tf, char *input)
default:
break;
}
/*FALL THROUGH*/
FALLTHROUGH;
case ctl_upcase:
case ctl_locase:

View File

@@ -1,6 +1,6 @@
/* Unlink files.
Copyright 2009, 2013-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 2009-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -127,7 +127,9 @@ flush_deferred_unlinks (bool force)
case EEXIST:
/* OpenSolaris >=10 sets EEXIST instead of ENOTEMPTY
if trying to remove a non-empty directory */
#if defined ENOTEMPTY && ENOTEMPTY != EEXIST
case ENOTEMPTY:
#endif
/* Keep the record in list, in the hope we'll
be able to remove it later */
prev = p;

View File

@@ -1,7 +1,6 @@
/* Update a tar archive.
Copyright 1988, 1992, 1994, 1996-1997, 1999-2001, 2003-2005, 2007,
2010, 2013-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -43,13 +42,14 @@ bool time_to_start_writing;
first part of the record. */
char *output_start;
static bool acting_as_filter;
/* Catenate file FILE_NAME to the archive without creating a header for it.
It had better be a tar file or the archive is screwed. */
static void
append_file (char *file_name)
{
int handle = openat (chdir_fd, file_name, O_RDONLY | O_BINARY);
struct stat stat_data;
if (handle < 0)
{
@@ -57,49 +57,48 @@ append_file (char *file_name)
return;
}
if (fstat (handle, &stat_data) != 0)
stat_error (file_name);
else
while (true)
{
off_t bytes_left = stat_data.st_size;
while (bytes_left > 0)
union block *start = find_next_block ();
size_t status = full_read (handle, start->buffer,
available_space_after (start));
if (status == 0)
{
union block *start = find_next_block ();
size_t buffer_size = available_space_after (start);
size_t status;
char buf[UINTMAX_STRSIZE_BOUND];
if (bytes_left < buffer_size)
{
buffer_size = bytes_left;
status = buffer_size % BLOCKSIZE;
if (status)
memset (start->buffer + bytes_left, 0, BLOCKSIZE - status);
}
status = safe_read (handle, start->buffer, buffer_size);
if (status == SAFE_READ_ERROR)
read_fatal_details (file_name, stat_data.st_size - bytes_left,
buffer_size);
if (status == 0)
FATAL_ERROR ((0, 0,
ngettext ("%s: File shrank by %s byte",
"%s: File shrank by %s bytes",
bytes_left),
quotearg_colon (file_name),
STRINGIFY_BIGINT (bytes_left, buf)));
bytes_left -= status;
set_next_block_after (start + (status - 1) / BLOCKSIZE);
if (errno == 0)
break;
read_fatal (file_name);
}
if (status == SAFE_READ_ERROR)
read_fatal (file_name);
if (status % BLOCKSIZE)
memset (start->buffer + status - status % BLOCKSIZE, 0,
BLOCKSIZE - status % BLOCKSIZE);
set_next_block_after (start + (status - 1) / BLOCKSIZE);
}
if (close (handle) != 0)
close_error (file_name);
}
/* If NAME is not a pattern, remove it from the namelist. Otherwise,
remove the FILE_NAME that matched it. Take care to look for exact
match when removing it. */
static void
remove_exact_name (struct name *name, char const *file_name)
{
if (name->is_wildcard)
{
struct name *match = name_scan (file_name, true);
name->found_count++;
if (match)
name = match;
else
return;
}
remname (name);
}
/* Implement the 'r' (add files to end of archive), and 'u' (add files
to end of archive if they aren't there, or are more up to date than
the version in the archive) commands. */
@@ -111,7 +110,8 @@ update_archive (void)
name_gather ();
open_archive (ACCESS_UPDATE);
buffer_write_global_xheader ();
acting_as_filter = strcmp (archive_name_array[0], "-") == 0;
xheader_forbid_global ();
while (!found_end)
{
@@ -136,7 +136,7 @@ update_archive (void)
archive_format = current_format;
if (subcommand_option == UPDATE_SUBCOMMAND
&& (name = name_scan (current_stat_info.file_name)) != NULL)
&& (name = name_scan (current_stat_info.file_name, false)) != NULL)
{
struct stat s;
@@ -145,10 +145,10 @@ update_archive (void)
{
if (S_ISDIR (s.st_mode))
{
char *p, *dirp = tar_savedir (name->name, 1);
char *p, *dirp = tar_savedir (current_stat_info.file_name, 1);
if (dirp)
{
namebuf_t nbuf = namebuf_create (name->name);
namebuf_t nbuf = namebuf_create (current_stat_info.file_name);
for (p = dirp; *p; p += strlen (p) + 1)
addname (namebuf_name (nbuf, p),
@@ -157,17 +157,22 @@ update_archive (void)
namebuf_free (nbuf);
free (dirp);
remname (name);
remove_exact_name (name, current_stat_info.file_name);
}
}
else if (tar_timespec_cmp (get_stat_mtime (&s),
current_stat_info.mtime)
<= 0)
remname (name);
{
remove_exact_name (name, current_stat_info.file_name);
}
else if (name->is_wildcard)
addname (current_stat_info.file_name,
name->change_dir, false, NULL);
}
}
skip_member ();
skim_member (acting_as_filter);
break;
}

View File

@@ -1,7 +1,6 @@
/* Charset handling for GNU tar.
Copyright 2004, 2006-2007, 2013-2014, 2016-2017 Free Software
Foundation, Inc.
Copyright 2004-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -36,11 +35,14 @@
# define iconv_open(tocode, fromcode) ((iconv_t) -1)
# undef iconv
# define iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft) ((size_t) 0)
# define iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft) (errno = ENOSYS, (size_t) -1)
# undef iconv_close
# define iconv_close(cd) 0
# undef iconv_t
# define iconv_t int
#endif
@@ -65,10 +67,9 @@ bool
utf8_convert (bool to_utf, char const *input, char **output)
{
char ICONV_CONST *ib;
char *ob;
char *ob, *ret;
size_t inlen;
size_t outlen;
size_t rc;
iconv_t cd = utf8_init (to_utf);
if (cd == 0)
@@ -81,11 +82,27 @@ utf8_convert (bool to_utf, char const *input, char **output)
inlen = strlen (input) + 1;
outlen = inlen * MB_LEN_MAX + 1;
ob = *output = xmalloc (outlen);
ob = ret = xmalloc (outlen);
ib = (char ICONV_CONST *) input;
rc = iconv (cd, &ib, &inlen, &ob, &outlen);
/* According to POSIX, "if iconv() encounters a character in the input
buffer that is valid, but for which an identical character does not
exist in the target codeset, iconv() shall perform an
implementation-defined conversion on this character." It will "update
the variables pointed to by the arguments to reflect the extent of the
conversion and return the number of non-identical conversions performed".
On error, it returns -1.
In other words, non-zero return always indicates failure, either because
the input was not fully converted, or because it was converted in a
non-reversible way.
*/
if (iconv (cd, &ib, &inlen, &ob, &outlen) != 0)
{
free (ret);
return false;
}
*ob = 0;
return rc != -1;
*output = ret;
return true;
}

View File

@@ -1,6 +1,6 @@
/* Warnings for GNU tar.
Copyright 2009, 2012-2014, 2016-2017 Free Software Foundation, Inc.
Copyright 2009-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -48,6 +48,8 @@ static char const *const warning_args[] = {
"xattr-write",
"record-size",
"failed-read",
"missing-zero-blocks",
"verbose",
NULL
};
@@ -76,12 +78,14 @@ static int warning_types[] = {
WARN_EXISTING_FILE,
WARN_XATTR_WRITE,
WARN_RECORD_SIZE,
WARN_FAILED_READ
WARN_FAILED_READ,
WARN_MISSING_ZERO_BLOCKS,
WARN_VERBOSE_WARNINGS,
};
ARGMATCH_VERIFY (warning_args, warning_types);
int warning_option = WARN_ALL;
int warning_option = WARN_ALL & ~(WARN_VERBOSE_WARNINGS|WARN_MISSING_ZERO_BLOCKS);
void
set_warning_option (const char *arg)

View File

@@ -1,6 +1,6 @@
/* Support for extended attributes.
Copyright (C) 2006-2014, 2016-2017 Free Software Foundation, Inc.
Copyright (C) 2006-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -30,6 +30,83 @@
#include "xattr-at.h"
#include "selinux-at.h"
#define XATTRS_PREFIX "SCHILY.xattr."
#define XATTRS_PREFIX_LEN (sizeof XATTRS_PREFIX - 1)
void
xheader_xattr_init (struct tar_stat_info *st)
{
xattr_map_init (&st->xattr_map);
st->acls_a_ptr = NULL;
st->acls_a_len = 0;
st->acls_d_ptr = NULL;
st->acls_d_len = 0;
st->cntx_name = NULL;
}
void
xattr_map_init (struct xattr_map *map)
{
memset (map, 0, sizeof *map);
}
void
xattr_map_free (struct xattr_map *xattr_map)
{
size_t i;
for (i = 0; i < xattr_map->xm_size; i++)
{
free (xattr_map->xm_map[i].xkey);
free (xattr_map->xm_map[i].xval_ptr);
}
free (xattr_map->xm_map);
}
void
xattr_map_add (struct xattr_map *map,
const char *key, const char *val, size_t len)
{
struct xattr_array *p;
if (map->xm_size == map->xm_max)
map->xm_map = x2nrealloc (map->xm_map, &map->xm_max,
sizeof (map->xm_map[0]));
p = &map->xm_map[map->xm_size];
p->xkey = xstrdup (key);
p->xval_ptr = xmemdup (val, len + 1);
p->xval_len = len;
map->xm_size++;
}
void
xheader_xattr_add (struct tar_stat_info *st,
const char *key, const char *val, size_t len)
{
size_t klen = strlen (key);
char *xkey = xmalloc (XATTRS_PREFIX_LEN + klen + 1);
char *tmp = xkey;
tmp = stpcpy (tmp, XATTRS_PREFIX);
stpcpy (tmp, key);
xattr_map_add (&st->xattr_map, xkey, val, len);
free (xkey);
}
void
xattr_map_copy (struct xattr_map *dst, const struct xattr_map *src)
{
size_t i;
for (i = 0; i < src->xm_size; i++)
xattr_map_add (dst, src->xm_map[i].xkey,
src->xm_map[i].xval_ptr,
src->xm_map[i].xval_len);
}
struct xattrs_mask_map
{
const char **masks;
@@ -53,6 +130,10 @@ static struct
#ifdef HAVE_POSIX_ACLS
# include "acl.h"
# include <sys/acl.h>
# ifdef HAVE_ACL_LIBACL_H
# /* needed for numeric-owner support */
# include <acl/libacl.h>
# endif
#endif
#ifdef HAVE_POSIX_ACLS
@@ -204,13 +285,12 @@ fixup_extra_acl_fields (char *ptr)
static void
xattrs__acls_set (struct tar_stat_info const *st,
char const *file_name, int type,
char *ptr, size_t len, bool def)
char *ptr, bool def)
{
acl_t acl;
if (ptr)
{
/* assert (strlen (ptr) == len); */
ptr = fixup_extra_acl_fields (ptr);
acl = acl_from_text (ptr);
}
@@ -246,23 +326,60 @@ xattrs__acls_set (struct tar_stat_info const *st,
acl_free (acl);
}
/* Cleanup textual representation of the ACL in VAL by eliminating tab
characters and comments */
static void
xattrs__acls_get_a (int parentfd, const char *file_name,
struct tar_stat_info *st,
char **ret_ptr, size_t * ret_len)
xattrs_acls_cleanup (char *val, size_t *plen)
{
char *p, *q;
p = q = val + strcspn (val, "#\t");
while (*q)
{
if (*q == '\t')
q++;
else if (*q == '#')
{
while (*q != '\n')
q++;
}
else
*p++ = *q++;
}
*plen = p - val;
*p++ = 0;
}
static void
acls_get_text (int parentfd, const char *file_name, acl_type_t type,
char **ret_ptr, size_t * ret_len)
{
char *val = NULL;
ssize_t len;
acl_t acl;
if (!(acl = acl_get_file_at (parentfd, file_name, ACL_TYPE_ACCESS)))
if (!(acl = acl_get_file_at (parentfd, file_name, type)))
{
if (errno != ENOTSUP)
call_arg_warn ("acl_get_file_at", file_name);
return;
}
val = acl_to_text (acl, &len);
if (numeric_owner_option)
{
#ifdef HAVE_ACL_LIBACL_H
val = acl_to_any_text (acl, NULL, '\n',
TEXT_SOME_EFFECTIVE | TEXT_NUMERIC_IDS);
#else
static int warned;
if (!warned)
{
WARN ((0, 0, _("--numeric-owner is ignored for ACLs: libacl is not available")));
warned = 1;
}
#endif
}
else
val = acl_to_text (acl, NULL);
acl_free (acl);
if (!val)
@@ -272,41 +389,23 @@ xattrs__acls_get_a (int parentfd, const char *file_name,
}
*ret_ptr = xstrdup (val);
*ret_len = len;
xattrs_acls_cleanup (*ret_ptr, ret_len);
acl_free (val);
}
static void
xattrs__acls_get_a (int parentfd, const char *file_name,
char **ret_ptr, size_t *ret_len)
{
acls_get_text (parentfd, file_name, ACL_TYPE_ACCESS, ret_ptr, ret_len);
}
/* "system.posix_acl_default" */
static void
xattrs__acls_get_d (int parentfd, char const *file_name,
struct tar_stat_info *st,
char **ret_ptr, size_t * ret_len)
{
char *val = NULL;
ssize_t len;
acl_t acl;
if (!(acl = acl_get_file_at (parentfd, file_name, ACL_TYPE_DEFAULT)))
{
if (errno != ENOTSUP)
call_arg_warn ("acl_get_file_at", file_name);
return;
}
val = acl_to_text (acl, &len);
acl_free (acl);
if (!val)
{
call_arg_warn ("acl_to_text", file_name);
return;
}
*ret_ptr = xstrdup (val);
*ret_len = len;
acl_free (val);
acls_get_text (parentfd, file_name, ACL_TYPE_DEFAULT, ret_ptr, ret_len);
}
#endif /* HAVE_POSIX_ACLS */
@@ -336,6 +435,7 @@ acls_one_line (const char *prefix, char delim,
obstack_grow (&stk, prefix, pref_len);
obstack_grow (&stk, aclstring, move);
pos += move + 1;
aclstring += move + 1;
}
@@ -348,7 +448,7 @@ acls_one_line (const char *prefix, char delim,
void
xattrs_acls_get (int parentfd, char const *file_name,
struct tar_stat_info *st, int fd, int xisfile)
struct tar_stat_info *st, int xisfile)
{
if (acls_option > 0)
{
@@ -367,10 +467,10 @@ xattrs_acls_get (int parentfd, char const *file_name,
return;
}
xattrs__acls_get_a (parentfd, file_name, st,
xattrs__acls_get_a (parentfd, file_name,
&st->acls_a_ptr, &st->acls_a_len);
if (!xisfile)
xattrs__acls_get_d (parentfd, file_name, st,
xattrs__acls_get_d (parentfd, file_name,
&st->acls_d_ptr, &st->acls_d_len);
#endif
}
@@ -389,10 +489,10 @@ xattrs_acls_set (struct tar_stat_info const *st,
done = 1;
#else
xattrs__acls_set (st, file_name, ACL_TYPE_ACCESS,
st->acls_a_ptr, st->acls_a_len, false);
st->acls_a_ptr, false);
if (typeflag == DIRTYPE || typeflag == GNUTYPE_DUMPDIR)
xattrs__acls_set (st, file_name, ACL_TYPE_DEFAULT,
st->acls_d_ptr, st->acls_d_len, true);
st->acls_d_ptr, true);
#endif
}
}
@@ -512,8 +612,7 @@ xattrs_xattrs_get (int parentfd, char const *file_name,
#ifdef HAVE_XATTRS
static void
xattrs__fd_set (struct tar_stat_info const *st,
char const *file_name, char typeflag,
xattrs__fd_set (char const *file_name, char typeflag,
const char *attr, const char *ptr, size_t len)
{
if (ptr)
@@ -629,7 +728,7 @@ xattrs_kw_included (const char *kw, bool archiving)
}
static bool
xattrs_kw_excluded (const char *kw, bool archiving)
xattrs_kw_excluded (const char *kw)
{
return xattrs_setup.excl.size ?
xattrs_matches_mask (kw, &xattrs_setup.excl) : false;
@@ -641,8 +740,7 @@ xattrs_kw_excluded (const char *kw, bool archiving)
static bool
xattrs_masked_out (const char *kw, bool archiving)
{
return xattrs_kw_included (kw, archiving) ?
xattrs_kw_excluded (kw, archiving) : true;
return xattrs_kw_included (kw, archiving) ? xattrs_kw_excluded (kw) : true;
}
void
@@ -657,15 +755,14 @@ xattrs_xattrs_set (struct tar_stat_info const *st,
WARN ((0, 0, _("XATTR support is not available")));
done = 1;
#else
size_t scan = 0;
size_t i;
if (!st->xattr_map_size)
if (!st->xattr_map.xm_size)
return;
for (; scan < st->xattr_map_size; ++scan)
for (i = 0; i < st->xattr_map.xm_size; i++)
{
char *keyword = st->xattr_map[scan].xkey;
keyword += strlen ("SCHILY.xattr.");
char *keyword = st->xattr_map.xm_map[i].xkey + XATTRS_PREFIX_LEN;
/* TODO: this 'later_run' workaround is temporary solution -> once
capabilities should become fully supported by it's API and there
@@ -681,9 +778,9 @@ xattrs_xattrs_set (struct tar_stat_info const *st,
/* we don't want to restore this keyword */
continue;
xattrs__fd_set (st, file_name, typeflag, keyword,
st->xattr_map[scan].xval_ptr,
st->xattr_map[scan].xval_len);
xattrs__fd_set (file_name, typeflag, keyword,
st->xattr_map.xm_map[i].xval_ptr,
st->xattr_map.xm_map[i].xval_len);
}
#endif
}
@@ -707,10 +804,10 @@ xattrs_print_char (struct tar_stat_info const *st, char *output)
output[1] = 0;
}
if (xattrs_option > 0 && st->xattr_map_size)
for (i = 0; i < st->xattr_map_size; ++i)
if (xattrs_option > 0 && st->xattr_map.xm_size)
for (i = 0; i < st->xattr_map.xm_size; ++i)
{
char *keyword = st->xattr_map[i].xkey + strlen ("SCHILY.xattr.");
char *keyword = st->xattr_map.xm_map[i].xkey + XATTRS_PREFIX_LEN;
if (!xattrs_masked_out (keyword, false /* like extracting */ ))
{
*output = '*';
@@ -740,21 +837,23 @@ xattrs_print (struct tar_stat_info const *st)
{
fprintf (stdlis, " a: ");
acls_one_line ("", ',', st->acls_a_ptr, st->acls_a_len);
if (st->acls_a_len && st->acls_d_len)
fprintf (stdlis, ",");
acls_one_line ("default:", ',', st->acls_d_ptr, st->acls_d_len);
fprintf (stdlis, "\n");
}
/* xattrs */
if (xattrs_option > 0 && st->xattr_map_size)
if (xattrs_option > 0 && st->xattr_map.xm_size)
{
int i;
for (i = 0; i < st->xattr_map_size; ++i)
for (i = 0; i < st->xattr_map.xm_size; ++i)
{
char *keyword = st->xattr_map[i].xkey + strlen ("SCHILY.xattr.");
char *keyword = st->xattr_map.xm_map[i].xkey + XATTRS_PREFIX_LEN;
if (!xattrs_masked_out (keyword, false /* like extracting */ ))
fprintf (stdlis, " x: %lu %s\n",
(unsigned long) st->xattr_map[i].xval_len, keyword);
(unsigned long) st->xattr_map.xm_map[i].xval_len, keyword);
}
}
}

View File

@@ -1,6 +1,6 @@
/* Support for extended attributes.
Copyright (C) 2006-2014, 2016-2017 Free Software Foundation, Inc.
Copyright (C) 2006-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -30,7 +30,7 @@ extern void xattrs_mask_add (const char *mask, bool incl);
extern void xattrs_clear_setup (void);
extern void xattrs_acls_get (int parentfd, char const *file_name,
struct tar_stat_info *st, int fd, int xisfile);
struct tar_stat_info *st, int xisfile);
extern void xattrs_selinux_get (int parentfd, char const *file_name,
struct tar_stat_info *st, int fd);
extern void xattrs_xattrs_get (int parentfd, char const *file_name,

View File

@@ -1,7 +1,6 @@
/* POSIX extended headers for tar.
Copyright (C) 2003-2007, 2009-2010, 2012-2014, 2016-2017 Free
Software Foundation, Inc.
Copyright (C) 2003-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -30,7 +29,6 @@
static void xheader_init (struct xheader *xhdr);
static bool xheader_protected_pattern_p (char const *pattern);
static bool xheader_protected_keyword_p (char const *keyword);
static void xheader_set_single_keyword (char *) __attribute__ ((noreturn));
/* Used by xheader_finish() */
static void code_string (char const *string, char const *keyword,
@@ -159,7 +157,7 @@ xheader_list_destroy (struct keyword_list **root)
}
}
static void
static _Noreturn void
xheader_set_single_keyword (char *kw)
{
USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet implemented"), kw));
@@ -185,6 +183,9 @@ xheader_set_keyword_equal (char *kw, char *eq)
bool global = true;
char *p = eq;
if (eq == kw)
USAGE_ERROR ((0, 0, _("Malformed pax option: %s"), quote (kw)));
if (eq[-1] == ':')
{
p--;
@@ -255,7 +256,7 @@ char *
xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
{
char *buf;
size_t len = strlen (fmt);
size_t len;
char *q;
const char *p;
char *dirp = NULL;
@@ -266,43 +267,51 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
char nbuf[UINTMAX_STRSIZE_BOUND];
char const *nptr = NULL;
for (p = fmt; *p && (p = strchr (p, '%')); )
len = 0;
for (p = fmt; *p; p++)
{
switch (p[1])
if (*p == '%' && p[1])
{
case '%':
len--;
break;
case 'd':
if (st)
switch (*++p)
{
if (!dirp)
dirp = dir_name (st->orig_file_name);
dir = safer_name_suffix (dirp, false, absolute_names_option);
len += strlen (dir) - 2;
case '%':
len++;
break;
case 'd':
if (st)
{
if (!dirp)
dirp = dir_name (st->orig_file_name);
dir = safer_name_suffix (dirp, false, absolute_names_option);
len += strlen (dir);
}
break;
case 'f':
if (st)
{
base = last_component (st->orig_file_name);
len += strlen (base);
}
break;
case 'p':
pptr = umaxtostr (getpid (), pidbuf);
len += pidbuf + sizeof pidbuf - 1 - pptr;
break;
case 'n':
nptr = umaxtostr (n, nbuf);
len += nbuf + sizeof nbuf - 1 - nptr;
break;
default:
len += 2;
}
break;
case 'f':
if (st)
{
base = last_component (st->orig_file_name);
len += strlen (base) - 2;
}
break;
case 'p':
pptr = umaxtostr (getpid (), pidbuf);
len += pidbuf + sizeof pidbuf - 1 - pptr - 2;
break;
case 'n':
nptr = umaxtostr (n, nbuf);
len += nbuf + sizeof nbuf - 1 - nptr - 2;
break;
}
p++;
else
len++;
}
buf = xmalloc (len + 1);
@@ -359,29 +368,46 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
return buf;
}
/* Table of templates for the names of POSIX extended headers.
Indexed by the the type of the header (per-file or global)
and POSIX compliance mode (0 or q depending on whether
POSIXLY_CORRECT environment variable is set. */
static const char *header_template[][2] = {
/* Individual header templates: */
{ "%d/PaxHeaders/%f", "%d/PaxHeaders.%p/%f" },
/* Global header templates: */
{ "/GlobalHead.%n", "/GlobalHead.%p.%n" }
};
/* Indices to the above table */
enum {
pax_file_header,
pax_global_header
};
/* Return the name for the POSIX extended header T */
#define HEADER_TEMPLATE(t) header_template[t][posixly_correct]
char *
xheader_xhdr_name (struct tar_stat_info *st)
{
if (!exthdr_name)
assign_string (&exthdr_name, "%d/PaxHeaders.%p/%f");
assign_string (&exthdr_name, HEADER_TEMPLATE (pax_file_header));
return xheader_format_name (st, exthdr_name, 0);
}
#define GLOBAL_HEADER_TEMPLATE "/GlobalHead.%p.%n"
char *
xheader_ghdr_name (void)
{
if (!globexthdr_name)
{
size_t len;
const char *global_header_template = HEADER_TEMPLATE (pax_global_header);
const char *tmp = getenv ("TMPDIR");
if (!tmp)
tmp = "/tmp";
len = strlen (tmp) + sizeof (GLOBAL_HEADER_TEMPLATE); /* Includes nul */
len = strlen (tmp) + strlen (global_header_template) + 1;
globexthdr_name = xmalloc (len);
strcpy(globexthdr_name, tmp);
strcat(globexthdr_name, GLOBAL_HEADER_TEMPLATE);
strcat(globexthdr_name, global_header_template);
}
return xheader_format_name (NULL, globexthdr_name, global_header_count + 1);
@@ -458,46 +484,12 @@ xheader_write_global (struct xheader *xhdr)
}
}
/* Forbid modifications of the global extended header */
void
xheader_xattr_init (struct tar_stat_info *st)
xheader_forbid_global (void)
{
st->xattr_map = NULL;
st->xattr_map_size = 0;
st->acls_a_ptr = NULL;
st->acls_a_len = 0;
st->acls_d_ptr = NULL;
st->acls_d_len = 0;
st->cntx_name = NULL;
}
void
xheader_xattr_free (struct xattr_array *xattr_map, size_t xattr_map_size)
{
size_t scan = 0;
while (scan < xattr_map_size)
{
free (xattr_map[scan].xkey);
free (xattr_map[scan].xval_ptr);
++scan;
}
free (xattr_map);
}
static void
xheader_xattr__add (struct xattr_array **xattr_map,
size_t *xattr_map_size,
const char *key, const char *val, size_t len)
{
size_t pos = (*xattr_map_size)++;
*xattr_map = xrealloc (*xattr_map,
*xattr_map_size * sizeof(struct xattr_array));
(*xattr_map)[pos].xkey = xstrdup (key);
(*xattr_map)[pos].xval_ptr = xmemdup (val, len + 1);
(*xattr_map)[pos].xval_len = len;
if (keyword_global_override_list)
USAGE_ERROR ((0, 0, _("can't update global extended header record")));
}
/* This is reversal function for xattr_encode_keyword. See comment for
@@ -537,44 +529,6 @@ xattr_decode_keyword (char *keyword)
kpl++;
}
}
void
xheader_xattr_add (struct tar_stat_info *st,
const char *key, const char *val, size_t len)
{
size_t klen = strlen (key);
char *xkey = xmalloc (strlen("SCHILY.xattr.") + klen + 1);
char *tmp = xkey;
tmp = stpcpy (tmp, "SCHILY.xattr.");
stpcpy (tmp, key);
xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len);
free (xkey);
}
void
xheader_xattr_copy (const struct tar_stat_info *st,
struct xattr_array **xattr_map, size_t *xattr_map_size)
{
size_t scan = 0;
*xattr_map = NULL;
*xattr_map_size = 0;
while (scan < st->xattr_map_size)
{
char *key = st->xattr_map[scan].xkey;
char *val = st->xattr_map[scan].xval_ptr;
size_t len = st->xattr_map[scan].xval_len;
xheader_xattr__add(xattr_map, xattr_map_size, key, val, len);
++scan;
}
}
/* General Interface */
@@ -603,11 +557,11 @@ static struct xhdr_tab const *
locate_handler (char const *keyword)
{
struct xhdr_tab const *p;
for (p = xhdr_tab; p->keyword; p++)
if (p->prefix)
{
if (strncmp (p->keyword, keyword, strlen(p->keyword)) == 0)
size_t kwlen = strlen (p->keyword);
if (strncmp (p->keyword, keyword, kwlen) == 0 && keyword[kwlen] == '.')
return p;
}
else
@@ -674,7 +628,7 @@ decode_record (struct xheader *xhdr,
if (len_max < len)
{
int len_len = len_lim - p;
ERROR ((0, 0, _("Extended header length %*s is out of range"),
ERROR ((0, 0, _("Extended header length %.*s is out of range"),
len_len, p));
return false;
}
@@ -769,7 +723,7 @@ xheader_decode (struct tar_stat_info *st)
static void
decg (void *data, char const *keyword, char const *value,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
struct keyword_list **kwl = data;
struct xhdr_tab const *tab = locate_handler (keyword);
@@ -885,7 +839,7 @@ xattr_encode_keyword(const char *keyword)
{
char c = *keyword;
if (bp + 2 /* enough for URL encoding also.. */ >= encode_buffer_size)
if (bp + 3 /* enough for URL encoding also.. */ >= encode_buffer_size)
{
encode_buffer = x2realloc (encode_buffer, &encode_buffer_size);
}
@@ -1105,6 +1059,12 @@ decode_time (struct timespec *ts, char const *arg, char const *keyword)
keyword, arg));
return false;
}
if (*arg_lim)
{
ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
keyword, arg));
return false;
}
*ts = t;
return true;
@@ -1161,24 +1121,24 @@ decode_num (uintmax_t *num, char const *arg, uintmax_t maxval,
}
static void
dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)),
char const *keyword __attribute__ ((unused)),
struct xheader *xhdr __attribute__ ((unused)),
void const *data __attribute__ ((unused)))
dummy_coder (MAYBE_UNUSED struct tar_stat_info const *st,
MAYBE_UNUSED char const *keyword,
MAYBE_UNUSED struct xheader *xhdr,
MAYBE_UNUSED void const *data)
{
}
static void
dummy_decoder (struct tar_stat_info *st __attribute__ ((unused)),
char const *keyword __attribute__ ((unused)),
char const *arg __attribute__ ((unused)),
size_t size __attribute__((unused)))
dummy_decoder (MAYBE_UNUSED struct tar_stat_info *st,
MAYBE_UNUSED char const *keyword,
MAYBE_UNUSED char const *arg,
MAYBE_UNUSED size_t size)
{
}
static void
atime_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data __attribute__ ((unused)))
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_time (st->atime, keyword, xhdr);
}
@@ -1187,7 +1147,7 @@ static void
atime_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
struct timespec ts;
if (decode_time (&ts, arg, keyword))
@@ -1196,7 +1156,7 @@ atime_decoder (struct tar_stat_info *st,
static void
gid_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data __attribute__ ((unused)))
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_signed_num (st->stat.st_gid, keyword,
TYPE_MINIMUM (gid_t), TYPE_MAXIMUM (gid_t), xhdr);
@@ -1206,7 +1166,7 @@ static void
gid_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
intmax_t u;
if (decode_signed_num (&u, arg, TYPE_MINIMUM (gid_t),
@@ -1216,39 +1176,39 @@ gid_decoder (struct tar_stat_info *st,
static void
gname_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data __attribute__ ((unused)))
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_string (st->gname, keyword, xhdr);
}
static void
gname_decoder (struct tar_stat_info *st,
char const *keyword __attribute__((unused)),
MAYBE_UNUSED char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
decode_string (&st->gname, arg);
}
static void
linkpath_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data __attribute__ ((unused)))
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_string (st->link_name, keyword, xhdr);
}
static void
linkpath_decoder (struct tar_stat_info *st,
char const *keyword __attribute__((unused)),
MAYBE_UNUSED char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
decode_string (&st->link_name, arg);
}
static void
ctime_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data __attribute__ ((unused)))
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_time (st->ctime, keyword, xhdr);
}
@@ -1257,7 +1217,7 @@ static void
ctime_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
struct timespec ts;
if (decode_time (&ts, arg, keyword))
@@ -1276,7 +1236,7 @@ static void
mtime_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
struct timespec ts;
if (decode_time (&ts, arg, keyword))
@@ -1285,7 +1245,7 @@ mtime_decoder (struct tar_stat_info *st,
static void
path_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data __attribute__ ((unused)))
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_string (st->file_name, keyword, xhdr);
}
@@ -1293,17 +1253,20 @@ path_coder (struct tar_stat_info const *st, char const *keyword,
static void
raw_path_decoder (struct tar_stat_info *st, char const *arg)
{
decode_string (&st->orig_file_name, arg);
decode_string (&st->file_name, arg);
st->had_trailing_slash = strip_trailing_slashes (st->file_name);
if (*arg)
{
decode_string (&st->orig_file_name, arg);
decode_string (&st->file_name, arg);
st->had_trailing_slash = strip_trailing_slashes (st->file_name);
}
}
static void
path_decoder (struct tar_stat_info *st,
char const *keyword __attribute__((unused)),
MAYBE_UNUSED char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
if (! st->sparse_name_done)
raw_path_decoder (st, arg);
@@ -1311,9 +1274,9 @@ path_decoder (struct tar_stat_info *st,
static void
sparse_path_decoder (struct tar_stat_info *st,
char const *keyword __attribute__((unused)),
MAYBE_UNUSED char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
st->sparse_name_done = true;
raw_path_decoder (st, arg);
@@ -1321,7 +1284,7 @@ sparse_path_decoder (struct tar_stat_info *st,
static void
size_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data __attribute__ ((unused)))
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_num (st->stat.st_size, keyword, xhdr);
}
@@ -1330,7 +1293,7 @@ static void
size_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
uintmax_t u;
if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
@@ -1339,7 +1302,7 @@ size_decoder (struct tar_stat_info *st,
static void
uid_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data __attribute__ ((unused)))
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_signed_num (st->stat.st_uid, keyword,
TYPE_MINIMUM (uid_t), TYPE_MAXIMUM (uid_t), xhdr);
@@ -1349,7 +1312,7 @@ static void
uid_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
intmax_t u;
if (decode_signed_num (&u, arg, TYPE_MINIMUM (uid_t),
@@ -1359,16 +1322,16 @@ uid_decoder (struct tar_stat_info *st,
static void
uname_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data __attribute__ ((unused)))
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_string (st->uname, keyword, xhdr);
}
static void
uname_decoder (struct tar_stat_info *st,
char const *keyword __attribute__((unused)),
MAYBE_UNUSED char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
decode_string (&st->uname, arg);
}
@@ -1384,7 +1347,7 @@ static void
sparse_size_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
uintmax_t u;
if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
@@ -1397,7 +1360,7 @@ sparse_size_decoder (struct tar_stat_info *st,
static void
sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr,
void const *data __attribute__ ((unused)))
MAYBE_UNUSED void const *data)
{
code_num (st->sparse_map_avail, keyword, xhdr);
}
@@ -1406,7 +1369,7 @@ static void
sparse_numblocks_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
uintmax_t u;
if (decode_num (&u, arg, SIZE_MAX, keyword))
@@ -1429,7 +1392,7 @@ static void
sparse_offset_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
uintmax_t u;
if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
@@ -1454,7 +1417,7 @@ static void
sparse_numbytes_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
uintmax_t u;
if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
@@ -1471,7 +1434,7 @@ static void
sparse_map_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
int offset = 1;
struct sp_array e;
@@ -1545,7 +1508,7 @@ sparse_map_decoder (struct tar_stat_info *st,
}
static void
dumpdir_coder (struct tar_stat_info const *st, char const *keyword,
dumpdir_coder (MAYBE_UNUSED struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data)
{
xheader_print_n (xhdr, keyword, data, dumpdir_size (data));
@@ -1553,7 +1516,7 @@ dumpdir_coder (struct tar_stat_info const *st, char const *keyword,
static void
dumpdir_decoder (struct tar_stat_info *st,
char const *keyword __attribute__((unused)),
MAYBE_UNUSED char const *keyword,
char const *arg,
size_t size)
{
@@ -1562,23 +1525,25 @@ dumpdir_decoder (struct tar_stat_info *st,
}
static void
volume_label_coder (struct tar_stat_info const *st, char const *keyword,
volume_label_coder (MAYBE_UNUSED struct tar_stat_info const *st,
char const *keyword,
struct xheader *xhdr, void const *data)
{
code_string (data, keyword, xhdr);
}
static void
volume_label_decoder (struct tar_stat_info *st,
char const *keyword __attribute__((unused)),
volume_label_decoder (MAYBE_UNUSED struct tar_stat_info *st,
MAYBE_UNUSED char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
decode_string (&volume_label, arg);
}
static void
volume_size_coder (struct tar_stat_info const *st, char const *keyword,
volume_size_coder (MAYBE_UNUSED struct tar_stat_info const *st,
char const *keyword,
struct xheader *xhdr, void const *data)
{
off_t const *v = data;
@@ -1586,9 +1551,9 @@ volume_size_coder (struct tar_stat_info const *st, char const *keyword,
}
static void
volume_size_decoder (struct tar_stat_info *st,
volume_size_decoder (MAYBE_UNUSED struct tar_stat_info *st,
char const *keyword,
char const *arg, size_t size)
char const *arg, MAYBE_UNUSED size_t size)
{
uintmax_t u;
if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
@@ -1597,7 +1562,8 @@ volume_size_decoder (struct tar_stat_info *st,
/* FIXME: Merge with volume_size_coder */
static void
volume_offset_coder (struct tar_stat_info const *st, char const *keyword,
volume_offset_coder (MAYBE_UNUSED struct tar_stat_info const *st,
char const *keyword,
struct xheader *xhdr, void const *data)
{
off_t const *v = data;
@@ -1605,9 +1571,9 @@ volume_offset_coder (struct tar_stat_info const *st, char const *keyword,
}
static void
volume_offset_decoder (struct tar_stat_info *st,
volume_offset_decoder (MAYBE_UNUSED struct tar_stat_info *st,
char const *keyword,
char const *arg, size_t size)
char const *arg, MAYBE_UNUSED size_t size)
{
uintmax_t u;
if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
@@ -1615,38 +1581,40 @@ volume_offset_decoder (struct tar_stat_info *st,
}
static void
volume_filename_decoder (struct tar_stat_info *st,
char const *keyword __attribute__((unused)),
volume_filename_decoder (MAYBE_UNUSED struct tar_stat_info *st,
MAYBE_UNUSED char const *keyword,
char const *arg,
size_t size __attribute__((unused)))
MAYBE_UNUSED size_t size)
{
decode_string (&continued_file_name, arg);
}
static void
xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data)
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_string (st->cntx_name, keyword, xhdr);
}
static void
xattr_selinux_decoder (struct tar_stat_info *st,
char const *keyword, char const *arg, size_t size)
MAYBE_UNUSED char const *keyword, char const *arg,
MAYBE_UNUSED size_t size)
{
decode_string (&st->cntx_name, arg);
}
static void
xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword,
struct xheader *xhdr, void const *data)
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len);
}
static void
xattr_acls_a_decoder (struct tar_stat_info *st,
char const *keyword, char const *arg, size_t size)
MAYBE_UNUSED char const *keyword,
char const *arg, size_t size)
{
st->acls_a_ptr = xmemdup (arg, size + 1);
st->acls_a_len = size;
@@ -1654,14 +1622,15 @@ xattr_acls_a_decoder (struct tar_stat_info *st,
static void
xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword,
struct xheader *xhdr, void const *data)
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len);
}
static void
xattr_acls_d_decoder (struct tar_stat_info *st,
char const *keyword, char const *arg, size_t size)
MAYBE_UNUSED char const *keyword, char const *arg,
size_t size)
{
st->acls_d_ptr = xmemdup (arg, size + 1);
st->acls_d_len = size;
@@ -1671,35 +1640,31 @@ static void
xattr_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data)
{
struct xattr_array *xattr_map = st->xattr_map;
const size_t *off = data;
size_t n = *(size_t *)data;
xheader_print_n (xhdr, keyword,
xattr_map[*off].xval_ptr, xattr_map[*off].xval_len);
st->xattr_map.xm_map[n].xval_ptr,
st->xattr_map.xm_map[n].xval_len);
}
static void
xattr_decoder (struct tar_stat_info *st,
char const *keyword, char const *arg, size_t size)
{
char *xstr, *xkey;
char *xkey;
/* copy keyword */
size_t klen_raw = strlen (keyword);
xkey = alloca (klen_raw + 1);
memcpy (xkey, keyword, klen_raw + 1) /* including null-terminating */;
/* copy value */
xstr = alloca (size + 1);
memcpy (xstr, arg, size + 1); /* separator included, for GNU tar '\n' */;
xkey = xstrdup (keyword);
xattr_decode_keyword (xkey);
xheader_xattr_add (st, xkey + strlen("SCHILY.xattr."), xstr, size);
xattr_map_add (&st->xattr_map, xkey, arg, size);
free (xkey);
}
static void
sparse_major_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data)
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_num (st->sparse_major, keyword, xhdr);
}
@@ -1708,7 +1673,7 @@ static void
sparse_major_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size)
MAYBE_UNUSED size_t size)
{
uintmax_t u;
if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
@@ -1717,7 +1682,7 @@ sparse_major_decoder (struct tar_stat_info *st,
static void
sparse_minor_coder (struct tar_stat_info const *st, char const *keyword,
struct xheader *xhdr, void const *data)
struct xheader *xhdr, MAYBE_UNUSED void const *data)
{
code_num (st->sparse_minor, keyword, xhdr);
}
@@ -1726,7 +1691,7 @@ static void
sparse_minor_decoder (struct tar_stat_info *st,
char const *keyword,
char const *arg,
size_t size)
MAYBE_UNUSED size_t size)
{
uintmax_t u;
if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))

1
tests/.gitignore vendored
View File

@@ -12,3 +12,4 @@ download
ttyemu
checkseekhole
ckmtime
/compress-*.at

View File

@@ -1,6 +1,6 @@
# Makefile for GNU tar regression tests.
# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2015 Free Software
# Copyright 1996-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -17,9 +17,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 star/README star/quicktest.sh
EXTRA_DIST = $(TESTSUITE_AT) \
testsuite package.m4 star/README star/quicktest.sh \
compress.m4
DISTCLEANFILES = atconfig $(check_SCRIPTS)
MAINTAINERCLEANFILES = Makefile.in $(TESTSUITE)
CLEANFILES =
## ------------ ##
## package.m4. ##
@@ -43,6 +47,7 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
TESTSUITE_AT = \
testsuite.at\
compress.m4\
T-cd.at\
T-dir00.at\
T-dir01.at\
@@ -66,11 +71,17 @@ TESTSUITE_AT = \
chtype.at\
comprec.at\
comperr.at\
checkpoint/defaults.at\
checkpoint/interval.at\
checkpoint/dot.at\
checkpoint/dot-compat.at\
checkpoint/dot-int.at\
delete01.at\
delete02.at\
delete03.at\
delete04.at\
delete05.at\
delete06.at\
difflink.at\
exclude.at\
exclude01.at\
@@ -110,6 +121,10 @@ TESTSUITE_AT = \
extrac19.at\
extrac20.at\
extrac21.at\
extrac22.at\
extrac23.at\
extrac24.at\
extrac25.at\
filerem01.at\
filerem02.at\
dirrem01.at\
@@ -188,6 +203,7 @@ TESTSUITE_AT = \
rename03.at\
rename04.at\
rename05.at\
rename06.at\
remfiles01.at\
remfiles02.at\
remfiles03.at\
@@ -228,6 +244,9 @@ TESTSUITE_AT = \
spmvp00.at\
spmvp01.at\
spmvp10.at\
sptrcreat.at\
sptrdiff00.at\
sptrdiff01.at\
time01.at\
time02.at\
truncate.at\
@@ -235,6 +254,7 @@ TESTSUITE_AT = \
update01.at\
update02.at\
update03.at\
update04.at\
volsize.at\
volume.at\
verbose.at\
@@ -257,6 +277,7 @@ TESTSUITE_AT = \
xattr05.at\
xattr06.at\
xattr07.at\
xattr08.at\
acls01.at\
acls02.at\
acls03.at\
@@ -310,4 +331,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/lib\
-DLOCALEDIR=\"$(localedir)\"
LDADD = ../gnu/libgnu.a $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS)
LDADD = ../gnu/libgnu.a\
$(LIB_ACL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS)\
$(LIB_GETRANDOM) $(LIB_HARD_LOCALE) $(FILE_HAS_ACL_LIB) $(LIB_MBRTOWC)\
$(LIB_SELINUX) $(LIB_SETLOCALE_NULL)

View File

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

View File

@@ -1,8 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright 2006-2007, 2013-2014, 2016-2017 Free Software Foundation,
# Inc.
# Copyright 2006-2023 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-2014, 2016-2017 Free Software Foundation, Inc.
# Copyright 2013-2023 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-2014, 2016-2017 Free Software Foundation, Inc.
# Copyright 2013-2023 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-2014, 2016-2017 Free Software Foundation, Inc.
# Copyright 2013-2023 Free Software Foundation, Inc.
#
# This file is part of GNU tar.
#
@@ -29,9 +29,8 @@ AT_KEYWORDS([files-from nonewline nonl T-nonl])
AT_TAR_CHECK([
genfile --length=0 --file empty
AS_ECHO_N(c) > 1.nonl
echo d > 2.nonl
AS_ECHO_N(e) >> 2.nonl
printf c > 1.nonl
printf 'd\ne' > 2.nonl
touch a b c d e
AT_DATA([filelist],[a
b
@@ -59,4 +58,3 @@ c
[],[],[],[ustar])
AT_CLEANUP

View File

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

View File

@@ -1,5 +1,5 @@
# This file is part of test suite for GNU tar. -*- Autotest -*-
# Copyright 2015-2017 Free Software Foundation, Inc.
# Copyright 2015-2023 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

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
#
# Test suite for GNU tar.
# Copyright 2013-2014, 2016-2017 Free Software Foundation, Inc.
# Copyright 2013-2023 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 2015-2017 Free Software Foundation, Inc.
# Copyright 2015-2023 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-2014, 2016-2017 Free Software Foundation, Inc.
# Copyright 2013-2023 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