xref: /csrg-svn/libexec/getty/subr.c (revision 25730)
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*25730Smckusick static char sccsid[] = "@(#)subr.c	5.4 (Berkeley) 01/07/86";
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
11919946Sedward 			*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 
192*25730Smckusick 	if (DX)
193*25730Smckusick 		f |= DECCTQ;
194*25730Smckusick 
19513796Ssam 	return (f);
19613796Ssam }
19713796Ssam 
19813796Ssam struct delayval {
19913796Ssam 	unsigned	delay;		/* delay in ms */
20013796Ssam 	int		bits;
20113796Ssam };
20213796Ssam 
20313796Ssam /*
20413796Ssam  * below are random guesses, I can't be bothered checking
20513796Ssam  */
20613796Ssam 
20713796Ssam struct delayval	crdelay[] = {
20813827Skre 	1,		CR1,
20913827Skre 	2,		CR2,
21013827Skre 	3,		CR3,
21113827Skre 	83,		CR1,
21213827Skre 	166,		CR2,
21313796Ssam 	0,		CR3,
21413796Ssam };
21513796Ssam 
21613796Ssam struct delayval nldelay[] = {
21713796Ssam 	1,		NL1,		/* special, calculated */
21813827Skre 	2,		NL2,
21913827Skre 	3,		NL3,
22013827Skre 	100,		NL2,
22113796Ssam 	0,		NL3,
22213796Ssam };
22313796Ssam 
22413796Ssam struct delayval	bsdelay[] = {
22513827Skre 	1,		BS1,
22613796Ssam 	0,		0,
22713796Ssam };
22813796Ssam 
22913796Ssam struct delayval	ffdelay[] = {
23013827Skre 	1,		FF1,
23113796Ssam 	1750,		FF1,
23213796Ssam 	0,		FF1,
23313796Ssam };
23413796Ssam 
23513796Ssam struct delayval	tbdelay[] = {
23613827Skre 	1,		TAB1,
23713827Skre 	2,		TAB2,
23813827Skre 	3,		XTABS,		/* this is expand tabs */
23913827Skre 	100,		TAB1,
24013796Ssam 	0,		TAB2,
24113796Ssam };
24213796Ssam 
24313796Ssam delaybits()
24413796Ssam {
24513796Ssam 	register f;
24613796Ssam 
24713796Ssam 	f  = adelay(CD, crdelay);
24813796Ssam 	f |= adelay(ND, nldelay);
24913796Ssam 	f |= adelay(FD, ffdelay);
25013796Ssam 	f |= adelay(TD, tbdelay);
25113796Ssam 	f |= adelay(BD, bsdelay);
25213796Ssam 	return (f);
25313796Ssam }
25413796Ssam 
25513796Ssam adelay(ms, dp)
25613796Ssam 	register ms;
25713796Ssam 	register struct delayval *dp;
25813796Ssam {
25913796Ssam 	if (ms == 0)
26013796Ssam 		return (0);
26113796Ssam 	while (dp->delay && ms > dp->delay)
26213796Ssam 		dp++;
26313796Ssam 	return (dp->bits);
26413796Ssam }
26513796Ssam 
26613796Ssam char	editedhost[32];
26713796Ssam 
26813796Ssam edithost(pat)
26913796Ssam 	register char *pat;
27013796Ssam {
27113796Ssam 	register char *host = HN;
27213796Ssam 	register char *res = editedhost;
27313796Ssam 
27413796Ssam 	if (!pat)
27513796Ssam 		pat = "";
27613796Ssam 	while (*pat) {
27713796Ssam 		switch (*pat) {
27813796Ssam 
27913796Ssam 		case '#':
28013796Ssam 			if (*host)
28113796Ssam 				host++;
28213796Ssam 			break;
28313796Ssam 
28413796Ssam 		case '@':
28513796Ssam 			if (*host)
28613796Ssam 				*res++ = *host++;
28713796Ssam 			break;
28813796Ssam 
28913796Ssam 		default:
29013796Ssam 			*res++ = *pat;
29113796Ssam 			break;
29213796Ssam 
29313796Ssam 		}
29413796Ssam 		if (res == &editedhost[sizeof editedhost - 1]) {
29513796Ssam 			*res = '\0';
29613796Ssam 			return;
29713796Ssam 		}
29813796Ssam 		pat++;
29913796Ssam 	}
30013796Ssam 	if (*host)
30113796Ssam 		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
30213796Ssam 	else
30313796Ssam 		*res = '\0';
30413796Ssam 	editedhost[sizeof editedhost - 1] = '\0';
30513796Ssam }
30613796Ssam 
30713796Ssam struct speedtab {
30813796Ssam 	int	speed;
30913796Ssam 	int	uxname;
31013796Ssam } speedtab[] = {
31113796Ssam 	50,	B50,
31213796Ssam 	75,	B75,
31313796Ssam 	110,	B110,
31413796Ssam 	134,	B134,
31513796Ssam 	150,	B150,
31613796Ssam 	200,	B200,
31713796Ssam 	300,	B300,
31813796Ssam 	600,	B600,
31913796Ssam 	1200,	B1200,
32013796Ssam 	1800,	B1800,
32113796Ssam 	2400,	B2400,
32213796Ssam 	4800,	B4800,
32313796Ssam 	9600,	B9600,
32413796Ssam 	19200,	EXTA,
32513796Ssam 	19,	EXTA,		/* for people who say 19.2K */
32613796Ssam 	38400,	EXTB,
32713796Ssam 	38,	EXTB,
32813796Ssam 	7200,	EXTB,		/* alternative */
32913796Ssam 	0
33013796Ssam };
33113796Ssam 
33213796Ssam speed(val)
33313796Ssam {
33413796Ssam 	register struct speedtab *sp;
33513796Ssam 
33613796Ssam 	if (val <= 15)
33717925Sralph 		return (val);
33813796Ssam 
33913796Ssam 	for (sp = speedtab; sp->speed; sp++)
34013796Ssam 		if (sp->speed == val)
34113796Ssam 			return (sp->uxname);
34213796Ssam 
34313796Ssam 	return (B300);		/* default in impossible cases */
34413796Ssam }
34513796Ssam 
34613796Ssam makeenv(env)
34713796Ssam 	char *env[];
34813796Ssam {
34913796Ssam 	static char termbuf[128] = "TERM=";
35013796Ssam 	register char *p, *q;
35113796Ssam 	register char **ep;
35213796Ssam 	char *index();
35313796Ssam 
35413796Ssam 	ep = env;
35513796Ssam 	if (TT && *TT) {
35613796Ssam 		strcat(termbuf, TT);
35713796Ssam 		*ep++ = termbuf;
35813796Ssam 	}
35913796Ssam 	if (p = EV) {
36013796Ssam 		q = p;
36113796Ssam 		while (q = index(q, ',')) {
36213796Ssam 			*q++ = '\0';
36313796Ssam 			*ep++ = p;
36413796Ssam 			p = q;
36513796Ssam 		}
36613796Ssam 		if (*p)
36713796Ssam 			*ep++ = p;
36813796Ssam 	}
36913796Ssam 	*ep = (char *)0;
37013796Ssam }
37113796Ssam 
37213796Ssam /*
37313796Ssam  * This speed select mechanism is written for the Develcon DATASWITCH.
37413796Ssam  * The Develcon sends a string of the form "B{speed}\n" at a predefined
37513796Ssam  * baud rate. This string indicates the user's actual speed.
37613796Ssam  * The routine below returns the terminal type mapped from derived speed.
37713796Ssam  */
37813796Ssam struct	portselect {
37913796Ssam 	char	*ps_baud;
38013796Ssam 	char	*ps_type;
38113796Ssam } portspeeds[] = {
38213796Ssam 	{ "B110",	"std.110" },
38313796Ssam 	{ "B134",	"std.134" },
38413796Ssam 	{ "B150",	"std.150" },
38513796Ssam 	{ "B300",	"std.300" },
38613796Ssam 	{ "B600",	"std.600" },
38713796Ssam 	{ "B1200",	"std.1200" },
38813796Ssam 	{ "B2400",	"std.2400" },
38913796Ssam 	{ "B4800",	"std.4800" },
39013796Ssam 	{ "B9600",	"std.9600" },
39125233Smckusick 	{ "B19200",	"std.19200" },
39213796Ssam 	{ 0 }
39313796Ssam };
39413796Ssam 
39513796Ssam char *
39613796Ssam portselector()
39713796Ssam {
39813796Ssam 	char c, baud[20], *type = "default";
39913796Ssam 	register struct portselect *ps;
40013796Ssam 	int len;
40113796Ssam 
40213796Ssam 	alarm(5*60);
40313796Ssam 	for (len = 0; len < sizeof (baud) - 1; len++) {
40413796Ssam 		if (read(0, &c, 1) <= 0)
40513796Ssam 			break;
40613796Ssam 		c &= 0177;
40713796Ssam 		if (c == '\n' || c == '\r')
40813796Ssam 			break;
40913796Ssam 		if (c == 'B')
41013796Ssam 			len = 0;	/* in case of leading garbage */
41113796Ssam 		baud[len] = c;
41213796Ssam 	}
41313796Ssam 	baud[len] = '\0';
41413796Ssam 	for (ps = portspeeds; ps->ps_baud; ps++)
41513796Ssam 		if (strcmp(ps->ps_baud, baud) == 0) {
41613796Ssam 			type = ps->ps_type;
41713796Ssam 			break;
41813796Ssam 		}
41913796Ssam 	sleep(2);	/* wait for connection to complete */
42013796Ssam 	return (type);
42113796Ssam }
42217925Sralph 
42317925Sralph /*
42417925Sralph  * This auto-baud speed select mechanism is written for the Micom 600
42517925Sralph  * portselector. Selection is done by looking at how the character '\r'
42617925Sralph  * is garbled at the different speeds.
42717925Sralph  */
42817925Sralph #include <sys/time.h>
42917925Sralph 
43017925Sralph char *
43117925Sralph autobaud()
43217925Sralph {
43317925Sralph 	int rfds;
43417925Sralph 	struct timeval timeout;
43517925Sralph 	char c, *type = "9600-baud";
43617925Sralph 	int null = 0;
43717925Sralph 
43817925Sralph 	ioctl(0, TIOCFLUSH, &null);
43917925Sralph 	rfds = 1 << 0;
44017925Sralph 	timeout.tv_sec = 5;
44117925Sralph 	timeout.tv_usec = 0;
44217925Sralph 	if (select(32, &rfds, (int *)0, (int *)0, &timeout) <= 0)
44317925Sralph 		return (type);
44417925Sralph 	if (read(0, &c, sizeof(char)) != sizeof(char))
44517925Sralph 		return (type);
44617925Sralph 	timeout.tv_sec = 0;
44717925Sralph 	timeout.tv_usec = 20;
44817925Sralph 	(void) select(32, (int *)0, (int *)0, (int *)0, &timeout);
44917925Sralph 	ioctl(0, TIOCFLUSH, &null);
45017925Sralph 	switch (c & 0377) {
45117925Sralph 
45217925Sralph 	case 0200:		/* 300-baud */
45317925Sralph 		type = "300-baud";
45417925Sralph 		break;
45517925Sralph 
45617925Sralph 	case 0346:		/* 1200-baud */
45717925Sralph 		type = "1200-baud";
45817925Sralph 		break;
45917925Sralph 
46017925Sralph 	case  015:		/* 2400-baud */
46117925Sralph 	case 0215:
46217925Sralph 		type = "2400-baud";
46317925Sralph 		break;
46417925Sralph 
46517925Sralph 	default:		/* 4800-baud */
46617925Sralph 		type = "4800-baud";
46717925Sralph 		break;
46817925Sralph 
46917925Sralph 	case 0377:		/* 9600-baud */
47017925Sralph 		type = "9600-baud";
47117925Sralph 		break;
47217925Sralph 	}
47317925Sralph 	return (type);
47417925Sralph }
475