|
|
1.1 ! root 1: #include <termio.h> ! 2: #include <fcntl.h> ! 3: #include <stdio.h> ! 4: #include <signal.h> ! 5: ! 6: /* EMACS_MODES: c,!fill,tabstop=4 */ ! 7: ! 8: #define MWIND 6 ! 9: ! 10: int wproc[MWIND]; ! 11: int wx[MWIND]; ! 12: int wy[MWIND]; ! 13: int wox[MWIND]; ! 14: int woy[MWIND]; ! 15: int wofrn[MWIND]; ! 16: int wifrn[MWIND]; ! 17: int wbase[MWIND]; ! 18: int wmode[MWIND]; ! 19: int wstate[MWIND]; ! 20: ! 21: char wrbuf[MWIND] [BUFSIZ]; ! 22: int wcnt[MWIND]; ! 23: int wptr[MWIND]; ! 24: int wmore[MWIND]; ! 25: ! 26: #define MSNORM 0 ! 27: #define MSESC 1 ! 28: #define MSXWAIT 2 ! 29: #define MSYWAIT 3 ! 30: ! 31: #define MRAW 1 ! 32: #define MMORE 2 ! 33: #define MMSCROLL 4 ! 34: #define MECHO 8 ! 35: #define MVSEND 16 ! 36: #define WSCROLL 32 ! 37: #define MOPENW 64 ! 38: #define MWAIT 128 ! 39: ! 40: char *mdname[16] = {"RAW", ! 41: "MORE", ! 42: "ROLL", ! 43: "ECHO", ! 44: "VIRTUAL", ! 45: "SCROLLING", ! 46: "OPEN-WAIT", ! 47: "MWAIT", ! 48: }; ! 49: int wlen[MWIND]; ! 50: ! 51: int talkf = 0; /* 1 if we are xtalk */ ! 52: ! 53: int cwind,nwind; ! 54: ! 55: int quote,squig; ! 56: ! 57: int ic; ! 58: int rx,ry; ! 59: ! 60: char ibuf[BUFSIZ]; ! 61: char tibuf[BUFSIZ]; ! 62: ! 63: extern int SCRNLIN; ! 64: extern int SCRWID; ! 65: extern int mcol; ! 66: extern int mline; ! 67: extern int ttykill; ! 68: extern int ttyerase; ! 69: extern int ttyintr; ! 70: extern int errno; ! 71: extern char *getname(); ! 72: extern char *homedir(); ! 73: extern char *findtty(); ! 74: extern char *getenv(); ! 75: ! 76: tdelay(num) ! 77: ! 78: int num; ! 79: { ! 80: /* VMIN = 0 does not seem to work ! 81: ! 82: ! 83: struct termio td; ! 84: ! 85: ioctl(0,TCGETA, &td); ! 86: td.c_cc[VMIN] = num; ! 87: td.c_cc[VTIME] = 1; ! 88: ioctl(0,TCSETA, &td); ! 89: */ ! 90: /* THIS KLUDGE ALSO WORKS POORLY, so now do it with a user level timer ! 91: ! 92: ! 93: if (num == 0) fcntl(0,F_SETFL,O_RDWR+O_NDELAY); ! 94: else fcntl(0,F_SETFL,O_RDWR); ! 95: */ ! 96: } ! 97: ! 98: ! 99: alarming() ! 100: { ! 101: return; ! 102: } ! 103: ! 104: xclose(x) ! 105: int x; ! 106: { ! 107: int i; ! 108: ! 109: for (i = x; i < 20; i++) close(i); ! 110: } ! 111: ! 112: wput(i,cp,nc) ! 113: int i; ! 114: int nc; ! 115: char *cp; ! 116: { ! 117: register int x; ! 118: int maxln; ! 119: ! 120: maxln = wbase[i]+wlen[i]; ! 121: xgo(wx[i]+wbase[i],wy[i]); ! 122: for (x = 0; x < nc; x++) { ! 123: if (cp[x] == '\n') { ! 124: clrl(); ! 125: mline++; ! 126: mcol=0; ! 127: } else xputc(cp[x]); ! 128: if (mline>=maxln) { ! 129: wroll(i); ! 130: } ! 131: } ! 132: } ! 133: ! 134: /* wroll -- roll over window i */ ! 135: ! 136: ! 137: wroll(i) ! 138: register int i; ! 139: { ! 140: if ((wmode[i] & WSCROLL) || (vadjust(wbase[i],wbase[i]-1+wlen[i],-1)== 0)) { ! 141: xgo(wbase[i],0); ! 142: clrl(); ! 143: } else { ! 144: mline--; ! 145: } ! 146: } ! 147: ! 148: wmfix(c) ! 149: register c; ! 150: { ! 151: xgo(wx[c]+wbase[c],wy[c]); ! 152: wroll(c); ! 153: if (mline == wbase[c]) { ! 154: wmore[c] = wlen[c]-1; ! 155: } else { ! 156: wmore[c] = 0; ! 157: wmode[c] |= MMSCROLL; ! 158: } ! 159: wmode[c] |= MWAIT; ! 160: wmode[c] ^= MWAIT; ! 161: wx[c]=mline-wbase[c]; ! 162: wy[c]=mcol; ! 163: } ! 164: ! 165: main(argc,argv) ! 166: ! 167: int argc; ! 168: char **argv; ! 169: { ! 170: ! 171: int c; ! 172: char *cp,*tp; ! 173: int status; ! 174: int pipe1[2]; ! 175: int pipe2[2]; ! 176: int i; ! 177: int x; ! 178: ttystart(); ! 179: signal(SIGCLD,SIG_IGN); ! 180: signal(SIGPIPE,SIG_IGN); ! 181: tdelay(0); ! 182: nwind = 1; ! 183: wifrn[0]=0; ! 184: wofrn[0]=0; ! 185: wmode[0]=0; ! 186: wx[0]=0; ! 187: wy[0]=0; ! 188: wbase[0]=0; ! 189: wlen[0]=SCRNLIN-2; ! 190: wmore[0] = wlen[0]-1; ! 191: ! 192: if (**argv != 'w') { ! 193: talkf = 1; /* We are talk */ ! 194: talk(argv[1]); /* start talking */ ! 195: } ! 196: ! 197: while (1) { ! 198: for (i = 0; i < nwind; i++) { ! 199: ! 200: if (wmode[i] & MOPENW) { ! 201: ! 202: wofrn[i] = open(wrbuf[i],1+O_NDELAY); ! 203: if (wofrn[i] >= 0) { ! 204: wmode[i] ^= MOPENW; ! 205: prompt1("TALKING"); ! 206: } else { ! 207: prompt1("WAITING"); ! 208: } ! 209: } else if (wifrn[i]) { ! 210: if (wcnt[i] == 0) { ! 211: wcnt[i] = read(wifrn[i],wrbuf[i],BUFSIZ); ! 212: wptr[i] = 0; ! 213: } ! 214: if (wcnt[i]) { ! 215: x = wprot(i,wrbuf[i]+wptr[i],wcnt[i]); ! 216: wptr[i] += wcnt[i]-x; ! 217: wcnt[i] = x; ! 218: if (i == cwind) { ! 219: rx = wx[i]+wbase[i]; ! 220: ry = wy[i]; ! 221: } ! 222: } ! 223: } ! 224: } ! 225: xgo (SCRNLIN-2,0); ! 226: for (i = 0; i < nwind; i++) { ! 227: if (wmode[i]&MWAIT) { ! 228: sputs(" MORE-"); ! 229: xputc(i+'0'); ! 230: } ! 231: } ! 232: clrl(); ! 233: if (squig) prompt1("~: "); ! 234: else if (wmode[cwind] & MRAW) { ! 235: mgo(wx[cwind]+wbase[cwind],wy[cwind]); ! 236: } else { ! 237: mgo (rx,ry); ! 238: } ! 239: fflush(stdout); ! 240: signal(SIGALRM,alarming); ! 241: alarm(1); ! 242: x = read(0,&c,1); ! 243: alarm(0); ! 244: if (x > 0) { ! 245: if (squig) { ! 246: squig = 0; ! 247: unprompt(); ! 248: switch(c) { ! 249: ! 250: case '': ! 251: abort(); ! 252: case '': ! 253: rfrsh(); ! 254: break; ! 255: case 'w': ! 256: cwind++; ! 257: if (cwind >= nwind) cwind = 0; ! 258: if ((wmode[cwind] &MRAW) == 0) { ! 259: rx = wx[cwind]+wbase[cwind]; ! 260: ry = wy[cwind]; ! 261: ic = 0; ! 262: } ! 263: break; ! 264: ! 265: ! 266: ! 267: ! 268: case 't': ! 269: cp = getname ("Talk to? "); ! 270: if (cp) talk(cp); ! 271: break; ! 272: case 's': ! 273: wsplit(cwind); ! 274: break; ! 275: ! 276: case '?': ! 277: wmode[cwind] |= MMORE; ! 278: newin("/n1/warren/emacs/windows.help"); ! 279: break; ! 280: case '<': ! 281: cp = getname("Input from? "); ! 282: newin(cp); ! 283: break; ! 284: case '>': ! 285: if (wofrn[cwind]) close(wofrn[cwind]); ! 286: tdelay(1); ! 287: cp = getname("Output to? "); ! 288: tdelay(0); ! 289: wofrn[cwind] = open(cp,1+O_NDELAY); ! 290: if (wofrn[cwind] < 0) prompt1("error code %d",errno); ! 291: break; ! 292: case '!': ! 293: if (wifrn[cwind]) close(wifrn[cwind]); ! 294: if (wofrn[cwind]) close(wofrn[cwind]); ! 295: if (wproc[cwind]) { ! 296: kill(wproc[cwind],9); ! 297: }; ! 298: tdelay(1); ! 299: cp = getname ("Command? "); ! 300: tdelay(0); ! 301: ! 302: pipe(pipe1); ! 303: pipe(pipe2); ! 304: if ((wproc[cwind] = fork()) == 0) { ! 305: close(0); ! 306: dup(pipe1[0]); ! 307: close(1); ! 308: close(2); ! 309: dup(pipe2[1]); ! 310: dup(pipe2[1]); ! 311: xclose(3); ! 312: signal(SIGCLD,SIG_DFL); ! 313: tp = getenv("TERM"); ! 314: *tp='v'; ! 315: tp[1]=0; ! 316: execl("/bin/sh", "sh", "-c", cp , 0); ! 317: exit(0); ! 318: } else { ! 319: close(pipe1[0]); ! 320: close(pipe2[1]); ! 321: wifrn[cwind] = pipe2[0]; ! 322: fcntl(pipe2[0],F_SETFL,O_RDONLY+O_NDELAY); ! 323: wofrn[cwind] = pipe1[1]; ! 324: } ! 325: break; ! 326: ! 327: case 'k': ! 328: if (wproc[cwind]) kill(wproc[cwind],9); ! 329: if (wofrn[cwind] ){ ! 330: close(wofrn[cwind]); ! 331: wofrn[cwind] = 0; ! 332: } ! 333: if (wifrn[cwind]) { ! 334: close(wifrn[cwind]); ! 335: wifrn[cwind] = 0; ! 336: } ! 337: break; ! 338: case 'v': ! 339: wmode[cwind] ^= MVSEND; ! 340: break; ! 341: case 'd': ! 342: xgo(SCRNLIN-1,0); ! 343: xprintf("#%d,ifrn:%d,ofrn:%d,base:%d,len:%d,", ! 344: cwind,wifrn[cwind],wofrn[cwind],wbase[cwind],wlen[cwind]); ! 345: xprintf("pid:%o,mode:%o (",wproc[cwind],wmode[cwind]); ! 346: for (x = 0; x < 16; x++) { ! 347: if (wmode[cwind] & (1<<x)) { ! 348: xprintf ("%s,",mdname[x]); ! 349: } ! 350: } ! 351: xputc(')'); ! 352: clrl(); ! 353: break; ! 354: case '0': ! 355: case '1': ! 356: case '2': ! 357: case '3': ! 358: c-='0'; ! 359: if (wmode[c]&MWAIT) { ! 360: wmfix(c); ! 361: } ! 362: break; ! 363: case 'm': ! 364: wmode[cwind] ^= MMORE; ! 365: case 'S': ! 366: wmode[cwind] ^= WSCROLL; ! 367: break; ! 368: case 'r': ! 369: wmode[cwind] ^= MRAW; ! 370: break; ! 371: case '~': ! 372: goto defchar; ! 373: case '.': ! 374: for (i = 0; i < nwind; i++) { ! 375: if (wproc[i]) kill (wproc[i],9); /* murder */ ! 376: } ! 377: tdelay(1); ! 378: die(0); /* go away */ ! 379: } ! 380: } else { ! 381: ! 382: if (c == '~') { ! 383: squig++; ! 384: } else { ! 385: defchar: /* implement modes here */ ! 386: ! 387: if (wmode[cwind]&MWAIT) { ! 388: wmfix(cwind); ! 389: } else { ! 390: if (wmode[cwind] & MMSCROLL) { ! 391: wmore[cwind] = 0; /* input to this window */ ! 392: } else { ! 393: wmore[cwind] = wlen[cwind]-1; ! 394: } ! 395: } ! 396: if (wmode[cwind]&MRAW) { ! 397: if (wofrn[cwind]) { ! 398: write(wofrn[cwind],&c,1); ! 399: } ! 400: } else { ! 401: if (quote) goto deflt; ! 402: if (c == ttyerase) { ! 403: if (ic) ic--; ! 404: if (wmode[cwind] & MVSEND) { ! 405: wput(cwind,tibuf,ic); ! 406: x = ry-mcol; ! 407: if (x < 0) x=1; ! 408: if (wofrn[cwind]) { ! 409: write(wofrn[cwind],"",x); ! 410: write(wofrn[cwind],"T",2); ! 411: } ! 412: } ! 413: } else if (c == ttykill) { ! 414: ic = 0; ! 415: if (wofrn[cwind] && (wmode[cwind] & MVSEND)) { ! 416: write(wofrn[cwind]," T",3); ! 417: } ! 418: } else if ((c == 015) ||(c == '\n') || (c == 4)) { ! 419: if (c == '\r') c = '\n'; ! 420: tibuf[ic++] = c; ! 421: wput(cwind,tibuf,ic); ! 422: rx = mline; ! 423: wx[cwind] = mline-wbase[cwind]; ! 424: ry = wy[cwind]=mcol; ! 425: if (wofrn[cwind]) { ! 426: if (wmode[cwind] & MVSEND) { ! 427: write(wofrn[cwind],&c,1); ! 428: } else { ! 429: write(wofrn[cwind],tibuf,ic); ! 430: } ! 431: } ! 432: ic = 0; ! 433: if ((c == 4) && talkf) die(0); /* exit */ ! 434: } else if (c == '\\') { ! 435: quote++; ! 436: } else if (c == ttyintr) { ! 437: if (wproc[cwind]) signal(wproc[cwind],SIGINT); ! 438: } else { ! 439: deflt: tibuf[ic++] = c; ! 440: quote = 0; ! 441: if ((wmode[cwind] & MVSEND) && wofrn[cwind]) { ! 442: write(wofrn[cwind],&c,1); ! 443: } ! 444: } ! 445: wput(cwind,tibuf,ic); ! 446: rx = mline; ! 447: ry = mcol; ! 448: clrl(); ! 449: } ! 450: } ! 451: } ! 452: } else { ! 453: /* sleep(1);*/ ! 454: } ! 455: } ! 456: } ! 457: wsplit(w) ! 458: ! 459: int w; ! 460: { ! 461: int x; ! 462: ! 463: wbase[nwind] = wbase[w]+1+(wlen[w]/2); ! 464: wlen[nwind] = wlen[w]-wbase[nwind]+wbase[w]; ! 465: wlen[w]=wbase[nwind]-wbase[w]-1; ! 466: xgo(wbase[w]+wlen[w],0); ! 467: for (x = 0; x < SCRWID; x++) { ! 468: xputc('-'); ! 469: } ! 470: wx[nwind]=wy[nwind]=wifrn[nwind]=wofrn[nwind]=0; ! 471: ! 472: if (wx[w] >= wlen[w]) wx[w] = 0; ! 473: ! 474: wmore[w] = wlen[w]-1; ! 475: wmore[nwind]=wlen[nwind]-1; ! 476: nwind++; ! 477: } ! 478: ! 479: ! 480: wprot(w,cp,n) ! 481: int w; ! 482: char *cp; ! 483: int n; ! 484: { ! 485: char wbuf[10]; ! 486: ! 487: int i; ! 488: ! 489: if (wmode[w] & MWAIT) return(n); ! 490: ! 491: for (i = 0; (i < n); i++) { ! 492: switch(wstate[w]) { ! 493: ! 494: case MSNORM: ! 495: switch(cp[i]) { ! 496: ! 497: case '': ! 498: if (wy[w]) wy[w]--; ! 499: break; ! 500: case '': ! 501: if (wx[w]) wx[w]--; ! 502: break; ! 503: case '': ! 504: wy[w]++; ! 505: break; ! 506: case ' ': ! 507: wy[w]=0; ! 508: break; ! 509: case '': ! 510: xgo(wx[w]+wbase[w],wy[w]); ! 511: sputs("EOF"); ! 512: if (talkf) die(0); ! 513: break; ! 514: case '': ! 515: case '\n': ! 516: xgo(wx[w]+wbase[w],wy[w]); ! 517: if (cp[i] == '\n'){ ! 518: clrl(); ! 519: mcol=0; ! 520: } ! 521: mline++; ! 522: if ((cp[i] == '\n') && (mline <wlen[w]+wbase[w])) clrl(); ! 523: goto wscroll; ! 524: case '': ! 525: beep(); ! 526: break; ! 527: case '': ! 528: wx[w]=wy[w]=0; ! 529: break; ! 530: case '': ! 531: wstate[w]=MSESC; ! 532: break; ! 533: case '&': ! 534: break; ! 535: default: ! 536: xgo(wx[w]+wbase[w],wy[w]); ! 537: xputc(cp[i]); ! 538: wscroll: if (mline>=wbase[w]+wlen[w]) { ! 539: if((wmode[w]&MMORE)&& (++wmore[w] >= (wlen[w]))) { ! 540: wmode[w] |= MWAIT; ! 541: wx[w]=mline-wbase[w]; ! 542: wy[w]=mcol; ! 543: return(n-i); ! 544: } ! 545: wroll(w); ! 546: } ! 547: wx[w]=mline-wbase[w]; ! 548: wy[w]=mcol; ! 549: } ! 550: break; ! 551: case MSESC: ! 552: switch(cp[i]) { ! 553: ! 554: case 'Y': ! 555: while (wx[w] < wlen[w]) { ! 556: xgo(wx[w]+wbase[w],0); ! 557: clrl(); ! 558: wx[w]++; ! 559: } ! 560: wx[w]=wy[w]=0; ! 561: break; ! 562: case 'T': ! 563: xgo(wx[w]+wbase[w],wy[w]); ! 564: clrl(); ! 565: break; ! 566: case '?': ! 567: if (wofrn[w]) { ! 568: sprintf(wbuf,">%c%c",wlen[w]+' ',SCRWID+' '); ! 569: write(wofrn[w],wbuf,4); ! 570: } ! 571: break; ! 572: case '=': ! 573: wstate[w] = MSXWAIT; ! 574: break; ! 575: } ! 576: if (wstate[w] == MSESC) wstate[w] = MSNORM; ! 577: break; ! 578: case MSXWAIT: ! 579: wx[w] = cp[i]-040; ! 580: if (wx[w] >= wlen[w]) wx[w]=0; ! 581: wstate[w]= MSYWAIT; ! 582: break; ! 583: case MSYWAIT: ! 584: wy[w] = cp[i]-040; ! 585: wstate[w] = MSNORM; ! 586: } ! 587: } ! 588: return(0); ! 589: } ! 590: ! 591: /* TALK stuff */ ! 592: ! 593: char desttty[20] = "/dev/"; ! 594: ! 595: alert(tty) ! 596: char *tty; ! 597: { ! 598: ! 599: /* Alerts the destination tty of an incoming "talk" */ ! 600: FILE *ttyfile; ! 601: ! 602: strcat(desttty, tty); ! 603: if ((ttyfile = fopen(desttty, "w")) == NULL) { ! 604: return(0); ! 605: } ! 606: ! 607: fprintf(ttyfile, "%cTALK2 FROM %s (%s)...\n%c", ! 608: 7, getenv("LOGNAME"), getenv("LOGTTY"), 7); ! 609: fclose(ttyfile); ! 610: return(1); ! 611: } ! 612: ! 613: ! 614: talk(cp) ! 615: char *cp; ! 616: { ! 617: char infifo[100]; ! 618: char outfifo[100]; ! 619: char *ttyp; ! 620: int owind; ! 621: ! 622: ! 623: owind = nwind; ! 624: wsplit(cwind); /* two windows */ ! 625: wmode[cwind] = MVSEND; ! 626: wmode[owind] = MVSEND+MOPENW; ! 627: ! 628: /* Find other user's terminal */ ! 629: ! 630: ttyp = findtty(cp); ! 631: if (*ttyp == NULL) { ! 632: prompt1("talk: user %s not logged on.\n", cp); ! 633: return; ! 634: } ! 635: ! 636: /* Check for existence of .talk fifos */ ! 637: ! 638: sprintf(infifo, "%s/.talk", getenv("HOME")); ! 639: sprintf(wrbuf[owind], "%s/.talk", homedir(cp)); ! 640: ! 641: if (access(infifo, 04) != 0) { ! 642: prompt1("Type mknod $HOME/.talk p and try again"); ! 643: return; ! 644: } ! 645: wifrn[cwind] = open(infifo,0+O_NDELAY); ! 646: ! 647: /* alert the destination terminal */ ! 648: ! 649: if (!alert(ttyp)) { ! 650: prompt1("talk: cant alert tty: /dev/%s.\n", ttyp); ! 651: } ! 652: cwind = owind; ! 653: rx = wbase[cwind]; ! 654: ry = 0; ! 655: } ! 656: newin(cp) ! 657: ! 658: register char *cp; ! 659: { ! 660: if (cp) { ! 661: if (wifrn[cwind]) close(wifrn[cwind]); ! 662: ! 663: wifrn[cwind] = open(cp,0+O_NDELAY); ! 664: if (wifrn[cwind] < 0) prompt1("error code %d",errno); ! 665: } ! 666: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.