Introduce a sane interface function, from_backend(), for backends to
[u/mdw/putty] / plink.c
diff --git a/plink.c b/plink.c
index 938bcb7..26a1729 100644 (file)
--- a/plink.c
+++ b/plink.c
@@ -11,6 +11,7 @@
 
 #define PUTTY_DO_GLOBALS                      /* actually _define_ globals */
 #include "putty.h"
+#include "winstuff.h"
 #include "storage.h"
 
 void fatalbox (char *p, ...) {
@@ -41,6 +42,8 @@ void logevent(char *string) { }
 void verify_ssh_host_key(char *host, int port, char *keytype,
                          char *keystr, char *fingerprint) {
     int ret;
+    HANDLE hin;
+    DWORD savemode, i;
 
     static const char absentmsg[] =
         "The server's host key is not cached in the registry. You\n"
@@ -83,10 +86,21 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
 
     if (ret == 0)                      /* success - key matched OK */
         return;
-    if (ret == 2) {                    /* key was different */
+
+    if (ret == 2)                      /* key was different */
         fprintf(stderr, wrongmsg, fingerprint);
-        if (fgets(line, sizeof(line), stdin) &&
-            line[0] != '\0' && line[0] != '\n') {
+    if (ret == 1)                      /* key was absent */
+        fprintf(stderr, absentmsg, fingerprint);
+
+    hin = GetStdHandle(STD_INPUT_HANDLE);
+    GetConsoleMode(hin, &savemode);
+    SetConsoleMode(hin, (savemode | ENABLE_ECHO_INPUT |
+                         ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT));
+    ReadFile(hin, line, sizeof(line)-1, &i, NULL);
+    SetConsoleMode(hin, savemode);
+
+    if (ret == 2) {                    /* key was different */
+        if (line[0] != '\0' && line[0] != '\r' && line[0] != '\n') {
             if (line[0] == 'y' || line[0] == 'Y')
                 store_host_key(host, port, keytype, keystr);
         } else {
@@ -95,9 +109,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
         }
     }
     if (ret == 1) {                    /* key was absent */
-        fprintf(stderr, absentmsg, fingerprint);
-        if (fgets(line, sizeof(line), stdin) &&
-            (line[0] == 'y' || line[0] == 'Y'))
+        if (line[0] == 'y' || line[0] == 'Y')
             store_host_key(host, port, keytype, keystr);
         else {
             fprintf(stderr, abandoned);
@@ -106,7 +118,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
     }
 }
 
-HANDLE outhandle;
+HANDLE outhandle, errhandle;
 DWORD orig_console_mode;
 
 void begin_session(void) {
@@ -116,17 +128,17 @@ void begin_session(void) {
         SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), orig_console_mode);
 }
 
-void term_out(void)
-{
-    int reap;
+void from_backend(int is_stderr, char *data, int len) {
+    int pos;
     DWORD ret;
-    reap = 0;
-    while (reap < inbuf_head) {
-        if (!WriteFile(outhandle, inbuf+reap, inbuf_head-reap, &ret, NULL))
+    HANDLE h = (is_stderr ? errhandle : outhandle);
+
+    pos = 0;
+    while (pos < len) {
+        if (!WriteFile(h, data+pos, len-pos, &ret, NULL))
             return;                    /* give up in panic */
-        reap += ret;
+        pos += ret;
     }
-    inbuf_head = 0;
 }
 
 struct input_data {
@@ -438,6 +450,7 @@ int main(int argc, char **argv) {
     GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &orig_console_mode);
     SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT);
     outhandle = GetStdHandle(STD_OUTPUT_HANDLE);
+    errhandle = GetStdHandle(STD_ERROR_HANDLE);
 
     /*
      * Now we must send the back end oodles of stuff.
@@ -492,7 +505,6 @@ int main(int argc, char **argv) {
                     break;
                 }
             }
-            term_out();
         } else if (n == 1) {
             if (idata.len > 0) {
                 back->send(idata.buffer, idata.len);
@@ -500,6 +512,8 @@ int main(int argc, char **argv) {
                 back->special(TS_EOF);
             }
         }
+        if (back->socket() == INVALID_SOCKET)
+            break;                 /* we closed the connection */
     }
     WSACleanup();
     return 0;