diff --git a/ldisc.c b/ldisc.c index e5e1449d..8c985f06 100644 --- a/ldisc.c +++ b/ldisc.c @@ -139,6 +139,10 @@ void ldisc_echoedit_update(Ldisc *ldisc) seat_echoedit_update(ldisc->seat, ECHOING, EDITING); } +void ldisc_check_sendok(Ldisc *ldisc) +{ +} + void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, bool interactive) { const char *buf = (const char *)vbuf; diff --git a/otherbackends/raw.c b/otherbackends/raw.c index 87a136ba..97b7be09 100644 --- a/otherbackends/raw.c +++ b/otherbackends/raw.c @@ -17,6 +17,7 @@ struct Raw { size_t bufsize; Seat *seat; LogContext *logctx; + Ldisc *ldisc; bool sent_console_eof, sent_socket_eof, socket_connected; Conf *conf; @@ -41,6 +42,8 @@ static void raw_log(Plug *plug, PlugLogType type, SockAddr *addr, int port, error_code, raw->conf, raw->socket_connected); if (type == PLUGLOG_CONNECT_SUCCESS) { raw->socket_connected = true; + if (raw->ldisc) + ldisc_check_sendok(raw->ldisc); if (is_tempseat(raw->seat)) { Seat *ts = raw->seat; tempseat_flush(ts); @@ -295,7 +298,8 @@ static bool raw_ldisc(Backend *be, int option) static void raw_provide_ldisc(Backend *be, Ldisc *ldisc) { - /* This is a stub. */ + Raw *raw = container_of(be, Raw, backend); + raw->ldisc = ldisc; } static int raw_exitcode(Backend *be) diff --git a/otherbackends/rlogin.c b/otherbackends/rlogin.c index 51e6ed05..11deb89c 100644 --- a/otherbackends/rlogin.c +++ b/otherbackends/rlogin.c @@ -22,6 +22,7 @@ struct Rlogin { int term_width, term_height; Seat *seat; LogContext *logctx; + Ldisc *ldisc; Conf *conf; @@ -194,6 +195,8 @@ static void rlogin_startup(Rlogin *rlogin, int prompt_result, } rlogin->prompt = NULL; + if (rlogin->ldisc) + ldisc_check_sendok(rlogin->ldisc); } static const PlugVtable Rlogin_plugvt = { @@ -413,7 +416,8 @@ static bool rlogin_ldisc(Backend *be, int option) static void rlogin_provide_ldisc(Backend *be, Ldisc *ldisc) { - /* This is a stub. */ + Rlogin *rlogin = container_of(be, Rlogin, backend); + rlogin->ldisc = ldisc; } static int rlogin_exitcode(Backend *be) diff --git a/otherbackends/supdup.c b/otherbackends/supdup.c index ae7e67f7..a3418fe1 100644 --- a/otherbackends/supdup.c +++ b/otherbackends/supdup.c @@ -71,6 +71,7 @@ struct supdup_tag Seat *seat; LogContext *logctx; + Ldisc *ldisc; int term_width, term_height; long long ttyopt; @@ -565,6 +566,8 @@ static void supdup_log(Plug *plug, PlugLogType type, SockAddr *addr, int port, supdup->conf, supdup->socket_connected); if (type == PLUGLOG_CONNECT_SUCCESS) { supdup->socket_connected = true; + if (supdup->ldisc) + ldisc_check_sendok(supdup->ldisc); if (is_tempseat(supdup->seat)) { Seat *ts = supdup->seat; tempseat_flush(ts); @@ -893,6 +896,8 @@ static bool supdup_ldisc(Backend *be, int option) static void supdup_provide_ldisc(Backend *be, Ldisc *ldisc) { + Supdup *supdup = container_of(be, Supdup, backend); + supdup->ldisc = ldisc; } static int supdup_exitcode(Backend *be) diff --git a/otherbackends/telnet.c b/otherbackends/telnet.c index 540d384c..98c202c6 100644 --- a/otherbackends/telnet.c +++ b/otherbackends/telnet.c @@ -628,6 +628,8 @@ static void telnet_log(Plug *plug, PlugLogType type, SockAddr *addr, int port, telnet->socket_connected); if (type == PLUGLOG_CONNECT_SUCCESS) { telnet->socket_connected = true; + if (telnet->ldisc) + ldisc_check_sendok(telnet->ldisc); if (is_tempseat(telnet->seat)) { Seat *ts = telnet->seat; tempseat_flush(ts); diff --git a/pscp.c b/pscp.c index ec4dfa8a..7717d8d6 100644 --- a/pscp.c +++ b/pscp.c @@ -58,6 +58,7 @@ const char *const appname = "PSCP"; #define MAX_SCP_BUFSIZE 16384 void ldisc_echoedit_update(Ldisc *ldisc) { } +void ldisc_check_sendok(Ldisc *ldisc) { } static size_t pscp_output(Seat *, bool is_stderr, const void *, size_t); static bool pscp_eof(Seat *); diff --git a/psftp.c b/psftp.c index 16beee56..a09837c7 100644 --- a/psftp.c +++ b/psftp.c @@ -2448,6 +2448,7 @@ int do_sftp(int mode, int modeflags, char *batchfile) static bool verbose = false; void ldisc_echoedit_update(Ldisc *ldisc) { } +void ldisc_check_sendok(Ldisc *ldisc) { } /* * Receive a block of data from the SSH link. Block until all data diff --git a/putty.h b/putty.h index 8b419a32..fcfff4b6 100644 --- a/putty.h +++ b/putty.h @@ -2055,6 +2055,7 @@ void ldisc_configure(Ldisc *, Conf *); void ldisc_free(Ldisc *); void ldisc_send(Ldisc *, const void *buf, int len, bool interactive); void ldisc_echoedit_update(Ldisc *); +void ldisc_check_sendok(Ldisc *); /* * Exports from sshrand.c. diff --git a/ssh.h b/ssh.h index 23bed390..34a8909d 100644 --- a/ssh.h +++ b/ssh.h @@ -397,6 +397,7 @@ LogContext *ssh_get_logctx(Ssh *ssh); void ssh_throttle_conn(Ssh *ssh, int adjust); void ssh_got_exitcode(Ssh *ssh, int status); void ssh_ldisc_update(Ssh *ssh); +void ssh_check_sendok(Ssh *ssh); void ssh_got_fallback_cmd(Ssh *ssh); bool ssh_is_bare(Ssh *ssh); diff --git a/ssh/connection1.c b/ssh/connection1.c index 7b1765f6..071e0139 100644 --- a/ssh/connection1.c +++ b/ssh/connection1.c @@ -775,6 +775,8 @@ static void ssh1_set_wants_user_input(ConnectionLayer *cl, bool wanted) s->want_user_input = wanted; s->finished_setup = true; + if (wanted) + ssh_check_sendok(s->ppl.ssh); } static bool ssh1_connection_want_user_input(PacketProtocolLayer *ppl) diff --git a/ssh/connection2.c b/ssh/connection2.c index 2e7102db..86e26f4b 100644 --- a/ssh/connection2.c +++ b/ssh/connection2.c @@ -1709,6 +1709,8 @@ static void ssh2_set_wants_user_input(ConnectionLayer *cl, bool wanted) container_of(cl, struct ssh2_connection_state, cl); s->want_user_input = wanted; + if (wanted) + ssh_check_sendok(s->ppl.ssh); } static bool ssh2_connection_want_user_input(PacketProtocolLayer *ppl) diff --git a/ssh/server.c b/ssh/server.c index 1517522b..a3c400c0 100644 --- a/ssh/server.c +++ b/ssh/server.c @@ -244,6 +244,8 @@ Conf *make_ssh_server_conf(void) return conf; } +void ssh_check_sendok(Ssh *ssh) {} + static const PlugVtable ssh_server_plugvt = { .log = server_socket_log, .closing = server_closing, diff --git a/ssh/ssh.c b/ssh/ssh.c index 98b7a68a..10c52001 100644 --- a/ssh/ssh.c +++ b/ssh/ssh.c @@ -1156,6 +1156,14 @@ static bool ssh_sendok(Backend *be) return ssh->base_layer && ssh_ppl_want_user_input(ssh->base_layer); } +void ssh_check_sendok(Ssh *ssh) +{ + /* Called when the connection layer might have caused ssh_sendok + * to start returning true */ + if (ssh->ldisc) + ldisc_check_sendok(ssh->ldisc); +} + void ssh_ldisc_update(Ssh *ssh) { /* Called when the connection layer wants to propagate an update