xref: /plan9/sys/src/cmd/sam/mesg.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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;
113e12c5d1SDavid 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);
17*219b2ee8SDavid 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",
493e12c5d1SDavid du Colombier };
503e12c5d1SDavid du Colombier 
513e12c5d1SDavid du Colombier char *tname[] = {
523e12c5d1SDavid du Colombier 	[Tversion]	"Tversion",
533e12c5d1SDavid du Colombier 	[Tstartcmdfile]	"Tstartcmdfile",
543e12c5d1SDavid du Colombier 	[Tcheck]	"Tcheck",
553e12c5d1SDavid du Colombier 	[Trequest]	"Trequest",
563e12c5d1SDavid du Colombier 	[Torigin]	"Torigin",
573e12c5d1SDavid du Colombier 	[Tstartfile]	"Tstartfile",
583e12c5d1SDavid du Colombier 	[Tworkfile]	"Tworkfile",
593e12c5d1SDavid du Colombier 	[Ttype]		"Ttype",
603e12c5d1SDavid du Colombier 	[Tcut]		"Tcut",
613e12c5d1SDavid du Colombier 	[Tpaste]	"Tpaste",
623e12c5d1SDavid du Colombier 	[Tsnarf]	"Tsnarf",
633e12c5d1SDavid du Colombier 	[Tstartnewfile]	"Tstartnewfile",
643e12c5d1SDavid du Colombier 	[Twrite]	"Twrite",
653e12c5d1SDavid du Colombier 	[Tclose]	"Tclose",
663e12c5d1SDavid du Colombier 	[Tlook]		"Tlook",
67*219b2ee8SDavid du Colombier 	[Tsearch]	"Tsearch",
683e12c5d1SDavid du Colombier 	[Tsend]		"Tsend",
69*219b2ee8SDavid du Colombier 	[Tdclick]	"Tdclick",
703e12c5d1SDavid du Colombier 	[Tstartsnarf]	"Tstartsnarf",
713e12c5d1SDavid du Colombier 	[Tsetsnarf]	"Tsetsnarf",
723e12c5d1SDavid du Colombier 	[Tack]		"Tack",
733e12c5d1SDavid du Colombier 	[Texit]		"Texit",
743e12c5d1SDavid du Colombier };
753e12c5d1SDavid du Colombier 
763e12c5d1SDavid du Colombier void
773e12c5d1SDavid du Colombier journal(int out, char *s)
783e12c5d1SDavid du Colombier {
79*219b2ee8SDavid du Colombier 	static int fd = 0;
803e12c5d1SDavid du Colombier 
813e12c5d1SDavid du Colombier 	if(fd <= 0)
823e12c5d1SDavid du Colombier 		fd = create("/tmp/sam.out", 1, 0666L);
833e12c5d1SDavid du Colombier 	fprint(fd, "%s%s\n", out? "out: " : "in:  ", s);
843e12c5d1SDavid du Colombier }
853e12c5d1SDavid du Colombier 
86bd389b36SDavid du Colombier void
87*219b2ee8SDavid du Colombier journaln(int out, long n)
883e12c5d1SDavid du Colombier {
893e12c5d1SDavid du Colombier 	char buf[32];
903e12c5d1SDavid du Colombier 	sprint(buf, "%d", n);
913e12c5d1SDavid du Colombier 	journal(out, buf);
923e12c5d1SDavid du Colombier }
933e12c5d1SDavid du Colombier #else
943e12c5d1SDavid du Colombier #define	journal(a, b)
953e12c5d1SDavid du Colombier #define journaln(a, b)
963e12c5d1SDavid du Colombier #endif
973e12c5d1SDavid du Colombier 
983e12c5d1SDavid du Colombier int
993e12c5d1SDavid du Colombier rcvchar(void){
1003e12c5d1SDavid du Colombier 	static uchar buf[64];
1013e12c5d1SDavid du Colombier 	static i, nleft = 0;
1023e12c5d1SDavid du Colombier 
1033e12c5d1SDavid du Colombier 	if(nleft <= 0){
1043e12c5d1SDavid du Colombier 		nleft = read(0, (char *)buf, sizeof buf);
1053e12c5d1SDavid du Colombier 		if(nleft <= 0)
1063e12c5d1SDavid du Colombier 			return -1;
1073e12c5d1SDavid du Colombier 		i = 0;
1083e12c5d1SDavid du Colombier 	}
1093e12c5d1SDavid du Colombier 	--nleft;
1103e12c5d1SDavid du Colombier 	return buf[i++];
1113e12c5d1SDavid du Colombier }
1123e12c5d1SDavid du Colombier 
1133e12c5d1SDavid du Colombier int
1143e12c5d1SDavid du Colombier rcv(void){
1153e12c5d1SDavid du Colombier 	int c;
1163e12c5d1SDavid du Colombier 	static state = 0;
1173e12c5d1SDavid du Colombier 	static count = 0;
1183e12c5d1SDavid du Colombier 	static i = 0;
1193e12c5d1SDavid du Colombier 
1203e12c5d1SDavid du Colombier 	while((c=rcvchar()) != -1)
1213e12c5d1SDavid du Colombier 		switch(state){
1223e12c5d1SDavid du Colombier 		case 0:
1233e12c5d1SDavid du Colombier 			h.type = c;
1243e12c5d1SDavid du Colombier 			state++;
1253e12c5d1SDavid du Colombier 			break;
1263e12c5d1SDavid du Colombier 
1273e12c5d1SDavid du Colombier 		case 1:
1283e12c5d1SDavid du Colombier 			h.count0 = c;
1293e12c5d1SDavid du Colombier 			state++;
1303e12c5d1SDavid du Colombier 			break;
1313e12c5d1SDavid du Colombier 
1323e12c5d1SDavid du Colombier 		case 2:
1333e12c5d1SDavid du Colombier 			h.count1 = c;
1343e12c5d1SDavid du Colombier 			count = h.count0|(h.count1<<8);
1353e12c5d1SDavid du Colombier 			i = 0;
1363e12c5d1SDavid du Colombier 			if(count > DATASIZE)
1373e12c5d1SDavid du Colombier 				panic("count>DATASIZE");
1383e12c5d1SDavid du Colombier 			if(count == 0)
1393e12c5d1SDavid du Colombier 				goto zerocount;
1403e12c5d1SDavid du Colombier 			state++;
1413e12c5d1SDavid du Colombier 			break;
1423e12c5d1SDavid du Colombier 
1433e12c5d1SDavid du Colombier 		case 3:
1443e12c5d1SDavid du Colombier 			indata[i++] = c;
1453e12c5d1SDavid du Colombier 			if(i == count){
1463e12c5d1SDavid du Colombier 		zerocount:
1473e12c5d1SDavid du Colombier 				indata[i] = 0;
1483e12c5d1SDavid du Colombier 				state = count = 0;
1493e12c5d1SDavid du Colombier 				return inmesg(h.type);
1503e12c5d1SDavid du Colombier 			}
1513e12c5d1SDavid du Colombier 			break;
1523e12c5d1SDavid du Colombier 		}
1533e12c5d1SDavid du Colombier 	return 0;
1543e12c5d1SDavid du Colombier }
1553e12c5d1SDavid du Colombier 
1563e12c5d1SDavid du Colombier File *
1573e12c5d1SDavid du Colombier whichfile(int tag)
1583e12c5d1SDavid du Colombier {
1593e12c5d1SDavid du Colombier 	int i;
1603e12c5d1SDavid du Colombier 
1613e12c5d1SDavid du Colombier 	for(i = 0; i<file.nused; i++)
1623e12c5d1SDavid du Colombier 		if(file.filepptr[i]->tag==tag)
1633e12c5d1SDavid du Colombier 			return file.filepptr[i];
1643e12c5d1SDavid du Colombier 	hiccough((char *)0);
1653e12c5d1SDavid du Colombier 	return 0;
1663e12c5d1SDavid du Colombier }
1673e12c5d1SDavid du Colombier 
1683e12c5d1SDavid du Colombier int
1693e12c5d1SDavid du Colombier inmesg(Tmesg type)
1703e12c5d1SDavid du Colombier {
1713e12c5d1SDavid du Colombier 	Rune buf[1025];
1723e12c5d1SDavid du Colombier 	int i, m;
1733e12c5d1SDavid du Colombier 	short s;
1743e12c5d1SDavid du Colombier 	long l, l1;
1753e12c5d1SDavid du Colombier 	File *f;
1763e12c5d1SDavid du Colombier 	Posn p0, p1;
1773e12c5d1SDavid du Colombier 	Range r;
1783e12c5d1SDavid du Colombier 	String *str;
1793e12c5d1SDavid du Colombier 	char *c;
180*219b2ee8SDavid du Colombier 	Rune *rp;
1813e12c5d1SDavid du Colombier 
1823e12c5d1SDavid du Colombier 	if(type > TMAX)
1833e12c5d1SDavid du Colombier 		panic("inmesg");
1843e12c5d1SDavid du Colombier 
1853e12c5d1SDavid du Colombier 	journal(0, tname[type]);
1863e12c5d1SDavid du Colombier 
1873e12c5d1SDavid du Colombier 	inp = indata;
1883e12c5d1SDavid du Colombier 	switch(type){
1893e12c5d1SDavid du Colombier 	case -1:
1903e12c5d1SDavid du Colombier 		panic("rcv error");
1913e12c5d1SDavid du Colombier 
1923e12c5d1SDavid du Colombier 	default:
1933e12c5d1SDavid du Colombier 		fprint(2, "unknown type %d\n", type);
1943e12c5d1SDavid du Colombier 		panic("rcv unknown");
1953e12c5d1SDavid du Colombier 
1963e12c5d1SDavid du Colombier 	case Tversion:
1973e12c5d1SDavid du Colombier 		tversion = inshort();
1983e12c5d1SDavid du Colombier 		journaln(0, tversion);
1993e12c5d1SDavid du Colombier 		break;
2003e12c5d1SDavid du Colombier 
2013e12c5d1SDavid du Colombier 	case Tstartcmdfile:
202*219b2ee8SDavid du Colombier 		l = invlong();		/* for 64-bit pointers */
2033e12c5d1SDavid du Colombier 		journaln(0, l);
2043e12c5d1SDavid du Colombier 		Strdupl(&genstr, samname);
2053e12c5d1SDavid du Colombier 		cmd = newfile();
206*219b2ee8SDavid du Colombier 		outTsv(Hbindname, cmd->tag, l);
2073e12c5d1SDavid du Colombier 		outTs(Hcurrent, cmd->tag);
2083e12c5d1SDavid du Colombier 		Fsetname(cmd, &genstr);
2093e12c5d1SDavid du Colombier 		cmd->rasp = emalloc(sizeof(List));
2103e12c5d1SDavid du Colombier 		cmd->state = Clean;
2113e12c5d1SDavid du Colombier 		if(cmdstr.n){
2123e12c5d1SDavid du Colombier 			Finsert(cmd, &cmdstr, 0L);
2133e12c5d1SDavid du Colombier 			Strdelete(&cmdstr, 0L, (Posn)cmdstr.n);
2143e12c5d1SDavid du Colombier 		}
2153e12c5d1SDavid du Colombier 		Fupdate(cmd, FALSE, TRUE);
2163e12c5d1SDavid du Colombier 		outT0(Hunlock);
2173e12c5d1SDavid du Colombier 		break;
2183e12c5d1SDavid du Colombier 
2193e12c5d1SDavid du Colombier 	case Tcheck:
2203e12c5d1SDavid du Colombier 		/* go through whichfile to check the tag */
2213e12c5d1SDavid du Colombier 		outTs(Hcheck, whichfile(inshort())->tag);
2223e12c5d1SDavid du Colombier 		break;
2233e12c5d1SDavid du Colombier 
2243e12c5d1SDavid du Colombier 	case Trequest:
2253e12c5d1SDavid du Colombier 		f = whichfile(inshort());
2263e12c5d1SDavid du Colombier 		p0 = inlong();
2273e12c5d1SDavid du Colombier 		p1 = p0+inshort();
2283e12c5d1SDavid du Colombier 		journaln(0, p0);
2293e12c5d1SDavid du Colombier 		journaln(0, p1-p0);
2303e12c5d1SDavid du Colombier 		if(f->state == Unread)
2313e12c5d1SDavid du Colombier 			panic("Trequest: unread");
2323e12c5d1SDavid du Colombier 		if(p1>f->nrunes)
2333e12c5d1SDavid du Colombier 			p1 = f->nrunes;
2343e12c5d1SDavid du Colombier 		if(p0>f->nrunes) /* can happen e.g. scrolling during command */
2353e12c5d1SDavid du Colombier 			p0 = f->nrunes;
2363e12c5d1SDavid du Colombier 		if(p0 == p1){
2373e12c5d1SDavid du Colombier 			i = 0;
2383e12c5d1SDavid du Colombier 			r.p1 = r.p2 = p0;
2393e12c5d1SDavid du Colombier 		}else{
2403e12c5d1SDavid du Colombier 			r = rdata(f->rasp, p0, p1-p0);
2413e12c5d1SDavid du Colombier 			i = r.p2-r.p1;
2423e12c5d1SDavid du Colombier 			if(Fchars(f, buf, r.p1, r.p2)!=i)
2433e12c5d1SDavid du Colombier 				panic("Trequest 2");
2443e12c5d1SDavid du Colombier 		}
2453e12c5d1SDavid du Colombier 		buf[i]=0;
2463e12c5d1SDavid du Colombier 		outTslS(Hdata, f->tag, r.p1, tmprstr(buf, i+1));
2473e12c5d1SDavid du Colombier 		break;
2483e12c5d1SDavid du Colombier 
2493e12c5d1SDavid du Colombier 	case Torigin:
2503e12c5d1SDavid du Colombier 		s = inshort();
2513e12c5d1SDavid du Colombier 		l = inlong();
2523e12c5d1SDavid du Colombier 		l1 = inlong();
2533e12c5d1SDavid du Colombier 		journaln(0, l1);
2543e12c5d1SDavid du Colombier 		lookorigin(whichfile(s), l, l1);
2553e12c5d1SDavid du Colombier 		break;
2563e12c5d1SDavid du Colombier 
2573e12c5d1SDavid du Colombier 	case Tstartfile:
2583e12c5d1SDavid du Colombier 		f = whichfile(inshort());
2593e12c5d1SDavid du Colombier 		if(!f->rasp)	/* this might be a duplicate message */
2603e12c5d1SDavid du Colombier 			f->rasp = emalloc(sizeof(List));
2613e12c5d1SDavid du Colombier 		current(f);
262*219b2ee8SDavid du Colombier 		outTsv(Hbindname, f->tag, invlong());	/* for 64-bit pointers */
2633e12c5d1SDavid du Colombier 		outTs(Hcurrent, f->tag);
2643e12c5d1SDavid du Colombier 		journaln(0, f->tag);
2653e12c5d1SDavid du Colombier 		termlocked++;
2663e12c5d1SDavid du Colombier 		if(f->state == Unread)
2673e12c5d1SDavid du Colombier 			load(f);
2683e12c5d1SDavid du Colombier 		else{
2693e12c5d1SDavid du Colombier 			if(f->nrunes>0){
2703e12c5d1SDavid du Colombier 				rgrow(f->rasp, 0L, f->nrunes);
2713e12c5d1SDavid du Colombier 				outTsll(Hgrow, f->tag, 0L, f->nrunes);
2723e12c5d1SDavid du Colombier 			}
2733e12c5d1SDavid du Colombier 			outTs(Hcheck0, f->tag);
2743e12c5d1SDavid du Colombier 			moveto(f, f->dot.r);
2753e12c5d1SDavid du Colombier 		}
2763e12c5d1SDavid du Colombier 		break;
2773e12c5d1SDavid du Colombier 
2783e12c5d1SDavid du Colombier 	case Tworkfile:
2793e12c5d1SDavid du Colombier 		i = inshort();
2803e12c5d1SDavid du Colombier 		f = whichfile(i);
2813e12c5d1SDavid du Colombier 		current(f);
2823e12c5d1SDavid du Colombier 		f->dot.r.p1 = inlong();
2833e12c5d1SDavid du Colombier 		f->dot.r.p2 = inlong();
2843e12c5d1SDavid du Colombier 		f->tdot = f->dot.r;
2853e12c5d1SDavid du Colombier 		journaln(0, i);
2863e12c5d1SDavid du Colombier 		journaln(0, f->dot.r.p1);
2873e12c5d1SDavid du Colombier 		journaln(0, f->dot.r.p2);
2883e12c5d1SDavid du Colombier 		break;
2893e12c5d1SDavid du Colombier 
2903e12c5d1SDavid du Colombier 	case Ttype:
2913e12c5d1SDavid du Colombier 		f = whichfile(inshort());
2923e12c5d1SDavid du Colombier 		p0 = inlong();
2933e12c5d1SDavid du Colombier 		journaln(0, p0);
2943e12c5d1SDavid du Colombier 		journal(0, (char*)inp);
2953e12c5d1SDavid du Colombier 		str = tmpcstr((char*)inp);
2963e12c5d1SDavid du Colombier 		i = str->n;
2973e12c5d1SDavid du Colombier 		Finsert(f, str, p0);
2983e12c5d1SDavid du Colombier 		if(Fupdate(f, FALSE, FALSE))
2993e12c5d1SDavid du Colombier 			modnum++;
3003e12c5d1SDavid du Colombier 		if(f==cmd && p0==f->nrunes-i && i>0 && str->s[i-1]=='\n'){
3013e12c5d1SDavid du Colombier 			freetmpstr(str);
3023e12c5d1SDavid du Colombier 			termlocked++;
3033e12c5d1SDavid du Colombier 			termcommand();
3043e12c5d1SDavid du Colombier 		}else
3053e12c5d1SDavid du Colombier 			freetmpstr(str);
3063e12c5d1SDavid du Colombier 		f->dot.r.p1 = f->dot.r.p2 = p0+i; /* terminal knows this already */
3073e12c5d1SDavid du Colombier 		f->tdot = f->dot.r;
3083e12c5d1SDavid du Colombier 		break;
3093e12c5d1SDavid du Colombier 
3103e12c5d1SDavid du Colombier 	case Tcut:
3113e12c5d1SDavid du Colombier 		f = whichfile(inshort());
3123e12c5d1SDavid du Colombier 		p0 = inlong();
3133e12c5d1SDavid du Colombier 		p1 = inlong();
3143e12c5d1SDavid du Colombier 		journaln(0, p0);
3153e12c5d1SDavid du Colombier 		journaln(0, p1);
3163e12c5d1SDavid du Colombier 		Fdelete(f, p0, p1);
3173e12c5d1SDavid du Colombier 		if(Fupdate(f, FALSE, FALSE))
3183e12c5d1SDavid du Colombier 			modnum++;
3193e12c5d1SDavid du Colombier 		f->dot.r.p1 = f->dot.r.p2 = p0;
3203e12c5d1SDavid du Colombier 		f->tdot = f->dot.r;   /* terminal knows the value of dot already */
3213e12c5d1SDavid du Colombier 		break;
3223e12c5d1SDavid du Colombier 
3233e12c5d1SDavid du Colombier 	case Tpaste:
3243e12c5d1SDavid du Colombier 		f = whichfile(inshort());
3253e12c5d1SDavid du Colombier 		p0 = inlong();
3263e12c5d1SDavid du Colombier 		journaln(0, p0);
3273e12c5d1SDavid du Colombier 		for(l=0; l<snarfbuf->nrunes; l+=m){
3283e12c5d1SDavid du Colombier 			m = snarfbuf->nrunes-l;
3293e12c5d1SDavid du Colombier 			if(m>BLOCKSIZE)
3303e12c5d1SDavid du Colombier 				m = BLOCKSIZE;
3313e12c5d1SDavid du Colombier 			Bread(snarfbuf, genbuf, m, l);
3323e12c5d1SDavid du Colombier 			Finsert(f, tmprstr(genbuf, m), p0);
3333e12c5d1SDavid du Colombier 		}
3343e12c5d1SDavid du Colombier 		if(Fupdate(f, FALSE, TRUE))
3353e12c5d1SDavid du Colombier 			modnum++;
3363e12c5d1SDavid du Colombier 		f->dot.r.p1 = p0;
3373e12c5d1SDavid du Colombier 		f->dot.r.p2 = p0+snarfbuf->nrunes;
3383e12c5d1SDavid du Colombier 		f->tdot.p1 = -1; /* force telldot to tell (arguably a BUG) */
3393e12c5d1SDavid du Colombier 		telldot(f);
3403e12c5d1SDavid du Colombier 		outTs(Hunlockfile, f->tag);
3413e12c5d1SDavid du Colombier 		break;
3423e12c5d1SDavid du Colombier 
3433e12c5d1SDavid du Colombier 	case Tsnarf:
3443e12c5d1SDavid du Colombier 		i = inshort();
3453e12c5d1SDavid du Colombier 		p0 = inlong();
3463e12c5d1SDavid du Colombier 		p1 = inlong();
3473e12c5d1SDavid du Colombier 		snarf(whichfile(i), p0, p1, snarfbuf, 0);
3483e12c5d1SDavid du Colombier 		break;
3493e12c5d1SDavid du Colombier 
3503e12c5d1SDavid du Colombier 	case Tstartnewfile:
351*219b2ee8SDavid du Colombier 		l = invlong();
3523e12c5d1SDavid du Colombier 		Strdupl(&genstr, empty);
3533e12c5d1SDavid du Colombier 		f = newfile();
3543e12c5d1SDavid du Colombier 		f->rasp = emalloc(sizeof(List));
355*219b2ee8SDavid du Colombier 		outTsv(Hbindname, f->tag, l);
3563e12c5d1SDavid du Colombier 		Fsetname(f, &genstr);
3573e12c5d1SDavid du Colombier 		outTs(Hcurrent, f->tag);
3583e12c5d1SDavid du Colombier 		current(f);
3593e12c5d1SDavid du Colombier 		load(f);
3603e12c5d1SDavid du Colombier 		break;
3613e12c5d1SDavid du Colombier 
3623e12c5d1SDavid du Colombier 	case Twrite:
3633e12c5d1SDavid du Colombier 		termlocked++;
3643e12c5d1SDavid du Colombier 		i = inshort();
3653e12c5d1SDavid du Colombier 		journaln(0, i);
3663e12c5d1SDavid du Colombier 		f = whichfile(i);
3673e12c5d1SDavid du Colombier 		addr.r.p1 = 0;
3683e12c5d1SDavid du Colombier 		addr.r.p2 = f->nrunes;
3693e12c5d1SDavid du Colombier 		if(f->name.s[0] == 0)
3703e12c5d1SDavid du Colombier 			error(Enoname);
3713e12c5d1SDavid du Colombier 		Strduplstr(&genstr, &f->name);
3723e12c5d1SDavid du Colombier 		writef(f);
3733e12c5d1SDavid du Colombier 		break;
3743e12c5d1SDavid du Colombier 
3753e12c5d1SDavid du Colombier 	case Tclose:
376*219b2ee8SDavid du Colombier 		termlocked++;
3773e12c5d1SDavid du Colombier 		i = inshort();
3783e12c5d1SDavid du Colombier 		journaln(0, i);
3793e12c5d1SDavid du Colombier 		f = whichfile(i);
3803e12c5d1SDavid du Colombier 		current(f);
3813e12c5d1SDavid du Colombier 		trytoclose(f);
382*219b2ee8SDavid du Colombier 		/* if trytoclose fails, will error out */
383*219b2ee8SDavid du Colombier 		delete(f);
3843e12c5d1SDavid du Colombier 		break;
3853e12c5d1SDavid du Colombier 
3863e12c5d1SDavid du Colombier 	case Tlook:
3873e12c5d1SDavid du Colombier 		f = whichfile(inshort());
3883e12c5d1SDavid du Colombier 		termlocked++;
3893e12c5d1SDavid du Colombier 		p0 = inlong();
3903e12c5d1SDavid du Colombier 		p1 = inlong();
3913e12c5d1SDavid du Colombier 		journaln(0, p0);
3923e12c5d1SDavid du Colombier 		journaln(0, p1);
3933e12c5d1SDavid du Colombier 		setgenstr(f, p0, p1);
3943e12c5d1SDavid du Colombier 		for(l = 0; l<genstr.n; l++){
3953e12c5d1SDavid du Colombier 			i = genstr.s[l];
3963e12c5d1SDavid du Colombier 			if(utfrune(".*+?(|)\\[]^$", i))
3973e12c5d1SDavid du Colombier 				Strinsert(&genstr, tmpcstr("\\"), l++);
3983e12c5d1SDavid du Colombier 		}
3993e12c5d1SDavid du Colombier 		Straddc(&genstr, '\0');
4003e12c5d1SDavid du Colombier 		nextmatch(f, &genstr, p1, 1);
4013e12c5d1SDavid du Colombier 		moveto(f, sel.p[0]);
4023e12c5d1SDavid du Colombier 		break;
4033e12c5d1SDavid du Colombier 
4043e12c5d1SDavid du Colombier 	case Tsearch:
4053e12c5d1SDavid du Colombier 		termlocked++;
4063e12c5d1SDavid du Colombier 		if(curfile == 0)
4073e12c5d1SDavid du Colombier 			error(Enofile);
4083e12c5d1SDavid du Colombier 		if(lastpat.s[0] == 0)
4093e12c5d1SDavid du Colombier 			panic("Tsearch");
4103e12c5d1SDavid du Colombier 		nextmatch(curfile, &lastpat, curfile->dot.r.p2, 1);
4113e12c5d1SDavid du Colombier 		moveto(curfile, sel.p[0]);
4123e12c5d1SDavid du Colombier 		break;
4133e12c5d1SDavid du Colombier 
4143e12c5d1SDavid du Colombier 	case Tsend:
4153e12c5d1SDavid du Colombier 		termlocked++;
4163e12c5d1SDavid du Colombier 		inshort();	/* ignored */
4173e12c5d1SDavid du Colombier 		p0 = inlong();
4183e12c5d1SDavid du Colombier 		p1 = inlong();
4193e12c5d1SDavid du Colombier 		setgenstr(cmd, p0, p1);
4203e12c5d1SDavid du Colombier 		Bdelete(snarfbuf, (Posn)0, snarfbuf->nrunes);
4213e12c5d1SDavid du Colombier 		Binsert(snarfbuf, &genstr, (Posn)0);
4223e12c5d1SDavid du Colombier 		outTl(Hsnarflen, genstr.n);
4233e12c5d1SDavid du Colombier 		if(genstr.s[genstr.n-1] != '\n')
4243e12c5d1SDavid du Colombier 			Straddc(&genstr, '\n');
4253e12c5d1SDavid du Colombier 		Finsert(cmd, &genstr, cmd->nrunes);
4263e12c5d1SDavid du Colombier 		Fupdate(cmd, FALSE, TRUE);
4273e12c5d1SDavid du Colombier 		cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->nrunes;
4283e12c5d1SDavid du Colombier 		telldot(cmd);
4293e12c5d1SDavid du Colombier 		termcommand();
4303e12c5d1SDavid du Colombier 		break;
4313e12c5d1SDavid du Colombier 
4323e12c5d1SDavid du Colombier 	case Tdclick:
4333e12c5d1SDavid du Colombier 		f = whichfile(inshort());
4343e12c5d1SDavid du Colombier 		p1 = inlong();
4353e12c5d1SDavid du Colombier 		doubleclick(f, p1);
4363e12c5d1SDavid du Colombier 		f->tdot.p1 = f->tdot.p2 = p1;
4373e12c5d1SDavid du Colombier 		telldot(f);
4383e12c5d1SDavid du Colombier 		outTs(Hunlockfile, f->tag);
4393e12c5d1SDavid du Colombier 		break;
4403e12c5d1SDavid du Colombier 
4413e12c5d1SDavid du Colombier 	case Tstartsnarf:
442*219b2ee8SDavid du Colombier 		if (snarfbuf->nrunes <= 0) {	/* nothing to export */
443*219b2ee8SDavid du Colombier 			outTs(Hsetsnarf, 0);
444*219b2ee8SDavid du Colombier 			break;
4453e12c5d1SDavid du Colombier 		}
446*219b2ee8SDavid du Colombier 		c = 0;
4473e12c5d1SDavid du Colombier 		i = 0;
448*219b2ee8SDavid du Colombier 		rp = malloc((snarfbuf->nrunes)*sizeof(Rune));
449*219b2ee8SDavid du Colombier 		if(rp){
450*219b2ee8SDavid du Colombier 			Bread(snarfbuf, rp, snarfbuf->nrunes, 0);
451*219b2ee8SDavid du Colombier 			c = Strtoc(tmprstr(rp, snarfbuf->nrunes));
452*219b2ee8SDavid du Colombier 			free(rp);
453*219b2ee8SDavid du Colombier 			i = strlen(c);
4543e12c5d1SDavid du Colombier 		}
4553e12c5d1SDavid du Colombier 		outTs(Hsetsnarf, i);
456*219b2ee8SDavid du Colombier 		if(c){
4573e12c5d1SDavid du Colombier 			Write(1, c, i);
4583e12c5d1SDavid du Colombier 			free(c);
459*219b2ee8SDavid du Colombier 		} else
460*219b2ee8SDavid du Colombier 			dprint("snarf buffer too long\n");
4613e12c5d1SDavid du Colombier 		break;
4623e12c5d1SDavid du Colombier 
4633e12c5d1SDavid du Colombier 	case Tsetsnarf:
4643e12c5d1SDavid du Colombier 		m = inshort();
4653e12c5d1SDavid du Colombier 		if(m > SNARFSIZE)
4663e12c5d1SDavid du Colombier 			error(Etoolong);
4673e12c5d1SDavid du Colombier 		c = malloc(m+1);
4683e12c5d1SDavid du Colombier 		if(c){
4693e12c5d1SDavid du Colombier 			for(i=0; i<m; i++)
4703e12c5d1SDavid du Colombier 				c[i] = rcvchar();
4713e12c5d1SDavid du Colombier 			c[m] = 0;
4723e12c5d1SDavid du Colombier 			str = tmpcstr(c);
4733e12c5d1SDavid du Colombier 			free(c);
4743e12c5d1SDavid du Colombier 			Bdelete(snarfbuf, (Posn)0, snarfbuf->nrunes);
4753e12c5d1SDavid du Colombier 			Binsert(snarfbuf, str, (Posn)0);
4763e12c5d1SDavid du Colombier 			freetmpstr(str);
4773e12c5d1SDavid du Colombier 			outT0(Hunlock);
4783e12c5d1SDavid du Colombier 		}
4793e12c5d1SDavid du Colombier 		break;
4803e12c5d1SDavid du Colombier 
4813e12c5d1SDavid du Colombier 	case Tack:
4823e12c5d1SDavid du Colombier 		waitack = 0;
4833e12c5d1SDavid du Colombier 		break;
4843e12c5d1SDavid du Colombier 
4853e12c5d1SDavid du Colombier 	case Texit:
4863e12c5d1SDavid du Colombier 		exits(0);
4873e12c5d1SDavid du Colombier 	}
4883e12c5d1SDavid du Colombier 	return TRUE;
4893e12c5d1SDavid du Colombier }
4903e12c5d1SDavid du Colombier 
4913e12c5d1SDavid du Colombier void
4923e12c5d1SDavid du Colombier snarf(File *f, Posn p1, Posn p2, Buffer *buf, int emptyok)
4933e12c5d1SDavid du Colombier {
4943e12c5d1SDavid du Colombier 	Posn l;
4953e12c5d1SDavid du Colombier 	int i;
4963e12c5d1SDavid du Colombier 
4973e12c5d1SDavid du Colombier 	if(!emptyok && p1==p2)
4983e12c5d1SDavid du Colombier 		return;
4993e12c5d1SDavid du Colombier 	Bdelete(buf, (Posn)0, buf->nrunes);
5003e12c5d1SDavid du Colombier 	/* Stage through genbuf to avoid compaction problems (vestigial) */
5013e12c5d1SDavid du Colombier 	for(l=p1; l<p2; l+=i){
5023e12c5d1SDavid du Colombier 		i = p2-l>BLOCKSIZE? BLOCKSIZE : p2-l;
5033e12c5d1SDavid du Colombier 		Fchars(f, genbuf, l, l+i);
5043e12c5d1SDavid du Colombier 		Binsert(buf, tmprstr(genbuf, i), buf->nrunes);
5053e12c5d1SDavid du Colombier 	}
5063e12c5d1SDavid du Colombier }
5073e12c5d1SDavid du Colombier 
5083e12c5d1SDavid du Colombier int
5093e12c5d1SDavid du Colombier inshort(void)
5103e12c5d1SDavid du Colombier {
5113e12c5d1SDavid du Colombier 	ushort n;
5123e12c5d1SDavid du Colombier 
5133e12c5d1SDavid du Colombier 	n = inp[0] | (inp[1]<<8);
5143e12c5d1SDavid du Colombier 	inp += 2;
5153e12c5d1SDavid du Colombier 	return n;
5163e12c5d1SDavid du Colombier }
5173e12c5d1SDavid du Colombier 
5183e12c5d1SDavid du Colombier long
5193e12c5d1SDavid du Colombier inlong(void)
5203e12c5d1SDavid du Colombier {
5213e12c5d1SDavid du Colombier 	ulong n;
5223e12c5d1SDavid du Colombier 
5233e12c5d1SDavid du Colombier 	n = inp[0] | (inp[1]<<8) | (inp[2]<<16) | (inp[3]<<24);
5243e12c5d1SDavid du Colombier 	inp += 4;
5253e12c5d1SDavid du Colombier 	return n;
5263e12c5d1SDavid du Colombier }
5273e12c5d1SDavid du Colombier 
528*219b2ee8SDavid du Colombier long
529*219b2ee8SDavid du Colombier invlong(void)
530*219b2ee8SDavid du Colombier {
531*219b2ee8SDavid du Colombier 	ulong n;
532*219b2ee8SDavid du Colombier 
533*219b2ee8SDavid du Colombier 	n = (inp[7]<<24) | (inp[6]<<16) | (inp[5]<<8) | inp[4];
534*219b2ee8SDavid du Colombier 	n = (n<<16) | (inp[3]<<8) | inp[2];
535*219b2ee8SDavid du Colombier 	n = (n<<16) | (inp[1]<<8) | inp[0];
536*219b2ee8SDavid du Colombier 	inp += 8;
537*219b2ee8SDavid du Colombier 	return n;
538*219b2ee8SDavid du Colombier }
539*219b2ee8SDavid du Colombier 
5403e12c5d1SDavid du Colombier void
5413e12c5d1SDavid du Colombier setgenstr(File *f, Posn p0, Posn p1)
5423e12c5d1SDavid du Colombier {
5433e12c5d1SDavid du Colombier 	if(p0 != p1){
5443e12c5d1SDavid du Colombier 		if(p1-p0 >= TBLOCKSIZE)
5453e12c5d1SDavid du Colombier 			error(Etoolong);
5463e12c5d1SDavid du Colombier 		Strinsure(&genstr, p1-p0);
5473e12c5d1SDavid du Colombier 		Fchars(f, genbuf, p0, p1);
5483e12c5d1SDavid du Colombier 		memmove(genstr.s, genbuf, RUNESIZE*(p1-p0));
5493e12c5d1SDavid du Colombier 		genstr.n = p1-p0;
5503e12c5d1SDavid du Colombier 	}else{
5513e12c5d1SDavid du Colombier 		if(snarfbuf->nrunes == 0)
5523e12c5d1SDavid du Colombier 			error(Eempty);
5533e12c5d1SDavid du Colombier 		if(snarfbuf->nrunes > TBLOCKSIZE)
5543e12c5d1SDavid du Colombier 			error(Etoolong);
5553e12c5d1SDavid du Colombier 		Bread(snarfbuf, genbuf, snarfbuf->nrunes, (Posn)0);
5563e12c5d1SDavid du Colombier 		Strinsure(&genstr, snarfbuf->nrunes);
5573e12c5d1SDavid du Colombier 		memmove(genstr.s, genbuf, RUNESIZE*snarfbuf->nrunes);
5583e12c5d1SDavid du Colombier 		genstr.n = snarfbuf->nrunes;
5593e12c5d1SDavid du Colombier 	}
5603e12c5d1SDavid du Colombier }
5613e12c5d1SDavid du Colombier 
5623e12c5d1SDavid du Colombier void
5633e12c5d1SDavid du Colombier outT0(Hmesg type)
5643e12c5d1SDavid du Colombier {
5653e12c5d1SDavid du Colombier 	outstart(type);
5663e12c5d1SDavid du Colombier 	outsend();
5673e12c5d1SDavid du Colombier }
5683e12c5d1SDavid du Colombier 
5693e12c5d1SDavid du Colombier void
5703e12c5d1SDavid du Colombier outTl(Hmesg type, long l)
5713e12c5d1SDavid du Colombier {
5723e12c5d1SDavid du Colombier 	outstart(type);
5733e12c5d1SDavid du Colombier 	outlong(l);
5743e12c5d1SDavid du Colombier 	outsend();
5753e12c5d1SDavid du Colombier }
5763e12c5d1SDavid du Colombier 
5773e12c5d1SDavid du Colombier void
5783e12c5d1SDavid du Colombier outTs(Hmesg type, int s)
5793e12c5d1SDavid du Colombier {
5803e12c5d1SDavid du Colombier 	outstart(type);
5813e12c5d1SDavid du Colombier 	journaln(1, s);
5823e12c5d1SDavid du Colombier 	outshort(s);
5833e12c5d1SDavid du Colombier 	outsend();
5843e12c5d1SDavid du Colombier }
5853e12c5d1SDavid du Colombier 
5863e12c5d1SDavid du Colombier void
5873e12c5d1SDavid du Colombier outS(String *s)
5883e12c5d1SDavid du Colombier {
5893e12c5d1SDavid du Colombier 	char *c;
5903e12c5d1SDavid du Colombier 	int i;
5913e12c5d1SDavid du Colombier 
5923e12c5d1SDavid du Colombier 	c = Strtoc(s);
5933e12c5d1SDavid du Colombier 	i = strlen(c);
5943e12c5d1SDavid du Colombier 	outcopy(i, c);
5953e12c5d1SDavid du Colombier 	if(i > 99)
5963e12c5d1SDavid du Colombier 		c[99] = 0;
5973e12c5d1SDavid du Colombier 	journaln(1, i);
5983e12c5d1SDavid du Colombier 	journal(1, c);
5993e12c5d1SDavid du Colombier 	free(c);
6003e12c5d1SDavid du Colombier }
6013e12c5d1SDavid du Colombier 
6023e12c5d1SDavid du Colombier void
6033e12c5d1SDavid du Colombier outTsS(Hmesg type, int s1, String *s)
6043e12c5d1SDavid du Colombier {
6053e12c5d1SDavid du Colombier 	outstart(type);
6063e12c5d1SDavid du Colombier 	outshort(s1);
6073e12c5d1SDavid du Colombier 	outS(s);
6083e12c5d1SDavid du Colombier 	outsend();
6093e12c5d1SDavid du Colombier }
6103e12c5d1SDavid du Colombier 
6113e12c5d1SDavid du Colombier void
6123e12c5d1SDavid du Colombier outTslS(Hmesg type, int s1, Posn l1, String *s)
6133e12c5d1SDavid du Colombier {
6143e12c5d1SDavid du Colombier 	outstart(type);
6153e12c5d1SDavid du Colombier 	outshort(s1);
6163e12c5d1SDavid du Colombier 	journaln(1, s1);
6173e12c5d1SDavid du Colombier 	outlong(l1);
6183e12c5d1SDavid du Colombier 	journaln(1, l1);
6193e12c5d1SDavid du Colombier 	outS(s);
6203e12c5d1SDavid du Colombier 	outsend();
6213e12c5d1SDavid du Colombier }
6223e12c5d1SDavid du Colombier 
6233e12c5d1SDavid du Colombier void
6243e12c5d1SDavid du Colombier outTS(Hmesg type, String *s)
6253e12c5d1SDavid du Colombier {
6263e12c5d1SDavid du Colombier 	outstart(type);
6273e12c5d1SDavid du Colombier 	outS(s);
6283e12c5d1SDavid du Colombier 	outsend();
6293e12c5d1SDavid du Colombier }
6303e12c5d1SDavid du Colombier 
6313e12c5d1SDavid du Colombier void
6323e12c5d1SDavid du Colombier outTsllS(Hmesg type, int s1, Posn l1, Posn l2, String *s)
6333e12c5d1SDavid du Colombier {
6343e12c5d1SDavid du Colombier 	outstart(type);
6353e12c5d1SDavid du Colombier 	outshort(s1);
6363e12c5d1SDavid du Colombier 	outlong(l1);
6373e12c5d1SDavid du Colombier 	outlong(l2);
6383e12c5d1SDavid du Colombier 	journaln(1, l1);
6393e12c5d1SDavid du Colombier 	journaln(1, l2);
6403e12c5d1SDavid du Colombier 	outS(s);
6413e12c5d1SDavid du Colombier 	outsend();
6423e12c5d1SDavid du Colombier }
6433e12c5d1SDavid du Colombier 
6443e12c5d1SDavid du Colombier void
6453e12c5d1SDavid du Colombier outTsll(Hmesg type, int s, Posn l1, Posn l2)
6463e12c5d1SDavid du Colombier {
6473e12c5d1SDavid du Colombier 	outstart(type);
6483e12c5d1SDavid du Colombier 	outshort(s);
6493e12c5d1SDavid du Colombier 	outlong(l1);
6503e12c5d1SDavid du Colombier 	outlong(l2);
6513e12c5d1SDavid du Colombier 	journaln(1, l1);
6523e12c5d1SDavid du Colombier 	journaln(1, l2);
6533e12c5d1SDavid du Colombier 	outsend();
6543e12c5d1SDavid du Colombier }
6553e12c5d1SDavid du Colombier 
6563e12c5d1SDavid du Colombier void
6573e12c5d1SDavid du Colombier outTsl(Hmesg type, int s, Posn l)
6583e12c5d1SDavid du Colombier {
6593e12c5d1SDavid du Colombier 	outstart(type);
6603e12c5d1SDavid du Colombier 	outshort(s);
6613e12c5d1SDavid du Colombier 	outlong(l);
6623e12c5d1SDavid du Colombier 	journaln(1, l);
6633e12c5d1SDavid du Colombier 	outsend();
6643e12c5d1SDavid du Colombier }
6653e12c5d1SDavid du Colombier 
6663e12c5d1SDavid du Colombier void
667*219b2ee8SDavid du Colombier outTsv(Hmesg type, int s, Posn l)
668*219b2ee8SDavid du Colombier {
669*219b2ee8SDavid du Colombier 	outstart(type);
670*219b2ee8SDavid du Colombier 	outshort(s);
671*219b2ee8SDavid du Colombier 	outvlong((void*)l);
672*219b2ee8SDavid du Colombier 	journaln(1, l);
673*219b2ee8SDavid du Colombier 	outsend();
674*219b2ee8SDavid du Colombier }
675*219b2ee8SDavid du Colombier 
676*219b2ee8SDavid du Colombier void
6773e12c5d1SDavid du Colombier outstart(Hmesg type)
6783e12c5d1SDavid du Colombier {
6793e12c5d1SDavid du Colombier 	journal(1, hname[type]);
6803e12c5d1SDavid du Colombier 	outmsg[0] = type;
6813e12c5d1SDavid du Colombier 	outp = outmsg+3;
6823e12c5d1SDavid du Colombier }
6833e12c5d1SDavid du Colombier 
6843e12c5d1SDavid du Colombier void
6853e12c5d1SDavid du Colombier outcopy(int count, void *data)
6863e12c5d1SDavid du Colombier {
6873e12c5d1SDavid du Colombier 	memmove(outp, data, count);
6883e12c5d1SDavid du Colombier 	outp += count;
6893e12c5d1SDavid du Colombier }
6903e12c5d1SDavid du Colombier 
6913e12c5d1SDavid du Colombier void
6923e12c5d1SDavid du Colombier outshort(int s)
6933e12c5d1SDavid du Colombier {
6943e12c5d1SDavid du Colombier 	*outp++ = s;
6953e12c5d1SDavid du Colombier 	*outp++ = s>>8;
6963e12c5d1SDavid du Colombier }
6973e12c5d1SDavid du Colombier 
6983e12c5d1SDavid du Colombier void
6993e12c5d1SDavid du Colombier outlong(long l)
7003e12c5d1SDavid du Colombier {
7013e12c5d1SDavid du Colombier 	*outp++ = l;
7023e12c5d1SDavid du Colombier 	*outp++ = l>>8;
7033e12c5d1SDavid du Colombier 	*outp++ = l>>16;
7043e12c5d1SDavid du Colombier 	*outp++ = l>>24;
7053e12c5d1SDavid du Colombier }
7063e12c5d1SDavid du Colombier 
7073e12c5d1SDavid du Colombier void
708*219b2ee8SDavid du Colombier outvlong(void *v)
709*219b2ee8SDavid du Colombier {
710*219b2ee8SDavid du Colombier 	int i;
711*219b2ee8SDavid du Colombier 	ulong l;
712*219b2ee8SDavid du Colombier 
713*219b2ee8SDavid du Colombier 	l = (ulong) v;
714*219b2ee8SDavid du Colombier 	for(i = 0; i < 8; i++, l >>= 8)
715*219b2ee8SDavid du Colombier 		*outp++ = l;
716*219b2ee8SDavid du Colombier }
717*219b2ee8SDavid du Colombier 
718*219b2ee8SDavid du Colombier void
7193e12c5d1SDavid du Colombier outsend(void)
7203e12c5d1SDavid du Colombier {
7213e12c5d1SDavid du Colombier 	int outcount;
7223e12c5d1SDavid du Colombier 
7233e12c5d1SDavid du Colombier 	outcount = outp-outmsg;
7243e12c5d1SDavid du Colombier 	outcount -= 3;
7253e12c5d1SDavid du Colombier 	outmsg[1] = outcount;
7263e12c5d1SDavid du Colombier 	outmsg[2] = outcount>>8;
7273e12c5d1SDavid du Colombier 	outmsg = outp;
7283e12c5d1SDavid du Colombier 	if(!noflush){
729bd389b36SDavid du Colombier 		outcount = outmsg-outdata;
730bd389b36SDavid du Colombier 		if (write(1, (char*) outdata, outcount) != outcount)
731bd389b36SDavid du Colombier 			rescue();
7323e12c5d1SDavid du Colombier 		outmsg = outdata;
7333e12c5d1SDavid du Colombier 		return;
7343e12c5d1SDavid du Colombier 	}
7353e12c5d1SDavid du Colombier 	if(outmsg < outdata+DATASIZE)
7363e12c5d1SDavid du Colombier 		return;
7373e12c5d1SDavid du Colombier 	outflush();
7383e12c5d1SDavid du Colombier }
7393e12c5d1SDavid du Colombier 
7403e12c5d1SDavid du Colombier void
7413e12c5d1SDavid du Colombier outflush(void)
7423e12c5d1SDavid du Colombier {
7433e12c5d1SDavid du Colombier 	if(outmsg == outdata)
7443e12c5d1SDavid du Colombier 		return;
7453e12c5d1SDavid du Colombier 	noflush = 0;
7463e12c5d1SDavid du Colombier 	outT0(Hack);
7473e12c5d1SDavid du Colombier 	waitack = 1;
7483e12c5d1SDavid du Colombier 	do
7493e12c5d1SDavid du Colombier 		if(rcv() == 0){
7503e12c5d1SDavid du Colombier 			rescue();
7513e12c5d1SDavid du Colombier 			exits("eof");
7523e12c5d1SDavid du Colombier 		}
7533e12c5d1SDavid du Colombier 	while(waitack);
7543e12c5d1SDavid du Colombier 	outmsg = outdata;
7553e12c5d1SDavid du Colombier 	noflush = 1;
7563e12c5d1SDavid du Colombier }
757