xref: /csrg-svn/libexec/getty/subr.c (revision 42668)
119061Sdist /*
236930Sbostic  * Copyright (c) 1983 The Regents of the University of California.
336930Sbostic  * All rights reserved.
436930Sbostic  *
536930Sbostic  * Redistribution and use in source and binary forms are permitted
636930Sbostic  * provided that the above copyright notice and this paragraph are
736930Sbostic  * duplicated in all such forms and that any documentation,
836930Sbostic  * advertising materials, and other materials related to such
936930Sbostic  * distribution and use acknowledge that the software was developed
1036930Sbostic  * by the University of California, Berkeley.  The name of the
1136930Sbostic  * University may not be used to endorse or promote products derived
1236930Sbostic  * from this software without specific prior written permission.
1336930Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1436930Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1536930Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1619061Sdist  */
1719061Sdist 
1813796Ssam #ifndef lint
19*42668Smarc static char sccsid[] = "@(#)subr.c	5.6 (Berkeley) 06/01/90";
2036930Sbostic #endif /* not lint */
2113796Ssam 
2213796Ssam /*
2313796Ssam  * Melbourne getty.
2413796Ssam  */
25*42668Smarc #define USE_OLD_TTY
2613796Ssam #include <sgtty.h>
2713796Ssam #include "gettytab.h"
2813796Ssam 
2913796Ssam extern	struct sgttyb tmode;
3013796Ssam extern	struct tchars tc;
3113796Ssam extern	struct ltchars ltc;
3213796Ssam 
3313796Ssam /*
3413796Ssam  * Get a table entry.
3513796Ssam  */
3613796Ssam gettable(name, buf, area)
3713796Ssam 	char *name, *buf, *area;
3813796Ssam {
3913796Ssam 	register struct gettystrs *sp;
4013796Ssam 	register struct gettynums *np;
4113796Ssam 	register struct gettyflags *fp;
4213796Ssam 	register n;
4313796Ssam 
4413796Ssam 	hopcount = 0;		/* new lookup, start fresh */
4513796Ssam 	if (getent(buf, name) != 1)
4613796Ssam 		return;
4713796Ssam 
4813796Ssam 	for (sp = gettystrs; sp->field; sp++)
4913796Ssam 		sp->value = getstr(sp->field, &area);
5013796Ssam 	for (np = gettynums; np->field; np++) {
5113796Ssam 		n = getnum(np->field);
5213796Ssam 		if (n == -1)
5313796Ssam 			np->set = 0;
5413796Ssam 		else {
5513796Ssam 			np->set = 1;
5613796Ssam 			np->value = n;
5713796Ssam 		}
5813796Ssam 	}
5913796Ssam 	for (fp = gettyflags; fp->field; fp++) {
6013796Ssam 		n = getflag(fp->field);
6113796Ssam 		if (n == -1)
6213796Ssam 			fp->set = 0;
6313796Ssam 		else {
6413796Ssam 			fp->set = 1;
6513796Ssam 			fp->value = n ^ fp->invrt;
6613796Ssam 		}
6713796Ssam 	}
6813796Ssam }
6913796Ssam 
7013796Ssam gendefaults()
7113796Ssam {
7213796Ssam 	register struct gettystrs *sp;
7313796Ssam 	register struct gettynums *np;
7413796Ssam 	register struct gettyflags *fp;
7513796Ssam 
7613796Ssam 	for (sp = gettystrs; sp->field; sp++)
7713796Ssam 		if (sp->value)
7813796Ssam 			sp->defalt = sp->value;
7913796Ssam 	for (np = gettynums; np->field; np++)
8013796Ssam 		if (np->set)
8113796Ssam 			np->defalt = np->value;
8213796Ssam 	for (fp = gettyflags; fp->field; fp++)
8313796Ssam 		if (fp->set)
8413796Ssam 			fp->defalt = fp->value;
8513796Ssam 		else
8613796Ssam 			fp->defalt = fp->invrt;
8713796Ssam }
8813796Ssam 
8913796Ssam setdefaults()
9013796Ssam {
9113796Ssam 	register struct gettystrs *sp;
9213796Ssam 	register struct gettynums *np;
9313796Ssam 	register struct gettyflags *fp;
9413796Ssam 
9513796Ssam 	for (sp = gettystrs; sp->field; sp++)
9613796Ssam 		if (!sp->value)
9713796Ssam 			sp->value = sp->defalt;
9813796Ssam 	for (np = gettynums; np->field; np++)
9913796Ssam 		if (!np->set)
10013796Ssam 			np->value = np->defalt;
10113796Ssam 	for (fp = gettyflags; fp->field; fp++)
10213796Ssam 		if (!fp->set)
10313796Ssam 			fp->value = fp->defalt;
10413796Ssam }
10513796Ssam 
10613796Ssam static char **
10713796Ssam charnames[] = {
10813796Ssam 	&ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
10913796Ssam 	&SU, &DS, &RP, &FL, &WE, &LN, 0
11013796Ssam };
11113796Ssam 
11213796Ssam static char *
11313796Ssam charvars[] = {
11413796Ssam 	&tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
11513796Ssam 	&tc.t_quitc, &tc.t_startc, &tc.t_stopc,
11613796Ssam 	&tc.t_eofc, &tc.t_brkc, &ltc.t_suspc,
11713796Ssam 	&ltc.t_dsuspc, &ltc.t_rprntc, &ltc.t_flushc,
11813796Ssam 	&ltc.t_werasc, &ltc.t_lnextc, 0
11913796Ssam };
12013796Ssam 
12113796Ssam setchars()
12213796Ssam {
12313796Ssam 	register int i;
12413796Ssam 	register char *p;
12513796Ssam 
12613796Ssam 	for (i = 0; charnames[i]; i++) {
12713796Ssam 		p = *charnames[i];
12813796Ssam 		if (p && *p)
12913796Ssam 			*charvars[i] = *p;
13013796Ssam 		else
13119946Sedward 			*charvars[i] = '\377';
13213796Ssam 	}
13313796Ssam }
13413796Ssam 
13513796Ssam long
13613796Ssam setflags(n)
13713796Ssam {
13813796Ssam 	register long f;
13913796Ssam 
14013796Ssam 	switch (n) {
14113796Ssam 	case 0:
14213796Ssam 		if (F0set)
14313796Ssam 			return(F0);
14413796Ssam 		break;
14513796Ssam 	case 1:
14613796Ssam 		if (F1set)
14713796Ssam 			return(F1);
14813796Ssam 		break;
14913796Ssam 	default:
15013796Ssam 		if (F2set)
15113796Ssam 			return(F2);
15213796Ssam 		break;
15313796Ssam 	}
15413796Ssam 
15513796Ssam 	f = 0;
15613796Ssam 
15713796Ssam 	if (AP)
15813796Ssam 		f |= ANYP;
15913796Ssam 	else if (OP)
16013796Ssam 		f |= ODDP;
16113796Ssam 	else if (EP)
16213796Ssam 		f |= EVENP;
16313796Ssam 
16413796Ssam 	if (UC)
16513796Ssam 		f |= LCASE;
16613796Ssam 
16713796Ssam 	if (NL)
16813796Ssam 		f |= CRMOD;
16913796Ssam 
17013796Ssam 	f |= delaybits();
17113796Ssam 
17213796Ssam 	if (n == 1) {		/* read mode flags */
17313796Ssam 		if (RW)
17413796Ssam 			f |= RAW;
17513796Ssam 		else
17613796Ssam 			f |= CBREAK;
17713796Ssam 		return (f);
17813796Ssam 	}
17913796Ssam 
18013796Ssam 	if (!HT)
18113796Ssam 		f |= XTABS;
18213796Ssam 
18313796Ssam 	if (n == 0)
18413796Ssam 		return (f);
18513796Ssam 
18613796Ssam 	if (CB)
18713796Ssam 		f |= CRTBS;
18813796Ssam 
18913796Ssam 	if (CE)
19013796Ssam 		f |= CRTERA;
19113796Ssam 
19216565Sralph 	if (CK)
19316565Sralph 		f |= CRTKIL;
19416565Sralph 
19513796Ssam 	if (PE)
19613796Ssam 		f |= PRTERA;
19713796Ssam 
19813796Ssam 	if (EC)
19913796Ssam 		f |= ECHO;
20013796Ssam 
20113796Ssam 	if (XC)
20213796Ssam 		f |= CTLECH;
20313796Ssam 
20425730Smckusick 	if (DX)
20525730Smckusick 		f |= DECCTQ;
20625730Smckusick 
20713796Ssam 	return (f);
20813796Ssam }
20913796Ssam 
21013796Ssam struct delayval {
21113796Ssam 	unsigned	delay;		/* delay in ms */
21213796Ssam 	int		bits;
21313796Ssam };
21413796Ssam 
21513796Ssam /*
21613796Ssam  * below are random guesses, I can't be bothered checking
21713796Ssam  */
21813796Ssam 
21913796Ssam struct delayval	crdelay[] = {
22013827Skre 	1,		CR1,
22113827Skre 	2,		CR2,
22213827Skre 	3,		CR3,
22313827Skre 	83,		CR1,
22413827Skre 	166,		CR2,
22513796Ssam 	0,		CR3,
22613796Ssam };
22713796Ssam 
22813796Ssam struct delayval nldelay[] = {
22913796Ssam 	1,		NL1,		/* special, calculated */
23013827Skre 	2,		NL2,
23113827Skre 	3,		NL3,
23213827Skre 	100,		NL2,
23313796Ssam 	0,		NL3,
23413796Ssam };
23513796Ssam 
23613796Ssam struct delayval	bsdelay[] = {
23713827Skre 	1,		BS1,
23813796Ssam 	0,		0,
23913796Ssam };
24013796Ssam 
24113796Ssam struct delayval	ffdelay[] = {
24213827Skre 	1,		FF1,
24313796Ssam 	1750,		FF1,
24413796Ssam 	0,		FF1,
24513796Ssam };
24613796Ssam 
24713796Ssam struct delayval	tbdelay[] = {
24813827Skre 	1,		TAB1,
24913827Skre 	2,		TAB2,
25013827Skre 	3,		XTABS,		/* this is expand tabs */
25113827Skre 	100,		TAB1,
25213796Ssam 	0,		TAB2,
25313796Ssam };
25413796Ssam 
25513796Ssam delaybits()
25613796Ssam {
25713796Ssam 	register f;
25813796Ssam 
25913796Ssam 	f  = adelay(CD, crdelay);
26013796Ssam 	f |= adelay(ND, nldelay);
26113796Ssam 	f |= adelay(FD, ffdelay);
26213796Ssam 	f |= adelay(TD, tbdelay);
26313796Ssam 	f |= adelay(BD, bsdelay);
26413796Ssam 	return (f);
26513796Ssam }
26613796Ssam 
26713796Ssam adelay(ms, dp)
26813796Ssam 	register ms;
26913796Ssam 	register struct delayval *dp;
27013796Ssam {
27113796Ssam 	if (ms == 0)
27213796Ssam 		return (0);
27313796Ssam 	while (dp->delay && ms > dp->delay)
27413796Ssam 		dp++;
27513796Ssam 	return (dp->bits);
27613796Ssam }
27713796Ssam 
27813796Ssam char	editedhost[32];
27913796Ssam 
28013796Ssam edithost(pat)
28113796Ssam 	register char *pat;
28213796Ssam {
28313796Ssam 	register char *host = HN;
28413796Ssam 	register char *res = editedhost;
28513796Ssam 
28613796Ssam 	if (!pat)
28713796Ssam 		pat = "";
28813796Ssam 	while (*pat) {
28913796Ssam 		switch (*pat) {
29013796Ssam 
29113796Ssam 		case '#':
29213796Ssam 			if (*host)
29313796Ssam 				host++;
29413796Ssam 			break;
29513796Ssam 
29613796Ssam 		case '@':
29713796Ssam 			if (*host)
29813796Ssam 				*res++ = *host++;
29913796Ssam 			break;
30013796Ssam 
30113796Ssam 		default:
30213796Ssam 			*res++ = *pat;
30313796Ssam 			break;
30413796Ssam 
30513796Ssam 		}
30613796Ssam 		if (res == &editedhost[sizeof editedhost - 1]) {
30713796Ssam 			*res = '\0';
30813796Ssam 			return;
30913796Ssam 		}
31013796Ssam 		pat++;
31113796Ssam 	}
31213796Ssam 	if (*host)
31313796Ssam 		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
31413796Ssam 	else
31513796Ssam 		*res = '\0';
31613796Ssam 	editedhost[sizeof editedhost - 1] = '\0';
31713796Ssam }
31813796Ssam 
31913796Ssam struct speedtab {
32013796Ssam 	int	speed;
32113796Ssam 	int	uxname;
32213796Ssam } speedtab[] = {
32313796Ssam 	50,	B50,
32413796Ssam 	75,	B75,
32513796Ssam 	110,	B110,
32613796Ssam 	134,	B134,
32713796Ssam 	150,	B150,
32813796Ssam 	200,	B200,
32913796Ssam 	300,	B300,
33013796Ssam 	600,	B600,
33113796Ssam 	1200,	B1200,
33213796Ssam 	1800,	B1800,
33313796Ssam 	2400,	B2400,
33413796Ssam 	4800,	B4800,
33513796Ssam 	9600,	B9600,
33613796Ssam 	19200,	EXTA,
33713796Ssam 	19,	EXTA,		/* for people who say 19.2K */
33813796Ssam 	38400,	EXTB,
33913796Ssam 	38,	EXTB,
34013796Ssam 	7200,	EXTB,		/* alternative */
34113796Ssam 	0
34213796Ssam };
34313796Ssam 
34413796Ssam speed(val)
34513796Ssam {
34613796Ssam 	register struct speedtab *sp;
34713796Ssam 
34813796Ssam 	if (val <= 15)
34917925Sralph 		return (val);
35013796Ssam 
35113796Ssam 	for (sp = speedtab; sp->speed; sp++)
35213796Ssam 		if (sp->speed == val)
35313796Ssam 			return (sp->uxname);
35413796Ssam 
35513796Ssam 	return (B300);		/* default in impossible cases */
35613796Ssam }
35713796Ssam 
35813796Ssam makeenv(env)
35913796Ssam 	char *env[];
36013796Ssam {
36113796Ssam 	static char termbuf[128] = "TERM=";
36213796Ssam 	register char *p, *q;
36313796Ssam 	register char **ep;
36413796Ssam 	char *index();
36513796Ssam 
36613796Ssam 	ep = env;
36713796Ssam 	if (TT && *TT) {
36813796Ssam 		strcat(termbuf, TT);
36913796Ssam 		*ep++ = termbuf;
37013796Ssam 	}
37113796Ssam 	if (p = EV) {
37213796Ssam 		q = p;
37313796Ssam 		while (q = index(q, ',')) {
37413796Ssam 			*q++ = '\0';
37513796Ssam 			*ep++ = p;
37613796Ssam 			p = q;
37713796Ssam 		}
37813796Ssam 		if (*p)
37913796Ssam 			*ep++ = p;
38013796Ssam 	}
38113796Ssam 	*ep = (char *)0;
38213796Ssam }
38313796Ssam 
38413796Ssam /*
38513796Ssam  * This speed select mechanism is written for the Develcon DATASWITCH.
38613796Ssam  * The Develcon sends a string of the form "B{speed}\n" at a predefined
38713796Ssam  * baud rate. This string indicates the user's actual speed.
38813796Ssam  * The routine below returns the terminal type mapped from derived speed.
38913796Ssam  */
39013796Ssam struct	portselect {
39113796Ssam 	char	*ps_baud;
39213796Ssam 	char	*ps_type;
39313796Ssam } portspeeds[] = {
39413796Ssam 	{ "B110",	"std.110" },
39513796Ssam 	{ "B134",	"std.134" },
39613796Ssam 	{ "B150",	"std.150" },
39713796Ssam 	{ "B300",	"std.300" },
39813796Ssam 	{ "B600",	"std.600" },
39913796Ssam 	{ "B1200",	"std.1200" },
40013796Ssam 	{ "B2400",	"std.2400" },
40113796Ssam 	{ "B4800",	"std.4800" },
40213796Ssam 	{ "B9600",	"std.9600" },
40325233Smckusick 	{ "B19200",	"std.19200" },
40413796Ssam 	{ 0 }
40513796Ssam };
40613796Ssam 
40713796Ssam char *
40813796Ssam portselector()
40913796Ssam {
41013796Ssam 	char c, baud[20], *type = "default";
41113796Ssam 	register struct portselect *ps;
41213796Ssam 	int len;
41313796Ssam 
41413796Ssam 	alarm(5*60);
41513796Ssam 	for (len = 0; len < sizeof (baud) - 1; len++) {
41613796Ssam 		if (read(0, &c, 1) <= 0)
41713796Ssam 			break;
41813796Ssam 		c &= 0177;
41913796Ssam 		if (c == '\n' || c == '\r')
42013796Ssam 			break;
42113796Ssam 		if (c == 'B')
42213796Ssam 			len = 0;	/* in case of leading garbage */
42313796Ssam 		baud[len] = c;
42413796Ssam 	}
42513796Ssam 	baud[len] = '\0';
42613796Ssam 	for (ps = portspeeds; ps->ps_baud; ps++)
42713796Ssam 		if (strcmp(ps->ps_baud, baud) == 0) {
42813796Ssam 			type = ps->ps_type;
42913796Ssam 			break;
43013796Ssam 		}
43113796Ssam 	sleep(2);	/* wait for connection to complete */
43213796Ssam 	return (type);
43313796Ssam }
43417925Sralph 
43517925Sralph /*
43617925Sralph  * This auto-baud speed select mechanism is written for the Micom 600
43717925Sralph  * portselector. Selection is done by looking at how the character '\r'
43817925Sralph  * is garbled at the different speeds.
43917925Sralph  */
44017925Sralph #include <sys/time.h>
44117925Sralph 
44217925Sralph char *
44317925Sralph autobaud()
44417925Sralph {
44517925Sralph 	int rfds;
44617925Sralph 	struct timeval timeout;
44717925Sralph 	char c, *type = "9600-baud";
44817925Sralph 	int null = 0;
44917925Sralph 
45017925Sralph 	ioctl(0, TIOCFLUSH, &null);
45117925Sralph 	rfds = 1 << 0;
45217925Sralph 	timeout.tv_sec = 5;
45317925Sralph 	timeout.tv_usec = 0;
45417925Sralph 	if (select(32, &rfds, (int *)0, (int *)0, &timeout) <= 0)
45517925Sralph 		return (type);
45617925Sralph 	if (read(0, &c, sizeof(char)) != sizeof(char))
45717925Sralph 		return (type);
45817925Sralph 	timeout.tv_sec = 0;
45917925Sralph 	timeout.tv_usec = 20;
46017925Sralph 	(void) select(32, (int *)0, (int *)0, (int *)0, &timeout);
46117925Sralph 	ioctl(0, TIOCFLUSH, &null);
46217925Sralph 	switch (c & 0377) {
46317925Sralph 
46417925Sralph 	case 0200:		/* 300-baud */
46517925Sralph 		type = "300-baud";
46617925Sralph 		break;
46717925Sralph 
46817925Sralph 	case 0346:		/* 1200-baud */
46917925Sralph 		type = "1200-baud";
47017925Sralph 		break;
47117925Sralph 
47217925Sralph 	case  015:		/* 2400-baud */
47317925Sralph 	case 0215:
47417925Sralph 		type = "2400-baud";
47517925Sralph 		break;
47617925Sralph 
47717925Sralph 	default:		/* 4800-baud */
47817925Sralph 		type = "4800-baud";
47917925Sralph 		break;
48017925Sralph 
48117925Sralph 	case 0377:		/* 9600-baud */
48217925Sralph 		type = "9600-baud";
48317925Sralph 		break;
48417925Sralph 	}
48517925Sralph 	return (type);
48617925Sralph }
487