xref: /csrg-svn/libexec/getty/subr.c (revision 13827)
113796Ssam #ifndef lint
2*13827Skre static char sccsid[] = "@(#)subr.c	4.2 (Berkeley) 83/07/07";
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 
17413796Ssam 	if (PE)
17513796Ssam 		f |= PRTERA;
17613796Ssam 
17713796Ssam 	if (EC)
17813796Ssam 		f |= ECHO;
17913796Ssam 
18013796Ssam 	if (XC)
18113796Ssam 		f |= CTLECH;
18213796Ssam 
18313796Ssam 	return (f);
18413796Ssam }
18513796Ssam 
18613796Ssam struct delayval {
18713796Ssam 	unsigned	delay;		/* delay in ms */
18813796Ssam 	int		bits;
18913796Ssam };
19013796Ssam 
19113796Ssam /*
19213796Ssam  * below are random guesses, I can't be bothered checking
19313796Ssam  */
19413796Ssam 
19513796Ssam struct delayval	crdelay[] = {
196*13827Skre 	1,		CR1,
197*13827Skre 	2,		CR2,
198*13827Skre 	3,		CR3,
199*13827Skre 	83,		CR1,
200*13827Skre 	166,		CR2,
20113796Ssam 	0,		CR3,
20213796Ssam };
20313796Ssam 
20413796Ssam struct delayval nldelay[] = {
20513796Ssam 	1,		NL1,		/* special, calculated */
206*13827Skre 	2,		NL2,
207*13827Skre 	3,		NL3,
208*13827Skre 	100,		NL2,
20913796Ssam 	0,		NL3,
21013796Ssam };
21113796Ssam 
21213796Ssam struct delayval	bsdelay[] = {
213*13827Skre 	1,		BS1,
21413796Ssam 	0,		0,
21513796Ssam };
21613796Ssam 
21713796Ssam struct delayval	ffdelay[] = {
218*13827Skre 	1,		FF1,
21913796Ssam 	1750,		FF1,
22013796Ssam 	0,		FF1,
22113796Ssam };
22213796Ssam 
22313796Ssam struct delayval	tbdelay[] = {
224*13827Skre 	1,		TAB1,
225*13827Skre 	2,		TAB2,
226*13827Skre 	3,		XTABS,		/* this is expand tabs */
227*13827Skre 	100,		TAB1,
22813796Ssam 	0,		TAB2,
22913796Ssam };
23013796Ssam 
23113796Ssam delaybits()
23213796Ssam {
23313796Ssam 	register f;
23413796Ssam 
23513796Ssam 	f  = adelay(CD, crdelay);
23613796Ssam 	f |= adelay(ND, nldelay);
23713796Ssam 	f |= adelay(FD, ffdelay);
23813796Ssam 	f |= adelay(TD, tbdelay);
23913796Ssam 	f |= adelay(BD, bsdelay);
24013796Ssam 	return (f);
24113796Ssam }
24213796Ssam 
24313796Ssam adelay(ms, dp)
24413796Ssam 	register ms;
24513796Ssam 	register struct delayval *dp;
24613796Ssam {
24713796Ssam 	if (ms == 0)
24813796Ssam 		return (0);
24913796Ssam 	while (dp->delay && ms > dp->delay)
25013796Ssam 		dp++;
25113796Ssam 	return (dp->bits);
25213796Ssam }
25313796Ssam 
25413796Ssam char	editedhost[32];
25513796Ssam 
25613796Ssam edithost(pat)
25713796Ssam 	register char *pat;
25813796Ssam {
25913796Ssam 	register char *host = HN;
26013796Ssam 	register char *res = editedhost;
26113796Ssam 
26213796Ssam 	if (!pat)
26313796Ssam 		pat = "";
26413796Ssam 	while (*pat) {
26513796Ssam 		switch (*pat) {
26613796Ssam 
26713796Ssam 		case '#':
26813796Ssam 			if (*host)
26913796Ssam 				host++;
27013796Ssam 			break;
27113796Ssam 
27213796Ssam 		case '@':
27313796Ssam 			if (*host)
27413796Ssam 				*res++ = *host++;
27513796Ssam 			break;
27613796Ssam 
27713796Ssam 		default:
27813796Ssam 			*res++ = *pat;
27913796Ssam 			break;
28013796Ssam 
28113796Ssam 		}
28213796Ssam 		if (res == &editedhost[sizeof editedhost - 1]) {
28313796Ssam 			*res = '\0';
28413796Ssam 			return;
28513796Ssam 		}
28613796Ssam 		pat++;
28713796Ssam 	}
28813796Ssam 	if (*host)
28913796Ssam 		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
29013796Ssam 	else
29113796Ssam 		*res = '\0';
29213796Ssam 	editedhost[sizeof editedhost - 1] = '\0';
29313796Ssam }
29413796Ssam 
29513796Ssam struct speedtab {
29613796Ssam 	int	speed;
29713796Ssam 	int	uxname;
29813796Ssam } speedtab[] = {
29913796Ssam 	50,	B50,
30013796Ssam 	75,	B75,
30113796Ssam 	110,	B110,
30213796Ssam 	134,	B134,
30313796Ssam 	150,	B150,
30413796Ssam 	200,	B200,
30513796Ssam 	300,	B300,
30613796Ssam 	600,	B600,
30713796Ssam 	1200,	B1200,
30813796Ssam 	1800,	B1800,
30913796Ssam 	2400,	B2400,
31013796Ssam 	4800,	B4800,
31113796Ssam 	9600,	B9600,
31213796Ssam 	19200,	EXTA,
31313796Ssam 	19,	EXTA,		/* for people who say 19.2K */
31413796Ssam 	38400,	EXTB,
31513796Ssam 	38,	EXTB,
31613796Ssam 	7200,	EXTB,		/* alternative */
31713796Ssam 	0
31813796Ssam };
31913796Ssam 
32013796Ssam speed(val)
32113796Ssam {
32213796Ssam 	register struct speedtab *sp;
32313796Ssam 
32413796Ssam 	if (val <= 15)
32513796Ssam 		return(val);
32613796Ssam 
32713796Ssam 	for (sp = speedtab; sp->speed; sp++)
32813796Ssam 		if (sp->speed == val)
32913796Ssam 			return (sp->uxname);
33013796Ssam 
33113796Ssam 	return (B300);		/* default in impossible cases */
33213796Ssam }
33313796Ssam 
33413796Ssam makeenv(env)
33513796Ssam 	char *env[];
33613796Ssam {
33713796Ssam 	static char termbuf[128] = "TERM=";
33813796Ssam 	register char *p, *q;
33913796Ssam 	register char **ep;
34013796Ssam 	char *index();
34113796Ssam 
34213796Ssam 	ep = env;
34313796Ssam 	if (TT && *TT) {
34413796Ssam 		strcat(termbuf, TT);
34513796Ssam 		*ep++ = termbuf;
34613796Ssam 	}
34713796Ssam 	if (p = EV) {
34813796Ssam 		q = p;
34913796Ssam 		while (q = index(q, ',')) {
35013796Ssam 			*q++ = '\0';
35113796Ssam 			*ep++ = p;
35213796Ssam 			p = q;
35313796Ssam 		}
35413796Ssam 		if (*p)
35513796Ssam 			*ep++ = p;
35613796Ssam 	}
35713796Ssam 	*ep = (char *)0;
35813796Ssam }
35913796Ssam 
36013796Ssam /*
36113796Ssam  * This speed select mechanism is written for the Develcon DATASWITCH.
36213796Ssam  * The Develcon sends a string of the form "B{speed}\n" at a predefined
36313796Ssam  * baud rate. This string indicates the user's actual speed.
36413796Ssam  * The routine below returns the terminal type mapped from derived speed.
36513796Ssam  */
36613796Ssam struct	portselect {
36713796Ssam 	char	*ps_baud;
36813796Ssam 	char	*ps_type;
36913796Ssam } portspeeds[] = {
37013796Ssam 	{ "B110",	"std.110" },
37113796Ssam 	{ "B134",	"std.134" },
37213796Ssam 	{ "B150",	"std.150" },
37313796Ssam 	{ "B300",	"std.300" },
37413796Ssam 	{ "B600",	"std.600" },
37513796Ssam 	{ "B1200",	"std.1200" },
37613796Ssam 	{ "B2400",	"std.2400" },
37713796Ssam 	{ "B4800",	"std.4800" },
37813796Ssam 	{ "B9600",	"std.9600" },
37913796Ssam 	{ 0 }
38013796Ssam };
38113796Ssam 
38213796Ssam char *
38313796Ssam portselector()
38413796Ssam {
38513796Ssam 	char c, baud[20], *type = "default";
38613796Ssam 	register struct portselect *ps;
38713796Ssam 	int len;
38813796Ssam 
38913796Ssam 	alarm(5*60);
39013796Ssam 	for (len = 0; len < sizeof (baud) - 1; len++) {
39113796Ssam 		if (read(0, &c, 1) <= 0)
39213796Ssam 			break;
39313796Ssam 		c &= 0177;
39413796Ssam 		if (c == '\n' || c == '\r')
39513796Ssam 			break;
39613796Ssam 		if (c == 'B')
39713796Ssam 			len = 0;	/* in case of leading garbage */
39813796Ssam 		baud[len] = c;
39913796Ssam 	}
40013796Ssam 	baud[len] = '\0';
40113796Ssam 	for (ps = portspeeds; ps->ps_baud; ps++)
40213796Ssam 		if (strcmp(ps->ps_baud, baud) == 0) {
40313796Ssam 			type = ps->ps_type;
40413796Ssam 			break;
40513796Ssam 		}
40613796Ssam 	sleep(2);	/* wait for connection to complete */
40713796Ssam 	return (type);
40813796Ssam }
409