Remove all the "assert(len>0)" which forbade zero-length writes across the
[u/mdw/putty] / unix / uxplink.c
index 9fce056..087c2d8 100644 (file)
 #include <pwd.h>
 #include <sys/ioctl.h>
 
-/* 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;
 }
 
@@ -213,8 +170,6 @@ int from_backend(void *frontend_handle, int is_stderr,
 {
     int osize, esize;
 
-    assert(len > 0);
-
     if (is_stderr) {
        bufchain_add(&stderr_data, data, len);
        try_output(1);
@@ -274,6 +229,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);
 }
 
@@ -287,7 +243,8 @@ int main(int argc, char **argv)
     int connopen;
     int exitcode;
     int errors;
-    void *ldisc;
+    int use_subsystem = 0;
+    void *ldisc, *logctx;
 
     ssh_get_line = console_get_line;
 
@@ -340,6 +297,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,
@@ -510,6 +470,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';
@@ -573,8 +539,9 @@ int main(int argc, char **argv)
      * 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);