xref: /plan9/sys/src/cmd/sam/mesg.c (revision 54d47c7104a034cf0bbe333e13d0054c9c216c87)
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;
117dd7cddfSDavid du Colombier Buffer	snarfbuf;
123e12c5d1SDavid du Colombier int	waitack;
13*54d47c71SDavid du Colombier int	outbuffered;
143e12c5d1SDavid du Colombier int	tversion;
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier int	inshort(void);
1773e742d7SDavid du Colombier long	inlong(void);
1873e742d7SDavid du Colombier vlong	invlong(void);
193e12c5d1SDavid du Colombier int	inmesg(Tmesg);
2073e742d7SDavid du Colombier 
2173e742d7SDavid du Colombier void	outshort(int);
2273e742d7SDavid du Colombier void	outlong(long);
2373e742d7SDavid du Colombier void	outvlong(vlong);
2473e742d7SDavid du Colombier void	outcopy(int, void*);
2573e742d7SDavid du Colombier void	outsend(void);
2673e742d7SDavid du Colombier void	outstart(Hmesg);
2773e742d7SDavid du Colombier 
283e12c5d1SDavid du Colombier void	setgenstr(File*, Posn, Posn);
293e12c5d1SDavid du Colombier 
303e12c5d1SDavid du Colombier #ifdef DEBUG
313e12c5d1SDavid du Colombier char *hname[] = {
323e12c5d1SDavid du Colombier 	[Hversion]	"Hversion",
333e12c5d1SDavid du Colombier 	[Hbindname]	"Hbindname",
343e12c5d1SDavid du Colombier 	[Hcurrent]	"Hcurrent",
353e12c5d1SDavid du Colombier 	[Hnewname]	"Hnewname",
363e12c5d1SDavid du Colombier 	[Hmovname]	"Hmovname",
373e12c5d1SDavid du Colombier 	[Hgrow]		"Hgrow",
383e12c5d1SDavid du Colombier 	[Hcheck0]	"Hcheck0",
393e12c5d1SDavid du Colombier 	[Hcheck]	"Hcheck",
403e12c5d1SDavid du Colombier 	[Hunlock]	"Hunlock",
413e12c5d1SDavid du Colombier 	[Hdata]		"Hdata",
423e12c5d1SDavid du Colombier 	[Horigin]	"Horigin",
433e12c5d1SDavid du Colombier 	[Hunlockfile]	"Hunlockfile",
443e12c5d1SDavid du Colombier 	[Hsetdot]	"Hsetdot",
453e12c5d1SDavid du Colombier 	[Hgrowdata]	"Hgrowdata",
463e12c5d1SDavid du Colombier 	[Hmoveto]	"Hmoveto",
473e12c5d1SDavid du Colombier 	[Hclean]	"Hclean",
483e12c5d1SDavid du Colombier 	[Hdirty]	"Hdirty",
493e12c5d1SDavid du Colombier 	[Hcut]		"Hcut",
503e12c5d1SDavid du Colombier 	[Hsetpat]	"Hsetpat",
513e12c5d1SDavid du Colombier 	[Hdelname]	"Hdelname",
523e12c5d1SDavid du Colombier 	[Hclose]	"Hclose",
533e12c5d1SDavid du Colombier 	[Hsetsnarf]	"Hsetsnarf",
543e12c5d1SDavid du Colombier 	[Hsnarflen]	"Hsnarflen",
553e12c5d1SDavid du Colombier 	[Hack]		"Hack",
563e12c5d1SDavid du Colombier 	[Hexit]		"Hexit",
577dd7cddfSDavid du Colombier 	[Hplumb]		"Hplumb",
583e12c5d1SDavid du Colombier };
593e12c5d1SDavid du Colombier 
603e12c5d1SDavid du Colombier char *tname[] = {
613e12c5d1SDavid du Colombier 	[Tversion]	"Tversion",
623e12c5d1SDavid du Colombier 	[Tstartcmdfile]	"Tstartcmdfile",
633e12c5d1SDavid du Colombier 	[Tcheck]	"Tcheck",
643e12c5d1SDavid du Colombier 	[Trequest]	"Trequest",
653e12c5d1SDavid du Colombier 	[Torigin]	"Torigin",
663e12c5d1SDavid du Colombier 	[Tstartfile]	"Tstartfile",
673e12c5d1SDavid du Colombier 	[Tworkfile]	"Tworkfile",
683e12c5d1SDavid du Colombier 	[Ttype]		"Ttype",
693e12c5d1SDavid du Colombier 	[Tcut]		"Tcut",
703e12c5d1SDavid du Colombier 	[Tpaste]	"Tpaste",
713e12c5d1SDavid du Colombier 	[Tsnarf]	"Tsnarf",
723e12c5d1SDavid du Colombier 	[Tstartnewfile]	"Tstartnewfile",
733e12c5d1SDavid du Colombier 	[Twrite]	"Twrite",
743e12c5d1SDavid du Colombier 	[Tclose]	"Tclose",
753e12c5d1SDavid du Colombier 	[Tlook]		"Tlook",
76219b2ee8SDavid du Colombier 	[Tsearch]	"Tsearch",
773e12c5d1SDavid du Colombier 	[Tsend]		"Tsend",
78219b2ee8SDavid du Colombier 	[Tdclick]	"Tdclick",
793e12c5d1SDavid du Colombier 	[Tstartsnarf]	"Tstartsnarf",
803e12c5d1SDavid du Colombier 	[Tsetsnarf]	"Tsetsnarf",
813e12c5d1SDavid du Colombier 	[Tack]		"Tack",
823e12c5d1SDavid du Colombier 	[Texit]		"Texit",
837dd7cddfSDavid du Colombier 	[Tplumb]		"Tplumb",
843e12c5d1SDavid du Colombier };
853e12c5d1SDavid du Colombier 
863e12c5d1SDavid du Colombier void
journal(int out,char * s)873e12c5d1SDavid du Colombier journal(int out, char *s)
883e12c5d1SDavid du Colombier {
89219b2ee8SDavid du Colombier 	static int fd = 0;
903e12c5d1SDavid du Colombier 
913e12c5d1SDavid du Colombier 	if(fd <= 0)
923e12c5d1SDavid du Colombier 		fd = create("/tmp/sam.out", 1, 0666L);
933e12c5d1SDavid du Colombier 	fprint(fd, "%s%s\n", out? "out: " : "in:  ", s);
943e12c5d1SDavid du Colombier }
953e12c5d1SDavid du Colombier 
96bd389b36SDavid du Colombier void
journaln(int out,long n)97219b2ee8SDavid du Colombier journaln(int out, long n)
983e12c5d1SDavid du Colombier {
993e12c5d1SDavid du Colombier 	char buf[32];
1007dd7cddfSDavid du Colombier 
10173e742d7SDavid du Colombier 	snprint(buf, sizeof(buf), "%ld", n);
10273e742d7SDavid du Colombier 	journal(out, buf);
10373e742d7SDavid du Colombier }
10473e742d7SDavid du Colombier 
10573e742d7SDavid du Colombier void
journalv(int out,vlong v)10673e742d7SDavid du Colombier journalv(int out, vlong v)
10773e742d7SDavid du Colombier {
10873e742d7SDavid du Colombier 	char buf[32];
10973e742d7SDavid du Colombier 
11073e742d7SDavid du Colombier 	sprint(buf, sizeof(buf), "%lld", v);
1113e12c5d1SDavid du Colombier 	journal(out, buf);
1123e12c5d1SDavid du Colombier }
1133e12c5d1SDavid du Colombier #else
1143e12c5d1SDavid du Colombier #define	journal(a, b)
1153e12c5d1SDavid du Colombier #define journaln(a, b)
11673e742d7SDavid du Colombier #define journalv(a, b)
1173e12c5d1SDavid du Colombier #endif
1183e12c5d1SDavid du Colombier 
1193e12c5d1SDavid du Colombier int
rcvchar(void)1203e12c5d1SDavid du Colombier rcvchar(void){
1213e12c5d1SDavid du Colombier 	static uchar buf[64];
1223e12c5d1SDavid du Colombier 	static i, nleft = 0;
1233e12c5d1SDavid du Colombier 
1243e12c5d1SDavid du Colombier 	if(nleft <= 0){
1253e12c5d1SDavid du Colombier 		nleft = read(0, (char *)buf, sizeof buf);
1263e12c5d1SDavid du Colombier 		if(nleft <= 0)
1273e12c5d1SDavid du Colombier 			return -1;
1283e12c5d1SDavid du Colombier 		i = 0;
1293e12c5d1SDavid du Colombier 	}
1303e12c5d1SDavid du Colombier 	--nleft;
1313e12c5d1SDavid du Colombier 	return buf[i++];
1323e12c5d1SDavid du Colombier }
1333e12c5d1SDavid du Colombier 
1343e12c5d1SDavid du Colombier int
rcv(void)1353e12c5d1SDavid du Colombier rcv(void){
1363e12c5d1SDavid du Colombier 	int c;
1373e12c5d1SDavid du Colombier 	static state = 0;
1383e12c5d1SDavid du Colombier 	static count = 0;
1393e12c5d1SDavid du Colombier 	static i = 0;
1403e12c5d1SDavid du Colombier 
1413e12c5d1SDavid du Colombier 	while((c=rcvchar()) != -1)
1423e12c5d1SDavid du Colombier 		switch(state){
1433e12c5d1SDavid du Colombier 		case 0:
1443e12c5d1SDavid du Colombier 			h.type = c;
1453e12c5d1SDavid du Colombier 			state++;
1463e12c5d1SDavid du Colombier 			break;
1473e12c5d1SDavid du Colombier 
1483e12c5d1SDavid du Colombier 		case 1:
1493e12c5d1SDavid du Colombier 			h.count0 = c;
1503e12c5d1SDavid du Colombier 			state++;
1513e12c5d1SDavid du Colombier 			break;
1523e12c5d1SDavid du Colombier 
1533e12c5d1SDavid du Colombier 		case 2:
1543e12c5d1SDavid du Colombier 			h.count1 = c;
1553e12c5d1SDavid du Colombier 			count = h.count0|(h.count1<<8);
1563e12c5d1SDavid du Colombier 			i = 0;
1573e12c5d1SDavid du Colombier 			if(count > DATASIZE)
1583e12c5d1SDavid du Colombier 				panic("count>DATASIZE");
1593e12c5d1SDavid du Colombier 			if(count == 0)
1603e12c5d1SDavid du Colombier 				goto zerocount;
1613e12c5d1SDavid du Colombier 			state++;
1623e12c5d1SDavid du Colombier 			break;
1633e12c5d1SDavid du Colombier 
1643e12c5d1SDavid du Colombier 		case 3:
1653e12c5d1SDavid du Colombier 			indata[i++] = c;
1663e12c5d1SDavid du Colombier 			if(i == count){
1673e12c5d1SDavid du Colombier 		zerocount:
1683e12c5d1SDavid du Colombier 				indata[i] = 0;
1693e12c5d1SDavid du Colombier 				state = count = 0;
1703e12c5d1SDavid du Colombier 				return inmesg(h.type);
1713e12c5d1SDavid du Colombier 			}
1723e12c5d1SDavid du Colombier 			break;
1733e12c5d1SDavid du Colombier 		}
1743e12c5d1SDavid du Colombier 	return 0;
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier 
1773e12c5d1SDavid du Colombier File *
whichfile(int tag)1783e12c5d1SDavid du Colombier whichfile(int tag)
1793e12c5d1SDavid du Colombier {
1803e12c5d1SDavid du Colombier 	int i;
1813e12c5d1SDavid du Colombier 
1823e12c5d1SDavid du Colombier 	for(i = 0; i<file.nused; i++)
1833e12c5d1SDavid du Colombier 		if(file.filepptr[i]->tag==tag)
1843e12c5d1SDavid du Colombier 			return file.filepptr[i];
1853e12c5d1SDavid du Colombier 	hiccough((char *)0);
1863e12c5d1SDavid du Colombier 	return 0;
1873e12c5d1SDavid du Colombier }
1883e12c5d1SDavid du Colombier 
1893e12c5d1SDavid du Colombier int
inmesg(Tmesg type)1903e12c5d1SDavid du Colombier inmesg(Tmesg type)
1913e12c5d1SDavid du Colombier {
1923e12c5d1SDavid du Colombier 	Rune buf[1025];
1937dd7cddfSDavid du Colombier 	char cbuf[64];
1943e12c5d1SDavid du Colombier 	int i, m;
1953e12c5d1SDavid du Colombier 	short s;
1963e12c5d1SDavid du Colombier 	long l, l1;
19773e742d7SDavid du Colombier 	vlong v;
1983e12c5d1SDavid du Colombier 	File *f;
1997dd7cddfSDavid du Colombier 	Posn p0, p1, p;
2003e12c5d1SDavid du Colombier 	Range r;
2013e12c5d1SDavid du Colombier 	String *str;
20280ee5cbfSDavid du Colombier 	char *c, *wdir;
203219b2ee8SDavid du Colombier 	Rune *rp;
2047dd7cddfSDavid du Colombier 	Plumbmsg *pm;
2053e12c5d1SDavid du Colombier 
2063e12c5d1SDavid du Colombier 	if(type > TMAX)
2073e12c5d1SDavid du Colombier 		panic("inmesg");
2083e12c5d1SDavid du Colombier 
2093e12c5d1SDavid du Colombier 	journal(0, tname[type]);
2103e12c5d1SDavid du Colombier 
2113e12c5d1SDavid du Colombier 	inp = indata;
2123e12c5d1SDavid du Colombier 	switch(type){
2133e12c5d1SDavid du Colombier 	case -1:
2143e12c5d1SDavid du Colombier 		panic("rcv error");
2153e12c5d1SDavid du Colombier 
2163e12c5d1SDavid du Colombier 	default:
2173e12c5d1SDavid du Colombier 		fprint(2, "unknown type %d\n", type);
2183e12c5d1SDavid du Colombier 		panic("rcv unknown");
2193e12c5d1SDavid du Colombier 
2203e12c5d1SDavid du Colombier 	case Tversion:
2213e12c5d1SDavid du Colombier 		tversion = inshort();
2223e12c5d1SDavid du Colombier 		journaln(0, tversion);
2233e12c5d1SDavid du Colombier 		break;
2243e12c5d1SDavid du Colombier 
2253e12c5d1SDavid du Colombier 	case Tstartcmdfile:
22673e742d7SDavid du Colombier 		v = invlong();		/* for 64-bit pointers */
22773e742d7SDavid du Colombier 		journalv(0, v);
2283e12c5d1SDavid du Colombier 		Strdupl(&genstr, samname);
2293e12c5d1SDavid du Colombier 		cmd = newfile();
2307dd7cddfSDavid du Colombier 		cmd->unread = 0;
23173e742d7SDavid du Colombier 		outTsv(Hbindname, cmd->tag, v);
2323e12c5d1SDavid du Colombier 		outTs(Hcurrent, cmd->tag);
2337dd7cddfSDavid du Colombier 		logsetname(cmd, &genstr);
23473e742d7SDavid du Colombier 		cmd->rasp = listalloc('P');
2357dd7cddfSDavid du Colombier 		cmd->mod = 0;
2363e12c5d1SDavid du Colombier 		if(cmdstr.n){
2377dd7cddfSDavid du Colombier 			loginsert(cmd, 0L, cmdstr.s, cmdstr.n);
2383e12c5d1SDavid du Colombier 			Strdelete(&cmdstr, 0L, (Posn)cmdstr.n);
2393e12c5d1SDavid du Colombier 		}
2407dd7cddfSDavid du Colombier 		fileupdate(cmd, FALSE, TRUE);
2413e12c5d1SDavid du Colombier 		outT0(Hunlock);
2423e12c5d1SDavid du Colombier 		break;
2433e12c5d1SDavid du Colombier 
2443e12c5d1SDavid du Colombier 	case Tcheck:
2453e12c5d1SDavid du Colombier 		/* go through whichfile to check the tag */
2463e12c5d1SDavid du Colombier 		outTs(Hcheck, whichfile(inshort())->tag);
2473e12c5d1SDavid du Colombier 		break;
2483e12c5d1SDavid du Colombier 
2493e12c5d1SDavid du Colombier 	case Trequest:
2503e12c5d1SDavid du Colombier 		f = whichfile(inshort());
2513e12c5d1SDavid du Colombier 		p0 = inlong();
2523e12c5d1SDavid du Colombier 		p1 = p0+inshort();
2533e12c5d1SDavid du Colombier 		journaln(0, p0);
2543e12c5d1SDavid du Colombier 		journaln(0, p1-p0);
2557dd7cddfSDavid du Colombier 		if(f->unread)
2563e12c5d1SDavid du Colombier 			panic("Trequest: unread");
2577dd7cddfSDavid du Colombier 		if(p1>f->nc)
2587dd7cddfSDavid du Colombier 			p1 = f->nc;
2597dd7cddfSDavid du Colombier 		if(p0>f->nc) /* can happen e.g. scrolling during command */
2607dd7cddfSDavid du Colombier 			p0 = f->nc;
2613e12c5d1SDavid du Colombier 		if(p0 == p1){
2623e12c5d1SDavid du Colombier 			i = 0;
2633e12c5d1SDavid du Colombier 			r.p1 = r.p2 = p0;
2643e12c5d1SDavid du Colombier 		}else{
2653e12c5d1SDavid du Colombier 			r = rdata(f->rasp, p0, p1-p0);
2663e12c5d1SDavid du Colombier 			i = r.p2-r.p1;
2677dd7cddfSDavid du Colombier 			bufread(f, r.p1, buf, i);
2683e12c5d1SDavid du Colombier 		}
2693e12c5d1SDavid du Colombier 		buf[i]=0;
2703e12c5d1SDavid du Colombier 		outTslS(Hdata, f->tag, r.p1, tmprstr(buf, i+1));
2713e12c5d1SDavid du Colombier 		break;
2723e12c5d1SDavid du Colombier 
2733e12c5d1SDavid du Colombier 	case Torigin:
2743e12c5d1SDavid du Colombier 		s = inshort();
2753e12c5d1SDavid du Colombier 		l = inlong();
2763e12c5d1SDavid du Colombier 		l1 = inlong();
2773e12c5d1SDavid du Colombier 		journaln(0, l1);
2783e12c5d1SDavid du Colombier 		lookorigin(whichfile(s), l, l1);
2793e12c5d1SDavid du Colombier 		break;
2803e12c5d1SDavid du Colombier 
2813e12c5d1SDavid du Colombier 	case Tstartfile:
2827dd7cddfSDavid du Colombier 		termlocked++;
2833e12c5d1SDavid du Colombier 		f = whichfile(inshort());
2843e12c5d1SDavid du Colombier 		if(!f->rasp)	/* this might be a duplicate message */
28573e742d7SDavid du Colombier 			f->rasp = listalloc('P');
2863e12c5d1SDavid du Colombier 		current(f);
287219b2ee8SDavid du Colombier 		outTsv(Hbindname, f->tag, invlong());	/* for 64-bit pointers */
2883e12c5d1SDavid du Colombier 		outTs(Hcurrent, f->tag);
2893e12c5d1SDavid du Colombier 		journaln(0, f->tag);
2907dd7cddfSDavid du Colombier 		if(f->unread)
2913e12c5d1SDavid du Colombier 			load(f);
2923e12c5d1SDavid du Colombier 		else{
2937dd7cddfSDavid du Colombier 			if(f->nc>0){
2947dd7cddfSDavid du Colombier 				rgrow(f->rasp, 0L, f->nc);
2957dd7cddfSDavid du Colombier 				outTsll(Hgrow, f->tag, 0L, f->nc);
2963e12c5d1SDavid du Colombier 			}
2973e12c5d1SDavid du Colombier 			outTs(Hcheck0, f->tag);
2983e12c5d1SDavid du Colombier 			moveto(f, f->dot.r);
2993e12c5d1SDavid du Colombier 		}
3003e12c5d1SDavid du Colombier 		break;
3013e12c5d1SDavid du Colombier 
3023e12c5d1SDavid du Colombier 	case Tworkfile:
3033e12c5d1SDavid du Colombier 		i = inshort();
3043e12c5d1SDavid du Colombier 		f = whichfile(i);
3053e12c5d1SDavid du Colombier 		current(f);
3063e12c5d1SDavid du Colombier 		f->dot.r.p1 = inlong();
3073e12c5d1SDavid du Colombier 		f->dot.r.p2 = inlong();
3083e12c5d1SDavid du Colombier 		f->tdot = f->dot.r;
3093e12c5d1SDavid du Colombier 		journaln(0, i);
3103e12c5d1SDavid du Colombier 		journaln(0, f->dot.r.p1);
3113e12c5d1SDavid du Colombier 		journaln(0, f->dot.r.p2);
3123e12c5d1SDavid du Colombier 		break;
3133e12c5d1SDavid du Colombier 
3143e12c5d1SDavid du Colombier 	case Ttype:
3153e12c5d1SDavid du Colombier 		f = whichfile(inshort());
3163e12c5d1SDavid du Colombier 		p0 = inlong();
3173e12c5d1SDavid du Colombier 		journaln(0, p0);
3183e12c5d1SDavid du Colombier 		journal(0, (char*)inp);
3193e12c5d1SDavid du Colombier 		str = tmpcstr((char*)inp);
3203e12c5d1SDavid du Colombier 		i = str->n;
3217dd7cddfSDavid du Colombier 		loginsert(f, p0, str->s, str->n);
3227dd7cddfSDavid du Colombier 		if(fileupdate(f, FALSE, FALSE))
3237dd7cddfSDavid du Colombier 			seq++;
3247dd7cddfSDavid du Colombier 		if(f==cmd && p0==f->nc-i && i>0 && str->s[i-1]=='\n'){
3253e12c5d1SDavid du Colombier 			freetmpstr(str);
3263e12c5d1SDavid du Colombier 			termlocked++;
3273e12c5d1SDavid du Colombier 			termcommand();
3283e12c5d1SDavid du Colombier 		}else
3293e12c5d1SDavid du Colombier 			freetmpstr(str);
3303e12c5d1SDavid du Colombier 		f->dot.r.p1 = f->dot.r.p2 = p0+i; /* terminal knows this already */
3313e12c5d1SDavid du Colombier 		f->tdot = f->dot.r;
3323e12c5d1SDavid du Colombier 		break;
3333e12c5d1SDavid du Colombier 
3343e12c5d1SDavid du Colombier 	case Tcut:
3353e12c5d1SDavid du Colombier 		f = whichfile(inshort());
3363e12c5d1SDavid du Colombier 		p0 = inlong();
3373e12c5d1SDavid du Colombier 		p1 = inlong();
3383e12c5d1SDavid du Colombier 		journaln(0, p0);
3393e12c5d1SDavid du Colombier 		journaln(0, p1);
3407dd7cddfSDavid du Colombier 		logdelete(f, p0, p1);
3417dd7cddfSDavid du Colombier 		if(fileupdate(f, FALSE, FALSE))
3427dd7cddfSDavid du Colombier 			seq++;
3433e12c5d1SDavid du Colombier 		f->dot.r.p1 = f->dot.r.p2 = p0;
3443e12c5d1SDavid du Colombier 		f->tdot = f->dot.r;   /* terminal knows the value of dot already */
3453e12c5d1SDavid du Colombier 		break;
3463e12c5d1SDavid du Colombier 
3473e12c5d1SDavid du Colombier 	case Tpaste:
3483e12c5d1SDavid du Colombier 		f = whichfile(inshort());
3493e12c5d1SDavid du Colombier 		p0 = inlong();
3503e12c5d1SDavid du Colombier 		journaln(0, p0);
3517dd7cddfSDavid du Colombier 		for(l=0; l<snarfbuf.nc; l+=m){
3527dd7cddfSDavid du Colombier 			m = snarfbuf.nc-l;
3533e12c5d1SDavid du Colombier 			if(m>BLOCKSIZE)
3543e12c5d1SDavid du Colombier 				m = BLOCKSIZE;
3557dd7cddfSDavid du Colombier 			bufread(&snarfbuf, l, genbuf, m);
3567dd7cddfSDavid du Colombier 			loginsert(f, p0, tmprstr(genbuf, m)->s, m);
3573e12c5d1SDavid du Colombier 		}
3587dd7cddfSDavid du Colombier 		if(fileupdate(f, FALSE, TRUE))
3597dd7cddfSDavid du Colombier 			seq++;
3603e12c5d1SDavid du Colombier 		f->dot.r.p1 = p0;
3617dd7cddfSDavid du Colombier 		f->dot.r.p2 = p0+snarfbuf.nc;
3623e12c5d1SDavid du Colombier 		f->tdot.p1 = -1; /* force telldot to tell (arguably a BUG) */
3633e12c5d1SDavid du Colombier 		telldot(f);
3643e12c5d1SDavid du Colombier 		outTs(Hunlockfile, f->tag);
3653e12c5d1SDavid du Colombier 		break;
3663e12c5d1SDavid du Colombier 
3673e12c5d1SDavid du Colombier 	case Tsnarf:
3683e12c5d1SDavid du Colombier 		i = inshort();
3693e12c5d1SDavid du Colombier 		p0 = inlong();
3703e12c5d1SDavid du Colombier 		p1 = inlong();
3717dd7cddfSDavid du Colombier 		snarf(whichfile(i), p0, p1, &snarfbuf, 0);
3723e12c5d1SDavid du Colombier 		break;
3733e12c5d1SDavid du Colombier 
3743e12c5d1SDavid du Colombier 	case Tstartnewfile:
37573e742d7SDavid du Colombier 		v = invlong();
3763e12c5d1SDavid du Colombier 		Strdupl(&genstr, empty);
3773e12c5d1SDavid du Colombier 		f = newfile();
37873e742d7SDavid du Colombier 		f->rasp = listalloc('P');
37973e742d7SDavid du Colombier 		outTsv(Hbindname, f->tag, v);
3807dd7cddfSDavid du Colombier 		logsetname(f, &genstr);
3813e12c5d1SDavid du Colombier 		outTs(Hcurrent, f->tag);
3823e12c5d1SDavid du Colombier 		current(f);
3833e12c5d1SDavid du Colombier 		load(f);
3843e12c5d1SDavid du Colombier 		break;
3853e12c5d1SDavid du Colombier 
3863e12c5d1SDavid du Colombier 	case Twrite:
3873e12c5d1SDavid du Colombier 		termlocked++;
3883e12c5d1SDavid du Colombier 		i = inshort();
3893e12c5d1SDavid du Colombier 		journaln(0, i);
3903e12c5d1SDavid du Colombier 		f = whichfile(i);
3913e12c5d1SDavid du Colombier 		addr.r.p1 = 0;
3927dd7cddfSDavid du Colombier 		addr.r.p2 = f->nc;
3933e12c5d1SDavid du Colombier 		if(f->name.s[0] == 0)
3943e12c5d1SDavid du Colombier 			error(Enoname);
3953e12c5d1SDavid du Colombier 		Strduplstr(&genstr, &f->name);
3963e12c5d1SDavid du Colombier 		writef(f);
3973e12c5d1SDavid du Colombier 		break;
3983e12c5d1SDavid du Colombier 
3993e12c5d1SDavid du Colombier 	case Tclose:
400219b2ee8SDavid du Colombier 		termlocked++;
4013e12c5d1SDavid du Colombier 		i = inshort();
4023e12c5d1SDavid du Colombier 		journaln(0, i);
4033e12c5d1SDavid du Colombier 		f = whichfile(i);
4043e12c5d1SDavid du Colombier 		current(f);
4053e12c5d1SDavid du Colombier 		trytoclose(f);
406219b2ee8SDavid du Colombier 		/* if trytoclose fails, will error out */
407219b2ee8SDavid du Colombier 		delete(f);
4083e12c5d1SDavid du Colombier 		break;
4093e12c5d1SDavid du Colombier 
4103e12c5d1SDavid du Colombier 	case Tlook:
4113e12c5d1SDavid du Colombier 		f = whichfile(inshort());
4123e12c5d1SDavid du Colombier 		termlocked++;
4133e12c5d1SDavid du Colombier 		p0 = inlong();
4143e12c5d1SDavid du Colombier 		p1 = inlong();
4153e12c5d1SDavid du Colombier 		journaln(0, p0);
4163e12c5d1SDavid du Colombier 		journaln(0, p1);
4173e12c5d1SDavid du Colombier 		setgenstr(f, p0, p1);
4183e12c5d1SDavid du Colombier 		for(l = 0; l<genstr.n; l++){
4193e12c5d1SDavid du Colombier 			i = genstr.s[l];
42039734e7eSDavid du Colombier 			if(utfrune(".*+?(|)\\[]^$", i)){
42139734e7eSDavid du Colombier 				str = tmpcstr("\\");
42239734e7eSDavid du Colombier 				Strinsert(&genstr, str, l++);
42339734e7eSDavid du Colombier 				freetmpstr(str);
42439734e7eSDavid du Colombier 			}
4253e12c5d1SDavid du Colombier 		}
4263e12c5d1SDavid du Colombier 		Straddc(&genstr, '\0');
4273e12c5d1SDavid du Colombier 		nextmatch(f, &genstr, p1, 1);
4283e12c5d1SDavid du Colombier 		moveto(f, sel.p[0]);
4293e12c5d1SDavid du Colombier 		break;
4303e12c5d1SDavid du Colombier 
4313e12c5d1SDavid du Colombier 	case Tsearch:
4323e12c5d1SDavid du Colombier 		termlocked++;
4333e12c5d1SDavid du Colombier 		if(curfile == 0)
4343e12c5d1SDavid du Colombier 			error(Enofile);
4353e12c5d1SDavid du Colombier 		if(lastpat.s[0] == 0)
4363e12c5d1SDavid du Colombier 			panic("Tsearch");
4373e12c5d1SDavid du Colombier 		nextmatch(curfile, &lastpat, curfile->dot.r.p2, 1);
4383e12c5d1SDavid du Colombier 		moveto(curfile, sel.p[0]);
4393e12c5d1SDavid du Colombier 		break;
4403e12c5d1SDavid du Colombier 
4413e12c5d1SDavid du Colombier 	case Tsend:
4423e12c5d1SDavid du Colombier 		termlocked++;
4433e12c5d1SDavid du Colombier 		inshort();	/* ignored */
4443e12c5d1SDavid du Colombier 		p0 = inlong();
4453e12c5d1SDavid du Colombier 		p1 = inlong();
4463e12c5d1SDavid du Colombier 		setgenstr(cmd, p0, p1);
4477dd7cddfSDavid du Colombier 		bufreset(&snarfbuf);
4487dd7cddfSDavid du Colombier 		bufinsert(&snarfbuf, (Posn)0, genstr.s, genstr.n);
4493e12c5d1SDavid du Colombier 		outTl(Hsnarflen, genstr.n);
4503e12c5d1SDavid du Colombier 		if(genstr.s[genstr.n-1] != '\n')
4513e12c5d1SDavid du Colombier 			Straddc(&genstr, '\n');
4527dd7cddfSDavid du Colombier 		loginsert(cmd, cmd->nc, genstr.s, genstr.n);
4537dd7cddfSDavid du Colombier 		fileupdate(cmd, FALSE, TRUE);
4547dd7cddfSDavid du Colombier 		cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->nc;
4553e12c5d1SDavid du Colombier 		telldot(cmd);
4563e12c5d1SDavid du Colombier 		termcommand();
4573e12c5d1SDavid du Colombier 		break;
4583e12c5d1SDavid du Colombier 
4593e12c5d1SDavid du Colombier 	case Tdclick:
4603e12c5d1SDavid du Colombier 		f = whichfile(inshort());
4613e12c5d1SDavid du Colombier 		p1 = inlong();
4623e12c5d1SDavid du Colombier 		doubleclick(f, p1);
4633e12c5d1SDavid du Colombier 		f->tdot.p1 = f->tdot.p2 = p1;
4643e12c5d1SDavid du Colombier 		telldot(f);
4653e12c5d1SDavid du Colombier 		outTs(Hunlockfile, f->tag);
4663e12c5d1SDavid du Colombier 		break;
4673e12c5d1SDavid du Colombier 
4683e12c5d1SDavid du Colombier 	case Tstartsnarf:
4697dd7cddfSDavid du Colombier 		if (snarfbuf.nc <= 0) {	/* nothing to export */
470219b2ee8SDavid du Colombier 			outTs(Hsetsnarf, 0);
471219b2ee8SDavid du Colombier 			break;
4723e12c5d1SDavid du Colombier 		}
473219b2ee8SDavid du Colombier 		c = 0;
4743e12c5d1SDavid du Colombier 		i = 0;
4757dd7cddfSDavid du Colombier 		m = snarfbuf.nc;
4767dd7cddfSDavid du Colombier 		if(m > SNARFSIZE) {
4777dd7cddfSDavid du Colombier 			m = SNARFSIZE;
4787dd7cddfSDavid du Colombier 			dprint("?warning: snarf buffer truncated\n");
4797dd7cddfSDavid du Colombier 		}
4807dd7cddfSDavid du Colombier 		rp = malloc(m*sizeof(Rune));
481219b2ee8SDavid du Colombier 		if(rp){
4827dd7cddfSDavid du Colombier 			bufread(&snarfbuf, 0, rp, m);
4837dd7cddfSDavid du Colombier 			c = Strtoc(tmprstr(rp, m));
484219b2ee8SDavid du Colombier 			free(rp);
485219b2ee8SDavid du Colombier 			i = strlen(c);
4863e12c5d1SDavid du Colombier 		}
4873e12c5d1SDavid du Colombier 		outTs(Hsetsnarf, i);
488219b2ee8SDavid du Colombier 		if(c){
4893e12c5d1SDavid du Colombier 			Write(1, c, i);
4903e12c5d1SDavid du Colombier 			free(c);
491219b2ee8SDavid du Colombier 		} else
492219b2ee8SDavid du Colombier 			dprint("snarf buffer too long\n");
4933e12c5d1SDavid du Colombier 		break;
4943e12c5d1SDavid du Colombier 
4953e12c5d1SDavid du Colombier 	case Tsetsnarf:
4963e12c5d1SDavid du Colombier 		m = inshort();
4973e12c5d1SDavid du Colombier 		if(m > SNARFSIZE)
4983e12c5d1SDavid du Colombier 			error(Etoolong);
4993e12c5d1SDavid du Colombier 		c = malloc(m+1);
5003e12c5d1SDavid du Colombier 		if(c){
5013e12c5d1SDavid du Colombier 			for(i=0; i<m; i++)
5023e12c5d1SDavid du Colombier 				c[i] = rcvchar();
5033e12c5d1SDavid du Colombier 			c[m] = 0;
5043e12c5d1SDavid du Colombier 			str = tmpcstr(c);
5053e12c5d1SDavid du Colombier 			free(c);
5067dd7cddfSDavid du Colombier 			bufreset(&snarfbuf);
5077dd7cddfSDavid du Colombier 			bufinsert(&snarfbuf, (Posn)0, str->s, str->n);
5083e12c5d1SDavid du Colombier 			freetmpstr(str);
5093e12c5d1SDavid du Colombier 			outT0(Hunlock);
5103e12c5d1SDavid du Colombier 		}
5113e12c5d1SDavid du Colombier 		break;
5123e12c5d1SDavid du Colombier 
5133e12c5d1SDavid du Colombier 	case Tack:
5143e12c5d1SDavid du Colombier 		waitack = 0;
5153e12c5d1SDavid du Colombier 		break;
5163e12c5d1SDavid du Colombier 
5177dd7cddfSDavid du Colombier 	case Tplumb:
5187dd7cddfSDavid du Colombier 		f = whichfile(inshort());
5197dd7cddfSDavid du Colombier 		p0 = inlong();
5207dd7cddfSDavid du Colombier 		p1 = inlong();
5217dd7cddfSDavid du Colombier 		pm = emalloc(sizeof(Plumbmsg));
5227dd7cddfSDavid du Colombier 		pm->src = strdup("sam");
5237dd7cddfSDavid du Colombier 		pm->dst = 0;
52480ee5cbfSDavid du Colombier 		/* construct current directory */
52580ee5cbfSDavid du Colombier 		c = Strtoc(&f->name);
52680ee5cbfSDavid du Colombier 		if(c[0] == '/')
52780ee5cbfSDavid du Colombier 			pm->wdir = c;
52880ee5cbfSDavid du Colombier 		else{
52980ee5cbfSDavid du Colombier 			wdir = emalloc(1024);
53080ee5cbfSDavid du Colombier 			getwd(wdir, 1024);
5317dd7cddfSDavid du Colombier 			pm->wdir = emalloc(1024);
53280ee5cbfSDavid du Colombier 			snprint(pm->wdir, 1024, "%s/%s", wdir, c);
53380ee5cbfSDavid du Colombier 			cleanname(pm->wdir);
53480ee5cbfSDavid du Colombier 			free(wdir);
53580ee5cbfSDavid du Colombier 			free(c);
53680ee5cbfSDavid du Colombier 		}
53780ee5cbfSDavid du Colombier 		c = strrchr(pm->wdir, '/');
53880ee5cbfSDavid du Colombier 		if(c)
53980ee5cbfSDavid du Colombier 			*c = '\0';
5407dd7cddfSDavid du Colombier 		pm->type = strdup("text");
5417dd7cddfSDavid du Colombier 		if(p1 > p0)
5427dd7cddfSDavid du Colombier 			pm->attr = nil;
5437dd7cddfSDavid du Colombier 		else{
5447dd7cddfSDavid du Colombier 			p = p0;
5457dd7cddfSDavid du Colombier 			while(p0>0 && (i=filereadc(f, p0 - 1))!=' ' && i!='\t' && i!='\n')
5467dd7cddfSDavid du Colombier 				p0--;
5477dd7cddfSDavid du Colombier 			while(p1<f->nc && (i=filereadc(f, p1))!=' ' && i!='\t' && i!='\n')
5487dd7cddfSDavid du Colombier 				p1++;
5497dd7cddfSDavid du Colombier 			sprint(cbuf, "click=%ld", p-p0);
5507dd7cddfSDavid du Colombier 			pm->attr = plumbunpackattr(cbuf);
5517dd7cddfSDavid du Colombier 		}
5527dd7cddfSDavid du Colombier 		if(p0==p1 || p1-p0>=BLOCKSIZE){
5537dd7cddfSDavid du Colombier 			plumbfree(pm);
5547dd7cddfSDavid du Colombier 			break;
5557dd7cddfSDavid du Colombier 		}
5567dd7cddfSDavid du Colombier 		setgenstr(f, p0, p1);
5577dd7cddfSDavid du Colombier 		pm->data = Strtoc(&genstr);
5587dd7cddfSDavid du Colombier 		pm->ndata = strlen(pm->data);
5597dd7cddfSDavid du Colombier 		c = plumbpack(pm, &i);
5607dd7cddfSDavid du Colombier 		if(c != 0){
5617dd7cddfSDavid du Colombier 			outTs(Hplumb, i);
5627dd7cddfSDavid du Colombier 			Write(1, c, i);
5637dd7cddfSDavid du Colombier 			free(c);
5647dd7cddfSDavid du Colombier 		}
5657dd7cddfSDavid du Colombier 		plumbfree(pm);
5667dd7cddfSDavid du Colombier 		break;
5677dd7cddfSDavid du Colombier 
5683e12c5d1SDavid du Colombier 	case Texit:
5693e12c5d1SDavid du Colombier 		exits(0);
5703e12c5d1SDavid du Colombier 	}
5713e12c5d1SDavid du Colombier 	return TRUE;
5723e12c5d1SDavid du Colombier }
5733e12c5d1SDavid du Colombier 
5743e12c5d1SDavid du Colombier void
snarf(File * f,Posn p1,Posn p2,Buffer * buf,int emptyok)5753e12c5d1SDavid du Colombier snarf(File *f, Posn p1, Posn p2, Buffer *buf, int emptyok)
5763e12c5d1SDavid du Colombier {
5773e12c5d1SDavid du Colombier 	Posn l;
5783e12c5d1SDavid du Colombier 	int i;
5793e12c5d1SDavid du Colombier 
5803e12c5d1SDavid du Colombier 	if(!emptyok && p1==p2)
5813e12c5d1SDavid du Colombier 		return;
5827dd7cddfSDavid du Colombier 	bufreset(buf);
5833e12c5d1SDavid du Colombier 	/* Stage through genbuf to avoid compaction problems (vestigial) */
5847dd7cddfSDavid du Colombier 	if(p2 > f->nc){
5857dd7cddfSDavid 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 */
5867dd7cddfSDavid du Colombier 		p2 = f->nc;
5877dd7cddfSDavid du Colombier 	}
5883e12c5d1SDavid du Colombier 	for(l=p1; l<p2; l+=i){
5893e12c5d1SDavid du Colombier 		i = p2-l>BLOCKSIZE? BLOCKSIZE : p2-l;
5907dd7cddfSDavid du Colombier 		bufread(f, l, genbuf, i);
5917dd7cddfSDavid du Colombier 		bufinsert(buf, buf->nc, tmprstr(genbuf, i)->s, i);
5923e12c5d1SDavid du Colombier 	}
5933e12c5d1SDavid du Colombier }
5943e12c5d1SDavid du Colombier 
5953e12c5d1SDavid du Colombier int
inshort(void)5963e12c5d1SDavid du Colombier inshort(void)
5973e12c5d1SDavid du Colombier {
5983e12c5d1SDavid du Colombier 	ushort n;
5993e12c5d1SDavid du Colombier 
6003e12c5d1SDavid du Colombier 	n = inp[0] | (inp[1]<<8);
6013e12c5d1SDavid du Colombier 	inp += 2;
6023e12c5d1SDavid du Colombier 	return n;
6033e12c5d1SDavid du Colombier }
6043e12c5d1SDavid du Colombier 
6053e12c5d1SDavid du Colombier long
inlong(void)6063e12c5d1SDavid du Colombier inlong(void)
6073e12c5d1SDavid du Colombier {
6083e12c5d1SDavid du Colombier 	ulong n;
6093e12c5d1SDavid du Colombier 
6103e12c5d1SDavid du Colombier 	n = inp[0] | (inp[1]<<8) | (inp[2]<<16) | (inp[3]<<24);
6113e12c5d1SDavid du Colombier 	inp += 4;
6123e12c5d1SDavid du Colombier 	return n;
6133e12c5d1SDavid du Colombier }
6143e12c5d1SDavid du Colombier 
61573e742d7SDavid du Colombier vlong
invlong(void)616219b2ee8SDavid du Colombier invlong(void)
617219b2ee8SDavid du Colombier {
61873e742d7SDavid du Colombier 	vlong v;
619219b2ee8SDavid du Colombier 
62073e742d7SDavid du Colombier 	v = (inp[7]<<24) | (inp[6]<<16) | (inp[5]<<8) | inp[4];
62173e742d7SDavid du Colombier 	v = (v<<16) | (inp[3]<<8) | inp[2];
62273e742d7SDavid du Colombier 	v = (v<<16) | (inp[1]<<8) | inp[0];
623219b2ee8SDavid du Colombier 	inp += 8;
62473e742d7SDavid du Colombier 	return v;
625219b2ee8SDavid du Colombier }
626219b2ee8SDavid du Colombier 
6273e12c5d1SDavid du Colombier void
setgenstr(File * f,Posn p0,Posn p1)6283e12c5d1SDavid du Colombier setgenstr(File *f, Posn p0, Posn p1)
6293e12c5d1SDavid du Colombier {
6303e12c5d1SDavid du Colombier 	if(p0 != p1){
6313e12c5d1SDavid du Colombier 		if(p1-p0 >= TBLOCKSIZE)
6323e12c5d1SDavid du Colombier 			error(Etoolong);
6333e12c5d1SDavid du Colombier 		Strinsure(&genstr, p1-p0);
6347dd7cddfSDavid du Colombier 		bufread(f, p0, genbuf, p1-p0);
6353e12c5d1SDavid du Colombier 		memmove(genstr.s, genbuf, RUNESIZE*(p1-p0));
6363e12c5d1SDavid du Colombier 		genstr.n = p1-p0;
6373e12c5d1SDavid du Colombier 	}else{
6387dd7cddfSDavid du Colombier 		if(snarfbuf.nc == 0)
6393e12c5d1SDavid du Colombier 			error(Eempty);
6407dd7cddfSDavid du Colombier 		if(snarfbuf.nc > TBLOCKSIZE)
6413e12c5d1SDavid du Colombier 			error(Etoolong);
6427dd7cddfSDavid du Colombier 		bufread(&snarfbuf, (Posn)0, genbuf, snarfbuf.nc);
6437dd7cddfSDavid du Colombier 		Strinsure(&genstr, snarfbuf.nc);
6447dd7cddfSDavid du Colombier 		memmove(genstr.s, genbuf, RUNESIZE*snarfbuf.nc);
6457dd7cddfSDavid du Colombier 		genstr.n = snarfbuf.nc;
6463e12c5d1SDavid du Colombier 	}
6473e12c5d1SDavid du Colombier }
6483e12c5d1SDavid du Colombier 
6493e12c5d1SDavid du Colombier void
outT0(Hmesg type)6503e12c5d1SDavid du Colombier outT0(Hmesg type)
6513e12c5d1SDavid du Colombier {
6523e12c5d1SDavid du Colombier 	outstart(type);
6533e12c5d1SDavid du Colombier 	outsend();
6543e12c5d1SDavid du Colombier }
6553e12c5d1SDavid du Colombier 
6563e12c5d1SDavid du Colombier void
outTl(Hmesg type,long l)6573e12c5d1SDavid du Colombier outTl(Hmesg type, long l)
6583e12c5d1SDavid du Colombier {
6593e12c5d1SDavid du Colombier 	outstart(type);
6603e12c5d1SDavid du Colombier 	outlong(l);
6613e12c5d1SDavid du Colombier 	outsend();
6623e12c5d1SDavid du Colombier }
6633e12c5d1SDavid du Colombier 
6643e12c5d1SDavid du Colombier void
outTs(Hmesg type,int s)6653e12c5d1SDavid du Colombier outTs(Hmesg type, int s)
6663e12c5d1SDavid du Colombier {
6673e12c5d1SDavid du Colombier 	outstart(type);
6683e12c5d1SDavid du Colombier 	journaln(1, s);
6693e12c5d1SDavid du Colombier 	outshort(s);
6703e12c5d1SDavid du Colombier 	outsend();
6713e12c5d1SDavid du Colombier }
6723e12c5d1SDavid du Colombier 
6733e12c5d1SDavid du Colombier void
outS(String * s)6743e12c5d1SDavid du Colombier outS(String *s)
6753e12c5d1SDavid du Colombier {
6763e12c5d1SDavid du Colombier 	char *c;
6773e12c5d1SDavid du Colombier 	int i;
6783e12c5d1SDavid du Colombier 
6793e12c5d1SDavid du Colombier 	c = Strtoc(s);
6803e12c5d1SDavid du Colombier 	i = strlen(c);
6813e12c5d1SDavid du Colombier 	outcopy(i, c);
6823e12c5d1SDavid du Colombier 	if(i > 99)
6833e12c5d1SDavid du Colombier 		c[99] = 0;
6843e12c5d1SDavid du Colombier 	journaln(1, i);
6853e12c5d1SDavid du Colombier 	journal(1, c);
6863e12c5d1SDavid du Colombier 	free(c);
6873e12c5d1SDavid du Colombier }
6883e12c5d1SDavid du Colombier 
6893e12c5d1SDavid du Colombier void
outTsS(Hmesg type,int s1,String * s)6903e12c5d1SDavid du Colombier outTsS(Hmesg type, int s1, String *s)
6913e12c5d1SDavid du Colombier {
6923e12c5d1SDavid du Colombier 	outstart(type);
6933e12c5d1SDavid du Colombier 	outshort(s1);
6943e12c5d1SDavid du Colombier 	outS(s);
6953e12c5d1SDavid du Colombier 	outsend();
6963e12c5d1SDavid du Colombier }
6973e12c5d1SDavid du Colombier 
6983e12c5d1SDavid du Colombier void
outTslS(Hmesg type,int s1,Posn l1,String * s)6993e12c5d1SDavid du Colombier outTslS(Hmesg type, int s1, Posn l1, String *s)
7003e12c5d1SDavid du Colombier {
7013e12c5d1SDavid du Colombier 	outstart(type);
7023e12c5d1SDavid du Colombier 	outshort(s1);
7033e12c5d1SDavid du Colombier 	journaln(1, s1);
7043e12c5d1SDavid du Colombier 	outlong(l1);
7053e12c5d1SDavid du Colombier 	journaln(1, l1);
7063e12c5d1SDavid du Colombier 	outS(s);
7073e12c5d1SDavid du Colombier 	outsend();
7083e12c5d1SDavid du Colombier }
7093e12c5d1SDavid du Colombier 
7103e12c5d1SDavid du Colombier void
outTS(Hmesg type,String * s)7113e12c5d1SDavid du Colombier outTS(Hmesg type, String *s)
7123e12c5d1SDavid du Colombier {
7133e12c5d1SDavid du Colombier 	outstart(type);
7143e12c5d1SDavid du Colombier 	outS(s);
7153e12c5d1SDavid du Colombier 	outsend();
7163e12c5d1SDavid du Colombier }
7173e12c5d1SDavid du Colombier 
7183e12c5d1SDavid du Colombier void
outTsllS(Hmesg type,int s1,Posn l1,Posn l2,String * s)7193e12c5d1SDavid du Colombier outTsllS(Hmesg type, int s1, Posn l1, Posn l2, String *s)
7203e12c5d1SDavid du Colombier {
7213e12c5d1SDavid du Colombier 	outstart(type);
7223e12c5d1SDavid du Colombier 	outshort(s1);
7233e12c5d1SDavid du Colombier 	outlong(l1);
7243e12c5d1SDavid du Colombier 	outlong(l2);
7253e12c5d1SDavid du Colombier 	journaln(1, l1);
7263e12c5d1SDavid du Colombier 	journaln(1, l2);
7273e12c5d1SDavid du Colombier 	outS(s);
7283e12c5d1SDavid du Colombier 	outsend();
7293e12c5d1SDavid du Colombier }
7303e12c5d1SDavid du Colombier 
7313e12c5d1SDavid du Colombier void
outTsll(Hmesg type,int s,Posn l1,Posn l2)7323e12c5d1SDavid du Colombier outTsll(Hmesg type, int s, Posn l1, Posn l2)
7333e12c5d1SDavid du Colombier {
7343e12c5d1SDavid du Colombier 	outstart(type);
7353e12c5d1SDavid du Colombier 	outshort(s);
7363e12c5d1SDavid du Colombier 	outlong(l1);
7373e12c5d1SDavid du Colombier 	outlong(l2);
7383e12c5d1SDavid du Colombier 	journaln(1, l1);
7393e12c5d1SDavid du Colombier 	journaln(1, l2);
7403e12c5d1SDavid du Colombier 	outsend();
7413e12c5d1SDavid du Colombier }
7423e12c5d1SDavid du Colombier 
7433e12c5d1SDavid du Colombier void
outTsl(Hmesg type,int s,Posn l)7443e12c5d1SDavid du Colombier outTsl(Hmesg type, int s, Posn l)
7453e12c5d1SDavid du Colombier {
7463e12c5d1SDavid du Colombier 	outstart(type);
7473e12c5d1SDavid du Colombier 	outshort(s);
7483e12c5d1SDavid du Colombier 	outlong(l);
7493e12c5d1SDavid du Colombier 	journaln(1, l);
7503e12c5d1SDavid du Colombier 	outsend();
7513e12c5d1SDavid du Colombier }
7523e12c5d1SDavid du Colombier 
7533e12c5d1SDavid du Colombier void
outTsv(Hmesg type,int s,vlong v)75473e742d7SDavid du Colombier outTsv(Hmesg type, int s, vlong v)
755219b2ee8SDavid du Colombier {
756219b2ee8SDavid du Colombier 	outstart(type);
757219b2ee8SDavid du Colombier 	outshort(s);
75873e742d7SDavid du Colombier 	outvlong(v);
75973e742d7SDavid du Colombier 	journalv(1, v);
760219b2ee8SDavid du Colombier 	outsend();
761219b2ee8SDavid du Colombier }
762219b2ee8SDavid du Colombier 
763219b2ee8SDavid du Colombier void
outstart(Hmesg type)7643e12c5d1SDavid du Colombier outstart(Hmesg type)
7653e12c5d1SDavid du Colombier {
7663e12c5d1SDavid du Colombier 	journal(1, hname[type]);
7673e12c5d1SDavid du Colombier 	outmsg[0] = type;
7683e12c5d1SDavid du Colombier 	outp = outmsg+3;
7693e12c5d1SDavid du Colombier }
7703e12c5d1SDavid du Colombier 
7713e12c5d1SDavid du Colombier void
outcopy(int count,void * data)7723e12c5d1SDavid du Colombier outcopy(int count, void *data)
7733e12c5d1SDavid du Colombier {
7743e12c5d1SDavid du Colombier 	memmove(outp, data, count);
7753e12c5d1SDavid du Colombier 	outp += count;
7763e12c5d1SDavid du Colombier }
7773e12c5d1SDavid du Colombier 
7783e12c5d1SDavid du Colombier void
outshort(int s)7793e12c5d1SDavid du Colombier outshort(int s)
7803e12c5d1SDavid du Colombier {
7813e12c5d1SDavid du Colombier 	*outp++ = s;
7823e12c5d1SDavid du Colombier 	*outp++ = s>>8;
7833e12c5d1SDavid du Colombier }
7843e12c5d1SDavid du Colombier 
7853e12c5d1SDavid du Colombier void
outlong(long l)7863e12c5d1SDavid du Colombier outlong(long l)
7873e12c5d1SDavid du Colombier {
7883e12c5d1SDavid du Colombier 	*outp++ = l;
7893e12c5d1SDavid du Colombier 	*outp++ = l>>8;
7903e12c5d1SDavid du Colombier 	*outp++ = l>>16;
7913e12c5d1SDavid du Colombier 	*outp++ = l>>24;
7923e12c5d1SDavid du Colombier }
7933e12c5d1SDavid du Colombier 
7943e12c5d1SDavid du Colombier void
outvlong(vlong v)79573e742d7SDavid du Colombier outvlong(vlong v)
796219b2ee8SDavid du Colombier {
797219b2ee8SDavid du Colombier 	int i;
798219b2ee8SDavid du Colombier 
79973e742d7SDavid du Colombier 	for(i = 0; i < 8; i++){
80073e742d7SDavid du Colombier 		*outp++ = v;
80173e742d7SDavid du Colombier 		v >>= 8;
80273e742d7SDavid du Colombier 	}
803219b2ee8SDavid du Colombier }
804219b2ee8SDavid du Colombier 
805219b2ee8SDavid du Colombier void
outsend(void)8063e12c5d1SDavid du Colombier outsend(void)
8073e12c5d1SDavid du Colombier {
8083e12c5d1SDavid du Colombier 	int outcount;
8093e12c5d1SDavid du Colombier 
810*54d47c71SDavid du Colombier 	if(outp >= outdata+nelem(outdata))
811*54d47c71SDavid du Colombier 		panic("outsend");
8123e12c5d1SDavid du Colombier 	outcount = outp-outmsg;
8133e12c5d1SDavid du Colombier 	outcount -= 3;
8143e12c5d1SDavid du Colombier 	outmsg[1] = outcount;
8153e12c5d1SDavid du Colombier 	outmsg[2] = outcount>>8;
8163e12c5d1SDavid du Colombier 	outmsg = outp;
817*54d47c71SDavid du Colombier 	if(!outbuffered){
818bd389b36SDavid du Colombier 		outcount = outmsg-outdata;
819bd389b36SDavid du Colombier 		if (write(1, (char*) outdata, outcount) != outcount)
820bd389b36SDavid du Colombier 			rescue();
8213e12c5d1SDavid du Colombier 		outmsg = outdata;
8223e12c5d1SDavid du Colombier 		return;
8233e12c5d1SDavid du Colombier 	}
824*54d47c71SDavid du Colombier }
825*54d47c71SDavid du Colombier 
826*54d47c71SDavid du Colombier int
needoutflush(void)827*54d47c71SDavid du Colombier needoutflush(void)
828*54d47c71SDavid du Colombier {
829*54d47c71SDavid du Colombier 	return outmsg >= outdata+DATASIZE;
8303e12c5d1SDavid du Colombier }
8313e12c5d1SDavid du Colombier 
8323e12c5d1SDavid du Colombier void
outflush(void)8333e12c5d1SDavid du Colombier outflush(void)
8343e12c5d1SDavid du Colombier {
8353e12c5d1SDavid du Colombier 	if(outmsg == outdata)
8363e12c5d1SDavid du Colombier 		return;
837*54d47c71SDavid du Colombier 	outbuffered = 0;
838*54d47c71SDavid du Colombier 	/* flow control */
8393e12c5d1SDavid du Colombier 	outT0(Hack);
8403e12c5d1SDavid du Colombier 	waitack = 1;
8413e12c5d1SDavid du Colombier 	do
8423e12c5d1SDavid du Colombier 		if(rcv() == 0){
8433e12c5d1SDavid du Colombier 			rescue();
8443e12c5d1SDavid du Colombier 			exits("eof");
8453e12c5d1SDavid du Colombier 		}
8463e12c5d1SDavid du Colombier 	while(waitack);
8473e12c5d1SDavid du Colombier 	outmsg = outdata;
848*54d47c71SDavid du Colombier 	outbuffered = 1;
8493e12c5d1SDavid du Colombier }
850