Home | History | Annotate | Line # | Download | only in getty
subr.c revision 1.2
      1 /*
      2  * Copyright (c) 1983 The Regents of the University of California.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *	This product includes software developed by the University of
     16  *	California, Berkeley and its contributors.
     17  * 4. Neither the name of the University nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #ifndef lint
     35 static char sccsid[] = "@(#)subr.c	5.10 (Berkeley) 2/26/91";
     36 #endif /* not lint */
     37 
     38 /*
     39  * Melbourne getty.
     40  */
     41 #define USE_OLD_TTY
     42 #include <sgtty.h>
     43 #include <unistd.h>
     44 #include <string.h>
     45 #include "gettytab.h"
     46 
     47 extern	struct sgttyb tmode;
     48 extern	struct tchars tc;
     49 extern	struct ltchars ltc;
     50 
     51 /*
     52  * Get a table entry.
     53  */
     54 gettable(name, buf, area)
     55 	char *name, *buf, *area;
     56 {
     57 	register struct gettystrs *sp;
     58 	register struct gettynums *np;
     59 	register struct gettyflags *fp;
     60 	register n;
     61 
     62 	hopcount = 0;		/* new lookup, start fresh */
     63 	if (getent(buf, name) != 1)
     64 		return;
     65 
     66 	for (sp = gettystrs; sp->field; sp++)
     67 		sp->value = getstr(sp->field, &area);
     68 	for (np = gettynums; np->field; np++) {
     69 		n = getnum(np->field);
     70 		if (n == -1)
     71 			np->set = 0;
     72 		else {
     73 			np->set = 1;
     74 			np->value = n;
     75 		}
     76 	}
     77 	for (fp = gettyflags; fp->field; fp++) {
     78 		n = getflag(fp->field);
     79 		if (n == -1)
     80 			fp->set = 0;
     81 		else {
     82 			fp->set = 1;
     83 			fp->value = n ^ fp->invrt;
     84 		}
     85 	}
     86 }
     87 
     88 gendefaults()
     89 {
     90 	register struct gettystrs *sp;
     91 	register struct gettynums *np;
     92 	register struct gettyflags *fp;
     93 
     94 	for (sp = gettystrs; sp->field; sp++)
     95 		if (sp->value)
     96 			sp->defalt = sp->value;
     97 	for (np = gettynums; np->field; np++)
     98 		if (np->set)
     99 			np->defalt = np->value;
    100 	for (fp = gettyflags; fp->field; fp++)
    101 		if (fp->set)
    102 			fp->defalt = fp->value;
    103 		else
    104 			fp->defalt = fp->invrt;
    105 }
    106 
    107 setdefaults()
    108 {
    109 	register struct gettystrs *sp;
    110 	register struct gettynums *np;
    111 	register struct gettyflags *fp;
    112 
    113 	for (sp = gettystrs; sp->field; sp++)
    114 		if (!sp->value)
    115 			sp->value = sp->defalt;
    116 	for (np = gettynums; np->field; np++)
    117 		if (!np->set)
    118 			np->value = np->defalt;
    119 	for (fp = gettyflags; fp->field; fp++)
    120 		if (!fp->set)
    121 			fp->value = fp->defalt;
    122 }
    123 
    124 static char **
    125 charnames[] = {
    126 	&ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
    127 	&SU, &DS, &RP, &FL, &WE, &LN, 0
    128 };
    129 
    130 static char *
    131 charvars[] = {
    132 	&tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
    133 	&tc.t_quitc, &tc.t_startc, &tc.t_stopc,
    134 	&tc.t_eofc, &tc.t_brkc, &ltc.t_suspc,
    135 	&ltc.t_dsuspc, &ltc.t_rprntc, &ltc.t_flushc,
    136 	&ltc.t_werasc, &ltc.t_lnextc, 0
    137 };
    138 
    139 setchars()
    140 {
    141 	register int i;
    142 	register char *p;
    143 
    144 	for (i = 0; charnames[i]; i++) {
    145 		p = *charnames[i];
    146 		if (p && *p)
    147 			*charvars[i] = *p;
    148 		else
    149 			*charvars[i] = '\377';
    150 	}
    151 }
    152 
    153 long
    154 setflags(n)
    155 {
    156 	register long f;
    157 
    158 	switch (n) {
    159 	case 0:
    160 		if (F0set)
    161 			return(F0);
    162 		break;
    163 	case 1:
    164 		if (F1set)
    165 			return(F1);
    166 		break;
    167 	default:
    168 		if (F2set)
    169 			return(F2);
    170 		break;
    171 	}
    172 
    173 	f = 0;
    174 
    175 	if (AP)
    176 		f |= ANYP;
    177 	else if (OP)
    178 		f |= ODDP;
    179 	else if (EP)
    180 		f |= EVENP;
    181 
    182 	if (UC)
    183 		f |= LCASE;
    184 
    185 	if (NL)
    186 		f |= CRMOD;
    187 
    188 	f |= delaybits();
    189 
    190 	if (n == 1) {		/* read mode flags */
    191 		if (RW)
    192 			f |= RAW;
    193 		else
    194 			f |= CBREAK;
    195 		return (f);
    196 	}
    197 
    198 	if (!HT)
    199 		f |= XTABS;
    200 
    201 	if (n == 0)
    202 		return (f);
    203 
    204 	if (CB)
    205 		f |= CRTBS;
    206 
    207 	if (CE)
    208 		f |= CRTERA;
    209 
    210 	if (CK)
    211 		f |= CRTKIL;
    212 
    213 	if (PE)
    214 		f |= PRTERA;
    215 
    216 	if (EC)
    217 		f |= ECHO;
    218 
    219 	if (XC)
    220 		f |= CTLECH;
    221 
    222 	if (DX)
    223 		f |= DECCTQ;
    224 
    225 	return (f);
    226 }
    227 
    228 struct delayval {
    229 	unsigned	delay;		/* delay in ms */
    230 	int		bits;
    231 };
    232 
    233 /*
    234  * below are random guesses, I can't be bothered checking
    235  */
    236 
    237 struct delayval	crdelay[] = {
    238 	1,		CR1,
    239 	2,		CR2,
    240 	3,		CR3,
    241 	83,		CR1,
    242 	166,		CR2,
    243 	0,		CR3,
    244 };
    245 
    246 struct delayval nldelay[] = {
    247 	1,		NL1,		/* special, calculated */
    248 	2,		NL2,
    249 	3,		NL3,
    250 	100,		NL2,
    251 	0,		NL3,
    252 };
    253 
    254 struct delayval	bsdelay[] = {
    255 	1,		BS1,
    256 	0,		0,
    257 };
    258 
    259 struct delayval	ffdelay[] = {
    260 	1,		FF1,
    261 	1750,		FF1,
    262 	0,		FF1,
    263 };
    264 
    265 struct delayval	tbdelay[] = {
    266 	1,		TAB1,
    267 	2,		TAB2,
    268 	3,		XTABS,		/* this is expand tabs */
    269 	100,		TAB1,
    270 	0,		TAB2,
    271 };
    272 
    273 delaybits()
    274 {
    275 	register f;
    276 
    277 	f  = adelay(CD, crdelay);
    278 	f |= adelay(ND, nldelay);
    279 	f |= adelay(FD, ffdelay);
    280 	f |= adelay(TD, tbdelay);
    281 	f |= adelay(BD, bsdelay);
    282 	return (f);
    283 }
    284 
    285 adelay(ms, dp)
    286 	register ms;
    287 	register struct delayval *dp;
    288 {
    289 	if (ms == 0)
    290 		return (0);
    291 	while (dp->delay && ms > dp->delay)
    292 		dp++;
    293 	return (dp->bits);
    294 }
    295 
    296 char	editedhost[32];
    297 
    298 edithost(pat)
    299 	register char *pat;
    300 {
    301 	register char *host = HN;
    302 	register char *res = editedhost;
    303 
    304 	if (!pat)
    305 		pat = "";
    306 	while (*pat) {
    307 		switch (*pat) {
    308 
    309 		case '#':
    310 			if (*host)
    311 				host++;
    312 			break;
    313 
    314 		case '@':
    315 			if (*host)
    316 				*res++ = *host++;
    317 			break;
    318 
    319 		default:
    320 			*res++ = *pat;
    321 			break;
    322 
    323 		}
    324 		if (res == &editedhost[sizeof editedhost - 1]) {
    325 			*res = '\0';
    326 			return;
    327 		}
    328 		pat++;
    329 	}
    330 	if (*host)
    331 		strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
    332 	else
    333 		*res = '\0';
    334 	editedhost[sizeof editedhost - 1] = '\0';
    335 }
    336 
    337 struct speedtab {
    338 	int	speed;
    339 	int	uxname;
    340 } speedtab[] = {
    341 	50,	B50,
    342 	75,	B75,
    343 	110,	B110,
    344 	134,	B134,
    345 	150,	B150,
    346 	200,	B200,
    347 	300,	B300,
    348 	600,	B600,
    349 	1200,	B1200,
    350 	1800,	B1800,
    351 	2400,	B2400,
    352 	4800,	B4800,
    353 	9600,	B9600,
    354 	19200,	EXTA,
    355 	19,	EXTA,		/* for people who say 19.2K */
    356 	38400,	EXTB,
    357 	38,	EXTB,
    358 	7200,	EXTB,		/* alternative */
    359 	57600,	B57600,
    360 	115200,	B115200,
    361 	0
    362 };
    363 
    364 speed(val)
    365 {
    366 	register struct speedtab *sp;
    367 
    368 	if (val <= 15)
    369 		return (val);
    370 
    371 	for (sp = speedtab; sp->speed; sp++)
    372 		if (sp->speed == val)
    373 			return (sp->uxname);
    374 
    375 	return (B300);		/* default in impossible cases */
    376 }
    377 
    378 makeenv(env)
    379 	char *env[];
    380 {
    381 	static char termbuf[128] = "TERM=";
    382 	register char *p, *q;
    383 	register char **ep;
    384 	char *index();
    385 
    386 	ep = env;
    387 	if (TT && *TT) {
    388 		strcat(termbuf, TT);
    389 		*ep++ = termbuf;
    390 	}
    391 	if (p = EV) {
    392 		q = p;
    393 		while (q = index(q, ',')) {
    394 			*q++ = '\0';
    395 			*ep++ = p;
    396 			p = q;
    397 		}
    398 		if (*p)
    399 			*ep++ = p;
    400 	}
    401 	*ep = (char *)0;
    402 }
    403 
    404 /*
    405  * This speed select mechanism is written for the Develcon DATASWITCH.
    406  * The Develcon sends a string of the form "B{speed}\n" at a predefined
    407  * baud rate. This string indicates the user's actual speed.
    408  * The routine below returns the terminal type mapped from derived speed.
    409  */
    410 struct	portselect {
    411 	char	*ps_baud;
    412 	char	*ps_type;
    413 } portspeeds[] = {
    414 	{ "B110",	"std.110" },
    415 	{ "B134",	"std.134" },
    416 	{ "B150",	"std.150" },
    417 	{ "B300",	"std.300" },
    418 	{ "B600",	"std.600" },
    419 	{ "B1200",	"std.1200" },
    420 	{ "B2400",	"std.2400" },
    421 	{ "B4800",	"std.4800" },
    422 	{ "B9600",	"std.9600" },
    423 	{ "B19200",	"std.19200" },
    424 	{ 0 }
    425 };
    426 
    427 char *
    428 portselector()
    429 {
    430 	char c, baud[20], *type = "default";
    431 	register struct portselect *ps;
    432 	int len;
    433 
    434 	alarm(5*60);
    435 	for (len = 0; len < sizeof (baud) - 1; len++) {
    436 		if (read(STDIN_FILENO, &c, 1) <= 0)
    437 			break;
    438 		c &= 0177;
    439 		if (c == '\n' || c == '\r')
    440 			break;
    441 		if (c == 'B')
    442 			len = 0;	/* in case of leading garbage */
    443 		baud[len] = c;
    444 	}
    445 	baud[len] = '\0';
    446 	for (ps = portspeeds; ps->ps_baud; ps++)
    447 		if (strcmp(ps->ps_baud, baud) == 0) {
    448 			type = ps->ps_type;
    449 			break;
    450 		}
    451 	sleep(2);	/* wait for connection to complete */
    452 	return (type);
    453 }
    454 
    455 /*
    456  * This auto-baud speed select mechanism is written for the Micom 600
    457  * portselector. Selection is done by looking at how the character '\r'
    458  * is garbled at the different speeds.
    459  */
    460 #include <sys/time.h>
    461 
    462 char *
    463 autobaud()
    464 {
    465 	int rfds;
    466 	struct timeval timeout;
    467 	char c, *type = "9600-baud";
    468 	int null = 0;
    469 
    470 	ioctl(0, TIOCFLUSH, &null);
    471 	rfds = 1 << 0;
    472 	timeout.tv_sec = 5;
    473 	timeout.tv_usec = 0;
    474 	if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
    475 	    (fd_set *)NULL, &timeout) <= 0)
    476 		return (type);
    477 	if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
    478 		return (type);
    479 	timeout.tv_sec = 0;
    480 	timeout.tv_usec = 20;
    481 	(void) select(32, (fd_set *)NULL, (fd_set *)NULL,
    482 	    (fd_set *)NULL, &timeout);
    483 	ioctl(0, TIOCFLUSH, &null);
    484 	switch (c & 0377) {
    485 
    486 	case 0200:		/* 300-baud */
    487 		type = "300-baud";
    488 		break;
    489 
    490 	case 0346:		/* 1200-baud */
    491 		type = "1200-baud";
    492 		break;
    493 
    494 	case  015:		/* 2400-baud */
    495 	case 0215:
    496 		type = "2400-baud";
    497 		break;
    498 
    499 	default:		/* 4800-baud */
    500 		type = "4800-baud";
    501 		break;
    502 
    503 	case 0377:		/* 9600-baud */
    504 		type = "9600-baud";
    505 		break;
    506 	}
    507 	return (type);
    508 }
    509