|  | @@ -312,6 +312,47 @@ _rmt_rexec (char *host, char *user)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  #endif /* WITH_REXEC */
 |  |  #endif /* WITH_REXEC */
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +/* Place into BUF a string representing OFLAG, which must be suitable
 | 
											
												
													
														|  | 
 |  | +   as argument 2 of `open'.  BUF must be large enough to hold the
 | 
											
												
													
														|  | 
 |  | +   result.  This function should generate a string that decode_oflag
 | 
											
												
													
														|  | 
 |  | +   can parse.  */
 | 
											
												
													
														|  | 
 |  | +static void
 | 
											
												
													
														|  | 
 |  | +encode_oflag (char *buf, int oflag)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +  sprintf (buf, "%d ", oflag);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  switch (oflag & O_ACCMODE)
 | 
											
												
													
														|  | 
 |  | +    {
 | 
											
												
													
														|  | 
 |  | +    case O_RDONLY: strcat (buf, "O_RDONLY"); break;
 | 
											
												
													
														|  | 
 |  | +    case O_RDWR: strcat (buf, "O_RDWR"); break;
 | 
											
												
													
														|  | 
 |  | +    case O_WRONLY: strcat (buf, "O_WRONLY"); break;
 | 
											
												
													
														|  | 
 |  | +    default: abort ();
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  if (oflag & O_APPEND) strcat (buf, "|O_APPEND");
 | 
											
												
													
														|  | 
 |  | +  if (oflag & O_CREAT) strcat (buf, "|O_CREAT");
 | 
											
												
													
														|  | 
 |  | +#ifdef O_DSYNC
 | 
											
												
													
														|  | 
 |  | +  if (oflag & O_DSYNC) strcat (buf, "|O_DSYNC");
 | 
											
												
													
														|  | 
 |  | +#endif
 | 
											
												
													
														|  | 
 |  | +  if (oflag & O_EXCL) strcat (buf, "|O_EXCL");
 | 
											
												
													
														|  | 
 |  | +#ifdef O_LARGEFILE
 | 
											
												
													
														|  | 
 |  | +  if (oflag & O_LARGEFILE) strcat (buf, "|O_LARGEFILE");
 | 
											
												
													
														|  | 
 |  | +#endif
 | 
											
												
													
														|  | 
 |  | +#ifdef O_NOCTTY
 | 
											
												
													
														|  | 
 |  | +  if (oflag & O_NOCTTY) strcat (buf, "|O_NOCTTY");
 | 
											
												
													
														|  | 
 |  | +#endif
 | 
											
												
													
														|  | 
 |  | +#ifdef O_NONBLOCK
 | 
											
												
													
														|  | 
 |  | +  if (oflag & O_NONBLOCK) strcat (buf, "|O_NONBLOCK");
 | 
											
												
													
														|  | 
 |  | +#endif
 | 
											
												
													
														|  | 
 |  | +#ifdef O_RSYNC
 | 
											
												
													
														|  | 
 |  | +  if (oflag & O_RSYNC) strcat (buf, "|O_RSYNC");
 | 
											
												
													
														|  | 
 |  | +#endif
 | 
											
												
													
														|  | 
 |  | +#ifdef O_SYNC
 | 
											
												
													
														|  | 
 |  | +  if (oflag & O_SYNC) strcat (buf, "|O_SYNC");
 | 
											
												
													
														|  | 
 |  | +#endif
 | 
											
												
													
														|  | 
 |  | +  if (oflag & O_TRUNC) strcat (buf, "|O_TRUNC");
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  /*------------------------------------------------------------------------.
 |  |  /*------------------------------------------------------------------------.
 | 
											
												
													
														|  |  | Open a file (a magnetic tape device?) on the system specified in PATH,  |
 |  |  | Open a file (a magnetic tape device?) on the system specified in PATH,  |
 | 
											
												
													
														|  |  | as the given user.  PATH has the form `[USER@]HOST:FILE'.  OPEN_MODE is |
 |  |  | as the given user.  PATH has the form `[USER@]HOST:FILE'.  OPEN_MODE is |
 | 
											
										
											
												
													
														|  | @@ -359,6 +400,13 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
 | 
											
												
													
														|  |  	default:
 |  |  	default:
 | 
											
												
													
														|  |  	  break;
 |  |  	  break;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +	case '\n':
 | 
											
												
													
														|  | 
 |  | +	  /* Do not allow newlines in the path, since the protocol
 | 
											
												
													
														|  | 
 |  | +	     uses newline delimiters.  */
 | 
											
												
													
														|  | 
 |  | +	  free (path_copy);
 | 
											
												
													
														|  | 
 |  | +	  errno = ENOENT;
 | 
											
												
													
														|  | 
 |  | +	  return -1;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  	case '@':
 |  |  	case '@':
 | 
											
												
													
														|  |  	  if (!remote_user)
 |  |  	  if (!remote_user)
 | 
											
												
													
														|  |  	    {
 |  |  	    {
 | 
											
										
											
												
													
														|  | @@ -390,7 +438,9 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
 | 
											
												
													
														|  |    READ_SIDE (remote_pipe_number) = _rmt_rexec (remote_host, remote_user);
 |  |    READ_SIDE (remote_pipe_number) = _rmt_rexec (remote_host, remote_user);
 | 
											
												
													
														|  |    if (READ_SIDE (remote_pipe_number) < 0)
 |  |    if (READ_SIDE (remote_pipe_number) < 0)
 | 
											
												
													
														|  |      {
 |  |      {
 | 
											
												
													
														|  | 
 |  | +      int e = errno;
 | 
											
												
													
														|  |        free (path_copy);
 |  |        free (path_copy);
 | 
											
												
													
														|  | 
 |  | +      errno = e;
 | 
											
												
													
														|  |        return -1;
 |  |        return -1;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -408,8 +458,8 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
 | 
											
												
													
														|  |  #ifdef REMOTE_SHELL
 |  |  #ifdef REMOTE_SHELL
 | 
											
												
													
														|  |  	remote_shell = REMOTE_SHELL;
 |  |  	remote_shell = REMOTE_SHELL;
 | 
											
												
													
														|  |  #else
 |  |  #else
 | 
											
												
													
														|  | -	errno = EIO;		/* FIXME: errno should be read-only */
 |  | 
 | 
											
												
													
														|  |  	free (path_copy);
 |  |  	free (path_copy);
 | 
											
												
													
														|  | 
 |  | +	errno = EIO;
 | 
											
												
													
														|  |  	return -1;
 |  |  	return -1;
 | 
											
												
													
														|  |  #endif
 |  |  #endif
 | 
											
												
													
														|  |        }
 |  |        }
 | 
											
										
											
												
													
														|  | @@ -420,14 +470,18 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
 | 
											
												
													
														|  |      if (pipe (to_remote[remote_pipe_number]) == -1
 |  |      if (pipe (to_remote[remote_pipe_number]) == -1
 | 
											
												
													
														|  |  	|| pipe (from_remote[remote_pipe_number]) == -1)
 |  |  	|| pipe (from_remote[remote_pipe_number]) == -1)
 | 
											
												
													
														|  |        {
 |  |        {
 | 
											
												
													
														|  | 
 |  | +	int e = errno;
 | 
											
												
													
														|  |  	free (path_copy);
 |  |  	free (path_copy);
 | 
											
												
													
														|  | 
 |  | +	errno = e;
 | 
											
												
													
														|  |  	return -1;
 |  |  	return -1;
 | 
											
												
													
														|  |        }
 |  |        }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      status = fork ();
 |  |      status = fork ();
 | 
											
												
													
														|  |      if (status == -1)
 |  |      if (status == -1)
 | 
											
												
													
														|  |        {
 |  |        {
 | 
											
												
													
														|  | 
 |  | +	int e = errno;
 | 
											
												
													
														|  |  	free (path_copy);
 |  |  	free (path_copy);
 | 
											
												
													
														|  | 
 |  | +	errno = e;
 | 
											
												
													
														|  |  	return -1;
 |  |  	return -1;
 | 
											
												
													
														|  |        }
 |  |        }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -473,16 +527,21 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
 | 
											
												
													
														|  |    /* Attempt to open the tape device.  */
 |  |    /* Attempt to open the tape device.  */
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |    {
 |  |    {
 | 
											
												
													
														|  | -    char command_buffer[COMMAND_BUFFER_SIZE];
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -    sprintf (command_buffer, "O%s\n%d\n", remote_file, open_mode);
 |  | 
 | 
											
												
													
														|  | 
 |  | +    size_t remote_file_len = strlen (remote_file);
 | 
											
												
													
														|  | 
 |  | +    char *command_buffer = xmalloc (remote_file_len + 1000);
 | 
											
												
													
														|  | 
 |  | +    sprintf (command_buffer, "O%s\n", remote_file);
 | 
											
												
													
														|  | 
 |  | +    encode_oflag (command_buffer + remote_file_len + 2, open_mode);
 | 
											
												
													
														|  | 
 |  | +    strcat (command_buffer, "\n");
 | 
											
												
													
														|  |      if (do_command (remote_pipe_number, command_buffer) == -1
 |  |      if (do_command (remote_pipe_number, command_buffer) == -1
 | 
											
												
													
														|  |  	|| get_status (remote_pipe_number) == -1)
 |  |  	|| get_status (remote_pipe_number) == -1)
 | 
											
												
													
														|  |        {
 |  |        {
 | 
											
												
													
														|  | -	_rmt_shutdown (remote_pipe_number, errno);
 |  | 
 | 
											
												
													
														|  | 
 |  | +	int e = errno;
 | 
											
												
													
														|  | 
 |  | +	free (command_buffer);
 | 
											
												
													
														|  |  	free (path_copy);
 |  |  	free (path_copy);
 | 
											
												
													
														|  | 
 |  | +	_rmt_shutdown (remote_pipe_number, e);
 | 
											
												
													
														|  |  	return -1;
 |  |  	return -1;
 | 
											
												
													
														|  |        }
 |  |        }
 | 
											
												
													
														|  | 
 |  | +    free (command_buffer);
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |    free (path_copy);
 |  |    free (path_copy);
 |