280 lines · 4.6 KB · C
RawDownload
#include <u.h>#include <sys/types.h>#include <sys/stat.h>#include <errno.h> #include <u.h>#include <libc.h>#include <draw.h>#include <thread.h>#include <mouse.h>#include <cursor.h>#include <keyboard.h>#include <frame.h>#define Tversion Tversion9p#define Twrite Twrite9p#include <fcall.h>#undef Tversion#undef Twrite#include <9pclient.h>#include <plumb.h>#include "flayer.h"#include "samterm.h" #define STACK 16384 voidusage(void){	fprint(2, "usage: samterm -a -W winsize\n");	threadexitsall("usage");} voidgetscreen(int argc, char **argv){	char *t; 	ARGBEGIN{	case 'a':		autoindent = 1;		break;	case 'W':		winsize = EARGF(usage());		break;	default:		usage();	}ARGEND 	if(initdraw(panic1, nil, "sam") < 0){		fprint(2, "samterm: initdraw: %r\n");		threadexitsall("init");	}	t = getenv("tabstop");	if(t != nil)		maxtab = strtoul(t, nil, 0);	draw(screen, screen->clipr, display->white, nil, ZP);} intscreensize(int *w, int *h){	int fd, n;	char buf[5*12+1]; 	fd = open("/dev/screen", OREAD);	if(fd < 0)		return 0;	n = read(fd, buf, sizeof(buf)-1);	close(fd);	if (n != sizeof(buf)-1)		return 0;	buf[n] = 0;	if (h) {		*h = atoi(buf+4*12)-atoi(buf+2*12);		if (*h < 0)			return 0;	}	if (w) {		*w = atoi(buf+3*12)-atoi(buf+1*12);		if (*w < 0)			return 0;	}	return 1;} intsnarfswap(char *fromsam, int nc, char **tosam){	char *s; 	s = getsnarf();	putsnarf(fromsam);	*tosam = s;	return s ? strlen(s) : 0;} voiddumperrmsg(int count, int type, int count0, int c){	fprint(2, "samterm: host mesg: count %d %ux %ux %ux %s...ignored\n",		count, type, count0, c, rcvstring());} Readbuf	hostbuf[2];Readbuf	plumbbuf[2]; voidextproc(void *argv){	Channel *c;	int i, n, which, ctl, fd;	void **arg;	char *adir, dir[40]; 	arg = argv;	c = arg[0];	adir = arg[1]; 	fd = -1;	i = 0;	for(;;){		i = 1-i;	/* toggle */		if(fd<0){			ctl = listen(adir, dir);			if(ctl < 0)				sysfatal("listen: %r");			fd = accept(ctl, dir);			close(ctl);		}		n = read(fd, plumbbuf[i].data, sizeof plumbbuf[i].data);if(0) fprint(2, "ext %d\n", n);		if(n <= 0){			close(fd);			fd = -1;		}else{			plumbbuf[i].n = n;			which = i;			send(c, &which);		}	}} voidextstart(void){	static void *arg[2];	static char adir[40];	char addr[200], *ns; 	ns = getns();	snprint(addr, sizeof addr, "unix!%s/sam", ns);	free(ns);	if(announce(addr, adir) < 0){		fprint(2, "announce %s: %r", addr);		return;	}	plumbc = chancreate(sizeof(int), 0);	chansetname(plumbc, "plumbc");	arg[0] = plumbc;	arg[1] = &adir[0];	proccreate(extproc, arg, STACK);} intplumbformat(Plumbmsg *m, int i){	char *addr, *data, *act;	int n; 	data = (char*)plumbbuf[i].data;	n = m->ndata;	if(n == 0 || 2+n+2 >= READBUFSIZE){		plumbfree(m);		return 0;	}	act = plumblookup(m->attr, "action");	if(act!=nil && strcmp(act, "showfile")!=0){		/* can't handle other cases yet */		plumbfree(m);		return 0;	}	addr = plumblookup(m->attr, "addr");	if(addr){		if(addr[0] == '\0')			addr = nil;		else			addr = strdup(addr);	/* copy to safe storage; we'll overwrite data */	}	memmove(data, "B ", 2);	/* we know there's enough room for this */	memmove(data+2, m->data, n);	n += 2;	if(data[n-1] != '\n')		data[n++] = '\n';	if(addr != nil){		if(n+strlen(addr)+1+1 <= READBUFSIZE)			n += sprint(data+n, "%s\n", addr);		free(addr);	}	plumbbuf[i].n = n;	plumbfree(m);	return 1;} voidplumbproc(void *arg){	CFid *fid;	int i;	Plumbmsg *m; 	fid = arg;	i = 0;	for(;;){		m = plumbrecvfid(fid);		if(m == nil){			fprint(2, "samterm: plumb read error: %r\n");			threadexits("plumb");	/* not a fatal error */		}		if(plumbformat(m, i)){			send(plumbc, &i);			i = 1-i;	/* toggle */		}	}} intplumbstart(void){	CFid *fid; 	plumbfd = plumbopen("send", OWRITE|OCEXEC);	/* not open is ok */	fid = plumbopenfid("edit", OREAD|OCEXEC);	if(fid == nil)		return -1;	plumbc = chancreate(sizeof(int), 0);	chansetname(plumbc, "plumbc");	if(plumbc == nil){		fsclose(fid);		return -1;	}	threadcreate(plumbproc, fid, STACK);	return 1;} voidhostproc(void *arg){	Channel *c;	int i, n, which; 	c = arg; 	i = 0;	for(;;){		i = 1-i;	/* toggle */		n = read(hostfd[0], hostbuf[i].data, sizeof hostbuf[i].data);if(0) fprint(2, "hostproc %d\n", n);		if(n <= 0){			if(n == 0){				if(exiting)					threadexits(nil);				werrstr("unexpected eof");			}			fprint(2, "samterm: host read error: %r\n");			threadexitsall("host");		}		hostbuf[i].n = n;		which = i;if(0) fprint(2, "hostproc send %d\n", which);		send(c, &which);	}} voidhoststart(void){	hostc = chancreate(sizeof(int), 0);	chansetname(hostc, "hostc");	proccreate(hostproc, hostc, STACK);}