xref: /csrg-svn/libexec/getty/subr.c (revision 16565)
113796Ssam #ifndef lint
2*16565Sralph static char sccsid[] = "@(#)subr.c	4.3 (Berkeley) 84/06/05";
313796Ssam #endif
413796Ssam 
513796Ssam /*
613796Ssam  * Melbourne getty.
713796Ssam  */
813796Ssam #include <sgtty.h>
913796Ssam #include "gettytab.h"
1013796Ssam 
1113796Ssam extern	struct sgttyb tmode;
1213796Ssam extern	struct tchars tc;
1313796Ssam extern	struct ltchars ltc;
1413796Ssam 
1513796Ssam /*
1613796Ssam  * Get a table entry.
1713796Ssam  */
1813796Ssam gettable(name, buf, area)
1913796Ssam 	char *name, *buf, *area;
2013796Ssam {
2113796Ssam 	register struct gettystrs *sp;
2213796Ssam 	register struct gettynums *np;
2313796Ssam 	register struct gettyflags *fp;
2413796Ssam 	register n;
2513796Ssam 
2613796Ssam 	hopcount = 0;		/* new lookup, start fresh */
2713796Ssam 	if (getent(buf, name) != 1)
2813796Ssam 		return;
2913796Ssam 
3013796Ssam 	for (sp = gettystrs; sp->field; sp++)
3113796Ssam 		sp->value = getstr(sp->field, &area);
3213796Ssam 	for (np = gettynums; np->field; np++) {
3313796Ssam 		n = getnum(np->field);
3413796Ssam 		if (n == -1)
3513796Ssam 			np->set = 0;
3613796Ssam 		else {
3713796Ssam 			np->set = 1;
3813796Ssam 			np->value = n;
3913796Ssam 		}
4013796Ssam 	}
4113796Ssam 	for (fp = gettyflags; fp->field; fp++) {
4213796Ssam 		n = getflag(fp->field);
4313796Ssam 		if (n == -1)
4413796Ssam 			fp->set = 0;
4513796Ssam 		else {
4613796Ssam 			fp->set = 1;
4713796Ssam 			fp->value = n ^ fp->invrt;
4813796Ssam 		}
4913796Ssam 	}
5013796Ssam }
5113796Ssam 
5213796Ssam gendefaults()
5313796Ssam {
5413796Ssam 	register struct gettystrs *sp;
5513796Ssam 	register struct gettynums *np;
5613796Ssam 	register struct gettyflags *fp;
5713796Ssam 
5813796Ssam 	for (sp = gettystrs; sp->field; sp++)
5913796Ssam 		if (sp->value)
6013796Ssam 			sp->defalt = sp->value;
6113796Ssam 	for (np = gettynums; np->field; np++)
6213796Ssam 		if (np->set)
6313796Ssam 			np->defalt = np->value;
6413796Ssam 	for (fp = gettyflags; fp->field; fp++)
6513796Ssam 		if (fp->set)
6613796Ssam 			fp->defalt = fp->value;
6713796Ssam 		else
6813796Ssam 			fp->defalt = fp->invrt;
6913796Ssam }
7013796Ssam 
7113796Ssam setdefaults()
7213796Ssam {
7313796Ssam 	register struct gettystrs *sp;
7413796Ssam 	register struct gettynums *np;
7513796Ssam 	register struct gettyflags *fp;
7613796Ssam 
7713796Ssam 	for (sp = gettystrs; sp->field; sp++)
7813796Ssam 		if (!sp->value)
7913796Ssam 			sp->value = sp->defalt;
8013796Ssam 	for (np = gettynums; np->field; np++)
8113796Ssam 		if (!np->set)
8213796Ssam 			np->value = np->defalt;
8313796Ssam 	for (fp = gettyflags; fp->field; fp++)
8413796Ssam 		if (!fp->set)
8513796Ssam 			fp->value = fp->defalt;
8613796Ssam }
8713796Ssam 
8813796Ssam static char **
8913796Ssam charnames[] = {
9013796Ssam 	&ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
9113796Ssam 	&SU, &DS, &RP, &FL, &WE, &LN, 0
9213796Ssam };
9313796Ssam 
9413796Ssam static char *
9513796Ssam charvars[] = {
9613796Ssam 	&tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
9713796Ssam 	&tc.t_quitc, &tc.t_startc, &tc.t_stopc,
9813796Ssam 	&tc.t_eofc, &tc.t_brkc, &ltc.t_suspc,
9913796Ssam 	&ltc.t_dsuspc, &ltc.t_rprntc, &ltc.t_flushc,
10013796Ssam 	&ltc.t_werasc, &ltc.t_lnextc, 0
10113796Ssam };
10213796Ssam 
10313796Ssam setchars()
10413796Ssam {
10513796Ssam 	register int i;
10613796Ssam 	register char *p;
10713796Ssam 
10813796Ssam 	for (i = 0; charnames[i]; i++) {
10913796Ssam 		p = *charnames[i];
11013796Ssam 		if (p && *p)
11113796Ssam 			*charvars[i] = *p;
11213796Ssam 		else
11313796Ssam 			*charvars[i] = '\0377';
11413796Ssam 	}
11513796Ssam }
11613796Ssam 
11713796Ssam long
11813796Ssam setflags(n)
11913796Ssam {
12013796Ssam 	register long f;
12113796Ssam 
12213796Ssam 	switch (n) {
12313796Ssam 	case 0:
12413796Ssam 		if (F0set)
12513796Ssam 			return(F0);
12613796Ssam 		break;
12713796Ssam 	case 1:
12813796Ssam 		if (F1set)
12913796Ssam 			return(F1);
13013796Ssam 		break;
13113796Ssam 	default:
13213796Ssam 		if (F2set)
13313796Ssam 			return(F2);
13413796Ssam 		break;
13513796Ssam 	}
13613796Ssam 
13713796Ssam 	f = 0;
13813796Ssam 
13913796Ssam 	if (AP)
14013796Ssam 		f |= ANYP;
14113796Ssam 	else if (OP)
14213796Ssam 		f |= ODDP;
14313796Ssam 	else if (EP)
14413796Ssam 		f |= EVENP;
14513796Ssam 
14613796Ssam 	if (UC)
14713796Ssam 		f |= LCASE;
14813796Ssam 
14913796Ssam 	if (NL)
15013796Ssam 		f |= CRMOD;
15113796Ssam 
15213796Ssam 	f |= delaybits();
15313796Ssam 
15413796Ssam 	if (n == 1) {		/* read mode flags */
15513796Ssam 		if (RW)
15613796Ssam 			f |= RAW;
15713796Ssam 		else
15813796Ssam 			f |= CBREAK;
15913796Ssam 		return (f);
16013796Ssam 	}
16113796Ssam 
16213796Ssam 	if (!HT)
16313796Ssam 		f |= XTABS;
16413796Ssam 
16513796Ssam 	if (n == 0)
16613796Ssam 		return (f);
16713796Ssam 
16813796Ssam 	if (CB)
16913796Ssam 		f |= CRTBS;
17013796Ssam 
17113796Ssam 	if (CE)
17213796Ssam 		f |= CRTERA;
17313796Ssam 
174*16565Sralph 	if (CK)
175*16565Sralph 		f |= CRTKIL;
176*16565Sralph 
17713796Ssam 	if (PE)
17813796Ssam 		f |= PRTERA;
17913796Ssam 
18013796Ssam 	if (EC)
18113796Ssam 		f |= ECHO;
18213796Ssam 
18313796Ssam 	if (XC)
18413796Ssam 		f |= CTLECH;
18513796Ssam 
18613796Ssam 	return (f);
18713796Ssam }
18813796Ssam 
18913796Ssam struct delayval {
19013796Ssam 	unsigned	delay;		/* delay in ms */
19113796Ssam 	int		bits;
19213796Ssam };
19313796Ssam 
19413796Ssam /*
19513796Ssam  * below are random guesses, I can't be bothered checking
19613796Ssam  */
19713796Ssam 
19813796Ssam struct delayval	crdelay[] = {
19913827Skre 	1,		CR1,
20013827Skre 	2,		CR2,
20113827Skre 	3,		CR3,
20213827Skre 	83,		CR1,
20313827Skre 	166,		CR2,
20413796Ssam 	0,		CR3,
20513796Ssam };
20613796Ssam 
20713796Ssam struct delayval nldelay[] = {
20813796Ssam 	1,		NL1,		/* special, calculated */
20913827Skre 	2,		NL2,
21013827Skre 	3,		NL3,
21113827Skre 	100,		NL2,
21213796Ssam 	0,		NL3,
21313796Ssam };
21413796Ssam 
21513796Ssam struct delayval	bsdelay[] = {
21613827Skre 	1,		BS1,
21713796Ssam 	0,		0,
21813796Ssam };
21913796Ssam 
22013796Ssam struct delayval	ffdelay[] = {
22113827Skre 	1,		FF1,
22213796Ssam 	1750,		FF1,
22313796Ssam 	0,		FF1,
22413796Ssam };
22513796Ssam 
22613796Ssam struct delayval	tbdelay[] = {
22713827Skre 	1,		TAB1,
22813827Skre 	2,		TAB2,
22913827Skre 	3,		XTABS,		/* this is expand tabs */
23013827Skre 	100,		TAB1,
23113796Ssam 	0,		TAB2,
23213796Ssam };
23313796Ssam 
23413796Ssam delaybits()
23513796Ssam {
23613796Ssam 	register f;
23713796Ssam 
23813796Ssam 	f  = adelay(CD, crdelay);
23913796Ssam 	f |= adelay(ND, nldelay);
24013796Ssam 	f |= adelay(FD, ffdelay);
24113796Ssam 	f |= adelay(TD, tbdelay);
24213796Ssam 	f |= adelay(BD, bsdelay);
24313796Ssam 	return (f);
24413796Ssam }
24513796Ssam 
24613796Ssam adelay(ms, dp)
24713796Ssam 	register ms;
24813796Ssam 	register struct delayval *dp;
24913796Ssam {
25013796Ssam 	if (ms == 0)
25113796Ssam 		return (0);
25213796Ssam 	while (dp->delay && ms > dp->delay)
25313796Ssam 		dp++;
25413796Ssam 	return (dp->bits);
25513796Ssam }
25613796Ssam 
25713796Ssam char	editedhost[32];
25813796Ssam 
25913796Ssam edithost(pat)
26013796Ssam 	register char *pat;
26113796Ssam {
26213796Ssam 	register char *host = HN;
26313796Ssam 	register char *res = editedhost;
26413796Ssam 
26513796Ssam 	if (!pat)
26613796Ssam 		pat = "";
26713796Ssam 	while (*pat) {
26813796Ssam 		switch (*pat) {
26913796Ssam 
27013796Ssam 		case '#':
27113796Ssam 			if (*host)
27213796Ssam 				host++;
27313796Ssam 			break;
27413796Ssam 
27513796Ssam 		case '@':
27613796Ssam 			if (*host)
27713796Ssam 				*res++ = *host++;
27813796Ssam 			break;
27913796Ssam 
28013796Ssam 		default:
28113796Ssam 			*res++ = *pat;
28213796Ssam 			break;
28313796Ssam 
28413796Ssam 		}
28513796Ssam 		if (res == &editedhost[sizeof editedhost - 1]) {
28613796Ssam 			*res = '\0';
28713796Ssam 			return;
28813796Ssam 		}
28913796Ssam 		pat++;
29013796Ssam 	}
29113796Ssam 	if (*host)
29213796Ssam 		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
29313796Ssam 	else
29413796Ssam 		*res = '\0';
29513796Ssam 	editedhost[sizeof editedhost - 1] = '\0';
29613796Ssam }
29713796Ssam 
29813796Ssam struct speedtab {
29913796Ssam 	int	speed;
30013796Ssam 	int	uxname;
30113796Ssam } speedtab[] = {
30213796Ssam 	50,	B50,
30313796Ssam 	75,	B75,
30413796Ssam 	110,	B110,
30513796Ssam 	134,	B134,
30613796Ssam 	150,	B150,
30713796Ssam 	200,	B200,
30813796Ssam 	300,	B300,
30913796Ssam 	600,	B600,
31013796Ssam 	1200,	B1200,
31113796Ssam 	1800,	B1800,
31213796Ssam 	2400,	B2400,
31313796Ssam 	4800,	B4800,
31413796Ssam 	9600,	B9600,
31513796Ssam 	19200,	EXTA,
31613796Ssam 	19,	EXTA,		/* for people who say 19.2K */
31713796Ssam 	38400,	EXTB,
31813796Ssam 	38,	EXTB,
31913796Ssam 	7200,	EXTB,		/* alternative */
32013796Ssam 	0
32113796Ssam };
32213796Ssam 
32313796Ssam speed(val)
32413796Ssam {
32513796Ssam 	register struct speedtab *sp;
32613796Ssam 
32713796Ssam 	if (val <= 15)
32813796Ssam 		return(val);
32913796Ssam 
33013796Ssam 	for (sp = speedtab; sp->speed; sp++)
33113796Ssam 		if (sp->speed == val)
33213796Ssam 			return (sp->uxname);
33313796Ssam 
33413796Ssam 	return (B300);		/* default in impossible cases */
33513796Ssam }
33613796Ssam 
33713796Ssam makeenv(env)
33813796Ssam 	char *env[];
33913796Ssam {
34013796Ssam 	static char termbuf[128] = "TERM=";
34113796Ssam 	register char *p, *q;
34213796Ssam 	register char **ep;
34313796Ssam 	char *index();
34413796Ssam 
34513796Ssam 	ep = env;
34613796Ssam 	if (TT && *TT) {
34713796Ssam 		strcat(termbuf, TT);
34813796Ssam 		*ep++ = termbuf;
34913796Ssam 	}
35013796Ssam 	if (p = EV) {
35113796Ssam 		q = p;
35213796Ssam 		while (q = index(q, ',')) {
35313796Ssam 			*q++ = '\0';
35413796Ssam 			*ep++ = p;
35513796Ssam 			p = q;
35613796Ssam 		}
35713796Ssam 		if (*p)
35813796Ssam 			*ep++ = p;
35913796Ssam 	}
36013796Ssam 	*ep = (char *)0;
36113796Ssam }
36213796Ssam 
36313796Ssam /*
36413796Ssam  * This speed select mechanism is written for the Develcon DATASWITCH.
36513796Ssam  * The Develcon sends a string of the form "B{speed}\n" at a predefined
36613796Ssam  * baud rate. This string indicates the user's actual speed.
36713796Ssam  * The routine below returns the terminal type mapped from derived speed.
36813796Ssam  */
36913796Ssam struct	portselect {
37013796Ssam 	char	*ps_baud;
37113796Ssam 	char	*ps_type;
37213796Ssam } portspeeds[] = {
37313796Ssam 	{ "B110",	"std.110" },
37413796Ssam 	{ "B134",	"std.134" },
37513796Ssam 	{ "B150",	"std.150" },
37613796Ssam 	{ "B300",	"std.300" },
37713796Ssam 	{ "B600",	"std.600" },
37813796Ssam 	{ "B1200",	"std.1200" },
37913796Ssam 	{ "B2400",	"std.2400" },
38013796Ssam 	{ "B4800",	"std.4800" },
38113796Ssam 	{ "B9600",	"std.9600" },
38213796Ssam 	{ 0 }
38313796Ssam };
38413796Ssam 
38513796Ssam char *
38613796Ssam portselector()
38713796Ssam {
38813796Ssam 	char c, baud[20], *type = "default";
38913796Ssam 	register struct portselect *ps;
39013796Ssam 	int len;
39113796Ssam 
39213796Ssam 	alarm(5*60);
39313796Ssam 	for (len = 0; len < sizeof (baud) - 1; len++) {
39413796Ssam 		if (read(0, &c, 1) <= 0)
39513796Ssam 			break;
39613796Ssam 		c &= 0177;
39713796Ssam 		if (c == '\n' || c == '\r')
39813796Ssam 			break;
39913796Ssam 		if (c == 'B')
40013796Ssam 			len = 0;	/* in case of leading garbage */
40113796Ssam 		baud[len] = c;
40213796Ssam 	}
40313796Ssam 	baud[len] = '\0';
40413796Ssam 	for (ps = portspeeds; ps->ps_baud; ps++)
40513796Ssam 		if (strcmp(ps->ps_baud, baud) == 0) {
40613796Ssam 			type = ps->ps_type;
40713796Ssam 			break;
40813796Ssam 		}
40913796Ssam 	sleep(2);	/* wait for connection to complete */
41013796Ssam 	return (type);
41113796Ssam }
412