Tweaks to make it work on Unix.
diff --git a/src/cmd/samterm/Makefile b/src/cmd/samterm/Makefile
index 8e7afe3..5bf1d97 100644
--- a/src/cmd/samterm/Makefile
+++ b/src/cmd/samterm/Makefile
@@ -24,4 +24,6 @@
 CFLAGS+=-I../sam
 LDFLAGS+=-lframe -ldraw -lthread -l9 -lregexp9 -lbio -lfmt -lutf -L$(X11)/lib -lX11 -lm
 
+samterm: $(9SRC)/lib/libdraw.a
+
 include ../Makeone
diff --git a/src/cmd/samterm/io.c b/src/cmd/samterm/io.c
index dfdfd9c..32cd413 100644
--- a/src/cmd/samterm/io.c
+++ b/src/cmd/samterm/io.c
@@ -74,10 +74,10 @@
 	return mousep->buttons&(1<<(but-1));
 }
 
-/*
 void
 externload(int i)
 {
+	drawtopwindow();
 	plumbbase = malloc(plumbbuf[i].n);
 	if(plumbbase == 0)
 		return;
@@ -86,7 +86,6 @@
 	plumbstop = plumbbase + plumbbuf[i].n;
 	got |= 1<<RPlumb;
 }
-*/
 
 int
 waitforio(void)
@@ -140,11 +139,9 @@
 		hoststop = hostbuf[i].data + hostbuf[i].n;
 		block = 0;
 		break;
-/*
 	case RPlumb:
 		externload(i);
 		break;
-*/
 	case RKeyboard:
 		kbdc = r;
 		break;
@@ -250,7 +247,7 @@
 int
 kbdchar(void)
 {
-	int c, i;
+	int i, c;
 
 	c = externchar();
 	if(c > 0)
@@ -261,14 +258,12 @@
 		got &= ~(1<<RKeyboard);
 		return c;
 	}
-#if 0
 	while(plumbc!=nil && nbrecv(plumbc, &i)>0){
 		externload(i);
 		c = externchar();
 		if(c > 0)
 			return c;
 	}
-#endif
 	if(!ecankbd())
 		return -1;
 	return ekbd();
diff --git a/src/cmd/samterm/main.c b/src/cmd/samterm/main.c
index ef958d7..79d3e0e 100644
--- a/src/cmd/samterm/main.c
+++ b/src/cmd/samterm/main.c
@@ -32,6 +32,20 @@
 	Rectangle r;
 	Flayer *nwhich;
 
+	/*
+	 * sam is talking to us on fd 0 and 1.
+	 * move these elsewhere so that if we accidentally
+	 * use 0 and 1 in other code, nothing bad happens.
+	 */
+	dup(0, 3);
+	dup(1, 4);
+	hostfd[0] = 3;
+	hostfd[1] = 4;
+	close(0);
+	close(1);
+	open("/dev/null", OREAD);
+	dup(2, 1);
+
 	getscreen(argc, argv);
 	iconinit();
 	initio();
diff --git a/src/cmd/samterm/mesg.c b/src/cmd/samterm/mesg.c
index 0971ee2..c332d7a 100644
--- a/src/cmd/samterm/mesg.c
+++ b/src/cmd/samterm/mesg.c
@@ -16,6 +16,7 @@
 uchar	outdata[DATASIZE];
 short	outcount;
 int	hversion;
+int	hostfd[2];
 
 void	inmesg(Hmesg, int);
 int	inshort(int);
@@ -510,7 +511,7 @@
 		panic("outcount>sizeof outdata");
 	outdata[1]=outcount;
 	outdata[2]=outcount>>8;
-	if(write(1, (char *)outdata, outcount+HSIZE)!=outcount+HSIZE)
+	if(write(hostfd[1], (char *)outdata, outcount+HSIZE)!=outcount+HSIZE)
 		panic("write error");
 }
 
@@ -651,7 +652,7 @@
 		s1[n] = 0;
 		snarflen = n;
 		outTs(Tsetsnarf, n);
-		if(n>0 && write(1, s1, n)!=n)
+		if(n>0 && write(hostfd[1], s1, n)!=n)
 			panic("snarf write error");
 		free(s1);
 	}else
diff --git a/src/cmd/samterm/plan9.c b/src/cmd/samterm/plan9.c
index d08349c..e8e8b0d 100644
--- a/src/cmd/samterm/plan9.c
+++ b/src/cmd/samterm/plan9.c
@@ -1,3 +1,7 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
@@ -9,7 +13,7 @@
 #include "flayer.h"
 #include "samterm.h"
 
-static char exname[64];
+static char *exname;
 
 void
 getscreen(int argc, char **argv)
@@ -19,7 +23,7 @@
 	USED(argc);
 	USED(argv);
 	if(initdraw(panic1, nil, "sam") < 0){
-		fprint(2, "samterm: initimage: %r\n");
+		fprint(2, "samterm: initdraw: %r\n");
 		threadexitsall("init");
 	}
 	t = getenv("tabstop");
@@ -58,33 +62,13 @@
 int
 snarfswap(char *fromsam, int nc, char **tosam)
 {
-	char *s1;
-	int f, n, ss;
+	char *s;
 
-	f = open("/dev/snarf", 0);
-	if(f < 0)
-		return -1;
-	ss = SNARFSIZE;
-	if(hversion < 2)
-		ss = 4096;
-	*tosam = s1 = alloc(ss);
-	n = read(f, s1, ss-1);
-	close(f);
-	if(n < 0)
-		n = 0;
-	if (n == 0) {
-		*tosam = 0;
-		free(s1);
-	} else
-		s1[n] = 0;
-/*
-	f = create("/dev/snarf", 1, 0666);
-	if(f >= 0){
-		write(f, fromsam, nc);
-		close(f);
-	}
-*/
-	return n;
+fprint(2, "snarfswap\n");
+	s = getsnarf();
+	putsnarf(fromsam);
+	*tosam = s;
+	return s ? strlen(s) : 0;
 }
 
 void
@@ -101,68 +85,86 @@
 }
 
 Readbuf	hostbuf[2];
-/*
 Readbuf	plumbbuf[2];
 
 void
 extproc(void *argv)
 {
 	Channel *c;
-	int i, n, which, *fdp;
+	int i, n, which, fd;
 	void **arg;
 
 	arg = argv;
 	c = arg[0];
-	fdp = arg[1];
+	fd = (int)arg[1];
 
 	i = 0;
 	for(;;){
-		i = 1-i;	/ * toggle * /
-		n = read(*fdp, plumbbuf[i].data, sizeof plumbbuf[i].data);
+		i = 1-i;	/* toggle */
+		n = read(fd, plumbbuf[i].data, sizeof plumbbuf[i].data);
 		if(n <= 0){
 			fprint(2, "samterm: extern read error: %r\n");
-			threadexits("extern");	/ * not a fatal error * /
+			threadexits("extern");	/* not a fatal error */
 		}
 		plumbbuf[i].n = n;
 		which = i;
 		send(c, &which);
 	}
 }
-*/
 
 void
 extstart(void)
 {
-	char buf[32];
-	int fd;
-	static int p[2];
+	char *user, *disp;
+	int fd, flags;
 	static void *arg[2];
 
-return;
-	if(pipe(p) < 0)
+	user = getenv("USER");
+	if(user == nil)
 		return;
-	sprint(exname, "/srv/sam.%s", "rsc"/*getuser()*/);
-	fd = open(exname, 1, 0600);/* BUG was create */
-	if(fd < 0){	/* assume existing guy is more important */
-    Err:
-		close(p[0]);
-		close(p[1]);
+	disp = getenv("DISPLAY");
+	if(disp)
+		exname = smprint("/tmp/.sam.%s.%s", user, disp);
+	else
+		exname = smprint("/tmp/.sam.%s", user);
+	if(exname == nil){
+		fprint(2, "not posting for B: out of memory\n");
 		return;
 	}
-	sprint(buf, "%d", p[0]);
-	if(write(fd, buf, strlen(buf)) <= 0)
-		goto Err;
-	close(fd);
+
+	if(mkfifo(exname, 0600) < 0){
+		struct stat st;
+		if(errno != EEXIST || stat(exname, &st) < 0)
+			return;
+		if(!S_ISFIFO(st.st_mode)){
+			removeextern();
+			if(mkfifo(exname, 0600) < 0)
+				return;
+		}
+	}
+
+	fd = open(exname, OREAD|O_NONBLOCK);
+	if(fd == -1){
+		removeextern();
+		return;
+	}
+
 	/*
-	 * leave p[0] open so if the file is removed the event
-	 * library won't get an error
+	 * Turn off no-delay and provide ourselves as a lingering
+	 * writer so as not to get end of file on read.
 	 */
-#if 0
+	flags = fcntl(fd, F_GETFL, 0);
+	if(flags<0 || fcntl(fd, F_SETFL, flags&~O_NONBLOCK)<0
+	||open(exname, OWRITE) < 0){
+		close(fd);
+		removeextern();
+		return;
+	}
+
 	plumbc = chancreate(sizeof(int), 0);
 	arg[0] = plumbc;
-	arg[1] = &p[1];
-	proccreate(extproc, arg, 1024);
-#endif
+	arg[1] = (void*)fd;
+	proccreate(extproc, arg, 8192);
 	atexit(removeextern);
 }
 
@@ -277,7 +279,7 @@
 	i = 0;
 	for(;;){
 		i = 1-i;	/* toggle */
-		n = read(0, hostbuf[i].data, sizeof hostbuf[i].data);
+		n = read(hostfd[0], hostbuf[i].data, sizeof hostbuf[i].data);
 		if(n <= 0){
 			fprint(2, "samterm: host read error: %r\n");
 			threadexitsall("host");
diff --git a/src/cmd/samterm/samterm.h b/src/cmd/samterm/samterm.h
index 3018c92..5eb05cd 100644
--- a/src/cmd/samterm/samterm.h
+++ b/src/cmd/samterm/samterm.h
@@ -84,6 +84,7 @@
 extern Channel *hostc;
 extern int	hversion;
 extern int	plumbfd;
+extern int	hostfd[2];
 
 Rune	*gettext(Flayer*, long, ulong*);
 void	*alloc(ulong n);
@@ -175,3 +176,8 @@
 void	outlong(long);
 void	outvlong(void*);
 void	outsend(void);
+
+int	perror(char*);
+int	remove(char*);
+int	create(char*, int, ulong);
+