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