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