/*
- *
+ *
* clientloop.c
- *
+ *
* Author: Tatu Ylonen <ylo@cs.hut.fi>
- *
+ *
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
- *
- *
+ *
+ *
* Created: Sat Sep 23 12:23:57 1995 ylo
- *
+ *
* The main loop for the interactive session (client side).
- *
+ *
* SSH2 support added by Markus Friedl.
*/
/* Returns the user\'s terminal to normal mode if it had been put in raw mode. */
-void
+void
leave_raw_mode()
{
if (!in_raw_mode)
/* Puts the user\'s terminal in raw mode. */
-void
+void
enter_raw_mode()
{
struct termios tio;
/* Restores stdin to blocking mode. */
-void
+void
leave_non_blocking()
{
if (in_non_blocking_mode) {
/* Puts stdin terminal in non-blocking mode. */
-void
+void
enter_non_blocking()
{
in_non_blocking_mode = 1;
* flag indicating that the window has changed.
*/
-void
+void
window_change_handler(int sig)
{
received_window_change_signal = 1;
* signals must be trapped to restore terminal modes.
*/
-void
+void
signal_handler(int sig)
{
if (in_raw_mode)
* available resolution.
*/
-double
+double
get_current_time()
{
struct timeval tv;
* not appear to wake up when redirecting from /dev/null.
*/
-void
+void
client_check_initial_eof_on_stdin()
{
int len;
* connection.
*/
-void
+void
client_make_packets_from_stdin_data()
{
unsigned int len;
* appropriate.
*/
-void
+void
client_check_window_change()
{
struct winsize ws;
* one of the file descriptors).
*/
-void
+void
client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
{
/*debug("client_wait_until_can_do_something"); */
}
}
-void
+void
client_suspend_self()
{
struct winsize oldws, newws;
enter_raw_mode();
}
-void
+void
client_process_net_input(fd_set * readset)
{
int len;
}
}
-void
+void
client_process_input(fd_set * readset)
{
- int len, pid;
+ int len;
+ pid_t pid;
char buf[8192], *s;
/* Read input from stdin. */
}
}
-void
+void
client_process_output(fd_set * writeset)
{
int len;
* preparatory phase.
*/
-void
+void
client_process_buffered_input_packets()
{
dispatch_run(DISPATCH_NONBLOCK, &quit_pending);
* character for terminating or suspending the session.
*/
-int
+int
client_loop(int have_pty, int escape_char_arg)
{
extern Options options;
quit_pending = 1;
}
-void
+/* XXXX move to generic input handler */
+void
+client_input_channel_open(int type, int plen)
+{
+ Channel *c = NULL;
+ char *ctype;
+ int id;
+ unsigned int len;
+ int rchan;
+ int rmaxpack;
+ int rwindow;
+
+ ctype = packet_get_string(&len);
+ rchan = packet_get_int();
+ rwindow = packet_get_int();
+ rmaxpack = packet_get_int();
+
+ debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
+ ctype, rchan, rwindow, rmaxpack);
+
+ if (strcmp(ctype, "x11") == 0) {
+ int sock;
+ char *originator;
+ int originator_port;
+ originator = packet_get_string(NULL);
+ if (datafellows & SSH_BUG_X11FWD) {
+ debug("buggy server: x11 request w/o originator_port");
+ originator_port = 0;
+ } else {
+ originator_port = packet_get_int();
+ }
+ packet_done();
+ /* XXX check permission */
+ xfree(originator);
+ /* XXX move to channels.c */
+ sock = x11_connect_display();
+ if (sock >= 0) {
+ id = channel_new("x11", SSH_CHANNEL_X11_OPEN,
+ sock, sock, -1, 4*1024, 32*1024, 0,
+ xstrdup("x11"));
+ c = channel_lookup(id);
+ }
+ }
+/* XXX duplicate : */
+ if (c != NULL) {
+ debug("confirm %s", ctype);
+ c->remote_id = rchan;
+ c->remote_window = rwindow;
+ c->remote_maxpacket = rmaxpack;
+
+ packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
+ packet_put_int(c->remote_id);
+ packet_put_int(c->self);
+ packet_put_int(c->local_window);
+ packet_put_int(c->local_maxpacket);
+ packet_send();
+ } else {
+ debug("failure %s", ctype);
+ packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
+ packet_put_int(rchan);
+ packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
+ packet_put_cstring("bla bla");
+ packet_put_cstring("");
+ packet_send();
+ }
+ xfree(ctype);
+}
+
+void
client_init_dispatch_20()
{
dispatch_init(&dispatch_protocol_error);
dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
+ 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_WINDOW_ADJUST, &channel_input_window_adjust);
}
-void
+void
client_init_dispatch_13()
{
dispatch_init(NULL);
dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
- dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);
dispatch_set(SSH_SMSG_X11_OPEN, &x11_input_open);
}
-void
+void
client_init_dispatch_15()
{
client_init_dispatch_13();
dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
}
-void
+void
client_init_dispatch()
{
if (compat20)
rtype = packet_get_string(&len);
reply = packet_get_char();
- debug("session_input_channel_req: rtype %s reply %d", rtype, reply);
+ debug("client_input_channel_req: rtype %s reply %d", rtype, reply);
c = channel_lookup(id);
if (c == NULL)
} else if (strcmp(rtype, "exit-status") == 0) {
success = 1;
exit_status = packet_get_int();
+ packet_done();
}
if (reply) {
packet_start(success ?