xref: /csrg-svn/libexec/getty/subr.c (revision 42670)
119061Sdist /*
236930Sbostic  * Copyright (c) 1983 The Regents of the University of California.
336930Sbostic  * All rights reserved.
436930Sbostic  *
5*42670Sbostic  * %sccs.include.redist.c%
619061Sdist  */
719061Sdist 
813796Ssam #ifndef lint
9*42670Sbostic static char sccsid[] = "@(#)subr.c	5.7 (Berkeley) 06/01/90";
1036930Sbostic #endif /* not lint */
1113796Ssam 
1213796Ssam /*
1313796Ssam  * Melbourne getty.
1413796Ssam  */
1542668Smarc #define USE_OLD_TTY
1613796Ssam #include <sgtty.h>
1713796Ssam #include "gettytab.h"
1813796Ssam 
1913796Ssam extern	struct sgttyb tmode;
2013796Ssam extern	struct tchars tc;
2113796Ssam extern	struct ltchars ltc;
2213796Ssam 
2313796Ssam /*
2413796Ssam  * Get a table entry.
2513796Ssam  */
2613796Ssam gettable(name, buf, area)
2713796Ssam 	char *name, *buf, *area;
2813796Ssam {
2913796Ssam 	register struct gettystrs *sp;
3013796Ssam 	register struct gettynums *np;
3113796Ssam 	register struct gettyflags *fp;
3213796Ssam 	register n;
3313796Ssam 
3413796Ssam 	hopcount = 0;		/* new lookup, start fresh */
3513796Ssam 	if (getent(buf, name) != 1)
3613796Ssam 		return;
3713796Ssam 
3813796Ssam 	for (sp = gettystrs; sp->field; sp++)
3913796Ssam 		sp->value = getstr(sp->field, &area);
4013796Ssam 	for (np = gettynums; np->field; np++) {
4113796Ssam 		n = getnum(np->field);
4213796Ssam 		if (n == -1)
4313796Ssam 			np->set = 0;
4413796Ssam 		else {
4513796Ssam 			np->set = 1;
4613796Ssam 			np->value = n;
4713796Ssam 		}
4813796Ssam 	}
4913796Ssam 	for (fp = gettyflags; fp->field; fp++) {
5013796Ssam 		n = getflag(fp->field);
5113796Ssam 		if (n == -1)
5213796Ssam 			fp->set = 0;
5313796Ssam 		else {
5413796Ssam 			fp->set = 1;
5513796Ssam 			fp->value = n ^ fp->invrt;
5613796Ssam 		}
5713796Ssam 	}
5813796Ssam }
5913796Ssam 
6013796Ssam gendefaults()
6113796Ssam {
6213796Ssam 	register struct gettystrs *sp;
6313796Ssam 	register struct gettynums *np;
6413796Ssam 	register struct gettyflags *fp;
6513796Ssam 
6613796Ssam 	for (sp = gettystrs; sp->field; sp++)
6713796Ssam 		if (sp->value)
6813796Ssam 			sp->defalt = sp->value;
6913796Ssam 	for (np = gettynums; np->field; np++)
7013796Ssam 		if (np->set)
7113796Ssam 			np->defalt = np->value;
7213796Ssam 	for (fp = gettyflags; fp->field; fp++)
7313796Ssam 		if (fp->set)
7413796Ssam 			fp->defalt = fp->value;
7513796Ssam 		else
7613796Ssam 			fp->defalt = fp->invrt;
7713796Ssam }
7813796Ssam 
7913796Ssam setdefaults()
8013796Ssam {
8113796Ssam 	register struct gettystrs *sp;
8213796Ssam 	register struct gettynums *np;
8313796Ssam 	register struct gettyflags *fp;
8413796Ssam 
8513796Ssam 	for (sp = gettystrs; sp->field; sp++)
8613796Ssam 		if (!sp->value)
8713796Ssam 			sp->value = sp->defalt;
8813796Ssam 	for (np = gettynums; np->field; np++)
8913796Ssam 		if (!np->set)
9013796Ssam 			np->value = np->defalt;
9113796Ssam 	for (fp = gettyflags; fp->field; fp++)
9213796Ssam 		if (!fp->set)
9313796Ssam 			fp->value = fp->defalt;
9413796Ssam }
9513796Ssam 
9613796Ssam static char **
9713796Ssam charnames[] = {
9813796Ssam 	&ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
9913796Ssam 	&SU, &DS, &RP, &FL, &WE, &LN, 0
10013796Ssam };
10113796Ssam 
10213796Ssam static char *
10313796Ssam charvars[] = {
10413796Ssam 	&tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
10513796Ssam 	&tc.t_quitc, &tc.t_startc, &tc.t_stopc,
10613796Ssam 	&tc.t_eofc, &tc.t_brkc, &ltc.t_suspc,
10713796Ssam 	&ltc.t_dsuspc, &ltc.t_rprntc, &ltc.t_flushc,
10813796Ssam 	&ltc.t_werasc, &ltc.t_lnextc, 0
10913796Ssam };
11013796Ssam 
11113796Ssam setchars()
11213796Ssam {
11313796Ssam 	register int i;
11413796Ssam 	register char *p;
11513796Ssam 
11613796Ssam 	for (i = 0; charnames[i]; i++) {
11713796Ssam 		p = *charnames[i];
11813796Ssam 		if (p && *p)
11913796Ssam 			*charvars[i] = *p;
12013796Ssam 		else
12119946Sedward 			*charvars[i] = '\377';
12213796Ssam 	}
12313796Ssam }
12413796Ssam 
12513796Ssam long
12613796Ssam setflags(n)
12713796Ssam {
12813796Ssam 	register long f;
12913796Ssam 
13013796Ssam 	switch (n) {
13113796Ssam 	case 0:
13213796Ssam 		if (F0set)
13313796Ssam 			return(F0);
13413796Ssam 		break;
13513796Ssam 	case 1:
13613796Ssam 		if (F1set)
13713796Ssam 			return(F1);
13813796Ssam 		break;
13913796Ssam 	default:
14013796Ssam 		if (F2set)
14113796Ssam 			return(F2);
14213796Ssam 		break;
14313796Ssam 	}
14413796Ssam 
14513796Ssam 	f = 0;
14613796Ssam 
14713796Ssam 	if (AP)
14813796Ssam 		f |= ANYP;
14913796Ssam 	else if (OP)
15013796Ssam 		f |= ODDP;
15113796Ssam 	else if (EP)
15213796Ssam 		f |= EVENP;
15313796Ssam 
15413796Ssam 	if (UC)
15513796Ssam 		f |= LCASE;
15613796Ssam 
15713796Ssam 	if (NL)
15813796Ssam 		f |= CRMOD;
15913796Ssam 
16013796Ssam 	f |= delaybits();
16113796Ssam 
16213796Ssam 	if (n == 1) {		/* read mode flags */
16313796Ssam 		if (RW)
16413796Ssam 			f |= RAW;
16513796Ssam 		else
16613796Ssam 			f |= CBREAK;
16713796Ssam 		return (f);
16813796Ssam 	}
16913796Ssam 
17013796Ssam 	if (!HT)
17113796Ssam 		f |= XTABS;
17213796Ssam 
17313796Ssam 	if (n == 0)
17413796Ssam 		return (f);
17513796Ssam 
17613796Ssam 	if (CB)
17713796Ssam 		f |= CRTBS;
17813796Ssam 
17913796Ssam 	if (CE)
18013796Ssam 		f |= CRTERA;
18113796Ssam 
18216565Sralph 	if (CK)
18316565Sralph 		f |= CRTKIL;
18416565Sralph 
18513796Ssam 	if (PE)
18613796Ssam 		f |= PRTERA;
18713796Ssam 
18813796Ssam 	if (EC)
18913796Ssam 		f |= ECHO;
19013796Ssam 
19113796Ssam 	if (XC)
19213796Ssam 		f |= CTLECH;
19313796Ssam 
19425730Smckusick 	if (DX)
19525730Smckusick 		f |= DECCTQ;
19625730Smckusick 
19713796Ssam 	return (f);
19813796Ssam }
19913796Ssam 
20013796Ssam struct delayval {
20113796Ssam 	unsigned	delay;		/* delay in ms */
20213796Ssam 	int		bits;
20313796Ssam };
20413796Ssam 
20513796Ssam /*
20613796Ssam  * below are random guesses, I can't be bothered checking
20713796Ssam  */
20813796Ssam 
20913796Ssam struct delayval	crdelay[] = {
21013827Skre 	1,		CR1,
21113827Skre 	2,		CR2,
21213827Skre 	3,		CR3,
21313827Skre 	83,		CR1,
21413827Skre 	166,		CR2,
21513796Ssam 	0,		CR3,
21613796Ssam };
21713796Ssam 
21813796Ssam struct delayval nldelay[] = {
21913796Ssam 	1,		NL1,		/* special, calculated */
22013827Skre 	2,		NL2,
22113827Skre 	3,		NL3,
22213827Skre 	100,		NL2,
22313796Ssam 	0,		NL3,
22413796Ssam };
22513796Ssam 
22613796Ssam struct delayval	bsdelay[] = {
22713827Skre 	1,		BS1,
22813796Ssam 	0,		0,
22913796Ssam };
23013796Ssam 
23113796Ssam struct delayval	ffdelay[] = {
23213827Skre 	1,		FF1,
23313796Ssam 	1750,		FF1,
23413796Ssam 	0,		FF1,
23513796Ssam };
23613796Ssam 
23713796Ssam struct delayval	tbdelay[] = {
23813827Skre 	1,		TAB1,
23913827Skre 	2,		TAB2,
24013827Skre 	3,		XTABS,		/* this is expand tabs */
24113827Skre 	100,		TAB1,
24213796Ssam 	0,		TAB2,
24313796Ssam };
24413796Ssam 
24513796Ssam delaybits()
24613796Ssam {
24713796Ssam 	register f;
24813796Ssam 
24913796Ssam 	f  = adelay(CD, crdelay);
25013796Ssam 	f |= adelay(ND, nldelay);
25113796Ssam 	f |= adelay(FD, ffdelay);
25213796Ssam 	f |= adelay(TD, tbdelay);
25313796Ssam 	f |= adelay(BD, bsdelay);
25413796Ssam 	return (f);
25513796Ssam }
25613796Ssam 
25713796Ssam adelay(ms, dp)
25813796Ssam 	register ms;
25913796Ssam 	register struct delayval *dp;
26013796Ssam {
26113796Ssam 	if (ms == 0)
26213796Ssam 		return (0);
26313796Ssam 	while (dp->delay && ms > dp->delay)
26413796Ssam 		dp++;
26513796Ssam 	return (dp->bits);
26613796Ssam }
26713796Ssam 
26813796Ssam char	editedhost[32];
26913796Ssam 
27013796Ssam edithost(pat)
27113796Ssam 	register char *pat;
27213796Ssam {
27313796Ssam 	register char *host = HN;
27413796Ssam 	register char *res = editedhost;
27513796Ssam 
27613796Ssam 	if (!pat)
27713796Ssam 		pat = "";
27813796Ssam 	while (*pat) {
27913796Ssam 		switch (*pat) {
28013796Ssam 
28113796Ssam 		case '#':
28213796Ssam 			if (*host)
28313796Ssam 				host++;
28413796Ssam 			break;
28513796Ssam 
28613796Ssam 		case '@':
28713796Ssam 			if (*host)
28813796Ssam 				*res++ = *host++;
28913796Ssam 			break;
29013796Ssam 
29113796Ssam 		default:
29213796Ssam 			*res++ = *pat;
29313796Ssam 			break;
29413796Ssam 
29513796Ssam 		}
29613796Ssam 		if (res == &editedhost[sizeof editedhost - 1]) {
29713796Ssam 			*res = '\0';
29813796Ssam 			return;
29913796Ssam 		}
30013796Ssam 		pat++;
30113796Ssam 	}
30213796Ssam 	if (*host)
30313796Ssam 		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
30413796Ssam 	else
30513796Ssam 		*res = '\0';
30613796Ssam 	editedhost[sizeof editedhost - 1] = '\0';
30713796Ssam }
30813796Ssam 
30913796Ssam struct speedtab {
31013796Ssam 	int	speed;
31113796Ssam 	int	uxname;
31213796Ssam } speedtab[] = {
31313796Ssam 	50,	B50,
31413796Ssam 	75,	B75,
31513796Ssam 	110,	B110,
31613796Ssam 	134,	B134,
31713796Ssam 	150,	B150,
31813796Ssam 	200,	B200,
31913796Ssam 	300,	B300,
32013796Ssam 	600,	B600,
32113796Ssam 	1200,	B1200,
32213796Ssam 	1800,	B1800,
32313796Ssam 	2400,	B2400,
32413796Ssam 	4800,	B4800,
32513796Ssam 	9600,	B9600,
32613796Ssam 	19200,	EXTA,
32713796Ssam 	19,	EXTA,		/* for people who say 19.2K */
32813796Ssam 	38400,	EXTB,
32913796Ssam 	38,	EXTB,
33013796Ssam 	7200,	EXTB,		/* alternative */
33113796Ssam 	0
33213796Ssam };
33313796Ssam 
33413796Ssam speed(val)
33513796Ssam {
33613796Ssam 	register struct speedtab *sp;
33713796Ssam 
33813796Ssam 	if (val <= 15)
33917925Sralph 		return (val);
34013796Ssam 
34113796Ssam 	for (sp = speedtab; sp->speed; sp++)
34213796Ssam 		if (sp->speed == val)
34313796Ssam 			return (sp->uxname);
34413796Ssam 
34513796Ssam 	return (B300);		/* default in impossible cases */
34613796Ssam }
34713796Ssam 
34813796Ssam makeenv(env)
34913796Ssam 	char *env[];
35013796Ssam {
35113796Ssam 	static char termbuf[128] = "TERM=";
35213796Ssam 	register char *p, *q;
35313796Ssam 	register char **ep;
35413796Ssam 	char *index();
35513796Ssam 
35613796Ssam 	ep = env;
35713796Ssam 	if (TT && *TT) {
35813796Ssam 		strcat(termbuf, TT);
35913796Ssam 		*ep++ = termbuf;
36013796Ssam 	}
36113796Ssam 	if (p = EV) {
36213796Ssam 		q = p;
36313796Ssam 		while (q = index(q, ',')) {
36413796Ssam 			*q++ = '\0';
36513796Ssam 			*ep++ = p;
36613796Ssam 			p = q;
36713796Ssam 		}
36813796Ssam 		if (*p)
36913796Ssam 			*ep++ = p;
37013796Ssam 	}
37113796Ssam 	*ep = (char *)0;
37213796Ssam }
37313796Ssam 
37413796Ssam /*
37513796Ssam  * This speed select mechanism is written for the Develcon DATASWITCH.
37613796Ssam  * The Develcon sends a string of the form "B{speed}\n" at a predefined
37713796Ssam  * baud rate. This string indicates the user's actual speed.
37813796Ssam  * The routine below returns the terminal type mapped from derived speed.
37913796Ssam  */
38013796Ssam struct	portselect {
38113796Ssam 	char	*ps_baud;
38213796Ssam 	char	*ps_type;
38313796Ssam } portspeeds[] = {
38413796Ssam 	{ "B110",	"std.110" },
38513796Ssam 	{ "B134",	"std.134" },
38613796Ssam 	{ "B150",	"std.150" },
38713796Ssam 	{ "B300",	"std.300" },
38813796Ssam 	{ "B600",	"std.600" },
38913796Ssam 	{ "B1200",	"std.1200" },
39013796Ssam 	{ "B2400",	"std.2400" },
39113796Ssam 	{ "B4800",	"std.4800" },
39213796Ssam 	{ "B9600",	"std.9600" },
39325233Smckusick 	{ "B19200",	"std.19200" },
39413796Ssam 	{ 0 }
39513796Ssam };
39613796Ssam 
39713796Ssam char *
39813796Ssam portselector()
39913796Ssam {
40013796Ssam 	char c, baud[20], *type = "default";
40113796Ssam 	register struct portselect *ps;
40213796Ssam 	int len;
40313796Ssam 
40413796Ssam 	alarm(5*60);
40513796Ssam 	for (len = 0; len < sizeof (baud) - 1; len++) {
40613796Ssam 		if (read(0, &c, 1) <= 0)
40713796Ssam 			break;
40813796Ssam 		c &= 0177;
40913796Ssam 		if (c == '\n' || c == '\r')
41013796Ssam 			break;
41113796Ssam 		if (c == 'B')
41213796Ssam 			len = 0;	/* in case of leading garbage */
41313796Ssam 		baud[len] = c;
41413796Ssam 	}
41513796Ssam 	baud[len] = '\0';
41613796Ssam 	for (ps = portspeeds; ps->ps_baud; ps++)
41713796Ssam 		if (strcmp(ps->ps_baud, baud) == 0) {
41813796Ssam 			type = ps->ps_type;
41913796Ssam 			break;
42013796Ssam 		}
42113796Ssam 	sleep(2);	/* wait for connection to complete */
42213796Ssam 	return (type);
42313796Ssam }
42417925Sralph 
42517925Sralph /*
42617925Sralph  * This auto-baud speed select mechanism is written for the Micom 600
42717925Sralph  * portselector. Selection is done by looking at how the character '\r'
42817925Sralph  * is garbled at the different speeds.
42917925Sralph  */
43017925Sralph #include <sys/time.h>
43117925Sralph 
43217925Sralph char *
43317925Sralph autobaud()
43417925Sralph {
43517925Sralph 	int rfds;
43617925Sralph 	struct timeval timeout;
43717925Sralph 	char c, *type = "9600-baud";
43817925Sralph 	int null = 0;
43917925Sralph 
44017925Sralph 	ioctl(0, TIOCFLUSH, &null);
44117925Sralph 	rfds = 1 << 0;
44217925Sralph 	timeout.tv_sec = 5;
44317925Sralph 	timeout.tv_usec = 0;
44417925Sralph 	if (select(32, &rfds, (int *)0, (int *)0, &timeout) <= 0)
44517925Sralph 		return (type);
44617925Sralph 	if (read(0, &c, sizeof(char)) != sizeof(char))
44717925Sralph 		return (type);
44817925Sralph 	timeout.tv_sec = 0;
44917925Sralph 	timeout.tv_usec = 20;
45017925Sralph 	(void) select(32, (int *)0, (int *)0, (int *)0, &timeout);
45117925Sralph 	ioctl(0, TIOCFLUSH, &null);
45217925Sralph 	switch (c & 0377) {
45317925Sralph 
45417925Sralph 	case 0200:		/* 300-baud */
45517925Sralph 		type = "300-baud";
45617925Sralph 		break;
45717925Sralph 
45817925Sralph 	case 0346:		/* 1200-baud */
45917925Sralph 		type = "1200-baud";
46017925Sralph 		break;
46117925Sralph 
46217925Sralph 	case  015:		/* 2400-baud */
46317925Sralph 	case 0215:
46417925Sralph 		type = "2400-baud";
46517925Sralph 		break;
46617925Sralph 
46717925Sralph 	default:		/* 4800-baud */
46817925Sralph 		type = "4800-baud";
46917925Sralph 		break;
47017925Sralph 
47117925Sralph 	case 0377:		/* 9600-baud */
47217925Sralph 		type = "9600-baud";
47317925Sralph 		break;
47417925Sralph 	}
47517925Sralph 	return (type);
47617925Sralph }
477