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