]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Add a new back-end function to return the exit code of the remote
authorSimon Tatham <anakin@pobox.com>
Sat, 29 Dec 2001 15:31:42 +0000 (15:31 +0000)
committerSimon Tatham <anakin@pobox.com>
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.

[originally from svn r1518]

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

diff --git a/plink.c b/plink.c
index 6c2115035bbab346d6d32b459dd2f979d3b82dbb..f8a9f7ce1d17ce809ae49574e0db2969eba79509 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 28639a9be9f4c21aec9f502fde58f89e3d53dacc..266d6ac413fc6168f40e9dc4bc464e92ce0e5dec 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 e3fcbc00ccfd0505259aac9ef0de3a89ea854b38..0d27bb77a485cc63b6fc70d5fed584ba0efd0e60 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 97699aea6260b8c2e325efc0837d18c8ba0d5b16..ba7dd37bd64cb429db15c9bfb4bbe088e51755f8 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 dcb791da3970bc510cadc727de8a18f0e1967eb4..e0fed88bcb4059e15e569e5a9711859a3cf18591 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 5c5d2ce3818feb4b46186fc0a6827a8a3401a130..5e5fb24765b145d5560470ec8d33a6dd715829f3 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,