The other utilities should do the same processing of the hostname
[u/mdw/putty] / plink.c
diff --git a/plink.c b/plink.c
index 4217116..1b742ce 100644 (file)
--- a/plink.c
+++ b/plink.c
@@ -122,6 +122,46 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
     }
 }
 
+/*
+ * Ask whether the selected cipher is acceptable (since it was
+ * below the configured 'warn' threshold).
+ * cs: 0 = both ways, 1 = client->server, 2 = server->client
+ */
+void askcipher(char *ciphername, int cs)
+{
+    HANDLE hin;
+    DWORD savemode, i;
+
+    static const char msg[] =
+       "The first %scipher supported by the server is\n"
+       "%s, which is below the configured warning threshold.\n"
+       "Continue with connection? (y/n) ";
+    static const char abandoned[] = "Connection abandoned.\n";
+
+    char line[32];
+
+    fprintf(stderr, msg,
+           (cs == 0) ? "" :
+           (cs == 1) ? "client-to-server " :
+                       "server-to-client ",
+           ciphername);
+    fflush(stderr);
+
+    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 (line[0] == 'y' || line[0] == 'Y') {
+       return;
+    } else {
+       fprintf(stderr, abandoned);
+       exit(0);
+    }
+}
+
 HANDLE inhandle, outhandle, errhandle;
 DWORD orig_console_mode;
 
@@ -274,11 +314,7 @@ void try_output(int is_stderr)
 
 int from_backend(int is_stderr, char *data, int len)
 {
-    int pos;
-    DWORD ret;
     HANDLE h = (is_stderr ? errhandle : outhandle);
-    void *writedata;
-    int writelen;
     int osize, esize;
 
     if (is_stderr) {
@@ -303,6 +339,7 @@ static void usage(void)
     printf("PuTTY Link: command-line connection utility\n");
     printf("%s\n", ver);
     printf("Usage: plink [options] [user@]host [command]\n");
+    printf("       (\"host\" can also be a PuTTY saved session name)\n");
     printf("Options:\n");
     printf("  -v        show verbose messages\n");
     printf("  -ssh      force use of ssh protocol\n");
@@ -316,7 +353,8 @@ char *do_select(SOCKET skt, int startup)
 {
     int events;
     if (startup) {
-       events = FD_READ | FD_WRITE | FD_OOB | FD_CLOSE | FD_ACCEPT;
+       events = (FD_CONNECT | FD_READ | FD_WRITE |
+                 FD_OOB | FD_CLOSE | FD_ACCEPT);
     } else {
        events = 0;
     }
@@ -431,6 +469,7 @@ int main(int argc, char **argv)
                    command[cmdlen++] = d;
                } while (c != EOF);
                cfg.remote_cmd_ptr = command;
+               cfg.remote_cmd_ptr2 = NULL;
                cfg.nopty = TRUE;      /* command => no terminal */
            } else if (!strcmp(p, "-P") && argc > 1) {
                --argc, portnumber = atoi(*++argv);
@@ -552,6 +591,32 @@ int main(int argc, char **argv)
        usage();
     }
 
+    /*
+     * Trim leading whitespace off the hostname if it's there.
+     */
+    {
+       int space = strspn(cfg.host, " \t");
+       memmove(cfg.host, cfg.host+space, 1+strlen(cfg.host)-space);
+    }
+
+    /* See if host is of the form user@host */
+    if (cfg.host[0] != '\0') {
+       char *atsign = strchr(cfg.host, '@');
+       /* Make sure we're not overflowing the user field */
+       if (atsign) {
+           if (atsign - cfg.host < sizeof cfg.username) {
+               strncpy(cfg.username, cfg.host, atsign - cfg.host);
+               cfg.username[atsign - cfg.host] = '\0';
+           }
+           memmove(cfg.host, atsign + 1, 1 + strlen(atsign + 1));
+       }
+    }
+
+    /*
+     * Trim a colon suffix off the hostname if it's there.
+     */
+    cfg.host[strcspn(cfg.host, ":")] = '\0';
+
     if (!*cfg.remote_cmd_ptr)
        flags |= FLAG_INTERACTIVE;
 
@@ -730,6 +795,8 @@ int main(int argc, char **argv)
                if (!WSAEnumNetworkEvents(socket, NULL, &things)) {
                    noise_ultralight(socket);
                    noise_ultralight(things.lNetworkEvents);
+                   if (things.lNetworkEvents & FD_CONNECT)
+                       connopen &= select_result(wp, (LPARAM) FD_CONNECT);
                    if (things.lNetworkEvents & FD_READ)
                        connopen &= select_result(wp, (LPARAM) FD_READ);
                    if (things.lNetworkEvents & FD_CLOSE)
@@ -746,10 +813,12 @@ int main(int argc, char **argv)
        } else if (n == 1) {
            reading = 0;
            noise_ultralight(idata.len);
-           if (idata.len > 0) {
-               back->send(idata.buffer, idata.len);
-           } else {
-               back->special(TS_EOF);
+           if (connopen && back->socket() != NULL) {
+               if (idata.len > 0) {
+                   back->send(idata.buffer, idata.len);
+               } else {
+                   back->special(TS_EOF);
+               }
            }
        } else if (n == 2) {
            odata.busy = 0;
@@ -760,8 +829,10 @@ int main(int argc, char **argv)
            bufchain_consume(&stdout_data, odata.lenwritten);
            if (bufchain_size(&stdout_data) > 0)
                try_output(0);
-           back->unthrottle(bufchain_size(&stdout_data) +
-                            bufchain_size(&stderr_data));
+           if (connopen && back->socket() != NULL) {
+               back->unthrottle(bufchain_size(&stdout_data) +
+                                bufchain_size(&stderr_data));
+           }
        } else if (n == 3) {
            edata.busy = 0;
            if (!edata.writeret) {
@@ -771,14 +842,18 @@ int main(int argc, char **argv)
            bufchain_consume(&stderr_data, edata.lenwritten);
            if (bufchain_size(&stderr_data) > 0)
                try_output(1);
-           back->unthrottle(bufchain_size(&stdout_data) +
-                            bufchain_size(&stderr_data));
+           if (connopen && back->socket() != NULL) {
+               back->unthrottle(bufchain_size(&stdout_data) +
+                                bufchain_size(&stderr_data));
+           }
        }
        if (!reading && back->sendbuffer() < MAX_STDIN_BACKLOG) {
            SetEvent(idata.eventback);
            reading = 1;
        }
-       if (!connopen || back->socket() == NULL)
+       if ((!connopen || back->socket() == NULL) &&
+           bufchain_size(&stdout_data) == 0 &&
+           bufchain_size(&stderr_data) == 0)
            break;                     /* we closed the connection */
     }
     WSACleanup();