xref: /csrg-svn/libexec/getty/subr.c (revision 13827)
1 #ifndef lint
2 static char sccsid[] = "@(#)subr.c	4.2 (Berkeley) 83/07/07";
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 	1,		CR1,
197 	2,		CR2,
198 	3,		CR3,
199 	83,		CR1,
200 	166,		CR2,
201 	0,		CR3,
202 };
203 
204 struct delayval nldelay[] = {
205 	1,		NL1,		/* special, calculated */
206 	2,		NL2,
207 	3,		NL3,
208 	100,		NL2,
209 	0,		NL3,
210 };
211 
212 struct delayval	bsdelay[] = {
213 	1,		BS1,
214 	0,		0,
215 };
216 
217 struct delayval	ffdelay[] = {
218 	1,		FF1,
219 	1750,		FF1,
220 	0,		FF1,
221 };
222 
223 struct delayval	tbdelay[] = {
224 	1,		TAB1,
225 	2,		TAB2,
226 	3,		XTABS,		/* this is expand tabs */
227 	100,		TAB1,
228 	0,		TAB2,
229 };
230 
231 delaybits()
232 {
233 	register f;
234 
235 	f  = adelay(CD, crdelay);
236 	f |= adelay(ND, nldelay);
237 	f |= adelay(FD, ffdelay);
238 	f |= adelay(TD, tbdelay);
239 	f |= adelay(BD, bsdelay);
240 	return (f);
241 }
242 
243 adelay(ms, dp)
244 	register ms;
245 	register struct delayval *dp;
246 {
247 	if (ms == 0)
248 		return (0);
249 	while (dp->delay && ms > dp->delay)
250 		dp++;
251 	return (dp->bits);
252 }
253 
254 char	editedhost[32];
255 
256 edithost(pat)
257 	register char *pat;
258 {
259 	register char *host = HN;
260 	register char *res = editedhost;
261 
262 	if (!pat)
263 		pat = "";
264 	while (*pat) {
265 		switch (*pat) {
266 
267 		case '#':
268 			if (*host)
269 				host++;
270 			break;
271 
272 		case '@':
273 			if (*host)
274 				*res++ = *host++;
275 			break;
276 
277 		default:
278 			*res++ = *pat;
279 			break;
280 
281 		}
282 		if (res == &editedhost[sizeof editedhost - 1]) {
283 			*res = '\0';
284 			return;
285 		}
286 		pat++;
287 	}
288 	if (*host)
289 		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
290 	else
291 		*res = '\0';
292 	editedhost[sizeof editedhost - 1] = '\0';
293 }
294 
295 struct speedtab {
296 	int	speed;
297 	int	uxname;
298 } speedtab[] = {
299 	50,	B50,
300 	75,	B75,
301 	110,	B110,
302 	134,	B134,
303 	150,	B150,
304 	200,	B200,
305 	300,	B300,
306 	600,	B600,
307 	1200,	B1200,
308 	1800,	B1800,
309 	2400,	B2400,
310 	4800,	B4800,
311 	9600,	B9600,
312 	19200,	EXTA,
313 	19,	EXTA,		/* for people who say 19.2K */
314 	38400,	EXTB,
315 	38,	EXTB,
316 	7200,	EXTB,		/* alternative */
317 	0
318 };
319 
320 speed(val)
321 {
322 	register struct speedtab *sp;
323 
324 	if (val <= 15)
325 		return(val);
326 
327 	for (sp = speedtab; sp->speed; sp++)
328 		if (sp->speed == val)
329 			return (sp->uxname);
330 
331 	return (B300);		/* default in impossible cases */
332 }
333 
334 makeenv(env)
335 	char *env[];
336 {
337 	static char termbuf[128] = "TERM=";
338 	register char *p, *q;
339 	register char **ep;
340 	char *index();
341 
342 	ep = env;
343 	if (TT && *TT) {
344 		strcat(termbuf, TT);
345 		*ep++ = termbuf;
346 	}
347 	if (p = EV) {
348 		q = p;
349 		while (q = index(q, ',')) {
350 			*q++ = '\0';
351 			*ep++ = p;
352 			p = q;
353 		}
354 		if (*p)
355 			*ep++ = p;
356 	}
357 	*ep = (char *)0;
358 }
359 
360 /*
361  * This speed select mechanism is written for the Develcon DATASWITCH.
362  * The Develcon sends a string of the form "B{speed}\n" at a predefined
363  * baud rate. This string indicates the user's actual speed.
364  * The routine below returns the terminal type mapped from derived speed.
365  */
366 struct	portselect {
367 	char	*ps_baud;
368 	char	*ps_type;
369 } portspeeds[] = {
370 	{ "B110",	"std.110" },
371 	{ "B134",	"std.134" },
372 	{ "B150",	"std.150" },
373 	{ "B300",	"std.300" },
374 	{ "B600",	"std.600" },
375 	{ "B1200",	"std.1200" },
376 	{ "B2400",	"std.2400" },
377 	{ "B4800",	"std.4800" },
378 	{ "B9600",	"std.9600" },
379 	{ 0 }
380 };
381 
382 char *
383 portselector()
384 {
385 	char c, baud[20], *type = "default";
386 	register struct portselect *ps;
387 	int len;
388 
389 	alarm(5*60);
390 	for (len = 0; len < sizeof (baud) - 1; len++) {
391 		if (read(0, &c, 1) <= 0)
392 			break;
393 		c &= 0177;
394 		if (c == '\n' || c == '\r')
395 			break;
396 		if (c == 'B')
397 			len = 0;	/* in case of leading garbage */
398 		baud[len] = c;
399 	}
400 	baud[len] = '\0';
401 	for (ps = portspeeds; ps->ps_baud; ps++)
402 		if (strcmp(ps->ps_baud, baud) == 0) {
403 			type = ps->ps_type;
404 			break;
405 		}
406 	sleep(2);	/* wait for connection to complete */
407 	return (type);
408 }
409