Replace PuTTY's 2-3-4 tree implementation with the shiny new counted
[u/mdw/putty] / plink.c
diff --git a/plink.c b/plink.c
index 5efcd45..6eb9a78 100644 (file)
--- a/plink.c
+++ b/plink.c
@@ -160,12 +160,12 @@ struct input_data {
     HANDLE event, eventback;
 };
 
-static int get_password(const char *prompt, char *str, int maxlen)
+static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
 {
     HANDLE hin, hout;
-    DWORD savemode, i;
+    DWORD savemode, newmode, i;
 
-    if (password) {
+    if (is_pw && password) {
         static int tried_once = 0;
 
         if (tried_once) {
@@ -186,8 +186,12 @@ static int get_password(const char *prompt, char *str, int maxlen)
     }
 
     GetConsoleMode(hin, &savemode);
-    SetConsoleMode(hin, (savemode & (~ENABLE_ECHO_INPUT)) |
-                   ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT);
+    newmode = savemode | ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT;
+    if (is_pw)
+        newmode &= ~ENABLE_ECHO_INPUT;
+    else
+        newmode |= ENABLE_ECHO_INPUT;
+    SetConsoleMode(hin, newmode);
 
     WriteFile(hout, prompt, strlen(prompt), &i, NULL);
     ReadFile(hin, str, maxlen-1, &i, NULL);
@@ -197,7 +201,8 @@ static int get_password(const char *prompt, char *str, int maxlen)
     if ((int)i > maxlen) i = maxlen-1; else i = i - 2;
     str[i] = '\0';
 
-    WriteFile(hout, "\r\n", 2, &i, NULL);
+    if (is_pw)
+        WriteFile(hout, "\r\n", 2, &i, NULL);
 
     return 1;
 }
@@ -233,6 +238,7 @@ static void usage(void)
     printf("  -ssh      force use of ssh protocol\n");
     printf("  -P port   connect to specified port\n");
     printf("  -pw passw login with specified password\n");
+    printf("  -m file   read remote command(s) from file\n");
     exit(1);
 }
 
@@ -265,7 +271,7 @@ int main(int argc, char **argv) {
     int skcount, sksize;
     int connopen;
 
-    ssh_get_password = get_password;
+    ssh_get_line = get_line;
 
     sklist = NULL; skcount = sksize = 0;
 
@@ -314,6 +320,35 @@ int main(int argc, char **argv) {
                 --argc, username = *++argv;
                 strncpy(cfg.username, username, sizeof(cfg.username));
                 cfg.username[sizeof(cfg.username)-1] = '\0';
+            } else if (!strcmp(p, "-m") && argc > 1) {
+                char *filename, *command;
+                int cmdlen, cmdsize;
+                FILE *fp;
+                int c, d;
+
+                --argc, filename = *++argv;
+
+                cmdlen = cmdsize = 0;
+                command = NULL;
+                fp = fopen(filename, "r");
+                if (!fp) {
+                    fprintf(stderr, "plink: unable to open command "
+                            "file \"%s\"\n", filename);
+                    return 1;
+                }
+                do {
+                    c = fgetc(fp);
+                    d = c;
+                    if (c == EOF)
+                        d = 0;
+                    if (cmdlen >= cmdsize) {
+                        cmdsize = cmdlen + 512;
+                        command = srealloc(command, cmdsize);
+                    }
+                    command[cmdlen++] = d;
+                } while (c != EOF);
+                cfg.remote_cmd_ptr = command;
+                cfg.nopty = TRUE;      /* command => no terminal */
             } else if (!strcmp(p, "-P") && argc > 1) {
                 --argc, portnumber = atoi(*++argv);
             }
@@ -388,8 +423,10 @@ int main(int argc, char **argv) {
                             strncpy(cfg.host, p, sizeof(cfg.host)-1);
                             cfg.host[sizeof(cfg.host)-1] = '\0';
                             cfg.port = default_port;
-                        } else
+                        } else {
                             cfg = cfg2;
+                            cfg.remote_cmd_ptr = cfg.remote_cmd;
+                        }
                     } else {
                         *r++ = '\0';
                         strncpy(cfg.username, p, sizeof(cfg.username)-1);
@@ -422,7 +459,7 @@ int main(int argc, char **argv) {
         usage();
     }
 
-    if (!*cfg.remote_cmd)
+    if (!*cfg.remote_cmd_ptr)
         flags |= FLAG_INTERACTIVE;
 
     /*
@@ -531,11 +568,10 @@ int main(int argc, char **argv) {
         n = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
         if (n == 0) {
             WSANETWORKEVENTS things;
-           enum234 e;
            SOCKET socket;
-           extern SOCKET first_socket(enum234 *), next_socket(enum234 *);
+           extern SOCKET first_socket(int *), next_socket(int *);
            extern int select_result(WPARAM, LPARAM);
-            int i;
+            int i, socketstate;
 
             /*
              * We must not call select_result() for any socket
@@ -545,8 +581,8 @@ int main(int argc, char **argv) {
              */
             /* Count the active sockets. */
             i = 0;
-            for (socket = first_socket(&e); socket != INVALID_SOCKET;
-                socket = next_socket(&e))
+            for (socket = first_socket(&socketstate); socket != INVALID_SOCKET;
+                socket = next_socket(&socketstate))
                 i++;
 
             /* Expand the buffer if necessary. */
@@ -557,8 +593,8 @@ int main(int argc, char **argv) {
 
             /* Retrieve the sockets into sklist. */
             skcount = 0;
-           for (socket = first_socket(&e); socket != INVALID_SOCKET;
-                socket = next_socket(&e)) {
+           for (socket = first_socket(&socketstate); socket != INVALID_SOCKET;
+                socket = next_socket(&socketstate)) {
                 sklist[skcount++] = socket;
             }