|
|
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.