subr.c revision 22208
11592Srgrimes/*
215645Sjoerg * Copyright (c) 1983, 1993
315645Sjoerg *	The Regents of the University of California.  All rights reserved.
41592Srgrimes *
51592Srgrimes * Redistribution and use in source and binary forms, with or without
61592Srgrimes * modification, are permitted provided that the following conditions
71592Srgrimes * are met:
81592Srgrimes * 1. Redistributions of source code must retain the above copyright
91592Srgrimes *    notice, this list of conditions and the following disclaimer.
101592Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111592Srgrimes *    notice, this list of conditions and the following disclaimer in the
121592Srgrimes *    documentation and/or other materials provided with the distribution.
131592Srgrimes * 3. All advertising materials mentioning features or use of this software
141592Srgrimes *    must display the following acknowledgement:
151592Srgrimes *	This product includes software developed by the University of
161592Srgrimes *	California, Berkeley and its contributors.
171592Srgrimes * 4. Neither the name of the University nor the names of its contributors
181592Srgrimes *    may be used to endorse or promote products derived from this software
191592Srgrimes *    without specific prior written permission.
201592Srgrimes *
211592Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221592Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231592Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241592Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251592Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261592Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271592Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281592Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291592Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301592Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311592Srgrimes * SUCH DAMAGE.
321592Srgrimes */
331592Srgrimes
341592Srgrimes#ifndef lint
3515645Sjoerg/*static char sccsid[] = "from: @(#)subr.c	8.1 (Berkeley) 6/4/93";*/
3621673Sjkhstatic char rcsid[] = "$FreeBSD: head/libexec/getty/subr.c 22208 1997-02-02 14:24:57Z davidn $";
371592Srgrimes#endif /* not lint */
381592Srgrimes
391592Srgrimes/*
401592Srgrimes * Melbourne getty.
411592Srgrimes */
4215645Sjoerg#define COMPAT_43
4315645Sjoerg#include <stdlib.h>
442286Sjkh#include <unistd.h>
451592Srgrimes#include <string.h>
4615645Sjoerg#include <termios.h>
4715645Sjoerg#include <sys/ioctl.h>
4815645Sjoerg#include <sys/param.h>
4915645Sjoerg#ifdef DEBUG
5015645Sjoerg#include <stdio.h>
5115645Sjoerg#endif
5215645Sjoerg
531592Srgrimes#include "gettytab.h"
5415645Sjoerg#include "pathnames.h"
5515645Sjoerg#include "extern.h"
561592Srgrimes
571592Srgrimes
5815645Sjoerg#ifdef COMPAT_43
5915645Sjoergstatic void	compatflags __P((long));
6015645Sjoerg#endif
6115645Sjoerg
621592Srgrimes/*
631592Srgrimes * Get a table entry.
641592Srgrimes */
6515645Sjoergvoid
6615645Sjoerggettable(name, buf)
6715645Sjoerg	const char *name;
6815645Sjoerg	char *buf;
691592Srgrimes{
701592Srgrimes	register struct gettystrs *sp;
711592Srgrimes	register struct gettynums *np;
721592Srgrimes	register struct gettyflags *fp;
7315645Sjoerg	long n;
7415645Sjoerg	const char *dba[2];
7515645Sjoerg	dba[0] = _PATH_GETTYTAB;
7615645Sjoerg	dba[1] = 0;
771592Srgrimes
7815645Sjoerg	if (cgetent(&buf, dba, name) != 0)
791592Srgrimes		return;
801592Srgrimes
812286Sjkh	for (sp = gettystrs; sp->field; sp++)
8215645Sjoerg		cgetstr(buf, sp->field, &sp->value);
831592Srgrimes	for (np = gettynums; np->field; np++) {
8415645Sjoerg		if (cgetnum(buf, np->field, &n) == -1)
851592Srgrimes			np->set = 0;
861592Srgrimes		else {
871592Srgrimes			np->set = 1;
881592Srgrimes			np->value = n;
891592Srgrimes		}
901592Srgrimes	}
911592Srgrimes	for (fp = gettyflags; fp->field; fp++) {
9215645Sjoerg		if (cgetcap(buf, fp->field, ':') == NULL)
931592Srgrimes			fp->set = 0;
941592Srgrimes		else {
951592Srgrimes			fp->set = 1;
9615645Sjoerg			fp->value = 1 ^ fp->invrt;
971592Srgrimes		}
981592Srgrimes	}
9915645Sjoerg#ifdef DEBUG
10015645Sjoerg	printf("name=\"%s\", buf=\"%s\"\r\n", name, buf);
10115645Sjoerg	for (sp = gettystrs; sp->field; sp++)
10215645Sjoerg		printf("cgetstr: %s=%s\r\n", sp->field, sp->value);
10315645Sjoerg	for (np = gettynums; np->field; np++)
10415645Sjoerg		printf("cgetnum: %s=%d\r\n", np->field, np->value);
10515645Sjoerg	for (fp = gettyflags; fp->field; fp++)
10615645Sjoerg		printf("cgetflags: %s='%c' set='%c'\r\n", fp->field,
10715645Sjoerg		       fp->value + '0', fp->set + '0');
10815645Sjoerg#endif /* DEBUG */
1091592Srgrimes}
1101592Srgrimes
11115645Sjoergvoid
1121592Srgrimesgendefaults()
1131592Srgrimes{
1141592Srgrimes	register struct gettystrs *sp;
1151592Srgrimes	register struct gettynums *np;
1161592Srgrimes	register struct gettyflags *fp;
1171592Srgrimes
1181592Srgrimes	for (sp = gettystrs; sp->field; sp++)
1191592Srgrimes		if (sp->value)
1201592Srgrimes			sp->defalt = sp->value;
1211592Srgrimes	for (np = gettynums; np->field; np++)
1221592Srgrimes		if (np->set)
1231592Srgrimes			np->defalt = np->value;
1241592Srgrimes	for (fp = gettyflags; fp->field; fp++)
1251592Srgrimes		if (fp->set)
1261592Srgrimes			fp->defalt = fp->value;
1271592Srgrimes		else
1281592Srgrimes			fp->defalt = fp->invrt;
1291592Srgrimes}
1301592Srgrimes
13115645Sjoergvoid
1321592Srgrimessetdefaults()
1331592Srgrimes{
1341592Srgrimes	register struct gettystrs *sp;
1351592Srgrimes	register struct gettynums *np;
1361592Srgrimes	register struct gettyflags *fp;
1371592Srgrimes
1381592Srgrimes	for (sp = gettystrs; sp->field; sp++)
1391592Srgrimes		if (!sp->value)
1401592Srgrimes			sp->value = sp->defalt;
1411592Srgrimes	for (np = gettynums; np->field; np++)
1421592Srgrimes		if (!np->set)
1431592Srgrimes			np->value = np->defalt;
1441592Srgrimes	for (fp = gettyflags; fp->field; fp++)
1451592Srgrimes		if (!fp->set)
1461592Srgrimes			fp->value = fp->defalt;
1471592Srgrimes}
1481592Srgrimes
1491592Srgrimesstatic char **
1501592Srgrimescharnames[] = {
1511592Srgrimes	&ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
1521592Srgrimes	&SU, &DS, &RP, &FL, &WE, &LN, 0
1531592Srgrimes};
1541592Srgrimes
1551592Srgrimesstatic char *
1561592Srgrimescharvars[] = {
15715645Sjoerg	&tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR],
15815645Sjoerg	&tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP],
15915645Sjoerg	&tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP],
16015645Sjoerg	&tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD],
16115645Sjoerg	&tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], 0
1621592Srgrimes};
1631592Srgrimes
16415645Sjoergvoid
1651592Srgrimessetchars()
1661592Srgrimes{
1671592Srgrimes	register int i;
16815645Sjoerg	register const char *p;
1691592Srgrimes
1701592Srgrimes	for (i = 0; charnames[i]; i++) {
1711592Srgrimes		p = *charnames[i];
1721592Srgrimes		if (p && *p)
1731592Srgrimes			*charvars[i] = *p;
1741592Srgrimes		else
17515645Sjoerg			*charvars[i] = _POSIX_VDISABLE;
1761592Srgrimes	}
1771592Srgrimes}
1781592Srgrimes
17915645Sjoerg/* Macros to clear/set/test flags. */
18015645Sjoerg#define	SET(t, f)	(t) |= (f)
18115645Sjoerg#define	CLR(t, f)	(t) &= ~(f)
18215645Sjoerg#define	ISSET(t, f)	((t) & (f))
18315645Sjoerg
18415645Sjoergvoid
1851592Srgrimessetflags(n)
18615645Sjoerg	int n;
1871592Srgrimes{
18815645Sjoerg	register tcflag_t iflag, oflag, cflag, lflag;
1891592Srgrimes
19015645Sjoerg#ifdef COMPAT_43
1911592Srgrimes	switch (n) {
1921592Srgrimes	case 0:
19315645Sjoerg		if (F0set) {
19415645Sjoerg			compatflags(F0);
19515645Sjoerg			return;
19615645Sjoerg		}
1971592Srgrimes		break;
1981592Srgrimes	case 1:
19915645Sjoerg		if (F1set) {
20015645Sjoerg			compatflags(F1);
20115645Sjoerg			return;
20215645Sjoerg		}
2031592Srgrimes		break;
2041592Srgrimes	default:
20515645Sjoerg		if (F2set) {
20615645Sjoerg			compatflags(F2);
20715645Sjoerg			return;
20815645Sjoerg		}
2091592Srgrimes		break;
2101592Srgrimes	}
21115645Sjoerg#endif
2121592Srgrimes
21315645Sjoerg	switch (n) {
21415645Sjoerg	case 0:
21515645Sjoerg		if (C0set && I0set && L0set && O0set) {
21615645Sjoerg			tmode.c_cflag = C0;
21715645Sjoerg			tmode.c_iflag = I0;
21815645Sjoerg			tmode.c_lflag = L0;
21915645Sjoerg			tmode.c_oflag = O0;
22015645Sjoerg			return;
22115645Sjoerg		}
22215645Sjoerg		break;
22315645Sjoerg	case 1:
22415645Sjoerg		if (C1set && I1set && L1set && O1set) {
22515645Sjoerg			tmode.c_cflag = C1;
22615645Sjoerg			tmode.c_iflag = I1;
22715645Sjoerg			tmode.c_lflag = L1;
22815645Sjoerg			tmode.c_oflag = O1;
22915645Sjoerg			return;
23015645Sjoerg		}
23115645Sjoerg		break;
23215645Sjoerg	default:
23315645Sjoerg		if (C2set && I2set && L2set && O2set) {
23415645Sjoerg			tmode.c_cflag = C2;
23515645Sjoerg			tmode.c_iflag = I2;
23615645Sjoerg			tmode.c_lflag = L2;
23715645Sjoerg			tmode.c_oflag = O2;
23815645Sjoerg			return;
23915645Sjoerg		}
24015645Sjoerg		break;
24115645Sjoerg	}
2421592Srgrimes
24315645Sjoerg	iflag = omode.c_iflag;
24415645Sjoerg	oflag = omode.c_oflag;
24515645Sjoerg	cflag = omode.c_cflag;
24615645Sjoerg	lflag = omode.c_lflag;
2471592Srgrimes
24815645Sjoerg	if (NP) {
24915645Sjoerg		CLR(cflag, CSIZE|PARENB);
25015645Sjoerg		SET(cflag, CS8);
25115645Sjoerg		CLR(iflag, ISTRIP|INPCK|IGNPAR);
25215645Sjoerg	} else if (AP || EP || OP) {
25315645Sjoerg		CLR(cflag, CSIZE);
25415645Sjoerg		SET(cflag, CS7|PARENB);
25515645Sjoerg		SET(iflag, ISTRIP);
25615645Sjoerg		if (OP && !EP) {
25715645Sjoerg			SET(iflag, INPCK|IGNPAR);
25815645Sjoerg			SET(cflag, PARODD);
25915645Sjoerg			if (AP)
26015645Sjoerg				CLR(iflag, INPCK);
26115645Sjoerg		} else if (EP && !OP) {
26215645Sjoerg			SET(iflag, INPCK|IGNPAR);
26315645Sjoerg			CLR(cflag, PARODD);
26415645Sjoerg			if (AP)
26515645Sjoerg				CLR(iflag, INPCK);
26615645Sjoerg		} else if (AP || (EP && OP)) {
26715645Sjoerg			CLR(iflag, INPCK|IGNPAR);
26815645Sjoerg			CLR(cflag, PARODD);
26915645Sjoerg		}
27015645Sjoerg	} /* else, leave as is */
27115645Sjoerg
27215645Sjoerg#if 0
2731592Srgrimes	if (UC)
2741592Srgrimes		f |= LCASE;
27515645Sjoerg#endif
2761592Srgrimes
27715645Sjoerg	if (HC)
27815645Sjoerg		SET(cflag, HUPCL);
27915645Sjoerg	else
28015645Sjoerg		CLR(cflag, HUPCL);
2811592Srgrimes
28215645Sjoerg	if (MB)
28315645Sjoerg		SET(cflag, MDMBUF);
28415645Sjoerg	else
28515645Sjoerg		CLR(cflag, MDMBUF);
2861592Srgrimes
28722208Sdavidn	if (HW)
28822208Sdavidn		SET(cflag, CRTSCTS);
28922208Sdavidn	else
29022208Sdavidn		CLR(cflag, CRTSCTS);
29122208Sdavidn
29215645Sjoerg	if (NL) {
29315645Sjoerg		SET(iflag, ICRNL);
29415645Sjoerg		SET(oflag, ONLCR|OPOST);
29515645Sjoerg	} else {
29615645Sjoerg		CLR(iflag, ICRNL);
29715645Sjoerg		CLR(oflag, ONLCR);
2981592Srgrimes	}
2991592Srgrimes
3001592Srgrimes	if (!HT)
30115645Sjoerg		SET(oflag, OXTABS|OPOST);
30215645Sjoerg	else
30315645Sjoerg		CLR(oflag, OXTABS);
3041592Srgrimes
30515645Sjoerg#ifdef XXX_DELAY
30615645Sjoerg	SET(f, delaybits());
30715645Sjoerg#endif
30815645Sjoerg
30915645Sjoerg	if (n == 1) {		/* read mode flags */
31015645Sjoerg		if (RW) {
31115645Sjoerg			iflag = 0;
31215645Sjoerg			CLR(oflag, OPOST);
31315645Sjoerg			CLR(cflag, CSIZE|PARENB);
31415645Sjoerg			SET(cflag, CS8);
31515645Sjoerg			lflag = 0;
31615645Sjoerg		} else {
31715645Sjoerg			CLR(lflag, ICANON);
31815645Sjoerg		}
31915645Sjoerg		goto out;
32015645Sjoerg	}
32115645Sjoerg
3221592Srgrimes	if (n == 0)
32315645Sjoerg		goto out;
3241592Srgrimes
32515645Sjoerg#if 0
3261592Srgrimes	if (CB)
32715645Sjoerg		SET(f, CRTBS);
32815645Sjoerg#endif
3291592Srgrimes
3301592Srgrimes	if (CE)
33115645Sjoerg		SET(lflag, ECHOE);
33215645Sjoerg	else
33315645Sjoerg		CLR(lflag, ECHOE);
3341592Srgrimes
3351592Srgrimes	if (CK)
33615645Sjoerg		SET(lflag, ECHOKE);
33715645Sjoerg	else
33815645Sjoerg		CLR(lflag, ECHOKE);
3391592Srgrimes
3401592Srgrimes	if (PE)
34115645Sjoerg		SET(lflag, ECHOPRT);
34215645Sjoerg	else
34315645Sjoerg		CLR(lflag, ECHOPRT);
3441592Srgrimes
3451592Srgrimes	if (EC)
34615645Sjoerg		SET(lflag, ECHO);
34715645Sjoerg	else
34815645Sjoerg		CLR(lflag, ECHO);
3491592Srgrimes
3501592Srgrimes	if (XC)
35115645Sjoerg		SET(lflag, ECHOCTL);
35215645Sjoerg	else
35315645Sjoerg		CLR(lflag, ECHOCTL);
3541592Srgrimes
3551592Srgrimes	if (DX)
35615645Sjoerg		SET(lflag, IXANY);
35715645Sjoerg	else
35815645Sjoerg		CLR(lflag, IXANY);
3591592Srgrimes
36015645Sjoergout:
36115645Sjoerg	tmode.c_iflag = iflag;
36215645Sjoerg	tmode.c_oflag = oflag;
36315645Sjoerg	tmode.c_cflag = cflag;
36415645Sjoerg	tmode.c_lflag = lflag;
3651592Srgrimes}
3661592Srgrimes
36715645Sjoerg#ifdef COMPAT_43
36815645Sjoerg/*
36915645Sjoerg * Old TTY => termios, snatched from <sys/kern/tty_compat.c>
37015645Sjoerg */
37115645Sjoergvoid
37215645Sjoergcompatflags(flags)
37315645Sjoergregister long flags;
37415645Sjoerg{
37515645Sjoerg	register tcflag_t iflag, oflag, cflag, lflag;
37615645Sjoerg
37715645Sjoerg	iflag = BRKINT|ICRNL|IMAXBEL|IXON|IXANY;
37815645Sjoerg	oflag = OPOST|ONLCR|OXTABS;
37915645Sjoerg	cflag = CREAD;
38015645Sjoerg	lflag = ICANON|ISIG|IEXTEN;
38115645Sjoerg
38215645Sjoerg	if (ISSET(flags, TANDEM))
38315645Sjoerg		SET(iflag, IXOFF);
38415645Sjoerg	else
38515645Sjoerg		CLR(iflag, IXOFF);
38615645Sjoerg	if (ISSET(flags, ECHO))
38715645Sjoerg		SET(lflag, ECHO);
38815645Sjoerg	else
38915645Sjoerg		CLR(lflag, ECHO);
39015645Sjoerg	if (ISSET(flags, CRMOD)) {
39115645Sjoerg		SET(iflag, ICRNL);
39215645Sjoerg		SET(oflag, ONLCR);
39315645Sjoerg	} else {
39415645Sjoerg		CLR(iflag, ICRNL);
39515645Sjoerg		CLR(oflag, ONLCR);
39615645Sjoerg	}
39715645Sjoerg	if (ISSET(flags, XTABS))
39815645Sjoerg		SET(oflag, OXTABS);
39915645Sjoerg	else
40015645Sjoerg		CLR(oflag, OXTABS);
40115645Sjoerg
40215645Sjoerg
40315645Sjoerg	if (ISSET(flags, RAW)) {
40415645Sjoerg		iflag &= IXOFF;
40515645Sjoerg		CLR(lflag, ISIG|ICANON|IEXTEN);
40615645Sjoerg		CLR(cflag, PARENB);
40715645Sjoerg	} else {
40815645Sjoerg		SET(iflag, BRKINT|IXON|IMAXBEL);
40915645Sjoerg		SET(lflag, ISIG|IEXTEN);
41015645Sjoerg		if (ISSET(flags, CBREAK))
41115645Sjoerg			CLR(lflag, ICANON);
41215645Sjoerg		else
41315645Sjoerg			SET(lflag, ICANON);
41415645Sjoerg		switch (ISSET(flags, ANYP)) {
41515645Sjoerg		case 0:
41615645Sjoerg			CLR(cflag, PARENB);
41715645Sjoerg			break;
41815645Sjoerg		case ANYP:
41915645Sjoerg			SET(cflag, PARENB);
42015645Sjoerg			CLR(iflag, INPCK);
42115645Sjoerg			break;
42215645Sjoerg		case EVENP:
42315645Sjoerg			SET(cflag, PARENB);
42415645Sjoerg			SET(iflag, INPCK);
42515645Sjoerg			CLR(cflag, PARODD);
42615645Sjoerg			break;
42715645Sjoerg		case ODDP:
42815645Sjoerg			SET(cflag, PARENB);
42915645Sjoerg			SET(iflag, INPCK);
43015645Sjoerg			SET(cflag, PARODD);
43115645Sjoerg			break;
43215645Sjoerg		}
43315645Sjoerg	}
43415645Sjoerg
43515645Sjoerg	/* Nothing we can do with CRTBS. */
43615645Sjoerg	if (ISSET(flags, PRTERA))
43715645Sjoerg		SET(lflag, ECHOPRT);
43815645Sjoerg	else
43915645Sjoerg		CLR(lflag, ECHOPRT);
44015645Sjoerg	if (ISSET(flags, CRTERA))
44115645Sjoerg		SET(lflag, ECHOE);
44215645Sjoerg	else
44315645Sjoerg		CLR(lflag, ECHOE);
44415645Sjoerg	/* Nothing we can do with TILDE. */
44515645Sjoerg	if (ISSET(flags, MDMBUF))
44615645Sjoerg		SET(cflag, MDMBUF);
44715645Sjoerg	else
44815645Sjoerg		CLR(cflag, MDMBUF);
44915645Sjoerg	if (ISSET(flags, NOHANG))
45015645Sjoerg		CLR(cflag, HUPCL);
45115645Sjoerg	else
45215645Sjoerg		SET(cflag, HUPCL);
45315645Sjoerg	if (ISSET(flags, CRTKIL))
45415645Sjoerg		SET(lflag, ECHOKE);
45515645Sjoerg	else
45615645Sjoerg		CLR(lflag, ECHOKE);
45715645Sjoerg	if (ISSET(flags, CTLECH))
45815645Sjoerg		SET(lflag, ECHOCTL);
45915645Sjoerg	else
46015645Sjoerg		CLR(lflag, ECHOCTL);
46115645Sjoerg	if (!ISSET(flags, DECCTQ))
46215645Sjoerg		SET(iflag, IXANY);
46315645Sjoerg	else
46415645Sjoerg		CLR(iflag, IXANY);
46515645Sjoerg	CLR(lflag, TOSTOP|FLUSHO|PENDIN|NOFLSH);
46615645Sjoerg	SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
46715645Sjoerg
46815645Sjoerg	if (ISSET(flags, RAW|LITOUT|PASS8)) {
46915645Sjoerg		CLR(cflag, CSIZE);
47015645Sjoerg		SET(cflag, CS8);
47115645Sjoerg		if (!ISSET(flags, RAW|PASS8))
47215645Sjoerg			SET(iflag, ISTRIP);
47315645Sjoerg		else
47415645Sjoerg			CLR(iflag, ISTRIP);
47515645Sjoerg		if (!ISSET(flags, RAW|LITOUT))
47615645Sjoerg			SET(oflag, OPOST);
47715645Sjoerg		else
47815645Sjoerg			CLR(oflag, OPOST);
47915645Sjoerg	} else {
48015645Sjoerg		CLR(cflag, CSIZE);
48115645Sjoerg		SET(cflag, CS7);
48215645Sjoerg		SET(iflag, ISTRIP);
48315645Sjoerg		SET(oflag, OPOST);
48415645Sjoerg	}
48515645Sjoerg
48615645Sjoerg	tmode.c_iflag = iflag;
48715645Sjoerg	tmode.c_oflag = oflag;
48815645Sjoerg	tmode.c_cflag = cflag;
48915645Sjoerg	tmode.c_lflag = lflag;
49015645Sjoerg}
49115645Sjoerg#endif
49215645Sjoerg
49315645Sjoerg#ifdef XXX_DELAY
4941592Srgrimesstruct delayval {
4951592Srgrimes	unsigned	delay;		/* delay in ms */
4961592Srgrimes	int		bits;
4971592Srgrimes};
4981592Srgrimes
4991592Srgrimes/*
5001592Srgrimes * below are random guesses, I can't be bothered checking
5011592Srgrimes */
5021592Srgrimes
5031592Srgrimesstruct delayval	crdelay[] = {
50415645Sjoerg	{ 1,		CR1 },
50515645Sjoerg	{ 2,		CR2 },
50615645Sjoerg	{ 3,		CR3 },
50715645Sjoerg	{ 83,		CR1 },
50815645Sjoerg	{ 166,		CR2 },
50915645Sjoerg	{ 0,		CR3 },
5101592Srgrimes};
5111592Srgrimes
5121592Srgrimesstruct delayval nldelay[] = {
51315645Sjoerg	{ 1,		NL1 },		/* special, calculated */
51415645Sjoerg	{ 2,		NL2 },
51515645Sjoerg	{ 3,		NL3 },
51615645Sjoerg	{ 100,		NL2 },
51715645Sjoerg	{ 0,		NL3 },
5181592Srgrimes};
5191592Srgrimes
5201592Srgrimesstruct delayval	bsdelay[] = {
52115645Sjoerg	{ 1,		BS1 },
52215645Sjoerg	{ 0,		0 },
5231592Srgrimes};
5241592Srgrimes
5251592Srgrimesstruct delayval	ffdelay[] = {
52615645Sjoerg	{ 1,		FF1 },
52715645Sjoerg	{ 1750,		FF1 },
52815645Sjoerg	{ 0,		FF1 },
5291592Srgrimes};
5301592Srgrimes
5311592Srgrimesstruct delayval	tbdelay[] = {
53215645Sjoerg	{ 1,		TAB1 },
53315645Sjoerg	{ 2,		TAB2 },
53415645Sjoerg	{ 3,		XTABS },	/* this is expand tabs */
53515645Sjoerg	{ 100,		TAB1 },
53615645Sjoerg	{ 0,		TAB2 },
5371592Srgrimes};
5381592Srgrimes
53915645Sjoergint
5401592Srgrimesdelaybits()
5411592Srgrimes{
54215645Sjoerg	register int f;
5431592Srgrimes
5441592Srgrimes	f  = adelay(CD, crdelay);
5451592Srgrimes	f |= adelay(ND, nldelay);
5461592Srgrimes	f |= adelay(FD, ffdelay);
5471592Srgrimes	f |= adelay(TD, tbdelay);
5481592Srgrimes	f |= adelay(BD, bsdelay);
5491592Srgrimes	return (f);
5501592Srgrimes}
5511592Srgrimes
55215645Sjoergint
5531592Srgrimesadelay(ms, dp)
5541592Srgrimes	register ms;
5551592Srgrimes	register struct delayval *dp;
5561592Srgrimes{
5571592Srgrimes	if (ms == 0)
5581592Srgrimes		return (0);
5591592Srgrimes	while (dp->delay && ms > dp->delay)
5601592Srgrimes		dp++;
5611592Srgrimes	return (dp->bits);
5621592Srgrimes}
56315645Sjoerg#endif
5641592Srgrimes
56515645Sjoergchar	editedhost[MAXHOSTNAMELEN];
5661592Srgrimes
56715645Sjoergvoid
5681592Srgrimesedithost(pat)
56915645Sjoerg	register const char *pat;
5701592Srgrimes{
57115645Sjoerg	register const char *host = HN;
5721592Srgrimes	register char *res = editedhost;
5731592Srgrimes
5741592Srgrimes	if (!pat)
5751592Srgrimes		pat = "";
5761592Srgrimes	while (*pat) {
5771592Srgrimes		switch (*pat) {
5781592Srgrimes
5791592Srgrimes		case '#':
5801592Srgrimes			if (*host)
5811592Srgrimes				host++;
5821592Srgrimes			break;
5831592Srgrimes
5841592Srgrimes		case '@':
5851592Srgrimes			if (*host)
5861592Srgrimes				*res++ = *host++;
5871592Srgrimes			break;
5881592Srgrimes
5891592Srgrimes		default:
5901592Srgrimes			*res++ = *pat;
5911592Srgrimes			break;
5921592Srgrimes
5931592Srgrimes		}
5941592Srgrimes		if (res == &editedhost[sizeof editedhost - 1]) {
5951592Srgrimes			*res = '\0';
5961592Srgrimes			return;
5971592Srgrimes		}
5981592Srgrimes		pat++;
5991592Srgrimes	}
6001592Srgrimes	if (*host)
6011592Srgrimes		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
6021592Srgrimes	else
6031592Srgrimes		*res = '\0';
6041592Srgrimes	editedhost[sizeof editedhost - 1] = '\0';
6051592Srgrimes}
6061592Srgrimes
60715645Sjoergstatic struct speedtab {
6081592Srgrimes	int	speed;
6091592Srgrimes	int	uxname;
6101592Srgrimes} speedtab[] = {
61115645Sjoerg	{ 50,	B50 },
61215645Sjoerg	{ 75,	B75 },
61315645Sjoerg	{ 110,	B110 },
61415645Sjoerg	{ 134,	B134 },
61515645Sjoerg	{ 150,	B150 },
61615645Sjoerg	{ 200,	B200 },
61715645Sjoerg	{ 300,	B300 },
61815645Sjoerg	{ 600,	B600 },
61915645Sjoerg	{ 1200,	B1200 },
62015645Sjoerg	{ 1800,	B1800 },
62115645Sjoerg	{ 2400,	B2400 },
62215645Sjoerg	{ 4800,	B4800 },
62315645Sjoerg	{ 9600,	B9600 },
62415645Sjoerg	{ 19200, EXTA },
62515645Sjoerg	{ 19,	EXTA },		/* for people who say 19.2K */
62615645Sjoerg	{ 38400, EXTB },
62715645Sjoerg	{ 38,	EXTB },
62815645Sjoerg	{ 7200,	EXTB },		/* alternative */
62915645Sjoerg	{ 57600, B57600 },
63015645Sjoerg	{ 115200, B115200 },
63115645Sjoerg	{ 0 }
6321592Srgrimes};
6331592Srgrimes
63415645Sjoergint
6351592Srgrimesspeed(val)
63615645Sjoerg	int val;
6371592Srgrimes{
6381592Srgrimes	register struct speedtab *sp;
6391592Srgrimes
6409651Sache	if (val <= B115200)
6411592Srgrimes		return (val);
6421592Srgrimes
6431592Srgrimes	for (sp = speedtab; sp->speed; sp++)
6441592Srgrimes		if (sp->speed == val)
6451592Srgrimes			return (sp->uxname);
6468870Srgrimes
6471592Srgrimes	return (B300);		/* default in impossible cases */
6481592Srgrimes}
6491592Srgrimes
65015645Sjoergvoid
6511592Srgrimesmakeenv(env)
6521592Srgrimes	char *env[];
6531592Srgrimes{
6541592Srgrimes	static char termbuf[128] = "TERM=";
6551592Srgrimes	register char *p, *q;
6561592Srgrimes	register char **ep;
6571592Srgrimes
6581592Srgrimes	ep = env;
6591592Srgrimes	if (TT && *TT) {
6601592Srgrimes		strcat(termbuf, TT);
6611592Srgrimes		*ep++ = termbuf;
6621592Srgrimes	}
66315645Sjoerg	if ((p = EV)) {
6641592Srgrimes		q = p;
66515645Sjoerg		while ((q = strchr(q, ','))) {
6661592Srgrimes			*q++ = '\0';
6671592Srgrimes			*ep++ = p;
6681592Srgrimes			p = q;
6691592Srgrimes		}
6701592Srgrimes		if (*p)
6711592Srgrimes			*ep++ = p;
6721592Srgrimes	}
6731592Srgrimes	*ep = (char *)0;
6741592Srgrimes}
6751592Srgrimes
6761592Srgrimes/*
6771592Srgrimes * This speed select mechanism is written for the Develcon DATASWITCH.
6781592Srgrimes * The Develcon sends a string of the form "B{speed}\n" at a predefined
6791592Srgrimes * baud rate. This string indicates the user's actual speed.
6801592Srgrimes * The routine below returns the terminal type mapped from derived speed.
6811592Srgrimes */
6821592Srgrimesstruct	portselect {
68315645Sjoerg	const char	*ps_baud;
68415645Sjoerg	const char	*ps_type;
6851592Srgrimes} portspeeds[] = {
6861592Srgrimes	{ "B110",	"std.110" },
6871592Srgrimes	{ "B134",	"std.134" },
6881592Srgrimes	{ "B150",	"std.150" },
6891592Srgrimes	{ "B300",	"std.300" },
6901592Srgrimes	{ "B600",	"std.600" },
6911592Srgrimes	{ "B1200",	"std.1200" },
6921592Srgrimes	{ "B2400",	"std.2400" },
6931592Srgrimes	{ "B4800",	"std.4800" },
6941592Srgrimes	{ "B9600",	"std.9600" },
6951592Srgrimes	{ "B19200",	"std.19200" },
6961592Srgrimes	{ 0 }
6971592Srgrimes};
6981592Srgrimes
69915645Sjoergconst char *
7001592Srgrimesportselector()
7011592Srgrimes{
70215645Sjoerg	char c, baud[20];
70315645Sjoerg	const char *type = "default";
7041592Srgrimes	register struct portselect *ps;
7051592Srgrimes	int len;
7061592Srgrimes
7071592Srgrimes	alarm(5*60);
7081592Srgrimes	for (len = 0; len < sizeof (baud) - 1; len++) {
7091592Srgrimes		if (read(STDIN_FILENO, &c, 1) <= 0)
7101592Srgrimes			break;
7111592Srgrimes		c &= 0177;
7121592Srgrimes		if (c == '\n' || c == '\r')
7131592Srgrimes			break;
7141592Srgrimes		if (c == 'B')
7151592Srgrimes			len = 0;	/* in case of leading garbage */
7161592Srgrimes		baud[len] = c;
7171592Srgrimes	}
7181592Srgrimes	baud[len] = '\0';
7191592Srgrimes	for (ps = portspeeds; ps->ps_baud; ps++)
7201592Srgrimes		if (strcmp(ps->ps_baud, baud) == 0) {
7211592Srgrimes			type = ps->ps_type;
7221592Srgrimes			break;
7231592Srgrimes		}
7241592Srgrimes	sleep(2);	/* wait for connection to complete */
7251592Srgrimes	return (type);
7261592Srgrimes}
7271592Srgrimes
7281592Srgrimes/*
7291592Srgrimes * This auto-baud speed select mechanism is written for the Micom 600
7301592Srgrimes * portselector. Selection is done by looking at how the character '\r'
7311592Srgrimes * is garbled at the different speeds.
7321592Srgrimes */
7331592Srgrimes#include <sys/time.h>
7341592Srgrimes
73515645Sjoergconst char *
7361592Srgrimesautobaud()
7371592Srgrimes{
7381592Srgrimes	int rfds;
7391592Srgrimes	struct timeval timeout;
74015645Sjoerg	char c;
74115645Sjoerg	const char *type = "9600-baud";
7421592Srgrimes
74315645Sjoerg	(void)tcflush(0, TCIOFLUSH);
7441592Srgrimes	rfds = 1 << 0;
7451592Srgrimes	timeout.tv_sec = 5;
7461592Srgrimes	timeout.tv_usec = 0;
7471592Srgrimes	if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
7481592Srgrimes	    (fd_set *)NULL, &timeout) <= 0)
7491592Srgrimes		return (type);
7501592Srgrimes	if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
7511592Srgrimes		return (type);
7521592Srgrimes	timeout.tv_sec = 0;
7531592Srgrimes	timeout.tv_usec = 20;
7541592Srgrimes	(void) select(32, (fd_set *)NULL, (fd_set *)NULL,
7551592Srgrimes	    (fd_set *)NULL, &timeout);
75615645Sjoerg	(void)tcflush(0, TCIOFLUSH);
7571592Srgrimes	switch (c & 0377) {
7581592Srgrimes
7591592Srgrimes	case 0200:		/* 300-baud */
7601592Srgrimes		type = "300-baud";
7611592Srgrimes		break;
7621592Srgrimes
7631592Srgrimes	case 0346:		/* 1200-baud */
7641592Srgrimes		type = "1200-baud";
7651592Srgrimes		break;
7661592Srgrimes
7671592Srgrimes	case  015:		/* 2400-baud */
7681592Srgrimes	case 0215:
7691592Srgrimes		type = "2400-baud";
7701592Srgrimes		break;
7711592Srgrimes
7721592Srgrimes	default:		/* 4800-baud */
7731592Srgrimes		type = "4800-baud";
7741592Srgrimes		break;
7751592Srgrimes
7761592Srgrimes	case 0377:		/* 9600-baud */
7771592Srgrimes		type = "9600-baud";
7781592Srgrimes		break;
7791592Srgrimes	}
7801592Srgrimes	return (type);
7811592Srgrimes}
782