X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=windows%2Fwinplink.c;h=ac4dab299fe19ffb0bb5de3f268da1b904feab7f;hb=21101c7397e460933635a7bfed813864fc4f88fe;hp=58063352745dbaf7a3e98d779c6ce6f79fa5bc14;hpb=947962e0b95e10151c186048a8b5cc2fb425838c;p=PuTTY.git diff --git a/windows/winplink.c b/windows/winplink.c index 58063352..ac4dab29 100644 --- a/windows/winplink.c +++ b/windows/winplink.c @@ -21,7 +21,7 @@ struct agent_callback { int len; }; -void fatalbox(char *p, ...) +void fatalbox(const char *p, ...) { va_list ap; fprintf(stderr, "FATAL ERROR: "); @@ -35,7 +35,7 @@ void fatalbox(char *p, ...) } cleanup_exit(1); } -void modalfatalbox(char *p, ...) +void modalfatalbox(const char *p, ...) { va_list ap; fprintf(stderr, "FATAL ERROR: "); @@ -49,7 +49,16 @@ void modalfatalbox(char *p, ...) } cleanup_exit(1); } -void connection_fatal(void *frontend, char *p, ...) +void nonfatal(const char *p, ...) +{ + va_list ap; + fprintf(stderr, "ERROR: "); + va_start(ap, p); + vfprintf(stderr, p, ap); + va_end(ap); + fputc('\n', stderr); +} +void connection_fatal(void *frontend, const char *p, ...) { va_list ap; fprintf(stderr, "FATAL ERROR: "); @@ -63,7 +72,7 @@ void connection_fatal(void *frontend, char *p, ...) } cleanup_exit(1); } -void cmdline_error(char *p, ...) +void cmdline_error(const char *p, ...) { va_list ap; fprintf(stderr, "plink: "); @@ -89,7 +98,7 @@ int term_ldisc(Terminal *term, int mode) { return FALSE; } -void ldisc_update(void *frontend, int echo, int edit) +void frontend_echoedit_update(void *frontend, int echo, int edit) { /* Update stdin read mode to reflect changes in line discipline. */ DWORD mode; @@ -136,7 +145,7 @@ int from_backend_eof(void *frontend_handle) return FALSE; /* do not respond to incoming EOF with outgoing */ } -int get_userpass_input(prompts_t *p, unsigned char *in, int inlen) +int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen) { int ret; ret = cmdline_get_passwd_input(p, in, inlen); @@ -163,7 +172,7 @@ void agent_schedule_callback(void (*callback)(void *, void *, int), */ static void usage(void) { - printf("PuTTY Link: command-line connection utility\n"); + printf("Plink: 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"); @@ -177,6 +186,8 @@ static void usage(void) printf(" -P port connect to specified port\n"); printf(" -l user connect with specified username\n"); printf(" -batch disable all interactive prompts\n"); + printf(" -sercfg configuration-string (e.g. 19200,8,n,1,X)\n"); + printf(" Specify the serial configuration (serial only)\n"); printf("The following options only apply to SSH connections:\n"); printf(" -pw passw login with specified password\n"); printf(" -D [listen-IP:]listen-port\n"); @@ -191,16 +202,21 @@ static void usage(void) printf(" -1 -2 force use of particular protocol version\n"); printf(" -4 -6 force use of IPv4 or IPv6\n"); printf(" -C enable compression\n"); - printf(" -i key private key file for authentication\n"); + printf(" -i key private key file for user authentication\n"); printf(" -noagent disable use of Pageant\n"); printf(" -agent enable use of Pageant\n"); + printf(" -hostkey aa:bb:cc:...\n"); + printf(" manually specify a host key (may be repeated)\n"); 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"); + printf(" -sshlog file\n"); + printf(" -sshrawlog file\n"); + printf(" log protocol details to a file\n"); + printf(" -shareexists\n"); + printf(" test whether a connection-sharing upstream exists\n"); exit(1); } @@ -279,6 +295,9 @@ void stdouterr_sent(struct handle *h, int new_backlog) } } +const int share_can_be_downstream = TRUE; +const int share_can_be_upstream = TRUE; + int main(int argc, char **argv) { int sending; @@ -289,7 +308,8 @@ int main(int argc, char **argv) int errors; int got_host = FALSE; int use_subsystem = 0; - long now, next; + int just_test_share_exists = FALSE; + unsigned long now, next, then; sklist = NULL; skcount = sksize = 0; @@ -343,11 +363,15 @@ int main(int argc, char **argv) } else if (!strcmp(p, "-s")) { /* 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); + } else if (!strcmp(p, "-shareexists")) { + just_test_share_exists = TRUE; } else { fprintf(stderr, "plink: unknown option \"%s\"\n", p); errors = 1; @@ -368,8 +392,7 @@ int main(int argc, char **argv) q += 2; conf_set_int(conf, CONF_protocol, PROT_TELNET); p = q; - while (*p && *p != ':' && *p != '/') - p++; + p += host_strcspn(p, ":/"); c = *p; if (*p) *p++ = '\0'; @@ -507,10 +530,21 @@ int main(int argc, char **argv) } } - /* - * Trim off a colon suffix if it's there. - */ - host[strcspn(host, ":")] = '\0'; + /* + * Trim a colon suffix off the hostname if it's there. In + * order to protect unbracketed IPv6 address literals + * against this treatment, we do not do this if there's + * _more_ than one colon. + */ + { + char *c = host_strchr(host, ':'); + + if (c) { + char *d = host_strchr(c+1, ':'); + if (!d) + *c = '\0'; + } + } /* * Remove any remaining whitespace. @@ -570,6 +604,19 @@ int main(int argc, char **argv) logctx = log_init(NULL, conf); console_provide_logctx(logctx); + if (just_test_share_exists) { + if (!back->test_for_upstream) { + fprintf(stderr, "Connection sharing not supported for connection " + "type '%s'\n", back->name); + return 1; + } + if (back->test_for_upstream(conf_get_str(conf, CONF_host), + conf_get_int(conf, CONF_port), conf)) + return 0; + else + return 1; + } + /* * Start up the connection. */ @@ -633,11 +680,20 @@ int main(int argc, char **argv) sending = TRUE; } - if (run_timers(now, &next)) { - ticks = next - GETTICKCOUNT(); - if (ticks < 0) ticks = 0; /* just in case */ + if (toplevel_callback_pending()) { + ticks = 0; + next = now; + } else if (run_timers(now, &next)) { + then = now; + now = GETTICKCOUNT(); + if (now - then > next - then) + ticks = 0; + else + ticks = next - now; } else { ticks = INFINITE; + /* no need to initialise next here because we can never + * get WAIT_TIMEOUT */ } handles = handle_get_events(&nhandles); @@ -719,6 +775,8 @@ int main(int argc, char **argv) } } + run_toplevel_callbacks(); + if (n == WAIT_TIMEOUT) { now = next; } else {