/* Functions for communicating with a remote tape drive.
- Copyright 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001 Free Software
- Foundation, Inc.
+ Copyright 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004 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
code, courtesy of Dan Kegel. */
#include "system.h"
-
+#include "common.h"
#include <safe-read.h>
#include <full-write.h>
if (*cursor == 'E' || *cursor == 'F')
{
- errno = atoi (cursor + 1);
-
/* Skip the error message line. */
/* FIXME: there is better to do than merely ignoring error messages
break;
}
+ errno = atoi (cursor + 1);
+
if (*cursor == 'F')
_rmt_shutdown (handle, errno);
/* Read and return the status from remote tape connection HANDLE. If
an error occurred, return -1 and set errno. */
-static long
+static long int
get_status (int handle)
{
char command_buffer[COMMAND_BUFFER_SIZE];
const char *status = get_status_string (handle, command_buffer);
- return status ? atol (status) : -1L;
+ if (status)
+ {
+ long int result = atol (status);
+ if (0 <= result)
+ return result;
+ errno = EIO;
+ }
+ return -1;
}
static off_t
for (; *status == ' ' || *status == '\t'; status++)
continue;
-
+
negative = *status == '-';
status += negative || *status == '+';
-
+
for (;;)
{
int digit = *status++ - '0';
close (from_remote[remote_pipe_number][PREAD]);
close (from_remote[remote_pipe_number][PWRITE]);
-#if !MSDOS
- setuid (getuid ());
- setgid (getgid ());
-#endif
+ sys_reset_uid_gid ();
if (remote_user)
execl (remote_shell, remote_shell_basename, remote_host,
int
rmt_close__ (int handle)
{
- int status;
+ long int status;
if (do_command (handle, "C\n") == -1)
return -1;
}
/* Read up to LENGTH bytes into BUFFER from remote tape connection HANDLE.
- Return the number of bytes read on success, -1 on error. */
-ssize_t
+ Return the number of bytes read on success, SAFE_READ_ERROR on error. */
+size_t
rmt_read__ (int handle, char *buffer, size_t length)
{
char command_buffer[COMMAND_BUFFER_SIZE];
- ssize_t status, rlen;
+ size_t status;
+ size_t rlen;
size_t counter;
sprintf (command_buffer, "R%lu\n", (unsigned long) length);
if (do_command (handle, command_buffer) == -1
- || (status = get_status (handle)) == -1)
- return -1;
+ || (status = get_status (handle)) == SAFE_READ_ERROR)
+ return SAFE_READ_ERROR;
for (counter = 0; counter < status; counter += rlen, buffer += rlen)
{
rlen = safe_read (READ_SIDE (handle), buffer, status - counter);
- if (rlen <= 0)
+ if (rlen == SAFE_READ_ERROR || rlen == 0)
{
_rmt_shutdown (handle, EIO);
- return -1;
+ return SAFE_READ_ERROR;
}
}
}
/* Write LENGTH bytes from BUFFER to remote tape connection HANDLE.
- Return the number of bytes written on success, -1 on error. */
-ssize_t
+ Return the number of bytes written. */
+size_t
rmt_write__ (int handle, char *buffer, size_t length)
{
char command_buffer[COMMAND_BUFFER_SIZE];
sprintf (command_buffer, "W%lu\n", (unsigned long) length);
if (do_command (handle, command_buffer) == -1)
- return -1;
+ return 0;
pipe_handler = signal (SIGPIPE, SIG_IGN);
written = full_write (WRITE_SIDE (handle), buffer, length);
signal (SIGPIPE, pipe_handler);
if (written == length)
- return get_status (handle);
+ {
+ long int r = get_status (handle);
+ if (r < 0)
+ return 0;
+ if (r == length)
+ return length;
+ written = r;
+ }
/* Write error. */
_rmt_shutdown (handle, EIO);
- return -1;
+ return written;
}
/* Perform an imitation lseek operation on remote tape connection
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);
? - (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);
case MTIOCGET:
{
ssize_t status;
- ssize_t counter;
+ size_t counter;
/* Grab the status and read it directly into the structure. This
assumes that the status buffer is not padded and that 2 shorts
for (; status > 0; status -= counter, argument += counter)
{
counter = safe_read (READ_SIDE (handle), argument, status);
- if (counter <= 0)
+ if (counter == SAFE_READ_ERROR || counter == 0)
{
_rmt_shutdown (handle, EIO);
return -1;