|
|
1.1 root 1: /*
2: * Copyright (c) 1983 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)subr.c 5.7 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: /*
25: * Melbourne getty.
26: */
27: #define USE_OLD_TTY
28: #include <sgtty.h>
29: #include "gettytab.h"
30:
31: extern struct sgttyb tmode;
32: extern struct tchars tc;
33: extern struct ltchars ltc;
34:
35: /*
36: * Get a table entry.
37: */
38: gettable(name, buf, area)
39: char *name, *buf, *area;
40: {
41: register struct gettystrs *sp;
42: register struct gettynums *np;
43: register struct gettyflags *fp;
44: register n;
45:
46: hopcount = 0; /* new lookup, start fresh */
47: if (getent(buf, name) != 1)
48: return;
49:
50: for (sp = gettystrs; sp->field; sp++)
51: sp->value = getstr(sp->field, &area);
52: for (np = gettynums; np->field; np++) {
53: n = getnum(np->field);
54: if (n == -1)
55: np->set = 0;
56: else {
57: np->set = 1;
58: np->value = n;
59: }
60: }
61: for (fp = gettyflags; fp->field; fp++) {
62: n = getflag(fp->field);
63: if (n == -1)
64: fp->set = 0;
65: else {
66: fp->set = 1;
67: fp->value = n ^ fp->invrt;
68: }
69: }
70: }
71:
72: gendefaults()
73: {
74: register struct gettystrs *sp;
75: register struct gettynums *np;
76: register struct gettyflags *fp;
77:
78: for (sp = gettystrs; sp->field; sp++)
79: if (sp->value)
80: sp->defalt = sp->value;
81: for (np = gettynums; np->field; np++)
82: if (np->set)
83: np->defalt = np->value;
84: for (fp = gettyflags; fp->field; fp++)
85: if (fp->set)
86: fp->defalt = fp->value;
87: else
88: fp->defalt = fp->invrt;
89: }
90:
91: setdefaults()
92: {
93: register struct gettystrs *sp;
94: register struct gettynums *np;
95: register struct gettyflags *fp;
96:
97: for (sp = gettystrs; sp->field; sp++)
98: if (!sp->value)
99: sp->value = sp->defalt;
100: for (np = gettynums; np->field; np++)
101: if (!np->set)
102: np->value = np->defalt;
103: for (fp = gettyflags; fp->field; fp++)
104: if (!fp->set)
105: fp->value = fp->defalt;
106: }
107:
108: static char **
109: charnames[] = {
110: &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
111: &SU, &DS, &RP, &FL, &WE, &LN, 0
112: };
113:
114: static char *
115: charvars[] = {
116: &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
117: &tc.t_quitc, &tc.t_startc, &tc.t_stopc,
118: &tc.t_eofc, &tc.t_brkc, <c.t_suspc,
119: <c.t_dsuspc, <c.t_rprntc, <c.t_flushc,
120: <c.t_werasc, <c.t_lnextc, 0
121: };
122:
123: setchars()
124: {
125: register int i;
126: register char *p;
127:
128: for (i = 0; charnames[i]; i++) {
129: p = *charnames[i];
130: if (p && *p)
131: *charvars[i] = *p;
132: else
133: *charvars[i] = '\377';
134: }
135: }
136:
137: long
138: setflags(n)
139: {
140: register long f;
141:
142: switch (n) {
143: case 0:
144: if (F0set)
145: return(F0);
146: break;
147: case 1:
148: if (F1set)
149: return(F1);
150: break;
151: default:
152: if (F2set)
153: return(F2);
154: break;
155: }
156:
157: f = 0;
158:
159: if (AP)
160: f |= ANYP;
161: else if (OP)
162: f |= ODDP;
163: else if (EP)
164: f |= EVENP;
165:
166: if (UC)
167: f |= LCASE;
168:
169: if (NL)
170: f |= CRMOD;
171:
172: f |= delaybits();
173:
174: if (n == 1) { /* read mode flags */
175: if (RW)
176: f |= RAW;
177: else
178: f |= CBREAK;
179: return (f);
180: }
181:
182: if (!HT)
183: f |= XTABS;
184:
185: if (n == 0)
186: return (f);
187:
188: if (CB)
189: f |= CRTBS;
190:
191: if (CE)
192: f |= CRTERA;
193:
194: if (CK)
195: f |= CRTKIL;
196:
197: if (PE)
198: f |= PRTERA;
199:
200: if (EC)
201: f |= ECHO;
202:
203: if (XC)
204: f |= CTLECH;
205:
206: if (DX)
207: f |= DECCTQ;
208:
209: return (f);
210: }
211:
212: struct delayval {
213: unsigned delay; /* delay in ms */
214: int bits;
215: };
216:
217: /*
218: * below are random guesses, I can't be bothered checking
219: */
220:
221: struct delayval crdelay[] = {
222: 1, CR1,
223: 2, CR2,
224: 3, CR3,
225: 83, CR1,
226: 166, CR2,
227: 0, CR3,
228: };
229:
230: struct delayval nldelay[] = {
231: 1, NL1, /* special, calculated */
232: 2, NL2,
233: 3, NL3,
234: 100, NL2,
235: 0, NL3,
236: };
237:
238: struct delayval bsdelay[] = {
239: 1, BS1,
240: 0, 0,
241: };
242:
243: struct delayval ffdelay[] = {
244: 1, FF1,
245: 1750, FF1,
246: 0, FF1,
247: };
248:
249: struct delayval tbdelay[] = {
250: 1, TAB1,
251: 2, TAB2,
252: 3, XTABS, /* this is expand tabs */
253: 100, TAB1,
254: 0, TAB2,
255: };
256:
257: delaybits()
258: {
259: register f;
260:
261: f = adelay(CD, crdelay);
262: f |= adelay(ND, nldelay);
263: f |= adelay(FD, ffdelay);
264: f |= adelay(TD, tbdelay);
265: f |= adelay(BD, bsdelay);
266: return (f);
267: }
268:
269: adelay(ms, dp)
270: register ms;
271: register struct delayval *dp;
272: {
273: if (ms == 0)
274: return (0);
275: while (dp->delay && ms > dp->delay)
276: dp++;
277: return (dp->bits);
278: }
279:
280: char editedhost[32];
281:
282: edithost(pat)
283: register char *pat;
284: {
285: register char *host = HN;
286: register char *res = editedhost;
287:
288: if (!pat)
289: pat = "";
290: while (*pat) {
291: switch (*pat) {
292:
293: case '#':
294: if (*host)
295: host++;
296: break;
297:
298: case '@':
299: if (*host)
300: *res++ = *host++;
301: break;
302:
303: default:
304: *res++ = *pat;
305: break;
306:
307: }
308: if (res == &editedhost[sizeof editedhost - 1]) {
309: *res = '\0';
310: return;
311: }
312: pat++;
313: }
314: if (*host)
315: strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
316: else
317: *res = '\0';
318: editedhost[sizeof editedhost - 1] = '\0';
319: }
320:
321: struct speedtab {
322: int speed;
323: int uxname;
324: } speedtab[] = {
325: 50, B50,
326: 75, B75,
327: 110, B110,
328: 134, B134,
329: 150, B150,
330: 200, B200,
331: 300, B300,
332: 600, B600,
333: 1200, B1200,
334: 1800, B1800,
335: 2400, B2400,
336: 4800, B4800,
337: 9600, B9600,
338: 19200, EXTA,
339: 19, EXTA, /* for people who say 19.2K */
340: 38400, EXTB,
341: 38, EXTB,
342: 7200, EXTB, /* alternative */
343: 0
344: };
345:
346: speed(val)
347: {
348: register struct speedtab *sp;
349:
350: if (val <= 15)
351: return (val);
352:
353: for (sp = speedtab; sp->speed; sp++)
354: if (sp->speed == val)
355: return (sp->uxname);
356:
357: return (B300); /* default in impossible cases */
358: }
359:
360: makeenv(env)
361: char *env[];
362: {
363: static char termbuf[128] = "TERM=";
364: register char *p, *q;
365: register char **ep;
366: char *index();
367:
368: ep = env;
369: if (TT && *TT) {
370: strcat(termbuf, TT);
371: *ep++ = termbuf;
372: }
373: if (p = EV) {
374: q = p;
375: while (q = index(q, ',')) {
376: *q++ = '\0';
377: *ep++ = p;
378: p = q;
379: }
380: if (*p)
381: *ep++ = p;
382: }
383: *ep = (char *)0;
384: }
385:
386: /*
387: * This speed select mechanism is written for the Develcon DATASWITCH.
388: * The Develcon sends a string of the form "B{speed}\n" at a predefined
389: * baud rate. This string indicates the user's actual speed.
390: * The routine below returns the terminal type mapped from derived speed.
391: */
392: struct portselect {
393: char *ps_baud;
394: char *ps_type;
395: } portspeeds[] = {
396: { "B110", "std.110" },
397: { "B134", "std.134" },
398: { "B150", "std.150" },
399: { "B300", "std.300" },
400: { "B600", "std.600" },
401: { "B1200", "std.1200" },
402: { "B2400", "std.2400" },
403: { "B4800", "std.4800" },
404: { "B9600", "std.9600" },
405: { "B19200", "std.19200" },
406: { 0 }
407: };
408:
409: char *
410: portselector()
411: {
412: char c, baud[20], *type = "default";
413: register struct portselect *ps;
414: int len;
415:
416: alarm(5*60);
417: for (len = 0; len < sizeof (baud) - 1; len++) {
418: if (read(0, &c, 1) <= 0)
419: break;
420: c &= 0177;
421: if (c == '\n' || c == '\r')
422: break;
423: if (c == 'B')
424: len = 0; /* in case of leading garbage */
425: baud[len] = c;
426: }
427: baud[len] = '\0';
428: for (ps = portspeeds; ps->ps_baud; ps++)
429: if (strcmp(ps->ps_baud, baud) == 0) {
430: type = ps->ps_type;
431: break;
432: }
433: sleep(2); /* wait for connection to complete */
434: return (type);
435: }
436:
437: /*
438: * This auto-baud speed select mechanism is written for the Micom 600
439: * portselector. Selection is done by looking at how the character '\r'
440: * is garbled at the different speeds.
441: */
442: #include <sys/time.h>
443:
444: char *
445: autobaud()
446: {
447: int rfds;
448: struct timeval timeout;
449: char c, *type = "9600-baud";
450: int null = 0;
451:
452: ioctl(0, TIOCFLUSH, &null);
453: rfds = 1 << 0;
454: timeout.tv_sec = 5;
455: timeout.tv_usec = 0;
456: if (select(32, &rfds, (int *)0, (int *)0, &timeout) <= 0)
457: return (type);
458: if (read(0, &c, sizeof(char)) != sizeof(char))
459: return (type);
460: timeout.tv_sec = 0;
461: timeout.tv_usec = 20;
462: (void) select(32, (int *)0, (int *)0, (int *)0, &timeout);
463: ioctl(0, TIOCFLUSH, &null);
464: switch (c & 0377) {
465:
466: case 0200: /* 300-baud */
467: type = "300-baud";
468: break;
469:
470: case 0346: /* 1200-baud */
471: type = "1200-baud";
472: break;
473:
474: case 015: /* 2400-baud */
475: case 0215:
476: type = "2400-baud";
477: break;
478:
479: default: /* 4800-baud */
480: type = "4800-baud";
481: break;
482:
483: case 0377: /* 9600-baud */
484: type = "9600-baud";
485: break;
486: }
487: return (type);
488: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.