#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 |
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)
{
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;
}
#ifdef REMOTE_SHELL
remote_shell = REMOTE_SHELL;
#else
- errno = EIO; /* FIXME: errno should be read-only */
free (path_copy);
+ errno = EIO;
return -1;
#endif
}
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;
}
/* 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);