4 uchar indata[DATASIZE];
5 uchar outdata[2*DATASIZE+3]; /* room for overflow message */
8 uchar *outmsg = outdata;
24 void outcopy(int, void*);
28 void setgenstr(File*, Posn, Posn);
32 [Hversion] "Hversion",
33 [Hbindname] "Hbindname",
34 [Hcurrent] "Hcurrent",
35 [Hnewname] "Hnewname",
36 [Hmovname] "Hmovname",
43 [Hunlockfile] "Hunlockfile",
45 [Hgrowdata] "Hgrowdata",
51 [Hdelname] "Hdelname",
53 [Hsetsnarf] "Hsetsnarf",
54 [Hsnarflen] "Hsnarflen",
61 [Tversion] "Tversion",
62 [Tstartcmdfile] "Tstartcmdfile",
64 [Trequest] "Trequest",
66 [Tstartfile] "Tstartfile",
67 [Tworkfile] "Tworkfile",
72 [Tstartnewfile] "Tstartnewfile",
79 [Tstartsnarf] "Tstartsnarf",
80 [Tsetsnarf] "Tsetsnarf",
87 journal(int out, char *s)
92 fd = create("/tmp/sam.out", 1, 0666L);
94 fprint(fd, "%s%s\n", out? "out: " : "in: ", s);
98 journaln(int out, long n)
102 snprint(buf, sizeof(buf), "%ld", n);
107 journalv(int out, vlong v)
111 sprint(buf, sizeof(buf), "%lld", v);
115 #define journal(a, b)
116 #define journaln(a, b)
117 #define journalv(a, b)
122 static uchar buf[64];
126 nleft = read(0, (char *)buf, sizeof buf);
142 while((c=rcvchar()) != -1)
156 count = h.count0|(h.count1<<8);
159 panic("count>DATASIZE");
171 return inmesg(h.type);
183 for(i = 0; i<file.nused; i++)
184 if(file.filepptr[i]->tag==tag)
185 return file.filepptr[i];
210 journal(0, tname[type]);
218 fprint(2, "unknown type %d\n", type);
219 panic("rcv unknown");
222 tversion = inshort();
223 journaln(0, tversion);
227 v = invlong(); /* for 64-bit pointers */
229 Strdupl(&genstr, samname);
232 outTsv(Hbindname, cmd->tag, v);
233 outTs(Hcurrent, cmd->tag);
234 logsetname(cmd, &genstr);
235 cmd->rasp = listalloc('P');
238 loginsert(cmd, 0L, cmdstr.s, cmdstr.n);
239 Strdelete(&cmdstr, 0L, (Posn)cmdstr.n);
241 fileupdate(cmd, FALSE, TRUE);
246 /* go through whichfile to check the tag */
247 outTs(Hcheck, whichfile(inshort())->tag);
251 f = whichfile(inshort());
257 panic("Trequest: unread");
260 if(p0>f->nc) /* can happen e.g. scrolling during command */
266 r = rdata(f->rasp, p0, p1-p0);
268 bufread(f, r.p1, buf, i);
271 outTslS(Hdata, f->tag, r.p1, tmprstr(buf, i+1));
279 lookorigin(whichfile(s), l, l1);
284 f = whichfile(inshort());
285 if(!f->rasp) /* this might be a duplicate message */
286 f->rasp = listalloc('P');
288 outTsv(Hbindname, f->tag, invlong()); /* for 64-bit pointers */
289 outTs(Hcurrent, f->tag);
295 rgrow(f->rasp, 0L, f->nc);
296 outTsll(Hgrow, f->tag, 0L, f->nc);
298 outTs(Hcheck0, f->tag);
307 f->dot.r.p1 = inlong();
308 f->dot.r.p2 = inlong();
311 journaln(0, f->dot.r.p1);
312 journaln(0, f->dot.r.p2);
316 f = whichfile(inshort());
319 journal(0, (char*)inp);
320 str = tmpcstr((char*)inp);
322 loginsert(f, p0, str->s, str->n);
323 if(fileupdate(f, FALSE, FALSE))
325 if(f==cmd && p0==f->nc-i && i>0 && str->s[i-1]=='\n'){
331 f->dot.r.p1 = f->dot.r.p2 = p0+i; /* terminal knows this already */
336 f = whichfile(inshort());
341 logdelete(f, p0, p1);
342 if(fileupdate(f, FALSE, FALSE))
344 f->dot.r.p1 = f->dot.r.p2 = p0;
345 f->tdot = f->dot.r; /* terminal knows the value of dot already */
349 f = whichfile(inshort());
352 for(l=0; l<snarfbuf.nc; l+=m){
356 bufread(&snarfbuf, l, genbuf, m);
357 loginsert(f, p0, tmprstr(genbuf, m)->s, m);
359 if(fileupdate(f, FALSE, TRUE))
362 f->dot.r.p2 = p0+snarfbuf.nc;
363 f->tdot.p1 = -1; /* force telldot to tell (arguably a BUG) */
365 outTs(Hunlockfile, f->tag);
372 snarf(whichfile(i), p0, p1, &snarfbuf, 0);
377 Strdupl(&genstr, empty);
379 f->rasp = listalloc('P');
380 outTsv(Hbindname, f->tag, v);
381 logsetname(f, &genstr);
382 outTs(Hcurrent, f->tag);
394 if(f->name.s[0] == 0)
396 Strduplstr(&genstr, &f->name);
407 /* if trytoclose fails, will error out */
412 f = whichfile(inshort());
418 setgenstr(f, p0, p1);
419 for(l = 0; l<genstr.n; l++){
421 if(utfrune(".*+?(|)\\[]^$", i)){
423 Strinsert(&genstr, str, l++);
427 Straddc(&genstr, '\0');
428 nextmatch(f, &genstr, p1, 1);
436 if(lastpat.s[0] == 0)
438 nextmatch(curfile, &lastpat, curfile->dot.r.p2, 1);
439 moveto(curfile, sel.p[0]);
444 inshort(); /* ignored */
447 setgenstr(cmd, p0, p1);
449 bufinsert(&snarfbuf, (Posn)0, genstr.s, genstr.n);
450 outTl(Hsnarflen, genstr.n);
451 if(genstr.s[genstr.n-1] != '\n')
452 Straddc(&genstr, '\n');
453 loginsert(cmd, cmd->nc, genstr.s, genstr.n);
454 fileupdate(cmd, FALSE, TRUE);
455 cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->nc;
461 f = whichfile(inshort());
464 f->tdot.p1 = f->tdot.p2 = p1;
466 outTs(Hunlockfile, f->tag);
470 if (snarfbuf.nc <= 0) { /* nothing to export */
479 dprint("?warning: snarf buffer truncated\n");
481 rp = malloc(m*sizeof(Rune));
483 bufread(&snarfbuf, 0, rp, m);
484 c = Strtoc(tmprstr(rp, m));
493 dprint("snarf buffer too long\n");
508 bufinsert(&snarfbuf, (Posn)0, str->s, str->n);
519 f = whichfile(inshort());
522 pm = emalloc(sizeof(Plumbmsg));
523 pm->src = strdup("sam");
525 /* construct current directory */
526 c = Strtoc(&f->name);
530 wdir = emalloc(1024);
532 pm->wdir = emalloc(1024);
533 snprint(pm->wdir, 1024, "%s/%s", wdir, c);
538 c = strrchr(pm->wdir, '/');
541 pm->type = strdup("text");
546 while(p0>0 && (i=filereadc(f, p0 - 1))!=' ' && i!='\t' && i!='\n')
548 while(p1<f->nc && (i=filereadc(f, p1))!=' ' && i!='\t' && i!='\n')
550 sprint(cbuf, "click=%ld", p-p0);
551 pm->attr = plumbunpackattr(cbuf);
553 if(p0==p1 || p1-p0>=BLOCKSIZE){
557 setgenstr(f, p0, p1);
558 pm->data = Strtoc(&genstr);
559 pm->ndata = strlen(pm->data);
560 c = plumbpack(pm, &i);
576 snarf(File *f, Posn p1, Posn p2, Buffer *buf, int emptyok)
581 if(!emptyok && p1==p2)
584 /* Stage through genbuf to avoid compaction problems (vestigial) */
586 fprint(2, "bad snarf addr p1=%ld p2=%ld f->nc=%d\n", p1, p2, f->nc); /*ZZZ should never happen, can remove */
589 for(l=p1; l<p2; l+=i){
590 i = p2-l>BLOCKSIZE? BLOCKSIZE : p2-l;
591 bufread(f, l, genbuf, i);
592 bufinsert(buf, buf->nc, tmprstr(genbuf, i)->s, i);
601 n = inp[0] | (inp[1]<<8);
611 n = inp[0] | (inp[1]<<8) | (inp[2]<<16) | (inp[3]<<24);
621 v = (inp[7]<<24) | (inp[6]<<16) | (inp[5]<<8) | inp[4];
622 v = (v<<16) | (inp[3]<<8) | inp[2];
623 v = (v<<16) | (inp[1]<<8) | inp[0];
629 setgenstr(File *f, Posn p0, Posn p1)
632 if(p1-p0 >= TBLOCKSIZE)
634 Strinsure(&genstr, p1-p0);
635 bufread(f, p0, genbuf, p1-p0);
636 memmove(genstr.s, genbuf, RUNESIZE*(p1-p0));
641 if(snarfbuf.nc > TBLOCKSIZE)
643 bufread(&snarfbuf, (Posn)0, genbuf, snarfbuf.nc);
644 Strinsure(&genstr, snarfbuf.nc);
645 memmove(genstr.s, genbuf, RUNESIZE*snarfbuf.nc);
646 genstr.n = snarfbuf.nc;
658 outTl(Hmesg type, long l)
666 outTs(Hmesg type, int s)
691 outTsS(Hmesg type, int s1, String *s)
700 outTslS(Hmesg type, int s1, Posn l1, String *s)
712 outTS(Hmesg type, String *s)
720 outTsllS(Hmesg type, int s1, Posn l1, Posn l2, String *s)
733 outTsll(Hmesg type, int s, Posn l1, Posn l2)
745 outTsl(Hmesg type, int s, Posn l)
755 outTsv(Hmesg type, int s, vlong v)
767 journal(1, hname[type]);
773 outcopy(int count, void *data)
775 memmove(outp, data, count);
800 for(i = 0; i < 8; i++){
811 if(outp >= outdata+nelem(outdata))
813 outcount = outp-outmsg;
815 outmsg[1] = outcount;
816 outmsg[2] = outcount>>8;
819 outcount = outmsg-outdata;
820 if (write(1, (char*) outdata, outcount) != outcount)
830 return outmsg >= outdata+DATASIZE;
836 if(outmsg == outdata)