X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/f0f51e90dcb84e35046dd6683e29f15336a429fb..33f4bde27b629068d4a17ca54d67ac54fc70c10c:/windows/winplink.c diff --git a/windows/winplink.c b/windows/winplink.c index 7eb3aec1..37453bb7 100644 --- a/windows/winplink.c +++ b/windows/winplink.c @@ -49,6 +49,19 @@ void modalfatalbox(char *p, ...) } cleanup_exit(1); } +void nonfatal(char *p, ...) +{ + va_list ap; + fprintf(stderr, "ERROR: "); + va_start(ap, p); + vfprintf(stderr, p, ap); + va_end(ap); + fputc('\n', stderr); + if (logctx) { + log_free(logctx); + logctx = NULL; + } +} void connection_fatal(void *frontend, char *p, ...) { va_list ap; @@ -83,7 +96,7 @@ WSAEVENT netevent; static Backend *back; static void *backhandle; -static Config cfg; +static Conf *conf; int term_ldisc(Terminal *term, int mode) { @@ -130,6 +143,12 @@ int from_backend_untrusted(void *frontend_handle, const char *data, int len) return 0; /* not reached */ } +int from_backend_eof(void *frontend_handle) +{ + handle_write_eof(stdout_handle); + return FALSE; /* do not respond to incoming EOF with outgoing */ +} + int get_userpass_input(prompts_t *p, unsigned char *in, int inlen) { int ret; @@ -283,7 +302,7 @@ int main(int argc, char **argv) int errors; int got_host = FALSE; int use_subsystem = 0; - long now, next; + unsigned long now, next, then; sklist = NULL; skcount = sksize = 0; @@ -298,10 +317,11 @@ int main(int argc, char **argv) /* * Process the command line. */ - do_defaults(NULL, &cfg); + conf = conf_new(); + do_defaults(NULL, conf); loaded_session = FALSE; - default_protocol = cfg.protocol; - default_port = cfg.port; + default_protocol = conf_get_int(conf, CONF_protocol); + default_port = conf_get_int(conf, CONF_port); errors = 0; { /* @@ -311,8 +331,10 @@ int main(int argc, char **argv) if (p) { const Backend *b = backend_from_name(p); if (b) { - default_protocol = cfg.protocol = b->protocol; - default_port = cfg.port = b->default_port; + default_protocol = b->protocol; + default_port = b->default_port; + conf_set_int(conf, CONF_protocol, default_protocol); + conf_set_int(conf, CONF_port, default_port); } } } @@ -320,7 +342,7 @@ int main(int argc, char **argv) char *p = *++argv; if (*p == '-') { int ret = cmdline_process_param(p, (argc > 1 ? argv[1] : NULL), - 1, &cfg); + 1, conf); if (ret == -2) { fprintf(stderr, "plink: option \"%s\" requires an argument\n", p); @@ -332,10 +354,12 @@ int main(int argc, char **argv) } else if (!strcmp(p, "-batch")) { console_batch_mode = 1; } else if (!strcmp(p, "-s")) { - /* Save status to write to cfg later. */ + /* Save status to write to conf later. */ use_subsystem = 1; - } else if (!strcmp(p, "-V")) { + } else if (!strcmp(p, "-V") || !strcmp(p, "--version")) { version(); + } else if (!strcmp(p, "--help")) { + usage(); } else if (!strcmp(p, "-pgpfp")) { pgp_fingerprints(); exit(1); @@ -344,7 +368,7 @@ int main(int argc, char **argv) errors = 1; } } else if (*p) { - if (!cfg_launchable(&cfg) || !(got_host || loaded_session)) { + if (!conf_launchable(conf) || !(got_host || loaded_session)) { char *q = p; /* * If the hostname starts with "telnet:", set the @@ -357,7 +381,7 @@ int main(int argc, char **argv) q += 7; if (q[0] == '/' && q[1] == '/') q += 2; - cfg.protocol = PROT_TELNET; + conf_set_int(conf, CONF_protocol, PROT_TELNET); p = q; while (*p && *p != ':' && *p != '/') p++; @@ -365,11 +389,10 @@ int main(int argc, char **argv) if (*p) *p++ = '\0'; if (c == ':') - cfg.port = atoi(p); + conf_set_int(conf, CONF_port, atoi(p)); else - cfg.port = -1; - strncpy(cfg.host, q, sizeof(cfg.host) - 1); - cfg.host[sizeof(cfg.host) - 1] = '\0'; + conf_set_int(conf, CONF_port, -1); + conf_set_str(conf, CONF_host, q); got_host = TRUE; } else { char *r, *user, *host; @@ -384,7 +407,9 @@ int main(int argc, char **argv) *r = '\0'; b = backend_from_name(p); if (b) { - default_protocol = cfg.protocol = b->protocol; + default_protocol = b->protocol; + conf_set_int(conf, CONF_protocol, + default_protocol); portnumber = b->default_port; } p = r + 1; @@ -411,26 +436,24 @@ int main(int argc, char **argv) * same name as the hostname. */ { - Config cfg2; - do_defaults(host, &cfg2); - if (loaded_session || !cfg_launchable(&cfg2)) { + Conf *conf2 = conf_new(); + do_defaults(host, conf2); + if (loaded_session || !conf_launchable(conf2)) { /* No settings for this host; use defaults */ /* (or session was already loaded with -load) */ - strncpy(cfg.host, host, sizeof(cfg.host) - 1); - cfg.host[sizeof(cfg.host) - 1] = '\0'; - cfg.port = default_port; + conf_set_str(conf, CONF_host, host); + conf_set_int(conf, CONF_port, default_port); got_host = TRUE; } else { - cfg = cfg2; + conf_copy_into(conf, conf2); loaded_session = TRUE; } + conf_free(conf2); } if (user) { /* Patch in specified username. */ - strncpy(cfg.username, user, - sizeof(cfg.username) - 1); - cfg.username[sizeof(cfg.username) - 1] = '\0'; + conf_set_str(conf, CONF_username, user); } } @@ -457,9 +480,9 @@ int main(int argc, char **argv) } if (cmdlen) command[--cmdlen]='\0'; /* change trailing blank to NUL */ - cfg.remote_cmd_ptr = command; - cfg.remote_cmd_ptr2 = NULL; - cfg.nopty = TRUE; /* command => no terminal */ + conf_set_str(conf, CONF_remote_cmd, command); + conf_set_str(conf, CONF_remote_cmd2, ""); + conf_set_int(conf, CONF_nopty, TRUE); /* command => no tty */ break; /* done with cmdline */ } @@ -469,70 +492,78 @@ int main(int argc, char **argv) if (errors) return 1; - if (!cfg_launchable(&cfg) || !(got_host || loaded_session)) { + if (!conf_launchable(conf) || !(got_host || loaded_session)) { usage(); } /* - * Trim leading whitespace off the hostname if it's there. + * Muck about with the hostname in various ways. */ { - int space = strspn(cfg.host, " \t"); - memmove(cfg.host, cfg.host+space, 1+strlen(cfg.host)-space); - } + char *hostbuf = dupstr(conf_get_str(conf, CONF_host)); + char *host = hostbuf; + char *p, *q; - /* See if host is of the form user@host */ - if (cfg_launchable(&cfg)) { - char *atsign = strrchr(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'; + /* + * Trim leading whitespace. + */ + host += strspn(host, " \t"); + + /* + * See if host is of the form user@host, and separate out + * the username if so. + */ + if (host[0] != '\0') { + char *atsign = strrchr(host, '@'); + if (atsign) { + *atsign = '\0'; + conf_set_str(conf, CONF_username, host); + host = atsign + 1; } - memmove(cfg.host, atsign + 1, 1 + strlen(atsign + 1)); } + + /* + * Trim off a colon suffix if it's there. + */ + host[strcspn(host, ":")] = '\0'; + + /* + * Remove any remaining whitespace. + */ + p = hostbuf; + q = host; + while (*q) { + if (*q != ' ' && *q != '\t') + *p++ = *q; + q++; + } + *p = '\0'; + + conf_set_str(conf, CONF_host, hostbuf); + sfree(hostbuf); } /* * Perform command-line overrides on session configuration. */ - cmdline_run_saved(&cfg); + cmdline_run_saved(conf); /* * Apply subsystem status. */ if (use_subsystem) - cfg.ssh_subsys = TRUE; + conf_set_int(conf, CONF_ssh_subsys, TRUE); - /* - * Trim a colon suffix off the hostname if it's there. - */ - cfg.host[strcspn(cfg.host, ":")] = '\0'; - - /* - * Remove any remaining whitespace from the hostname. - */ - { - int p1 = 0, p2 = 0; - while (cfg.host[p2] != '\0') { - if (cfg.host[p2] != ' ' && cfg.host[p2] != '\t') { - cfg.host[p1] = cfg.host[p2]; - p1++; - } - p2++; - } - cfg.host[p1] = '\0'; - } - - if (!cfg.remote_cmd_ptr && !*cfg.remote_cmd && !*cfg.ssh_nc_host) + if (!*conf_get_str(conf, CONF_remote_cmd) && + !*conf_get_str(conf, CONF_remote_cmd2) && + !*conf_get_str(conf, CONF_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. */ - back = backend_from_proto(cfg.protocol); + back = backend_from_proto(conf_get_int(conf, CONF_protocol)); if (back == NULL) { fprintf(stderr, "Internal fault: Unsupported protocol found\n"); @@ -543,7 +574,7 @@ int main(int argc, char **argv) * Select port. */ if (portnumber != -1) - cfg.port = portnumber; + conf_set_int(conf, CONF_port, portnumber); sk_init(); if (p_WSAEventSelect == NULL) { @@ -551,7 +582,7 @@ int main(int argc, char **argv) return 1; } - logctx = log_init(NULL, &cfg); + logctx = log_init(NULL, conf); console_provide_logctx(logctx); /* @@ -562,11 +593,14 @@ int main(int argc, char **argv) const char *error; char *realhost; /* nodelay is only useful if stdin is a character device (console) */ - int nodelay = cfg.tcp_nodelay && + int nodelay = conf_get_int(conf, CONF_tcp_nodelay) && (GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR); - error = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, - &realhost, nodelay, cfg.tcp_keepalives); + error = back->init(NULL, &backhandle, conf, + conf_get_str(conf, CONF_host), + conf_get_int(conf, CONF_port), + &realhost, nodelay, + conf_get_int(conf, CONF_tcp_keepalives)); if (error) { fprintf(stderr, "Unable to open connection:\n%s", error); return 1; @@ -615,8 +649,12 @@ int main(int argc, char **argv) } if (run_timers(now, &next)) { - ticks = next - GETTICKCOUNT(); - if (ticks < 0) ticks = 0; /* just in case */ + then = now; + now = GETTICKCOUNT(); + if (now - then > next - then) + ticks = 0; + else + ticks = next - now; } else { ticks = INFINITE; }