xref: /plan9/sys/src/cmd/sam/mesg.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include "sam.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier Header	h;
43e12c5d1SDavid du Colombier uchar	indata[DATASIZE];
53e12c5d1SDavid du Colombier uchar	outdata[2*DATASIZE+3];	/* room for overflow message */
63e12c5d1SDavid du Colombier uchar	*inp;
73e12c5d1SDavid du Colombier uchar	*outp;
83e12c5d1SDavid du Colombier uchar	*outmsg = outdata;
93e12c5d1SDavid du Colombier Posn	cmdpt;
103e12c5d1SDavid du Colombier Posn	cmdptadv;
11*7dd7cddfSDavid du Colombier Buffer	snarfbuf;
123e12c5d1SDavid du Colombier int	waitack;
133e12c5d1SDavid du Colombier int	noflush;
143e12c5d1SDavid du Colombier int	tversion;
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier long	inlong(void);
17219b2ee8SDavid du Colombier long	invlong(void);
183e12c5d1SDavid du Colombier int	inshort(void);
193e12c5d1SDavid du Colombier int	inmesg(Tmesg);
203e12c5d1SDavid du Colombier void	setgenstr(File*, Posn, Posn);
213e12c5d1SDavid du Colombier 
223e12c5d1SDavid du Colombier #ifdef DEBUG
233e12c5d1SDavid du Colombier char *hname[] = {
243e12c5d1SDavid du Colombier 	[Hversion]	"Hversion",
253e12c5d1SDavid du Colombier 	[Hbindname]	"Hbindname",
263e12c5d1SDavid du Colombier 	[Hcurrent]	"Hcurrent",
273e12c5d1SDavid du Colombier 	[Hnewname]	"Hnewname",
283e12c5d1SDavid du Colombier 	[Hmovname]	"Hmovname",
293e12c5d1SDavid du Colombier 	[Hgrow]		"Hgrow",
303e12c5d1SDavid du Colombier 	[Hcheck0]	"Hcheck0",
313e12c5d1SDavid du Colombier 	[Hcheck]	"Hcheck",
323e12c5d1SDavid du Colombier 	[Hunlock]	"Hunlock",
333e12c5d1SDavid du Colombier 	[Hdata]		"Hdata",
343e12c5d1SDavid du Colombier 	[Horigin]	"Horigin",
353e12c5d1SDavid du Colombier 	[Hunlockfile]	"Hunlockfile",
363e12c5d1SDavid du Colombier 	[Hsetdot]	"Hsetdot",
373e12c5d1SDavid du Colombier 	[Hgrowdata]	"Hgrowdata",
383e12c5d1SDavid du Colombier 	[Hmoveto]	"Hmoveto",
393e12c5d1SDavid du Colombier 	[Hclean]	"Hclean",
403e12c5d1SDavid du Colombier 	[Hdirty]	"Hdirty",
413e12c5d1SDavid du Colombier 	[Hcut]		"Hcut",
423e12c5d1SDavid du Colombier 	[Hsetpat]	"Hsetpat",
433e12c5d1SDavid du Colombier 	[Hdelname]	"Hdelname",
443e12c5d1SDavid du Colombier 	[Hclose]	"Hclose",
453e12c5d1SDavid du Colombier 	[Hsetsnarf]	"Hsetsnarf",
463e12c5d1SDavid du Colombier 	[Hsnarflen]	"Hsnarflen",
473e12c5d1SDavid du Colombier 	[Hack]		"Hack",
483e12c5d1SDavid du Colombier 	[Hexit]		"Hexit",
49*7dd7cddfSDavid du Colombier 	[Hplumb]		"Hplumb",
503e12c5d1SDavid du Colombier };
513e12c5d1SDavid du Colombier 
523e12c5d1SDavid du Colombier char *tname[] = {
533e12c5d1SDavid du Colombier 	[Tversion]	"Tversion",
543e12c5d1SDavid du Colombier 	[Tstartcmdfile]	"Tstartcmdfile",
553e12c5d1SDavid du Colombier 	[Tcheck]	"Tcheck",
563e12c5d1SDavid du Colombier 	[Trequest]	"Trequest",
573e12c5d1SDavid du Colombier 	[Torigin]	"Torigin",
583e12c5d1SDavid du Colombier 	[Tstartfile]	"Tstartfile",
593e12c5d1SDavid du Colombier 	[Tworkfile]	"Tworkfile",
603e12c5d1SDavid du Colombier 	[Ttype]		"Ttype",
613e12c5d1SDavid du Colombier 	[Tcut]		"Tcut",
623e12c5d1SDavid du Colombier 	[Tpaste]	"Tpaste",
633e12c5d1SDavid du Colombier 	[Tsnarf]	"Tsnarf",
643e12c5d1SDavid du Colombier 	[Tstartnewfile]	"Tstartnewfile",
653e12c5d1SDavid du Colombier 	[Twrite]	"Twrite",
663e12c5d1SDavid du Colombier 	[Tclose]	"Tclose",
673e12c5d1SDavid du Colombier 	[Tlook]		"Tlook",
68219b2ee8SDavid du Colombier 	[Tsearch]	"Tsearch",
693e12c5d1SDavid du Colombier 	[Tsend]		"Tsend",
70219b2ee8SDavid du Colombier 	[Tdclick]	"Tdclick",
713e12c5d1SDavid du Colombier 	[Tstartsnarf]	"Tstartsnarf",
723e12c5d1SDavid du Colombier 	[Tsetsnarf]	"Tsetsnarf",
733e12c5d1SDavid du Colombier 	[Tack]		"Tack",
743e12c5d1SDavid du Colombier 	[Texit]		"Texit",
75*7dd7cddfSDavid du Colombier 	[Tplumb]		"Tplumb",
763e12c5d1SDavid du Colombier };
773e12c5d1SDavid du Colombier 
783e12c5d1SDavid du Colombier void
793e12c5d1SDavid du Colombier journal(int out, char *s)
803e12c5d1SDavid du Colombier {
81219b2ee8SDavid du Colombier 	static int fd = 0;
823e12c5d1SDavid du Colombier 
833e12c5d1SDavid du Colombier 	if(fd <= 0)
843e12c5d1SDavid du Colombier 		fd = create("/tmp/sam.out", 1, 0666L);
853e12c5d1SDavid du Colombier 	fprint(fd, "%s%s\n", out? "out: " : "in:  ", s);
863e12c5d1SDavid du Colombier }
873e12c5d1SDavid du Colombier 
88bd389b36SDavid du Colombier void
89219b2ee8SDavid du Colombier journaln(int out, long n)
903e12c5d1SDavid du Colombier {
913e12c5d1SDavid du Colombier 	char buf[32];
92*7dd7cddfSDavid du Colombier 
93*7dd7cddfSDavid du Colombier 	sprint(buf, "%ld", n);
943e12c5d1SDavid du Colombier 	journal(out, buf);
953e12c5d1SDavid du Colombier }
963e12c5d1SDavid du Colombier #else
973e12c5d1SDavid du Colombier #define	journal(a, b)
983e12c5d1SDavid du Colombier #define journaln(a, b)
993e12c5d1SDavid du Colombier #endif
1003e12c5d1SDavid du Colombier 
1013e12c5d1SDavid du Colombier int
1023e12c5d1SDavid du Colombier rcvchar(void){
1033e12c5d1SDavid du Colombier 	static uchar buf[64];
1043e12c5d1SDavid du Colombier 	static i, nleft = 0;
1053e12c5d1SDavid du Colombier 
1063e12c5d1SDavid du Colombier 	if(nleft <= 0){
1073e12c5d1SDavid du Colombier 		nleft = read(0, (char *)buf, sizeof buf);
1083e12c5d1SDavid du Colombier 		if(nleft <= 0)
1093e12c5d1SDavid du Colombier 			return -1;
1103e12c5d1SDavid du Colombier 		i = 0;
1113e12c5d1SDavid du Colombier 	}
1123e12c5d1SDavid du Colombier 	--nleft;
1133e12c5d1SDavid du Colombier 	return buf[i++];
1143e12c5d1SDavid du Colombier }
1153e12c5d1SDavid du Colombier 
1163e12c5d1SDavid du Colombier int
1173e12c5d1SDavid du Colombier rcv(void){
1183e12c5d1SDavid du Colombier 	int c;
1193e12c5d1SDavid du Colombier 	static state = 0;
1203e12c5d1SDavid du Colombier 	static count = 0;
1213e12c5d1SDavid du Colombier 	static i = 0;
1223e12c5d1SDavid du Colombier 
1233e12c5d1SDavid du Colombier 	while((c=rcvchar()) != -1)
1243e12c5d1SDavid du Colombier 		switch(state){
1253e12c5d1SDavid du Colombier 		case 0:
1263e12c5d1SDavid du Colombier 			h.type = c;
1273e12c5d1SDavid du Colombier 			state++;
1283e12c5d1SDavid du Colombier 			break;
1293e12c5d1SDavid du Colombier 
1303e12c5d1SDavid du Colombier 		case 1:
1313e12c5d1SDavid du Colombier 			h.count0 = c;
1323e12c5d1SDavid du Colombier 			state++;
1333e12c5d1SDavid du Colombier 			break;
1343e12c5d1SDavid du Colombier 
1353e12c5d1SDavid du Colombier 		case 2:
1363e12c5d1SDavid du Colombier 			h.count1 = c;
1373e12c5d1SDavid du Colombier 			count = h.count0|(h.count1<<8);
1383e12c5d1SDavid du Colombier 			i = 0;
1393e12c5d1SDavid du Colombier 			if(count > DATASIZE)
1403e12c5d1SDavid du Colombier 				panic("count>DATASIZE");
1413e12c5d1SDavid du Colombier 			if(count == 0)
1423e12c5d1SDavid du Colombier 				goto zerocount;
1433e12c5d1SDavid du Colombier 			state++;
1443e12c5d1SDavid du Colombier 			break;
1453e12c5d1SDavid du Colombier 
1463e12c5d1SDavid du Colombier 		case 3:
1473e12c5d1SDavid du Colombier 			indata[i++] = c;
1483e12c5d1SDavid du Colombier 			if(i == count){
1493e12c5d1SDavid du Colombier 		zerocount:
1503e12c5d1SDavid du Colombier 				indata[i] = 0;
1513e12c5d1SDavid du Colombier 				state = count = 0;
1523e12c5d1SDavid du Colombier 				return inmesg(h.type);
1533e12c5d1SDavid du Colombier 			}
1543e12c5d1SDavid du Colombier 			break;
1553e12c5d1SDavid du Colombier 		}
1563e12c5d1SDavid du Colombier 	return 0;
1573e12c5d1SDavid du Colombier }
1583e12c5d1SDavid du Colombier 
1593e12c5d1SDavid du Colombier File *
1603e12c5d1SDavid du Colombier whichfile(int tag)
1613e12c5d1SDavid du Colombier {
1623e12c5d1SDavid du Colombier 	int i;
1633e12c5d1SDavid du Colombier 
1643e12c5d1SDavid du Colombier 	for(i = 0; i<file.nused; i++)
1653e12c5d1SDavid du Colombier 		if(file.filepptr[i]->tag==tag)
1663e12c5d1SDavid du Colombier 			return file.filepptr[i];
1673e12c5d1SDavid du Colombier 	hiccough((char *)0);
1683e12c5d1SDavid du Colombier 	return 0;
1693e12c5d1SDavid du Colombier }
1703e12c5d1SDavid du Colombier 
1713e12c5d1SDavid du Colombier int
1723e12c5d1SDavid du Colombier inmesg(Tmesg type)
1733e12c5d1SDavid du Colombier {
1743e12c5d1SDavid du Colombier 	Rune buf[1025];
175*7dd7cddfSDavid du Colombier 	char cbuf[64];
1763e12c5d1SDavid du Colombier 	int i, m;
1773e12c5d1SDavid du Colombier 	short s;
1783e12c5d1SDavid du Colombier 	long l, l1;
1793e12c5d1SDavid du Colombier 	File *f;
180*7dd7cddfSDavid du Colombier 	Posn p0, p1, p;
1813e12c5d1SDavid du Colombier 	Range r;
1823e12c5d1SDavid du Colombier 	String *str;
1833e12c5d1SDavid du Colombier 	char *c;
184219b2ee8SDavid du Colombier 	Rune *rp;
185*7dd7cddfSDavid du Colombier 	Plumbmsg *pm;
1863e12c5d1SDavid du Colombier 
1873e12c5d1SDavid du Colombier 	if(type > TMAX)
1883e12c5d1SDavid du Colombier 		panic("inmesg");
1893e12c5d1SDavid du Colombier 
1903e12c5d1SDavid du Colombier 	journal(0, tname[type]);
1913e12c5d1SDavid du Colombier 
1923e12c5d1SDavid du Colombier 	inp = indata;
1933e12c5d1SDavid du Colombier 	switch(type){
1943e12c5d1SDavid du Colombier 	case -1:
1953e12c5d1SDavid du Colombier 		panic("rcv error");
1963e12c5d1SDavid du Colombier 
1973e12c5d1SDavid du Colombier 	default:
1983e12c5d1SDavid du Colombier 		fprint(2, "unknown type %d\n", type);
1993e12c5d1SDavid du Colombier 		panic("rcv unknown");
2003e12c5d1SDavid du Colombier 
2013e12c5d1SDavid du Colombier 	case Tversion:
2023e12c5d1SDavid du Colombier 		tversion = inshort();
2033e12c5d1SDavid du Colombier 		journaln(0, tversion);
2043e12c5d1SDavid du Colombier 		break;
2053e12c5d1SDavid du Colombier 
2063e12c5d1SDavid du Colombier 	case Tstartcmdfile:
207219b2ee8SDavid du Colombier 		l = invlong();		/* for 64-bit pointers */
2083e12c5d1SDavid du Colombier 		journaln(0, l);
2093e12c5d1SDavid du Colombier 		Strdupl(&genstr, samname);
2103e12c5d1SDavid du Colombier 		cmd = newfile();
211*7dd7cddfSDavid du Colombier 		cmd->unread = 0;
212219b2ee8SDavid du Colombier 		outTsv(Hbindname, cmd->tag, l);
2133e12c5d1SDavid du Colombier 		outTs(Hcurrent, cmd->tag);
214*7dd7cddfSDavid du Colombier 		logsetname(cmd, &genstr);
2153e12c5d1SDavid du Colombier 		cmd->rasp = emalloc(sizeof(List));
216*7dd7cddfSDavid du Colombier 		cmd->mod = 0;
2173e12c5d1SDavid du Colombier 		if(cmdstr.n){
218*7dd7cddfSDavid du Colombier 			loginsert(cmd, 0L, cmdstr.s, cmdstr.n);
2193e12c5d1SDavid du Colombier 			Strdelete(&cmdstr, 0L, (Posn)cmdstr.n);
2203e12c5d1SDavid du Colombier 		}
221*7dd7cddfSDavid du Colombier 		fileupdate(cmd, FALSE, TRUE);
2223e12c5d1SDavid du Colombier 		outT0(Hunlock);
2233e12c5d1SDavid du Colombier 		break;
2243e12c5d1SDavid du Colombier 
2253e12c5d1SDavid du Colombier 	case Tcheck:
2263e12c5d1SDavid du Colombier 		/* go through whichfile to check the tag */
2273e12c5d1SDavid du Colombier 		outTs(Hcheck, whichfile(inshort())->tag);
2283e12c5d1SDavid du Colombier 		break;
2293e12c5d1SDavid du Colombier 
2303e12c5d1SDavid du Colombier 	case Trequest:
2313e12c5d1SDavid du Colombier 		f = whichfile(inshort());
2323e12c5d1SDavid du Colombier 		p0 = inlong();
2333e12c5d1SDavid du Colombier 		p1 = p0+inshort();
2343e12c5d1SDavid du Colombier 		journaln(0, p0);
2353e12c5d1SDavid du Colombier 		journaln(0, p1-p0);
236*7dd7cddfSDavid du Colombier 		if(f->unread)
2373e12c5d1SDavid du Colombier 			panic("Trequest: unread");
238*7dd7cddfSDavid du Colombier 		if(p1>f->nc)
239*7dd7cddfSDavid du Colombier 			p1 = f->nc;
240*7dd7cddfSDavid du Colombier 		if(p0>f->nc) /* can happen e.g. scrolling during command */
241*7dd7cddfSDavid du Colombier 			p0 = f->nc;
2423e12c5d1SDavid du Colombier 		if(p0 == p1){
2433e12c5d1SDavid du Colombier 			i = 0;
2443e12c5d1SDavid du Colombier 			r.p1 = r.p2 = p0;
2453e12c5d1SDavid du Colombier 		}else{
2463e12c5d1SDavid du Colombier 			r = rdata(f->rasp, p0, p1-p0);
2473e12c5d1SDavid du Colombier 			i = r.p2-r.p1;
248*7dd7cddfSDavid du Colombier 			bufread(f, r.p1, buf, i);
2493e12c5d1SDavid du Colombier 		}
2503e12c5d1SDavid du Colombier 		buf[i]=0;
2513e12c5d1SDavid du Colombier 		outTslS(Hdata, f->tag, r.p1, tmprstr(buf, i+1));
2523e12c5d1SDavid du Colombier 		break;
2533e12c5d1SDavid du Colombier 
2543e12c5d1SDavid du Colombier 	case Torigin:
2553e12c5d1SDavid du Colombier 		s = inshort();
2563e12c5d1SDavid du Colombier 		l = inlong();
2573e12c5d1SDavid du Colombier 		l1 = inlong();
2583e12c5d1SDavid du Colombier 		journaln(0, l1);
2593e12c5d1SDavid du Colombier 		lookorigin(whichfile(s), l, l1);
2603e12c5d1SDavid du Colombier 		break;
2613e12c5d1SDavid du Colombier 
2623e12c5d1SDavid du Colombier 	case Tstartfile:
263*7dd7cddfSDavid du Colombier 		termlocked++;
2643e12c5d1SDavid du Colombier 		f = whichfile(inshort());
2653e12c5d1SDavid du Colombier 		if(!f->rasp)	/* this might be a duplicate message */
2663e12c5d1SDavid du Colombier 			f->rasp = emalloc(sizeof(List));
2673e12c5d1SDavid du Colombier 		current(f);
268219b2ee8SDavid du Colombier 		outTsv(Hbindname, f->tag, invlong());	/* for 64-bit pointers */
2693e12c5d1SDavid du Colombier 		outTs(Hcurrent, f->tag);
2703e12c5d1SDavid du Colombier 		journaln(0, f->tag);
271*7dd7cddfSDavid du Colombier 		if(f->unread)
2723e12c5d1SDavid du Colombier 			load(f);
2733e12c5d1SDavid du Colombier 		else{
274*7dd7cddfSDavid du Colombier 			if(f->nc>0){
275*7dd7cddfSDavid du Colombier 				rgrow(f->rasp, 0L, f->nc);
276*7dd7cddfSDavid du Colombier 				outTsll(Hgrow, f->tag, 0L, f->nc);
2773e12c5d1SDavid du Colombier 			}
2783e12c5d1SDavid du Colombier 			outTs(Hcheck0, f->tag);
2793e12c5d1SDavid du Colombier 			moveto(f, f->dot.r);
2803e12c5d1SDavid du Colombier 		}
2813e12c5d1SDavid du Colombier 		break;
2823e12c5d1SDavid du Colombier 
2833e12c5d1SDavid du Colombier 	case Tworkfile:
2843e12c5d1SDavid du Colombier 		i = inshort();
2853e12c5d1SDavid du Colombier 		f = whichfile(i);
2863e12c5d1SDavid du Colombier 		current(f);
2873e12c5d1SDavid du Colombier 		f->dot.r.p1 = inlong();
2883e12c5d1SDavid du Colombier 		f->dot.r.p2 = inlong();
2893e12c5d1SDavid du Colombier 		f->tdot = f->dot.r;
2903e12c5d1SDavid du Colombier 		journaln(0, i);
2913e12c5d1SDavid du Colombier 		journaln(0, f->dot.r.p1);
2923e12c5d1SDavid du Colombier 		journaln(0, f->dot.r.p2);
2933e12c5d1SDavid du Colombier 		break;
2943e12c5d1SDavid du Colombier 
2953e12c5d1SDavid du Colombier 	case Ttype:
2963e12c5d1SDavid du Colombier 		f = whichfile(inshort());
2973e12c5d1SDavid du Colombier 		p0 = inlong();
2983e12c5d1SDavid du Colombier 		journaln(0, p0);
2993e12c5d1SDavid du Colombier 		journal(0, (char*)inp);
3003e12c5d1SDavid du Colombier 		str = tmpcstr((char*)inp);
3013e12c5d1SDavid du Colombier 		i = str->n;
302*7dd7cddfSDavid du Colombier 		loginsert(f, p0, str->s, str->n);
303*7dd7cddfSDavid du Colombier 		if(fileupdate(f, FALSE, FALSE))
304*7dd7cddfSDavid du Colombier 			seq++;
305*7dd7cddfSDavid du Colombier 		if(f==cmd && p0==f->nc-i && i>0 && str->s[i-1]=='\n'){
3063e12c5d1SDavid du Colombier 			freetmpstr(str);
3073e12c5d1SDavid du Colombier 			termlocked++;
3083e12c5d1SDavid du Colombier 			termcommand();
3093e12c5d1SDavid du Colombier 		}else
3103e12c5d1SDavid du Colombier 			freetmpstr(str);
3113e12c5d1SDavid du Colombier 		f->dot.r.p1 = f->dot.r.p2 = p0+i; /* terminal knows this already */
3123e12c5d1SDavid du Colombier 		f->tdot = f->dot.r;
3133e12c5d1SDavid du Colombier 		break;
3143e12c5d1SDavid du Colombier 
3153e12c5d1SDavid du Colombier 	case Tcut:
3163e12c5d1SDavid du Colombier 		f = whichfile(inshort());
3173e12c5d1SDavid du Colombier 		p0 = inlong();
3183e12c5d1SDavid du Colombier 		p1 = inlong();
3193e12c5d1SDavid du Colombier 		journaln(0, p0);
3203e12c5d1SDavid du Colombier 		journaln(0, p1);
321*7dd7cddfSDavid du Colombier 		logdelete(f, p0, p1);
322*7dd7cddfSDavid du Colombier 		if(fileupdate(f, FALSE, FALSE))
323*7dd7cddfSDavid du Colombier 			seq++;
3243e12c5d1SDavid du Colombier 		f->dot.r.p1 = f->dot.r.p2 = p0;
3253e12c5d1SDavid du Colombier 		f->tdot = f->dot.r;   /* terminal knows the value of dot already */
3263e12c5d1SDavid du Colombier 		break;
3273e12c5d1SDavid du Colombier 
3283e12c5d1SDavid du Colombier 	case Tpaste:
3293e12c5d1SDavid du Colombier 		f = whichfile(inshort());
3303e12c5d1SDavid du Colombier 		p0 = inlong();
3313e12c5d1SDavid du Colombier 		journaln(0, p0);
332*7dd7cddfSDavid du Colombier 		for(l=0; l<snarfbuf.nc; l+=m){
333*7dd7cddfSDavid du Colombier 			m = snarfbuf.nc-l;
3343e12c5d1SDavid du Colombier 			if(m>BLOCKSIZE)
3353e12c5d1SDavid du Colombier 				m = BLOCKSIZE;
336*7dd7cddfSDavid du Colombier 			bufread(&snarfbuf, l, genbuf, m);
337*7dd7cddfSDavid du Colombier 			loginsert(f, p0, tmprstr(genbuf, m)->s, m);
3383e12c5d1SDavid du Colombier 		}
339*7dd7cddfSDavid du Colombier 		if(fileupdate(f, FALSE, TRUE))
340*7dd7cddfSDavid du Colombier 			seq++;
3413e12c5d1SDavid du Colombier 		f->dot.r.p1 = p0;
342*7dd7cddfSDavid du Colombier 		f->dot.r.p2 = p0+snarfbuf.nc;
3433e12c5d1SDavid du Colombier 		f->tdot.p1 = -1; /* force telldot to tell (arguably a BUG) */
3443e12c5d1SDavid du Colombier 		telldot(f);
3453e12c5d1SDavid du Colombier 		outTs(Hunlockfile, f->tag);
3463e12c5d1SDavid du Colombier 		break;
3473e12c5d1SDavid du Colombier 
3483e12c5d1SDavid du Colombier 	case Tsnarf:
3493e12c5d1SDavid du Colombier 		i = inshort();
3503e12c5d1SDavid du Colombier 		p0 = inlong();
3513e12c5d1SDavid du Colombier 		p1 = inlong();
352*7dd7cddfSDavid du Colombier 		snarf(whichfile(i), p0, p1, &snarfbuf, 0);
3533e12c5d1SDavid du Colombier 		break;
3543e12c5d1SDavid du Colombier 
3553e12c5d1SDavid du Colombier 	case Tstartnewfile:
356219b2ee8SDavid du Colombier 		l = invlong();
3573e12c5d1SDavid du Colombier 		Strdupl(&genstr, empty);
3583e12c5d1SDavid du Colombier 		f = newfile();
3593e12c5d1SDavid du Colombier 		f->rasp = emalloc(sizeof(List));
360219b2ee8SDavid du Colombier 		outTsv(Hbindname, f->tag, l);
361*7dd7cddfSDavid du Colombier 		logsetname(f, &genstr);
3623e12c5d1SDavid du Colombier 		outTs(Hcurrent, f->tag);
3633e12c5d1SDavid du Colombier 		current(f);
3643e12c5d1SDavid du Colombier 		load(f);
3653e12c5d1SDavid du Colombier 		break;
3663e12c5d1SDavid du Colombier 
3673e12c5d1SDavid du Colombier 	case Twrite:
3683e12c5d1SDavid du Colombier 		termlocked++;
3693e12c5d1SDavid du Colombier 		i = inshort();
3703e12c5d1SDavid du Colombier 		journaln(0, i);
3713e12c5d1SDavid du Colombier 		f = whichfile(i);
3723e12c5d1SDavid du Colombier 		addr.r.p1 = 0;
373*7dd7cddfSDavid du Colombier 		addr.r.p2 = f->nc;
3743e12c5d1SDavid du Colombier 		if(f->name.s[0] == 0)
3753e12c5d1SDavid du Colombier 			error(Enoname);
3763e12c5d1SDavid du Colombier 		Strduplstr(&genstr, &f->name);
3773e12c5d1SDavid du Colombier 		writef(f);
3783e12c5d1SDavid du Colombier 		break;
3793e12c5d1SDavid du Colombier 
3803e12c5d1SDavid du Colombier 	case Tclose:
381219b2ee8SDavid du Colombier 		termlocked++;
3823e12c5d1SDavid du Colombier 		i = inshort();
3833e12c5d1SDavid du Colombier 		journaln(0, i);
3843e12c5d1SDavid du Colombier 		f = whichfile(i);
3853e12c5d1SDavid du Colombier 		current(f);
3863e12c5d1SDavid du Colombier 		trytoclose(f);
387219b2ee8SDavid du Colombier 		/* if trytoclose fails, will error out */
388219b2ee8SDavid du Colombier 		delete(f);
3893e12c5d1SDavid du Colombier 		break;
3903e12c5d1SDavid du Colombier 
3913e12c5d1SDavid du Colombier 	case Tlook:
3923e12c5d1SDavid du Colombier 		f = whichfile(inshort());
3933e12c5d1SDavid du Colombier 		termlocked++;
3943e12c5d1SDavid du Colombier 		p0 = inlong();
3953e12c5d1SDavid du Colombier 		p1 = inlong();
3963e12c5d1SDavid du Colombier 		journaln(0, p0);
3973e12c5d1SDavid du Colombier 		journaln(0, p1);
3983e12c5d1SDavid du Colombier 		setgenstr(f, p0, p1);
3993e12c5d1SDavid du Colombier 		for(l = 0; l<genstr.n; l++){
4003e12c5d1SDavid du Colombier 			i = genstr.s[l];
4013e12c5d1SDavid du Colombier 			if(utfrune(".*+?(|)\\[]^$", i))
4023e12c5d1SDavid du Colombier 				Strinsert(&genstr, tmpcstr("\\"), l++);
4033e12c5d1SDavid du Colombier 		}
4043e12c5d1SDavid du Colombier 		Straddc(&genstr, '\0');
4053e12c5d1SDavid du Colombier 		nextmatch(f, &genstr, p1, 1);
4063e12c5d1SDavid du Colombier 		moveto(f, sel.p[0]);
4073e12c5d1SDavid du Colombier 		break;
4083e12c5d1SDavid du Colombier 
4093e12c5d1SDavid du Colombier 	case Tsearch:
4103e12c5d1SDavid du Colombier 		termlocked++;
4113e12c5d1SDavid du Colombier 		if(curfile == 0)
4123e12c5d1SDavid du Colombier 			error(Enofile);
4133e12c5d1SDavid du Colombier 		if(lastpat.s[0] == 0)
4143e12c5d1SDavid du Colombier 			panic("Tsearch");
4153e12c5d1SDavid du Colombier 		nextmatch(curfile, &lastpat, curfile->dot.r.p2, 1);
4163e12c5d1SDavid du Colombier 		moveto(curfile, sel.p[0]);
4173e12c5d1SDavid du Colombier 		break;
4183e12c5d1SDavid du Colombier 
4193e12c5d1SDavid du Colombier 	case Tsend:
4203e12c5d1SDavid du Colombier 		termlocked++;
4213e12c5d1SDavid du Colombier 		inshort();	/* ignored */
4223e12c5d1SDavid du Colombier 		p0 = inlong();
4233e12c5d1SDavid du Colombier 		p1 = inlong();
4243e12c5d1SDavid du Colombier 		setgenstr(cmd, p0, p1);
425*7dd7cddfSDavid du Colombier 		bufreset(&snarfbuf);
426*7dd7cddfSDavid du Colombier 		bufinsert(&snarfbuf, (Posn)0, genstr.s, genstr.n);
4273e12c5d1SDavid du Colombier 		outTl(Hsnarflen, genstr.n);
4283e12c5d1SDavid du Colombier 		if(genstr.s[genstr.n-1] != '\n')
4293e12c5d1SDavid du Colombier 			Straddc(&genstr, '\n');
430*7dd7cddfSDavid du Colombier 		loginsert(cmd, cmd->nc, genstr.s, genstr.n);
431*7dd7cddfSDavid du Colombier 		fileupdate(cmd, FALSE, TRUE);
432*7dd7cddfSDavid du Colombier 		cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->nc;
4333e12c5d1SDavid du Colombier 		telldot(cmd);
4343e12c5d1SDavid du Colombier 		termcommand();
4353e12c5d1SDavid du Colombier 		break;
4363e12c5d1SDavid du Colombier 
4373e12c5d1SDavid du Colombier 	case Tdclick:
4383e12c5d1SDavid du Colombier 		f = whichfile(inshort());
4393e12c5d1SDavid du Colombier 		p1 = inlong();
4403e12c5d1SDavid du Colombier 		doubleclick(f, p1);
4413e12c5d1SDavid du Colombier 		f->tdot.p1 = f->tdot.p2 = p1;
4423e12c5d1SDavid du Colombier 		telldot(f);
4433e12c5d1SDavid du Colombier 		outTs(Hunlockfile, f->tag);
4443e12c5d1SDavid du Colombier 		break;
4453e12c5d1SDavid du Colombier 
4463e12c5d1SDavid du Colombier 	case Tstartsnarf:
447*7dd7cddfSDavid du Colombier 		if (snarfbuf.nc <= 0) {	/* nothing to export */
448219b2ee8SDavid du Colombier 			outTs(Hsetsnarf, 0);
449219b2ee8SDavid du Colombier 			break;
4503e12c5d1SDavid du Colombier 		}
451219b2ee8SDavid du Colombier 		c = 0;
4523e12c5d1SDavid du Colombier 		i = 0;
453*7dd7cddfSDavid du Colombier 		m = snarfbuf.nc;
454*7dd7cddfSDavid du Colombier 		if(m > SNARFSIZE) {
455*7dd7cddfSDavid du Colombier 			m = SNARFSIZE;
456*7dd7cddfSDavid du Colombier 			dprint("?warning: snarf buffer truncated\n");
457*7dd7cddfSDavid du Colombier 		}
458*7dd7cddfSDavid du Colombier 		rp = malloc(m*sizeof(Rune));
459219b2ee8SDavid du Colombier 		if(rp){
460*7dd7cddfSDavid du Colombier 			bufread(&snarfbuf, 0, rp, m);
461*7dd7cddfSDavid du Colombier 			c = Strtoc(tmprstr(rp, m));
462219b2ee8SDavid du Colombier 			free(rp);
463219b2ee8SDavid du Colombier 			i = strlen(c);
4643e12c5d1SDavid du Colombier 		}
4653e12c5d1SDavid du Colombier 		outTs(Hsetsnarf, i);
466219b2ee8SDavid du Colombier 		if(c){
4673e12c5d1SDavid du Colombier 			Write(1, c, i);
4683e12c5d1SDavid du Colombier 			free(c);
469219b2ee8SDavid du Colombier 		} else
470219b2ee8SDavid du Colombier 			dprint("snarf buffer too long\n");
4713e12c5d1SDavid du Colombier 		break;
4723e12c5d1SDavid du Colombier 
4733e12c5d1SDavid du Colombier 	case Tsetsnarf:
4743e12c5d1SDavid du Colombier 		m = inshort();
4753e12c5d1SDavid du Colombier 		if(m > SNARFSIZE)
4763e12c5d1SDavid du Colombier 			error(Etoolong);
4773e12c5d1SDavid du Colombier 		c = malloc(m+1);
4783e12c5d1SDavid du Colombier 		if(c){
4793e12c5d1SDavid du Colombier 			for(i=0; i<m; i++)
4803e12c5d1SDavid du Colombier 				c[i] = rcvchar();
4813e12c5d1SDavid du Colombier 			c[m] = 0;
4823e12c5d1SDavid du Colombier 			str = tmpcstr(c);
4833e12c5d1SDavid du Colombier 			free(c);
484*7dd7cddfSDavid du Colombier 			bufreset(&snarfbuf);
485*7dd7cddfSDavid du Colombier 			bufinsert(&snarfbuf, (Posn)0, str->s, str->n);
4863e12c5d1SDavid du Colombier 			freetmpstr(str);
4873e12c5d1SDavid du Colombier 			outT0(Hunlock);
4883e12c5d1SDavid du Colombier 		}
4893e12c5d1SDavid du Colombier 		break;
4903e12c5d1SDavid du Colombier 
4913e12c5d1SDavid du Colombier 	case Tack:
4923e12c5d1SDavid du Colombier 		waitack = 0;
4933e12c5d1SDavid du Colombier 		break;
4943e12c5d1SDavid du Colombier 
495*7dd7cddfSDavid du Colombier 	case Tplumb:
496*7dd7cddfSDavid du Colombier 		f = whichfile(inshort());
497*7dd7cddfSDavid du Colombier 		p0 = inlong();
498*7dd7cddfSDavid du Colombier 		p1 = inlong();
499*7dd7cddfSDavid du Colombier 		pm = emalloc(sizeof(Plumbmsg));
500*7dd7cddfSDavid du Colombier 		pm->src = strdup("sam");
501*7dd7cddfSDavid du Colombier 		pm->dst = 0;
502*7dd7cddfSDavid du Colombier 		pm->wdir = emalloc(1024);
503*7dd7cddfSDavid du Colombier 		getwd(pm->wdir, 1024);
504*7dd7cddfSDavid du Colombier 		pm->type = strdup("text");
505*7dd7cddfSDavid du Colombier 		if(p1 > p0)
506*7dd7cddfSDavid du Colombier 			pm->attr = nil;
507*7dd7cddfSDavid du Colombier 		else{
508*7dd7cddfSDavid du Colombier 			p = p0;
509*7dd7cddfSDavid du Colombier 			while(p0>0 && (i=filereadc(f, p0 - 1))!=' ' && i!='\t' && i!='\n')
510*7dd7cddfSDavid du Colombier 				p0--;
511*7dd7cddfSDavid du Colombier 			while(p1<f->nc && (i=filereadc(f, p1))!=' ' && i!='\t' && i!='\n')
512*7dd7cddfSDavid du Colombier 				p1++;
513*7dd7cddfSDavid du Colombier 			sprint(cbuf, "click=%ld", p-p0);
514*7dd7cddfSDavid du Colombier 			pm->attr = plumbunpackattr(cbuf);
515*7dd7cddfSDavid du Colombier 		}
516*7dd7cddfSDavid du Colombier 		if(p0==p1 || p1-p0>=BLOCKSIZE){
517*7dd7cddfSDavid du Colombier 			plumbfree(pm);
518*7dd7cddfSDavid du Colombier 			break;
519*7dd7cddfSDavid du Colombier 		}
520*7dd7cddfSDavid du Colombier 		setgenstr(f, p0, p1);
521*7dd7cddfSDavid du Colombier 		pm->data = Strtoc(&genstr);
522*7dd7cddfSDavid du Colombier 		pm->ndata = strlen(pm->data);
523*7dd7cddfSDavid du Colombier 		c = plumbpack(pm, &i);
524*7dd7cddfSDavid du Colombier 		if(c != 0){
525*7dd7cddfSDavid du Colombier 			outTs(Hplumb, i);
526*7dd7cddfSDavid du Colombier 			Write(1, c, i);
527*7dd7cddfSDavid du Colombier 			free(c);
528*7dd7cddfSDavid du Colombier 		}
529*7dd7cddfSDavid du Colombier 		plumbfree(pm);
530*7dd7cddfSDavid du Colombier 		break;
531*7dd7cddfSDavid du Colombier 
5323e12c5d1SDavid du Colombier 	case Texit:
5333e12c5d1SDavid du Colombier 		exits(0);
5343e12c5d1SDavid du Colombier 	}
5353e12c5d1SDavid du Colombier 	return TRUE;
5363e12c5d1SDavid du Colombier }
5373e12c5d1SDavid du Colombier 
5383e12c5d1SDavid du Colombier void
5393e12c5d1SDavid du Colombier snarf(File *f, Posn p1, Posn p2, Buffer *buf, int emptyok)
5403e12c5d1SDavid du Colombier {
5413e12c5d1SDavid du Colombier 	Posn l;
5423e12c5d1SDavid du Colombier 	int i;
5433e12c5d1SDavid du Colombier 
5443e12c5d1SDavid du Colombier 	if(!emptyok && p1==p2)
5453e12c5d1SDavid du Colombier 		return;
546*7dd7cddfSDavid du Colombier 	bufreset(buf);
5473e12c5d1SDavid du Colombier 	/* Stage through genbuf to avoid compaction problems (vestigial) */
548*7dd7cddfSDavid du Colombier 	if(p2 > f->nc){
549*7dd7cddfSDavid du Colombier 		fprint(2, "bad snarf addr p1=%ld p2=%ld f->nc=%d\n", p1, p2, f->nc); /*ZZZ should never happen, can remove */
550*7dd7cddfSDavid du Colombier 		p2 = f->nc;
551*7dd7cddfSDavid du Colombier 	}
5523e12c5d1SDavid du Colombier 	for(l=p1; l<p2; l+=i){
5533e12c5d1SDavid du Colombier 		i = p2-l>BLOCKSIZE? BLOCKSIZE : p2-l;
554*7dd7cddfSDavid du Colombier 		bufread(f, l, genbuf, i);
555*7dd7cddfSDavid du Colombier 		bufinsert(buf, buf->nc, tmprstr(genbuf, i)->s, i);
5563e12c5d1SDavid du Colombier 	}
5573e12c5d1SDavid du Colombier }
5583e12c5d1SDavid du Colombier 
5593e12c5d1SDavid du Colombier int
5603e12c5d1SDavid du Colombier inshort(void)
5613e12c5d1SDavid du Colombier {
5623e12c5d1SDavid du Colombier 	ushort n;
5633e12c5d1SDavid du Colombier 
5643e12c5d1SDavid du Colombier 	n = inp[0] | (inp[1]<<8);
5653e12c5d1SDavid du Colombier 	inp += 2;
5663e12c5d1SDavid du Colombier 	return n;
5673e12c5d1SDavid du Colombier }
5683e12c5d1SDavid du Colombier 
5693e12c5d1SDavid du Colombier long
5703e12c5d1SDavid du Colombier inlong(void)
5713e12c5d1SDavid du Colombier {
5723e12c5d1SDavid du Colombier 	ulong n;
5733e12c5d1SDavid du Colombier 
5743e12c5d1SDavid du Colombier 	n = inp[0] | (inp[1]<<8) | (inp[2]<<16) | (inp[3]<<24);
5753e12c5d1SDavid du Colombier 	inp += 4;
5763e12c5d1SDavid du Colombier 	return n;
5773e12c5d1SDavid du Colombier }
5783e12c5d1SDavid du Colombier 
579219b2ee8SDavid du Colombier long
580219b2ee8SDavid du Colombier invlong(void)
581219b2ee8SDavid du Colombier {
582219b2ee8SDavid du Colombier 	ulong n;
583219b2ee8SDavid du Colombier 
584219b2ee8SDavid du Colombier 	n = (inp[7]<<24) | (inp[6]<<16) | (inp[5]<<8) | inp[4];
585219b2ee8SDavid du Colombier 	n = (n<<16) | (inp[3]<<8) | inp[2];
586219b2ee8SDavid du Colombier 	n = (n<<16) | (inp[1]<<8) | inp[0];
587219b2ee8SDavid du Colombier 	inp += 8;
588219b2ee8SDavid du Colombier 	return n;
589219b2ee8SDavid du Colombier }
590219b2ee8SDavid du Colombier 
5913e12c5d1SDavid du Colombier void
5923e12c5d1SDavid du Colombier setgenstr(File *f, Posn p0, Posn p1)
5933e12c5d1SDavid du Colombier {
5943e12c5d1SDavid du Colombier 	if(p0 != p1){
5953e12c5d1SDavid du Colombier 		if(p1-p0 >= TBLOCKSIZE)
5963e12c5d1SDavid du Colombier 			error(Etoolong);
5973e12c5d1SDavid du Colombier 		Strinsure(&genstr, p1-p0);
598*7dd7cddfSDavid du Colombier 		bufread(f, p0, genbuf, p1-p0);
5993e12c5d1SDavid du Colombier 		memmove(genstr.s, genbuf, RUNESIZE*(p1-p0));
6003e12c5d1SDavid du Colombier 		genstr.n = p1-p0;
6013e12c5d1SDavid du Colombier 	}else{
602*7dd7cddfSDavid du Colombier 		if(snarfbuf.nc == 0)
6033e12c5d1SDavid du Colombier 			error(Eempty);
604*7dd7cddfSDavid du Colombier 		if(snarfbuf.nc > TBLOCKSIZE)
6053e12c5d1SDavid du Colombier 			error(Etoolong);
606*7dd7cddfSDavid du Colombier 		bufread(&snarfbuf, (Posn)0, genbuf, snarfbuf.nc);
607*7dd7cddfSDavid du Colombier 		Strinsure(&genstr, snarfbuf.nc);
608*7dd7cddfSDavid du Colombier 		memmove(genstr.s, genbuf, RUNESIZE*snarfbuf.nc);
609*7dd7cddfSDavid du Colombier 		genstr.n = snarfbuf.nc;
6103e12c5d1SDavid du Colombier 	}
6113e12c5d1SDavid du Colombier }
6123e12c5d1SDavid du Colombier 
6133e12c5d1SDavid du Colombier void
6143e12c5d1SDavid du Colombier outT0(Hmesg type)
6153e12c5d1SDavid du Colombier {
6163e12c5d1SDavid du Colombier 	outstart(type);
6173e12c5d1SDavid du Colombier 	outsend();
6183e12c5d1SDavid du Colombier }
6193e12c5d1SDavid du Colombier 
6203e12c5d1SDavid du Colombier void
6213e12c5d1SDavid du Colombier outTl(Hmesg type, long l)
6223e12c5d1SDavid du Colombier {
6233e12c5d1SDavid du Colombier 	outstart(type);
6243e12c5d1SDavid du Colombier 	outlong(l);
6253e12c5d1SDavid du Colombier 	outsend();
6263e12c5d1SDavid du Colombier }
6273e12c5d1SDavid du Colombier 
6283e12c5d1SDavid du Colombier void
6293e12c5d1SDavid du Colombier outTs(Hmesg type, int s)
6303e12c5d1SDavid du Colombier {
6313e12c5d1SDavid du Colombier 	outstart(type);
6323e12c5d1SDavid du Colombier 	journaln(1, s);
6333e12c5d1SDavid du Colombier 	outshort(s);
6343e12c5d1SDavid du Colombier 	outsend();
6353e12c5d1SDavid du Colombier }
6363e12c5d1SDavid du Colombier 
6373e12c5d1SDavid du Colombier void
6383e12c5d1SDavid du Colombier outS(String *s)
6393e12c5d1SDavid du Colombier {
6403e12c5d1SDavid du Colombier 	char *c;
6413e12c5d1SDavid du Colombier 	int i;
6423e12c5d1SDavid du Colombier 
6433e12c5d1SDavid du Colombier 	c = Strtoc(s);
6443e12c5d1SDavid du Colombier 	i = strlen(c);
6453e12c5d1SDavid du Colombier 	outcopy(i, c);
6463e12c5d1SDavid du Colombier 	if(i > 99)
6473e12c5d1SDavid du Colombier 		c[99] = 0;
6483e12c5d1SDavid du Colombier 	journaln(1, i);
6493e12c5d1SDavid du Colombier 	journal(1, c);
6503e12c5d1SDavid du Colombier 	free(c);
6513e12c5d1SDavid du Colombier }
6523e12c5d1SDavid du Colombier 
6533e12c5d1SDavid du Colombier void
6543e12c5d1SDavid du Colombier outTsS(Hmesg type, int s1, String *s)
6553e12c5d1SDavid du Colombier {
6563e12c5d1SDavid du Colombier 	outstart(type);
6573e12c5d1SDavid du Colombier 	outshort(s1);
6583e12c5d1SDavid du Colombier 	outS(s);
6593e12c5d1SDavid du Colombier 	outsend();
6603e12c5d1SDavid du Colombier }
6613e12c5d1SDavid du Colombier 
6623e12c5d1SDavid du Colombier void
6633e12c5d1SDavid du Colombier outTslS(Hmesg type, int s1, Posn l1, String *s)
6643e12c5d1SDavid du Colombier {
6653e12c5d1SDavid du Colombier 	outstart(type);
6663e12c5d1SDavid du Colombier 	outshort(s1);
6673e12c5d1SDavid du Colombier 	journaln(1, s1);
6683e12c5d1SDavid du Colombier 	outlong(l1);
6693e12c5d1SDavid du Colombier 	journaln(1, l1);
6703e12c5d1SDavid du Colombier 	outS(s);
6713e12c5d1SDavid du Colombier 	outsend();
6723e12c5d1SDavid du Colombier }
6733e12c5d1SDavid du Colombier 
6743e12c5d1SDavid du Colombier void
6753e12c5d1SDavid du Colombier outTS(Hmesg type, String *s)
6763e12c5d1SDavid du Colombier {
6773e12c5d1SDavid du Colombier 	outstart(type);
6783e12c5d1SDavid du Colombier 	outS(s);
6793e12c5d1SDavid du Colombier 	outsend();
6803e12c5d1SDavid du Colombier }
6813e12c5d1SDavid du Colombier 
6823e12c5d1SDavid du Colombier void
6833e12c5d1SDavid du Colombier outTsllS(Hmesg type, int s1, Posn l1, Posn l2, String *s)
6843e12c5d1SDavid du Colombier {
6853e12c5d1SDavid du Colombier 	outstart(type);
6863e12c5d1SDavid du Colombier 	outshort(s1);
6873e12c5d1SDavid du Colombier 	outlong(l1);
6883e12c5d1SDavid du Colombier 	outlong(l2);
6893e12c5d1SDavid du Colombier 	journaln(1, l1);
6903e12c5d1SDavid du Colombier 	journaln(1, l2);
6913e12c5d1SDavid du Colombier 	outS(s);
6923e12c5d1SDavid du Colombier 	outsend();
6933e12c5d1SDavid du Colombier }
6943e12c5d1SDavid du Colombier 
6953e12c5d1SDavid du Colombier void
6963e12c5d1SDavid du Colombier outTsll(Hmesg type, int s, Posn l1, Posn l2)
6973e12c5d1SDavid du Colombier {
6983e12c5d1SDavid du Colombier 	outstart(type);
6993e12c5d1SDavid du Colombier 	outshort(s);
7003e12c5d1SDavid du Colombier 	outlong(l1);
7013e12c5d1SDavid du Colombier 	outlong(l2);
7023e12c5d1SDavid du Colombier 	journaln(1, l1);
7033e12c5d1SDavid du Colombier 	journaln(1, l2);
7043e12c5d1SDavid du Colombier 	outsend();
7053e12c5d1SDavid du Colombier }
7063e12c5d1SDavid du Colombier 
7073e12c5d1SDavid du Colombier void
7083e12c5d1SDavid du Colombier outTsl(Hmesg type, int s, Posn l)
7093e12c5d1SDavid du Colombier {
7103e12c5d1SDavid du Colombier 	outstart(type);
7113e12c5d1SDavid du Colombier 	outshort(s);
7123e12c5d1SDavid du Colombier 	outlong(l);
7133e12c5d1SDavid du Colombier 	journaln(1, l);
7143e12c5d1SDavid du Colombier 	outsend();
7153e12c5d1SDavid du Colombier }
7163e12c5d1SDavid du Colombier 
7173e12c5d1SDavid du Colombier void
718219b2ee8SDavid du Colombier outTsv(Hmesg type, int s, Posn l)
719219b2ee8SDavid du Colombier {
720219b2ee8SDavid du Colombier 	outstart(type);
721219b2ee8SDavid du Colombier 	outshort(s);
722219b2ee8SDavid du Colombier 	outvlong((void*)l);
723219b2ee8SDavid du Colombier 	journaln(1, l);
724219b2ee8SDavid du Colombier 	outsend();
725219b2ee8SDavid du Colombier }
726219b2ee8SDavid du Colombier 
727219b2ee8SDavid du Colombier void
7283e12c5d1SDavid du Colombier outstart(Hmesg type)
7293e12c5d1SDavid du Colombier {
7303e12c5d1SDavid du Colombier 	journal(1, hname[type]);
7313e12c5d1SDavid du Colombier 	outmsg[0] = type;
7323e12c5d1SDavid du Colombier 	outp = outmsg+3;
7333e12c5d1SDavid du Colombier }
7343e12c5d1SDavid du Colombier 
7353e12c5d1SDavid du Colombier void
7363e12c5d1SDavid du Colombier outcopy(int count, void *data)
7373e12c5d1SDavid du Colombier {
7383e12c5d1SDavid du Colombier 	memmove(outp, data, count);
7393e12c5d1SDavid du Colombier 	outp += count;
7403e12c5d1SDavid du Colombier }
7413e12c5d1SDavid du Colombier 
7423e12c5d1SDavid du Colombier void
7433e12c5d1SDavid du Colombier outshort(int s)
7443e12c5d1SDavid du Colombier {
7453e12c5d1SDavid du Colombier 	*outp++ = s;
7463e12c5d1SDavid du Colombier 	*outp++ = s>>8;
7473e12c5d1SDavid du Colombier }
7483e12c5d1SDavid du Colombier 
7493e12c5d1SDavid du Colombier void
7503e12c5d1SDavid du Colombier outlong(long l)
7513e12c5d1SDavid du Colombier {
7523e12c5d1SDavid du Colombier 	*outp++ = l;
7533e12c5d1SDavid du Colombier 	*outp++ = l>>8;
7543e12c5d1SDavid du Colombier 	*outp++ = l>>16;
7553e12c5d1SDavid du Colombier 	*outp++ = l>>24;
7563e12c5d1SDavid du Colombier }
7573e12c5d1SDavid du Colombier 
7583e12c5d1SDavid du Colombier void
759219b2ee8SDavid du Colombier outvlong(void *v)
760219b2ee8SDavid du Colombier {
761219b2ee8SDavid du Colombier 	int i;
762219b2ee8SDavid du Colombier 	ulong l;
763219b2ee8SDavid du Colombier 
764219b2ee8SDavid du Colombier 	l = (ulong) v;
765219b2ee8SDavid du Colombier 	for(i = 0; i < 8; i++, l >>= 8)
766219b2ee8SDavid du Colombier 		*outp++ = l;
767219b2ee8SDavid du Colombier }
768219b2ee8SDavid du Colombier 
769219b2ee8SDavid du Colombier void
7703e12c5d1SDavid du Colombier outsend(void)
7713e12c5d1SDavid du Colombier {
7723e12c5d1SDavid du Colombier 	int outcount;
7733e12c5d1SDavid du Colombier 
7743e12c5d1SDavid du Colombier 	outcount = outp-outmsg;
7753e12c5d1SDavid du Colombier 	outcount -= 3;
7763e12c5d1SDavid du Colombier 	outmsg[1] = outcount;
7773e12c5d1SDavid du Colombier 	outmsg[2] = outcount>>8;
7783e12c5d1SDavid du Colombier 	outmsg = outp;
7793e12c5d1SDavid du Colombier 	if(!noflush){
780bd389b36SDavid du Colombier 		outcount = outmsg-outdata;
781bd389b36SDavid du Colombier 		if (write(1, (char*) outdata, outcount) != outcount)
782bd389b36SDavid du Colombier 			rescue();
7833e12c5d1SDavid du Colombier 		outmsg = outdata;
7843e12c5d1SDavid du Colombier 		return;
7853e12c5d1SDavid du Colombier 	}
7863e12c5d1SDavid du Colombier 	if(outmsg < outdata+DATASIZE)
7873e12c5d1SDavid du Colombier 		return;
7883e12c5d1SDavid du Colombier 	outflush();
7893e12c5d1SDavid du Colombier }
7903e12c5d1SDavid du Colombier 
7913e12c5d1SDavid du Colombier void
7923e12c5d1SDavid du Colombier outflush(void)
7933e12c5d1SDavid du Colombier {
7943e12c5d1SDavid du Colombier 	if(outmsg == outdata)
7953e12c5d1SDavid du Colombier 		return;
7963e12c5d1SDavid du Colombier 	noflush = 0;
7973e12c5d1SDavid du Colombier 	outT0(Hack);
7983e12c5d1SDavid du Colombier 	waitack = 1;
7993e12c5d1SDavid du Colombier 	do
8003e12c5d1SDavid du Colombier 		if(rcv() == 0){
8013e12c5d1SDavid du Colombier 			rescue();
8023e12c5d1SDavid du Colombier 			exits("eof");
8033e12c5d1SDavid du Colombier 		}
8043e12c5d1SDavid du Colombier 	while(waitack);
8053e12c5d1SDavid du Colombier 	outmsg = outdata;
8063e12c5d1SDavid du Colombier 	noflush = 1;
8073e12c5d1SDavid du Colombier }
808