tools: tar: update to 1.35
Instead of backporting select 1.35 fixes to make tar work for us, lets update to 1.35 now that we have identified the upstream fix for macOS. Signed-off-by: Robert Marko <robimarko@gmail.com> Link: https://github.com/openwrt/openwrt/pull/15743 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
parent
157c7bd50c
commit
fcdc7da31c
|
@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk
|
|||
|
||||
PKG_NAME:=tar
|
||||
PKG_CPE_ID:=cpe:/a:gnu:tar
|
||||
PKG_VERSION:=1.34
|
||||
PKG_VERSION:=1.35
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=@GNU/tar
|
||||
PKG_HASH:=03d908cf5768cfe6b7ad588c921c6ed21acabfb2b79b788d1330453507647aed
|
||||
PKG_HASH:=14d55e32063ea9526e057fbf35fcabd53378e769787eff7919c3755b02d2b57e
|
||||
|
||||
HOST_BUILD_PARALLEL:=1
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
From 6bec1e7e7fe0ae5bbeb66fc9f32b0b1dd156957d Mon Sep 17 00:00:00 2001
|
||||
From: Sergey Poznyakoff <gray@gnu.org>
|
||||
Date: Tue, 18 Jun 2024 14:31:17 +0200
|
||||
Subject: [PATCH] Fix savannah bug #64441
|
||||
|
||||
* src/Makefile.am (tar_LDADD): Add libiconv libraries.
|
||||
|
||||
Adapted upstream commit 8632df398b2f548465ebe68b8f494c0d6f8d913d to patch
|
||||
the pregenerated Makefile.in instead of Makefile.am to avoid invoking
|
||||
automake which requires m4.
|
||||
|
||||
This is required for macOS, as otherwise it will fail with:
|
||||
Undefined symbols for architecture arm64:
|
||||
"_iconv", referenced from:
|
||||
_utf8_convert in utf8.o
|
||||
"_iconv_open", referenced from:
|
||||
_utf8_convert in utf8.o
|
||||
ld: symbol(s) not found for architecture arm64
|
||||
clang: error: linker command failed with exit code 1 (use -v to see invocation)
|
||||
---
|
||||
src/Makefile.in | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/Makefile.in
|
||||
+++ b/src/Makefile.in
|
||||
@@ -1793,7 +1793,8 @@ AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLA
|
||||
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)
|
||||
+ $(LIB_SELINUX) $(LIB_SETLOCALE_NULL) \
|
||||
+ $(LIBINTL) $(LIBICONV)
|
||||
|
||||
all: all-am
|
||||
|
|
@ -1,491 +0,0 @@
|
|||
From 66be5a789e70f911170017754fc51e499998f90e Mon Sep 17 00:00:00 2001
|
||||
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Sun, 14 Aug 2022 16:32:26 -0700
|
||||
Subject: [PATCH] Avoid excess lseek etc.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
* 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.
|
||||
---
|
||||
src/buffer.c | 99 ++++++++++++++++++---------------------------------
|
||||
src/common.h | 10 +++---
|
||||
src/compare.c | 31 ++++------------
|
||||
src/delete.c | 51 +++++++++-----------------
|
||||
src/system.c | 81 +++++++++++++++++++++++++++--------------
|
||||
5 files changed, 119 insertions(+), 153 deletions(-)
|
||||
|
||||
--- a/src/buffer.c
|
||||
+++ b/src/buffer.c
|
||||
@@ -20,7 +20,6 @@
|
||||
Written by John Gilmore, on 1985-08-25. */
|
||||
|
||||
#include <system.h>
|
||||
-#include <system-ioctl.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
@@ -420,37 +419,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 +670,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 +793,13 @@ _open_archive (enum access_mode wanted_a
|
||||
{
|
||||
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 +827,7 @@ _open_archive (enum access_mode wanted_a
|
||||
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)
|
||||
{
|
||||
@@ -1048,18 +1030,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);
|
||||
@@ -1372,7 +1344,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 +1368,7 @@ new_volume (enum access_mode mode)
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
- SET_BINARY_MODE (archive);
|
||||
+ get_archive_status (mode, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
--- a/src/common.h
|
||||
+++ b/src/common.h
|
||||
@@ -397,9 +397,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 +406,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;
|
||||
@@ -894,7 +896,6 @@ void xheader_xattr_add (struct tar_stat_
|
||||
/* 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,6 +913,7 @@ int sys_exec_info_script (const char **a
|
||||
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, ...)
|
||||
--- a/src/compare.c
|
||||
+++ b/src/compare.c
|
||||
@@ -566,31 +566,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;
|
||||
--- a/src/delete.c
|
||||
+++ b/src/delete.c
|
||||
@@ -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,25 @@ 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 (mtioseek (false, count))
|
||||
+ return;
|
||||
|
||||
- if (errno == EIO
|
||||
- && 0 <= rmtioctl (archive, MTIOCTOP, (char *) &operation))
|
||||
+ off_t position0 = rmtlseek (archive, 0, SEEK_CUR), position = 0;
|
||||
+ if (0 <= position0)
|
||||
+ {
|
||||
+ off_t increment;
|
||||
+ if (INT_MULTIPLY_WRAPV (record_size, count, &increment)
|
||||
+ || INT_ADD_WRAPV (position0, increment, &position)
|
||||
+ || position < 0)
|
||||
+ {
|
||||
+ ERROR ((0, EOVERFLOW, "lseek: %s", archive_name_array[0]));
|
||||
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);
|
||||
-
|
||||
- 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,
|
||||
--- a/src/system.c
|
||||
+++ b/src/system.c
|
||||
@@ -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
|
||||
@@ -52,11 +82,6 @@ sys_file_is_archive (struct tar_stat_inf
|
||||
}
|
||||
|
||||
void
|
||||
-sys_save_archive_dev_ino (void)
|
||||
-{
|
||||
-}
|
||||
-
|
||||
-void
|
||||
sys_detect_dev_null_output (void)
|
||||
{
|
||||
static char const dev_null[] = "nul";
|
||||
@@ -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
|
|
@ -1,59 +0,0 @@
|
|||
From f8e14746d2ca72804a4520c059d7bf65ca00c5ac Mon Sep 17 00:00:00 2001
|
||||
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Fri, 2 Sep 2022 16:32:27 -0500
|
||||
Subject: [PATCH] Fix --delete bug with short reads
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
* gnulib.modules: Add idx.
|
||||
* src/common.h: Include idx.h.
|
||||
* src/delete.c (move_archive): Don’t botch short reads.
|
||||
---
|
||||
gnulib.modules | 1 +
|
||||
src/common.h | 1 +
|
||||
src/delete.c | 10 ++++++++--
|
||||
3 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
# diff --git a/gnulib.modules b/gnulib.modules
|
||||
# index 63e8354a..dac77d61 100644
|
||||
# --- a/gnulib.modules
|
||||
# +++ b/gnulib.modules
|
||||
# @@ -54,6 +54,7 @@ gettime
|
||||
# gitlog-to-changelog
|
||||
# hash
|
||||
# human
|
||||
# +idx
|
||||
# inttostr
|
||||
# inttypes
|
||||
# lchown
|
||||
--- a/src/common.h
|
||||
+++ b/src/common.h
|
||||
@@ -58,6 +58,7 @@
|
||||
#include <backupfile.h>
|
||||
#include <exclude.h>
|
||||
#include <full-write.h>
|
||||
+#include <idx.h>
|
||||
#include <modechange.h>
|
||||
#include <quote.h>
|
||||
#include <safe-read.h>
|
||||
--- a/src/delete.c
|
||||
+++ b/src/delete.c
|
||||
@@ -55,9 +55,15 @@ move_archive (off_t count)
|
||||
off_t position0 = rmtlseek (archive, 0, SEEK_CUR), position = 0;
|
||||
if (0 <= position0)
|
||||
{
|
||||
- off_t increment;
|
||||
+ /* 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, increment, &position)
|
||||
+ || 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]));
|
|
@ -1,189 +0,0 @@
|
|||
From 4053ba7cfb5255c0e6832781aebc909666b2e984 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Sat, 27 Feb 2021 14:39:06 -0800
|
||||
Subject: [PATCH] Pacify rtapelib.c for GCC 10 and fix a bug or two
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch assumes C99, but that’s OK nowadays.
|
||||
* lib/rtapelib.c: Include verify.h.
|
||||
(rmt_open__): Tell GCC that remote_file must be nonnull.
|
||||
(rmt_read__, rmt_write__, rmt_lseek__, rmt_ioctl__):
|
||||
Properly size outgoing command buffers instead of guessing 64.
|
||||
Simplify by using C99 printf formats like %zu,
|
||||
as that’s a safe assumption nowadays.
|
||||
(rmt_ioctl__): 3rd arg is now void * not char *, to pacify gcc
|
||||
-Wcast-align. Fix unlikely bug with short reads: ARGUMENT was
|
||||
being incremented, whereas later code wanted the original
|
||||
ARGUMENT.
|
||||
* paxlib.modules: Add ‘verify’.
|
||||
---
|
||||
lib/rmt.h | 2 +-
|
||||
lib/rtapelib.c | 64 ++++++++++++++++++++------------------------------
|
||||
paxlib.modules | 1 +
|
||||
3 files changed, 28 insertions(+), 39 deletions(-)
|
||||
|
||||
--- a/lib/rmt.h
|
||||
+++ b/lib/rmt.h
|
||||
@@ -25,7 +25,7 @@ int rmt_close__ (int);
|
||||
size_t rmt_read__ (int, char *, size_t);
|
||||
size_t rmt_write__ (int, char *, size_t);
|
||||
off_t rmt_lseek__ (int, off_t, int);
|
||||
-int rmt_ioctl__ (int, int, char *);
|
||||
+int rmt_ioctl__ (int, int, void *);
|
||||
|
||||
extern bool force_local_option;
|
||||
|
||||
--- a/lib/rtapelib.c
|
||||
+++ b/lib/rtapelib.c
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <safe-read.h>
|
||||
#include <full-write.h>
|
||||
+#include <verify.h>
|
||||
|
||||
/* Try hard to get EOPNOTSUPP defined. 486/ISC has it in net/errno.h,
|
||||
3B2/SVR3 has it in sys/inet.h. Otherwise, like on MSDOS, use EINVAL. */
|
||||
@@ -424,6 +425,8 @@ rmt_open__ (const char *file_name, int o
|
||||
}
|
||||
}
|
||||
|
||||
+ assume (remote_file);
|
||||
+
|
||||
/* FIXME: Should somewhat validate the decoding, here. */
|
||||
if (gethostbyname (remote_host) == NULL)
|
||||
error (EXIT_ON_EXEC_ERROR, 0, _("Cannot connect to %s: resolve failed"),
|
||||
@@ -567,12 +570,12 @@ rmt_close__ (int handle)
|
||||
size_t
|
||||
rmt_read__ (int handle, char *buffer, size_t length)
|
||||
{
|
||||
- char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
+ char command_buffer[sizeof "R\n" + INT_STRLEN_BOUND (size_t)];
|
||||
size_t status;
|
||||
size_t rlen;
|
||||
size_t counter;
|
||||
|
||||
- sprintf (command_buffer, "R%lu\n", (unsigned long) length);
|
||||
+ sprintf (command_buffer, "R%zu\n", length);
|
||||
if (do_command (handle, command_buffer) == -1
|
||||
|| (status = get_status (handle)) == SAFE_READ_ERROR
|
||||
|| status > length)
|
||||
@@ -596,11 +599,11 @@ rmt_read__ (int handle, char *buffer, si
|
||||
size_t
|
||||
rmt_write__ (int handle, char *buffer, size_t length)
|
||||
{
|
||||
- char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
+ char command_buffer[sizeof "W\n" + INT_STRLEN_BOUND (size_t)];
|
||||
RETSIGTYPE (*pipe_handler) (int);
|
||||
size_t written;
|
||||
|
||||
- sprintf (command_buffer, "W%lu\n", (unsigned long) length);
|
||||
+ sprintf (command_buffer, "W%zu\n", length);
|
||||
if (do_command (handle, command_buffer) == -1)
|
||||
return 0;
|
||||
|
||||
@@ -628,17 +631,7 @@ rmt_write__ (int handle, char *buffer, s
|
||||
off_t
|
||||
rmt_lseek__ (int handle, off_t offset, int whence)
|
||||
{
|
||||
- char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
- char operand_buffer[UINTMAX_STRSIZE_BOUND];
|
||||
- uintmax_t u = offset < 0 ? - (uintmax_t) offset : (uintmax_t) offset;
|
||||
- char *p = operand_buffer + sizeof operand_buffer;
|
||||
-
|
||||
- *--p = 0;
|
||||
- do
|
||||
- *--p = '0' + (int) (u % 10);
|
||||
- while ((u /= 10) != 0);
|
||||
- if (offset < 0)
|
||||
- *--p = '-';
|
||||
+ char command_buffer[sizeof "L\n0\n" + INT_STRLEN_BOUND (+offset)];
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
@@ -648,7 +641,8 @@ rmt_lseek__ (int handle, off_t offset, i
|
||||
default: abort ();
|
||||
}
|
||||
|
||||
- sprintf (command_buffer, "L%s\n%d\n", p, whence);
|
||||
+ intmax_t off = offset;
|
||||
+ sprintf (command_buffer, "L%jd\n%d\n", off, whence);
|
||||
|
||||
if (do_command (handle, command_buffer) == -1)
|
||||
return -1;
|
||||
@@ -659,7 +653,7 @@ rmt_lseek__ (int handle, off_t offset, i
|
||||
/* Perform a raw tape operation on remote tape connection HANDLE.
|
||||
Return the results of the ioctl, or -1 on error. */
|
||||
int
|
||||
-rmt_ioctl__ (int handle, int operation, char *argument)
|
||||
+rmt_ioctl__ (int handle, int operation, void *argument)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
@@ -670,24 +664,16 @@ rmt_ioctl__ (int handle, int operation,
|
||||
#ifdef MTIOCTOP
|
||||
case MTIOCTOP:
|
||||
{
|
||||
- char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
- char operand_buffer[UINTMAX_STRSIZE_BOUND];
|
||||
- uintmax_t u = (((struct mtop *) argument)->mt_count < 0
|
||||
- ? - (uintmax_t) ((struct mtop *) argument)->mt_count
|
||||
- : (uintmax_t) ((struct mtop *) argument)->mt_count);
|
||||
- char *p = operand_buffer + sizeof operand_buffer;
|
||||
-
|
||||
- *--p = 0;
|
||||
- do
|
||||
- *--p = '0' + (int) (u % 10);
|
||||
- while ((u /= 10) != 0);
|
||||
- if (((struct mtop *) argument)->mt_count < 0)
|
||||
- *--p = '-';
|
||||
+ struct mtop *mtop = argument;
|
||||
+ enum { oplen = INT_STRLEN_BOUND (+mtop->mt_op) };
|
||||
+ enum { countlen = INT_STRLEN_BOUND (+mtop->mt_count) };
|
||||
+ char command_buffer[sizeof "I\n\n" + oplen + countlen];
|
||||
|
||||
/* MTIOCTOP is the easy one. Nothing is transferred in binary. */
|
||||
|
||||
- sprintf (command_buffer, "I%d\n%s\n",
|
||||
- ((struct mtop *) argument)->mt_op, p);
|
||||
+ verify (EXPR_SIGNED (mtop->mt_count));
|
||||
+ intmax_t count = mtop->mt_count;
|
||||
+ sprintf (command_buffer, "I%d\n%jd\n", mtop->mt_op, count);
|
||||
if (do_command (handle, command_buffer) == -1)
|
||||
return -1;
|
||||
|
||||
@@ -717,9 +703,9 @@ rmt_ioctl__ (int handle, int operation,
|
||||
return -1;
|
||||
}
|
||||
|
||||
- for (; status > 0; status -= counter, argument += counter)
|
||||
+ for (char *p = argument; status > 0; status -= counter, p += counter)
|
||||
{
|
||||
- counter = safe_read (READ_SIDE (handle), argument, status);
|
||||
+ counter = safe_read (READ_SIDE (handle), p, status);
|
||||
if (counter == SAFE_READ_ERROR || counter == 0)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
@@ -732,15 +718,17 @@ rmt_ioctl__ (int handle, int operation,
|
||||
than 256, we will assume that the bytes are swapped and go through
|
||||
and reverse all the bytes. */
|
||||
|
||||
- if (((struct mtget *) argument)->MTIO_CHECK_FIELD < 256)
|
||||
+ struct mtget *mtget = argument;
|
||||
+ if (mtget->MTIO_CHECK_FIELD < 256)
|
||||
return 0;
|
||||
|
||||
+ char *buf = argument;
|
||||
for (counter = 0; counter < status; counter += 2)
|
||||
{
|
||||
- char copy = argument[counter];
|
||||
+ char copy = buf[counter];
|
||||
|
||||
- argument[counter] = argument[counter + 1];
|
||||
- argument[counter + 1] = copy;
|
||||
+ buf[counter] = buf[counter + 1];
|
||||
+ buf[counter + 1] = copy;
|
||||
}
|
||||
|
||||
return 0;
|
|
@ -5,7 +5,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||
---
|
||||
--- a/src/create.c
|
||||
+++ b/src/create.c
|
||||
@@ -543,17 +543,8 @@ write_gnu_long_link (struct tar_stat_inf
|
||||
@@ -544,17 +544,8 @@ write_gnu_long_link (struct tar_stat_inf
|
||||
union block *header;
|
||||
|
||||
header = start_private_header ("././@LongLink", size, 0);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/src/create.c
|
||||
+++ b/src/create.c
|
||||
@@ -1844,6 +1844,7 @@ dump_file0 (struct tar_stat_info *st, ch
|
||||
@@ -1855,6 +1855,7 @@ dump_file0 (struct tar_stat_info *st, ch
|
||||
#ifdef HAVE_READLINK
|
||||
else if (S_ISLNK (st->stat.st_mode))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue