Home | History | Annotate | Line # | Download | only in getty
subr.c revision 1.1
      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 	0
    360 };
    361 
    362 speed(val)
    363 {
    364 	register struct speedtab *sp;
    365 
    366 	if (val <= 15)
    367 		return (val);
    368 
    369 	for (sp = speedtab; sp->speed; sp++)
    370 		if (sp->speed == val)
    371 			return (sp->uxname);
    372 
    373 	return (B300);		/* default in impossible cases */
    374 }
    375 
    376 makeenv(env)
    377 	char *env[];
    378 {
    379 	static char termbuf[128] = "TERM=";
    380 	register char *p, *q;
    381 	register char **ep;
    382 	char *index();
    383 
    384 	ep = env;
    385 	if (TT && *TT) {
    386 		strcat(termbuf, TT);
    387 		*ep++ = termbuf;
    388 	}
    389 	if (p = EV) {
    390 		q = p;
    391 		while (q = index(q, ',')) {
    392 			*q++ = '\0';
    393 			*ep++ = p;
    394 			p = q;
    395 		}
    396 		if (*p)
    397 			*ep++ = p;
    398 	}
    399 	*ep = (char *)0;
    400 }
    401 
    402 /*
    403  * This speed select mechanism is written for the Develcon DATASWITCH.
    404  * The Develcon sends a string of the form "B{speed}\n" at a predefined
    405  * baud rate. This string indicates the user's actual speed.
    406  * The routine below returns the terminal type mapped from derived speed.
    407  */
    408 struct	portselect {
    409 	char	*ps_baud;
    410 	char	*ps_type;
    411 } portspeeds[] = {
    412 	{ "B110",	"std.110" },
    413 	{ "B134",	"std.134" },
    414 	{ "B150",	"std.150" },
    415 	{ "B300",	"std.300" },
    416 	{ "B600",	"std.600" },
    417 	{ "B1200",	"std.1200" },
    418 	{ "B2400",	"std.2400" },
    419 	{ "B4800",	"std.4800" },
    420 	{ "B9600",	"std.9600" },
    421 	{ "B19200",	"std.19200" },
    422 	{ 0 }
    423 };
    424 
    425 char *
    426 portselector()
    427 {
    428 	char c, baud[20], *type = "default";
    429 	register struct portselect *ps;
    430 	int len;
    431 
    432 	alarm(5*60);
    433 	for (len = 0; len < sizeof (baud) - 1; len++) {
    434 		if (read(STDIN_FILENO, &c, 1) <= 0)
    435 			break;
    436 		c &= 0177;
    437 		if (c == '\n' || c == '\r')
    438 			break;
    439 		if (c == 'B')
    440 			len = 0;	/* in case of leading garbage */
    441 		baud[len] = c;
    442 	}
    443 	baud[len] = '\0';
    444 	for (ps = portspeeds; ps->ps_baud; ps++)
    445 		if (strcmp(ps->ps_baud, baud) == 0) {
    446 			type = ps->ps_type;
    447 			break;
    448 		}
    449 	sleep(2);	/* wait for connection to complete */
    450 	return (type);
    451 }
    452 
    453 /*
    454  * This auto-baud speed select mechanism is written for the Micom 600
    455  * portselector. Selection is done by looking at how the character '\r'
    456  * is garbled at the different speeds.
    457  */
    458 #include <sys/time.h>
    459 
    460 char *
    461 autobaud()
    462 {
    463 	int rfds;
    464 	struct timeval timeout;
    465 	char c, *type = "9600-baud";
    466 	int null = 0;
    467 
    468 	ioctl(0, TIOCFLUSH, &null);
    469 	rfds = 1 << 0;
    470 	timeout.tv_sec = 5;
    471 	timeout.tv_usec = 0;
    472 	if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
    473 	    (fd_set *)NULL, &timeout) <= 0)
    474 		return (type);
    475 	if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
    476 		return (type);
    477 	timeout.tv_sec = 0;
    478 	timeout.tv_usec = 20;
    479 	(void) select(32, (fd_set *)NULL, (fd_set *)NULL,
    480 	    (fd_set *)NULL, &timeout);
    481 	ioctl(0, TIOCFLUSH, &null);
    482 	switch (c & 0377) {
    483 
    484 	case 0200:		/* 300-baud */
    485 		type = "300-baud";
    486 		break;
    487 
    488 	case 0346:		/* 1200-baud */
    489 		type = "1200-baud";
    490 		break;
    491 
    492 	case  015:		/* 2400-baud */
    493 	case 0215:
    494 		type = "2400-baud";
    495 		break;
    496 
    497 	default:		/* 4800-baud */
    498 		type = "4800-baud";
    499 		break;
    500 
    501 	case 0377:		/* 9600-baud */
    502 		type = "9600-baud";
    503 		break;
    504 	}
    505 	return (type);
    506 }
    507