xref: /csrg-svn/libexec/getty/subr.c (revision 13796)
1 #ifndef lint
2 static char sccsid[] = "@(#)subr.c	4.1 (Berkeley) 83/07/06";
3 #endif
4 
5 /*
6  * Melbourne getty.
7  */
8 #include <sgtty.h>
9 #include "gettytab.h"
10 
11 extern	struct sgttyb tmode;
12 extern	struct tchars tc;
13 extern	struct ltchars ltc;
14 
15 /*
16  * Get a table entry.
17  */
18 gettable(name, buf, area)
19 	char *name, *buf, *area;
20 {
21 	register struct gettystrs *sp;
22 	register struct gettynums *np;
23 	register struct gettyflags *fp;
24 	register n;
25 
26 	hopcount = 0;		/* new lookup, start fresh */
27 	if (getent(buf, name) != 1)
28 		return;
29 
30 	for (sp = gettystrs; sp->field; sp++)
31 		sp->value = getstr(sp->field, &area);
32 	for (np = gettynums; np->field; np++) {
33 		n = getnum(np->field);
34 		if (n == -1)
35 			np->set = 0;
36 		else {
37 			np->set = 1;
38 			np->value = n;
39 		}
40 	}
41 	for (fp = gettyflags; fp->field; fp++) {
42 		n = getflag(fp->field);
43 		if (n == -1)
44 			fp->set = 0;
45 		else {
46 			fp->set = 1;
47 			fp->value = n ^ fp->invrt;
48 		}
49 	}
50 }
51 
52 gendefaults()
53 {
54 	register struct gettystrs *sp;
55 	register struct gettynums *np;
56 	register struct gettyflags *fp;
57 
58 	for (sp = gettystrs; sp->field; sp++)
59 		if (sp->value)
60 			sp->defalt = sp->value;
61 	for (np = gettynums; np->field; np++)
62 		if (np->set)
63 			np->defalt = np->value;
64 	for (fp = gettyflags; fp->field; fp++)
65 		if (fp->set)
66 			fp->defalt = fp->value;
67 		else
68 			fp->defalt = fp->invrt;
69 }
70 
71 setdefaults()
72 {
73 	register struct gettystrs *sp;
74 	register struct gettynums *np;
75 	register struct gettyflags *fp;
76 
77 	for (sp = gettystrs; sp->field; sp++)
78 		if (!sp->value)
79 			sp->value = sp->defalt;
80 	for (np = gettynums; np->field; np++)
81 		if (!np->set)
82 			np->value = np->defalt;
83 	for (fp = gettyflags; fp->field; fp++)
84 		if (!fp->set)
85 			fp->value = fp->defalt;
86 }
87 
88 static char **
89 charnames[] = {
90 	&ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
91 	&SU, &DS, &RP, &FL, &WE, &LN, 0
92 };
93 
94 static char *
95 charvars[] = {
96 	&tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
97 	&tc.t_quitc, &tc.t_startc, &tc.t_stopc,
98 	&tc.t_eofc, &tc.t_brkc, &ltc.t_suspc,
99 	&ltc.t_dsuspc, &ltc.t_rprntc, &ltc.t_flushc,
100 	&ltc.t_werasc, &ltc.t_lnextc, 0
101 };
102 
103 setchars()
104 {
105 	register int i;
106 	register char *p;
107 
108 	for (i = 0; charnames[i]; i++) {
109 		p = *charnames[i];
110 		if (p && *p)
111 			*charvars[i] = *p;
112 		else
113 			*charvars[i] = '\0377';
114 	}
115 }
116 
117 long
118 setflags(n)
119 {
120 	register long f;
121 
122 	switch (n) {
123 	case 0:
124 		if (F0set)
125 			return(F0);
126 		break;
127 	case 1:
128 		if (F1set)
129 			return(F1);
130 		break;
131 	default:
132 		if (F2set)
133 			return(F2);
134 		break;
135 	}
136 
137 	f = 0;
138 
139 	if (AP)
140 		f |= ANYP;
141 	else if (OP)
142 		f |= ODDP;
143 	else if (EP)
144 		f |= EVENP;
145 
146 	if (UC)
147 		f |= LCASE;
148 
149 	if (NL)
150 		f |= CRMOD;
151 
152 	f |= delaybits();
153 
154 	if (n == 1) {		/* read mode flags */
155 		if (RW)
156 			f |= RAW;
157 		else
158 			f |= CBREAK;
159 		return (f);
160 	}
161 
162 	if (!HT)
163 		f |= XTABS;
164 
165 	if (n == 0)
166 		return (f);
167 
168 	if (CB)
169 		f |= CRTBS;
170 
171 	if (CE)
172 		f |= CRTERA;
173 
174 	if (PE)
175 		f |= PRTERA;
176 
177 	if (EC)
178 		f |= ECHO;
179 
180 	if (XC)
181 		f |= CTLECH;
182 
183 	return (f);
184 }
185 
186 struct delayval {
187 	unsigned	delay;		/* delay in ms */
188 	int		bits;
189 };
190 
191 /*
192  * below are random guesses, I can't be bothered checking
193  */
194 
195 struct delayval	crdelay[] = {
196 	20,		CR1,
197 	30,		CR2,
198 	40,		CR3,
199 	0,		CR3,
200 };
201 
202 struct delayval nldelay[] = {
203 	1,		NL1,		/* special, calculated */
204 	16,		NL2,
205 	30,		NL3,
206 	0,		NL3,
207 };
208 
209 struct delayval	bsdelay[] = {
210 	0,		0,
211 };
212 
213 struct delayval	ffdelay[] = {
214 	1750,		FF1,
215 	0,		FF1,
216 };
217 
218 struct delayval	tbdelay[] = {
219 	10,		TAB1,
220 	20,		TAB2,
221 	0,		TAB2,
222 };
223 
224 delaybits()
225 {
226 	register f;
227 
228 	f  = adelay(CD, crdelay);
229 	f |= adelay(ND, nldelay);
230 	f |= adelay(FD, ffdelay);
231 	f |= adelay(TD, tbdelay);
232 	f |= adelay(BD, bsdelay);
233 	return (f);
234 }
235 
236 adelay(ms, dp)
237 	register ms;
238 	register struct delayval *dp;
239 {
240 	if (ms == 0)
241 		return (0);
242 	while (dp->delay && ms > dp->delay)
243 		dp++;
244 	return (dp->bits);
245 }
246 
247 char	editedhost[32];
248 
249 edithost(pat)
250 	register char *pat;
251 {
252 	register char *host = HN;
253 	register char *res = editedhost;
254 
255 	if (!pat)
256 		pat = "";
257 	while (*pat) {
258 		switch (*pat) {
259 
260 		case '#':
261 			if (*host)
262 				host++;
263 			break;
264 
265 		case '@':
266 			if (*host)
267 				*res++ = *host++;
268 			break;
269 
270 		default:
271 			*res++ = *pat;
272 			break;
273 
274 		}
275 		if (res == &editedhost[sizeof editedhost - 1]) {
276 			*res = '\0';
277 			return;
278 		}
279 		pat++;
280 	}
281 	if (*host)
282 		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
283 	else
284 		*res = '\0';
285 	editedhost[sizeof editedhost - 1] = '\0';
286 }
287 
288 struct speedtab {
289 	int	speed;
290 	int	uxname;
291 } speedtab[] = {
292 	50,	B50,
293 	75,	B75,
294 	110,	B110,
295 	134,	B134,
296 	150,	B150,
297 	200,	B200,
298 	300,	B300,
299 	600,	B600,
300 	1200,	B1200,
301 	1800,	B1800,
302 	2400,	B2400,
303 	4800,	B4800,
304 	9600,	B9600,
305 	19200,	EXTA,
306 	19,	EXTA,		/* for people who say 19.2K */
307 	38400,	EXTB,
308 	38,	EXTB,
309 	7200,	EXTB,		/* alternative */
310 	0
311 };
312 
313 speed(val)
314 {
315 	register struct speedtab *sp;
316 
317 	if (val <= 15)
318 		return(val);
319 
320 	for (sp = speedtab; sp->speed; sp++)
321 		if (sp->speed == val)
322 			return (sp->uxname);
323 
324 	return (B300);		/* default in impossible cases */
325 }
326 
327 makeenv(env)
328 	char *env[];
329 {
330 	static char termbuf[128] = "TERM=";
331 	register char *p, *q;
332 	register char **ep;
333 	char *index();
334 
335 	ep = env;
336 	if (TT && *TT) {
337 		strcat(termbuf, TT);
338 		*ep++ = termbuf;
339 	}
340 	if (p = EV) {
341 		q = p;
342 		while (q = index(q, ',')) {
343 			*q++ = '\0';
344 			*ep++ = p;
345 			p = q;
346 		}
347 		if (*p)
348 			*ep++ = p;
349 	}
350 	*ep = (char *)0;
351 }
352 
353 /*
354  * This speed select mechanism is written for the Develcon DATASWITCH.
355  * The Develcon sends a string of the form "B{speed}\n" at a predefined
356  * baud rate. This string indicates the user's actual speed.
357  * The routine below returns the terminal type mapped from derived speed.
358  */
359 struct	portselect {
360 	char	*ps_baud;
361 	char	*ps_type;
362 } portspeeds[] = {
363 	{ "B110",	"std.110" },
364 	{ "B134",	"std.134" },
365 	{ "B150",	"std.150" },
366 	{ "B300",	"std.300" },
367 	{ "B600",	"std.600" },
368 	{ "B1200",	"std.1200" },
369 	{ "B2400",	"std.2400" },
370 	{ "B4800",	"std.4800" },
371 	{ "B9600",	"std.9600" },
372 	{ 0 }
373 };
374 
375 char *
376 portselector()
377 {
378 	char c, baud[20], *type = "default";
379 	register struct portselect *ps;
380 	int len;
381 
382 	alarm(5*60);
383 	for (len = 0; len < sizeof (baud) - 1; len++) {
384 		if (read(0, &c, 1) <= 0)
385 			break;
386 		c &= 0177;
387 		if (c == '\n' || c == '\r')
388 			break;
389 		if (c == 'B')
390 			len = 0;	/* in case of leading garbage */
391 		baud[len] = c;
392 	}
393 	baud[len] = '\0';
394 	for (ps = portspeeds; ps->ps_baud; ps++)
395 		if (strcmp(ps->ps_baud, baud) == 0) {
396 			type = ps->ps_type;
397 			break;
398 		}
399 	sleep(2);	/* wait for connection to complete */
400 	return (type);
401 }
402