plink can now execute a specific command instead of just a shell session
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 8 Sep 2000 15:24:19 +0000 (15:24 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 8 Sep 2000 15:24:19 +0000 (15:24 +0000)
git-svn-id: svn://svn.tartarus.org/sgt/putty@576 cda61777-01e9-0310-a592-d414129be87e

putty.h
ssh.c
windlg.c

diff --git a/putty.h b/putty.h
index fbd5e64..8c69d90 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -134,6 +134,7 @@ typedef struct {
     int close_on_exit;
     int warn_on_close;
     /* SSH options */
+    char remote_cmd[512];
     int nopty;
     enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
     char keyfile[FILENAME_MAX];
diff --git a/ssh.c b/ssh.c
index 26043c6..7e02bac 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -221,6 +221,7 @@ struct Packet {
 static struct Packet pktin = { 0, 0, NULL, NULL, 0 };
 static struct Packet pktout = { 0, 0, NULL, NULL, 0 };
 
+static int ssh_version;
 static void (*ssh_protocol)(unsigned char *in, int inlen, int ispkt);
 static void ssh1_protocol(unsigned char *in, int inlen, int ispkt);
 static void ssh2_protocol(unsigned char *in, int inlen, int ispkt);
@@ -972,6 +973,7 @@ static int do_ssh_init(void) {
         logevent("Using SSH protocol version 2");
         s_write(vstring, strlen(vstring));
         ssh_protocol = ssh2_protocol;
+        ssh_version = 2;
         s_rdpkt = ssh2_rdpkt;
     } else {
         /*
@@ -985,6 +987,7 @@ static int do_ssh_init(void) {
         logevent("Using SSH protocol version 1");
         s_write(vstring, strlen(vstring));
         ssh_protocol = ssh1_protocol;
+        ssh_version = 1;
         s_rdpkt = ssh1_rdpkt;
     }
     return 1;
@@ -1398,7 +1401,10 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) {
        logevent("Allocated pty");
     }
 
-    send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END);
+    if (*cfg.remote_cmd)
+        send_packet(SSH1_CMSG_EXEC_CMD, PKT_STR, cfg.remote_cmd, PKT_END);
+    else
+        send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END);
     logevent("Started session");
 
     ssh_state = SSH_STATE_SESSION;
@@ -1744,11 +1750,15 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
 }
 
 /*
+ * SSH2: remote identifier for the main session channel.
+ */
+static unsigned long ssh_remote_channel;
+
+/*
  * Handle the SSH2 userauth and connection layers.
  */
 static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
 {
-    static unsigned long their_channel;
     static unsigned long remote_winsize;
     static unsigned long remote_maxpkt;
 
@@ -1909,7 +1919,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
     if (ssh2_pkt_getuint32() != 100) {
         fatalbox("Server's channel confirmation cited wrong channel");
     }
-    their_channel = ssh2_pkt_getuint32();
+    ssh_remote_channel = ssh2_pkt_getuint32();
     remote_winsize = ssh2_pkt_getuint32();
     remote_maxpkt = ssh2_pkt_getuint32();
     logevent("Opened channel for session");
@@ -1918,7 +1928,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
      * Now allocate a pty for the session.
      */
     ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
-    ssh2_pkt_adduint32(their_channel); /* recipient channel */
+    ssh2_pkt_adduint32(ssh_remote_channel); /* recipient channel */
     ssh2_pkt_addstring("pty-req");
     ssh2_pkt_addbool(1);               /* want reply */
     ssh2_pkt_addstring(cfg.termtype);
@@ -1947,7 +1957,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
      * Start a shell.
      */
     ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
-    ssh2_pkt_adduint32(their_channel); /* recipient channel */
+    ssh2_pkt_adduint32(ssh_remote_channel); /* recipient channel */
     ssh2_pkt_addstring("shell");
     ssh2_pkt_addbool(1);               /* want reply */
     ssh2_pkt_send();
@@ -1994,7 +2004,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
        } else {
             /* FIXME: for now, ignore window size */
             ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
-            ssh2_pkt_adduint32(their_channel);
+            ssh2_pkt_adduint32(ssh_remote_channel);
             ssh2_pkt_addstring_start();
             ssh2_pkt_addstring_data(in, inlen);
             ssh2_pkt_send();
@@ -2120,10 +2130,22 @@ static void ssh_size(void) {
 }
 
 /*
- * (Send Telnet special codes)
+ * Send Telnet special codes. TS_EOF is useful for `plink', so you
+ * can send an EOF and collect resulting output (e.g. `plink
+ * hostname sort').
  */
 static void ssh_special (Telnet_Special code) {
-    /* do nothing */
+    if (code == TS_EOF) {
+        if (ssh_version = 1) {
+            send_packet(SSH1_CMSG_EOF, PKT_END);
+        } else {
+            ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
+            ssh2_pkt_adduint32(ssh_remote_channel);
+            ssh2_pkt_send();
+        }
+    } else {
+        /* do nothing */
+    }
 }
 
 
index f6c342e..825072b 100644 (file)
--- a/windlg.c
+++ b/windlg.c
@@ -149,6 +149,7 @@ static void save_settings (char *section, int do_host) {
     }
     wpps (sesskey, "UserName", cfg.username);
     wppi (sesskey, "NoPTY", cfg.nopty);
+    wpps (sesskey, "RemoteCmd", cfg.remote_cmd);
     wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
                              cfg.cipher == CIPHER_DES ? "des" : "3des");
     wppi (sesskey, "AuthTIS", cfg.try_tis_auth);
@@ -283,6 +284,7 @@ static void load_settings (char *section, int do_host) {
     }
     gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username));
     gppi (sesskey, "NoPTY", 0, &cfg.nopty);
+    gpps (sesskey, "RemoteCmd", "", cfg.remote_cmd, sizeof(cfg.remote_cmd));
     {
        char cipher[10];
        gpps (sesskey, "Cipher", "3des", cipher, 10);