summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2021-02-27 14:39:06 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2021-02-27 15:32:44 -0800
commit4053ba7cfb5255c0e6832781aebc909666b2e984 (patch)
tree8b511401cfcd1fc3ed18a705d86b45fa5732a312
parent9b8a60cb91d2018813e308442968d4a9879deddb (diff)
downloadpaxutils-4053ba7cfb5255c0e6832781aebc909666b2e984.tar.gz
Pacify rtapelib.c for GCC 10 and fix a bug or two
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’.
-rw-r--r--lib/rmt.h2
-rw-r--r--lib/rtapelib.c64
-rw-r--r--paxlib.modules1
3 files changed, 28 insertions, 39 deletions
diff --git a/lib/rmt.h b/lib/rmt.h
index ff10e7c..721061c 100644
--- 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;
diff --git a/lib/rtapelib.c b/lib/rtapelib.c
index 7213031..fae0db8 100644
--- 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 open_mode, int bias,
}
}
+ 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, size_t length)
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, size_t length)
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, int whence)
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, int whence)
/* 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, char *argument)
#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, char *argument)
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, char *argument)
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;
diff --git a/paxlib.modules b/paxlib.modules
index 5627911..81bbc6d 100644
--- a/paxlib.modules
+++ b/paxlib.modules
@@ -19,4 +19,5 @@ savedir
stdbool
strtol
unlocked-io
+verify
xalloc