|
|
1.1 root 1: /*
2: * 450 (for DASI 450/DIABLO 1620 terminals)
3: * includes handling of REV L to still work with forms tractors
4: * -f option handles fast (1200 baud) output with ETX/ACK protocol
5: * -f option errors
6: * 1: standard output is not a terminal
7: 2: error when opened output terminal for read
8: * 3: output terminal did not respond to ETX
9: * 4: output terminal did not respond with ACK
10: */
11:
12: char x450vers[] = "@(#)450.c 1.11";
13:
14: #include <stdio.h>
15: #include <signal.h>
16: #include <sys/types.h>
17: #include <sys/stat.h>
18: #include <sgtty.h>
19:
20: /* input sequences (TTY37 style) */
21: #define ESC 033 /* escape */
22: #define HFWD '9'
23: #define HREV '8'
24: #define FREV '7'
25: #define SO 016 /* shift out - enter greek */
26: #define SI 017 /* shift in */
27:
28: /* output specials (450/1620 style) */
29: #define PLOT 006 /* ack, on/off plot mode */
30: #define BEL 007 /* exit plot mode */
31: #define U 013
32: #define D 012
33: #define R ' '
34: #define L '\b'
35: #define LF '\n'
36: #define CR 015
37: #define ETX 003 /* -f query */
38: #define ACK 006 /* -f response */
39:
40: int charcnt = 0; /* -f count of characters output */
41: int problem(); /* -f alarm procedure */
42: short foption = 0; /* -f flag */
43:
44: int nlcnt, /* accumulated newline count */
45: frevcnt; /* accumulated reverse line-feeds */
46: char *ttydev; /* will pt to /dev/tty?? */
47: int svstmode; /* for mesg restore */
48: int restore();
49: struct sgttyb svsgb;
50: struct sgttyb sgb;
51:
52:
53: main(argc, argv)
54: char **argv;
55: int argc;
56: {
57: register c;
58:
59: if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'f') foption = 1;
60: if (((int)signal(SIGINT, SIG_IGN) & 01) == 0)
61: signal(SIGINT, restore);
62: if (gtty(1, &sgb) == 0)
63: fixtty();
64: setbuf(stdin, calloc(BUFSIZ,1));
65: if (foption) { signal(SIGALRM,problem); putchar(ETX); }
66: while ((c = getchar()) != EOF) {
67: if (c == '\n') {
68: if (frevcnt)
69: flushrv();
70: nlcnt++;
71: continue;
72: }
73: else if (nlcnt)
74: flushnl();
75: else if (frevcnt && c != ESC)
76: flushrv();
77: if(c == SO) {
78: special();
79: continue;
80: }
81: if( c != ESC ) {
82: output(c);
83: continue;
84: }
85: c = getchar();
86: if (frevcnt && c != FREV) {
87: flushrv();
88: }
89: if (c == HREV || c == HFWD)
90: pout(c);
91: else if (c == FREV)
92: frevcnt++;
93: }
94: flusher();
95: if (foption) { getack(); putchar(ETX); getack(); }
96: restore(0);
97: }
98:
99: /* fixtty: get tty status and save; remove CR-LF mapping */
100: fixtty()
101: {
102: struct stat sb;
103: extern char *ttyname();
104:
105: svsgb = sgb;
106: if (foption) {
107: if (isatty(1)) {
108: ttydev = ttyname(1);
109: close(1);
110: if (open(ttydev,2) != 1) restore(2);
111: } else restore(1);
112: sgb.sg_ispeed = sgb.sg_ospeed = B1200;
113: stty(1,&sgb);
114: }
115: sgb.sg_flags &= ~CRMOD;
116: stty(1, &sgb); /* stty nl */
117: fstat(1, &sb);
118: svstmode = sb.st_mode;
119: ttydev = ttyname(1);
120: chmod(ttydev, 0600); /* mesg n */
121: }
122:
123: /* flusher: flush accumulated newlines, reverse line feeds, buffer */
124: flusher()
125: {
126: if (nlcnt)
127: flushnl();
128: if (frevcnt)
129: flushrv();
130: }
131:
132: /* flushrv: flush accumulated reverse line feeds */
133: /* note: expects to be out of plot mode on entry */
134: char frvadj[] = {U,U,U,LF,LF,LF,0}; /* forms tractor fixup */
135: flushrv()
136: {
137: while (frevcnt--) {
138: putx(U);
139: nplot(5,'\0'); /* slow down somewhat */
140: }
141: putstr(frvadj);
142: frevcnt = 0;
143: }
144:
145: /* flushnl: flush accumulated newlines (count in nlcnt) */
146: flushnl()
147: {
148: putx(CR); /* must have 1 CR; only 1 needed */
149: while (nlcnt--)
150: putx(LF); /* no plot mode needed for these */
151: nlcnt = 0;
152: }
153:
154: putstr(p)
155: register char *p;
156: {
157: while (*p)
158: putx(*p++);
159: }
160:
161: restore(e)
162: short e;
163: {
164: output(ESC); output('4');
165: if (isatty(1)) {
166: sgb = svsgb;
167: stty(1, &sgb);
168: chmod(ttydev,svstmode);
169: }
170: exit(e);
171: }
172:
173: char alpha[] = {L,'c',R,R,'(',L,0};
174: char beta[] = {'B',L,L,D,D,'|',R,R,U,U,0};
175: char delta[] = {'o',U,U,'<',D,D,0};
176: char DELTA[] = {L,L,'/',0203,D,'-',0204,R,'-',0203,U,'\\',L,L,0};
177: char epsilon[] = {'<','-',0};
178: char eta[] = {'n',R,R,D,D,'|',L,L,U,U,0};
179: char gamma[] = {')',R,'/',L,0};
180: char GAMMA[] = {L,L,'|',R,R,0203,U,'-',0203,D,R,R,'`',L,L,0};
181: char infinity[] = {L,L,'c',0204,R,'o',L,L,0};
182: char integral[] = {'|','\'',R,R,'`',0203,L,0206,D,'\'',L,'`',R,R,0206,U,0};
183: char lambda[] = {'\\',0204,D,L,'\'',D,L,'\'',0205,U,R,R,0};
184: char LAMBDA[] = {L,L,'/',0204,R,'\\',L,L,0};
185: char mu[] = {'u',L,L,',',R,R,0};
186: char nabla[] = {L,L,'\\',0203,U,'-',0204,R,'-',0203,D,'/',L,L,0};
187: char not[] = {'-',0202,R,U,',',D,0202,L,0};
188: char nu[] = {L,'(',0203,R,'/',L,L,0};
189: char omega[] = {L,'u',0203,R,'u',L,L,0};
190: char OMEGA[] = {'O',D,D,L,'-',R,R,'-',L,U,U,0};
191: char partial[] = {'o',R,D,'`',L,U,'`',L,U,'`',R,D,0};
192: char phi[] = {'o','/',0};
193: char PHI[] = {'o','[',']',0};
194: char psi[] = {'/','-',D,D,R,R,'\'',0204,L,'\'',R,R,U,U,0};
195: char PSI[] = {'[',']','-',D,D,R,R,'\'',0204,L,'`',R,R,U,U,0};
196: char pi[] = {U,'-',0203,D,'"',D,'"',0203,U,0};
197: char PI[] = {L,L,'[',']',0204,R,'[',']',L,L,0203,U,'-',0203,D,0};
198: char rho[] = {'o',L,L,D,D,'|',U,U,R,R,0};
199: char sigma[] = {'o',D,R,R,'~',U,L,L,0};
200: char SIGMA[] = {'>',0202,D,'-',0205,U,'-',D,D,0};
201: char tau[] = {'t',D,R,R,'~',L,L,L,'~',R,U,0};
202: char theta[] = {'O','-',0};
203: char THETA[] = {'O','=',0};
204: char xi[] = {'c',R,D,',',L,0203,U,'c',L,D,'`',R,D,0};
205: char zeta[] = {'c',R,D,',',L,0203,U,'<',D,D,0};
206:
207: char tab[]= {
208: 'A', /* alpha */
209: 'B', /* beta */
210: 'D', /* delta */
211: 'W', /* DELTA */
212: 'S', /* epsilon */
213: 'N', /* eta */
214: '\\', /* gamma */
215: 'G', /* GAMMA */
216: 'o', /* infinity - not in M37 */
217: '^', /* integral */
218: 'L', /* lambda */
219: 'E', /* LAMBDA */
220: 'M', /* mu */
221: '[', /* nabla (del) */
222: '_', /* not */
223: '@', /* nu */
224: 'C', /* omega */
225: 'Z', /* OMEGA */
226: ']', /* partial */
227: 'U', /* phi */
228: 'F', /* PHI */
229: 'V', /* psi */
230: 'H', /* PSI */
231: 'J', /* pi */
232: 'P', /* PI */
233: 'K', /* rho */
234: 'Y', /* sigma */
235: 'R', /* SIGMA */
236: 'I', /* tau */
237: 'T', /* theta */
238: 'O', /* THETA */
239: 'X', /* xi */
240: 'Q', /* zeta */
241: 0
242: };
243: char *trans[]= {
244: alpha,
245: beta,
246: delta,
247: DELTA,
248: epsilon,
249: eta,
250: gamma,
251: GAMMA,
252: infinity,
253: integral,
254: lambda,
255: LAMBDA,
256: mu,
257: nabla,
258: not,
259: nu,
260: omega,
261: OMEGA,
262: partial,
263: phi,
264: PHI,
265: psi,
266: PSI,
267: pi,
268: PI,
269: rho,
270: sigma,
271: SIGMA,
272: tau,
273: theta,
274: THETA,
275: xi,
276: zeta,
277: 0
278: };
279:
280: special()
281: {
282: register c, i;
283: loop:
284: if ((c = getchar()) == SI || c < 0)
285: return;
286: for (i = 0; tab[i] != 0; i++)
287: if (c == tab[i]) {
288: plot(trans[i]);
289: goto loop;
290: }
291: putx(c);
292: goto loop;
293: }
294:
295: plot(s)
296: register char *s;
297: {
298: register i,c;
299:
300: pout(PLOT);
301: for (i = 0; (c = s[i]) != 0; i++) {
302: if( c & 0200 )
303: nplot(c&0177,s[++i]);
304: else
305: putx(c);
306: }
307: pout(BEL);
308: putx(' ');
309: }
310:
311: nplot(n, c)
312: register n, c;
313: {
314: while(n--)
315: putx(c);
316: }
317:
318: /* pout: put out appropriate sequence for motions */
319: char hrvadj[] = {ESC,'D', ESC,'U',0};
320: pout(type)
321: int type;
322: {
323: putx(ESC);
324: switch(type) {
325: case HFWD:
326: putx('U'); break;
327: case HREV:
328: putx('D');
329: putstr(hrvadj); /* up & down for forms tractor */
330: break;
331: case PLOT:
332: putx('3'); break; /* into plot mode */
333: case BEL: /* out of plot mode */
334: putx('4'); break;
335: }
336: }
337:
338: /* putx: add character to output; convert U to ESC LF */
339: putx(c)
340: register c;
341: {
342: if (c == U) {
343: output(ESC);
344: output(LF);
345: } else {
346: output(c);
347: }
348: }
349:
350: /* output: all actual output done here */
351:
352: output(c)
353: register c;
354: {
355: putchar(c);
356: if (foption) {
357: charcnt++;
358: if (charcnt > 78 && c != ESC ) {
359: charcnt = 1;
360: putchar(ETX);
361: getack();
362: }
363: }
364: }
365: /* problem: to catch foption read alarm */
366: problem()
367: {
368: restore(3);
369: }
370:
371: getack()
372: {
373: char dummy;
374: alarm(10);
375: read(1,&dummy,1);
376: alarm(0);
377: if (dummy != ACK) restore(4);
378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.