134 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
328 changed files with 4522 additions and 2758 deletions

44
.gitignore vendored
View File

@@ -1,32 +1,32 @@
*.a
*.[aios]
*.[gx]z
*.bz2
*.cache
*.diff
*.la
*.lo
*.o
*.orig
*.patch
*.rej
*.so
*DISTFILES
*~
.bootstrap
.deps
.emacs*
.libs
.gdbinit
ABOUT-NLS
ChangeLog
INSTALL
Make.rules
/.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,6 +1,6 @@
# Main Makefile for GNU tar.
# Copyright 1994-2021 Free Software Foundation, Inc.
# Copyright 1994-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.

82
NEWS
View File

@@ -1,10 +1,78 @@
GNU tar NEWS - User visible changes. 2021-01-07
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.
@@ -16,7 +84,7 @@ the pid.
* 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.
@@ -26,9 +94,9 @@ owned by the current user that did not have the S_IWUSR bit set.
* 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,
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.
@@ -1718,7 +1786,7 @@ Versions 1.07 back to 1.00 by Jay Fenlason.
Copyright 1994-2021 Free Software Foundation, Inc.
Copyright 1994-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -1738,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"

2
README
View File

@@ -221,7 +221,7 @@ and share your findings by writing to <bug-tar@gnu.org>.
* Copying
Copyright 1990-2021 Free Software Foundation, Inc.
Copyright 1990-2023 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -3,39 +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-2021 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-2021 Free Software Foundation, Inc.
Copyright 2007-2023 Free Software Foundation, Inc.
This file is part of GNU tar.

2
TODO
View File

@@ -45,7 +45,7 @@ Suggestions for improving GNU tar.
* Copyright notice
Copyright 2003-2021 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-2021 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,6 +1,6 @@
# Bootstrap configuration for GNU tar.
# Copyright 2006-2021 Free Software Foundation, Inc.
# Copyright 2006-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -60,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
@@ -100,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-2021 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.33], [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.64])
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,
@@ -103,6 +106,20 @@ 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
@@ -112,7 +129,7 @@ if test $ac_cv_lib_error_at_line = no; then
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
fi
# paxutils modules
tar_PAXUTILS
@@ -145,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]
)
@@ -162,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])
@@ -171,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])
@@ -356,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)
@@ -366,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)'
@@ -381,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\
@@ -389,3 +406,4 @@ AC_OUTPUT([Makefile\
scripts/Makefile\
rmt/Makefile\
src/Makefile])
AC_OUTPUT

View File

@@ -1,5 +1,5 @@
%%comments:
Copyright 2004-2021 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

View File

@@ -1,6 +1,6 @@
# Makefile for GNU tar documentation.
# Copyright 1994-2021 Free Software Foundation, Inc.
# Copyright 1994-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -138,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:
@@ -148,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,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2006--2021 Free Software Foundation, 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,8 +5,9 @@
@c hence no sectioning command or @node.
@display
Copyright @copyright{} 2000--2021 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.
@@ -97,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,
@@ -414,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
@@ -481,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
@@ -503,4 +504,3 @@ to permit their use in free software.
@c Local Variables:
@c ispell-local-pdict: "ispell-dict"
@c End:

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-2021 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--2021 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,6 +1,6 @@
;;; mastermenu.el --- Redefinition of texinfo-master-menu-list
;; Copyright 2006-2021 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--2021 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,5 +1,5 @@
@c This is part of GNU tar manual.
@c Copyright 1992--2021 Free 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,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2005--2021 Free Software Foundation, 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.

View File

@@ -1,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2006--2021 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.

View File

@@ -1,5 +1,5 @@
@c This is part of the paxutils manual.
@c Copyright (C) 2007--2021 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.

104
doc/tar.1
View File

@@ -1,5 +1,5 @@
.\" This file is part of GNU tar. -*- nroff -*-
.\" Copyright 2013-2021 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 "July 13, 2020" "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,7 +105,7 @@ 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
@@ -117,15 +115,15 @@ tar cfv etc.tar /etc
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
@@ -166,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.
@@ -220,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
@@ -232,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.
@@ -251,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
@@ -277,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
@@ -309,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
@@ -317,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
@@ -372,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
@@ -475,7 +470,7 @@ executing.
\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
@@ -563,14 +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)
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
@@ -744,7 +741,7 @@ 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
@@ -1013,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.
@@ -1063,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.
@@ -1122,14 +1120,14 @@ 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.1 "\fBThe \-\-verbose Option\fR".
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
@@ -1168,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"
@@ -1269,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
@@ -1277,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.
@@ -1318,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-2019 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>

View File

@@ -5,6 +5,16 @@
@settitle GNU tar @value{VERSION}
@setchapternewpage odd
@documentencoding UTF-8
@c These two commands require Texinfo 5.0; for now use the older
@c equivalent @set commands supported in Texinfo 4.11 and later.
@ignore
@codequotebacktick on
@codequoteundirected on
@end ignore
@set txicodequoteundirected
@set txicodequotebacktick
@finalout
@smallbook
@@ -36,8 +46,8 @@ This manual is for @acronym{GNU} @command{tar} (version
@value{VERSION}, @value{UPDATED}), which creates and extracts files
from archives.
Copyright @copyright{} 1992, 1994--1997, 1999--2001, 2003--2017, 2021
Free Software Foundation, Inc.
Copyright @copyright{} 1992, 1994--1997, 1999--2001, 2003--2017,
2021--2023 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -175,13 +185,14 @@ Invoking @GNUTAR{}
* Synopsis::
* using tar options::
* Styles::
* All Options::
* help::
* defaults::
* verbose::
* checkpoints::
* warnings::
* interactive::
* All Options:: All @command{tar} Options.
* help:: Where to Get Help.
* defaults:: What are the Default Values.
* verbose:: Checking @command{tar} progress.
* checkpoints:: Checkpoints.
* warnings:: Controlling Warning Messages.
* interactive:: Asking for Confirmation During Operations.
* external:: Running External Commands.
The Three Option Styles
@@ -197,6 +208,15 @@ All @command{tar} Options
* Short Option Summary::
* Position-Sensitive Options::
Controlling Warning Messages
* General Warnings:: Keywords applicable for @command{tar --create}.
* Archive Creation Warnings:: Keywords applicable for @command{tar --create}.
* Archive Extraction Warnings:: Keywords applicable for @command{tar --extract}.
* Incremental Extraction Warnings:: Keywords controlling incremental extraction.
* Warning Classes:: Convenience keywords control multiple warnings.
* Warning Defaults:: Default settings for warnings.
@GNUTAR{} Operations
* Basic tar::
@@ -309,16 +329,17 @@ Crossing File System Boundaries
Date input formats
* General date syntax:: Common rules.
* Calendar date items:: 19 Dec 1994.
* Time of day items:: 9:20pm.
* Time zone items:: @sc{est}, @sc{pdt}, @sc{gmt}.
* Day of week items:: Monday and others.
* Relative items in date strings:: next tuesday, 2 years ago.
* Pure numbers in date strings:: 19931219, 1440.
* Seconds since the Epoch:: @@1078100502.
* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0".
* Authors of parse_datetime:: Bellovin, Eggert, Salz, Berets, et al.
* General date syntax:: Common rules
* Calendar date items:: 21 Jul 2020
* Time of day items:: 9:20pm
* Time zone items:: UTC, -0700, +0900, @dots{}
* Combined date and time of day items:: 2020-07-21T20:02:00,000000-0400
* Day of week items:: Monday and others
* Relative items in date strings:: next tuesday, 2 years ago
* Pure numbers in date strings:: 20200721, 1440
* Seconds since the Epoch:: @@1595289600
* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0"
* Authors of parse_datetime:: Bellovin, Eggert, Salz, Berets, et al.
Controlling the Archive Format
@@ -388,6 +409,29 @@ Using Multiple Tapes
* Tarcat:: Concatenate Volumes into a Single Archive
Reliability and Security
* Reliability::
* Security::
Reliability
* Permissions problems::
* Data corruption and repair::
* Race conditions::
Security
* Privacy::
* Integrity::
* Live untrusted data::
* Security rules of thumb::
Recipes
* copy directory hierarchy::
* intermediate directories::
Tar Internals
* Standard:: Basic Tar Format
@@ -410,7 +454,7 @@ Genfile
Copying This Manual
* GNU Free Documentation License:: License for copying this manual
* GNU Free Documentation License:: License for copying this manual.
@end detailmenu
@end menu
@@ -631,7 +675,7 @@ For version 1.12, Daniel Hagerty contributed a great deal of technical
consulting. In particular, he is the primary author of @ref{Backups}.
In July, 2003 @GNUTAR{} was put on CVS at savannah.gnu.org
(see @url{http://savannah.gnu.org/projects/tar}), and
(see @url{https://savannah.gnu.org/projects/tar}), and
active development and maintenance work has started
again. Currently @GNUTAR{} is being maintained by Paul Eggert, Sergey
Poznyakoff and Jeff Bailey.
@@ -954,6 +998,19 @@ Note that you must double the hyphens properly each time.
Later in the tutorial, we will give examples using @w{@option{--verbose
--verbose}}.
The @option{--verbose} option also enables several @dfn{warning
messages}, that tar does not issue otherwise, such as the
warning about record size being used (@pxref{Blocking Factor}), selecting
the decompress program and the like. If these are of no interest to
you, you can suppress them using the @option{--warning} option
@emph{after} @option{--verbose}, e.g.:
@example
$ @kbd{tar -c -v --warning=no-verbose -f afiles.tar apple angst aspic}
@end example
@xref{Warning Classes, verbose}, for details.
@anchor{verbose member listing}
The full output consists of six fields:
@@ -1031,9 +1088,6 @@ hrw-r--r-- gray/staff 0 2006-06-09 12:06 music link to blues
@end group
@end smallexample
@smallexample
@end smallexample
@node help tutorial
@unnumberedsubsec Getting Help: Using the @option{--help} Option
@@ -1221,13 +1275,8 @@ jazz
@end smallexample
This example is just like the example we showed which did not use
@option{--verbose}, except that @command{tar} generated the remaining
@iftex
lines (note the different font styles).
@end iftex
@ifinfo
@option{--verbose}, except that @command{tar} generated three output
lines.
@end ifinfo
In the rest of the examples in this chapter, we will frequently use
@code{verbose} mode so we can show actions or @command{tar} responses that
@@ -1803,7 +1852,7 @@ will extract the file @file{folk} into the current working directory.
@node going further
@section Going Further Ahead in this Manual
@UNREVISED
@UNREVISED{}
@FIXME{need to write up a node here about the things that are going to
be in the rest of the manual.}
@@ -2362,7 +2411,7 @@ tape! @xref{delete}.
@item --diff
@itemx -d
Same @option{--compare}. @xref{compare}.
Same as @option{--compare}. @xref{compare}.
@opsummary{extract}
@item --extract
@@ -2854,7 +2903,7 @@ Ignore exit codes of subprocesses. @xref{Writing to an External Program}.
@opsummary{ignore-failed-read}
@item --ignore-failed-read
Do not exit unsuccessfully merely because an unreadable file was encountered.
Do not exit unsuccessfully merely because reading failed.
@xref{Ignore Failed Read}.
@opsummary{ignore-zeros}
@@ -2862,7 +2911,9 @@ Do not exit unsuccessfully merely because an unreadable file was encountered.
@itemx -i
With this option, @command{tar} will ignore zeroed blocks in the
archive, which normally signals EOF. @xref{Reading}.
archive, which normally signals EOF. This option also suppresses
warnings about missing or incomplete zero blocks at the end of the
archive. @xref{Ignore Zeros}.
@opsummary{incremental}
@item --incremental
@@ -2940,7 +2991,7 @@ the pattern specified in @var{name}. @xref{Tape Files}.
@opsummary{level}
@item --level=@var{n}
Force incremental backup of level @var{n}. As of @GNUTAR version
Force incremental backup of level @var{n}. As of @GNUTAR{} version
@value{VERSION}, the option @option{--level=0} truncates the snapshot
file, thereby forcing the level 0 dump. Other values of @var{n} are
effectively ignored. @xref{--level=0}, for details and examples.
@@ -3286,7 +3337,7 @@ Same as @option{--format=posix}.
@opsummary{preserve-order}
@item --preserve-order
(See @option{--same-order}; @pxref{Reading}.)
(See @option{--same-order}; @pxref{Same Order}.)
@opsummary{preserve-permissions}
@opsummary{same-permissions}
@@ -3376,7 +3427,7 @@ devices. @xref{Device}.
This option is an optimization for @command{tar} when running on machines with
small amounts of memory. It informs @command{tar} that the list of file
arguments has already been sorted to match the order of files in the
archive. @xref{Reading}.
archive. @xref{Same Order}.
@opsummary{same-owner}
@item --same-owner
@@ -3992,16 +4043,16 @@ itself, containing possibly many programs. The package is currently
named @samp{tar}, after the name of the main program it
contains@footnote{There are plans to merge the @command{cpio} and
@command{tar} packages into a single one which would be called
@code{paxutils}. So, who knows if, one of this days, the
@option{--version} would not output @w{@samp{tar (@acronym{GNU}
@code{paxutils}. So, who knows, one of these days
@option{--version} might output @w{@samp{tar (@acronym{GNU}
paxutils) 3.2}}.}.
@cindex Obtaining help
@cindex Listing all @command{tar} options
@xopindex{help, introduction}
Another thing you might want to do is checking the spelling or meaning
Another thing you might want to do is check the spelling or meaning
of some particular @command{tar} option, without resorting to this
manual, for once you have carefully read it. @GNUTAR{}
manual, once you have carefully read it. @GNUTAR{}
has a short help feature, triggerable through the
@option{--help} option. By using this option, @command{tar} will
print a usage message listing all available options on standard
@@ -4041,7 +4092,7 @@ The short help output is quite succinct, and you might have to get
back to the full documentation for precise points. If you are reading
this paragraph, you already have the @command{tar} manual in some
form. This manual is available in a variety of forms from
@url{http://www.gnu.org/software/tar/manual}. It may be printed out of the @GNUTAR{}
@url{https://www.gnu.org/software/tar/manual}. It may be printed out of the @GNUTAR{}
distribution, provided you have @TeX{} already installed somewhere,
and a laser printer around. Just configure the distribution, execute
the command @w{@samp{make dvi}}, then print @file{doc/tar.dvi} the
@@ -4052,12 +4103,10 @@ file. Just call @w{@samp{info tar}} or, if you do not have the
@command{info} program handy, use the Info reader provided within
@acronym{GNU} Emacs, calling @samp{tar} from the main Info menu.
There is currently no @code{man} page for @GNUTAR{}.
If you observe such a @code{man} page on the system you are running,
either it does not belong to @GNUTAR{}, or it has not
been produced by @acronym{GNU}. Some package maintainers convert
@kbd{tar --help} output to a man page, using @command{help2man}. In
any case, please bear in mind that the authoritative source of
Since 2014, @GNUTAR{} also has a @code{man} page.
It briefly explains all the options and operations.
This might be preferable when you don't need any background.
But bear in mind that the authoritative source of
information about @GNUTAR{} is this Texinfo documentation.
@node defaults
@@ -4573,110 +4622,154 @@ Control display of the warning messages identified by @var{keyword}.
If @var{keyword} starts with the prefix @samp{no-}, such messages are
suppressed. Otherwise, they are enabled.
Multiple @option{--warning} messages accumulate.
Multiple @option{--warning} options accumulate.
@end table
The tables below list allowed values for @var{keyword} along with the
By default, @GNUTAR enables all messages, except those that are
enabled in verbose mode (@pxref{verbose tutorial}). @xref{Warning
Defaults}, for details.
The subsections below discuss allowed values for @var{keyword} along with the
warning messages they control.
@end table
@subheading Keywords controlling @command{tar} operation
@table @asis
@kwindex all
@item all
Enable all warning messages. This is the default.
@kwindex none
@item none
Disable all warning messages.
@kwindex filename-with-nuls
@menu
* General Warnings:: Keywords applicable for @command{tar --create}.
* Archive Creation Warnings:: Keywords applicable for @command{tar --create}.
* Archive Extraction Warnings:: Keywords applicable for @command{tar --extract}.
* Incremental Extraction Warnings:: Keywords controlling incremental extraction.
* Warning Classes:: Convenience keywords control multiple warnings.
* Warning Defaults:: Default settings for warnings.
@end menu
@node General Warnings
@subsection Keywords controlling @command{tar} operation
These keywords control warnings that may appear in any @GNUTAR{}
operation mode:
@defvr {warning} filename-with-nuls
@cindex @samp{file name read contains nul character}, warning message
@item filename-with-nuls
@samp{%s: file name read contains nul character}
@kwindex alone-zero-block
@cindex @samp{A lone zero block at}, warning message
@item alone-zero-block
@samp{A lone zero block at %s}
@end table
@samp{file name read contains nul character}
@end defvr
@subheading Keywords applicable for @command{tar --create}
@table @asis
@kwindex cachedir
@defvr {warning} filename-with-nuls
@cindex @samp{file name read contains nul character}, warning message
@samp{%s: file name read contains nul character}
@end defvr
@defvr {warning} alone-zero-block
@cindex @samp{A lone zero block at}, warning message
@samp{A lone zero block at %s}. Notice, that this warning is
suppressed if @option{--ignore-zeros} is in effect (@pxref{Ignore
Zeros}).
@end defvr
@defvr {warning} missing-zero-blocks
@cindex @samp{Terminating zero blocks missing}, warning message.
@samp{Terminating zero blocks missing at %s}. This warning is
suppressed if @option{--ignore-zeros} is in effect (@pxref{Ignore
Zeros}).
@end defvr
@node Archive Creation Warnings
@subsection Keywords applicable for @command{tar --create}
The following keywords control messages that can be issued while
creating archives.
@defvr {warning} cachedir
@cindex @samp{contains a cache directory tag}, warning message
@item cachedir
@samp{%s: contains a cache directory tag %s; %s}
@kwindex file-shrank
@end defvr
@defvr {warning} file-shrank
@cindex @samp{File shrank by %s bytes}, warning message
@item file-shrank
@samp{%s: File shrank by %s bytes; padding with zeros}
@kwindex xdev
@end defvr
@defvr {warning} xdev
@cindex @samp{file is on a different filesystem}, warning message
@item xdev
@samp{%s: file is on a different filesystem; not dumped}
@kwindex file-ignored
@end defvr
@defvr {warning} file-ignored
@cindex @samp{Unknown file type; file ignored}, warning message
@cindex @samp{socket ignored}, warning message
@cindex @samp{door ignored}, warning message
@item file-ignored
@samp{%s: Unknown file type; file ignored}
@*@samp{%s: socket ignored}
@*@samp{%s: door ignored}
@kwindex file-unchanged
@end defvr
@defvr {warning} file-unchanged
@cindex @samp{file is unchanged; not dumped}, warning message
@item file-unchanged
@samp{%s: file is unchanged; not dumped}
@kwindex ignore-archive
@cindex @samp{file is the archive; not dumped}, warning message
@kwindex ignore-archive
@cindex @samp{file is the archive; not dumped}, warning message
@item ignore-archive
@samp{%s: file is the archive; not dumped}
@kwindex file-removed
@end defvr
@defvr {warning} ignore-archive
@cindex @samp{archive cannot contain itself; not dumped}, warning message
@samp{%s: archive cannot contain itself; not dumped}
@end defvr
@defvr {warning} file-removed
@cindex @samp{File removed before we read it}, warning message
@item file-removed
@samp{%s: File removed before we read it}
@kwindex file-changed
@end defvr
@defvr {warning} file-changed
@cindex @samp{file changed as we read it}, warning message
@item file-changed
@samp{%s: file changed as we read it}
@item failed-read
Suppresses warnings about unreadable files or directories. This
Suppresses warnings about read failures, which can occur if files
or directories are unreadable, or if they change while being read. This
keyword applies only if used together with the @option{--ignore-failed-read}
option. @xref{Ignore Failed Read}.
@end table
@end defvr
@subheading Keywords applicable for @command{tar --extract}
@table @asis
@kwindex existing-file
@node Archive Extraction Warnings
@subsection Keywords applicable for @command{tar --extract}
The following keywords control warnings that can be issued during
archive extraction.
@defvr {warning} existing-file
@cindex @samp{%s: skipping existing file}, warning message
@item existing-file
@samp{%s: skipping existing file}
@kwindex timestamp
@end defvr
@defvr {warning} timestamp
@cindex @samp{implausibly old time stamp %s}, warning message
@cindex @samp{time stamp %s is %s s in the future}, warning message
@item timestamp
@samp{%s: implausibly old time stamp %s}
@*@samp{%s: time stamp %s is %s s in the future}
@kwindex contiguous-cast
@end defvr
@defvr {warning} contiguous-cast
@cindex @samp{Extracting contiguous files as regular files}, warning message
@item contiguous-cast
@samp{Extracting contiguous files as regular files}
@kwindex symlink-cast
@cindex @samp{Attempting extraction of symbolic links as hard links}, warning message
@item symlink-cast
@end defvr
@defvr {warning} symlink-cast
@samp{Attempting extraction of symbolic links as hard links}, warning message
@samp{Attempting extraction of symbolic links as hard links}
@kwindex unknown-cast
@end defvr
@defvr {warning} unknown-cast
@cindex @samp{Unknown file type '%c', extracted as normal file}, warning message
@item unknown-cast
@samp{%s: Unknown file type '%c', extracted as normal file}
@kwindex ignore-newer
@end defvr
@defvr {warning} ignore-newer
@cindex @samp{Current %s is newer or same age}, warning message
@item ignore-newer
@samp{Current %s is newer or same age}
@kwindex unknown-keyword
@end defvr
@defvr {warning} unknown-keyword
@cindex @samp{Ignoring unknown extended header keyword '%s'}, warning message
@item unknown-keyword
@samp{Ignoring unknown extended header keyword '%s'}
@kwindex decompress-program
@item decompress-program
@end defvr
@defvr {warning} decompress-program
Controls verbose description of failures occurring when trying to run
alternative decompressor programs (@pxref{alternative decompression
programs}). This warning is disabled by default (unless
@@ -4692,33 +4785,69 @@ tar (child): trying gzip
This means that @command{tar} first tried to decompress
@file{archive.Z} using @command{compress}, and, when that
failed, switched to @command{gzip}.
@kwindex record-size
@cindex @samp{Record size = %lu blocks}, warning message
@item record-size
@samp{Record size = %lu blocks}
@end table
@end defvr
@subheading Keywords controlling incremental extraction:
@table @asis
@kwindex rename-directory
@defvr {warning} record-size
@cindex @samp{Record size = %lu blocks}, warning message
@samp{Record size = %lu blocks}
@end defvr
@node Incremental Extraction Warnings
@subsection Keywords controlling incremental extraction
These keywords control warnings that may appear when extracting from
incremental archives.
@defvr {warning} rename-directory
@cindex @samp{%s: Directory has been renamed from %s}, warning message
@cindex @samp{%s: Directory has been renamed}, warning message
@item rename-directory
@samp{%s: Directory has been renamed from %s}
@*@samp{%s: Directory has been renamed}
@kwindex new-directory
@end defvr
@defvr {warning} new-directory
@cindex @samp{%s: Directory is new}, warning message
@item new-directory
@samp{%s: Directory is new}
@kwindex xdev
@end defvr
@defvr {warning} xdev
@cindex @samp{%s: directory is on a different device: not purging}, warning message
@item xdev
@samp{%s: directory is on a different device: not purging}
@kwindex bad-dumpdir
@end defvr
@defvr {warning} bad-dumpdir
@cindex @samp{Malformed dumpdir: 'X' never used}, warning message
@item bad-dumpdir
@samp{Malformed dumpdir: 'X' never used}
@end table
@end defvr
@node Warning Classes
@subsection Warning Classes
These convenience keywords define @dfn{warning classes}. When used,
they affect several warnings at once.
@defvr {warning} all
Enable all warning messages.
@end defvr
@defvr {warning} none
Disable all warning messages.
@end defvr
@defvr {warning} verbose
A shorthand for all messages enabled when @option{--verbose}
(@pxref{verbose tutorial}) is in effect. These are:
@code{decompress-program}, @code{existing-file}, @code{new-directory},
@code{record-size}, @code{rename-directory}.
@end defvr
@node Warning Defaults
@subsection Default Warning Settings
@GNUTAR default settings correspond to:
@example
--warning=all --warning=no-verbose --warning=no-missing-zero-blocks
@end example
@node interactive
@section Asking for Confirmation During Operations
@@ -5271,7 +5400,7 @@ jazz
@end smallexample
@noindent
If you like, You can run @samp{tar --list} to make sure the archives
If you like, you can run @samp{tar --list} to make sure the archives
contain what they are supposed to:
@smallexample
@@ -5286,7 +5415,6 @@ $ @kbd{tar -tvf jazzfolk.tar}
We can concatenate these two archives with @command{tar}:
@smallexample
$ @kbd{cd ..}
$ @kbd{tar --concatenate --file=bluesrock.tar jazzfolk.tar}
@end smallexample
@@ -5632,7 +5760,7 @@ controlled by the following command line arguments:
@table @option
@item --xattrs
Enable extended attributes support. When used with @option{--create},
this option instructs @GNUTAR to store extended file attribute in the
this option instructs @GNUTAR{} to store extended file attribute in the
created archive. This implies POSIX.1-2001 archive format
(@option{--format=pax}).
@@ -5646,10 +5774,15 @@ Disable extended attributes support. This is the default.
Attribute names are strings prefixed by a @dfn{namespace} name and a dot.
Currently, four namespaces exist: @samp{user}, @samp{trusted},
@samp{security} and @samp{system}. By default, when @option{--xattr}
is used, all names are stored in the archive (or extracted, if using
@option{--extract}). This can be controlled using the following
options:
@samp{security} and @samp{system}. By default, when @option{--xattrs}
is used, all names are stored in the archive (with @option{--create}),
but only @samp{user} namespace is extracted (if using @option{--extract}).
The reason for this behavior is that any other, system defined attributes
don't provide us sufficient compatibility promise. Storing all attributes
is safe operation for the archiving purposes. Though extracting those
(often security related) attributes on a different system than originally
archived can lead to extraction failures, or even misinterpretations.
This behavior can be controlled using the following options:
@table @option
@item --xattrs-exclude=@var{pattern}
@@ -5663,12 +5796,16 @@ Here, the @var{pattern} is a globbing pattern. For example, the
following command:
@example
$ @kbd{tar --xattrs --xattrs-exclude='user.*' -c a.tar .}
$ @kbd{tar --xattrs --xattrs-exclude='user.*' -cf a.tar .}
@end example
will include in the archive @file{a.tar} all attributes, except those
from the @samp{user} namespace.
Users shall check the attributes are binary compatible with the target system
before any other namespace is extracted with an explicit
@option{--xattrs-include} option.
Any number of these options can be given, thereby creating lists of
include and exclude patterns.
@@ -5761,11 +5898,12 @@ Disable SELinux context support.
@table @option
@item --ignore-failed-read
@opindex ignore-failed-read
Do not exit with nonzero on unreadable files or directories.
Do not exit with nonzero if there are mild problems while reading.
@end table
This option has effect only during creation. It instructs tar to
treat as mild conditions any missing or unreadable files (directories).
treat as mild conditions any missing or unreadable files (directories),
or files that change while reading.
Such failures don't affect the program exit code, and the
corresponding diagnostic messages are marked as warnings, not errors.
These warnings can be suppressed using the
@@ -5852,7 +5990,11 @@ between file entries (which usually indicates the end of the archive).
@option{--ignore-zeros} (@option{-i}) allows @command{tar} to
completely read an archive which contains a block of zeros before the
end (i.e., a damaged archive, or one that was created by concatenating
several archives together).
several archives together). This option also suppresses warnings
about missing or incomplete zero blocks at the end of the archive.
This can be turned on, if the need be, using the
@option{--warning=alone-zero-block --warning=missing-zero-blocks}
options (@pxref{warnings}).
The @option{--ignore-zeros} (@option{-i}) option is turned off by default because many
versions of @command{tar} write garbage after the end-of-archive entry,
@@ -5870,7 +6012,7 @@ encountered while reading an archive. Use in conjunction with
@node Writing
@subsection Changing How @command{tar} Writes Files
@UNREVISED
@UNREVISED{}
@FIXME{Introductory paragraph}
@@ -6383,7 +6525,7 @@ Remove files after adding them to the archive.
@node Scarce
@subsection Coping with Scarce Resources
@UNREVISED
@UNREVISED{}
@cindex Small memory
@cindex Running out of space
@@ -6630,7 +6772,7 @@ called @dfn{dumps}.
@node Full Dumps
@section Using @command{tar} to Perform Full Dumps
@UNREVISED
@UNREVISED{}
@cindex full dumps
@cindex dumps, full
@@ -6956,8 +7098,8 @@ mainly variable assignments. However, any valid shell construct
is allowed in this file. Particularly, you may wish to define
functions within that script (e.g., see @code{RESTORE_BEGIN} below).
For more information about shell script syntax, please refer to
@url{http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#ta
g_02, the definition of the Shell Command Language}. See also
@url{https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html,
the definition of the Shell Command Language}. See also
@ref{Top,,Bash Features,bashref,Bash Reference Manual}.
The shell variables controlling behavior of @code{backup} and
@@ -7712,7 +7854,11 @@ command.
Any number of @option{-T} options can be given in the command line.
The following example shows how to use @command{find} to generate a list of
files smaller than 400K in length and put that list into a file
files smaller than 400 blocks in length@footnote{A file system block
is usually 512 bytes, so this amounts to 200K. Use the @samp{c}
suffix to specify size in @emph{bytes}. Also, when using
GNU find, you can specify other size units, such as @samp{k},
@samp{m}, etc. @xref{Size,,,find.info,GNU Findutils}, for details.} and put that list into a file
called @file{small-files}. You can then use the @option{-T} option to
@command{tar} to specify the files from that file, @file{small-files}, to
create the archive @file{little.tgz}. (The @option{-z} option to
@@ -7838,7 +7984,7 @@ file names that begin with dash (similar to
@option{--verbatim-files-from} option).
This example shows how to use @command{find} to generate a list of files
larger than 800K in length and put that list into a file called
larger than 800 blocks in length and put that list into a file called
@file{long-files}. The @option{-print0} option to @command{find} is just
like @option{-print}, except that it separates files with a @code{NUL}
rather than with a newline. You can then run @command{tar} with both the
@@ -7867,7 +8013,7 @@ $ @kbd{find . -size +800 -print0 |
This example uses short options for typographic reasons, to avoid
very long lines.
@GNUTAR is tries to automatically detect @code{NUL}-terminated file
@GNUTAR{} is tries to automatically detect @code{NUL}-terminated file
lists, so in many cases it is safe to use them even without the
@option{--null} option. In this case @command{tar} will print a
warning and continue reading such a file as if @option{--null} were
@@ -10194,11 +10340,9 @@ contain @samp{/-}. Avoid deep directory nesting. For portability to
old Unix hosts, limit your file name components to 14 characters or
less.
If you intend to have your @command{tar} archives to be read under
MSDOS, you should not rely on case distinction for file names, and you
might use the @acronym{GNU} @command{doschk} program for helping you
further diagnosing illegal MSDOS names, which are even more limited
than System V's.
If you intend to have your @command{tar} archives to be read on
case-insensitive file systems like FAT32,
you should not rely on case distinction for file names.
@node dereference
@subsection Symbolic Links
@@ -10423,6 +10567,9 @@ the following forms:
When used with one of archive-creation commands,
this option instructs @command{tar} to omit from extended header records
that it produces any keywords matching the string @var{pattern}.
If the pattern contains shell metacharacters like @samp{*}, it should
be quoted to prevent the shell from expanding the pattern before
@command{tar} sees it.
When used in extract or list mode, this option instructs tar
to ignore any keywords matching the given @var{pattern} in the extended
@@ -10431,7 +10578,7 @@ matching notation described in @acronym{POSIX 1003.2}, 3.13
(@pxref{wildcards}). For example:
@smallexample
--pax-option delete=security.*
--pax-option 'delete=security.*'
@end smallexample
would suppress security-related information.
@@ -10560,11 +10707,9 @@ For example, to set all modification times to the current date, you
use the following option:
@smallexample
--pax-option='mtime:=@{now@}'
--pax-option 'mtime:=@{now@}'
@end smallexample
Note quoting of the option's argument.
@cindex archives, binary equivalent
@cindex binary equivalent archives, creating
As another example, here is the option that ensures that any two
@@ -10572,36 +10717,36 @@ archives created using it, will be binary equivalent if they have the
same contents:
@smallexample
--pax-option=atime:=0
--pax-option delete=atime
@end smallexample
@noindent
If you extract files from such an archive and recreate the archive
from them, you will also need to eliminate changes due to ctime, as
shown in examples below:
from them, you will also need to eliminate changes due to ctime:
@smallexample
--pax-option=atime:=0,ctime:=0
--pax-option 'delete=atime,delete=ctime'
@end smallexample
@noindent
or
Normally @command{tar} saves an mtime value with subsecond resolution
in an extended header for any file with a timestamp that is not on a
one-second boundary. This is in addition to the traditional mtime
timestamp in the header block. Although you can suppress subsecond
timestamp resolution with @option{--pax-option delete=mtime},
this hack will not work for timestamps before 1970 or after 2242-03-16
12:56:31 @sc{utc}.
If the environment variable @env{POSIXLY_CORRECT} is set, two POSIX
archives created using the same options on the same set of files might
not be byte-to-byte equivalent even with the above options. This is
because the POSIX default for extended header names includes
the @command{tar} process @acronym{ID}, which typically differs at each
run. To produce byte-to-byte equivalent archives in this case, either
unset @env{POSIXLY_CORRECT}, or use the following option, which can be
combined with the above options:
@smallexample
--pax-option=atime:=0,delete=ctime
@end smallexample
Notice, that if you create an archive in POSIX format (@pxref{posix})
and the environment variable @env{POSIXLY_CORRECT} is set, then the
two archives created using the same options on the same set of files
will not be byte-to-byte equivalent even with the above option. This
is because the posix default for extended header names includes the
PID of the tar process, which is different at each run. To produce
byte-to-byte equivalent archives in this case, either unset
@env{POSIXLY_CORRECT}, or use the following option:
@smallexample
---pax-option=exthdr.name=%d/PaxHeaders/%f,atime:=0,ctime:=0
--pax-option exthdr.name=%d/PaxHeaders/%f
@end smallexample
@node Checksumming
@@ -10645,7 +10790,7 @@ a @command{tar} able to read the good archives they receive.
@cindex large values
@cindex future time stamps
@cindex negative time stamps
@UNREVISED
@UNREVISED{}
The above sections suggest to use @samp{oldest possible} archive
format if in doubt. However, sometimes it is not possible. If you
@@ -11028,7 +11173,7 @@ Done
@node cpio
@section Comparison of @command{tar} and @command{cpio}
@UNREVISED
@UNREVISED{}
@FIXME{Reorganize the following material}
@@ -11140,7 +11285,7 @@ easily test, because the resulting archive gets smaller, and
@node Media
@chapter Tapes and Other Archive Media
@UNREVISED
@UNREVISED{}
A few special cases about tape handling warrant more detailed
description. These special cases are discussed below.
@@ -11184,7 +11329,7 @@ not a good idea.
@node Device
@section Device Selection and Switching
@UNREVISED
@UNREVISED{}
@table @option
@item -f [@var{hostname}:]@var{file}
@@ -11552,7 +11697,7 @@ device.
@cindex Format Options
@cindex Options, archive format specifying
@cindex Options, format specifying
@UNREVISED
@UNREVISED{}
Format parameters specify how an archive is written on the archive
media. The best choice of format parameters will vary depending on
@@ -11576,7 +11721,7 @@ examples of format parameter considerations.
@cindex Number of bytes per record
@cindex Bytes per record
@cindex Blocks per record
@UNREVISED
@UNREVISED{}
@opindex blocking-factor
The data in an archive is grouped into blocks, which are 512 bytes.
@@ -11929,7 +12074,7 @@ you should do the proper things for that as well. @xref{Blocking}.
@node Tape Positioning
@subsection Tape Positions and Tape Marks
@UNREVISED
@UNREVISED{}
Just as archives can store more than one file from the file system,
tapes can store more than one archive file. To keep track of where
@@ -11970,7 +12115,7 @@ rrrr*rrrrrr*rrrrr*rr*rrrrr*rrr*rrrr**----------------
@node mt
@subsection The @command{mt} Utility
@UNREVISED
@UNREVISED{}
@FIXME{Is it true that this only works on non-block devices?
should explain the difference, (fixed or variable).}
@@ -12355,7 +12500,7 @@ implementation, read @ref{Split Recovery}.
@subsection Tape Files
@cindex labeling archives
@opindex label
@UNREVISED
@UNREVISED{}
To give the archive a name which will be recorded in it, use the
@option{--label=@var{volume-label}} (@option{-V @var{volume-label}})

View File

@@ -1,4 +1,4 @@
# Copyright 2006-2021 Free Software Foundation, Inc.
# Copyright 2006-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -1,5 +1,5 @@
@c This is part of GNU tar manual.
@c Copyright 1992--2021 Free 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: 30820c2d7c...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-2021 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,6 +88,7 @@ stat-time
stdbool
stdint
stpcpy
stdopen
strdup-posix
strerror
strnlen
@@ -103,3 +109,4 @@ xalloc-die
xgetcwd
xstrtoumax
xvasprintf
year2038-recommended

View File

@@ -1,6 +1,6 @@
# Makefile for GNU tar library. -*- Makefile -*-
# Copyright 1994-2021 Free Software Foundation, Inc.
# Copyright 1994-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -32,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\
@@ -42,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-2021 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,76 +0,0 @@
/* stdopen.c - ensure that the three standard file descriptors are in use
Copyright 2005-2021 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

View File

@@ -36,14 +36,6 @@
#define _(msgid) gettext (msgid)
#define N_(msgid) msgid
#ifndef FALLTHROUGH
# if __GNUC__ < 7
# define FALLTHROUGH ((void) 0)
# else
# define FALLTHROUGH __attribute__ ((__fallthrough__))
# endif
#endif
#include <wordsplit.h>
#define ISWS(c) ((c)==' '||(c)=='\t'||(c)=='\n')
@@ -74,7 +66,7 @@ _wsplt_alloc_die (struct wordsplit *wsp)
abort ();
}
static void __WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2))
static void ATTRIBUTE_FORMAT ((__printf__, 1, 2))
_wsplt_error (const char *fmt, ...)
{
va_list ap;
@@ -95,7 +87,7 @@ _wsplt_seterr (struct wordsplit *wsp, int ec)
wordsplit_perror (wsp);
return ec;
}
static int
_wsplt_nomem (struct wordsplit *wsp)
{
@@ -126,7 +118,7 @@ _wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
unsigned flags, int finalize)
{
int rc;
wss->ws_delim = wsp->ws_delim;
wss->ws_debug = wsp->ws_debug;
wss->ws_error = wsp->ws_error;
@@ -150,7 +142,7 @@ _wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
}
wss->ws_options = wsp->ws_options;
flags |= WRDSF_DELIM
| WRDSF_ALLOC_DIE
| WRDSF_ERROR
@@ -209,7 +201,7 @@ wordsplit_init0 (struct wordsplit *wsp)
}
char wordsplit_c_escape_tab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
static int
wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
unsigned flags)
@@ -282,7 +274,7 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
{
wsp->ws_escape[WRDSX_WORD] = wordsplit_c_escape_tab;
wsp->ws_escape[WRDSX_QUOTE] = wordsplit_c_escape_tab;
wsp->ws_options |= WRDSO_OESC_QUOTE | WRDSO_OESC_WORD
wsp->ws_options |= WRDSO_OESC_QUOTE | WRDSO_OESC_WORD
| WRDSO_XESC_QUOTE | WRDSO_XESC_WORD;
}
else
@@ -292,16 +284,16 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
wsp->ws_options |= WRDSO_BSKEEP_QUOTE;
}
}
wsp->ws_endp = 0;
wsp->ws_wordi = 0;
if (wsp->ws_flags & WRDSF_REUSE)
wordsplit_free_nodes (wsp);
wsp->ws_head = wsp->ws_tail = NULL;
wordsplit_init0 (wsp);
return 0;
}
@@ -424,14 +416,13 @@ wsnode_len (struct wordsplit_node *p)
return p->v.segm.end - p->v.segm.beg;
}
static int
wsnode_new (struct wordsplit *wsp, struct wordsplit_node **pnode)
static struct wordsplit_node *
wsnode_new (struct wordsplit *wsp)
{
struct wordsplit_node *node = calloc (1, sizeof (*node));
if (!node)
return _wsplt_nomem (wsp);
*pnode = node;
return 0;
_wsplt_nomem (wsp);
return node;
}
static void
@@ -481,7 +472,7 @@ wsnode_remove (struct wordsplit *wsp, struct wordsplit_node *node)
static struct wordsplit_node *
wsnode_tail (struct wordsplit_node *p)
{
while (p && p->next)
while (p->next)
p = p->next;
return p;
}
@@ -527,14 +518,11 @@ wsnode_insert (struct wordsplit *wsp, struct wordsplit_node *node,
static int
wordsplit_add_segm (struct wordsplit *wsp, size_t beg, size_t end, int flg)
{
struct wordsplit_node *node;
int rc;
if (end == beg && !(flg & _WSNF_EMPTYOK))
return 0;
rc = wsnode_new (wsp, &node);
if (rc)
return rc;
struct wordsplit_node *node = wsnode_new (wsp);
if (!node)
return 1;
node->flags = flg & ~(_WSNF_WORD | _WSNF_EMPTYOK);
node->v.segm.beg = beg;
node->v.segm.end = end;
@@ -583,17 +571,16 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
struct wordsplit_node *p, *end;
size_t len = 0;
char *buf, *cur;
int stop;
if (!(node->flags & _WSNF_JOIN))
return 0;
for (p = node; p && (p->flags & _WSNF_JOIN); p = p->next)
for (p = node; p->flags & _WSNF_JOIN; )
{
len += wsnode_len (p);
p = p->next;
if (!p)
break;
}
if (p)
len += wsnode_len (p);
if (p == node)
return 0;
end = p;
buf = malloc (len + 1);
@@ -602,7 +589,7 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
cur = buf;
p = node;
for (stop = 0; !stop;)
for (;;)
{
struct wordsplit_node *next = p->next;
const char *str = wsnode_ptr (wsp, p);
@@ -614,7 +601,12 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
{
node->flags |= p->flags & _WSNF_QUOTE;
wsnode_remove (wsp, p);
stop = p == end;
if (p == end)
{
/* Call wsnode_free separately to work around GCC bug 106427. */
wsnode_free (p);
break;
}
wsnode_free (p);
}
p = next;
@@ -717,7 +709,7 @@ wordsplit_finish (struct wordsplit *wsp)
Nodes of type _WSNF_DELIM get inserted to the node list if either
WRDSF_RETURN_DELIMS flag or WRDSO_MAXWORDS option is set.
The following cases should be distinguished:
1. If both WRDSF_SQUEEZE_DELIMS and WRDSF_RETURN_DELIMS are set, compress
@@ -781,7 +773,7 @@ wordsplit_finish (struct wordsplit *wsp)
continue;
}
}
else
else
{
if (delim)
{
@@ -900,11 +892,11 @@ node_split_prefix (struct wordsplit *wsp,
struct wordsplit_node *node,
size_t beg, size_t len, int flg)
{
struct wordsplit_node *newnode;
if (len == 0)
return 0;
if (wsnode_new (wsp, &newnode))
struct wordsplit_node *newnode = wsnode_new (wsp);
if (!newnode)
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
if (node->flags & _WSNF_WORD)
@@ -958,7 +950,7 @@ find_closing_paren (const char *str, size_t i, size_t len, size_t *poff,
break;
}
break;
case '"':
state = st_dquote;
break;
@@ -1038,7 +1030,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
{
int n = (wsp->ws_flags & WRDSF_ENV_KV) ? 2 : 1;
char *v;
if (wsp->ws_envidx + n >= wsp->ws_envsiz)
{
size_t sz;
@@ -1055,7 +1047,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
for (; wsp->ws_env[i]; i++)
;
}
sz = i + n + 1;
newenv = calloc (sz, sizeof(newenv[0]));
@@ -1075,7 +1067,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
}
}
newenv[j] = NULL;
wsp->ws_envbuf = newenv;
wsp->ws_envidx = i;
wsp->ws_envsiz = sz;
@@ -1104,7 +1096,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
wsp->ws_env = (const char**) wsp->ws_envbuf;
}
}
if (wsp->ws_flags & WRDSF_ENV_KV)
{
/* A key-value pair environment */
@@ -1149,7 +1141,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
const char *start = str - 1;
int rc;
struct wordsplit ws;
if (ISVARBEG (str[0]))
{
for (i = 1; i < len; i++)
@@ -1166,7 +1158,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
if (str[i] == ':')
{
size_t j;
defstr = str + i + 1;
if (find_closing_paren (str, i + 1, len, &j, "{}"))
return _wsplt_seterr (wsp, WRDSE_CBRACE);
@@ -1182,7 +1174,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
else if (strchr ("-+?=", str[i]))
{
size_t j;
defstr = str + i;
if (find_closing_paren (str, i, len, &j, "{}"))
return _wsplt_seterr (wsp, WRDSE_CBRACE);
@@ -1195,7 +1187,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
else
{
if (wsnode_new (wsp, &newnode))
newnode = wsnode_new (wsp);
if (!newnode)
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
*ptail = newnode;
@@ -1247,7 +1240,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
rc = WRDSE_UNDEF;
}
}
switch (rc)
{
case WRDSE_OK:
@@ -1267,7 +1260,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
wordsplit_free (&ws);
}
break;
case WRDSE_UNDEF:
if (defstr)
{
@@ -1287,11 +1280,11 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
value = ws.ws_wordv[0];
ws.ws_wordv[0] = NULL;
wordsplit_free (&ws);
if (defstr[-1] == '=')
wsplt_assign_var (wsp, str, i, value);
}
else
else
{
if (*defstr == '?')
{
@@ -1339,7 +1332,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
}
break;
case WRDSE_NOSPACE:
return _wsplt_nomem (wsp);
@@ -1357,7 +1350,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
{
if (flg & _WSNF_QUOTE)
{
if (wsnode_new (wsp, &newnode))
newnode = wsnode_new (wsp);
if (!newnode)
{
free (value);
return 1;
@@ -1371,7 +1365,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
{
free (value);
/* Empty string is a special case */
if (wsnode_new (wsp, &newnode))
newnode = wsnode_new (wsp);
if (!newnode)
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
*ptail = newnode;
@@ -1381,7 +1376,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
{
struct wordsplit ws;
int rc;
rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
WRDSF_NOVAR | WRDSF_NOCMD |
WRDSF_QUOTE
@@ -1404,7 +1399,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
{
size_t size = *pend - start + 1;
if (wsnode_new (wsp, &newnode))
newnode = wsnode_new (wsp);
if (!newnode)
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
*ptail = newnode;
@@ -1417,7 +1413,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
else
{
if (wsnode_new (wsp, &newnode))
newnode = wsnode_new (wsp);
if (!newnode)
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
*ptail = newnode;
@@ -1486,7 +1483,7 @@ node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
}
return 0;
}
/* Remove NULL nodes from the list */
static void
wsnode_nullelim (struct wordsplit *wsp)
@@ -1539,7 +1536,7 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
size_t j;
char *value;
struct wordsplit_node *newnode;
str++;
len--;
@@ -1566,7 +1563,7 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
}
else
rc = wsp->ws_command (&value, str, j, NULL, wsp->ws_closure);
if (rc == WRDSE_NOSPACE)
return _wsplt_nomem (wsp);
else if (rc)
@@ -1585,7 +1582,8 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
{
if (flg & _WSNF_QUOTE)
{
if (wsnode_new (wsp, &newnode))
newnode = wsnode_new (wsp);
if (!newnode)
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
*ptail = newnode;
@@ -1596,7 +1594,8 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
{
free (value);
/* Empty string is a special case */
if (wsnode_new (wsp, &newnode))
newnode = wsnode_new (wsp);
if (!newnode)
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
*ptail = newnode;
@@ -1627,7 +1626,8 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
}
else
{
if (wsnode_new (wsp, &newnode))
newnode = wsnode_new (wsp);
if (!newnode)
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
*ptail = newnode;
@@ -1674,13 +1674,13 @@ wordsplit_trimws (struct wordsplit *wsp)
;
p->v.segm.beg = n;
}
while (p->next && (p->flags & _WSNF_JOIN))
p = p->next;
if (p->flags & _WSNF_QUOTE)
continue;
/* Trim trailing whitespace */
for (n = p->v.segm.end;
n > p->v.segm.beg && ISWS (wsp->ws_input[n - 1]); n--);
@@ -1699,7 +1699,7 @@ wordsplit_tildexpand (struct wordsplit *wsp)
struct wordsplit_node *p;
char *uname = NULL;
size_t usize = 0;
for (p = wsp->ws_head; p; p = p->next)
{
const char *str;
@@ -1714,7 +1714,7 @@ wordsplit_tildexpand (struct wordsplit *wsp)
size_t slen = wsnode_len (p);
struct passwd *pw;
char *newstr;
for (i = 1; i < slen && str[i] != '/'; i++)
;
if (i == slen)
@@ -1788,7 +1788,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
if (wsp->ws_options & WRDSO_DOTGLOB)
flags = GLOB_PERIOD;
#endif
for (p = wsp->ws_head; p; p = next)
{
const char *str;
@@ -1807,23 +1807,23 @@ wordsplit_pathexpand (struct wordsplit *wsp)
glob_t g;
struct wordsplit_node *prev;
char *pattern;
pattern = malloc (slen + 1);
if (!pattern)
return _wsplt_nomem (wsp);
memcpy (pattern, str, slen);
pattern[slen] = 0;
switch (glob (pattern, flags, NULL, &g))
{
case 0:
free (pattern);
break;
case GLOB_NOSPACE:
free (pattern);
return _wsplt_nomem (wsp);
case GLOB_NOMATCH:
if (wsp->ws_options & WRDSO_NULLGLOB)
{
@@ -1846,7 +1846,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
}
free (pattern);
continue;
default:
free (pattern);
return _wsplt_seterr (wsp, WRDSE_GLOBERR);
@@ -1855,10 +1855,10 @@ wordsplit_pathexpand (struct wordsplit *wsp)
prev = p;
for (i = 0; i < g.gl_pathc; i++)
{
struct wordsplit_node *newnode;
struct wordsplit_node *newnode = wsnode_new (wsp);
char *newstr;
if (wsnode_new (wsp, &newnode))
if (!newnode)
return 1;
newstr = strdup (g.gl_pathv[i]);
if (!newstr)
@@ -1915,19 +1915,19 @@ skip_sed_expr (const char *command, size_t i, size_t len)
/* wsp->ws_endp points to a delimiter character. If RETURN_DELIMS
is true, return its value, otherwise return the index past it. */
static inline size_t
static size_t
skip_delim_internal (struct wordsplit *wsp, int return_delims)
{
return return_delims ? wsp->ws_endp : wsp->ws_endp + 1;
}
static inline size_t
static size_t
skip_delim (struct wordsplit *wsp)
{
return skip_delim_internal (wsp, WSP_RETURN_DELIMS (wsp));
}
static inline size_t
static size_t
skip_delim_real (struct wordsplit *wsp)
{
return skip_delim_internal (wsp, wsp->ws_flags & WRDSF_RETURN_DELIMS);
@@ -1975,7 +1975,7 @@ scan_word (struct wordsplit *wsp, size_t start, int consume_all)
int join = 0;
unsigned flags = 0;
struct wordsplit_node *np = wsp->ws_tail;
size_t i = start;
if (i >= len)
@@ -2064,7 +2064,7 @@ scan_word (struct wordsplit *wsp, size_t start, int consume_all)
wsp->ws_endp = i;
if (wsp->ws_flags & WRDSF_INCREMENTAL)
return _WRDS_EOF;
if (consume_all)
{
if (!np)
@@ -2075,7 +2075,7 @@ scan_word (struct wordsplit *wsp, size_t start, int consume_all)
np = np->next;
}
}
return _WRDS_OK;
}
@@ -2320,8 +2320,8 @@ static struct exptab exptab[] = {
{ NULL }
};
static inline int
exptab_matches(struct exptab *p, struct wordsplit *wsp)
static int
exptab_matches (struct exptab *p, struct wordsplit *wsp)
{
int result;
@@ -2342,7 +2342,7 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start)
if (wsp->ws_flags & WRDSF_SHOWDBG)
wsp->ws_debug (_("(%02d) Input:%.*s;"),
wsp->ws_lvl, (int) wsp->ws_len, wsp->ws_input);
if ((wsp->ws_flags & WRDSF_NOSPLIT)
|| ((wsp->ws_options & WRDSO_MAXWORDS)
&& wsp->ws_wordi + 1 == wsp->ws_maxwords))
@@ -2438,7 +2438,7 @@ wordsplit_run (const char *command, size_t length, struct wordsplit *wsp,
}
int
wordsplit_len (const char *command, size_t length, struct wordsplit *wsp,
wordsplit_len (const char *command, size_t length, struct wordsplit *wsp,
unsigned flags)
{
return wordsplit_run (command, length, wsp, flags, 0);
@@ -2559,4 +2559,3 @@ wordsplit_perror (struct wordsplit *wsp)
wsp->ws_error ("%s", wordsplit_strerror (wsp));
}
}

View File

@@ -18,12 +18,7 @@
#define __WORDSPLIT_H
#include <stddef.h>
#if 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
#else
# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) /* empty */
#endif
#include <attribute.h>
typedef struct wordsplit wordsplit_t;
@@ -36,16 +31,16 @@ typedef struct wordsplit wordsplit_t;
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
struct wordsplit
{
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 accomodate. */
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. */
@@ -62,11 +57,11 @@ struct wordsplit
/* [Input] (WRDSF_ALLOC_DIE) Function called when
out of memory. Must not return. */
void (*ws_error) (const char *, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
ATTRIBUTE_FORMAT ((printf, 1, 2));
/* [Input] (WRDSF_ERROR) Function used for error
reporting */
void (*ws_debug) (const char *, ...)
__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
@@ -75,7 +70,7 @@ struct wordsplit
char **ws_envbuf;
size_t ws_envidx;
size_t ws_envsiz;
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
@@ -100,8 +95,8 @@ struct wordsplit
See ws_getvar for a discussion of possible
return values. */
const char *ws_input; /* Input string (the S argument to wordsplit. */
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. */
@@ -221,9 +216,9 @@ struct wordsplit
/* 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
#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
@@ -253,15 +248,6 @@ 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);
static inline void wordsplit_getwords (wordsplit_t *ws, size_t *wordc, char ***wordv)
__attribute__ ((deprecated));
static inline void
wordsplit_getwords (wordsplit_t *ws, size_t *wordc, char ***wordv)
{
wordsplit_get_words (ws, wordc, wordv);
}
int wordsplit_append (wordsplit_t *wsp, int argc, char **argv);
int wordsplit_c_unquote_char (int c);

View File

@@ -1,7 +1,7 @@
/* openat-style fd-relative functions for operating with extended file
attributes.
Copyright 2012-2021 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-2021 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,6 +1,6 @@
# List of files which contain translatable strings.
# Copyright 1996-2021 Free Software Foundation, Inc.
# Copyright 1996-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -1,6 +1,6 @@
# Make GNU tar scripts.
# Copyright 2004-2021 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,7 +82,7 @@ SLEEP_MESSAGE="`awk '
}' /dev/null`"
# Copyright 2004-2021 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-2021 Free Software Foundation, Inc.
# Copyright 2004-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

@@ -8,7 +8,7 @@
# interested parties that a tape for the next volume of the backup needs to
# be put in the tape drive.
# Copyright 2004-2021 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
# Restore backups.
# Copyright 2004-2021 Free Software Foundation, Inc.
# Copyright 2004-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -183,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,6 +1,6 @@
#! /usr/bin/perl -w
# Display and edit the 'dev' field in tar's snapshots
# Copyright 2007-2021 Free Software Foundation, Inc.
# Copyright 2007-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.

View File

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

View File

@@ -1,7 +1,7 @@
/* xsparse - expands compressed sparse file images extracted from GNU tar
archives.
Copyright 2006-2021 Free Software Foundation, Inc.
Copyright 2006-2023 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -1,6 +1,6 @@
# Makefile for GNU tar sources.
# Copyright 1994-2021 Free Software Foundation, Inc.
# Copyright 1994-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -49,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,5 +1,5 @@
/* Long integers, for GNU tar.
Copyright 1999-2021 Free Software Foundation, Inc.
Copyright 1999-2023 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -1,6 +1,6 @@
/* Buffer management for tar.
Copyright 1988-2021 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -20,7 +20,6 @@
Written by John Gilmore, on 1985-08-25. */
#include <system.h>
#include <system-ioctl.h>
#include <signal.h>
@@ -28,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
@@ -308,6 +313,7 @@ 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" },
@@ -327,15 +333,15 @@ static struct zip_program zip_program[] = {
{ ct_lzop, LZOP_PROGRAM, "--lzop" },
{ ct_xz, XZ_PROGRAM, "-J" },
{ ct_zstd, ZSTD_PROGRAM, "--zstd" },
{ ct_none }
};
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)
{
@@ -352,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;
@@ -368,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;
}
@@ -420,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 */
@@ -702,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")));
@@ -796,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,
@@ -832,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)
{
@@ -998,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. */
@@ -1048,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);
@@ -1325,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;
@@ -1372,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:
@@ -1397,7 +1376,7 @@ new_volume (enum access_mode mode)
goto tryagain;
}
SET_BINARY_MODE (archive);
get_archive_status (mode, false);
return true;
}
@@ -1505,7 +1484,7 @@ try_new_volume (void)
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:
@@ -1688,6 +1667,7 @@ _write_volume_label (const char *str)
{
union block *label = find_next_block ();
assume (label);
memset (label, 0, BLOCKSIZE);
strcpy (label->header.name, str);
@@ -1848,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-2021 Free Software Foundation, Inc.
Copyright 2007-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -84,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;

View File

@@ -1,6 +1,6 @@
/* Common declarations for the tar program.
Copyright 1988-2021 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -43,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
@@ -379,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 */
@@ -397,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;
@@ -407,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;
@@ -469,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);
@@ -504,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);
@@ -616,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));
@@ -624,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. */
@@ -633,7 +636,10 @@ 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);
@@ -670,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. */
@@ -729,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]);
@@ -751,7 +759,7 @@ enum files_count
extern enum files_count filename_args;
/* Return true if there are file names in the list */
static inline bool
COMMON_INLINE bool
name_more_files (void)
{
return filename_args != FILES_NONE;
@@ -765,7 +773,6 @@ 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);
@@ -778,7 +785,7 @@ 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);
@@ -799,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);
@@ -885,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);
@@ -912,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);
@@ -923,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 */
@@ -978,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,6 +1,6 @@
/* Diff files from a tar archive.
Copyright 1988-2021 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -73,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;
}
@@ -566,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,6 +1,6 @@
/* Create a tar archive.
Copyright 1985-2021 Free Software Foundation, Inc.
Copyright 1985-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -22,6 +22,7 @@
#include <system.h>
#include <areadlink.h>
#include <flexmember.h>
#include <quotearg.h>
#include "common.h"
@@ -36,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
@@ -174,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 =
@@ -205,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
@@ -245,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:
@@ -272,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))
@@ -308,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;
}
@@ -321,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';
@@ -342,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
@@ -383,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
@@ -398,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)
@@ -428,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
@@ -452,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
@@ -881,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)
{
@@ -966,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);
}
}
@@ -1529,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;
@@ -1650,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;
@@ -1694,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))
@@ -1734,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;
}
@@ -1747,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);
@@ -1815,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);
}
@@ -1889,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);
}
@@ -1937,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,6 +1,6 @@
/* Delete entries from a tar archive.
Copyright 1988-2021 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -18,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>
@@ -50,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,
@@ -147,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)
{
@@ -155,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;
@@ -163,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)
{
@@ -175,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;
@@ -243,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;
@@ -259,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-2021 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);
@@ -198,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;
@@ -212,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;
@@ -224,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-2021 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,6 +1,6 @@
/* GNU dump extensions to tar.
Copyright 1988-2021 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -903,19 +903,19 @@ store_rename (struct directory *dir, struct obstack *stk)
else
{
char *temp_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);
free (temp_name);
}
@@ -993,7 +993,7 @@ read_incr_db_01 (int version, const char *initbuf)
}
else
{
buf = strdup (initbuf);
buf = xstrdup (initbuf);
bufsize = strlen (buf) + 1;
}

View File

@@ -1,6 +1,6 @@
/* List a tar archive, with support routines for reading a tar archive.
Copyright 1988-2021 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -256,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];
@@ -408,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. */
@@ -437,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
@@ -447,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;
@@ -517,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! */
@@ -536,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
{
@@ -567,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
{
@@ -578,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')
@@ -858,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
@@ -1352,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];
@@ -1375,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)
@@ -1410,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)
{
@@ -1419,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 ();
}

View File

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

View File

@@ -1,6 +1,6 @@
/* Miscellaneous functions, not really specific to GNU tar.
Copyright 1988-2021 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
@@ -42,11 +42,28 @@ 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
@@ -61,6 +78,8 @@ assign_string_n (char **string, const char *value, size_t n)
p[l] = 0;
*string = p;
}
else
*string = NULL;
}
#if 0
@@ -676,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;
}
}
@@ -715,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. */
@@ -758,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;
}
}
@@ -782,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);
}
}
@@ -804,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)
@@ -812,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;
}
@@ -908,8 +927,6 @@ chdir_count (void)
int
chdir_arg (char const *dir)
{
char *absdir;
if (wd_count == wd_alloc)
{
if (wd_alloc == 0)
@@ -919,9 +936,7 @@ chdir_arg (char const *dir)
if (! wd_count)
{
wd[wd_count].name = ".";
wd[wd_count].abspath = xgetcwd ();
if (!wd[wd_count].abspath)
call_arg_fatal ("getcwd", ".");
wd[wd_count].abspath = NULL;
wd[wd_count].fd = AT_FDCWD;
wd_count++;
}
@@ -938,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++;
}
@@ -1054,6 +1055,40 @@ tar_getcdpath (int idx)
}
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;
}
@@ -1179,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,6 +1,6 @@
/* Various processing of names.
Copyright 1988-2021 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
@@ -199,7 +199,7 @@ names_parse_opt (int key, char *arg, struct argp_state *state)
case ADD_FILE_OPTION:
name_add_name (arg);
break;
case ARGP_KEY_ERROR:
{
struct tar_args *args = state->input;
@@ -217,7 +217,7 @@ names_parse_opt (int key, char *arg, struct argp_state *state)
name_add_option (key, arg);
else
return ARGP_ERR_UNKNOWN;
}
return 0;
}
@@ -348,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:
@@ -395,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;
@@ -744,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)
@@ -980,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;
}
@@ -1029,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;
@@ -1060,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;
@@ -1151,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.
@@ -1187,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;
}
@@ -1230,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;
@@ -1250,33 +1261,35 @@ add_starting_file (char const *file_name)
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 (whose string length is LENGTH) in the name
list. */
/* 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;
}
@@ -1305,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;
@@ -1322,7 +1333,7 @@ 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
@@ -1871,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;
@@ -1899,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 *
@@ -1910,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-2021 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,
@@ -429,27 +427,39 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i)
}
else if (bytes_read == 0)
{
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;
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
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;
{
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);
@@ -570,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;
@@ -585,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;
@@ -597,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;
}
@@ -614,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,
@@ -624,10 +637,15 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
}
else if (bytes_read == 0)
{
report_difference (file->stat_info, _("Size differs"));
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)];
@@ -666,8 +684,8 @@ check_data_region (struct tar_sparse_file *file, size_t i)
return false;
}
set_next_block_after (blk);
file->dumped_size += BLOCKSIZE;
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,
@@ -679,7 +697,14 @@ check_data_region (struct tar_sparse_file *file, size_t i)
}
else if (bytes_read == 0)
{
report_difference (&current_stat_info, _("Size differs"));
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;
@@ -720,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);
@@ -754,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;
}
@@ -898,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;
}
@@ -1018,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
@@ -1250,7 +1275,7 @@ pax_decode_header (struct tar_sparse_file *file)
char *p;
size_t i;
off_t start;
#define COPY_BUF(b,buf,src) do \
{ \
char *endp = b->buffer + BLOCKSIZE; \
@@ -1308,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));

View File

@@ -1,5 +1,5 @@
/* This file is part of GNU tar.
Copyright 2007-2021 Free Software Foundation, Inc.
Copyright 2007-2023 Free Software Foundation, Inc.
Written by Sergey Poznyakoff.

View File

@@ -1,6 +1,6 @@
/* System-dependent calls for tar.
Copyright 2003-2021 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
@@ -16,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>
@@ -37,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
@@ -51,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)
{
@@ -128,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". */
@@ -160,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
@@ -270,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
@@ -277,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;
@@ -540,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);

View File

@@ -1,6 +1,6 @@
/* A tar (tape archiver) program.
Copyright 1988-2021 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
Written by John Gilmore, starting 1985-08-25.
@@ -47,6 +47,7 @@
#include <wordsplit.h>
#include <sysexits.h>
#include <quotearg.h>
#include <verify.h>
#include <version-etc.h>
#include <xstrtol.h>
#include <stdopen.h>
@@ -392,36 +393,36 @@ enum
{
GRH_COMMAND,
GRID_COMMAND, /* Main operation mode */
GRH_MODIFIER,
GRID_MODIFIER, /* Operation modifiers */
GRID_FILE_NAME,
GRH_OVERWRITE,
GRID_OVERWRITE, /* Overwrite control options */
GRH_OUTPUT,
GRID_OUTPUT, /* Output stream selection */
GRH_FATTR,
GRID_FATTR, /* File attributes (ownership and mode) */
GRH_XATTR,
GRID_XATTR, /* Extended file attributes */
GRH_DEVICE,
GRID_DEVICE, /* Device selection */
GRH_BLOCKING,
GRID_BLOCKING, /* Block and record length */
GRH_FORMAT,
GRID_FORMAT, /* Archive format options */
GRDOC_FORMAT,
GRID_FORMAT_OPT,
GRH_COMPRESS,
GRID_COMPRESS, /* Compression options */
@@ -845,10 +846,25 @@ static enum atime_preserve const atime_preserve_types[] =
ARGMATCH_VERIFY (atime_preserve_args, atime_preserve_types);
static char * ATTRIBUTE_FORMAT ((printf, 1, 2))
easprintf (char const *format, ...)
{
va_list args;
va_start (args, format);
char *result = xvasprintf (format, args);
int err = errno;
va_end (args);
if (!result)
FATAL_ERROR ((0, err, "vasprintf"));
return result;
}
static char *
format_default_settings (void)
{
return xasprintf (
return easprintf (
"--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s"
#ifdef REMOTE_SHELL
" --rsh-command=%s"
@@ -889,7 +905,7 @@ enum option_class
};
/* Table of locations of potentially conflicting options. Two options can
conflict only if they procede from the command line. Otherwise, options
conflict only if they proceed from the command line. Otherwise, options
in command line silently override those defined in TAR_OPTIONS. */
static struct option_locus *option_class[OC_MAX];
@@ -944,6 +960,7 @@ option_set_in_cl (int id)
static int
optloc_eq (struct option_locus *a, struct option_locus *b)
{
assume (a); /* Pacify GCC bug 106436. */
if (a->source != b->source)
return 0;
if (a->source == OPTS_COMMAND_LINE)
@@ -1118,7 +1135,7 @@ report_textual_dates (struct tar_args *args)
static char *
tar_help_filter (int key, const char *text, void *input)
tar_help_filter (int key, const char *text, MAYBE_UNUSED void *input)
{
struct obstack stk;
char *s;
@@ -1130,35 +1147,35 @@ tar_help_filter (int key, const char *text, void *input)
break;
case 'j':
s = xasprintf (_("filter the archive through %s"), BZIP2_PROGRAM);
s = easprintf (_("filter the archive through %s"), BZIP2_PROGRAM);
break;
case 'z':
s = xasprintf (_("filter the archive through %s"), GZIP_PROGRAM);
s = easprintf (_("filter the archive through %s"), GZIP_PROGRAM);
break;
case 'Z':
s = xasprintf (_("filter the archive through %s"), COMPRESS_PROGRAM);
s = easprintf (_("filter the archive through %s"), COMPRESS_PROGRAM);
break;
case LZIP_OPTION:
s = xasprintf (_("filter the archive through %s"), LZIP_PROGRAM);
s = easprintf (_("filter the archive through %s"), LZIP_PROGRAM);
break;
case LZMA_OPTION:
s = xasprintf (_("filter the archive through %s"), LZMA_PROGRAM);
s = easprintf (_("filter the archive through %s"), LZMA_PROGRAM);
break;
case LZOP_OPTION:
s = xasprintf (_("filter the archive through %s"), LZOP_PROGRAM);
s = easprintf (_("filter the archive through %s"), LZOP_PROGRAM);
break;
case 'J':
s = xasprintf (_("filter the archive through %s"), XZ_PROGRAM);
s = easprintf (_("filter the archive through %s"), XZ_PROGRAM);
break;
case ZSTD_OPTION:
s = xasprintf (_("filter the archive through %s"), ZSTD_PROGRAM);
s = easprintf (_("filter the archive through %s"), ZSTD_PROGRAM);
break;
case ARGP_KEY_HELP_EXTRA:
@@ -1354,12 +1371,12 @@ parse_opt (int key, char *arg, struct argp_state *state)
if (state->root_argp->children)
{
int i;
for (i = 0; state->root_argp->children[i].argp; i++)
state->child_inputs[i] = state->input;
}
break;
case ARGP_KEY_ARG:
/* File name or non-parsed option, because of ARGP_IN_ORDER */
name_add_name (arg);
@@ -1751,7 +1768,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
case WARNING_OPTION:
set_warning_option (arg);
break;
case 'x':
set_subcommand_option (EXTRACT_SUBCOMMAND);
break;
@@ -2231,7 +2248,7 @@ parse_default_options (struct tar_args *args)
struct wordsplit ws;
struct option_locus loc = { OPTS_ENVIRON, "TAR_OPTIONS", 0, 0 };
struct option_locus *save_loc_ptr;
if (!opts)
return;
@@ -2248,11 +2265,11 @@ parse_default_options (struct tar_args *args)
if (argp_parse (&argp,
ws.ws_offs + ws.ws_wordc,
ws.ws_wordv,
ARGP_IN_ORDER|ARGP_NO_EXIT, &idx, &args))
ARGP_IN_ORDER|ARGP_NO_EXIT, &idx, args))
abort (); /* shouldn't happen */
args->loc = save_loc_ptr;
if (name_more_files ())
USAGE_ERROR ((0, 0, _("non-option arguments in %s"), loc.name));
USAGE_ERROR ((0, 0, _("non-option arguments in %s"), loc.name));
/* Don't free consumed words */
ws.ws_wordc = 0;
}
@@ -2632,7 +2649,7 @@ decode_options (int argc, char **argv)
if (optloc_eq (preserve_order_loc, listed_incremental_loc))
option_conflict_error ("--preserve-order", "--listed-incremental");
else if (preserve_order_loc->source == OPTS_COMMAND_LINE)
listed_incremental_option = false;
listed_incremental_option = NULL;
else
same_order_option = false;
}
@@ -2697,7 +2714,7 @@ decode_options (int argc, char **argv)
if (backup_option)
{
backup_type = xget_version ("--backup", args.version_control_string);
/* No backup is needed either if explicitely disabled or if
/* No backup is needed either if explicitly disabled or if
the extracted files are not being written to disk. */
if (backup_type == no_backups || EXTRACT_OVER_PIPE)
backup_option = false;
@@ -2751,8 +2768,11 @@ main (int argc, char **argv)
set_quoting_style (0, DEFAULT_QUOTING_STYLE);
close_stdout_set_file_name (_("stdout"));
/* Make sure we have first three descriptors available */
stdopen ();
if (stdopen ())
FATAL_ERROR ((0, 0, "%s",
_("failed to assert availability of the standard file descriptors")));
/* Pre-allocate a few structures. */
@@ -2832,11 +2852,14 @@ main (int argc, char **argv)
if (volno_file_option)
closeout_volume_number ();
/* Dispose of allocated memory, and return. */
free (archive_name_array);
xattrs_clear_setup ();
name_term ();
/* There is little point to freeing, as we are about to exit,
and freeing is more likely to cause than cure trouble. */
if (false)
{
free (archive_name_array);
xattrs_clear_setup ();
name_term ();
}
if (exit_status == TAREXIT_FAILURE)
error (0, 0, _("Exiting with failure status due to previous errors"));
@@ -2880,7 +2903,7 @@ void
tar_stat_destroy (struct tar_stat_info *st)
{
tar_stat_close (st);
xheader_xattr_free (st->xattr_map, st->xattr_map_size);
xattr_map_free (&st->xattr_map);
free (st->orig_file_name);
free (st->file_name);
free (st->link_name);

View File

@@ -1,6 +1,6 @@
/* GNU tar Archive Format description.
Copyright 1988-2021 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -284,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 */
@@ -334,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,5 +1,5 @@
/* This file is part of GNU tar.
Copyright 2006-2021 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
@@ -493,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)
{
@@ -504,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)

View File

@@ -1,6 +1,6 @@
/* Unlink files.
Copyright 2009-2021 Free Software Foundation, Inc.
Copyright 2009-2023 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -1,6 +1,6 @@
/* Update a tar archive.
Copyright 1988-2021 Free Software Foundation, Inc.
Copyright 1988-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -42,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)
{
@@ -56,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. */
@@ -110,6 +110,7 @@ update_archive (void)
name_gather ();
open_archive (ACCESS_UPDATE);
acting_as_filter = strcmp (archive_name_array[0], "-") == 0;
xheader_forbid_global ();
while (!found_end)
@@ -135,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;
@@ -144,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),
@@ -156,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,6 +1,6 @@
/* Charset handling for GNU tar.
Copyright 2004-2021 Free Software Foundation, Inc.
Copyright 2004-2023 Free Software Foundation, Inc.
This file is part of GNU tar.

View File

@@ -1,6 +1,6 @@
/* Warnings for GNU tar.
Copyright 2009-2021 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-2021 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);
}
@@ -271,21 +351,35 @@ xattrs_acls_cleanup (char *val, size_t *plen)
}
static void
xattrs__acls_get_a (int parentfd, const char *file_name,
struct tar_stat_info *st,
char **ret_ptr, size_t * ret_len)
acls_get_text (int parentfd, const char *file_name, acl_type_t type,
char **ret_ptr, size_t * ret_len)
{
char *val = NULL;
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, NULL);
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)
@@ -299,34 +393,19 @@ xattrs__acls_get_a (int parentfd, const char *file_name,
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;
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, NULL);
acl_free (acl);
if (!val)
{
call_arg_warn ("acl_to_text", file_name);
return;
}
*ret_ptr = xstrdup (val);
xattrs_acls_cleanup (*ret_ptr, ret_len);
acl_free (val);
acls_get_text (parentfd, file_name, ACL_TYPE_DEFAULT, ret_ptr, ret_len);
}
#endif /* HAVE_POSIX_ACLS */
@@ -369,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)
{
@@ -388,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
}
@@ -410,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
}
}
@@ -533,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)
@@ -650,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;
@@ -662,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
@@ -678,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
@@ -702,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
}
@@ -728,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 = '*';
@@ -768,16 +844,16 @@ xattrs_print (struct tar_stat_info const *st)
}
/* 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-2021 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,6 +1,6 @@
/* POSIX extended headers for tar.
Copyright (C) 2003-2021 Free Software Foundation, Inc.
Copyright (C) 2003-2023 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -29,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,
@@ -158,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));
@@ -186,7 +185,7 @@ xheader_set_keyword_equal (char *kw, char *eq)
if (eq == kw)
USAGE_ERROR ((0, 0, _("Malformed pax option: %s"), quote (kw)));
if (eq[-1] == ':')
{
p--;
@@ -306,7 +305,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
nptr = umaxtostr (n, nbuf);
len += nbuf + sizeof nbuf - 1 - nptr;
break;
default:
len += 2;
}
@@ -493,48 +492,6 @@ xheader_forbid_global (void)
USAGE_ERROR ((0, 0, _("can't update global extended header record")));
}
void
xheader_xattr_init (struct tar_stat_info *st)
{
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;
}
/* This is reversal function for xattr_encode_keyword. See comment for
xattr_encode_keyword() for more info. */
static void
@@ -572,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 */
@@ -638,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
@@ -709,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;
}
@@ -804,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);
@@ -920,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);
}
@@ -1140,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;
@@ -1196,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);
}
@@ -1222,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))
@@ -1231,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);
@@ -1241,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),
@@ -1251,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);
}
@@ -1292,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))
@@ -1311,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))
@@ -1320,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);
}
@@ -1328,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);
@@ -1346,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);
@@ -1356,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);
}
@@ -1365,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))
@@ -1374,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);
@@ -1384,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),
@@ -1394,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);
}
@@ -1419,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))
@@ -1432,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);
}
@@ -1441,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))
@@ -1464,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))
@@ -1489,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))
@@ -1506,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;
@@ -1580,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));
@@ -1588,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)
{
@@ -1597,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;
@@ -1621,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))
@@ -1632,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;
@@ -1640,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))
@@ -1650,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;
@@ -1689,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;
@@ -1706,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);
}
@@ -1743,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))
@@ -1752,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);
}
@@ -1761,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))

View File

@@ -1,6 +1,6 @@
# Makefile for GNU tar regression tests.
# Copyright 1996-2021 Free Software Foundation, Inc.
# Copyright 1996-2023 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -81,6 +81,7 @@ TESTSUITE_AT = \
delete03.at\
delete04.at\
delete05.at\
delete06.at\
difflink.at\
exclude.at\
exclude01.at\
@@ -122,6 +123,8 @@ TESTSUITE_AT = \
extrac21.at\
extrac22.at\
extrac23.at\
extrac24.at\
extrac25.at\
filerem01.at\
filerem02.at\
dirrem01.at\
@@ -251,6 +254,7 @@ TESTSUITE_AT = \
update01.at\
update02.at\
update03.at\
update04.at\
volsize.at\
volume.at\
verbose.at\
@@ -273,6 +277,7 @@ TESTSUITE_AT = \
xattr05.at\
xattr06.at\
xattr07.at\
xattr08.at\
acls01.at\
acls02.at\
acls03.at\
@@ -326,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-2021 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-2021 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-2021 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 2006-2021 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-2021 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-2021 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-2021 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 2006-2021 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-2021 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-2021 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-2021 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-2021 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 2011-2021 Free Software Foundation, Inc.
# Copyright 2011-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 2011-2021 Free Software Foundation, Inc.
# Copyright 2011-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-2021 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 2016-2021 Free Software Foundation, Inc.
# Copyright 2016-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 2004-2021 Free Software Foundation, Inc.
# Copyright 2004-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