subr.c revision 15645
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";*/
3615645Sjoergstatic char rcsid[] = "$Id: subr.c,v 1.1.1.2 1996/04/13 15:33:14 joerg Exp $";
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
28715645Sjoerg	if (NL) {
28815645Sjoerg		SET(iflag, ICRNL);
28915645Sjoerg		SET(oflag, ONLCR|OPOST);
29015645Sjoerg	} else {
29115645Sjoerg		CLR(iflag, ICRNL);
29215645Sjoerg		CLR(oflag, ONLCR);
2931592Srgrimes	}
2941592Srgrimes
2951592Srgrimes	if (!HT)
29615645Sjoerg		SET(oflag, OXTABS|OPOST);
29715645Sjoerg	else
29815645Sjoerg		CLR(oflag, OXTABS);
2991592Srgrimes
30015645Sjoerg#ifdef XXX_DELAY
30115645Sjoerg	SET(f, delaybits());
30215645Sjoerg#endif
30315645Sjoerg
30415645Sjoerg	if (n == 1) {		/* read mode flags */
30515645Sjoerg		if (RW) {
30615645Sjoerg			iflag = 0;
30715645Sjoerg			CLR(oflag, OPOST);
30815645Sjoerg			CLR(cflag, CSIZE|PARENB);
30915645Sjoerg			SET(cflag, CS8);
31015645Sjoerg			lflag = 0;
31115645Sjoerg		} else {
31215645Sjoerg			CLR(lflag, ICANON);
31315645Sjoerg		}
31415645Sjoerg		goto out;
31515645Sjoerg	}
31615645Sjoerg
3171592Srgrimes	if (n == 0)
31815645Sjoerg		goto out;
3191592Srgrimes
32015645Sjoerg#if 0
3211592Srgrimes	if (CB)
32215645Sjoerg		SET(f, CRTBS);
32315645Sjoerg#endif
3241592Srgrimes
3251592Srgrimes	if (CE)
32615645Sjoerg		SET(lflag, ECHOE);
32715645Sjoerg	else
32815645Sjoerg		CLR(lflag, ECHOE);
3291592Srgrimes
3301592Srgrimes	if (CK)
33115645Sjoerg		SET(lflag, ECHOKE);
33215645Sjoerg	else
33315645Sjoerg		CLR(lflag, ECHOKE);
3341592Srgrimes
3351592Srgrimes	if (PE)
33615645Sjoerg		SET(lflag, ECHOPRT);
33715645Sjoerg	else
33815645Sjoerg		CLR(lflag, ECHOPRT);
3391592Srgrimes
3401592Srgrimes	if (EC)
34115645Sjoerg		SET(lflag, ECHO);
34215645Sjoerg	else
34315645Sjoerg		CLR(lflag, ECHO);
3441592Srgrimes
3451592Srgrimes	if (XC)
34615645Sjoerg		SET(lflag, ECHOCTL);
34715645Sjoerg	else
34815645Sjoerg		CLR(lflag, ECHOCTL);
3491592Srgrimes
3501592Srgrimes	if (DX)
35115645Sjoerg		SET(lflag, IXANY);
35215645Sjoerg	else
35315645Sjoerg		CLR(lflag, IXANY);
3541592Srgrimes
35515645Sjoergout:
35615645Sjoerg	tmode.c_iflag = iflag;
35715645Sjoerg	tmode.c_oflag = oflag;
35815645Sjoerg	tmode.c_cflag = cflag;
35915645Sjoerg	tmode.c_lflag = lflag;
3601592Srgrimes}
3611592Srgrimes
36215645Sjoerg#ifdef COMPAT_43
36315645Sjoerg/*
36415645Sjoerg * Old TTY => termios, snatched from <sys/kern/tty_compat.c>
36515645Sjoerg */
36615645Sjoergvoid
36715645Sjoergcompatflags(flags)
36815645Sjoergregister long flags;
36915645Sjoerg{
37015645Sjoerg	register tcflag_t iflag, oflag, cflag, lflag;
37115645Sjoerg
37215645Sjoerg	iflag = BRKINT|ICRNL|IMAXBEL|IXON|IXANY;
37315645Sjoerg	oflag = OPOST|ONLCR|OXTABS;
37415645Sjoerg	cflag = CREAD;
37515645Sjoerg	lflag = ICANON|ISIG|IEXTEN;
37615645Sjoerg
37715645Sjoerg	if (ISSET(flags, TANDEM))
37815645Sjoerg		SET(iflag, IXOFF);
37915645Sjoerg	else
38015645Sjoerg		CLR(iflag, IXOFF);
38115645Sjoerg	if (ISSET(flags, ECHO))
38215645Sjoerg		SET(lflag, ECHO);
38315645Sjoerg	else
38415645Sjoerg		CLR(lflag, ECHO);
38515645Sjoerg	if (ISSET(flags, CRMOD)) {
38615645Sjoerg		SET(iflag, ICRNL);
38715645Sjoerg		SET(oflag, ONLCR);
38815645Sjoerg	} else {
38915645Sjoerg		CLR(iflag, ICRNL);
39015645Sjoerg		CLR(oflag, ONLCR);
39115645Sjoerg	}
39215645Sjoerg	if (ISSET(flags, XTABS))
39315645Sjoerg		SET(oflag, OXTABS);
39415645Sjoerg	else
39515645Sjoerg		CLR(oflag, OXTABS);
39615645Sjoerg
39715645Sjoerg
39815645Sjoerg	if (ISSET(flags, RAW)) {
39915645Sjoerg		iflag &= IXOFF;
40015645Sjoerg		CLR(lflag, ISIG|ICANON|IEXTEN);
40115645Sjoerg		CLR(cflag, PARENB);
40215645Sjoerg	} else {
40315645Sjoerg		SET(iflag, BRKINT|IXON|IMAXBEL);
40415645Sjoerg		SET(lflag, ISIG|IEXTEN);
40515645Sjoerg		if (ISSET(flags, CBREAK))
40615645Sjoerg			CLR(lflag, ICANON);
40715645Sjoerg		else
40815645Sjoerg			SET(lflag, ICANON);
40915645Sjoerg		switch (ISSET(flags, ANYP)) {
41015645Sjoerg		case 0:
41115645Sjoerg			CLR(cflag, PARENB);
41215645Sjoerg			break;
41315645Sjoerg		case ANYP:
41415645Sjoerg			SET(cflag, PARENB);
41515645Sjoerg			CLR(iflag, INPCK);
41615645Sjoerg			break;
41715645Sjoerg		case EVENP:
41815645Sjoerg			SET(cflag, PARENB);
41915645Sjoerg			SET(iflag, INPCK);
42015645Sjoerg			CLR(cflag, PARODD);
42115645Sjoerg			break;
42215645Sjoerg		case ODDP:
42315645Sjoerg			SET(cflag, PARENB);
42415645Sjoerg			SET(iflag, INPCK);
42515645Sjoerg			SET(cflag, PARODD);
42615645Sjoerg			break;
42715645Sjoerg		}
42815645Sjoerg	}
42915645Sjoerg
43015645Sjoerg	/* Nothing we can do with CRTBS. */
43115645Sjoerg	if (ISSET(flags, PRTERA))
43215645Sjoerg		SET(lflag, ECHOPRT);
43315645Sjoerg	else
43415645Sjoerg		CLR(lflag, ECHOPRT);
43515645Sjoerg	if (ISSET(flags, CRTERA))
43615645Sjoerg		SET(lflag, ECHOE);
43715645Sjoerg	else
43815645Sjoerg		CLR(lflag, ECHOE);
43915645Sjoerg	/* Nothing we can do with TILDE. */
44015645Sjoerg	if (ISSET(flags, MDMBUF))
44115645Sjoerg		SET(cflag, MDMBUF);
44215645Sjoerg	else
44315645Sjoerg		CLR(cflag, MDMBUF);
44415645Sjoerg	if (ISSET(flags, NOHANG))
44515645Sjoerg		CLR(cflag, HUPCL);
44615645Sjoerg	else
44715645Sjoerg		SET(cflag, HUPCL);
44815645Sjoerg	if (ISSET(flags, CRTKIL))
44915645Sjoerg		SET(lflag, ECHOKE);
45015645Sjoerg	else
45115645Sjoerg		CLR(lflag, ECHOKE);
45215645Sjoerg	if (ISSET(flags, CTLECH))
45315645Sjoerg		SET(lflag, ECHOCTL);
45415645Sjoerg	else
45515645Sjoerg		CLR(lflag, ECHOCTL);
45615645Sjoerg	if (!ISSET(flags, DECCTQ))
45715645Sjoerg		SET(iflag, IXANY);
45815645Sjoerg	else
45915645Sjoerg		CLR(iflag, IXANY);
46015645Sjoerg	CLR(lflag, TOSTOP|FLUSHO|PENDIN|NOFLSH);
46115645Sjoerg	SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
46215645Sjoerg
46315645Sjoerg	if (ISSET(flags, RAW|LITOUT|PASS8)) {
46415645Sjoerg		CLR(cflag, CSIZE);
46515645Sjoerg		SET(cflag, CS8);
46615645Sjoerg		if (!ISSET(flags, RAW|PASS8))
46715645Sjoerg			SET(iflag, ISTRIP);
46815645Sjoerg		else
46915645Sjoerg			CLR(iflag, ISTRIP);
47015645Sjoerg		if (!ISSET(flags, RAW|LITOUT))
47115645Sjoerg			SET(oflag, OPOST);
47215645Sjoerg		else
47315645Sjoerg			CLR(oflag, OPOST);
47415645Sjoerg	} else {
47515645Sjoerg		CLR(cflag, CSIZE);
47615645Sjoerg		SET(cflag, CS7);
47715645Sjoerg		SET(iflag, ISTRIP);
47815645Sjoerg		SET(oflag, OPOST);
47915645Sjoerg	}
48015645Sjoerg
48115645Sjoerg	tmode.c_iflag = iflag;
48215645Sjoerg	tmode.c_oflag = oflag;
48315645Sjoerg	tmode.c_cflag = cflag;
48415645Sjoerg	tmode.c_lflag = lflag;
48515645Sjoerg}
48615645Sjoerg#endif
48715645Sjoerg
48815645Sjoerg#ifdef XXX_DELAY
4891592Srgrimesstruct delayval {
4901592Srgrimes	unsigned	delay;		/* delay in ms */
4911592Srgrimes	int		bits;
4921592Srgrimes};
4931592Srgrimes
4941592Srgrimes/*
4951592Srgrimes * below are random guesses, I can't be bothered checking
4961592Srgrimes */
4971592Srgrimes
4981592Srgrimesstruct delayval	crdelay[] = {
49915645Sjoerg	{ 1,		CR1 },
50015645Sjoerg	{ 2,		CR2 },
50115645Sjoerg	{ 3,		CR3 },
50215645Sjoerg	{ 83,		CR1 },
50315645Sjoerg	{ 166,		CR2 },
50415645Sjoerg	{ 0,		CR3 },
5051592Srgrimes};
5061592Srgrimes
5071592Srgrimesstruct delayval nldelay[] = {
50815645Sjoerg	{ 1,		NL1 },		/* special, calculated */
50915645Sjoerg	{ 2,		NL2 },
51015645Sjoerg	{ 3,		NL3 },
51115645Sjoerg	{ 100,		NL2 },
51215645Sjoerg	{ 0,		NL3 },
5131592Srgrimes};
5141592Srgrimes
5151592Srgrimesstruct delayval	bsdelay[] = {
51615645Sjoerg	{ 1,		BS1 },
51715645Sjoerg	{ 0,		0 },
5181592Srgrimes};
5191592Srgrimes
5201592Srgrimesstruct delayval	ffdelay[] = {
52115645Sjoerg	{ 1,		FF1 },
52215645Sjoerg	{ 1750,		FF1 },
52315645Sjoerg	{ 0,		FF1 },
5241592Srgrimes};
5251592Srgrimes
5261592Srgrimesstruct delayval	tbdelay[] = {
52715645Sjoerg	{ 1,		TAB1 },
52815645Sjoerg	{ 2,		TAB2 },
52915645Sjoerg	{ 3,		XTABS },	/* this is expand tabs */
53015645Sjoerg	{ 100,		TAB1 },
53115645Sjoerg	{ 0,		TAB2 },
5321592Srgrimes};
5331592Srgrimes
53415645Sjoergint
5351592Srgrimesdelaybits()
5361592Srgrimes{
53715645Sjoerg	register int f;
5381592Srgrimes
5391592Srgrimes	f  = adelay(CD, crdelay);
5401592Srgrimes	f |= adelay(ND, nldelay);
5411592Srgrimes	f |= adelay(FD, ffdelay);
5421592Srgrimes	f |= adelay(TD, tbdelay);
5431592Srgrimes	f |= adelay(BD, bsdelay);
5441592Srgrimes	return (f);
5451592Srgrimes}
5461592Srgrimes
54715645Sjoergint
5481592Srgrimesadelay(ms, dp)
5491592Srgrimes	register ms;
5501592Srgrimes	register struct delayval *dp;
5511592Srgrimes{
5521592Srgrimes	if (ms == 0)
5531592Srgrimes		return (0);
5541592Srgrimes	while (dp->delay && ms > dp->delay)
5551592Srgrimes		dp++;
5561592Srgrimes	return (dp->bits);
5571592Srgrimes}
55815645Sjoerg#endif
5591592Srgrimes
56015645Sjoergchar	editedhost[MAXHOSTNAMELEN];
5611592Srgrimes
56215645Sjoergvoid
5631592Srgrimesedithost(pat)
56415645Sjoerg	register const char *pat;
5651592Srgrimes{
56615645Sjoerg	register const char *host = HN;
5671592Srgrimes	register char *res = editedhost;
5681592Srgrimes
5691592Srgrimes	if (!pat)
5701592Srgrimes		pat = "";
5711592Srgrimes	while (*pat) {
5721592Srgrimes		switch (*pat) {
5731592Srgrimes
5741592Srgrimes		case '#':
5751592Srgrimes			if (*host)
5761592Srgrimes				host++;
5771592Srgrimes			break;
5781592Srgrimes
5791592Srgrimes		case '@':
5801592Srgrimes			if (*host)
5811592Srgrimes				*res++ = *host++;
5821592Srgrimes			break;
5831592Srgrimes
5841592Srgrimes		default:
5851592Srgrimes			*res++ = *pat;
5861592Srgrimes			break;
5871592Srgrimes
5881592Srgrimes		}
5891592Srgrimes		if (res == &editedhost[sizeof editedhost - 1]) {
5901592Srgrimes			*res = '\0';
5911592Srgrimes			return;
5921592Srgrimes		}
5931592Srgrimes		pat++;
5941592Srgrimes	}
5951592Srgrimes	if (*host)
5961592Srgrimes		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
5971592Srgrimes	else
5981592Srgrimes		*res = '\0';
5991592Srgrimes	editedhost[sizeof editedhost - 1] = '\0';
6001592Srgrimes}
6011592Srgrimes
60215645Sjoergstatic struct speedtab {
6031592Srgrimes	int	speed;
6041592Srgrimes	int	uxname;
6051592Srgrimes} speedtab[] = {
60615645Sjoerg	{ 50,	B50 },
60715645Sjoerg	{ 75,	B75 },
60815645Sjoerg	{ 110,	B110 },
60915645Sjoerg	{ 134,	B134 },
61015645Sjoerg	{ 150,	B150 },
61115645Sjoerg	{ 200,	B200 },
61215645Sjoerg	{ 300,	B300 },
61315645Sjoerg	{ 600,	B600 },
61415645Sjoerg	{ 1200,	B1200 },
61515645Sjoerg	{ 1800,	B1800 },
61615645Sjoerg	{ 2400,	B2400 },
61715645Sjoerg	{ 4800,	B4800 },
61815645Sjoerg	{ 9600,	B9600 },
61915645Sjoerg	{ 19200, EXTA },
62015645Sjoerg	{ 19,	EXTA },		/* for people who say 19.2K */
62115645Sjoerg	{ 38400, EXTB },
62215645Sjoerg	{ 38,	EXTB },
62315645Sjoerg	{ 7200,	EXTB },		/* alternative */
62415645Sjoerg	{ 57600, B57600 },
62515645Sjoerg	{ 115200, B115200 },
62615645Sjoerg	{ 0 }
6271592Srgrimes};
6281592Srgrimes
62915645Sjoergint
6301592Srgrimesspeed(val)
63115645Sjoerg	int val;
6321592Srgrimes{
6331592Srgrimes	register struct speedtab *sp;
6341592Srgrimes
6359651Sache	if (val <= B115200)
6361592Srgrimes		return (val);
6371592Srgrimes
6381592Srgrimes	for (sp = speedtab; sp->speed; sp++)
6391592Srgrimes		if (sp->speed == val)
6401592Srgrimes			return (sp->uxname);
6418870Srgrimes
6421592Srgrimes	return (B300);		/* default in impossible cases */
6431592Srgrimes}
6441592Srgrimes
64515645Sjoergvoid
6461592Srgrimesmakeenv(env)
6471592Srgrimes	char *env[];
6481592Srgrimes{
6491592Srgrimes	static char termbuf[128] = "TERM=";
6501592Srgrimes	register char *p, *q;
6511592Srgrimes	register char **ep;
6521592Srgrimes
6531592Srgrimes	ep = env;
6541592Srgrimes	if (TT && *TT) {
6551592Srgrimes		strcat(termbuf, TT);
6561592Srgrimes		*ep++ = termbuf;
6571592Srgrimes	}
65815645Sjoerg	if ((p = EV)) {
6591592Srgrimes		q = p;
66015645Sjoerg		while ((q = strchr(q, ','))) {
6611592Srgrimes			*q++ = '\0';
6621592Srgrimes			*ep++ = p;
6631592Srgrimes			p = q;
6641592Srgrimes		}
6651592Srgrimes		if (*p)
6661592Srgrimes			*ep++ = p;
6671592Srgrimes	}
6681592Srgrimes	*ep = (char *)0;
6691592Srgrimes}
6701592Srgrimes
6711592Srgrimes/*
6721592Srgrimes * This speed select mechanism is written for the Develcon DATASWITCH.
6731592Srgrimes * The Develcon sends a string of the form "B{speed}\n" at a predefined
6741592Srgrimes * baud rate. This string indicates the user's actual speed.
6751592Srgrimes * The routine below returns the terminal type mapped from derived speed.
6761592Srgrimes */
6771592Srgrimesstruct	portselect {
67815645Sjoerg	const char	*ps_baud;
67915645Sjoerg	const char	*ps_type;
6801592Srgrimes} portspeeds[] = {
6811592Srgrimes	{ "B110",	"std.110" },
6821592Srgrimes	{ "B134",	"std.134" },
6831592Srgrimes	{ "B150",	"std.150" },
6841592Srgrimes	{ "B300",	"std.300" },
6851592Srgrimes	{ "B600",	"std.600" },
6861592Srgrimes	{ "B1200",	"std.1200" },
6871592Srgrimes	{ "B2400",	"std.2400" },
6881592Srgrimes	{ "B4800",	"std.4800" },
6891592Srgrimes	{ "B9600",	"std.9600" },
6901592Srgrimes	{ "B19200",	"std.19200" },
6911592Srgrimes	{ 0 }
6921592Srgrimes};
6931592Srgrimes
69415645Sjoergconst char *
6951592Srgrimesportselector()
6961592Srgrimes{
69715645Sjoerg	char c, baud[20];
69815645Sjoerg	const char *type = "default";
6991592Srgrimes	register struct portselect *ps;
7001592Srgrimes	int len;
7011592Srgrimes
7021592Srgrimes	alarm(5*60);
7031592Srgrimes	for (len = 0; len < sizeof (baud) - 1; len++) {
7041592Srgrimes		if (read(STDIN_FILENO, &c, 1) <= 0)
7051592Srgrimes			break;
7061592Srgrimes		c &= 0177;
7071592Srgrimes		if (c == '\n' || c == '\r')
7081592Srgrimes			break;
7091592Srgrimes		if (c == 'B')
7101592Srgrimes			len = 0;	/* in case of leading garbage */
7111592Srgrimes		baud[len] = c;
7121592Srgrimes	}
7131592Srgrimes	baud[len] = '\0';
7141592Srgrimes	for (ps = portspeeds; ps->ps_baud; ps++)
7151592Srgrimes		if (strcmp(ps->ps_baud, baud) == 0) {
7161592Srgrimes			type = ps->ps_type;
7171592Srgrimes			break;
7181592Srgrimes		}
7191592Srgrimes	sleep(2);	/* wait for connection to complete */
7201592Srgrimes	return (type);
7211592Srgrimes}
7221592Srgrimes
7231592Srgrimes/*
7241592Srgrimes * This auto-baud speed select mechanism is written for the Micom 600
7251592Srgrimes * portselector. Selection is done by looking at how the character '\r'
7261592Srgrimes * is garbled at the different speeds.
7271592Srgrimes */
7281592Srgrimes#include <sys/time.h>
7291592Srgrimes
73015645Sjoergconst char *
7311592Srgrimesautobaud()
7321592Srgrimes{
7331592Srgrimes	int rfds;
7341592Srgrimes	struct timeval timeout;
73515645Sjoerg	char c;
73615645Sjoerg	const char *type = "9600-baud";
7371592Srgrimes
73815645Sjoerg	(void)tcflush(0, TCIOFLUSH);
7391592Srgrimes	rfds = 1 << 0;
7401592Srgrimes	timeout.tv_sec = 5;
7411592Srgrimes	timeout.tv_usec = 0;
7421592Srgrimes	if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
7431592Srgrimes	    (fd_set *)NULL, &timeout) <= 0)
7441592Srgrimes		return (type);
7451592Srgrimes	if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
7461592Srgrimes		return (type);
7471592Srgrimes	timeout.tv_sec = 0;
7481592Srgrimes	timeout.tv_usec = 20;
7491592Srgrimes	(void) select(32, (fd_set *)NULL, (fd_set *)NULL,
7501592Srgrimes	    (fd_set *)NULL, &timeout);
75115645Sjoerg	(void)tcflush(0, TCIOFLUSH);
7521592Srgrimes	switch (c & 0377) {
7531592Srgrimes
7541592Srgrimes	case 0200:		/* 300-baud */
7551592Srgrimes		type = "300-baud";
7561592Srgrimes		break;
7571592Srgrimes
7581592Srgrimes	case 0346:		/* 1200-baud */
7591592Srgrimes		type = "1200-baud";
7601592Srgrimes		break;
7611592Srgrimes
7621592Srgrimes	case  015:		/* 2400-baud */
7631592Srgrimes	case 0215:
7641592Srgrimes		type = "2400-baud";
7651592Srgrimes		break;
7661592Srgrimes
7671592Srgrimes	default:		/* 4800-baud */
7681592Srgrimes		type = "4800-baud";
7691592Srgrimes		break;
7701592Srgrimes
7711592Srgrimes	case 0377:		/* 9600-baud */
7721592Srgrimes		type = "9600-baud";
7731592Srgrimes		break;
7741592Srgrimes	}
7751592Srgrimes	return (type);
7761592Srgrimes}
777