|
|
1.1 root 1: #include "sam.h"
2:
3: Header h;
4: uchar indata[DATASIZE];
5: uchar outdata[DATASIZE+3];
6: short outcount;
7: long inlong();
8: Posn cmdpt;
9: Posn cmdptadv;
10: Buffer *snarfbuf;
11:
12: log(out, s)
13: char *s;
14: {
15: static fd=0;
16: if(fd<=0)
17: fd=creat("/usr/rob/sam.out", 0666);
18: fprint(fd, "%s%s\n", out? "out: " : "in: ", s);
19: }
20: logn(out, n)
21: int n;
22: {
23: char buf[32];
24: sprint(buf, "%d", n);
25: log(out, buf);
26: }
27: #ifdef DIST
28: #define log(a, b)
29: #define logn(a, b)
30: #endif
31: rcvchar(){
32: static uchar buf[64];
33: static i, nleft=0;
34: if(nleft<=0){
35: nleft=read(0, (char *)buf, sizeof buf);
36: if(nleft<=0)
37: return -1;
38: i=0;
39: }
40: --nleft;
41: return buf[i++];
42: }
43: rcv(){
44: register c;
45: static state=0;
46: static count=0;
47: static i=0;
48: while((c=rcvchar())!=-1)
49: switch(state){
50: case 0:
51: h.type=c;
52: state++;
53: break;
54: case 1:
55: h.count0=c;
56: state++;
57: break;
58: case 2:
59: h.count1=c;
60: count=h.count0|(h.count1<<8);
61: i=0;
62: if(count>DATASIZE)
63: panic("count>DATASIZE");
64: if(count==0)
65: goto zerocount;
66: state++;
67: break;
68: case 3:
69: indata[i++]=c;
70: if(i==count){
71: zerocount:
72: state=count=0;
73: return inmesg(h.type);
74: }
75: break;
76: }
77: return 0;
78: }
79: File *
80: whichfile(tag)
81: register tag;
82: {
83: register i;
84: for(i=0; i<file.nused; i++)
85: if(file.ptr[i]->tag==tag)
86: return file.ptr[i];
87: hiccough((char *)0);
88: /*NOTREACHED*/
89: return 0;
90: }
91: inmesg(type)
92: Tmesg type;
93: {
94: uchar buf[1025];
95: register i, m;
96: long l;
97: register File *f;
98: register Posn p0, p1;
99: Range r;
100: switch(type){
101: case -1:
102: panic("rcv error");
103: default:
104: panic("rcv unknown");
105: case Tcut:
106: log(0, "Tcut");
107: f=whichfile(inshort(0));
108: p0=inlong(2);
109: p1=inlong(6);
110: logn(0, (int)p0);
111: logn(0, (int)p1);
112: Fdelete(f, p0, p1);
113: if(Fupdate(f, FALSE, FALSE))
114: modnum++;
115: f->dot.r.p1=f->dot.r.p2=p0;
116: f->tdot=f->dot.r; /* terminal knows the value of dot already */
117: break;
118: case Tpaste:
119: log(0, "Tpaste");
120: f=whichfile(inshort(0));
121: p0=inlong(2);
122: logn(0, (int)p0);
123: for(l=0; l<snarfbuf->nbytes; l+=m){
124: m=snarfbuf->nbytes-l;
125: if(m>BLOCKSIZE)
126: m=BLOCKSIZE;
127: Bread(snarfbuf, genbuf, m, l);
128: Finsert(f, tempstr(genbuf, m), p0);
129: }
130: if(Fupdate(f, FALSE, TRUE))
131: modnum++;
132: f->dot.r.p1=p0;
133: f->dot.r.p2=p0+snarfbuf->nbytes;
134: f->tdot.p1= -1; /* force telldot to tell (arguably a BUG) */
135: telldot(f);
136: outTs(Hunlockfile, f->tag);
137: break;
138: case Tsnarf:
139: log(0, "Tsnarf");
140: snarf(whichfile(inshort(0)), inlong(2), inlong(6));
141: break;
142: case Ttype:
143: log(0, "Ttype");
144: f=whichfile(inshort(0));
145: p0=inlong(2);
146: logn(0, (int)p0);
147: log(0, (char *)indata+6);
148: i=strlen(indata+6);
149: Finsert(f, tempstr(indata+6, i), p0);
150: if(Fupdate(f, FALSE, FALSE))
151: modnum++;
152: if(f==cmd && p0==f->nbytes-i && i>0 && indata[i+6-1]=='\n')
153: termcommand();
154: f->dot.r.p1=f->dot.r.p2=p0+i; /* terminal knows this already */
155: f->tdot=f->dot.r;
156: break;
157: case Tstartfile:
158: log(0, "Tstartfile");
159: f=whichfile(inshort(0));
160: if(!f->rasp) /* this might be a duplicate message */
161: f->rasp=new(List, 1);
162: current(f);
163: outTsl(Hbindname, f->tag, inlong(2));
164: outTs(Hcurrent, f->tag);
165: logn(0, f->tag);
166: if(f->state==Unread)
167: load(f);
168: else{
169: if(f->nbytes>0){
170: rgrow(f->rasp, 0L, f->nbytes);
171: outTsll(Hgrow, f->tag, 0L, f->nbytes);
172: }
173: outTs(Hcheck0, f->tag);
174: moveto(f, f->dot.r);
175: }
176: break;
177: case Tstartcmdfile:
178: log(0, "Tstartcmdfile");
179: l=inlong(0);
180: strdup(&genstr, (uchar *)"~~sam~~");
181: cmd=newfile();
182: outTsl(Hbindname, cmd->tag, l);
183: outTs(Hcurrent, cmd->tag);
184: Fsetname(cmd);
185: cmd->rasp=new(List, 1);
186: cmd->state=Clean;
187: if(cmdstr.n){
188: Finsert(cmd, &cmdstr, 0L);
189: strdelete(&cmdstr, 0L, (Posn)cmdstr.n);
190: }
191: Fupdate(cmd, FALSE, TRUE);
192: outT0(Hunlock);
193: break;
194: case Tstartnewfile:
195: log(0, "Tstartnewfile");
196: l=inlong(0);
197: strdup(&genstr, (uchar *)"");
198: f=newfile();
199: f->rasp=new(List, 1);
200: outTsl(Hbindname, f->tag, l);
201: Fsetname(f);
202: outTs(Hcurrent, f->tag);
203: current(f);
204: load(f);
205: break;
206: case Trequest:
207: log(0, "Trequest");
208: f=whichfile(inshort(0));
209: p0=inlong(2);
210: logn(0, (int)p0);
211: logn(0, inshort(6));
212: if(f->state==Unread)
213: panic("Trequest: unread");
214: p1=p0+inshort(6);
215: if(p0>f->nbytes){ /* can happen e.g. scrolling during command */
216: buf[0]=0;
217: r.p1=r.p2=f->nbytes;
218: }else{
219: if(p1>f->nbytes)
220: p1=f->nbytes;
221: r=rdata(f->rasp, p0, p1-p0);
222: i=r.p2-r.p1;
223: if(Fchars(f, buf, r.p1, r.p2)!=i)
224: panic("Trequest 2");
225: buf[i]=0;
226: }
227: outTslS(Hdata, f->tag, r.p1, buf);
228: break;
229: case Twrite:
230: log(0, "Twrite");
231: f=whichfile(inshort(0));
232: addr.r.p1=0;
233: addr.r.p2=f->nbytes;
234: if(f->name.s[0]==0)
235: error(Enoname);
236: strdupstr(&genstr, &f->name);
237: writef(f);
238: break;
239: case Tworkfile:
240: log(0, "Tworkfile");
241: logn(0, (int)inlong(2));
242: logn(0, (int)inlong(6));
243: f=whichfile(inshort(0));
244: current(f);
245: f->dot.r.p1=inlong(2);
246: f->dot.r.p2=inlong(6);
247: f->tdot=f->dot.r;
248: break;
249: case Tcheck:
250: log(0, "Tcheck");
251: /* go through whichfile to check the tag */
252: outTs(Hcheck, whichfile(inshort(0))->tag);
253: break;
254: case Torigin:
255: log(0, "Torigin");
256: logn(0, (int)inlong(6));
257: lookorigin(whichfile(inshort(0)), inlong(2), inlong(6));
258: break;
259: case Tclose:
260: log(0, "Tclose");
261: f=whichfile(inshort(0));
262: current(f);
263: trytoclose(f);
264: break;
265: case Tlook:
266: log(0, "Tlook");
267: f=whichfile(inshort(0));
268: p0=inlong(2);
269: p1=inlong(6);
270: setgenstr(f, p0, p1);
271: for(l=0; l<genstr.n; l++){
272: i=genstr.s[l];
273: if(i && !('a'<=i && i<='z') && !('A'<=i && i<='Z'))
274: strinsert(&genstr, tempstr((uchar *)"\\", 1), l++);
275: }
276: straddc(&genstr, '\0');
277: {Regexp poot;
278: poot.text=genstr;
279: nextmatch(f, &poot, p1, 1); /* BUGGERED */
280: }
281: moveto(f, sel);
282: break;
283: case Tsearch:
284: log(0, "Tsearch");
285: if(curfile==0)
286: error(Enofile);
287: if(lastpat.n==0)
288: panic("Tsearch");
289: {Regexp poot;
290: poot.text=lastpat;
291: nextmatch(curfile, &poot, curfile->dot.r.p2, 1); /* BUGGERED */
292: }
293: moveto(curfile, sel);
294: break;
295: case Tsend:
296: log(0, "Tsend");
297: p0=inlong(2);
298: p1=inlong(6);
299: setgenstr(cmd, p0, p1);
300: Bdelete(snarfbuf, (Posn)0, snarfbuf->nbytes);
301: Binsert(snarfbuf, &genstr, (Posn)0);
302: outTl(Hsnarflen, (long)genstr.n);
303: if(genstr.s[genstr.n-1]!='\n')
304: straddc(&genstr, '\n');
305: Fdelete(cmd, cmdpt, cmd->nbytes);
306: Finsert(cmd, &genstr, cmd->nbytes);
307: Fupdate(cmd, FALSE, TRUE);
308: cmd->dot.r.p1=cmd->dot.r.p2=cmd->nbytes;
309: telldot(cmd);
310: termcommand();
311: break;
312: case Tunlockfile:
313: log(0, "Tunlockfile");
314: outTs(Hunlockfile, whichfile(inshort(0))->tag);
315: break;
316: case Tstartsnarf:
317: log(0, "Tstartsnarf");
318: if(snarfbuf->nbytes>BLOCKSIZE)
319: error(Etoolong);
320: outTs(Hsetsnarf, (int)snarfbuf->nbytes);
321: Bread(snarfbuf, genbuf, (int)snarfbuf->nbytes, (Posn)0);
322: Write(1, genbuf, (int)snarfbuf->nbytes);
323: break;
324: case Tsetsnarf:
325: log(0, "Tsetsnarf");
326: m=inshort(0);
327: if(m>BLOCKSIZE)
328: error(Etoolong);
329: for(i=0; i<m; i++)
330: genbuf[i]=rcvchar();
331: Bdelete(snarfbuf, (Posn)0, snarfbuf->nbytes);
332: Binsert(snarfbuf, tempstr(genbuf, m), (Posn)0);
333: outT0(Hunlock);
334: break;
335: case Tdclick:
336: log(0, "Tdclick");
337: f=whichfile(inshort(0));
338: p1=inlong(2);
339: doubleclick(f, p1);
340: f->tdot.p1=f->tdot.p2=p1;
341: telldot(f);
342: outTs(Hunlockfile, f->tag);
343: break;
344: case Texit:
345: log(0, "Texit");
346: return FALSE;
347: }
348: return TRUE;
349: }
350: snarf(f, p1, p2)
351: register File *f;
352: register Posn p1, p2;
353: {
354: register Posn l;
355: register i;
356: if(p1==p2)
357: return;
358: Bdelete(snarfbuf, (Posn)0, snarfbuf->nbytes);
359: /* Stage through genbuf to avoid compaction problems */
360: for(l=p1; l<p2; l+=i){
361: i=p2-l>BLOCKSIZE? BLOCKSIZE : p2-l;
362: Fchars(f, genbuf, l, l+i);
363: Binsert(snarfbuf, tempstr(genbuf, i), snarfbuf->nbytes);
364: }
365: }
366: inshort(n)
367: {
368: return indata[n]|(indata[n+1]<<8);
369: }
370: long
371: inlong(n)
372: {
373: return indata[n]|(indata[n+1]<<8)|
374: ((long)indata[n+2]<<16)|((long)indata[n+3]<<24);
375: }
376: setgenstr(f, p0, p1)
377: register File *f;
378: register Posn p0, p1;
379: {
380: if(p0!=p1){
381: if(p1-p0>=TBLOCKSIZE)
382: error(Etoolong);
383: strinsure(&genstr, p1-p0);
384: genstr.n=p1-p0;
385: Fchars(f, genstr.s, p0, p1);
386: }else{
387: if(snarfbuf->nbytes==0)
388: error(Eempty);
389: if(snarfbuf->nbytes>TBLOCKSIZE)
390: error(Etoolong);
391: Bread(snarfbuf, genbuf, (int)snarfbuf->nbytes, (Posn)0);
392: strinsure(&genstr, snarfbuf->nbytes);
393: bcopy(genbuf, genbuf+snarfbuf->nbytes, genstr.s, 1);
394: genstr.n=snarfbuf->nbytes;
395: }
396: }
397: outT0(type)
398: Hmesg type;
399: {
400: outstart(type);
401: outsend();
402: }
403: outTl(type, l)
404: Hmesg type;
405: long l;
406: {
407: outstart(type);
408: outlong(l);
409: outsend();
410: }
411: outTs(type, s)
412: Hmesg type;
413: {
414: outstart(type);
415: logn(1, s);
416: outshort(s);
417: outsend();
418: }
419: outTsS(type, s1, s)
420: Hmesg type;
421: uchar *s;
422: {
423: outstart(type);
424: outshort(s1);
425: outcopy(strlen(s)+1, s);
426: log(1, (char *)s);
427: outsend();
428: }
429: outTssl(type, s1, s2, l)
430: Hmesg type;
431: long l;
432: {
433: outstart(type);
434: outshort(s1);
435: outshort(s2);
436: outlong(l);
437: outsend();
438: }
439: outTslS(type, s1, l1, s)
440: Hmesg type;
441: Posn l1;
442: uchar *s;
443: {
444: char buf[100];
445: register i;
446: outstart(type);
447: outshort(s1);
448: outlong(l1);
449: logn(1, (int)l1);
450: outcopy(strlen(s)+1, s);
451: i=strlen(s);
452: if(i>99)
453: i=99;
454: buf[i]=0;
455: while(--i>=0)
456: buf[i]=s[i];
457: log(1, buf);
458: outsend();
459: }
460: outTS(type, s)
461: Hmesg type;
462: uchar *s;
463: {
464: char buf[100];
465: register i;
466: outstart(type);
467: outcopy(strlen(s)+1, s);
468: i=strlen(s);
469: if(i>99)
470: i=99;
471: buf[i]=0;
472: while(--i>=0)
473: buf[i]=s[i];
474: log(1, buf);
475: outsend();
476: }
477: outTsllS(type, s1, l1, l2, s)
478: Hmesg type;
479: Posn l1, l2;
480: uchar *s;
481: {
482: char buf[100];
483: register i;
484: outstart(type);
485: outshort(s1);
486: outlong(l1);
487: outlong(l2);
488: logn(1, (int)l1);
489: logn(1, (int)l2);
490: outcopy(strlen(s)+1, s);
491: i=strlen(s);
492: if(i>99)
493: i=99;
494: buf[i]=0;
495: while(--i>=0)
496: buf[i]=s[i];
497: log(1, buf);
498: outsend();
499: }
500: outTsll(type, s, l1, l2)
501: Hmesg type;
502: Posn l1, l2;
503: {
504: outstart(type);
505: outshort(s);
506: outlong(l1);
507: outlong(l2);
508: logn(1, (int)l1);
509: logn(1, (int)l2);
510: outsend();
511: }
512: outTsl(type, s, l)
513: Hmesg type;
514: Posn l;
515: {
516: outstart(type);
517: outshort(s);
518: outlong(l);
519: logn(1, (int)l);
520: outsend();
521: }
522: outstart(type)
523: Hmesg type;
524: {
525: switch(type){
526: case Hnewname:
527: log(1, "Hnewname");
528: break;
529: case Hdelname:
530: log(1, "Hdelname");
531: break;
532: case Hmovname:
533: log(1, "Hmovname");
534: break;
535: case Hbindname:
536: log(1, "Hbindname");
537: break;
538: case Hcurrent:
539: log(1, "Hcurrent");
540: break;
541: case Hgrow:
542: log(1, "Hgrow");
543: break;
544: case Hdata:
545: log(1, "Hdata");
546: break;
547: case Hgrowdata:
548: log(1, "Hgrowdata");
549: break;
550: case Hcut:
551: log(1, "Hcut");
552: break;
553: case Hclean:
554: log(1, "Hclean");
555: break;
556: case Hdirty:
557: log(1, "Hdirty");
558: break;
559: case Hcheck0:
560: log(1, "Hcheck0");
561: break;
562: case Hcheck:
563: log(1, "Hcheck");
564: break;
565: case Hmoveto:
566: log(1, "Hmoveto");
567: break;
568: case Hsetdot:
569: log(1, "Hsetdot");
570: break;
571: case Horigin:
572: log(1, "Horigin");
573: break;
574: case Hclose:
575: log(1, "Hclose");
576: break;
577: case Hunlock:
578: log(1, "Hunlock");
579: break;
580: case Hsetpat:
581: log(1, "Hsetpat");
582: break;
583: case Hsetsnarf:
584: log(1, "Hsetsnarf");
585: break;
586: case Hsnarflen:
587: log(1, "Hsnarflen");
588: break;
589: case Hexit:
590: log(1, "Hexit");
591: break;
592: }
593: outdata[0]=type;
594: outcount=0;
595: }
596: outcopy(count, data)
597: register uchar *data;
598: {
599: while(count--)
600: outdata[3+outcount++]= *data++;
601: }
602: outshort(s)
603: {
604: uchar buf[2];
605: buf[0]=s;
606: buf[1]=s>>8;
607: outcopy(2, buf);
608: }
609: outlong(l)
610: long l;
611: {
612: uchar buf[4];
613: buf[0]=l;
614: buf[1]=l>>8;
615: buf[2]=l>>16;
616: buf[3]=l>>24;
617: outcopy(4, buf);
618: }
619: outsend()
620: {
621: if(outcount>DATASIZE)
622: panic("outcount>DATASIZE");
623: outdata[1]=outcount;
624: outdata[2]=outcount>>8;
625: Write(1, outdata, outcount+3);
626: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.