*/
#include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.46 2001/01/29 16:55:36 markus Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.52 2001/02/28 08:45:39 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
static int connection_in; /* Connection to server (input). */
static int connection_out; /* Connection to server (output). */
-
void client_init_dispatch(void);
int session_ident = -1;
/* Returns the user\'s terminal to normal mode if it had been put in raw mode. */
void
-leave_raw_mode()
+leave_raw_mode(void)
{
if (!in_raw_mode)
return;
/* Puts the user\'s terminal in raw mode. */
void
-enter_raw_mode()
+enter_raw_mode(void)
{
struct termios tio;
/* Restores stdin to blocking mode. */
void
-leave_non_blocking()
+leave_non_blocking(void)
{
if (in_non_blocking_mode) {
(void) fcntl(fileno(stdin), F_SETFL, 0);
/* Puts stdin terminal in non-blocking mode. */
void
-enter_non_blocking()
+enter_non_blocking(void)
{
in_non_blocking_mode = 1;
(void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
*/
double
-get_current_time()
+get_current_time(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
*/
void
-client_check_initial_eof_on_stdin()
+client_check_initial_eof_on_stdin(void)
{
int len;
char buf[1];
*/
if ((u_char) buf[0] == escape_char)
escape_pending = 1;
- else {
+ else
buffer_append(&stdin_buffer, buf, 1);
- stdin_bytes += 1;
- }
}
leave_non_blocking();
}
*/
void
-client_make_packets_from_stdin_data()
+client_make_packets_from_stdin_data(void)
{
u_int len;
packet_put_string(buffer_ptr(&stdin_buffer), len);
packet_send();
buffer_consume(&stdin_buffer, len);
+ stdin_bytes += len;
/* If we have a pending EOF, send it now. */
if (stdin_eof && buffer_len(&stdin_buffer) == 0) {
packet_start(SSH_CMSG_EOF);
*/
void
-client_check_window_change()
+client_check_window_change(void)
{
struct winsize ws;
if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) {
char buf[100];
+
+ /*
+ * We have to clear the select masks, because we return.
+ * We have to return, because the mainloop checks for the flags
+ * set by the signal handlers.
+ */
+ memset(*readsetp, 0, *maxfdp);
+ memset(*writesetp, 0, *maxfdp);
+
if (errno == EINTR)
return;
/* Note: we might still have data in the buffers. */
snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
buffer_append(&stderr_buffer, buf, strlen(buf));
- stderr_bytes += strlen(buf);
quit_pending = 1;
}
}
snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
host);
buffer_append(&stderr_buffer, buf, strlen(buf));
- stderr_bytes += strlen(buf);
quit_pending = 1;
return;
}
snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n",
host, strerror(errno));
buffer_append(&stderr_buffer, buf, strlen(buf));
- stderr_bytes += strlen(buf);
quit_pending = 1;
return;
}
/* Terminate the connection. */
snprintf(string, sizeof string, "%c.\r\n", escape_char);
buffer_append(berr, string, strlen(string));
- /*stderr_bytes += strlen(string); XXX*/
quit_pending = 1;
return -1;
/* Print a message to that effect to the user. */
snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char);
buffer_append(berr, string, strlen(string));
- /*stderr_bytes += strlen(string); XXX*/
/* Restore terminal modes and suspend. */
client_suspend_self(bin, bout, berr);
void
client_process_input(fd_set * readset)
{
- int ret;
int len;
char buf[8192];
if (len < 0) {
snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno));
buffer_append(&stderr_buffer, buf, strlen(buf));
- stderr_bytes += strlen(buf);
}
/* Mark that we have seen EOF. */
stdin_eof = 1;
* Just append the data to buffer.
*/
buffer_append(&stdin_buffer, buf, len);
- stdin_bytes += len;
} else {
/*
* Normal, successful read. But we have an escape character
* and have to process the characters one by one.
*/
- ret = process_escapes(&stdin_buffer, &stdout_buffer, &stderr_buffer, buf, len);
- if (ret == -1)
+ if (process_escapes(&stdin_buffer, &stdout_buffer,
+ &stderr_buffer, buf, len) == -1)
return;
- stdout_bytes += ret;
}
}
}
*/
snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno));
buffer_append(&stderr_buffer, buf, strlen(buf));
- stderr_bytes += strlen(buf);
quit_pending = 1;
return;
}
}
/* Consume printed data from the buffer. */
buffer_consume(&stdout_buffer, len);
+ stdout_bytes += len;
}
/* Write buffered output to stderr. */
if (FD_ISSET(fileno(stderr), writeset)) {
}
/* Consume printed characters from the buffer. */
buffer_consume(&stderr_buffer, len);
+ stderr_bytes += len;
}
}
*/
void
-client_process_buffered_input_packets()
+client_process_buffered_input_packets(void)
{
dispatch_run(DISPATCH_NONBLOCK, &quit_pending, NULL);
}
if (have_pty)
enter_raw_mode();
- /* Check if we should immediately send eof on stdin. */
- if (!compat20)
+ if (compat20) {
+ session_ident = ssh2_chan_id;
+ if (escape_char != -1)
+ channel_register_filter(session_ident,
+ simple_escape_filter);
+ } else {
+ /* Check if we should immediately send eof on stdin. */
client_check_initial_eof_on_stdin();
-
- if (compat20 && escape_char != -1)
- channel_register_filter(ssh2_chan_id, simple_escape_filter);
+ }
/* Main loop of the client for the interactive session mode. */
while (!quit_pending) {
if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);
buffer_append(&stderr_buffer, buf, strlen(buf));
- stderr_bytes += strlen(buf);
}
/* Output any buffered data for stdout. */
while (buffer_len(&stdout_buffer) > 0) {
break;
}
buffer_consume(&stdout_buffer, len);
+ stdout_bytes += len;
}
/* Output any buffered data for stderr. */
break;
}
buffer_consume(&stderr_buffer, len);
+ stderr_bytes += len;
}
if (have_pty)
char *data = packet_get_string(&data_len);
packet_integrity_check(plen, 4 + data_len, type);
buffer_append(&stdout_buffer, data, data_len);
- stdout_bytes += data_len;
memset(data, 0, data_len);
xfree(data);
}
char *data = packet_get_string(&data_len);
packet_integrity_check(plen, 4 + data_len, type);
buffer_append(&stderr_buffer, data, data_len);
- stdout_bytes += data_len;
memset(data, 0, data_len);
xfree(data);
}
}
packet_done();
/* XXX check permission */
+ debug("client_request_x11: request from %s %d", originator,
+ originator_port);
sock = x11_connect_display();
if (sock >= 0) {
newch = channel_new("x11",
}
xfree(ctype);
}
+void
+client_input_channel_req(int type, int plen, void *ctxt)
+{
+ Channel *c = NULL;
+ int id, reply, success = 0;
+ char *rtype;
+
+ id = packet_get_int();
+ rtype = packet_get_string(NULL);
+ reply = packet_get_char();
+
+ debug("client_input_channel_req: channel %d rtype %s reply %d",
+ id, rtype, reply);
+
+ if (session_ident == -1) {
+ error("client_input_channel_req: no channel %d", session_ident);
+ } else if (id != session_ident) {
+ error("client_input_channel_req: channel %d: wrong channel: %d",
+ session_ident, id);
+ }
+ c = channel_lookup(id);
+ if (c == NULL) {
+ error("client_input_channel_req: channel %d: unknown channel", id);
+ } else if (strcmp(rtype, "exit-status") == 0) {
+ success = 1;
+ exit_status = packet_get_int();
+ packet_done();
+ }
+ if (reply) {
+ packet_start(success ?
+ SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
+ packet_put_int(c->remote_id);
+ packet_send();
+ }
+ xfree(rtype);
+}
void
-client_init_dispatch_20()
+client_init_dispatch_20(void)
{
dispatch_init(&dispatch_protocol_error);
dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);
dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
- dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request);
+ dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
}
void
-client_init_dispatch_13()
+client_init_dispatch_13(void)
{
dispatch_init(NULL);
dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
&x11_input_open : &deny_input_open);
}
void
-client_init_dispatch_15()
+client_init_dispatch_15(void)
{
client_init_dispatch_13();
dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
}
void
-client_init_dispatch()
+client_init_dispatch(void)
{
if (compat20)
client_init_dispatch_20();
else
client_init_dispatch_15();
}
-
-void
-client_input_channel_req(int id, void *arg)
-{
- Channel *c = NULL;
- u_int len;
- int success = 0;
- int reply;
- char *rtype;
-
- rtype = packet_get_string(&len);
- reply = packet_get_char();
-
- debug("client_input_channel_req: rtype %s reply %d", rtype, reply);
-
- c = channel_lookup(id);
- if (c == NULL)
- fatal("client_input_channel_req: channel %d: bad channel", id);
-
- if (session_ident == -1) {
- error("client_input_channel_req: no channel %d", id);
- } else if (id != session_ident) {
- error("client_input_channel_req: bad channel %d != %d",
- id, session_ident);
- } else if (strcmp(rtype, "exit-status") == 0) {
- success = 1;
- exit_status = packet_get_int();
- packet_done();
- }
- if (reply) {
- packet_start(success ?
- SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
- packet_put_int(c->remote_id);
- packet_send();
- }
- xfree(rtype);
-}
-
-void
-clientloop_set_session_ident(int id)
-{
- debug2("clientloop_set_session_ident: id %d", id);
- session_ident = id;
- channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST,
- client_input_channel_req, (void *)0);
-}