]> Dogcows Code - chaz/tar/blobdiff - src/rtapelib.c
Fix improper use of 'path' word
[chaz/tar] / src / rtapelib.c
index 772f208528d6eaa55c141097effcf651b685eda8..a31a8930c912cffca617ac4e9f9e2c294983c70a 100644 (file)
@@ -1,7 +1,7 @@
 /* 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
@@ -33,7 +33,7 @@
    code, courtesy of Dan Kegel.  */
 
 #include "system.h"
-
+#include "common.h"
 #include <safe-read.h>
 #include <full-write.h>
 
@@ -88,8 +88,10 @@ static int from_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}};
 /* The pipes for sending data to remote tape drives.  */
 static int to_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}};
 
+#define RMT_COMMAND (rmt_command_option ? rmt_command_option : "/etc/rmt")
+
 /* Temporary variable used by macros in rmt.h.  */
-char *rmt_path__;
+char *rmt_dev_name__;
 \f
 
 /* Close remote tape connection HANDLE, and reset errno to ERRNO_VALUE.  */
@@ -163,8 +165,6 @@ get_status_string (int handle, char *command_buffer)
 
   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
@@ -178,6 +178,8 @@ get_status_string (int handle, char *command_buffer)
            break;
       }
 
+      errno = atoi (cursor + 1);
+
       if (*cursor == 'F')
        _rmt_shutdown (handle, errno);
 
@@ -199,12 +201,19 @@ get_status_string (int handle, char *command_buffer)
 
 /* 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
@@ -226,10 +235,10 @@ get_status_off (int handle)
 
       for (;  *status == ' ' || *status == '\t';  status++)
        continue;
-      
+
       negative = *status == '-';
       status += negative || *status == '+';
-      
+
       for (;;)
        {
          int digit = *status++ - '0';
@@ -251,8 +260,6 @@ get_status_off (int handle)
 
 #if WITH_REXEC
 
-int rexec ();
-
 /* Execute /etc/rmt as user USER on remote system HOST using rexec.
    Return a file descriptor of a bidirectional socket for stdin and
    stdout.  If USER is zero, use the current username.
@@ -284,7 +291,7 @@ _rmt_rexec (char *host, char *user)
   if (rexecserv = getservbyname ("exec", "tcp"), !rexecserv)
     error (EXIT_ON_EXEC_ERROR, 0, _("exec/tcp: Service not available"));
 
-  result = rexec (&host, rexecserv->s_port, user, 0, "/etc/rmt", 0);
+  result = rexec (&host, rexecserv->s_port, user, 0, RMT_COMMAND, 0);
   if (fclose (stdin) == EOF)
     error (0, errno, _("stdin"));
   fdopen (saved_stdin, "r");
@@ -341,15 +348,16 @@ encode_oflag (char *buf, int oflag)
 }
 
 /* Open a file (a magnetic tape device?) on the system specified in
-   PATH, as the given user.  PATH has the form `[USER@]HOST:FILE'.
+   FILE_NAME, as the given user. FILE_NAME has the form `[USER@]HOST:FILE'.
    OPEN_MODE is O_RDONLY, O_WRONLY, etc.  If successful, return the
    remote pipe number plus BIAS.  REMOTE_SHELL may be overridden.  On
    error, return -1.  */
 int
-rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
+rmt_open__ (const char *file_name, int open_mode, int bias, 
+            const char *remote_shell)
 {
   int remote_pipe_number;      /* pseudo, biased file descriptor */
-  char *path_copy ;            /* copy of path string */
+  char *file_name_copy;                /* copy of file_name string */
   char *remote_host;           /* remote host name */
   char *remote_file;           /* remote file name (often a device) */
   char *remote_user;           /* remote user name */
@@ -374,21 +382,21 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
   {
     char *cursor;
 
-    path_copy = xstrdup (path);
-    remote_host = path_copy;
+    file_name_copy = xstrdup (file_name);
+    remote_host = file_name_copy;
     remote_user = 0;
     remote_file = 0;
 
-    for (cursor = path_copy; *cursor; cursor++)
+    for (cursor = file_name_copy; *cursor; cursor++)
       switch (*cursor)
        {
        default:
          break;
 
        case '\n':
-         /* Do not allow newlines in the path, since the protocol
+         /* Do not allow newlines in the file_name, since the protocol
             uses newline delimiters.  */
-         free (path_copy);
+         free (file_name_copy);
          errno = ENOENT;
          return -1;
 
@@ -424,7 +432,7 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
   if (READ_SIDE (remote_pipe_number) < 0)
     {
       int e = errno;
-      free (path_copy);
+      free (file_name_copy);
       errno = e;
       return -1;
     }
@@ -443,7 +451,7 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
 #ifdef REMOTE_SHELL
        remote_shell = REMOTE_SHELL;
 #else
-       free (path_copy);
+       free (file_name_copy);
        errno = EIO;
        return -1;
 #endif
@@ -456,7 +464,7 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
        || pipe (from_remote[remote_pipe_number]) == -1)
       {
        int e = errno;
-       free (path_copy);
+       free (file_name_copy);
        errno = e;
        return -1;
       }
@@ -465,7 +473,7 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
     if (status == -1)
       {
        int e = errno;
-       free (path_copy);
+       free (file_name_copy);
        errno = e;
        return -1;
       }
@@ -484,17 +492,14 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
        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,
-                "-l", remote_user, "/etc/rmt", (char *) 0);
+                "-l", remote_user, RMT_COMMAND, (char *) 0);
        else
          execl (remote_shell, remote_shell_basename, remote_host,
-                "/etc/rmt", (char *) 0);
+                RMT_COMMAND, (char *) 0);
 
        /* Bad problems if we get here.  */
 
@@ -522,14 +527,14 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
       {
        int e = errno;
        free (command_buffer);
-       free (path_copy);
+       free (file_name_copy);
        _rmt_shutdown (remote_pipe_number, e);
        return -1;
       }
     free (command_buffer);
   }
 
-  free (path_copy);
+  free (file_name_copy);
   return remote_pipe_number + bias;
 }
 
@@ -538,7 +543,7 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
 int
 rmt_close__ (int handle)
 {
-  int status;
+  long int status;
 
   if (do_command (handle, "C\n") == -1)
     return -1;
@@ -549,26 +554,27 @@ rmt_close__ (int handle)
 }
 
 /* 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;
        }
     }
 
@@ -576,8 +582,8 @@ rmt_read__ (int handle, char *buffer, size_t length)
 }
 
 /* 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];
@@ -586,18 +592,25 @@ rmt_write__ (int handle, char *buffer, size_t length)
 
   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
@@ -610,6 +623,7 @@ rmt_lseek__ (int handle, off_t offset, int whence)
   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);
@@ -652,7 +666,8 @@ rmt_ioctl__ (int handle, int operation, char *argument)
                       ? - (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);
@@ -674,7 +689,7 @@ rmt_ioctl__ (int handle, int operation, char *argument)
     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
@@ -689,7 +704,7 @@ rmt_ioctl__ (int handle, int operation, char *argument)
        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;
This page took 0.032184 seconds and 4 git commands to generate.