ref: e0bdfe1e763dba59efcaad635fe150adff5873ed
parent: fdcb55d6967291e80cd62fc1fbf313fdf74b7592
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Apr 2 13:28:56 EDT 2019
sshnet: actually make sure ssh established connection before exiting main proc this fixes password prompts and handles errors properly.
--- a/sys/src/cmd/sshnet.c
+++ b/sys/src/cmd/sshnet.c
@@ -32,6 +32,7 @@
#define TYPE(path) ((int)(path) & 0xFF)
#define NUM(path) ((uint)(path)>>8)
+Channel *ssherrchan; /* chan(char*) */
Channel *sshmsgchan; /* chan(Msg*) */
Channel *fsreqchan; /* chan(Req*) */
Channel *fsreqwaitchan; /* chan(nil) */
@@ -92,6 +93,8 @@
MaxPacket = 1<<15,
WinPackets = 8,
+
+ SESSIONCHAN = 1<<24,
};
struct Msg
@@ -1028,7 +1031,7 @@
static void
handlemsg(Msg *m)
{
- int chan, win, pkt, n;
+ int chan, win, pkt, n, l;
Client *c;
char *s;
@@ -1075,6 +1078,10 @@
case MSG_CHANNEL_OPEN_CONFIRMATION:
if(unpack(m, "_uuuu", &chan, &n, &win, &pkt) < 0)
break;
+ if(chan == SESSIONCHAN){
+ sendp(ssherrchan, nil);
+ break;
+ }
c = getclient(chan);
if(c == nil || c->state != Dialing)
break;
@@ -1087,8 +1094,12 @@
dialedclient(c);
break;
case MSG_CHANNEL_OPEN_FAILURE:
- if(unpack(m, "_uu", &chan, &n) < 0)
+ if(unpack(m, "_uus", &chan, &n, &s, &l) < 0)
break;
+ if(chan == SESSIONCHAN){
+ sendp(ssherrchan, smprint("%.*s", utfnlen(s, l), s));
+ break;
+ }
c = getclient(chan);
if(c == nil || c->state != Dialing)
break;
@@ -1228,6 +1239,48 @@
}
void
+ssh(int argc, char *argv[])
+{
+ Alt a[3];
+ Waitmsg *w;
+ char *e;
+
+ sshargc = argc + 2;
+ sshargv = emalloc9p(sizeof(char *) * (sshargc + 1));
+ sshargv[0] = "ssh";
+ sshargv[1] = "-X";
+ memcpy(sshargv + 2, argv, argc * sizeof(char *));
+
+ pipe(pfd);
+ sshfd = pfd[0];
+ procrfork(startssh, nil, mainstacksize, RFFDG|RFNOTEG|RFNAMEG);
+ close(pfd[1]);
+
+ sendmsg(pack(nil, "bsuuu", MSG_CHANNEL_OPEN,
+ "session", 7,
+ SESSIONCHAN,
+ MaxPacket,
+ MaxPacket));
+
+ a[0].op = CHANRCV;
+ a[0].c = threadwaitchan();
+ a[0].v = &w;
+ a[1].op = CHANRCV;
+ a[1].c = ssherrchan;
+ a[1].v = &e;
+ a[2].op = CHANEND;
+
+ switch(alt(a)){
+ case 0:
+ sysfatal("ssh failed: %s", w->msg);
+ case 1:
+ if(e != nil)
+ sysfatal("ssh failed: %s", e);
+ }
+ chanclose(ssherrchan);
+}
+
+void
usage(void)
{
fprint(2, "usage: sshnet [-m mtpt] [ssh options]\n");
@@ -1259,27 +1312,18 @@
if(argc == 0)
usage();
-
- sshargc = argc + 2;
- sshargv = emalloc9p(sizeof(char *) * (sshargc + 1));
- sshargv[0] = "ssh";
- sshargv[1] = "-X";
- memcpy(sshargv + 2, argv, argc * sizeof(char *));
- pipe(pfd);
- sshfd = pfd[0];
- procrfork(startssh, nil, mainstacksize, RFFDG|RFNOTEG|RFNAMEG);
- close(pfd[1]);
-
time0 = time(0);
+ ssherrchan = chancreate(sizeof(char*), 0);
sshmsgchan = chancreate(sizeof(Msg*), 16);
fsreqchan = chancreate(sizeof(Req*), 0);
fsreqwaitchan = chancreate(sizeof(void*), 0);
fsclunkchan = chancreate(sizeof(Fid*), 0);
fsclunkwaitchan = chancreate(sizeof(void*), 0);
-
- procrfork(sshreadproc, nil, mainstacksize, RFNAMEG|RFNOTEG);
procrfork(fsnetproc, nil, mainstacksize, RFNAMEG|RFNOTEG);
+ procrfork(sshreadproc, nil, mainstacksize, RFNAMEG|RFNOTEG);
+
+ ssh(argc, argv);
threadpostmountsrv(&fs, service, mtpt, MREPL);
exits(0);