X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=lib%2Frtapelib.c;h=7213031a1c77d88a28cc0df980311d0c10856ba6;hb=fa701417bf3178b7fcc8c6c374dafd6d6dedf6e3;hp=51faf3ce91dbd50496705ff15338e87d58c39466;hpb=138fc7e67e3d9845cd7d81aad0e9c7724784f9b9;p=debian%2Ftar diff --git a/lib/rtapelib.c b/lib/rtapelib.c index 51faf3ce..7213031a 100644 --- a/lib/rtapelib.c +++ b/lib/rtapelib.c @@ -90,10 +90,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}}; -char *rmt_command = DEFAULT_RMT_COMMAND; +char const *rmt_command = DEFAULT_RMT_COMMAND; /* Temporary variable used by macros in rmt.h. */ -char *rmt_dev_name__; +char const *rmt_dev_name__; /* If true, always consider file names to be local, even if they contain colons */ @@ -121,7 +121,7 @@ do_command (int handle, const char *buffer) /* Save the current pipe handler and try to make the request. */ size_t length = strlen (buffer); - RETSIGTYPE (*pipe_handler) () = signal (SIGPIPE, SIG_IGN); + RETSIGTYPE (*pipe_handler) (int) = signal (SIGPIPE, SIG_IGN); ssize_t written = full_write (WRITE_SIDE (handle), buffer, length); signal (SIGPIPE, pipe_handler); @@ -425,6 +425,9 @@ rmt_open__ (const char *file_name, int open_mode, int bias, } /* FIXME: Should somewhat validate the decoding, here. */ + if (gethostbyname (remote_host) == NULL) + error (EXIT_ON_EXEC_ERROR, 0, _("Cannot connect to %s: resolve failed"), + remote_host); if (remote_user && *remote_user == '\0') remote_user = 0; @@ -487,15 +490,16 @@ rmt_open__ (const char *file_name, int open_mode, int bias, { /* Child. */ - close (STDIN_FILENO); - dup (to_remote[remote_pipe_number][PREAD]); - close (to_remote[remote_pipe_number][PREAD]); - close (to_remote[remote_pipe_number][PWRITE]); - - close (STDOUT_FILENO); - dup (from_remote[remote_pipe_number][PWRITE]); - close (from_remote[remote_pipe_number][PREAD]); - close (from_remote[remote_pipe_number][PWRITE]); + if (dup2 (to_remote[remote_pipe_number][PREAD], STDIN_FILENO) < 0 + || (to_remote[remote_pipe_number][PREAD] != STDIN_FILENO + && close (to_remote[remote_pipe_number][PREAD]) != 0) + || (to_remote[remote_pipe_number][PWRITE] != STDIN_FILENO + && close (to_remote[remote_pipe_number][PWRITE]) != 0) + || dup2 (from_remote[remote_pipe_number][PWRITE], STDOUT_FILENO) < 0 + || close (from_remote[remote_pipe_number][PREAD]) != 0 + || close (from_remote[remote_pipe_number][PWRITE]) != 0) + error (EXIT_ON_EXEC_ERROR, errno, + _("Cannot redirect files for remote shell")); sys_reset_uid_gid (); @@ -570,7 +574,8 @@ rmt_read__ (int handle, char *buffer, size_t length) sprintf (command_buffer, "R%lu\n", (unsigned long) length); if (do_command (handle, command_buffer) == -1 - || (status = get_status (handle)) == SAFE_READ_ERROR) + || (status = get_status (handle)) == SAFE_READ_ERROR + || status > length) return SAFE_READ_ERROR; for (counter = 0; counter < status; counter += rlen, buffer += rlen) @@ -592,7 +597,7 @@ size_t rmt_write__ (int handle, char *buffer, size_t length) { char command_buffer[COMMAND_BUFFER_SIZE]; - RETSIGTYPE (*pipe_handler) (); + RETSIGTYPE (*pipe_handler) (int); size_t written; sprintf (command_buffer, "W%lu\n", (unsigned long) length); @@ -706,6 +711,12 @@ rmt_ioctl__ (int handle, int operation, char *argument) || (status = get_status (handle), status == -1)) return -1; + if (status > sizeof (struct mtop)) + { + errno = EOVERFLOW; + return -1; + } + for (; status > 0; status -= counter, argument += counter) { counter = safe_read (READ_SIDE (handle), argument, status);