Add a new back-end function to return the exit code of the remote
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sat, 29 Dec 2001 15:31:42 +0000 (15:31 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sat, 29 Dec 2001 15:31:42 +0000 (15:31 +0000)
process. This is functional in SSH, and vestigial (just returns 0)
in the other three protocols. Plink's Windows exit code is now
determined by the remote process exit code, which should make it
more usable in scripting applications. Tested in both SSH1 and SSH2.

git-svn-id: svn://svn.tartarus.org/sgt/putty@1518 cda61777-01e9-0310-a592-d414129be87e

plink.c
putty.h
raw.c
rlogin.c
ssh.c
telnet.c

diff --git a/plink.c b/plink.c
index 6c21150..f8a9f7c 100644 (file)
--- a/plink.c
+++ b/plink.c
@@ -444,6 +444,7 @@ int main(int argc, char **argv)
     SOCKET *sklist;
     int skcount, sksize;
     int connopen;
+    int exitcode;
     char extra_portfwd[sizeof(cfg.portfwd)];
 
     ssh_get_line = get_line;
@@ -967,5 +968,10 @@ int main(int argc, char **argv)
            break;                     /* we closed the connection */
     }
     WSACleanup();
-    return 0;
+    exitcode = back->exitcode();
+    if (exitcode < 0) {
+       fprintf(stderr, "Remote process exit code unavailable\n");
+       exitcode = 1;                  /* this is an error condition */
+    }
+    return exitcode;
 }
diff --git a/putty.h b/putty.h
index 28639a9..266d6ac 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -214,6 +214,7 @@ typedef struct {
     void (*size) (void);
     void (*special) (Telnet_Special code);
     Socket(*socket) (void);
+    int (*exitcode) (void);
     int (*sendok) (void);
     int (*ldisc) (int);
     /*
diff --git a/raw.c b/raw.c
index e3fcbc0..0d27bb7 100644 (file)
--- a/raw.c
+++ b/raw.c
@@ -162,6 +162,12 @@ static int raw_ldisc(int option)
     return 0;
 }
 
+static int raw_exitcode(void)
+{
+    /* Exit codes are a meaningless concept in the Raw protocol */
+    return 0;
+}
+
 Backend raw_backend = {
     raw_init,
     raw_send,
@@ -169,6 +175,7 @@ Backend raw_backend = {
     raw_size,
     raw_special,
     raw_socket,
+    raw_exitcode,
     raw_sendok,
     raw_ldisc,
     raw_unthrottle,
index 97699ae..ba7dd37 100644 (file)
--- a/rlogin.c
+++ b/rlogin.c
@@ -217,6 +217,12 @@ static int rlogin_ldisc(int option)
     return 0;
 }
 
+static int rlogin_exitcode(void)
+{
+    /* If we ever implement RSH, we'll probably need to do this properly */
+    return 0;
+}
+
 Backend rlogin_backend = {
     rlogin_init,
     rlogin_send,
@@ -224,6 +230,7 @@ Backend rlogin_backend = {
     rlogin_size,
     rlogin_special,
     rlogin_socket,
+    rlogin_exitcode,
     rlogin_sendok,
     rlogin_ldisc,
     rlogin_unthrottle,
diff --git a/ssh.c b/ssh.c
index dcb791d..e0fed88 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -499,6 +499,7 @@ static int ssh_echoing, ssh_editing;
 
 static tree234 *ssh_channels;         /* indexed by local id */
 static struct ssh_channel *mainchan;   /* primary session channel */
+static int ssh_exitcode = -1;
 
 static tree234 *ssh_rportfwds;
 
@@ -3110,6 +3111,11 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt)
                /* may be from EXEC_SHELL on some servers
                 * if no pty is available or in other odd cases. Ignore */
            } else if (pktin.type == SSH1_SMSG_EXIT_STATUS) {
+               char buf[100];
+               ssh_exitcode = GET_32BIT(pktin.body);
+               sprintf(buf, "Server sent command exit status %d",
+                       ssh_exitcode);
+               logevent(buf);
                send_packet(SSH1_CMSG_EXIT_CONFIRMATION, PKT_END);
                 /*
                  * In case `helpful' firewalls or proxies tack
@@ -5061,14 +5067,35 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
                }
 
                /*
-                * We don't recognise any form of channel request,
-                * so we now either ignore the request or respond
-                * with CHANNEL_FAILURE, depending on want_reply.
+                * Having got the channel number, we now look at
+                * the request type string to see if it's something
+                * we recognise.
                 */
-               if (want_reply) {
-                   ssh2_pkt_init(SSH2_MSG_CHANNEL_FAILURE);
-                   ssh2_pkt_adduint32(c->remoteid);
-                   ssh2_pkt_send();
+               if (typelen == 11 && !memcmp(type, "exit-status", 11) &&
+                   c == mainchan) {
+                   /* We recognise "exit-status" on the primary channel. */
+                   char buf[100];
+                   ssh_exitcode = ssh2_pkt_getuint32();
+                   sprintf(buf, "Server sent command exit status %d",
+                           ssh_exitcode);
+                   logevent(buf);
+                   if (want_reply) {
+                       ssh2_pkt_init(SSH2_MSG_CHANNEL_SUCCESS);
+                       ssh2_pkt_adduint32(c->remoteid);
+                       ssh2_pkt_send();
+                   }
+               } else {
+                   /*
+                    * This is a channel request we don't know
+                    * about, so we now either ignore the request
+                    * or respond with CHANNEL_FAILURE, depending
+                    * on want_reply.
+                    */
+                   if (want_reply) {
+                       ssh2_pkt_init(SSH2_MSG_CHANNEL_FAILURE);
+                       ssh2_pkt_adduint32(c->remoteid);
+                       ssh2_pkt_send();
+                   }
                }
            } else if (pktin.type == SSH2_MSG_CHANNEL_OPEN) {
                char *type;
@@ -5443,6 +5470,11 @@ static int ssh_ldisc(int option)
     return FALSE;
 }
 
+static int ssh_return_exitcode(void)
+{
+    return ssh_exitcode;
+}
+
 Backend ssh_backend = {
     ssh_init,
     ssh_send,
@@ -5450,6 +5482,7 @@ Backend ssh_backend = {
     ssh_size,
     ssh_special,
     ssh_socket,
+    ssh_return_exitcode,
     ssh_sendok,
     ssh_ldisc,
     ssh_unthrottle,
index 5c5d2ce..5e5fb24 100644 (file)
--- a/telnet.c
+++ b/telnet.c
@@ -848,6 +848,12 @@ static int telnet_ldisc(int option)
     return FALSE;
 }
 
+static int telnet_exitcode(void)
+{
+    /* Telnet doesn't transmit exit codes back to the client */
+    return 0;
+}
+
 Backend telnet_backend = {
     telnet_init,
     telnet_send,
@@ -855,6 +861,7 @@ Backend telnet_backend = {
     telnet_size,
     telnet_special,
     telnet_socket,
+    telnet_exitcode,
     telnet_sendok,
     telnet_ldisc,
     telnet_unthrottle,