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