xref: /freebsd/libexec/getty/subr.c (revision 95289b278a615ee45551c70f0ac343c7a8243f33)
1ea022d16SRodney W. Grimes /*
2cae66988SJoerg Wunsch  * Copyright (c) 1983, 1993
3cae66988SJoerg Wunsch  *	The Regents of the University of California.  All rights reserved.
4ea022d16SRodney W. Grimes  *
5ea022d16SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
6ea022d16SRodney W. Grimes  * modification, are permitted provided that the following conditions
7ea022d16SRodney W. Grimes  * are met:
8ea022d16SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
9ea022d16SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
10ea022d16SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
11ea022d16SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
12ea022d16SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
13ea022d16SRodney W. Grimes  * 3. All advertising materials mentioning features or use of this software
14ea022d16SRodney W. Grimes  *    must display the following acknowledgement:
15ea022d16SRodney W. Grimes  *	This product includes software developed by the University of
16ea022d16SRodney W. Grimes  *	California, Berkeley and its contributors.
17ea022d16SRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
18ea022d16SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
19ea022d16SRodney W. Grimes  *    without specific prior written permission.
20ea022d16SRodney W. Grimes  *
21ea022d16SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22ea022d16SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23ea022d16SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24ea022d16SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25ea022d16SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26ea022d16SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27ea022d16SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28ea022d16SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29ea022d16SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30ea022d16SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31ea022d16SRodney W. Grimes  * SUCH DAMAGE.
32ea022d16SRodney W. Grimes  */
33ea022d16SRodney W. Grimes 
34ea022d16SRodney W. Grimes #ifndef lint
35d748864dSPhilippe Charnier #if 0
36d748864dSPhilippe Charnier static char sccsid[] = "@(#)from: subr.c	8.1 (Berkeley) 6/4/93";
37d748864dSPhilippe Charnier #endif
38d748864dSPhilippe Charnier static const char rcsid[] =
397f3dea24SPeter Wemm   "$FreeBSD$";
40ea022d16SRodney W. Grimes #endif /* not lint */
41ea022d16SRodney W. Grimes 
42ea022d16SRodney W. Grimes /*
43ea022d16SRodney W. Grimes  * Melbourne getty.
44ea022d16SRodney W. Grimes  */
45cae66988SJoerg Wunsch #define COMPAT_43
46cae66988SJoerg Wunsch #ifdef DEBUG
47cae66988SJoerg Wunsch #include <stdio.h>
48cae66988SJoerg Wunsch #endif
49d748864dSPhilippe Charnier #include <stdlib.h>
50d748864dSPhilippe Charnier #include <string.h>
51d748864dSPhilippe Charnier #include <termios.h>
52d748864dSPhilippe Charnier #include <unistd.h>
53d748864dSPhilippe Charnier #include <sys/ioctl.h>
54d748864dSPhilippe Charnier #include <sys/param.h>
55d748864dSPhilippe Charnier #include <sys/time.h>
56d748864dSPhilippe Charnier #include <syslog.h>
57ea022d16SRodney W. Grimes 
58cae66988SJoerg Wunsch #include "gettytab.h"
59cae66988SJoerg Wunsch #include "pathnames.h"
60cae66988SJoerg Wunsch #include "extern.h"
61cae66988SJoerg Wunsch 
62cae66988SJoerg Wunsch 
63cae66988SJoerg Wunsch #ifdef COMPAT_43
6495289b27SWarner Losh static void	compatflags(long);
65cae66988SJoerg Wunsch #endif
66ea022d16SRodney W. Grimes 
67ea022d16SRodney W. Grimes /*
68ea022d16SRodney W. Grimes  * Get a table entry.
69ea022d16SRodney W. Grimes  */
70cae66988SJoerg Wunsch void
7195289b27SWarner Losh gettable(const char *name, char *buf)
72ea022d16SRodney W. Grimes {
7395289b27SWarner Losh 	struct gettystrs *sp;
7495289b27SWarner Losh 	struct gettynums *np;
7595289b27SWarner Losh 	struct gettyflags *fp;
76cae66988SJoerg Wunsch 	long n;
7704a59e67SDavid Nugent 	int l;
7804a59e67SDavid Nugent 	char *p;
7904a59e67SDavid Nugent 	char *msg = NULL;
80cae66988SJoerg Wunsch 	const char *dba[2];
8104a59e67SDavid Nugent 
8204a59e67SDavid Nugent 	static int firsttime = 1;
8304a59e67SDavid Nugent 
84cae66988SJoerg Wunsch 	dba[0] = _PATH_GETTYTAB;
85cae66988SJoerg Wunsch 	dba[1] = 0;
86ea022d16SRodney W. Grimes 
8704a59e67SDavid Nugent 	if (firsttime) {
8804a59e67SDavid Nugent 		/*
8904a59e67SDavid Nugent 		 * we need to strdup() anything in the strings array
9004a59e67SDavid Nugent 		 * initially in order to simplify things later
9104a59e67SDavid Nugent 		 */
92ea022d16SRodney W. Grimes 		for (sp = gettystrs; sp->field; sp++)
9304a59e67SDavid Nugent 			if (sp->value != NULL) {
9404a59e67SDavid Nugent 				/* handle these ones more carefully */
9504a59e67SDavid Nugent 				if (sp >= &gettystrs[4] && sp <= &gettystrs[6])
9604a59e67SDavid Nugent 					l = 2;
9704a59e67SDavid Nugent 				else
9804a59e67SDavid Nugent 					l = strlen(sp->value) + 1;
9904a59e67SDavid Nugent 				if ((p = malloc(l)) != NULL) {
10004a59e67SDavid Nugent 					strncpy(p, sp->value, l);
10104a59e67SDavid Nugent 					p[l-1] = '\0';
10204a59e67SDavid Nugent 				}
10304a59e67SDavid Nugent 				/*
10404a59e67SDavid Nugent 				 * replace, even if NULL, else we'll
10504a59e67SDavid Nugent 				 * have problems with free()ing static mem
10604a59e67SDavid Nugent 				 */
10704a59e67SDavid Nugent 				sp->value = p;
10804a59e67SDavid Nugent 			}
10904a59e67SDavid Nugent 		firsttime = 0;
11004a59e67SDavid Nugent 	}
11104a59e67SDavid Nugent 
11204a59e67SDavid Nugent 	switch (cgetent(&buf, (char **)dba, (char *)name)) {
11304a59e67SDavid Nugent 	case 1:
11404a59e67SDavid Nugent 		msg = "%s: couldn't resolve 'tc=' in gettytab '%s'";
11504a59e67SDavid Nugent 	case 0:
11604a59e67SDavid Nugent 		break;
11704a59e67SDavid Nugent 	case -1:
11804a59e67SDavid Nugent 		msg = "%s: unknown gettytab entry '%s'";
11904a59e67SDavid Nugent 		break;
12004a59e67SDavid Nugent 	case -2:
12104a59e67SDavid Nugent 		msg = "%s: retrieving gettytab entry '%s': %m";
12204a59e67SDavid Nugent 		break;
12304a59e67SDavid Nugent 	case -3:
12404a59e67SDavid Nugent 		msg = "%s: recursive 'tc=' reference gettytab entry '%s'";
12504a59e67SDavid Nugent 		break;
12604a59e67SDavid Nugent 	default:
12704a59e67SDavid Nugent 		msg = "%s: unexpected cgetent() error for entry '%s'";
12804a59e67SDavid Nugent 		break;
12904a59e67SDavid Nugent 	}
13004a59e67SDavid Nugent 
13104a59e67SDavid Nugent 	if (msg != NULL) {
13204a59e67SDavid Nugent 		syslog(LOG_ERR, msg, "getty", name);
13304a59e67SDavid Nugent 		return;
13404a59e67SDavid Nugent 	}
13504a59e67SDavid Nugent 
13604a59e67SDavid Nugent 	for (sp = gettystrs; sp->field; sp++) {
1371cc15828SDavid Nugent 		if ((l = cgetstr(buf, (char*)sp->field, &p)) >= 0) {
13804a59e67SDavid Nugent 			if (sp->value) {
13904a59e67SDavid Nugent 				/* prefer existing value */
14004a59e67SDavid Nugent 				if (strcmp(p, sp->value) != 0)
14104a59e67SDavid Nugent 					free(sp->value);
14204a59e67SDavid Nugent 				else {
14304a59e67SDavid Nugent 					free(p);
14404a59e67SDavid Nugent 					p = sp->value;
14504a59e67SDavid Nugent 				}
14604a59e67SDavid Nugent 			}
14704a59e67SDavid Nugent 			sp->value = p;
14804a59e67SDavid Nugent 		} else if (l == -1) {
14904a59e67SDavid Nugent 			free(sp->value);
15004a59e67SDavid Nugent 			sp->value = NULL;
15104a59e67SDavid Nugent 		}
15204a59e67SDavid Nugent 	}
15304a59e67SDavid Nugent 
154ea022d16SRodney W. Grimes 	for (np = gettynums; np->field; np++) {
15504a59e67SDavid Nugent 		if (cgetnum(buf, (char*)np->field, &n) == -1)
156ea022d16SRodney W. Grimes 			np->set = 0;
157ea022d16SRodney W. Grimes 		else {
158ea022d16SRodney W. Grimes 			np->set = 1;
159ea022d16SRodney W. Grimes 			np->value = n;
160ea022d16SRodney W. Grimes 		}
161ea022d16SRodney W. Grimes 	}
16204a59e67SDavid Nugent 
163ea022d16SRodney W. Grimes 	for (fp = gettyflags; fp->field; fp++) {
16404a59e67SDavid Nugent 		if (cgetcap(buf, (char *)fp->field, ':') == NULL)
165ea022d16SRodney W. Grimes 			fp->set = 0;
166ea022d16SRodney W. Grimes 		else {
167ea022d16SRodney W. Grimes 			fp->set = 1;
168cae66988SJoerg Wunsch 			fp->value = 1 ^ fp->invrt;
169ea022d16SRodney W. Grimes 		}
170ea022d16SRodney W. Grimes 	}
17104a59e67SDavid Nugent 
172cae66988SJoerg Wunsch #ifdef DEBUG
173cae66988SJoerg Wunsch 	printf("name=\"%s\", buf=\"%s\"\r\n", name, buf);
174cae66988SJoerg Wunsch 	for (sp = gettystrs; sp->field; sp++)
1751cc15828SDavid Nugent 		printf("cgetstr: %s=%s\r\n", sp->field, sp->value);
176cae66988SJoerg Wunsch 	for (np = gettynums; np->field; np++)
177cae66988SJoerg Wunsch 		printf("cgetnum: %s=%d\r\n", np->field, np->value);
178cae66988SJoerg Wunsch 	for (fp = gettyflags; fp->field; fp++)
179cae66988SJoerg Wunsch 		printf("cgetflags: %s='%c' set='%c'\r\n", fp->field,
180cae66988SJoerg Wunsch 		       fp->value + '0', fp->set + '0');
181cae66988SJoerg Wunsch #endif /* DEBUG */
182ea022d16SRodney W. Grimes }
183ea022d16SRodney W. Grimes 
184cae66988SJoerg Wunsch void
18595289b27SWarner Losh gendefaults(void)
186ea022d16SRodney W. Grimes {
18795289b27SWarner Losh 	struct gettystrs *sp;
18895289b27SWarner Losh 	struct gettynums *np;
18995289b27SWarner Losh 	struct gettyflags *fp;
190ea022d16SRodney W. Grimes 
191ea022d16SRodney W. Grimes 	for (sp = gettystrs; sp->field; sp++)
192ea022d16SRodney W. Grimes 		if (sp->value)
19304a59e67SDavid Nugent 			sp->defalt = strdup(sp->value);
194ea022d16SRodney W. Grimes 	for (np = gettynums; np->field; np++)
195ea022d16SRodney W. Grimes 		if (np->set)
196ea022d16SRodney W. Grimes 			np->defalt = np->value;
197ea022d16SRodney W. Grimes 	for (fp = gettyflags; fp->field; fp++)
198ea022d16SRodney W. Grimes 		if (fp->set)
199ea022d16SRodney W. Grimes 			fp->defalt = fp->value;
200ea022d16SRodney W. Grimes 		else
201ea022d16SRodney W. Grimes 			fp->defalt = fp->invrt;
202ea022d16SRodney W. Grimes }
203ea022d16SRodney W. Grimes 
204cae66988SJoerg Wunsch void
20595289b27SWarner Losh setdefaults(void)
206ea022d16SRodney W. Grimes {
20795289b27SWarner Losh 	struct gettystrs *sp;
20895289b27SWarner Losh 	struct gettynums *np;
20995289b27SWarner Losh 	struct gettyflags *fp;
210ea022d16SRodney W. Grimes 
211ea022d16SRodney W. Grimes 	for (sp = gettystrs; sp->field; sp++)
212ea022d16SRodney W. Grimes 		if (!sp->value)
21304a59e67SDavid Nugent 			sp->value = !sp->defalt ? sp->defalt
21404a59e67SDavid Nugent 						: strdup(sp->defalt);
215ea022d16SRodney W. Grimes 	for (np = gettynums; np->field; np++)
216ea022d16SRodney W. Grimes 		if (!np->set)
217ea022d16SRodney W. Grimes 			np->value = np->defalt;
218ea022d16SRodney W. Grimes 	for (fp = gettyflags; fp->field; fp++)
219ea022d16SRodney W. Grimes 		if (!fp->set)
220ea022d16SRodney W. Grimes 			fp->value = fp->defalt;
221ea022d16SRodney W. Grimes }
222ea022d16SRodney W. Grimes 
223ea022d16SRodney W. Grimes static char **
224ea022d16SRodney W. Grimes charnames[] = {
225ea022d16SRodney W. Grimes 	&ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
226ea022d16SRodney W. Grimes 	&SU, &DS, &RP, &FL, &WE, &LN, 0
227ea022d16SRodney W. Grimes };
228ea022d16SRodney W. Grimes 
229ea022d16SRodney W. Grimes static char *
230ea022d16SRodney W. Grimes charvars[] = {
231cae66988SJoerg Wunsch 	&tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR],
232cae66988SJoerg Wunsch 	&tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP],
233cae66988SJoerg Wunsch 	&tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP],
234cae66988SJoerg Wunsch 	&tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD],
235cae66988SJoerg Wunsch 	&tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], 0
236ea022d16SRodney W. Grimes };
237ea022d16SRodney W. Grimes 
238cae66988SJoerg Wunsch void
23995289b27SWarner Losh setchars(void)
240ea022d16SRodney W. Grimes {
24195289b27SWarner Losh 	int i;
24295289b27SWarner Losh 	const char *p;
243ea022d16SRodney W. Grimes 
244ea022d16SRodney W. Grimes 	for (i = 0; charnames[i]; i++) {
245ea022d16SRodney W. Grimes 		p = *charnames[i];
246ea022d16SRodney W. Grimes 		if (p && *p)
247ea022d16SRodney W. Grimes 			*charvars[i] = *p;
248ea022d16SRodney W. Grimes 		else
249cae66988SJoerg Wunsch 			*charvars[i] = _POSIX_VDISABLE;
250ea022d16SRodney W. Grimes 	}
251ea022d16SRodney W. Grimes }
252ea022d16SRodney W. Grimes 
253cae66988SJoerg Wunsch /* Macros to clear/set/test flags. */
254cae66988SJoerg Wunsch #define	SET(t, f)	(t) |= (f)
255cae66988SJoerg Wunsch #define	CLR(t, f)	(t) &= ~(f)
256cae66988SJoerg Wunsch #define	ISSET(t, f)	((t) & (f))
257cae66988SJoerg Wunsch 
258cae66988SJoerg Wunsch void
25995289b27SWarner Losh set_flags(int n)
260ea022d16SRodney W. Grimes {
26195289b27SWarner Losh 	tcflag_t iflag, oflag, cflag, lflag;
262cae66988SJoerg Wunsch 
263cae66988SJoerg Wunsch #ifdef COMPAT_43
264cae66988SJoerg Wunsch 	switch (n) {
265cae66988SJoerg Wunsch 	case 0:
266cae66988SJoerg Wunsch 		if (F0set) {
267cae66988SJoerg Wunsch 			compatflags(F0);
268cae66988SJoerg Wunsch 			return;
269cae66988SJoerg Wunsch 		}
270cae66988SJoerg Wunsch 		break;
271cae66988SJoerg Wunsch 	case 1:
272cae66988SJoerg Wunsch 		if (F1set) {
273cae66988SJoerg Wunsch 			compatflags(F1);
274cae66988SJoerg Wunsch 			return;
275cae66988SJoerg Wunsch 		}
276cae66988SJoerg Wunsch 		break;
277cae66988SJoerg Wunsch 	default:
278cae66988SJoerg Wunsch 		if (F2set) {
279cae66988SJoerg Wunsch 			compatflags(F2);
280cae66988SJoerg Wunsch 			return;
281cae66988SJoerg Wunsch 		}
282cae66988SJoerg Wunsch 		break;
283cae66988SJoerg Wunsch 	}
284cae66988SJoerg Wunsch #endif
285ea022d16SRodney W. Grimes 
286ea022d16SRodney W. Grimes 	switch (n) {
287ea022d16SRodney W. Grimes 	case 0:
288cae66988SJoerg Wunsch 		if (C0set && I0set && L0set && O0set) {
289cae66988SJoerg Wunsch 			tmode.c_cflag = C0;
290cae66988SJoerg Wunsch 			tmode.c_iflag = I0;
291cae66988SJoerg Wunsch 			tmode.c_lflag = L0;
292cae66988SJoerg Wunsch 			tmode.c_oflag = O0;
293cae66988SJoerg Wunsch 			return;
294cae66988SJoerg Wunsch 		}
295ea022d16SRodney W. Grimes 		break;
296ea022d16SRodney W. Grimes 	case 1:
297cae66988SJoerg Wunsch 		if (C1set && I1set && L1set && O1set) {
298cae66988SJoerg Wunsch 			tmode.c_cflag = C1;
299cae66988SJoerg Wunsch 			tmode.c_iflag = I1;
300cae66988SJoerg Wunsch 			tmode.c_lflag = L1;
301cae66988SJoerg Wunsch 			tmode.c_oflag = O1;
302cae66988SJoerg Wunsch 			return;
303cae66988SJoerg Wunsch 		}
304ea022d16SRodney W. Grimes 		break;
305ea022d16SRodney W. Grimes 	default:
306cae66988SJoerg Wunsch 		if (C2set && I2set && L2set && O2set) {
307cae66988SJoerg Wunsch 			tmode.c_cflag = C2;
308cae66988SJoerg Wunsch 			tmode.c_iflag = I2;
309cae66988SJoerg Wunsch 			tmode.c_lflag = L2;
310cae66988SJoerg Wunsch 			tmode.c_oflag = O2;
311cae66988SJoerg Wunsch 			return;
312cae66988SJoerg Wunsch 		}
313ea022d16SRodney W. Grimes 		break;
314ea022d16SRodney W. Grimes 	}
315ea022d16SRodney W. Grimes 
316cae66988SJoerg Wunsch 	iflag = omode.c_iflag;
317cae66988SJoerg Wunsch 	oflag = omode.c_oflag;
318cae66988SJoerg Wunsch 	cflag = omode.c_cflag;
319cae66988SJoerg Wunsch 	lflag = omode.c_lflag;
320ea022d16SRodney W. Grimes 
321cae66988SJoerg Wunsch 	if (NP) {
322cae66988SJoerg Wunsch 		CLR(cflag, CSIZE|PARENB);
323cae66988SJoerg Wunsch 		SET(cflag, CS8);
324cae66988SJoerg Wunsch 		CLR(iflag, ISTRIP|INPCK|IGNPAR);
325cae66988SJoerg Wunsch 	} else if (AP || EP || OP) {
326cae66988SJoerg Wunsch 		CLR(cflag, CSIZE);
327cae66988SJoerg Wunsch 		SET(cflag, CS7|PARENB);
328cae66988SJoerg Wunsch 		SET(iflag, ISTRIP);
329cae66988SJoerg Wunsch 		if (OP && !EP) {
330cae66988SJoerg Wunsch 			SET(iflag, INPCK|IGNPAR);
331cae66988SJoerg Wunsch 			SET(cflag, PARODD);
332ea022d16SRodney W. Grimes 			if (AP)
333cae66988SJoerg Wunsch 				CLR(iflag, INPCK);
334cae66988SJoerg Wunsch 		} else if (EP && !OP) {
335cae66988SJoerg Wunsch 			SET(iflag, INPCK|IGNPAR);
336cae66988SJoerg Wunsch 			CLR(cflag, PARODD);
337cae66988SJoerg Wunsch 			if (AP)
338cae66988SJoerg Wunsch 				CLR(iflag, INPCK);
339cae66988SJoerg Wunsch 		} else if (AP || (EP && OP)) {
340cae66988SJoerg Wunsch 			CLR(iflag, INPCK|IGNPAR);
341cae66988SJoerg Wunsch 			CLR(cflag, PARODD);
342cae66988SJoerg Wunsch 		}
343cae66988SJoerg Wunsch 	} /* else, leave as is */
344ea022d16SRodney W. Grimes 
345cae66988SJoerg Wunsch #if 0
346ea022d16SRodney W. Grimes 	if (UC)
347ea022d16SRodney W. Grimes 		f |= LCASE;
348cae66988SJoerg Wunsch #endif
349ea022d16SRodney W. Grimes 
350cae66988SJoerg Wunsch 	if (HC)
351cae66988SJoerg Wunsch 		SET(cflag, HUPCL);
352ea022d16SRodney W. Grimes 	else
353cae66988SJoerg Wunsch 		CLR(cflag, HUPCL);
354cae66988SJoerg Wunsch 
355cae66988SJoerg Wunsch 	if (MB)
356cae66988SJoerg Wunsch 		SET(cflag, MDMBUF);
357cae66988SJoerg Wunsch 	else
358cae66988SJoerg Wunsch 		CLR(cflag, MDMBUF);
359cae66988SJoerg Wunsch 
360fe552114SDavid Nugent 	if (HW)
361fe552114SDavid Nugent 		SET(cflag, CRTSCTS);
362fe552114SDavid Nugent 	else
363fe552114SDavid Nugent 		CLR(cflag, CRTSCTS);
364fe552114SDavid Nugent 
365cae66988SJoerg Wunsch 	if (NL) {
366cae66988SJoerg Wunsch 		SET(iflag, ICRNL);
367cae66988SJoerg Wunsch 		SET(oflag, ONLCR|OPOST);
368cae66988SJoerg Wunsch 	} else {
369cae66988SJoerg Wunsch 		CLR(iflag, ICRNL);
370cae66988SJoerg Wunsch 		CLR(oflag, ONLCR);
371ea022d16SRodney W. Grimes 	}
372ea022d16SRodney W. Grimes 
373ea022d16SRodney W. Grimes 	if (!HT)
374cae66988SJoerg Wunsch 		SET(oflag, OXTABS|OPOST);
375cae66988SJoerg Wunsch 	else
376cae66988SJoerg Wunsch 		CLR(oflag, OXTABS);
377ea022d16SRodney W. Grimes 
378cae66988SJoerg Wunsch #ifdef XXX_DELAY
379cae66988SJoerg Wunsch 	SET(f, delaybits());
380cae66988SJoerg Wunsch #endif
381ea022d16SRodney W. Grimes 
382cae66988SJoerg Wunsch 	if (n == 1) {		/* read mode flags */
383cae66988SJoerg Wunsch 		if (RW) {
384cae66988SJoerg Wunsch 			iflag = 0;
385cae66988SJoerg Wunsch 			CLR(oflag, OPOST);
386cae66988SJoerg Wunsch 			CLR(cflag, CSIZE|PARENB);
387cae66988SJoerg Wunsch 			SET(cflag, CS8);
388cae66988SJoerg Wunsch 			lflag = 0;
389cae66988SJoerg Wunsch 		} else {
390cae66988SJoerg Wunsch 			CLR(lflag, ICANON);
391cae66988SJoerg Wunsch 		}
392cae66988SJoerg Wunsch 		goto out;
393ea022d16SRodney W. Grimes 	}
394ea022d16SRodney W. Grimes 
395cae66988SJoerg Wunsch 	if (n == 0)
396cae66988SJoerg Wunsch 		goto out;
397cae66988SJoerg Wunsch 
398cae66988SJoerg Wunsch #if 0
399cae66988SJoerg Wunsch 	if (CB)
400cae66988SJoerg Wunsch 		SET(f, CRTBS);
401cae66988SJoerg Wunsch #endif
402cae66988SJoerg Wunsch 
403cae66988SJoerg Wunsch 	if (CE)
404cae66988SJoerg Wunsch 		SET(lflag, ECHOE);
405cae66988SJoerg Wunsch 	else
406cae66988SJoerg Wunsch 		CLR(lflag, ECHOE);
407cae66988SJoerg Wunsch 
408cae66988SJoerg Wunsch 	if (CK)
409cae66988SJoerg Wunsch 		SET(lflag, ECHOKE);
410cae66988SJoerg Wunsch 	else
411cae66988SJoerg Wunsch 		CLR(lflag, ECHOKE);
412cae66988SJoerg Wunsch 
413cae66988SJoerg Wunsch 	if (PE)
414cae66988SJoerg Wunsch 		SET(lflag, ECHOPRT);
415cae66988SJoerg Wunsch 	else
416cae66988SJoerg Wunsch 		CLR(lflag, ECHOPRT);
417cae66988SJoerg Wunsch 
418cae66988SJoerg Wunsch 	if (EC)
419cae66988SJoerg Wunsch 		SET(lflag, ECHO);
420cae66988SJoerg Wunsch 	else
421cae66988SJoerg Wunsch 		CLR(lflag, ECHO);
422cae66988SJoerg Wunsch 
423cae66988SJoerg Wunsch 	if (XC)
424cae66988SJoerg Wunsch 		SET(lflag, ECHOCTL);
425cae66988SJoerg Wunsch 	else
426cae66988SJoerg Wunsch 		CLR(lflag, ECHOCTL);
427cae66988SJoerg Wunsch 
428cae66988SJoerg Wunsch 	if (DX)
429cae66988SJoerg Wunsch 		SET(lflag, IXANY);
430cae66988SJoerg Wunsch 	else
431cae66988SJoerg Wunsch 		CLR(lflag, IXANY);
432cae66988SJoerg Wunsch 
433cae66988SJoerg Wunsch out:
434cae66988SJoerg Wunsch 	tmode.c_iflag = iflag;
435cae66988SJoerg Wunsch 	tmode.c_oflag = oflag;
436cae66988SJoerg Wunsch 	tmode.c_cflag = cflag;
437cae66988SJoerg Wunsch 	tmode.c_lflag = lflag;
438cae66988SJoerg Wunsch }
439cae66988SJoerg Wunsch 
440cae66988SJoerg Wunsch #ifdef COMPAT_43
441cae66988SJoerg Wunsch /*
442cae66988SJoerg Wunsch  * Old TTY => termios, snatched from <sys/kern/tty_compat.c>
443cae66988SJoerg Wunsch  */
444cae66988SJoerg Wunsch void
44595289b27SWarner Losh compatflags(long flags)
446cae66988SJoerg Wunsch {
44795289b27SWarner Losh 	tcflag_t iflag, oflag, cflag, lflag;
448cae66988SJoerg Wunsch 
449cae66988SJoerg Wunsch 	iflag = BRKINT|ICRNL|IMAXBEL|IXON|IXANY;
450cae66988SJoerg Wunsch 	oflag = OPOST|ONLCR|OXTABS;
451cae66988SJoerg Wunsch 	cflag = CREAD;
452cae66988SJoerg Wunsch 	lflag = ICANON|ISIG|IEXTEN;
453cae66988SJoerg Wunsch 
454cae66988SJoerg Wunsch 	if (ISSET(flags, TANDEM))
455cae66988SJoerg Wunsch 		SET(iflag, IXOFF);
456cae66988SJoerg Wunsch 	else
457cae66988SJoerg Wunsch 		CLR(iflag, IXOFF);
458cae66988SJoerg Wunsch 	if (ISSET(flags, ECHO))
459cae66988SJoerg Wunsch 		SET(lflag, ECHO);
460cae66988SJoerg Wunsch 	else
461cae66988SJoerg Wunsch 		CLR(lflag, ECHO);
462cae66988SJoerg Wunsch 	if (ISSET(flags, CRMOD)) {
463cae66988SJoerg Wunsch 		SET(iflag, ICRNL);
464cae66988SJoerg Wunsch 		SET(oflag, ONLCR);
465cae66988SJoerg Wunsch 	} else {
466cae66988SJoerg Wunsch 		CLR(iflag, ICRNL);
467cae66988SJoerg Wunsch 		CLR(oflag, ONLCR);
468cae66988SJoerg Wunsch 	}
469cae66988SJoerg Wunsch 	if (ISSET(flags, XTABS))
470cae66988SJoerg Wunsch 		SET(oflag, OXTABS);
471cae66988SJoerg Wunsch 	else
472cae66988SJoerg Wunsch 		CLR(oflag, OXTABS);
473cae66988SJoerg Wunsch 
474cae66988SJoerg Wunsch 
475cae66988SJoerg Wunsch 	if (ISSET(flags, RAW)) {
476cae66988SJoerg Wunsch 		iflag &= IXOFF;
477cae66988SJoerg Wunsch 		CLR(lflag, ISIG|ICANON|IEXTEN);
478cae66988SJoerg Wunsch 		CLR(cflag, PARENB);
479cae66988SJoerg Wunsch 	} else {
480cae66988SJoerg Wunsch 		SET(iflag, BRKINT|IXON|IMAXBEL);
481cae66988SJoerg Wunsch 		SET(lflag, ISIG|IEXTEN);
482cae66988SJoerg Wunsch 		if (ISSET(flags, CBREAK))
483cae66988SJoerg Wunsch 			CLR(lflag, ICANON);
484cae66988SJoerg Wunsch 		else
485cae66988SJoerg Wunsch 			SET(lflag, ICANON);
486cae66988SJoerg Wunsch 		switch (ISSET(flags, ANYP)) {
487cae66988SJoerg Wunsch 		case 0:
488cae66988SJoerg Wunsch 			CLR(cflag, PARENB);
489cae66988SJoerg Wunsch 			break;
490cae66988SJoerg Wunsch 		case ANYP:
491cae66988SJoerg Wunsch 			SET(cflag, PARENB);
492cae66988SJoerg Wunsch 			CLR(iflag, INPCK);
493cae66988SJoerg Wunsch 			break;
494cae66988SJoerg Wunsch 		case EVENP:
495cae66988SJoerg Wunsch 			SET(cflag, PARENB);
496cae66988SJoerg Wunsch 			SET(iflag, INPCK);
497cae66988SJoerg Wunsch 			CLR(cflag, PARODD);
498cae66988SJoerg Wunsch 			break;
499cae66988SJoerg Wunsch 		case ODDP:
500cae66988SJoerg Wunsch 			SET(cflag, PARENB);
501cae66988SJoerg Wunsch 			SET(iflag, INPCK);
502cae66988SJoerg Wunsch 			SET(cflag, PARODD);
503cae66988SJoerg Wunsch 			break;
504cae66988SJoerg Wunsch 		}
505cae66988SJoerg Wunsch 	}
506cae66988SJoerg Wunsch 
507cae66988SJoerg Wunsch 	/* Nothing we can do with CRTBS. */
508cae66988SJoerg Wunsch 	if (ISSET(flags, PRTERA))
509cae66988SJoerg Wunsch 		SET(lflag, ECHOPRT);
510cae66988SJoerg Wunsch 	else
511cae66988SJoerg Wunsch 		CLR(lflag, ECHOPRT);
512cae66988SJoerg Wunsch 	if (ISSET(flags, CRTERA))
513cae66988SJoerg Wunsch 		SET(lflag, ECHOE);
514cae66988SJoerg Wunsch 	else
515cae66988SJoerg Wunsch 		CLR(lflag, ECHOE);
516cae66988SJoerg Wunsch 	/* Nothing we can do with TILDE. */
517cae66988SJoerg Wunsch 	if (ISSET(flags, MDMBUF))
518cae66988SJoerg Wunsch 		SET(cflag, MDMBUF);
519cae66988SJoerg Wunsch 	else
520cae66988SJoerg Wunsch 		CLR(cflag, MDMBUF);
521cae66988SJoerg Wunsch 	if (ISSET(flags, NOHANG))
522cae66988SJoerg Wunsch 		CLR(cflag, HUPCL);
523cae66988SJoerg Wunsch 	else
524cae66988SJoerg Wunsch 		SET(cflag, HUPCL);
525cae66988SJoerg Wunsch 	if (ISSET(flags, CRTKIL))
526cae66988SJoerg Wunsch 		SET(lflag, ECHOKE);
527cae66988SJoerg Wunsch 	else
528cae66988SJoerg Wunsch 		CLR(lflag, ECHOKE);
529cae66988SJoerg Wunsch 	if (ISSET(flags, CTLECH))
530cae66988SJoerg Wunsch 		SET(lflag, ECHOCTL);
531cae66988SJoerg Wunsch 	else
532cae66988SJoerg Wunsch 		CLR(lflag, ECHOCTL);
533cae66988SJoerg Wunsch 	if (!ISSET(flags, DECCTQ))
534cae66988SJoerg Wunsch 		SET(iflag, IXANY);
535cae66988SJoerg Wunsch 	else
536cae66988SJoerg Wunsch 		CLR(iflag, IXANY);
537cae66988SJoerg Wunsch 	CLR(lflag, TOSTOP|FLUSHO|PENDIN|NOFLSH);
538cae66988SJoerg Wunsch 	SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
539cae66988SJoerg Wunsch 
540cae66988SJoerg Wunsch 	if (ISSET(flags, RAW|LITOUT|PASS8)) {
541cae66988SJoerg Wunsch 		CLR(cflag, CSIZE);
542cae66988SJoerg Wunsch 		SET(cflag, CS8);
543cae66988SJoerg Wunsch 		if (!ISSET(flags, RAW|PASS8))
544cae66988SJoerg Wunsch 			SET(iflag, ISTRIP);
545cae66988SJoerg Wunsch 		else
546cae66988SJoerg Wunsch 			CLR(iflag, ISTRIP);
547cae66988SJoerg Wunsch 		if (!ISSET(flags, RAW|LITOUT))
548cae66988SJoerg Wunsch 			SET(oflag, OPOST);
549cae66988SJoerg Wunsch 		else
550cae66988SJoerg Wunsch 			CLR(oflag, OPOST);
551cae66988SJoerg Wunsch 	} else {
552cae66988SJoerg Wunsch 		CLR(cflag, CSIZE);
553cae66988SJoerg Wunsch 		SET(cflag, CS7);
554cae66988SJoerg Wunsch 		SET(iflag, ISTRIP);
555cae66988SJoerg Wunsch 		SET(oflag, OPOST);
556cae66988SJoerg Wunsch 	}
557cae66988SJoerg Wunsch 
558cae66988SJoerg Wunsch 	tmode.c_iflag = iflag;
559cae66988SJoerg Wunsch 	tmode.c_oflag = oflag;
560cae66988SJoerg Wunsch 	tmode.c_cflag = cflag;
561cae66988SJoerg Wunsch 	tmode.c_lflag = lflag;
562cae66988SJoerg Wunsch }
563cae66988SJoerg Wunsch #endif
564cae66988SJoerg Wunsch 
565cae66988SJoerg Wunsch #ifdef XXX_DELAY
566ea022d16SRodney W. Grimes struct delayval {
567ea022d16SRodney W. Grimes 	unsigned	delay;		/* delay in ms */
568ea022d16SRodney W. Grimes 	int		bits;
569ea022d16SRodney W. Grimes };
570ea022d16SRodney W. Grimes 
571ea022d16SRodney W. Grimes /*
572ea022d16SRodney W. Grimes  * below are random guesses, I can't be bothered checking
573ea022d16SRodney W. Grimes  */
574ea022d16SRodney W. Grimes 
575ea022d16SRodney W. Grimes struct delayval	crdelay[] = {
576cae66988SJoerg Wunsch 	{ 1,		CR1 },
577cae66988SJoerg Wunsch 	{ 2,		CR2 },
578cae66988SJoerg Wunsch 	{ 3,		CR3 },
579cae66988SJoerg Wunsch 	{ 83,		CR1 },
580cae66988SJoerg Wunsch 	{ 166,		CR2 },
581cae66988SJoerg Wunsch 	{ 0,		CR3 },
582ea022d16SRodney W. Grimes };
583ea022d16SRodney W. Grimes 
584ea022d16SRodney W. Grimes struct delayval nldelay[] = {
585cae66988SJoerg Wunsch 	{ 1,		NL1 },		/* special, calculated */
586cae66988SJoerg Wunsch 	{ 2,		NL2 },
587cae66988SJoerg Wunsch 	{ 3,		NL3 },
588cae66988SJoerg Wunsch 	{ 100,		NL2 },
589cae66988SJoerg Wunsch 	{ 0,		NL3 },
590ea022d16SRodney W. Grimes };
591ea022d16SRodney W. Grimes 
592ea022d16SRodney W. Grimes struct delayval	bsdelay[] = {
593cae66988SJoerg Wunsch 	{ 1,		BS1 },
594cae66988SJoerg Wunsch 	{ 0,		0 },
595ea022d16SRodney W. Grimes };
596ea022d16SRodney W. Grimes 
597ea022d16SRodney W. Grimes struct delayval	ffdelay[] = {
598cae66988SJoerg Wunsch 	{ 1,		FF1 },
599cae66988SJoerg Wunsch 	{ 1750,		FF1 },
600cae66988SJoerg Wunsch 	{ 0,		FF1 },
601ea022d16SRodney W. Grimes };
602ea022d16SRodney W. Grimes 
603ea022d16SRodney W. Grimes struct delayval	tbdelay[] = {
604cae66988SJoerg Wunsch 	{ 1,		TAB1 },
605cae66988SJoerg Wunsch 	{ 2,		TAB2 },
606cae66988SJoerg Wunsch 	{ 3,		XTABS },	/* this is expand tabs */
607cae66988SJoerg Wunsch 	{ 100,		TAB1 },
608cae66988SJoerg Wunsch 	{ 0,		TAB2 },
609ea022d16SRodney W. Grimes };
610ea022d16SRodney W. Grimes 
611cae66988SJoerg Wunsch int
61295289b27SWarner Losh delaybits(void)
613ea022d16SRodney W. Grimes {
61495289b27SWarner Losh 	int f;
615ea022d16SRodney W. Grimes 
616ea022d16SRodney W. Grimes 	f  = adelay(CD, crdelay);
617ea022d16SRodney W. Grimes 	f |= adelay(ND, nldelay);
618ea022d16SRodney W. Grimes 	f |= adelay(FD, ffdelay);
619ea022d16SRodney W. Grimes 	f |= adelay(TD, tbdelay);
620ea022d16SRodney W. Grimes 	f |= adelay(BD, bsdelay);
621ea022d16SRodney W. Grimes 	return (f);
622ea022d16SRodney W. Grimes }
623ea022d16SRodney W. Grimes 
624cae66988SJoerg Wunsch int
62595289b27SWarner Losh adelay(int ms, struct delayval *dp)
626ea022d16SRodney W. Grimes {
627ea022d16SRodney W. Grimes 	if (ms == 0)
628ea022d16SRodney W. Grimes 		return (0);
629ea022d16SRodney W. Grimes 	while (dp->delay && ms > dp->delay)
630ea022d16SRodney W. Grimes 		dp++;
631ea022d16SRodney W. Grimes 	return (dp->bits);
632ea022d16SRodney W. Grimes }
633cae66988SJoerg Wunsch #endif
634ea022d16SRodney W. Grimes 
635c568fce9SAndrey A. Chernov char	editedhost[MAXHOSTNAMELEN];
636ea022d16SRodney W. Grimes 
637cae66988SJoerg Wunsch void
63895289b27SWarner Losh edithost(const char *pat)
639ea022d16SRodney W. Grimes {
64095289b27SWarner Losh 	const char *host = HN;
64195289b27SWarner Losh 	char *res = editedhost;
642ea022d16SRodney W. Grimes 
643ea022d16SRodney W. Grimes 	if (!pat)
644ea022d16SRodney W. Grimes 		pat = "";
645ea022d16SRodney W. Grimes 	while (*pat) {
646ea022d16SRodney W. Grimes 		switch (*pat) {
647ea022d16SRodney W. Grimes 
648ea022d16SRodney W. Grimes 		case '#':
649ea022d16SRodney W. Grimes 			if (*host)
650ea022d16SRodney W. Grimes 				host++;
651ea022d16SRodney W. Grimes 			break;
652ea022d16SRodney W. Grimes 
653ea022d16SRodney W. Grimes 		case '@':
654ea022d16SRodney W. Grimes 			if (*host)
655ea022d16SRodney W. Grimes 				*res++ = *host++;
656ea022d16SRodney W. Grimes 			break;
657ea022d16SRodney W. Grimes 
658ea022d16SRodney W. Grimes 		default:
659ea022d16SRodney W. Grimes 			*res++ = *pat;
660ea022d16SRodney W. Grimes 			break;
661ea022d16SRodney W. Grimes 
662ea022d16SRodney W. Grimes 		}
663ea022d16SRodney W. Grimes 		if (res == &editedhost[sizeof editedhost - 1]) {
664ea022d16SRodney W. Grimes 			*res = '\0';
665ea022d16SRodney W. Grimes 			return;
666ea022d16SRodney W. Grimes 		}
667ea022d16SRodney W. Grimes 		pat++;
668ea022d16SRodney W. Grimes 	}
669ea022d16SRodney W. Grimes 	if (*host)
670ea022d16SRodney W. Grimes 		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
671ea022d16SRodney W. Grimes 	else
672ea022d16SRodney W. Grimes 		*res = '\0';
673ea022d16SRodney W. Grimes 	editedhost[sizeof editedhost - 1] = '\0';
674ea022d16SRodney W. Grimes }
675ea022d16SRodney W. Grimes 
676cae66988SJoerg Wunsch static struct speedtab {
677ea022d16SRodney W. Grimes 	int	speed;
678ea022d16SRodney W. Grimes 	int	uxname;
679ea022d16SRodney W. Grimes } speedtab[] = {
680cae66988SJoerg Wunsch 	{ 50,	B50 },
681cae66988SJoerg Wunsch 	{ 75,	B75 },
682cae66988SJoerg Wunsch 	{ 110,	B110 },
683cae66988SJoerg Wunsch 	{ 134,	B134 },
684cae66988SJoerg Wunsch 	{ 150,	B150 },
685cae66988SJoerg Wunsch 	{ 200,	B200 },
686cae66988SJoerg Wunsch 	{ 300,	B300 },
687cae66988SJoerg Wunsch 	{ 600,	B600 },
688cae66988SJoerg Wunsch 	{ 1200,	B1200 },
689cae66988SJoerg Wunsch 	{ 1800,	B1800 },
690cae66988SJoerg Wunsch 	{ 2400,	B2400 },
691cae66988SJoerg Wunsch 	{ 4800,	B4800 },
692cae66988SJoerg Wunsch 	{ 9600,	B9600 },
693cae66988SJoerg Wunsch 	{ 19200, EXTA },
694cae66988SJoerg Wunsch 	{ 19,	EXTA },		/* for people who say 19.2K */
695cae66988SJoerg Wunsch 	{ 38400, EXTB },
696cae66988SJoerg Wunsch 	{ 38,	EXTB },
697cae66988SJoerg Wunsch 	{ 7200,	EXTB },		/* alternative */
698cae66988SJoerg Wunsch 	{ 57600, B57600 },
699cae66988SJoerg Wunsch 	{ 115200, B115200 },
700ee98a93fSPoul-Henning Kamp 	{ 230400, B230400 },
701cae66988SJoerg Wunsch 	{ 0 }
702ea022d16SRodney W. Grimes };
703ea022d16SRodney W. Grimes 
704cae66988SJoerg Wunsch int
70595289b27SWarner Losh speed(int val)
706ea022d16SRodney W. Grimes {
70795289b27SWarner Losh 	struct speedtab *sp;
708ea022d16SRodney W. Grimes 
709ee98a93fSPoul-Henning Kamp 	if (val <= B230400)
710ea022d16SRodney W. Grimes 		return (val);
711ea022d16SRodney W. Grimes 
712ea022d16SRodney W. Grimes 	for (sp = speedtab; sp->speed; sp++)
713ea022d16SRodney W. Grimes 		if (sp->speed == val)
714ea022d16SRodney W. Grimes 			return (sp->uxname);
715ea022d16SRodney W. Grimes 
716ea022d16SRodney W. Grimes 	return (B300);		/* default in impossible cases */
717ea022d16SRodney W. Grimes }
718ea022d16SRodney W. Grimes 
719cae66988SJoerg Wunsch void
72095289b27SWarner Losh makeenv(char *env[])
721ea022d16SRodney W. Grimes {
722ea022d16SRodney W. Grimes 	static char termbuf[128] = "TERM=";
72395289b27SWarner Losh 	char *p, *q;
72495289b27SWarner Losh 	char **ep;
725ea022d16SRodney W. Grimes 
726ea022d16SRodney W. Grimes 	ep = env;
727ea022d16SRodney W. Grimes 	if (TT && *TT) {
7286e76e16fSKris Kennaway 		strlcat(termbuf, TT, sizeof(termbuf));
729ea022d16SRodney W. Grimes 		*ep++ = termbuf;
730ea022d16SRodney W. Grimes 	}
731cae66988SJoerg Wunsch 	if ((p = EV)) {
732ea022d16SRodney W. Grimes 		q = p;
733cae66988SJoerg Wunsch 		while ((q = strchr(q, ','))) {
734ea022d16SRodney W. Grimes 			*q++ = '\0';
735ea022d16SRodney W. Grimes 			*ep++ = p;
736ea022d16SRodney W. Grimes 			p = q;
737ea022d16SRodney W. Grimes 		}
738ea022d16SRodney W. Grimes 		if (*p)
739ea022d16SRodney W. Grimes 			*ep++ = p;
740ea022d16SRodney W. Grimes 	}
741ea022d16SRodney W. Grimes 	*ep = (char *)0;
742ea022d16SRodney W. Grimes }
743ea022d16SRodney W. Grimes 
744ea022d16SRodney W. Grimes /*
745ea022d16SRodney W. Grimes  * This speed select mechanism is written for the Develcon DATASWITCH.
746ea022d16SRodney W. Grimes  * The Develcon sends a string of the form "B{speed}\n" at a predefined
747ea022d16SRodney W. Grimes  * baud rate. This string indicates the user's actual speed.
748ea022d16SRodney W. Grimes  * The routine below returns the terminal type mapped from derived speed.
749ea022d16SRodney W. Grimes  */
750ea022d16SRodney W. Grimes struct	portselect {
751cae66988SJoerg Wunsch 	const char	*ps_baud;
752cae66988SJoerg Wunsch 	const char	*ps_type;
753ea022d16SRodney W. Grimes } portspeeds[] = {
754ea022d16SRodney W. Grimes 	{ "B110",	"std.110" },
755ea022d16SRodney W. Grimes 	{ "B134",	"std.134" },
756ea022d16SRodney W. Grimes 	{ "B150",	"std.150" },
757ea022d16SRodney W. Grimes 	{ "B300",	"std.300" },
758ea022d16SRodney W. Grimes 	{ "B600",	"std.600" },
759ea022d16SRodney W. Grimes 	{ "B1200",	"std.1200" },
760ea022d16SRodney W. Grimes 	{ "B2400",	"std.2400" },
761ea022d16SRodney W. Grimes 	{ "B4800",	"std.4800" },
762ea022d16SRodney W. Grimes 	{ "B9600",	"std.9600" },
763ea022d16SRodney W. Grimes 	{ "B19200",	"std.19200" },
764ea022d16SRodney W. Grimes 	{ 0 }
765ea022d16SRodney W. Grimes };
766ea022d16SRodney W. Grimes 
767cae66988SJoerg Wunsch const char *
76895289b27SWarner Losh portselector(void)
769ea022d16SRodney W. Grimes {
770cae66988SJoerg Wunsch 	char c, baud[20];
771cae66988SJoerg Wunsch 	const char *type = "default";
77295289b27SWarner Losh 	struct portselect *ps;
773ea022d16SRodney W. Grimes 	int len;
774ea022d16SRodney W. Grimes 
775ea022d16SRodney W. Grimes 	alarm(5*60);
776ea022d16SRodney W. Grimes 	for (len = 0; len < sizeof (baud) - 1; len++) {
777ea022d16SRodney W. Grimes 		if (read(STDIN_FILENO, &c, 1) <= 0)
778ea022d16SRodney W. Grimes 			break;
779ea022d16SRodney W. Grimes 		c &= 0177;
780ea022d16SRodney W. Grimes 		if (c == '\n' || c == '\r')
781ea022d16SRodney W. Grimes 			break;
782ea022d16SRodney W. Grimes 		if (c == 'B')
783ea022d16SRodney W. Grimes 			len = 0;	/* in case of leading garbage */
784ea022d16SRodney W. Grimes 		baud[len] = c;
785ea022d16SRodney W. Grimes 	}
786ea022d16SRodney W. Grimes 	baud[len] = '\0';
787ea022d16SRodney W. Grimes 	for (ps = portspeeds; ps->ps_baud; ps++)
788ea022d16SRodney W. Grimes 		if (strcmp(ps->ps_baud, baud) == 0) {
789ea022d16SRodney W. Grimes 			type = ps->ps_type;
790ea022d16SRodney W. Grimes 			break;
791ea022d16SRodney W. Grimes 		}
792ea022d16SRodney W. Grimes 	sleep(2);	/* wait for connection to complete */
793ea022d16SRodney W. Grimes 	return (type);
794ea022d16SRodney W. Grimes }
795ea022d16SRodney W. Grimes 
796ea022d16SRodney W. Grimes /*
797ea022d16SRodney W. Grimes  * This auto-baud speed select mechanism is written for the Micom 600
798ea022d16SRodney W. Grimes  * portselector. Selection is done by looking at how the character '\r'
799ea022d16SRodney W. Grimes  * is garbled at the different speeds.
800ea022d16SRodney W. Grimes  */
801cae66988SJoerg Wunsch const char *
80295289b27SWarner Losh autobaud(void)
803ea022d16SRodney W. Grimes {
804ea022d16SRodney W. Grimes 	int rfds;
805ea022d16SRodney W. Grimes 	struct timeval timeout;
806cae66988SJoerg Wunsch 	char c;
807cae66988SJoerg Wunsch 	const char *type = "9600-baud";
808ea022d16SRodney W. Grimes 
809cae66988SJoerg Wunsch 	(void)tcflush(0, TCIOFLUSH);
810ea022d16SRodney W. Grimes 	rfds = 1 << 0;
811ea022d16SRodney W. Grimes 	timeout.tv_sec = 5;
812ea022d16SRodney W. Grimes 	timeout.tv_usec = 0;
813ea022d16SRodney W. Grimes 	if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
814ea022d16SRodney W. Grimes 	    (fd_set *)NULL, &timeout) <= 0)
815ea022d16SRodney W. Grimes 		return (type);
816ea022d16SRodney W. Grimes 	if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
817ea022d16SRodney W. Grimes 		return (type);
818ea022d16SRodney W. Grimes 	timeout.tv_sec = 0;
819ea022d16SRodney W. Grimes 	timeout.tv_usec = 20;
820ea022d16SRodney W. Grimes 	(void) select(32, (fd_set *)NULL, (fd_set *)NULL,
821ea022d16SRodney W. Grimes 	    (fd_set *)NULL, &timeout);
822cae66988SJoerg Wunsch 	(void)tcflush(0, TCIOFLUSH);
823ea022d16SRodney W. Grimes 	switch (c & 0377) {
824ea022d16SRodney W. Grimes 
825ea022d16SRodney W. Grimes 	case 0200:		/* 300-baud */
826ea022d16SRodney W. Grimes 		type = "300-baud";
827ea022d16SRodney W. Grimes 		break;
828ea022d16SRodney W. Grimes 
829ea022d16SRodney W. Grimes 	case 0346:		/* 1200-baud */
830ea022d16SRodney W. Grimes 		type = "1200-baud";
831ea022d16SRodney W. Grimes 		break;
832ea022d16SRodney W. Grimes 
833ea022d16SRodney W. Grimes 	case  015:		/* 2400-baud */
834ea022d16SRodney W. Grimes 	case 0215:
835ea022d16SRodney W. Grimes 		type = "2400-baud";
836ea022d16SRodney W. Grimes 		break;
837ea022d16SRodney W. Grimes 
838ea022d16SRodney W. Grimes 	default:		/* 4800-baud */
839ea022d16SRodney W. Grimes 		type = "4800-baud";
840ea022d16SRodney W. Grimes 		break;
841ea022d16SRodney W. Grimes 
842ea022d16SRodney W. Grimes 	case 0377:		/* 9600-baud */
843ea022d16SRodney W. Grimes 		type = "9600-baud";
844ea022d16SRodney W. Grimes 		break;
845ea022d16SRodney W. Grimes 	}
846ea022d16SRodney W. Grimes 	return (type);
847ea022d16SRodney W. Grimes }
848