X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/32874aeac8dacbca26663777b39a79efc5d8dc4b..9954aaa37368a233dc614d610ca68c2ce5a7e8cd:/telnet.c diff --git a/telnet.c b/telnet.c index b2e49994..04cbec02 100644 --- a/telnet.c +++ b/telnet.c @@ -175,6 +175,7 @@ static struct Opt *opts[] = { }; static int echoing = TRUE, editing = TRUE; +static int activated = FALSE; static int in_synch; static int sb_opt, sb_len; @@ -226,6 +227,23 @@ static void option_side_effects(struct Opt *o, int enabled) else if (o->option == TELOPT_SGA && o->send == DO) editing = !enabled; ldisc_send(NULL, 0); /* cause ldisc to notice the change */ + + /* Ensure we get the minimum options */ + if (!activated) { + if (o_echo.state == INACTIVE) { + o_echo.state = REQUESTED; + send_opt(o_echo.send, o_echo.option); + } + if (o_we_sga.state == INACTIVE) { + o_we_sga.state = REQUESTED; + send_opt(o_we_sga.send, o_we_sga.option); + } + if (o_they_sga.state == INACTIVE) { + o_they_sga.state = REQUESTED; + send_opt(o_they_sga.send, o_they_sga.option); + } + activated = TRUE; + } } static void activate_option(struct Opt *o) @@ -547,8 +565,10 @@ static void do_telnet_read(char *buf, int len) static int telnet_closing(Plug plug, char *error_msg, int error_code, int calling_back) { - sk_close(s); - s = NULL; + if (s) { + sk_close(s); + s = NULL; + } if (error_msg) { /* A socket error has occurred. */ connection_fatal(error_msg); @@ -569,7 +589,8 @@ static int telnet_receive(Plug plug, int urgent, char *data, int len) * * Returns an error message, or NULL on success. * - * Also places the canonical host name into `realhost'. + * Also places the canonical host name into `realhost'. It must be + * freed by the caller. */ static char *telnet_init(char *host, int port, char **realhost) { @@ -603,12 +624,19 @@ static char *telnet_init(char *host, int port, char **realhost) /* * Initialise option states. */ - { + if (cfg.passive_telnet) { + struct Opt **o; + + for (o = opts; *o; o++) + if ((*o)->state == REQUESTED) + (*o)->state = INACTIVE; + } else { struct Opt **o; for (o = opts; *o; o++) if ((*o)->state == REQUESTED) send_opt((*o)->send, (*o)->option); + activated = TRUE; } /* @@ -627,7 +655,9 @@ static void telnet_send(char *buf, int len) char *p; static unsigned char iac[2] = { IAC, IAC }; static unsigned char cr[2] = { CR, NUL }; +#if 0 static unsigned char nl[2] = { CR, LF }; +#endif if (s == NULL) return; @@ -641,7 +671,7 @@ static void telnet_send(char *buf, int len) sk_write(s, q, p - q); while (p < buf + len && !iswritable((unsigned char) *p)) { - sk_write(s, (unsigned char) *p == IAC ? iac : nl, 2); + sk_write(s, (unsigned char) *p == IAC ? iac : cr, 2); p++; } } @@ -733,6 +763,9 @@ static void telnet_special(Telnet_Special code) b[1] = xEOF; sk_write(s, b, 2); break; + case TS_EOL: + sk_write(s, "\r\n", 2); + break; case TS_SYNCH: b[1] = DM; sk_write(s, b, 1);