X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/34292b1daab0fcd6ce02627497117d01aaa39a19..13874a7c4dd056a4db43fb60075075fc73d8abc4:/windows/winplink.c diff --git a/windows/winplink.c b/windows/winplink.c index 4ef2c980..bc2e674a 100644 --- a/windows/winplink.c +++ b/windows/winplink.c @@ -29,6 +29,10 @@ void fatalbox(char *p, ...) vfprintf(stderr, p, ap); va_end(ap); fputc('\n', stderr); + if (logctx) { + log_free(logctx); + logctx = NULL; + } cleanup_exit(1); } void modalfatalbox(char *p, ...) @@ -39,6 +43,10 @@ void modalfatalbox(char *p, ...) vfprintf(stderr, p, ap); va_end(ap); fputc('\n', stderr); + if (logctx) { + log_free(logctx); + logctx = NULL; + } cleanup_exit(1); } void connection_fatal(void *frontend, char *p, ...) @@ -49,6 +57,10 @@ void connection_fatal(void *frontend, char *p, ...) vfprintf(stderr, p, ap); va_end(ap); fputc('\n', stderr); + if (logctx) { + log_free(logctx); + logctx = NULL; + } cleanup_exit(1); } void cmdline_error(char *p, ...) @@ -154,7 +166,7 @@ static void usage(void) printf(" -pgpfp print PGP key fingerprints and exit\n"); printf(" -v show verbose messages\n"); printf(" -load sessname Load settings from saved session\n"); - printf(" -ssh -telnet -rlogin -raw\n"); + printf(" -ssh -telnet -rlogin -raw -serial\n"); printf(" force use of a particular protocol\n"); printf(" -P port connect to specified port\n"); printf(" -l user connect with specified username\n"); @@ -179,6 +191,10 @@ static void usage(void) printf(" -m file read remote command(s) from file\n"); printf(" -s remote command is an SSH subsystem (SSH-2 only)\n"); printf(" -N don't start a shell/command (SSH-2 only)\n"); + printf(" -nc host:port\n"); + printf(" open tunnel in place of session (SSH-2 only)\n"); + printf(" -sercfg configuration-string (e.g. 19200,8,n,1,X)\n"); + printf(" Specify the serial configuration (serial only)\n"); exit(1); } @@ -214,11 +230,17 @@ int stdin_gotdata(struct handle *h, void *data, int len) /* * Special case: report read error. */ - fprintf(stderr, "Unable to read from standard input\n"); + char buf[4096]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, -len, 0, + buf, lenof(buf), NULL); + buf[lenof(buf)-1] = '\0'; + if (buf[strlen(buf)-1] == '\n') + buf[strlen(buf)-1] = '\0'; + fprintf(stderr, "Unable to read from standard input: %s\n", buf); cleanup_exit(0); } noise_ultralight(len); - if (connopen && back->socket(backhandle) != NULL) { + if (connopen && back->connected(backhandle)) { if (len > 0) { return back->send(backhandle, data, len); } else { @@ -235,11 +257,17 @@ void stdouterr_sent(struct handle *h, int new_backlog) /* * Special case: report write error. */ - fprintf(stderr, "Unable to write to standard %s\n", - (h == stdout_handle ? "output" : "error")); + char buf[4096]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, -new_backlog, 0, + buf, lenof(buf), NULL); + buf[lenof(buf)-1] = '\0'; + if (buf[strlen(buf)-1] == '\n') + buf[strlen(buf)-1] = '\0'; + fprintf(stderr, "Unable to write to standard %s: %s\n", + (h == stdout_handle ? "output" : "error"), buf); cleanup_exit(0); } - if (connopen && back->socket(backhandle) != NULL) { + if (connopen && back->connected(backhandle)) { back->unthrottle(backhandle, (handle_backlog(stdout_handle) + handle_backlog(stderr_handle))); } @@ -279,15 +307,11 @@ int main(int argc, char **argv) * Override the default protocol if PLINK_PROTOCOL is set. */ char *p = getenv("PLINK_PROTOCOL"); - int i; if (p) { - for (i = 0; backends[i].backend != NULL; i++) { - if (!strcmp(backends[i].name, p)) { - default_protocol = cfg.protocol = backends[i].protocol; - default_port = cfg.port = - backends[i].backend->default_port; - break; - } + const Backend *b = backend_from_name(p); + if (b) { + default_protocol = cfg.protocol = b->protocol; + default_port = cfg.port = b->default_port; } } } @@ -319,7 +343,7 @@ int main(int argc, char **argv) errors = 1; } } else if (*p) { - if (!*cfg.host) { + if (!cfg_launchable(&cfg)) { char *q = p; /* * If the hostname starts with "telnet:", set the @@ -354,19 +378,14 @@ int main(int argc, char **argv) */ r = strchr(p, ','); if (r) { - int i, j; - for (i = 0; backends[i].backend != NULL; i++) { - j = strlen(backends[i].name); - if (j == r - p && - !memcmp(backends[i].name, p, j)) { - default_protocol = cfg.protocol = - backends[i].protocol; - portnumber = - backends[i].backend->default_port; - p = r + 1; - break; - } + const Backend *b; + *r = '\0'; + b = backend_from_name(p); + if (b) { + default_protocol = cfg.protocol = b->protocol; + portnumber = b->default_port; } + p = r + 1; } /* @@ -392,7 +411,7 @@ int main(int argc, char **argv) { Config cfg2; do_defaults(host, &cfg2); - if (loaded_session || cfg2.host[0] == '\0') { + if (loaded_session || !cfg_launchable(&cfg2)) { /* No settings for this host; use defaults */ /* (or session was already loaded with -load) */ strncpy(cfg.host, host, sizeof(cfg.host) - 1); @@ -446,7 +465,7 @@ int main(int argc, char **argv) if (errors) return 1; - if (!*cfg.host) { + if (!cfg_launchable(&cfg)) { usage(); } @@ -459,7 +478,7 @@ int main(int argc, char **argv) } /* See if host is of the form user@host */ - if (cfg.host[0] != '\0') { + if (cfg_launchable(&cfg)) { char *atsign = strrchr(cfg.host, '@'); /* Make sure we're not overflowing the user field */ if (atsign) { @@ -502,26 +521,18 @@ int main(int argc, char **argv) cfg.host[p1] = '\0'; } - if (!cfg.remote_cmd_ptr && !*cfg.remote_cmd) + if (!cfg.remote_cmd_ptr && !*cfg.remote_cmd && !*cfg.ssh_nc_host) flags |= FLAG_INTERACTIVE; /* * Select protocol. This is farmed out into a table in a * separate file to enable an ssh-free variant. */ - { - int i; - back = NULL; - for (i = 0; backends[i].backend != NULL; i++) - if (backends[i].protocol == cfg.protocol) { - back = backends[i].backend; - break; - } - if (back == NULL) { - fprintf(stderr, - "Internal fault: Unsupported protocol found\n"); - return 1; - } + back = backend_from_proto(cfg.protocol); + if (back == NULL) { + fprintf(stderr, + "Internal fault: Unsupported protocol found\n"); + return 1; } /* @@ -536,6 +547,9 @@ int main(int argc, char **argv) return 1; } + logctx = log_init(NULL, &cfg); + console_provide_logctx(logctx); + /* * Start up the connection. */ @@ -553,9 +567,7 @@ int main(int argc, char **argv) fprintf(stderr, "Unable to open connection:\n%s", error); return 1; } - logctx = log_init(NULL, &cfg); back->provide_logctx(backhandle, logctx); - console_provide_logctx(logctx); sfree(realhost); } connopen = 1; @@ -577,8 +589,8 @@ int main(int argc, char **argv) * (The input one we leave until we're through the * authentication process.) */ - stdout_handle = handle_output_new(outhandle, stdouterr_sent); - stderr_handle = handle_output_new(errhandle, stdouterr_sent); + stdout_handle = handle_output_new(outhandle, stdouterr_sent, NULL, 0); + stderr_handle = handle_output_new(errhandle, stdouterr_sent, NULL, 0); main_thread_id = GetCurrentThreadId(); @@ -593,7 +605,8 @@ int main(int argc, char **argv) DWORD ticks; if (!sending && back->sendok(backhandle)) { - stdin_handle = handle_input_new(inhandle, stdin_gotdata); + stdin_handle = handle_input_new(inhandle, stdin_gotdata, NULL, + 0); sending = TRUE; } @@ -694,7 +707,7 @@ int main(int argc, char **argv) if (sending) handle_unthrottle(stdin_handle, back->sendbuffer(backhandle)); - if ((!connopen || back->socket(backhandle) == NULL) && + if ((!connopen || !back->connected(backhandle)) && handle_backlog(stdout_handle) + handle_backlog(stderr_handle) == 0) break; /* we closed the connection */ }