X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/984992ef01577c0c12cdb5f404ea91d3954264ae..5a9eb1056517b6ee6efa526a3a6b5a21aa802648:/unix/uxplink.c diff --git a/unix/uxplink.c b/unix/uxplink.c index 453a9f41..a005ce6d 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include /* More helpful version of the FD_SET macro, to also handle maxfd. */ #define FD_SET_MAX(fd, max, set) do { \ @@ -69,6 +71,68 @@ struct termios orig_termios; static Backend *back; static void *backhandle; +/* + * Default settings that are specific to pterm. + */ +char *platform_default_s(char *name) +{ + if (!strcmp(name, "X11Display")) + return getenv("DISPLAY"); + if (!strcmp(name, "TermType")) + return getenv("TERM"); + if (!strcmp(name, "UserName")) { + /* + * Remote login username will default to the local username. + */ + struct passwd *p; + uid_t uid = getuid(); + char *user, *ret = NULL; + + /* + * First, find who we think we are using getlogin. If this + * agrees with our uid, we'll go along with it. This should + * allow sharing of uids between several login names whilst + * coping correctly with people who have su'ed. + */ + user = getlogin(); + setpwent(); + if (user) + p = getpwnam(user); + else + p = NULL; + if (p && p->pw_uid == uid) { + /* + * The result of getlogin() really does correspond to + * our uid. Fine. + */ + ret = user; + } else { + /* + * If that didn't work, for whatever reason, we'll do + * the simpler version: look up our uid in the password + * file and map it straight to a name. + */ + p = getpwuid(uid); + ret = p->pw_name; + } + endpwent(); + + return ret; + } + return NULL; +} + +int platform_default_i(char *name, int def) +{ + if (!strcmp(name, "TermWidth") || + !strcmp(name, "TermHeight")) { + struct winsize size; + if (ioctl(0, TIOCGWINSZ, (void *)&size) >= 0) + return (!strcmp(name, "TermWidth") ? size.ws_col : size.ws_row); + } + return def; +} + char *x_get_default(char *key) { return NULL; /* this is a stub */ @@ -111,6 +175,9 @@ void try_output(int is_stderr) void *senddata; int sendlen, ret; + if (bufchain_size(chain) == 0) + return; + bufchain_prefix(chain, &senddata, &sendlen); ret = write(fd, senddata, sendlen); if (ret > 0) @@ -183,7 +250,7 @@ int main(int argc, char **argv) int i, skcount, sksize, socketstate; int connopen; int exitcode; - void *logctx; + int errors; void *ldisc; ssh_get_line = console_get_line; @@ -204,6 +271,7 @@ int main(int argc, char **argv) do_defaults(NULL, &cfg); default_protocol = cfg.protocol; default_port = cfg.port; + errors = 0; { /* * Override the default protocol if PLINK_PROTOCOL is set. @@ -228,16 +296,32 @@ int main(int argc, char **argv) if (ret == -2) { fprintf(stderr, "plink: option \"%s\" requires an argument\n", p); + errors = 1; } else if (ret == 2) { --argc, ++argv; } else if (ret == 1) { continue; } else if (!strcmp(p, "-batch")) { console_batch_mode = 1; + } else if (!strcmp(p, "-o")) { + if (argc <= 1) { + fprintf(stderr, + "plink: option \"-o\" requires an argument\n"); + errors = 1; + } else { + --argc; + provide_xrm_string(*++argv); + } + } else { + fprintf(stderr, "plink: unknown option \"%s\"\n", p); + errors = 1; } } else if (*p) { if (!*cfg.host) { char *q = p; + + do_defaults(NULL, &cfg); + /* * If the hostname starts with "telnet:", set the * protocol to Telnet and process the string as a @@ -355,6 +439,9 @@ int main(int argc, char **argv) } } + if (errors) + return 1; + if (!*cfg.host) { usage(); } @@ -438,6 +525,7 @@ int main(int argc, char **argv) /* * Start up the connection. */ + logctx = log_init(NULL); { char *error; char *realhost; @@ -450,9 +538,8 @@ int main(int argc, char **argv) fprintf(stderr, "Unable to open connection:\n%s\n", error); return 1; } - logctx = log_init(NULL); back->provide_logctx(backhandle, logctx); - ldisc = ldisc_create(NULL, back, backhandle, NULL); + ldisc = ldisc_create(&cfg, NULL, back, backhandle, NULL); sfree(realhost); } connopen = 1; @@ -532,12 +619,17 @@ int main(int argc, char **argv) for (i = 0; i < skcount; i++) { socket = sklist[i]; + /* + * We must process exceptional notifications before + * ordinary readability ones, or we may go straight + * past the urgent marker. + */ + if (FD_ISSET(socket, &xset)) + select_result(socket, 4); if (FD_ISSET(socket, &rset)) select_result(socket, 1); if (FD_ISSET(socket, &wset)) select_result(socket, 2); - if (FD_ISSET(socket, &xset)) - select_result(socket, 4); } if (FD_ISSET(0, &rset)) { @@ -576,5 +668,6 @@ int main(int argc, char **argv) fprintf(stderr, "Remote process exit code unavailable\n"); exitcode = 1; /* this is an error condition */ } - return exitcode; + cleanup_exit(exitcode); + return exitcode; /* shouldn't happen, but placates gcc */ }