1
0
mirror of https://git.openwrt.org/openwrt/openwrt.git synced 2024-10-18 05:18:14 +02:00

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:
Robert Marko 2024-06-18 13:32:31 +02:00 committed by Christian Marangi
parent 157c7bd50c
commit fcdc7da31c
No known key found for this signature in database
GPG Key ID: AC001D09ADBFEAD7
7 changed files with 39 additions and 743 deletions

@ -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): Dont return true if the archive is /dev/null
since its not a problem in that case.
(sys_detect_dev_null_output): Cache dev_null_stat.
doc: omit MS-DOS mentions in doc
Its really FAT32 were 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): Dont 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 thats 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 thats 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))
{