(encode_oflag): New function.
(rmt_open__): Do not allow newlines in the path. Propagate errno correctly. Decode symbolic open flags, if present.
This commit is contained in:
@@ -312,6 +312,47 @@ _rmt_rexec (char *host, char *user)
|
||||
|
||||
#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, |
|
||||
| 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:
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
/* Do not allow newlines in the path, since the protocol
|
||||
uses newline delimiters. */
|
||||
free (path_copy);
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
|
||||
case '@':
|
||||
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);
|
||||
if (READ_SIDE (remote_pipe_number) < 0)
|
||||
{
|
||||
int e = errno;
|
||||
free (path_copy);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -408,8 +458,8 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
|
||||
#ifdef REMOTE_SHELL
|
||||
remote_shell = REMOTE_SHELL;
|
||||
#else
|
||||
errno = EIO; /* FIXME: errno should be read-only */
|
||||
free (path_copy);
|
||||
errno = EIO;
|
||||
return -1;
|
||||
#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
|
||||
|| pipe (from_remote[remote_pipe_number]) == -1)
|
||||
{
|
||||
int e = errno;
|
||||
free (path_copy);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = fork ();
|
||||
if (status == -1)
|
||||
{
|
||||
int e = errno;
|
||||
free (path_copy);
|
||||
errno = e;
|
||||
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. */
|
||||
|
||||
{
|
||||
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
|
||||
|| get_status (remote_pipe_number) == -1)
|
||||
{
|
||||
_rmt_shutdown (remote_pipe_number, errno);
|
||||
int e = errno;
|
||||
free (command_buffer);
|
||||
free (path_copy);
|
||||
_rmt_shutdown (remote_pipe_number, e);
|
||||
return -1;
|
||||
}
|
||||
free (command_buffer);
|
||||
}
|
||||
|
||||
free (path_copy);
|
||||
|
||||
Reference in New Issue
Block a user