xref: /freebsd/libexec/getty/subr.c (revision 18587b84c53f716a8e7220d2ecadafdad5eefd30)
18a16b7a1SPedro F. Giffuni /*-
28a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni  *
4cae66988SJoerg Wunsch  * Copyright (c) 1983, 1993
5cae66988SJoerg Wunsch  *	The Regents of the University of California.  All rights reserved.
6ea022d16SRodney W. Grimes  *
7ea022d16SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
8ea022d16SRodney W. Grimes  * modification, are permitted provided that the following conditions
9ea022d16SRodney W. Grimes  * are met:
10ea022d16SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
11ea022d16SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
12ea022d16SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
13ea022d16SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
14ea022d16SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
155efaea4cSChristian Brueffer  * 3. Neither the name of the University nor the names of its contributors
16ea022d16SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
17ea022d16SRodney W. Grimes  *    without specific prior written permission.
18ea022d16SRodney W. Grimes  *
19ea022d16SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20ea022d16SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21ea022d16SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22ea022d16SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23ea022d16SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24ea022d16SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25ea022d16SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26ea022d16SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27ea022d16SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28ea022d16SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29ea022d16SRodney W. Grimes  * SUCH DAMAGE.
30ea022d16SRodney W. Grimes  */
31ea022d16SRodney W. Grimes 
32ea022d16SRodney W. Grimes #ifndef lint
33d748864dSPhilippe Charnier #if 0
34d748864dSPhilippe Charnier static char sccsid[] = "@(#)from: subr.c	8.1 (Berkeley) 6/4/93";
35d748864dSPhilippe Charnier #endif
36d748864dSPhilippe Charnier static const char rcsid[] =
377f3dea24SPeter Wemm   "$FreeBSD$";
38ea022d16SRodney W. Grimes #endif /* not lint */
39ea022d16SRodney W. Grimes 
40ea022d16SRodney W. Grimes /*
41ea022d16SRodney W. Grimes  * Melbourne getty.
42ea022d16SRodney W. Grimes  */
43d748864dSPhilippe Charnier #include <sys/ioctl.h>
44d748864dSPhilippe Charnier #include <sys/param.h>
45d748864dSPhilippe Charnier #include <sys/time.h>
46a3e4b982SPedro F. Giffuni 
47a3e4b982SPedro F. Giffuni #include <poll.h>
48f73ff060SAlexey Dokuchaev #include <regex.h>
49a3e4b982SPedro F. Giffuni #include <stdlib.h>
50a3e4b982SPedro F. Giffuni #include <string.h>
51d748864dSPhilippe Charnier #include <syslog.h>
52a3e4b982SPedro F. Giffuni #include <termios.h>
53a3e4b982SPedro F. Giffuni #include <unistd.h>
54ea022d16SRodney W. Grimes 
55cae66988SJoerg Wunsch #include "gettytab.h"
56cae66988SJoerg Wunsch #include "pathnames.h"
57cae66988SJoerg Wunsch #include "extern.h"
58cae66988SJoerg Wunsch 
59ea022d16SRodney W. Grimes /*
60ea022d16SRodney W. Grimes  * Get a table entry.
61ea022d16SRodney W. Grimes  */
62cae66988SJoerg Wunsch void
6395289b27SWarner Losh gettable(const char *name, char *buf)
64ea022d16SRodney W. Grimes {
6595289b27SWarner Losh 	struct gettystrs *sp;
6695289b27SWarner Losh 	struct gettynums *np;
6795289b27SWarner Losh 	struct gettyflags *fp;
68cae66988SJoerg Wunsch 	long n;
6904a59e67SDavid Nugent 	int l;
7004a59e67SDavid Nugent 	char *p;
71*18587b84SEdward Tomasz Napierala 	static char path_gettytab[PATH_MAX];
72*18587b84SEdward Tomasz Napierala 	char *dba[2];
7304a59e67SDavid Nugent 
7404a59e67SDavid Nugent 	static int firsttime = 1;
7504a59e67SDavid Nugent 
76*18587b84SEdward Tomasz Napierala 	strlcpy(path_gettytab, _PATH_GETTYTAB, sizeof(path_gettytab));
77*18587b84SEdward Tomasz Napierala 	dba[0] = path_gettytab;
7873906f57SPedro F. Giffuni 	dba[1] = NULL;
79ea022d16SRodney W. Grimes 
8004a59e67SDavid Nugent 	if (firsttime) {
8104a59e67SDavid Nugent 		/*
8204a59e67SDavid Nugent 		 * we need to strdup() anything in the strings array
8304a59e67SDavid Nugent 		 * initially in order to simplify things later
8404a59e67SDavid Nugent 		 */
85ea022d16SRodney W. Grimes 		for (sp = gettystrs; sp->field; sp++)
8604a59e67SDavid Nugent 			if (sp->value != NULL) {
8704a59e67SDavid Nugent 				/* handle these ones more carefully */
8804a59e67SDavid Nugent 				if (sp >= &gettystrs[4] && sp <= &gettystrs[6])
8904a59e67SDavid Nugent 					l = 2;
9004a59e67SDavid Nugent 				else
9104a59e67SDavid Nugent 					l = strlen(sp->value) + 1;
9204a59e67SDavid Nugent 				if ((p = malloc(l)) != NULL) {
9304a59e67SDavid Nugent 					strncpy(p, sp->value, l);
9404a59e67SDavid Nugent 					p[l-1] = '\0';
9504a59e67SDavid Nugent 				}
9604a59e67SDavid Nugent 				/*
9704a59e67SDavid Nugent 				 * replace, even if NULL, else we'll
9804a59e67SDavid Nugent 				 * have problems with free()ing static mem
9904a59e67SDavid Nugent 				 */
10004a59e67SDavid Nugent 				sp->value = p;
10104a59e67SDavid Nugent 			}
10204a59e67SDavid Nugent 		firsttime = 0;
10304a59e67SDavid Nugent 	}
10404a59e67SDavid Nugent 
105*18587b84SEdward Tomasz Napierala 	switch (cgetent(&buf, dba, name)) {
10604a59e67SDavid Nugent 	case 1:
107*18587b84SEdward Tomasz Napierala 		syslog(LOG_ERR, "getty: couldn't resolve 'tc=' in gettytab '%s'", name);
108*18587b84SEdward Tomasz Napierala 		return;
10904a59e67SDavid Nugent 	case 0:
11004a59e67SDavid Nugent 		break;
11104a59e67SDavid Nugent 	case -1:
112*18587b84SEdward Tomasz Napierala 		syslog(LOG_ERR, "getty: unknown gettytab entry '%s'", name);
113*18587b84SEdward Tomasz Napierala 		return;
11404a59e67SDavid Nugent 	case -2:
115*18587b84SEdward Tomasz Napierala 		syslog(LOG_ERR, "getty: retrieving gettytab entry '%s': %m", name);
116*18587b84SEdward Tomasz Napierala 		return;
11704a59e67SDavid Nugent 	case -3:
118*18587b84SEdward Tomasz Napierala 		syslog(LOG_ERR, "getty: recursive 'tc=' reference gettytab entry '%s'", name);
119*18587b84SEdward Tomasz Napierala 		return;
12004a59e67SDavid Nugent 	default:
121*18587b84SEdward Tomasz Napierala 		syslog(LOG_ERR, "getty: unexpected cgetent() error for entry '%s'", name);
12204a59e67SDavid Nugent 		return;
12304a59e67SDavid Nugent 	}
12404a59e67SDavid Nugent 
12504a59e67SDavid Nugent 	for (sp = gettystrs; sp->field; sp++) {
126076ec402SEdward Tomasz Napierala 		if ((l = cgetstr(buf, sp->field, &p)) >= 0) {
12704a59e67SDavid Nugent 			if (sp->value) {
12804a59e67SDavid Nugent 				/* prefer existing value */
12904a59e67SDavid Nugent 				if (strcmp(p, sp->value) != 0)
13004a59e67SDavid Nugent 					free(sp->value);
13104a59e67SDavid Nugent 				else {
13204a59e67SDavid Nugent 					free(p);
13304a59e67SDavid Nugent 					p = sp->value;
13404a59e67SDavid Nugent 				}
13504a59e67SDavid Nugent 			}
13604a59e67SDavid Nugent 			sp->value = p;
13704a59e67SDavid Nugent 		} else if (l == -1) {
13804a59e67SDavid Nugent 			free(sp->value);
13904a59e67SDavid Nugent 			sp->value = NULL;
14004a59e67SDavid Nugent 		}
14104a59e67SDavid Nugent 	}
14204a59e67SDavid Nugent 
143ea022d16SRodney W. Grimes 	for (np = gettynums; np->field; np++) {
144076ec402SEdward Tomasz Napierala 		if (cgetnum(buf, np->field, &n) == -1)
145ea022d16SRodney W. Grimes 			np->set = 0;
146ea022d16SRodney W. Grimes 		else {
147ea022d16SRodney W. Grimes 			np->set = 1;
148ea022d16SRodney W. Grimes 			np->value = n;
149ea022d16SRodney W. Grimes 		}
150ea022d16SRodney W. Grimes 	}
15104a59e67SDavid Nugent 
152ea022d16SRodney W. Grimes 	for (fp = gettyflags; fp->field; fp++) {
153076ec402SEdward Tomasz Napierala 		if (cgetcap(buf, fp->field, ':') == NULL)
154ea022d16SRodney W. Grimes 			fp->set = 0;
155ea022d16SRodney W. Grimes 		else {
156ea022d16SRodney W. Grimes 			fp->set = 1;
157cae66988SJoerg Wunsch 			fp->value = 1 ^ fp->invrt;
158ea022d16SRodney W. Grimes 		}
159ea022d16SRodney W. Grimes 	}
160ea022d16SRodney W. Grimes }
161ea022d16SRodney W. Grimes 
162cae66988SJoerg Wunsch void
16395289b27SWarner Losh gendefaults(void)
164ea022d16SRodney W. Grimes {
16595289b27SWarner Losh 	struct gettystrs *sp;
16695289b27SWarner Losh 	struct gettynums *np;
16795289b27SWarner Losh 	struct gettyflags *fp;
168ea022d16SRodney W. Grimes 
169ea022d16SRodney W. Grimes 	for (sp = gettystrs; sp->field; sp++)
170ea022d16SRodney W. Grimes 		if (sp->value)
17104a59e67SDavid Nugent 			sp->defalt = strdup(sp->value);
172ea022d16SRodney W. Grimes 	for (np = gettynums; np->field; np++)
173ea022d16SRodney W. Grimes 		if (np->set)
174ea022d16SRodney W. Grimes 			np->defalt = np->value;
175ea022d16SRodney W. Grimes 	for (fp = gettyflags; fp->field; fp++)
176ea022d16SRodney W. Grimes 		if (fp->set)
177ea022d16SRodney W. Grimes 			fp->defalt = fp->value;
178ea022d16SRodney W. Grimes 		else
179ea022d16SRodney W. Grimes 			fp->defalt = fp->invrt;
180ea022d16SRodney W. Grimes }
181ea022d16SRodney W. Grimes 
182cae66988SJoerg Wunsch void
18395289b27SWarner Losh setdefaults(void)
184ea022d16SRodney W. Grimes {
18595289b27SWarner Losh 	struct gettystrs *sp;
18695289b27SWarner Losh 	struct gettynums *np;
18795289b27SWarner Losh 	struct gettyflags *fp;
188ea022d16SRodney W. Grimes 
189ea022d16SRodney W. Grimes 	for (sp = gettystrs; sp->field; sp++)
190ea022d16SRodney W. Grimes 		if (!sp->value)
19104a59e67SDavid Nugent 			sp->value = !sp->defalt ? sp->defalt
19204a59e67SDavid Nugent 						: strdup(sp->defalt);
193ea022d16SRodney W. Grimes 	for (np = gettynums; np->field; np++)
194ea022d16SRodney W. Grimes 		if (!np->set)
195ea022d16SRodney W. Grimes 			np->value = np->defalt;
196ea022d16SRodney W. Grimes 	for (fp = gettyflags; fp->field; fp++)
197ea022d16SRodney W. Grimes 		if (!fp->set)
198ea022d16SRodney W. Grimes 			fp->value = fp->defalt;
199ea022d16SRodney W. Grimes }
200ea022d16SRodney W. Grimes 
201ea022d16SRodney W. Grimes static char **
202ea022d16SRodney W. Grimes charnames[] = {
203ea022d16SRodney W. Grimes 	&ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
204ea022d16SRodney W. Grimes 	&SU, &DS, &RP, &FL, &WE, &LN, 0
205ea022d16SRodney W. Grimes };
206ea022d16SRodney W. Grimes 
207ea022d16SRodney W. Grimes static char *
208ea022d16SRodney W. Grimes charvars[] = {
209cae66988SJoerg Wunsch 	&tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR],
210cae66988SJoerg Wunsch 	&tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP],
211cae66988SJoerg Wunsch 	&tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP],
212cae66988SJoerg Wunsch 	&tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD],
213bc13b10eSPedro F. Giffuni 	&tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], 0
214ea022d16SRodney W. Grimes };
215ea022d16SRodney W. Grimes 
216cae66988SJoerg Wunsch void
21795289b27SWarner Losh setchars(void)
218ea022d16SRodney W. Grimes {
21995289b27SWarner Losh 	int i;
22095289b27SWarner Losh 	const char *p;
221ea022d16SRodney W. Grimes 
222ea022d16SRodney W. Grimes 	for (i = 0; charnames[i]; i++) {
223ea022d16SRodney W. Grimes 		p = *charnames[i];
224ea022d16SRodney W. Grimes 		if (p && *p)
225ea022d16SRodney W. Grimes 			*charvars[i] = *p;
226ea022d16SRodney W. Grimes 		else
227cae66988SJoerg Wunsch 			*charvars[i] = _POSIX_VDISABLE;
228ea022d16SRodney W. Grimes 	}
229ea022d16SRodney W. Grimes }
230ea022d16SRodney W. Grimes 
231cae66988SJoerg Wunsch /* Macros to clear/set/test flags. */
232cae66988SJoerg Wunsch #define	SET(t, f)	(t) |= (f)
233cae66988SJoerg Wunsch #define	CLR(t, f)	(t) &= ~(f)
234cae66988SJoerg Wunsch #define	ISSET(t, f)	((t) & (f))
235cae66988SJoerg Wunsch 
236cae66988SJoerg Wunsch void
23795289b27SWarner Losh set_flags(int n)
238ea022d16SRodney W. Grimes {
23995289b27SWarner Losh 	tcflag_t iflag, oflag, cflag, lflag;
240cae66988SJoerg Wunsch 
241ea022d16SRodney W. Grimes 
242ea022d16SRodney W. Grimes 	switch (n) {
243ea022d16SRodney W. Grimes 	case 0:
244cae66988SJoerg Wunsch 		if (C0set && I0set && L0set && O0set) {
245cae66988SJoerg Wunsch 			tmode.c_cflag = C0;
246cae66988SJoerg Wunsch 			tmode.c_iflag = I0;
247cae66988SJoerg Wunsch 			tmode.c_lflag = L0;
248cae66988SJoerg Wunsch 			tmode.c_oflag = O0;
249cae66988SJoerg Wunsch 			return;
250cae66988SJoerg Wunsch 		}
251ea022d16SRodney W. Grimes 		break;
252ea022d16SRodney W. Grimes 	case 1:
253cae66988SJoerg Wunsch 		if (C1set && I1set && L1set && O1set) {
254cae66988SJoerg Wunsch 			tmode.c_cflag = C1;
255cae66988SJoerg Wunsch 			tmode.c_iflag = I1;
256cae66988SJoerg Wunsch 			tmode.c_lflag = L1;
257cae66988SJoerg Wunsch 			tmode.c_oflag = O1;
258cae66988SJoerg Wunsch 			return;
259cae66988SJoerg Wunsch 		}
260ea022d16SRodney W. Grimes 		break;
261ea022d16SRodney W. Grimes 	default:
262cae66988SJoerg Wunsch 		if (C2set && I2set && L2set && O2set) {
263cae66988SJoerg Wunsch 			tmode.c_cflag = C2;
264cae66988SJoerg Wunsch 			tmode.c_iflag = I2;
265cae66988SJoerg Wunsch 			tmode.c_lflag = L2;
266cae66988SJoerg Wunsch 			tmode.c_oflag = O2;
267cae66988SJoerg Wunsch 			return;
268cae66988SJoerg Wunsch 		}
269ea022d16SRodney W. Grimes 		break;
270ea022d16SRodney W. Grimes 	}
271ea022d16SRodney W. Grimes 
272cae66988SJoerg Wunsch 	iflag = omode.c_iflag;
273cae66988SJoerg Wunsch 	oflag = omode.c_oflag;
274cae66988SJoerg Wunsch 	cflag = omode.c_cflag;
275cae66988SJoerg Wunsch 	lflag = omode.c_lflag;
276ea022d16SRodney W. Grimes 
277cae66988SJoerg Wunsch 	if (NP) {
278cae66988SJoerg Wunsch 		CLR(cflag, CSIZE|PARENB);
279cae66988SJoerg Wunsch 		SET(cflag, CS8);
280cae66988SJoerg Wunsch 		CLR(iflag, ISTRIP|INPCK|IGNPAR);
281cae66988SJoerg Wunsch 	} else if (AP || EP || OP) {
282cae66988SJoerg Wunsch 		CLR(cflag, CSIZE);
283cae66988SJoerg Wunsch 		SET(cflag, CS7|PARENB);
284cae66988SJoerg Wunsch 		SET(iflag, ISTRIP);
285cae66988SJoerg Wunsch 		if (OP && !EP) {
286cae66988SJoerg Wunsch 			SET(iflag, INPCK|IGNPAR);
287cae66988SJoerg Wunsch 			SET(cflag, PARODD);
288ea022d16SRodney W. Grimes 			if (AP)
289cae66988SJoerg Wunsch 				CLR(iflag, INPCK);
290cae66988SJoerg Wunsch 		} else if (EP && !OP) {
291cae66988SJoerg Wunsch 			SET(iflag, INPCK|IGNPAR);
292cae66988SJoerg Wunsch 			CLR(cflag, PARODD);
293cae66988SJoerg Wunsch 			if (AP)
294cae66988SJoerg Wunsch 				CLR(iflag, INPCK);
295cae66988SJoerg Wunsch 		} else if (AP || (EP && OP)) {
296cae66988SJoerg Wunsch 			CLR(iflag, INPCK|IGNPAR);
297cae66988SJoerg Wunsch 			CLR(cflag, PARODD);
298cae66988SJoerg Wunsch 		}
299cae66988SJoerg Wunsch 	} /* else, leave as is */
300ea022d16SRodney W. Grimes 
301cae66988SJoerg Wunsch #if 0
302ea022d16SRodney W. Grimes 	if (UC)
303ea022d16SRodney W. Grimes 		f |= LCASE;
304cae66988SJoerg Wunsch #endif
305ea022d16SRodney W. Grimes 
306cae66988SJoerg Wunsch 	if (HC)
307cae66988SJoerg Wunsch 		SET(cflag, HUPCL);
308ea022d16SRodney W. Grimes 	else
309cae66988SJoerg Wunsch 		CLR(cflag, HUPCL);
310cae66988SJoerg Wunsch 
311cae66988SJoerg Wunsch 	if (MB)
312cae66988SJoerg Wunsch 		SET(cflag, MDMBUF);
313cae66988SJoerg Wunsch 	else
314cae66988SJoerg Wunsch 		CLR(cflag, MDMBUF);
315cae66988SJoerg Wunsch 
316fe552114SDavid Nugent 	if (HW)
317fe552114SDavid Nugent 		SET(cflag, CRTSCTS);
318fe552114SDavid Nugent 	else
319fe552114SDavid Nugent 		CLR(cflag, CRTSCTS);
320fe552114SDavid Nugent 
321cae66988SJoerg Wunsch 	if (NL) {
322cae66988SJoerg Wunsch 		SET(iflag, ICRNL);
323cae66988SJoerg Wunsch 		SET(oflag, ONLCR|OPOST);
324cae66988SJoerg Wunsch 	} else {
325cae66988SJoerg Wunsch 		CLR(iflag, ICRNL);
326cae66988SJoerg Wunsch 		CLR(oflag, ONLCR);
327ea022d16SRodney W. Grimes 	}
328ea022d16SRodney W. Grimes 
329ea022d16SRodney W. Grimes 	if (!HT)
330cae66988SJoerg Wunsch 		SET(oflag, OXTABS|OPOST);
331cae66988SJoerg Wunsch 	else
332cae66988SJoerg Wunsch 		CLR(oflag, OXTABS);
333ea022d16SRodney W. Grimes 
334cae66988SJoerg Wunsch #ifdef XXX_DELAY
335cae66988SJoerg Wunsch 	SET(f, delaybits());
336cae66988SJoerg Wunsch #endif
337ea022d16SRodney W. Grimes 
338cae66988SJoerg Wunsch 	if (n == 1) {		/* read mode flags */
339cae66988SJoerg Wunsch 		if (RW) {
340cae66988SJoerg Wunsch 			iflag = 0;
341cae66988SJoerg Wunsch 			CLR(oflag, OPOST);
342cae66988SJoerg Wunsch 			CLR(cflag, CSIZE|PARENB);
343cae66988SJoerg Wunsch 			SET(cflag, CS8);
344cae66988SJoerg Wunsch 			lflag = 0;
345cae66988SJoerg Wunsch 		} else {
346cae66988SJoerg Wunsch 			CLR(lflag, ICANON);
347cae66988SJoerg Wunsch 		}
348cae66988SJoerg Wunsch 		goto out;
349ea022d16SRodney W. Grimes 	}
350ea022d16SRodney W. Grimes 
351cae66988SJoerg Wunsch 	if (n == 0)
352cae66988SJoerg Wunsch 		goto out;
353cae66988SJoerg Wunsch 
354cae66988SJoerg Wunsch #if 0
355cae66988SJoerg Wunsch 	if (CB)
356cae66988SJoerg Wunsch 		SET(f, CRTBS);
357cae66988SJoerg Wunsch #endif
358cae66988SJoerg Wunsch 
359cae66988SJoerg Wunsch 	if (CE)
360cae66988SJoerg Wunsch 		SET(lflag, ECHOE);
361cae66988SJoerg Wunsch 	else
362cae66988SJoerg Wunsch 		CLR(lflag, ECHOE);
363cae66988SJoerg Wunsch 
364cae66988SJoerg Wunsch 	if (CK)
365cae66988SJoerg Wunsch 		SET(lflag, ECHOKE);
366cae66988SJoerg Wunsch 	else
367cae66988SJoerg Wunsch 		CLR(lflag, ECHOKE);
368cae66988SJoerg Wunsch 
369cae66988SJoerg Wunsch 	if (PE)
370cae66988SJoerg Wunsch 		SET(lflag, ECHOPRT);
371cae66988SJoerg Wunsch 	else
372cae66988SJoerg Wunsch 		CLR(lflag, ECHOPRT);
373cae66988SJoerg Wunsch 
374cae66988SJoerg Wunsch 	if (EC)
375cae66988SJoerg Wunsch 		SET(lflag, ECHO);
376cae66988SJoerg Wunsch 	else
377cae66988SJoerg Wunsch 		CLR(lflag, ECHO);
378cae66988SJoerg Wunsch 
379cae66988SJoerg Wunsch 	if (XC)
380cae66988SJoerg Wunsch 		SET(lflag, ECHOCTL);
381cae66988SJoerg Wunsch 	else
382cae66988SJoerg Wunsch 		CLR(lflag, ECHOCTL);
383cae66988SJoerg Wunsch 
384cae66988SJoerg Wunsch 	if (DX)
385cae66988SJoerg Wunsch 		SET(lflag, IXANY);
386cae66988SJoerg Wunsch 	else
387cae66988SJoerg Wunsch 		CLR(lflag, IXANY);
388cae66988SJoerg Wunsch 
389cae66988SJoerg Wunsch out:
390cae66988SJoerg Wunsch 	tmode.c_iflag = iflag;
391cae66988SJoerg Wunsch 	tmode.c_oflag = oflag;
392cae66988SJoerg Wunsch 	tmode.c_cflag = cflag;
393cae66988SJoerg Wunsch 	tmode.c_lflag = lflag;
394cae66988SJoerg Wunsch }
395cae66988SJoerg Wunsch 
396cae66988SJoerg Wunsch 
397cae66988SJoerg Wunsch #ifdef XXX_DELAY
398ea022d16SRodney W. Grimes struct delayval {
399ea022d16SRodney W. Grimes 	unsigned	delay;		/* delay in ms */
400ea022d16SRodney W. Grimes 	int		bits;
401ea022d16SRodney W. Grimes };
402ea022d16SRodney W. Grimes 
403ea022d16SRodney W. Grimes /*
404ea022d16SRodney W. Grimes  * below are random guesses, I can't be bothered checking
405ea022d16SRodney W. Grimes  */
406ea022d16SRodney W. Grimes 
407ea022d16SRodney W. Grimes struct delayval	crdelay[] = {
408cae66988SJoerg Wunsch 	{ 1,		CR1 },
409cae66988SJoerg Wunsch 	{ 2,		CR2 },
410cae66988SJoerg Wunsch 	{ 3,		CR3 },
411cae66988SJoerg Wunsch 	{ 83,		CR1 },
412cae66988SJoerg Wunsch 	{ 166,		CR2 },
413cae66988SJoerg Wunsch 	{ 0,		CR3 },
414ea022d16SRodney W. Grimes };
415ea022d16SRodney W. Grimes 
416ea022d16SRodney W. Grimes struct delayval nldelay[] = {
417cae66988SJoerg Wunsch 	{ 1,		NL1 },		/* special, calculated */
418cae66988SJoerg Wunsch 	{ 2,		NL2 },
419cae66988SJoerg Wunsch 	{ 3,		NL3 },
420cae66988SJoerg Wunsch 	{ 100,		NL2 },
421cae66988SJoerg Wunsch 	{ 0,		NL3 },
422ea022d16SRodney W. Grimes };
423ea022d16SRodney W. Grimes 
424ea022d16SRodney W. Grimes struct delayval	bsdelay[] = {
425cae66988SJoerg Wunsch 	{ 1,		BS1 },
426cae66988SJoerg Wunsch 	{ 0,		0 },
427ea022d16SRodney W. Grimes };
428ea022d16SRodney W. Grimes 
429ea022d16SRodney W. Grimes struct delayval	ffdelay[] = {
430cae66988SJoerg Wunsch 	{ 1,		FF1 },
431cae66988SJoerg Wunsch 	{ 1750,		FF1 },
432cae66988SJoerg Wunsch 	{ 0,		FF1 },
433ea022d16SRodney W. Grimes };
434ea022d16SRodney W. Grimes 
435ea022d16SRodney W. Grimes struct delayval	tbdelay[] = {
436cae66988SJoerg Wunsch 	{ 1,		TAB1 },
437cae66988SJoerg Wunsch 	{ 2,		TAB2 },
438cae66988SJoerg Wunsch 	{ 3,		XTABS },	/* this is expand tabs */
439cae66988SJoerg Wunsch 	{ 100,		TAB1 },
440cae66988SJoerg Wunsch 	{ 0,		TAB2 },
441ea022d16SRodney W. Grimes };
442ea022d16SRodney W. Grimes 
443cae66988SJoerg Wunsch int
44495289b27SWarner Losh delaybits(void)
445ea022d16SRodney W. Grimes {
44695289b27SWarner Losh 	int f;
447ea022d16SRodney W. Grimes 
448ea022d16SRodney W. Grimes 	f  = adelay(CD, crdelay);
449ea022d16SRodney W. Grimes 	f |= adelay(ND, nldelay);
450ea022d16SRodney W. Grimes 	f |= adelay(FD, ffdelay);
451ea022d16SRodney W. Grimes 	f |= adelay(TD, tbdelay);
452ea022d16SRodney W. Grimes 	f |= adelay(BD, bsdelay);
453ea022d16SRodney W. Grimes 	return (f);
454ea022d16SRodney W. Grimes }
455ea022d16SRodney W. Grimes 
456cae66988SJoerg Wunsch int
45795289b27SWarner Losh adelay(int ms, struct delayval *dp)
458ea022d16SRodney W. Grimes {
459ea022d16SRodney W. Grimes 	if (ms == 0)
460ea022d16SRodney W. Grimes 		return (0);
461ea022d16SRodney W. Grimes 	while (dp->delay && ms > dp->delay)
462ea022d16SRodney W. Grimes 		dp++;
463ea022d16SRodney W. Grimes 	return (dp->bits);
464ea022d16SRodney W. Grimes }
465cae66988SJoerg Wunsch #endif
466ea022d16SRodney W. Grimes 
467c568fce9SAndrey A. Chernov char	editedhost[MAXHOSTNAMELEN];
468ea022d16SRodney W. Grimes 
469cae66988SJoerg Wunsch void
470f73ff060SAlexey Dokuchaev edithost(const char *pattern)
471ea022d16SRodney W. Grimes {
472f73ff060SAlexey Dokuchaev 	regex_t regex;
473f73ff060SAlexey Dokuchaev 	regmatch_t *match;
474f73ff060SAlexey Dokuchaev 	int found;
475ea022d16SRodney W. Grimes 
476f73ff060SAlexey Dokuchaev 	if (pattern == NULL || *pattern == '\0')
477f73ff060SAlexey Dokuchaev 		goto copyasis;
478f73ff060SAlexey Dokuchaev 	if (regcomp(&regex, pattern, REG_EXTENDED) != 0)
479f73ff060SAlexey Dokuchaev 		goto copyasis;
480ea022d16SRodney W. Grimes 
481f73ff060SAlexey Dokuchaev 	match = calloc(regex.re_nsub + 1, sizeof(*match));
482f73ff060SAlexey Dokuchaev 	if (match == NULL) {
483f73ff060SAlexey Dokuchaev 		regfree(&regex);
484f73ff060SAlexey Dokuchaev 		goto copyasis;
485ea022d16SRodney W. Grimes 	}
486f73ff060SAlexey Dokuchaev 
487f73ff060SAlexey Dokuchaev 	found = !regexec(&regex, HN, regex.re_nsub + 1, match, 0);
488f73ff060SAlexey Dokuchaev 	if (found) {
489f73ff060SAlexey Dokuchaev 		size_t subex, totalsize;
490f73ff060SAlexey Dokuchaev 
491f73ff060SAlexey Dokuchaev 		/*
492f73ff060SAlexey Dokuchaev 		 * We found a match.  If there were no parenthesized
493f73ff060SAlexey Dokuchaev 		 * subexpressions in the pattern, use entire matched
494f73ff060SAlexey Dokuchaev 		 * string as ``editedhost''; otherwise use the first
495f73ff060SAlexey Dokuchaev 		 * matched subexpression.
496f73ff060SAlexey Dokuchaev 		 */
497f73ff060SAlexey Dokuchaev 		subex = !!regex.re_nsub;
498f73ff060SAlexey Dokuchaev 		totalsize = match[subex].rm_eo - match[subex].rm_so + 1;
499f73ff060SAlexey Dokuchaev 		strlcpy(editedhost, HN + match[subex].rm_so, totalsize >
500f73ff060SAlexey Dokuchaev 		    sizeof(editedhost) ? sizeof(editedhost) : totalsize);
501f73ff060SAlexey Dokuchaev 	}
502f73ff060SAlexey Dokuchaev 	free(match);
503f73ff060SAlexey Dokuchaev 	regfree(&regex);
504f73ff060SAlexey Dokuchaev 	if (found)
505ea022d16SRodney W. Grimes 		return;
506f73ff060SAlexey Dokuchaev 	/*
507f73ff060SAlexey Dokuchaev 	 * In case of any errors, or if the pattern did not match, pass
508f73ff060SAlexey Dokuchaev 	 * the original hostname as is.
509f73ff060SAlexey Dokuchaev 	 */
510f73ff060SAlexey Dokuchaev  copyasis:
511f73ff060SAlexey Dokuchaev 	strlcpy(editedhost, HN, sizeof(editedhost));
512ea022d16SRodney W. Grimes }
513ea022d16SRodney W. Grimes 
514cae66988SJoerg Wunsch static struct speedtab {
515ea022d16SRodney W. Grimes 	int	speed;
516ea022d16SRodney W. Grimes 	int	uxname;
517ea022d16SRodney W. Grimes } speedtab[] = {
518cae66988SJoerg Wunsch 	{ 50,	B50 },
519cae66988SJoerg Wunsch 	{ 75,	B75 },
520cae66988SJoerg Wunsch 	{ 110,	B110 },
521cae66988SJoerg Wunsch 	{ 134,	B134 },
522cae66988SJoerg Wunsch 	{ 150,	B150 },
523cae66988SJoerg Wunsch 	{ 200,	B200 },
524cae66988SJoerg Wunsch 	{ 300,	B300 },
525cae66988SJoerg Wunsch 	{ 600,	B600 },
526cae66988SJoerg Wunsch 	{ 1200,	B1200 },
527cae66988SJoerg Wunsch 	{ 1800,	B1800 },
528cae66988SJoerg Wunsch 	{ 2400,	B2400 },
529cae66988SJoerg Wunsch 	{ 4800,	B4800 },
530cae66988SJoerg Wunsch 	{ 9600,	B9600 },
531cae66988SJoerg Wunsch 	{ 19200, EXTA },
532cae66988SJoerg Wunsch 	{ 19,	EXTA },		/* for people who say 19.2K */
533cae66988SJoerg Wunsch 	{ 38400, EXTB },
534cae66988SJoerg Wunsch 	{ 38,	EXTB },
535cae66988SJoerg Wunsch 	{ 7200,	EXTB },		/* alternative */
536cae66988SJoerg Wunsch 	{ 57600, B57600 },
537cae66988SJoerg Wunsch 	{ 115200, B115200 },
538ee98a93fSPoul-Henning Kamp 	{ 230400, B230400 },
5391776dc9fSEdward Tomasz Napierala 	{ 0, 0 }
540ea022d16SRodney W. Grimes };
541ea022d16SRodney W. Grimes 
542cae66988SJoerg Wunsch int
54395289b27SWarner Losh speed(int val)
544ea022d16SRodney W. Grimes {
54595289b27SWarner Losh 	struct speedtab *sp;
546ea022d16SRodney W. Grimes 
547ee98a93fSPoul-Henning Kamp 	if (val <= B230400)
548ea022d16SRodney W. Grimes 		return (val);
549ea022d16SRodney W. Grimes 
550ea022d16SRodney W. Grimes 	for (sp = speedtab; sp->speed; sp++)
551ea022d16SRodney W. Grimes 		if (sp->speed == val)
552ea022d16SRodney W. Grimes 			return (sp->uxname);
553ea022d16SRodney W. Grimes 
554ea022d16SRodney W. Grimes 	return (B300);		/* default in impossible cases */
555ea022d16SRodney W. Grimes }
556ea022d16SRodney W. Grimes 
557cae66988SJoerg Wunsch void
55895289b27SWarner Losh makeenv(char *env[])
559ea022d16SRodney W. Grimes {
560ea022d16SRodney W. Grimes 	static char termbuf[128] = "TERM=";
56195289b27SWarner Losh 	char *p, *q;
56295289b27SWarner Losh 	char **ep;
563ea022d16SRodney W. Grimes 
564ea022d16SRodney W. Grimes 	ep = env;
565ea022d16SRodney W. Grimes 	if (TT && *TT) {
5666e76e16fSKris Kennaway 		strlcat(termbuf, TT, sizeof(termbuf));
567ea022d16SRodney W. Grimes 		*ep++ = termbuf;
568ea022d16SRodney W. Grimes 	}
569cae66988SJoerg Wunsch 	if ((p = EV)) {
570ea022d16SRodney W. Grimes 		q = p;
571cae66988SJoerg Wunsch 		while ((q = strchr(q, ','))) {
572ea022d16SRodney W. Grimes 			*q++ = '\0';
573ea022d16SRodney W. Grimes 			*ep++ = p;
574ea022d16SRodney W. Grimes 			p = q;
575ea022d16SRodney W. Grimes 		}
576ea022d16SRodney W. Grimes 		if (*p)
577ea022d16SRodney W. Grimes 			*ep++ = p;
578ea022d16SRodney W. Grimes 	}
579ea022d16SRodney W. Grimes 	*ep = (char *)0;
580ea022d16SRodney W. Grimes }
581ea022d16SRodney W. Grimes 
582ea022d16SRodney W. Grimes /*
583ea022d16SRodney W. Grimes  * This speed select mechanism is written for the Develcon DATASWITCH.
584ea022d16SRodney W. Grimes  * The Develcon sends a string of the form "B{speed}\n" at a predefined
585ea022d16SRodney W. Grimes  * baud rate. This string indicates the user's actual speed.
586ea022d16SRodney W. Grimes  * The routine below returns the terminal type mapped from derived speed.
587ea022d16SRodney W. Grimes  */
5889c33cc93SEdward Tomasz Napierala static struct	portselect {
589cae66988SJoerg Wunsch 	const char	*ps_baud;
590cae66988SJoerg Wunsch 	const char	*ps_type;
591ea022d16SRodney W. Grimes } portspeeds[] = {
592ea022d16SRodney W. Grimes 	{ "B110",	"std.110" },
593ea022d16SRodney W. Grimes 	{ "B134",	"std.134" },
594ea022d16SRodney W. Grimes 	{ "B150",	"std.150" },
595ea022d16SRodney W. Grimes 	{ "B300",	"std.300" },
596ea022d16SRodney W. Grimes 	{ "B600",	"std.600" },
597ea022d16SRodney W. Grimes 	{ "B1200",	"std.1200" },
598ea022d16SRodney W. Grimes 	{ "B2400",	"std.2400" },
599ea022d16SRodney W. Grimes 	{ "B4800",	"std.4800" },
600ea022d16SRodney W. Grimes 	{ "B9600",	"std.9600" },
601ea022d16SRodney W. Grimes 	{ "B19200",	"std.19200" },
60273906f57SPedro F. Giffuni 	{ NULL, NULL }
603ea022d16SRodney W. Grimes };
604ea022d16SRodney W. Grimes 
605cae66988SJoerg Wunsch const char *
60695289b27SWarner Losh portselector(void)
607ea022d16SRodney W. Grimes {
608cae66988SJoerg Wunsch 	char c, baud[20];
609cae66988SJoerg Wunsch 	const char *type = "default";
61095289b27SWarner Losh 	struct portselect *ps;
61173906f57SPedro F. Giffuni 	size_t len;
612ea022d16SRodney W. Grimes 
613ea022d16SRodney W. Grimes 	alarm(5*60);
614ea022d16SRodney W. Grimes 	for (len = 0; len < sizeof (baud) - 1; len++) {
615ea022d16SRodney W. Grimes 		if (read(STDIN_FILENO, &c, 1) <= 0)
616ea022d16SRodney W. Grimes 			break;
617ea022d16SRodney W. Grimes 		c &= 0177;
618ea022d16SRodney W. Grimes 		if (c == '\n' || c == '\r')
619ea022d16SRodney W. Grimes 			break;
620ea022d16SRodney W. Grimes 		if (c == 'B')
621ea022d16SRodney W. Grimes 			len = 0;	/* in case of leading garbage */
622ea022d16SRodney W. Grimes 		baud[len] = c;
623ea022d16SRodney W. Grimes 	}
624ea022d16SRodney W. Grimes 	baud[len] = '\0';
625ea022d16SRodney W. Grimes 	for (ps = portspeeds; ps->ps_baud; ps++)
626ea022d16SRodney W. Grimes 		if (strcmp(ps->ps_baud, baud) == 0) {
627ea022d16SRodney W. Grimes 			type = ps->ps_type;
628ea022d16SRodney W. Grimes 			break;
629ea022d16SRodney W. Grimes 		}
630ea022d16SRodney W. Grimes 	sleep(2);	/* wait for connection to complete */
631ea022d16SRodney W. Grimes 	return (type);
632ea022d16SRodney W. Grimes }
633ea022d16SRodney W. Grimes 
634ea022d16SRodney W. Grimes /*
635ea022d16SRodney W. Grimes  * This auto-baud speed select mechanism is written for the Micom 600
636ea022d16SRodney W. Grimes  * portselector. Selection is done by looking at how the character '\r'
637ea022d16SRodney W. Grimes  * is garbled at the different speeds.
638ea022d16SRodney W. Grimes  */
639cae66988SJoerg Wunsch const char *
64095289b27SWarner Losh autobaud(void)
641ea022d16SRodney W. Grimes {
642a3e4b982SPedro F. Giffuni 	struct pollfd set[1];
643a3e4b982SPedro F. Giffuni 	struct timespec timeout;
644cae66988SJoerg Wunsch 	char c;
645cae66988SJoerg Wunsch 	const char *type = "9600-baud";
646ea022d16SRodney W. Grimes 
647cae66988SJoerg Wunsch 	(void)tcflush(0, TCIOFLUSH);
648a3e4b982SPedro F. Giffuni 	set[0].fd = STDIN_FILENO;
649a3e4b982SPedro F. Giffuni 	set[0].events = POLLIN;
650a3e4b982SPedro F. Giffuni 	if (poll(set, 1, 5000) <= 0)
651ea022d16SRodney W. Grimes 		return (type);
652ea022d16SRodney W. Grimes 	if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
653ea022d16SRodney W. Grimes 		return (type);
654ea022d16SRodney W. Grimes 	timeout.tv_sec = 0;
655a3e4b982SPedro F. Giffuni 	timeout.tv_nsec = 20000;
656a3e4b982SPedro F. Giffuni 	(void)nanosleep(&timeout, NULL);
657cae66988SJoerg Wunsch 	(void)tcflush(0, TCIOFLUSH);
658ea022d16SRodney W. Grimes 	switch (c & 0377) {
659ea022d16SRodney W. Grimes 
660ea022d16SRodney W. Grimes 	case 0200:		/* 300-baud */
661ea022d16SRodney W. Grimes 		type = "300-baud";
662ea022d16SRodney W. Grimes 		break;
663ea022d16SRodney W. Grimes 
664ea022d16SRodney W. Grimes 	case 0346:		/* 1200-baud */
665ea022d16SRodney W. Grimes 		type = "1200-baud";
666ea022d16SRodney W. Grimes 		break;
667ea022d16SRodney W. Grimes 
668ea022d16SRodney W. Grimes 	case  015:		/* 2400-baud */
669ea022d16SRodney W. Grimes 	case 0215:
670ea022d16SRodney W. Grimes 		type = "2400-baud";
671ea022d16SRodney W. Grimes 		break;
672ea022d16SRodney W. Grimes 
673ea022d16SRodney W. Grimes 	default:		/* 4800-baud */
674ea022d16SRodney W. Grimes 		type = "4800-baud";
675ea022d16SRodney W. Grimes 		break;
676ea022d16SRodney W. Grimes 
677ea022d16SRodney W. Grimes 	case 0377:		/* 9600-baud */
678ea022d16SRodney W. Grimes 		type = "9600-baud";
679ea022d16SRodney W. Grimes 		break;
680ea022d16SRodney W. Grimes 	}
681ea022d16SRodney W. Grimes 	return (type);
682ea022d16SRodney W. Grimes }
683