Commit Graph

219 Commits

Author SHA1 Message Date
Paul Eggert
4e742fc867 --no-overwrite-dir no overwrite even temporarily
Problem and fix reported by Pavel Cahyna in
https://lists.gnu.org/r/bug-tar/2025-01/msg00000.html
* src/extract.c (extract_dir): With --no-overwrite-dir,
skip the chmod if the directory already exists.
* tests/extrac23.at (--no-overwrite-dir on empty directory):
Move the part of the test that looks at a nonempty directory ...
* tests/extrac30.at: ... to this new file, because the test now
must be run as non-root.  Adjust the test to match the new behavior.
* tests/Makefile.am (TESTSUITE_AT), tests/testsuite.at: Add it.
2025-07-26 21:49:20 -07:00
Paul Eggert
75735940f1 Port more code to UBSan, and fix alignment bug
Problem with extract_file reported by Kirill Furman in:
https://lists.gnu.org/r/bug-tar/2025-07/msg00003.html
Since the UBSan thing seems to be a recurring issue,
I fixed other instances of the problem that I found.
Also, I noticed that the same line of code had another failure to
conform to C23’s rules for pointers (an alignment issue not caught
by UBSan), so I fixed that too.  None of these issues matter on
practical production hosts.
* src/common.h (charptr): New function.
* src/buffer.c (available_space_after, short_read, flush_archive)
(backspace_output, try_new_volume, simple_flush_read)
(_gnu_flush_read, _gnu_flush_write):
* src/compare.c (read_and_process):
* src/create.c (write_eot, write_gnu_long_link)
(dump_regular_file, dump_dir0):
* src/extract.c (extract_file):
* src/incremen.c (get_gnu_dumpdir):
* src/list.c (read_header):
* src/sparse.c (sparse_dump_region, sparse_extract_region):
* src/system.c (sys_write_archive_buffer)
(sys_child_open_for_compress, sys_child_open_for_uncompress):
* src/update.c (append_file, update_archive):
Use it.
* src/buffer.c (set_next_block_after): Arg is now void *,
not union block *, since it need not be a valid union block * pointer
and this can matter on unusual or debugging implementations.
Turn a loop into an if so that the code is O(1) not O(N).
2025-07-26 02:20:53 -07:00
Anssi Hannula
827dde1605 Fix missing type in mknodat() mode argument
Per POSIX, the type of the file to be created should be OR'ed to the
`mode` argument of mknodat().

However, set_xattr() creates an empty file using mknodat() and does not
do that.

E.g. Linux kernel considers zero type as S_IFREG, so the code works on
most systems.

However, e.g. fakeroot, at least up to the current v1.36, does not
consider 0 as S_IFREG, instead creating an invalid file, causing tar to
enter an infinite retry loop when trying to create a file with xattrs
under fakeroot.

Since set_xattr is used only when extracting regular files, fix that
by ORing its mode argument with S_IFREG.

Copyright-paperwork-exempt: Yes
2025-05-12 13:18:21 +03:00
Sergey Poznyakoff
807e340ab2 Minor fix
* src/extract.c (set_mode): Re-stat the file if current_mode_mask
bits tell so.
2025-05-06 22:29:29 +03:00
Sergey Poznyakoff
cd1f6624f7 Fix restoring permissions of intermediate directories with --skip-old-files
Detailed bug report: https://savannah.gnu.org/bugs/index.php?66774

* src/extract.c (update_interdir_set_stat): New function.
(extract_dir): If the directory already exists, check if it
has been created as intermediate directory earlier.  If so,
update its delayed_set_stat data from archive.

* tests/Makefile.am: Add new testcase.
* tests/testsuite.at: Add new testcase.
* tests/extrac28.at: New file.
2025-03-14 15:07:27 +02:00
Paul Eggert
0aa991f386 Update copyright years
UPDATE_COPYRIGHT_USE_INTERVALS=1 \
$HOME/src/gnu/gnulib/build-aux/update-copyright \
  $(git ls-files | sed -e '/^gnulib$/d
			   /^paxutils$/d
			   /^COPYING$/d
			   /\/fdl.texi$/d')
sed -i '2000,${
    /^Copyright @copyright/d
    s/^[0-9]*--\(2025 Free Software Foundation, Inc.\)/Copyright (C) \1/
  }' doc/tar.texi
2025-01-01 18:33:10 -08:00
Paul Eggert
04b4f491a8 Prefer other types to int in xattrs.c
* src/xattrs.c (xattrs__acls_set) [HAVE_POSIX_ACLS]:
Prefer acl_type_t to int for ACL types.
(acls_get_text, xattrs_acls_get, xattrs_acls_set)
(xattrs_xattrs_get, xattrs_selinux_get, xattrs_selinux_set)
(xattrs_xattrs_set): Prefer bool for booleans.
2024-11-01 23:47:23 -07:00
Paul Eggert
112ead7931 Prefer other types to int in extract.c
* src/extract.c (fd_chmod, extract_chdir, open_output_file)
(extract_file, extract_link, extract_symlink, extract_node)
(extract_fifo, tar_extractor_t, pepare_to_extract): Prefer char to
int for typeflag, since it’s a char.  All uses changed.
(fd_chmod): Use clearer code for errno.
(extract_dir, extract_file, create_placeholder_file, extract_link)
(extract_symlink, extract_node, extract_fifo, tar_extractor_t):
Return bool true for success, false for failure.  All uses changed.
(open_output_file): Prefer bool for boolean.
(prepare_to_extract): Simplify by returning the extractor a null
pointer, rather than storing through a pointer to an extractor.
2024-11-01 23:47:23 -07:00
Paul Eggert
f8a679e942 Be a bit more consistent about comparing to zero
* src/buffer.c (xclose, archive_is_dev, close_archive)
(write_fatal_details, init_volume_number)
(closeout_volume_number, new_volume, try_new_volume):
* src/checkpoint.c (format_checkpoint_string):
* src/compare.c (process_rawdata, diff_file, diff_dumpdir):
* src/create.c (create_archive, restore_parent_fd, dump_file0):
* src/delete.c (delete_archive_members):
* src/exclist.c (cvs_addfn):
* src/extract.c (set_mode, mark_after_links, delay_set_stat)
(repair_delayed_set_stat, make_directories, file_newer_p)
(maybe_recoverable, apply_nonancestor_delayed_set_stat)
(extract_dir, open_output_file, find_delayed_link_source)
(create_placeholder_file, extract_symlink, extract_node)
(extract_fifo, apply_delayed_link):
* src/incremen.c (update_parent_directory, scan_directory)
(read_obstack, read_incr_db_2, write_directory_file)
(try_purge_directory):
* src/map.c (map_read):
* src/misc.c (maybe_backup_file, undo_last_backup, chdir_do)
(tar_savedir):
* src/names.c (handle_file_selection_option, add_file_id)
(handle_option, read_next_name, add_hierarchy_to_namelist)
(collect_and_sort_names):
* src/system.c (run_decompress_program, dec_to_env, time_to_env)
(oct_to_env, str_to_env, chr_to_env, sys_exec_setmtime_script):
* src/tar.c (get_date_or_file, parse_default_options)
(decode_options, main):
* src/unlink.c (flush_deferred_unlinks):
* src/update.c (append_file):
* src/xattrs.c (xattrs__acls_set, xattrs_xattrs_set):
Prefer < 0 when looking at syscalls; prefer != 0 to nothing
when testing an integer in a boolean context.
This is for style, not substance; for example, it’s easier
to read ‘if (wordsplit (...) != WRDSE_OK) ...’ than
‘if (wordsplit (...)) ...’ if you don’t already know that
wordsplit returns an enum rather than bool.
* src/names.c (add_file_id, read_next_name, regex_usage_warning):
* src/transform.c (parse_xform_flags):
Return bool not int, possibly inverting sense so that true means OK.
All callers changed.
* src/tar.c (main): Report errno info if stdopen fails.
2024-11-01 23:47:23 -07:00
Paul Eggert
5a7185ae31 Prefer other types to int in tar.c
Use types that are more specific than ‘int’, if that is easy.
* src/tar.c (after_date_option, xattrs_option, check_links_option)
(confirm, confirm_file_EOF, set_xattr_option, optloc_eq)
(get_date_or_file):
Prefer bool to int.
(tar_list_quoting_styles, tar_set_quoting_style, parse_opt):
Prefer idx_t to int.
(optloc_lookup, option_set_in_cl): Prefer enum option_class to int.
(decode_signal): Avoid some pointer reallocation.
(sort_mode_flag, hole_detection_types, set_old_files_option)
(is_subcommand_class): Prefer enum to int.
(parse_opt) [DEVICE_PREFIX]: Remove unused var.
Simplify creation of device name.
(find_argp_option_key, find_argp_option): Prefer char to int.
(enum subcommand_class): Now named.
(subcommand_class): Now char, not int.
(decode_options): Check for unlikely int overflow.
2024-11-01 23:47:23 -07:00
Paul Eggert
04b92eca49 Fewer uses of size_t in extract.c
* src/extract.c (struct delayed_set_stat, struct delayed_link)
(delay_set_stat, apply_nonancestor_delayed_set_stat)
(extract_file): Prefer idx_t to size_t.
(struct delayed_set_stat): Remove unused member xattr_map_size.
2024-11-01 23:47:23 -07:00
Paul Eggert
79cb9aaab6 Fewer macros in extract.c
* src/extract.c (ALL_MODE_BITS, RECOVER_NO, RECOVER_OK)
(RECOVER_SKIP): Now constants or inline functions, not macros.
(maybe_recoverable): Return enum recover, not int.
2024-08-19 09:57:13 -07:00
Paul Eggert
4323e98683 Fewer macros in common.h
In common.h, replace macros with constants or functions when that
is easy.  This makes code a bit more reliable (functions evaluate
their args exactly once) and easier to debug (many debugging
environments cannot access macros).
* src/common.h (CHKBLANKS): Remove.  All uses removed.
(NAME_FIELD_SIZE, PREFIX_FIELD_SIZE, UNAME_FIELD_SIZE)
(GNAME_FIELD_SIZE, TAREXIT_SUCCESS, TAREXIT_DIFFERS)
(TAREXIT_FAILURE, LG_8, LG_256, DEFAULT_CHECKPOINT)
(MAX_OLD_FILES, TF_READ, TF_WRITE, TF_DELETED, XFORM_REGFILE)
(XFORM_LINK, XFORM_SYMLINK, XFORM_ALL, WARN_ALONE_ZERO_BLOCK)
(WARN_BAD_DUMPDIR, WARN_CACHEDIR, WARN_CONTIGUOUS_CAST)
(WARN_FILE_CHANGED, WARN_FILE_IGNORED, WARN_FILE_REMOVED)
(WARN_FILE_SHRANK, WARN_FILE_UNCHANGED, WARN_FILENAME_WITH_NULS)
(WARN_IGNORE_ARCHIVE, WARN_IGNORE_NEWER, WARN_NEW_DIRECTORY)
(WARN_RENAME_DIRECTORY, WARN_SYMLINK_CAST, WARN_TIMESTAMP)
(WARN_UNKNOWN_CAST, WARN_UNKNOWN_KEYWORD, WARN_XDEV)
(WARN_DECOMPRESS_PROGRAM, WARN_EXISTING_FILE, WARN_XATTR_WRITE)
(WARN_RECORD_SIZE, WARN_FAILED_READ, WARN_MISSING_ZERO_BLOCKS)
(WARN_VERBOSE_WARNINGS, WARN_ALL, EXCL_DEFAULT, EXCL_RECURSIVE)
(EXCL_NON_RECURSIVE): Now enum constants rather than macros.
(time_option_initialized, isfound, wasfound, warning_enabled):
Now functions rather than macros TIME_OPTION_INITIALIZED, ISFOUND,
WASFOUND, WARNING_ENABLED.  All uses changed.
(OLDER_STAT_TIME, OLDER_TAR_STAT_TIME, EXTRACT_OVER_PIPE)
(TAR_ARGS_INITIALIZER): Remove.  All uses replaced with their
definiens or equivalent.
2024-08-19 09:57:13 -07:00
Paul Eggert
0dfcfa4aa4 maint: switch from ERROR to paxerror etc
Prefer functions like ‘paxerror’ to macros like ‘ERROR’.
The functions have cleaner semantics, and calls are
easier to read.
2024-08-19 09:57:13 -07:00
Paul Eggert
b3992e4ef8 Prefer signed types in blocking_read etc
* src/compare.c (process_noop, process_rawdata):
Return bool, not int.
* src/compare.c (process_noop, process_rawdata):
* src/create.c (dump_regular_file):
* src/extract.c (extract_file):
* src/misc.c (blocking_read, blocking_write):
* src/sparse.c (sparse_scan_file_raw, sparse_extract_region):
Prefer signed types like idx_t to unsigned ones like size_t.
(sparse_scan_file_raw): Diagnose read errors.
2024-08-14 23:25:46 -07:00
Paul Eggert
cc691f8272 Support >INT_MAX -C dirs
* src/extract.c (struct delayed_set_stat, struct delayed_link):
* src/misc.c (normalize_filename, wd_count, chdir_count)
(chdir_arg, tar_getcdpath):
* src/names.c (name_gather, addname, add_hierarchy_to_namelist):
* src/unlink.c (struct deferred_unlink, flush_deferred_unlinks):
Use idx_t, not int, for directory indexes, so as to not
limit their number to INT_MAX; this is theoretically possible
if -T is used.
* src/names.c (name_next_elt, name_next):
Use bool for boolean.
2024-08-04 01:41:43 -07:00
Paul Eggert
afd073399a maint: remove GLOBAL as per GCC 14
* src/common.h (GLOBAL): Remove this macro, and all its uses.
It collides with GCC 14 and -Wmissing-variable-declarations.
Change all uses of GLOBAL to use extern instead,
and declare the variables in their respective .c files.
Move .c file’s extern declarations here, so that they
appear only once and are checked against definitions.
* src/names.c (unconsumed_option_tail): Now static.
2024-07-26 23:44:03 -07:00
Paul Eggert
9f1c32c18b Modernize use of Gnulib, paxutils
* configure.ac: Omit stuff no longer needed now that Gnulib or
paxlib does it, or the code no longer needs the configure-time checks.
Do not use AC_SYS_LARGEFILE (Gnulib largefile does this) or check
for fcntl.h, memory.h, net/errno.h, sgtty.h, string.h,
sys/param.h, sys/device.h, sys/gentape.h, sys/inet.h,
sys/io/trioctl.h, sys/time.h, sys/tprintf.h, sys/tape.h, unistd.h,
locale.h, netdb.h; these are all now standard, or old ways of getting
at magtapes are no longer needed and we now have only sys/mtio.h.
Do not check for lstat, readlink, symlink, and check only for
waitpid’s existence rather than attempting to replace it.
Do not check for decls of getgrgid, getpwuid, or time.
Check just once for iconv.h.
* gnulib.modules: Add largefile.
* lib/.gitignore, lib/Makefile.am (noinst_HEADERS, libtar_a_SOURCES):
Remove system-ioctl.h, which is no longer in paxlib.
All includes now changed to just check HAVE_SYS_MTIO_H directly.
* lib/wordsplit.c (wordsplit_c_escape_tab, wordsplit_errstr)
(wordsplit_nerrs):
Now static or an enum, and without any leading "_" in the name.
* src/buffer.c (record_start, record_end, current_block, records_read):
* src/delete.c (records_skipped): Add extern decl to pacify GCC.
* src/compare.c, src/create.c, src/extract.c: Omit uses of
HAVE_READLINK and HAVE_SYMLINK since we now let Gnulib deal with
platforms lacking readlinkat and symlinkat.
* src/system.c: Use "#if !HAVE_WAITPID" instead of "#if MSDOS".
2024-07-26 21:56:20 -07:00
Sergey Poznyakoff
1e6ce98e3a Fix spurious diagnostic during extraction of . with --keep-newer-files
Bug reported in https://savannah.gnu.org/bugs/?65838.

Bug introduced by 79d1ac38c1.

* src/extract.c (make_directories): Restore second argument.  This
reverts the change made in 79d1ac38c1.
(maybe_recoverable, rename_directory): Update calls to make_directories.
* tests/extrac27.at: New file.
* tests/Makefile.am: Add new test.
* tests/testsuite.at: Likewise.
2024-06-05 18:19:10 +03:00
Paul Eggert
c6f0ad5117 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')
sed -i '2000,${
    /^Copyright @copyright/d
    s/^[0-9]*--\(2024 Free Software Foundation, Inc.\)/Copyright (C) \1/
  }' doc/tar.texi
2024-01-01 19:08:46 -08:00
Paul Eggert
12b58a69aa Simplify recently-added hash code
* src/extract.c (delay_set_stat): Simplify hash lookup;
no need to initialize members other than file_name.
Avoid assignment in ‘if’ when it’s easy.
(extract_finish): Do not bother to free when we are about to exit.
2023-08-21 13:42:14 -07:00
Benjamin Woodruff
a5afb36765 Fix O(n^2) time bug in --delay-directory-restore
delayed_set_stat avoids inserting duplicate entries into
delayed_set_stat_head. It was doing this by scanning the entire
list.

Normally this list is small, but if --delay-directory-restore is
used (including automatically for incremental archives), this list
grows with the total number of directories in the archive.

The entire scan takes O(n) time. Extracting an archive with n
directories could therefore take O(n^2) time.

The included test uses AT_SKIP_LARGE_FILES, allowing it to optionally be
skipped. It may execute slowly on certain filesystems or disks, as it
creates thousands of directories.

There are still potentially problematic O(n) scans in
find_direct_ancestor and remove_delayed_set_stat, which this patch does
not attempt to fix.

* NEWS: Update.
* src/extract.c (delayed_set_stat_table): Create a table for O(1)
lookups of entries in the delayed_set_stat_head list. The list
remains, as tracking insertion order is important.
(dl_hash, dl_compare): New hash table helper functions.
(delay_set_stat): Create the hash table, replace the O(n) list scan
with a hash_lookup, insert new entries into the hash table.
(remove_delayed_set_stat): Also remove entry from hash table.
(apply_nonancestor_delayed_set_stat): Also remove entry from hash
table.
(extract_finish): Free the (empty) hash table.
* tests/extrac26.at: New file.
* tests/Makefile.am (TESTSUITE_AT): Include extrac26.at.
* tests/testsuite.at: Include extrac26.at.
2023-08-21 13:42:14 -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
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
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
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
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
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
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
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
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
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
Sergey Poznyakoff
5c713540e3 Update copyright years 2022-01-02 10:25:29 +02: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
Samanta Navarro
3730dddb3f Fix typos
Typos found with codespell
2021-06-01 18:54:07 +03: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
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
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
afa743ac23 Update copyright years 2021-01-06 17:55:16 +02:00
Sergey Poznyakoff
34d15af170 Fix the logic of prepare_to_extract.
* src/extract.c (prepare_to_extract): Return true to proceed with
the extraction, and false to skip the current member.  If extracting
over a pipe, skip unlinking logic.
(extract_archive): Update accordingly.
2020-06-22 22:17:46 +03:00
Sergey Poznyakoff
8d90723d30 Update copyright years 2020-02-08 13:21:13 +02:00
Sergey Poznyakoff
14d8fc718f Fix the --no-overwrite-dir option
Given this option, tar failed to preserve permissions of empty directories
and to create files under directories owned by the current user that did
not have the S_IWUSR bit set.

* src/extract.c (fd_chmod): Rename to fd_i_chmod.
(fd_chmod): New function.
(safe_dir_mode): New function.
(extract_dir): Special handling for existing directories in
--no-overwrite-dir mode.
* tests/extrac23.at: New file.
* tests/Makefile.am: Add new test case.
* tests/testsuite.at: Likewise.
2020-02-08 13:08:20 +02:00