From RDB: a patch to allow special keys (^C, ^Z, Delete, Return) to
[u/mdw/putty] / telnet.c
index b2e4999..b00a6da 100644 (file)
--- 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)
@@ -569,7 +587,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 +622,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 +653,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 +669,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 +761,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);