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