X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/3d88e64dfcf5dc0fd361ce0c504c67a9196ce44c..df0870fc8ceb5a8fea66a4d0fe00e7db12317e33:/unix/uxplink.c diff --git a/unix/uxplink.c b/unix/uxplink.c index e71e6446..d069e045 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -14,12 +14,6 @@ #include #include -/* More helpful version of the FD_SET macro, to also handle maxfd. */ -#define FD_SET_MAX(fd, max, set) do { \ - FD_SET(fd, &set); \ - if (max < fd + 1) max = fd + 1; \ -} while (0) - #define PUTTY_DO_GLOBALS /* actually _define_ globals */ #include "putty.h" #include "storage.h" @@ -80,48 +74,11 @@ static Config cfg; char *platform_default_s(const char *name) { if (!strcmp(name, "X11Display")) - return getenv("DISPLAY"); + return dupstr(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 dupstr(getenv("TERM")); + if (!strcmp(name, "UserName")) + return get_username(); return NULL; } @@ -237,6 +194,13 @@ void sigwinch(int signum) } /* + * In Plink our selects are synchronous, so these functions are + * empty stubs. + */ +int uxsel_input_add(int fd, int rwx) { return 0; } +void uxsel_input_remove(int id) { } + +/* * Short description of parameters. */ static void usage(void) @@ -256,6 +220,7 @@ static void usage(void) printf(" -batch disable all interactive prompts\n"); printf("The following options only apply to SSH connections:\n"); printf(" -pw passw login with specified password\n"); + printf(" -D listen-port Dynamic SOCKS-based port forwarding\n"); printf(" -L listen-port:host:port Forward local port to " "remote address\n"); printf(" -R listen-port:host:port Forward remote port to" @@ -266,6 +231,7 @@ static void usage(void) printf(" -1 -2 force use of particular protocol version\n"); printf(" -C enable compression\n"); printf(" -i key private key file for authentication\n"); + printf(" -s remote command is an SSH subsystem (SSH-2 only)\n"); exit(1); } @@ -273,18 +239,19 @@ int main(int argc, char **argv) { int sending; int portnumber = -1; - int *sklist; - int socket; - int i, skcount, sksize, socketstate; + int *fdlist; + int fd; + int i, fdcount, fdsize, fdstate; int connopen; int exitcode; int errors; - void *ldisc; + int use_subsystem = 0; + void *ldisc, *logctx; ssh_get_line = console_get_line; - sklist = NULL; - skcount = sksize = 0; + fdlist = NULL; + fdcount = fdsize = 0; /* * Initialise port and protocol to sensible defaults. (These * will be overridden by more or less anything.) @@ -332,6 +299,9 @@ int main(int argc, char **argv) continue; } else if (!strcmp(p, "-batch")) { console_batch_mode = 1; + } else if (!strcmp(p, "-s")) { + /* Save status to write to cfg later. */ + use_subsystem = 1; } else if (!strcmp(p, "-o")) { if (argc <= 1) { fprintf(stderr, @@ -502,6 +472,12 @@ int main(int argc, char **argv) cmdline_run_saved(&cfg); /* + * Apply subsystem status. + */ + if (use_subsystem) + cfg.ssh_subsys = TRUE; + + /* * Trim a colon suffix off the hostname if it's there. */ cfg.host[strcspn(cfg.host, ":")] = '\0'; @@ -559,13 +535,15 @@ int main(int argc, char **argv) putty_signal(SIGWINCH, sigwinch); sk_init(); + uxsel_init(); /* * Start up the connection. */ logctx = log_init(NULL, &cfg); + console_provide_logctx(logctx); { - char *error; + const char *error; char *realhost; /* nodelay is only useful if stdin is a terminal device */ int nodelay = cfg.tcp_nodelay && isatty(0); @@ -623,31 +601,31 @@ int main(int argc, char **argv) FD_SET_MAX(2, maxfd, wset); } - /* Count the currently active sockets. */ + /* Count the currently active fds. */ i = 0; - for (socket = first_socket(&socketstate, &rwx); socket >= 0; - socket = next_socket(&socketstate, &rwx)) i++; + for (fd = first_fd(&fdstate, &rwx); fd >= 0; + fd = next_fd(&fdstate, &rwx)) i++; - /* Expand the sklist buffer if necessary. */ - if (i > sksize) { - sksize = i + 16; - sklist = sresize(sklist, sksize, int); + /* Expand the fdlist buffer if necessary. */ + if (i > fdsize) { + fdsize = i + 16; + fdlist = sresize(fdlist, fdsize, int); } /* - * Add all currently open sockets to the select sets, and - * store them in sklist as well. + * Add all currently open fds to the select sets, and store + * them in fdlist as well. */ - skcount = 0; - for (socket = first_socket(&socketstate, &rwx); socket >= 0; - socket = next_socket(&socketstate, &rwx)) { - sklist[skcount++] = socket; + fdcount = 0; + for (fd = first_fd(&fdstate, &rwx); fd >= 0; + fd = next_fd(&fdstate, &rwx)) { + fdlist[fdcount++] = fd; if (rwx & 1) - FD_SET_MAX(socket, maxfd, rset); + FD_SET_MAX(fd, maxfd, rset); if (rwx & 2) - FD_SET_MAX(socket, maxfd, wset); + FD_SET_MAX(fd, maxfd, wset); if (rwx & 4) - FD_SET_MAX(socket, maxfd, xset); + FD_SET_MAX(fd, maxfd, xset); } do { @@ -659,19 +637,19 @@ int main(int argc, char **argv) exit(1); } - for (i = 0; i < skcount; i++) { - socket = sklist[i]; + for (i = 0; i < fdcount; i++) { + fd = fdlist[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(fd, &xset)) + select_result(fd, 4); + if (FD_ISSET(fd, &rset)) + select_result(fd, 1); + if (FD_ISSET(fd, &wset)) + select_result(fd, 2); } if (FD_ISSET(signalpipe[0], &rset)) {