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",
80 [Tstartsnarf] "Tstartsnarf",
81 [Tsetsnarf] "Tsetsnarf",
88 journal(int out, char *s)
93 fd = create("/tmp/sam.out", 1, 0666L);
95 fprint(fd, "%s%s\n", out? "out: " : "in: ", s);
99 journaln(int out, long n)
103 snprint(buf, sizeof(buf), "%ld", n);
108 journalv(int out, vlong v)
112 sprint(buf, sizeof(buf), "%lld", v);
116 #define journal(a, b)
117 #define journaln(a, b)
118 #define journalv(a, b)
123 static uchar buf[64];
127 nleft = read(0, (char *)buf, sizeof buf);
143 while((c=rcvchar()) != -1)
157 count = h.count0|(h.count1<<8);
160 panic("count>DATASIZE");
172 return inmesg(h.type);
184 for(i = 0; i<file.nused; i++)
185 if(file.filepptr[i]->tag==tag)
186 return file.filepptr[i];
211 journal(0, tname[type]);
219 fprint(2, "unknown type %d\n", type);
220 panic("rcv unknown");
223 tversion = inshort();
224 journaln(0, tversion);
228 v = invlong(); /* for 64-bit pointers */
230 Strdupl(&genstr, samname);
233 outTsv(Hbindname, cmd->tag, v);
234 outTs(Hcurrent, cmd->tag);
235 logsetname(cmd, &genstr);
236 cmd->rasp = listalloc('P');
239 loginsert(cmd, 0L, cmdstr.s, cmdstr.n);
240 Strdelete(&cmdstr, 0L, (Posn)cmdstr.n);
242 fileupdate(cmd, FALSE, TRUE);
247 /* go through whichfile to check the tag */
248 outTs(Hcheck, whichfile(inshort())->tag);
252 f = whichfile(inshort());
258 panic("Trequest: unread");
261 if(p0>f->nc) /* can happen e.g. scrolling during command */
267 r = rdata(f->rasp, p0, p1-p0);
269 bufread(f, r.p1, buf, i);
272 outTslS(Hdata, f->tag, r.p1, tmprstr(buf, i+1));
280 lookorigin(whichfile(s), l, l1);
285 f = whichfile(inshort());
286 if(!f->rasp) /* this might be a duplicate message */
287 f->rasp = listalloc('P');
289 outTsv(Hbindname, f->tag, invlong()); /* for 64-bit pointers */
290 outTs(Hcurrent, f->tag);
296 rgrow(f->rasp, 0L, f->nc);
297 outTsll(Hgrow, f->tag, 0L, f->nc);
299 outTs(Hcheck0, f->tag);
308 f->dot.r.p1 = inlong();
309 f->dot.r.p2 = inlong();
312 journaln(0, f->dot.r.p1);
313 journaln(0, f->dot.r.p2);
317 f = whichfile(inshort());
320 journal(0, (char*)inp);
321 str = tmpcstr((char*)inp);
323 loginsert(f, p0, str->s, str->n);
324 if(fileupdate(f, FALSE, FALSE))
326 if(f==cmd && p0==f->nc-i && i>0 && str->s[i-1]=='\n'){
332 f->dot.r.p1 = f->dot.r.p2 = p0+i; /* terminal knows this already */
337 f = whichfile(inshort());
342 logdelete(f, p0, p1);
343 if(fileupdate(f, FALSE, FALSE))
345 f->dot.r.p1 = f->dot.r.p2 = p0;
346 f->tdot = f->dot.r; /* terminal knows the value of dot already */
350 f = whichfile(inshort());
353 for(l=0; l<snarfbuf.nc; l+=m){
357 bufread(&snarfbuf, l, genbuf, m);
358 loginsert(f, p0, tmprstr(genbuf, m)->s, m);
360 if(fileupdate(f, FALSE, TRUE))
363 f->dot.r.p2 = p0+snarfbuf.nc;
364 f->tdot.p1 = -1; /* force telldot to tell (arguably a BUG) */
366 outTs(Hunlockfile, f->tag);
373 snarf(whichfile(i), p0, p1, &snarfbuf, 0);
378 Strdupl(&genstr, empty);
380 f->rasp = listalloc('P');
381 outTsv(Hbindname, f->tag, v);
382 logsetname(f, &genstr);
383 outTs(Hcurrent, f->tag);
395 if(f->name.s[0] == 0)
397 Strduplstr(&genstr, &f->name);
408 /* if trytoclose fails, will error out */
413 f = whichfile(inshort());
419 setgenstr(f, p0, p1);
420 for(l = 0; l<genstr.n; l++){
422 if(utfrune(".*+?(|)\\[]^$", i)){
424 Strinsert(&genstr, str, l++);
428 Straddc(&genstr, '\0');
429 nextmatch(f, &genstr, p1, 1);
437 if(lastpat.s[0] == 0)
439 nextmatch(curfile, &lastpat, curfile->dot.r.p2, 1);
440 moveto(curfile, sel.p[0]);
445 inshort(); /* ignored */
448 setgenstr(cmd, p0, p1);
450 bufinsert(&snarfbuf, (Posn)0, genstr.s, genstr.n);
451 outTl(Hsnarflen, genstr.n);
452 if(genstr.s[genstr.n-1] != '\n')
453 Straddc(&genstr, '\n');
454 loginsert(cmd, cmd->nc, genstr.s, genstr.n);
455 fileupdate(cmd, FALSE, TRUE);
456 cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->nc;
463 f = whichfile(inshort());
465 stretchsel(f, p1, type == Ttclick);
466 f->tdot.p1 = f->tdot.p2 = p1;
468 outTs(Hunlockfile, f->tag);
472 if (snarfbuf.nc <= 0) { /* nothing to export */
481 dprint("?warning: snarf buffer truncated\n");
483 rp = malloc(m*sizeof(Rune));
485 bufread(&snarfbuf, 0, rp, m);
486 c = Strtoc(tmprstr(rp, m));
495 dprint("snarf buffer too long\n");
510 bufinsert(&snarfbuf, (Posn)0, str->s, str->n);
521 f = whichfile(inshort());
524 pm = emalloc(sizeof(Plumbmsg));
525 pm->src = strdup("sam");
527 /* construct current directory */
528 c = Strtoc(&f->name);
532 wdir = emalloc(1024);
534 pm->wdir = emalloc(1024);
535 snprint(pm->wdir, 1024, "%s/%s", wdir, c);
540 c = strrchr(pm->wdir, '/');
543 pm->type = strdup("text");
548 while(p0>0 && (i=filereadc(f, p0 - 1))!=' ' && i!='\t' && i!='\n')
550 while(p1<f->nc && (i=filereadc(f, p1))!=' ' && i!='\t' && i!='\n')
552 sprint(cbuf, "click=%ld", p-p0);
553 pm->attr = plumbunpackattr(cbuf);
555 if(p0==p1 || p1-p0>=BLOCKSIZE){
559 setgenstr(f, p0, p1);
560 pm->data = Strtoc(&genstr);
561 pm->ndata = strlen(pm->data);
562 c = plumbpack(pm, &i);
578 snarf(File *f, Posn p1, Posn p2, Buffer *buf, int emptyok)
583 if(!emptyok && p1==p2)
586 /* Stage through genbuf to avoid compaction problems (vestigial) */
588 fprint(2, "bad snarf addr p1=%ld p2=%ld f->nc=%d\n", p1, p2, f->nc); /*ZZZ should never happen, can remove */
591 for(l=p1; l<p2; l+=i){
592 i = p2-l>BLOCKSIZE? BLOCKSIZE : p2-l;
593 bufread(f, l, genbuf, i);
594 bufinsert(buf, buf->nc, tmprstr(genbuf, i)->s, i);
603 n = inp[0] | (inp[1]<<8);
613 n = inp[0] | (inp[1]<<8) | (inp[2]<<16) | (inp[3]<<24);
623 v = (inp[7]<<24) | (inp[6]<<16) | (inp[5]<<8) | inp[4];
624 v = (v<<16) | (inp[3]<<8) | inp[2];
625 v = (v<<16) | (inp[1]<<8) | inp[0];
631 setgenstr(File *f, Posn p0, Posn p1)
634 if(p1-p0 >= TBLOCKSIZE)
636 Strinsure(&genstr, p1-p0);
637 bufread(f, p0, genbuf, p1-p0);
638 memmove(genstr.s, genbuf, RUNESIZE*(p1-p0));
643 if(snarfbuf.nc > TBLOCKSIZE)
645 bufread(&snarfbuf, (Posn)0, genbuf, snarfbuf.nc);
646 Strinsure(&genstr, snarfbuf.nc);
647 memmove(genstr.s, genbuf, RUNESIZE*snarfbuf.nc);
648 genstr.n = snarfbuf.nc;
660 outTl(Hmesg type, long l)
668 outTs(Hmesg type, int s)
693 outTsS(Hmesg type, int s1, String *s)
702 outTslS(Hmesg type, int s1, Posn l1, String *s)
714 outTS(Hmesg type, String *s)
722 outTsllS(Hmesg type, int s1, Posn l1, Posn l2, String *s)
735 outTsll(Hmesg type, int s, Posn l1, Posn l2)
747 outTsl(Hmesg type, int s, Posn l)
757 outTsv(Hmesg type, int s, vlong v)
769 journal(1, hname[type]);
775 outcopy(int count, void *data)
777 memmove(outp, data, count);
802 for(i = 0; i < 8; i++){
813 if(outp >= outdata+nelem(outdata))
815 outcount = outp-outmsg;
817 outmsg[1] = outcount;
818 outmsg[2] = outcount>>8;
821 outcount = outmsg-outdata;
822 if (write(1, (char*) outdata, outcount) != outcount)
832 return outmsg >= outdata+DATASIZE;
838 if(outmsg == outdata)