shithub: riscv

Download patch

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);