Home | History | Annotate | Line # | Download | only in getty
subr.c revision 1.33.40.1
      1  1.33.40.1      yamt /*	$NetBSD: subr.c,v 1.33.40.1 2014/05/22 11:37:13 yamt Exp $	*/
      2       1.19   thorpej 
      3        1.1       cgd /*
      4        1.9        pk  * Copyright (c) 1983, 1993
      5        1.9        pk  *	The Regents of the University of California.  All rights reserved.
      6        1.1       cgd  *
      7        1.1       cgd  * Redistribution and use in source and binary forms, with or without
      8        1.1       cgd  * modification, are permitted provided that the following conditions
      9        1.1       cgd  * are met:
     10        1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     11        1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     12        1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13        1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     14        1.1       cgd  *    documentation and/or other materials provided with the distribution.
     15       1.29       agc  * 3. Neither the name of the University nor the names of its contributors
     16        1.1       cgd  *    may be used to endorse or promote products derived from this software
     17        1.1       cgd  *    without specific prior written permission.
     18        1.1       cgd  *
     19        1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20        1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21        1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22        1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23        1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24        1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25        1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26        1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27        1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28        1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29        1.1       cgd  * SUCH DAMAGE.
     30        1.1       cgd  */
     31        1.1       cgd 
     32       1.22     mikel #include <sys/cdefs.h>
     33        1.1       cgd #ifndef lint
     34       1.19   thorpej #if 0
     35       1.19   thorpej static char sccsid[] = "from: @(#)subr.c	8.1 (Berkeley) 6/4/93";
     36       1.19   thorpej #else
     37  1.33.40.1      yamt __RCSID("$NetBSD: subr.c,v 1.33.40.1 2014/05/22 11:37:13 yamt Exp $");
     38       1.19   thorpej #endif
     39        1.1       cgd #endif /* not lint */
     40        1.1       cgd 
     41        1.1       cgd /*
     42        1.1       cgd  * Melbourne getty.
     43        1.1       cgd  */
     44        1.7        pk #define COMPAT_43
     45       1.20   thorpej #include <sys/param.h>
     46       1.22     mikel #include <sys/ioctl.h>
     47       1.22     mikel 
     48        1.4       cgd #include <stdlib.h>
     49        1.1       cgd #include <string.h>
     50        1.7        pk #include <termios.h>
     51       1.22     mikel #include <unistd.h>
     52       1.27    itojun #include <poll.h>
     53  1.33.40.1      yamt #include <util.h>
     54        1.4       cgd 
     55       1.22     mikel #include "extern.h"
     56        1.1       cgd #include "gettytab.h"
     57        1.4       cgd #include "pathnames.h"
     58        1.1       cgd 
     59        1.9        pk extern	struct termios tmode, omode;
     60        1.1       cgd 
     61       1.25   thorpej static void	compatflags(long);
     62        1.9        pk 
     63        1.1       cgd /*
     64        1.1       cgd  * Get a table entry.
     65        1.1       cgd  */
     66        1.9        pk void
     67  1.33.40.1      yamt gettable(const char *name, char *buf)
     68        1.1       cgd {
     69       1.23       mrg 	struct gettystrs *sp;
     70       1.23       mrg 	struct gettynums *np;
     71       1.23       mrg 	struct gettyflags *fp;
     72        1.4       cgd 	long n;
     73       1.30  christos 	const char *dba[2];
     74        1.4       cgd 	dba[0] = _PATH_GETTYTAB;
     75  1.33.40.1      yamt 	dba[1] = NULL;
     76        1.1       cgd 
     77        1.4       cgd 	if (cgetent(&buf, dba, name) != 0)
     78        1.1       cgd 		return;
     79        1.1       cgd 
     80        1.1       cgd 	for (sp = gettystrs; sp->field; sp++)
     81       1.33  christos 		(void)cgetstr(buf, sp->field, &sp->value);
     82        1.1       cgd 	for (np = gettynums; np->field; np++) {
     83        1.4       cgd 		if (cgetnum(buf, np->field, &n) == -1)
     84        1.1       cgd 			np->set = 0;
     85        1.1       cgd 		else {
     86        1.1       cgd 			np->set = 1;
     87        1.1       cgd 			np->value = n;
     88        1.1       cgd 		}
     89        1.1       cgd 	}
     90        1.1       cgd 	for (fp = gettyflags; fp->field; fp++) {
     91        1.4       cgd 		if (cgetcap(buf, fp->field, ':') == NULL)
     92        1.1       cgd 			fp->set = 0;
     93        1.1       cgd 		else {
     94        1.1       cgd 			fp->set = 1;
     95        1.4       cgd 			fp->value = 1 ^ fp->invrt;
     96        1.1       cgd 		}
     97        1.1       cgd 	}
     98        1.4       cgd #ifdef DEBUG
     99        1.4       cgd 	printf("name=\"%s\", buf=\"%s\"\n", name, buf);
    100        1.4       cgd 	for (sp = gettystrs; sp->field; sp++)
    101        1.4       cgd 		printf("cgetstr: %s=%s\n", sp->field, sp->value);
    102        1.4       cgd 	for (np = gettynums; np->field; np++)
    103        1.4       cgd 		printf("cgetnum: %s=%d\n", np->field, np->value);
    104        1.4       cgd 	for (fp = gettyflags; fp->field; fp++)
    105        1.9        pk 		printf("cgetflags: %s='%c' set='%c'\n", fp->field,
    106        1.9        pk 		       fp->value + '0', fp->set + '0');
    107        1.4       cgd 	exit(1);
    108        1.4       cgd #endif /* DEBUG */
    109        1.1       cgd }
    110        1.1       cgd 
    111        1.9        pk void
    112       1.25   thorpej gendefaults(void)
    113        1.1       cgd {
    114       1.23       mrg 	struct gettystrs *sp;
    115       1.23       mrg 	struct gettynums *np;
    116       1.23       mrg 	struct gettyflags *fp;
    117        1.1       cgd 
    118        1.1       cgd 	for (sp = gettystrs; sp->field; sp++)
    119        1.1       cgd 		if (sp->value)
    120        1.1       cgd 			sp->defalt = sp->value;
    121        1.1       cgd 	for (np = gettynums; np->field; np++)
    122        1.1       cgd 		if (np->set)
    123        1.1       cgd 			np->defalt = np->value;
    124        1.1       cgd 	for (fp = gettyflags; fp->field; fp++)
    125        1.1       cgd 		if (fp->set)
    126        1.1       cgd 			fp->defalt = fp->value;
    127        1.1       cgd 		else
    128        1.1       cgd 			fp->defalt = fp->invrt;
    129        1.1       cgd }
    130        1.1       cgd 
    131        1.9        pk void
    132       1.25   thorpej setdefaults(void)
    133        1.1       cgd {
    134       1.23       mrg 	struct gettystrs *sp;
    135       1.23       mrg 	struct gettynums *np;
    136       1.23       mrg 	struct gettyflags *fp;
    137        1.1       cgd 
    138        1.1       cgd 	for (sp = gettystrs; sp->field; sp++)
    139        1.1       cgd 		if (!sp->value)
    140  1.33.40.1      yamt 			sp->value = sp->defalt ? estrdup(sp->defalt) : NULL;
    141        1.1       cgd 	for (np = gettynums; np->field; np++)
    142        1.1       cgd 		if (!np->set)
    143        1.1       cgd 			np->value = np->defalt;
    144        1.1       cgd 	for (fp = gettyflags; fp->field; fp++)
    145        1.1       cgd 		if (!fp->set)
    146        1.1       cgd 			fp->value = fp->defalt;
    147        1.1       cgd }
    148        1.1       cgd 
    149        1.1       cgd static char **
    150        1.1       cgd charnames[] = {
    151        1.1       cgd 	&ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
    152       1.31  christos 	&SU, &DS, &RP, &FL, &WE, &LN, &ST, &B2, 0
    153        1.1       cgd };
    154        1.1       cgd 
    155       1.32  christos static cc_t *
    156        1.1       cgd charvars[] = {
    157        1.7        pk 	&tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR],
    158        1.7        pk 	&tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP],
    159        1.7        pk 	&tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP],
    160        1.7        pk 	&tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD],
    161       1.31  christos 	&tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], &tmode.c_cc[VSTATUS],
    162       1.31  christos 	&tmode.c_cc[VEOL2], 0
    163        1.1       cgd };
    164        1.1       cgd 
    165        1.9        pk void
    166       1.25   thorpej setchars(void)
    167        1.1       cgd {
    168       1.23       mrg 	int i;
    169       1.23       mrg 	char *p;
    170        1.1       cgd 
    171        1.1       cgd 	for (i = 0; charnames[i]; i++) {
    172        1.1       cgd 		p = *charnames[i];
    173        1.1       cgd 		if (p && *p)
    174        1.1       cgd 			*charvars[i] = *p;
    175        1.1       cgd 		else
    176       1.12   mycroft 			*charvars[i] = _POSIX_VDISABLE;
    177        1.1       cgd 	}
    178        1.1       cgd }
    179        1.1       cgd 
    180       1.17   mycroft /* Macros to clear/set/test flags. */
    181       1.17   mycroft #define	SET(t, f)	(t) |= (f)
    182       1.17   mycroft #define	CLR(t, f)	(t) &= ~(f)
    183       1.17   mycroft #define	ISSET(t, f)	((t) & (f))
    184       1.17   mycroft 
    185        1.7        pk void
    186       1.25   thorpej setflags(int n)
    187        1.1       cgd {
    188       1.23       mrg 	tcflag_t iflag, oflag, cflag, lflag;
    189        1.1       cgd 
    190        1.7        pk #ifdef COMPAT_43
    191        1.1       cgd 	switch (n) {
    192        1.1       cgd 	case 0:
    193        1.7        pk 		if (F0set) {
    194        1.7        pk 			compatflags(F0);
    195        1.7        pk 			return;
    196        1.7        pk 		}
    197        1.1       cgd 		break;
    198        1.1       cgd 	case 1:
    199        1.7        pk 		if (F1set) {
    200        1.7        pk 			compatflags(F1);
    201        1.7        pk 			return;
    202        1.7        pk 		}
    203        1.1       cgd 		break;
    204        1.1       cgd 	default:
    205        1.7        pk 		if (F2set) {
    206        1.7        pk 			compatflags(F2);
    207        1.7        pk 			return;
    208        1.7        pk 		}
    209        1.1       cgd 		break;
    210        1.1       cgd 	}
    211        1.7        pk #endif
    212        1.1       cgd 
    213        1.7        pk 	switch (n) {
    214        1.7        pk 	case 0:
    215        1.7        pk 		if (C0set && I0set && L0set && O0set) {
    216        1.7        pk 			tmode.c_cflag = C0;
    217        1.7        pk 			tmode.c_iflag = I0;
    218        1.7        pk 			tmode.c_lflag = L0;
    219        1.7        pk 			tmode.c_oflag = O0;
    220        1.7        pk 			return;
    221        1.7        pk 		}
    222        1.7        pk 		break;
    223        1.7        pk 	case 1:
    224        1.7        pk 		if (C1set && I1set && L1set && O1set) {
    225        1.7        pk 			tmode.c_cflag = C1;
    226        1.7        pk 			tmode.c_iflag = I1;
    227        1.7        pk 			tmode.c_lflag = L1;
    228        1.7        pk 			tmode.c_oflag = O1;
    229        1.7        pk 			return;
    230        1.7        pk 		}
    231        1.7        pk 		break;
    232        1.7        pk 	default:
    233        1.7        pk 		if (C2set && I2set && L2set && O2set) {
    234        1.7        pk 			tmode.c_cflag = C2;
    235        1.7        pk 			tmode.c_iflag = I2;
    236        1.7        pk 			tmode.c_lflag = L2;
    237        1.7        pk 			tmode.c_oflag = O2;
    238        1.7        pk 			return;
    239        1.7        pk 		}
    240        1.7        pk 		break;
    241        1.7        pk 	}
    242        1.1       cgd 
    243        1.9        pk 	iflag = omode.c_iflag;
    244       1.16   mycroft 	oflag = omode.c_oflag;
    245        1.9        pk 	cflag = omode.c_cflag;
    246        1.9        pk 	lflag = omode.c_lflag;
    247        1.7        pk 
    248        1.7        pk 	if (NP) {
    249       1.17   mycroft 		CLR(cflag, CSIZE|PARENB);
    250       1.17   mycroft 		SET(cflag, CS8);
    251       1.17   mycroft 		CLR(iflag, ISTRIP|INPCK|IGNPAR);
    252       1.17   mycroft 	} else if (AP || EP || OP) {
    253       1.17   mycroft 		CLR(cflag, CSIZE);
    254       1.17   mycroft 		SET(cflag, CS7|PARENB);
    255       1.17   mycroft 		SET(iflag, ISTRIP);
    256       1.17   mycroft 		if (OP && !EP) {
    257       1.17   mycroft 			SET(iflag, INPCK|IGNPAR);
    258       1.17   mycroft 			SET(cflag, PARODD);
    259       1.17   mycroft 			if (AP)
    260       1.17   mycroft 				CLR(iflag, INPCK);
    261       1.17   mycroft 		} else if (EP && !OP) {
    262       1.17   mycroft 			SET(iflag, INPCK|IGNPAR);
    263       1.17   mycroft 			CLR(cflag, PARODD);
    264       1.17   mycroft 			if (AP)
    265       1.17   mycroft 				CLR(iflag, INPCK);
    266       1.22     mikel 		} else if (AP || (EP && OP)) {
    267       1.17   mycroft 			CLR(iflag, INPCK|IGNPAR);
    268       1.17   mycroft 			CLR(cflag, PARODD);
    269       1.17   mycroft 		}
    270        1.9        pk 	} /* else, leave as is */
    271        1.1       cgd 
    272        1.7        pk #if 0
    273        1.1       cgd 	if (UC)
    274        1.1       cgd 		f |= LCASE;
    275        1.7        pk #endif
    276        1.1       cgd 
    277        1.7        pk 	if (HC)
    278       1.17   mycroft 		SET(cflag, HUPCL);
    279        1.9        pk 	else
    280       1.17   mycroft 		CLR(cflag, HUPCL);
    281        1.7        pk 
    282       1.13        pk 	if (MB)
    283       1.17   mycroft 		SET(cflag, MDMBUF);
    284       1.13        pk 	else
    285       1.17   mycroft 		CLR(cflag, MDMBUF);
    286       1.13        pk 
    287        1.7        pk 	if (NL) {
    288       1.17   mycroft 		SET(iflag, ICRNL);
    289       1.17   mycroft 		SET(oflag, ONLCR|OPOST);
    290       1.15   mycroft 	} else {
    291       1.17   mycroft 		CLR(iflag, ICRNL);
    292       1.17   mycroft 		CLR(oflag, ONLCR);
    293        1.7        pk 	}
    294        1.1       cgd 
    295       1.16   mycroft 	if (!HT)
    296       1.17   mycroft 		SET(oflag, OXTABS|OPOST);
    297       1.16   mycroft 	else
    298       1.17   mycroft 		CLR(oflag, OXTABS);
    299       1.16   mycroft 
    300        1.7        pk #ifdef XXX_DELAY
    301       1.17   mycroft 	SET(f, delaybits());
    302        1.7        pk #endif
    303        1.1       cgd 
    304        1.1       cgd 	if (n == 1) {		/* read mode flags */
    305        1.7        pk 		if (RW) {
    306        1.7        pk 			iflag = 0;
    307       1.17   mycroft 			CLR(oflag, OPOST);
    308       1.17   mycroft 			CLR(cflag, CSIZE|PARENB);
    309       1.17   mycroft 			SET(cflag, CS8);
    310        1.7        pk 			lflag = 0;
    311        1.7        pk 		} else {
    312       1.17   mycroft 			CLR(lflag, ICANON);
    313        1.7        pk 		}
    314        1.7        pk 		goto out;
    315        1.1       cgd 	}
    316        1.1       cgd 
    317        1.1       cgd 	if (n == 0)
    318        1.7        pk 		goto out;
    319        1.1       cgd 
    320        1.7        pk #if 0
    321        1.1       cgd 	if (CB)
    322       1.17   mycroft 		SET(f, CRTBS);
    323        1.7        pk #endif
    324        1.1       cgd 
    325        1.1       cgd 	if (CE)
    326       1.17   mycroft 		SET(lflag, ECHOE);
    327       1.16   mycroft 	else
    328       1.17   mycroft 		CLR(lflag, ECHOE);
    329        1.1       cgd 
    330        1.1       cgd 	if (CK)
    331       1.17   mycroft 		SET(lflag, ECHOKE);
    332       1.16   mycroft 	else
    333       1.17   mycroft 		CLR(lflag, ECHOKE);
    334        1.1       cgd 
    335        1.1       cgd 	if (PE)
    336       1.17   mycroft 		SET(lflag, ECHOPRT);
    337       1.16   mycroft 	else
    338       1.17   mycroft 		CLR(lflag, ECHOPRT);
    339        1.1       cgd 
    340        1.1       cgd 	if (EC)
    341       1.17   mycroft 		SET(lflag, ECHO);
    342       1.16   mycroft 	else
    343       1.17   mycroft 		CLR(lflag, ECHO);
    344        1.1       cgd 
    345        1.1       cgd 	if (XC)
    346       1.17   mycroft 		SET(lflag, ECHOCTL);
    347       1.16   mycroft 	else
    348       1.17   mycroft 		CLR(lflag, ECHOCTL);
    349        1.1       cgd 
    350        1.1       cgd 	if (DX)
    351       1.17   mycroft 		SET(lflag, IXANY);
    352       1.16   mycroft 	else
    353       1.17   mycroft 		CLR(lflag, IXANY);
    354        1.1       cgd 
    355        1.7        pk out:
    356        1.7        pk 	tmode.c_iflag = iflag;
    357        1.7        pk 	tmode.c_oflag = oflag;
    358        1.7        pk 	tmode.c_cflag = cflag;
    359        1.7        pk 	tmode.c_lflag = lflag;
    360        1.7        pk }
    361        1.7        pk 
    362        1.7        pk #ifdef COMPAT_43
    363        1.7        pk /*
    364        1.7        pk  * Old TTY => termios, snatched from <sys/kern/tty_compat.c>
    365        1.7        pk  */
    366        1.7        pk void
    367       1.25   thorpej compatflags(long flags)
    368        1.7        pk {
    369       1.23       mrg 	tcflag_t iflag, oflag, cflag, lflag;
    370        1.7        pk 
    371       1.17   mycroft 	iflag = BRKINT|ICRNL|IMAXBEL|IXON|IXANY;
    372       1.17   mycroft 	oflag = OPOST|ONLCR|OXTABS;
    373       1.17   mycroft 	cflag = CREAD;
    374       1.17   mycroft 	lflag = ICANON|ISIG|IEXTEN;
    375       1.17   mycroft 
    376       1.17   mycroft 	if (ISSET(flags, TANDEM))
    377       1.17   mycroft 		SET(iflag, IXOFF);
    378       1.17   mycroft 	else
    379       1.17   mycroft 		CLR(iflag, IXOFF);
    380       1.17   mycroft 	if (ISSET(flags, ECHO))
    381       1.17   mycroft 		SET(lflag, ECHO);
    382       1.17   mycroft 	else
    383       1.17   mycroft 		CLR(lflag, ECHO);
    384       1.17   mycroft 	if (ISSET(flags, CRMOD)) {
    385       1.17   mycroft 		SET(iflag, ICRNL);
    386       1.17   mycroft 		SET(oflag, ONLCR);
    387        1.8        pk 	} else {
    388       1.17   mycroft 		CLR(iflag, ICRNL);
    389       1.17   mycroft 		CLR(oflag, ONLCR);
    390        1.8        pk 	}
    391       1.17   mycroft 	if (ISSET(flags, XTABS))
    392       1.17   mycroft 		SET(oflag, OXTABS);
    393        1.8        pk 	else
    394       1.17   mycroft 		CLR(oflag, OXTABS);
    395        1.8        pk 
    396       1.17   mycroft 
    397       1.17   mycroft 	if (ISSET(flags, RAW)) {
    398        1.8        pk 		iflag &= IXOFF;
    399       1.17   mycroft 		CLR(lflag, ISIG|ICANON|IEXTEN);
    400       1.18   mycroft 		CLR(cflag, PARENB);
    401        1.7        pk 	} else {
    402       1.17   mycroft 		SET(iflag, BRKINT|IXON|IMAXBEL);
    403       1.17   mycroft 		SET(lflag, ISIG|IEXTEN);
    404       1.17   mycroft 		if (ISSET(flags, CBREAK))
    405       1.17   mycroft 			CLR(lflag, ICANON);
    406        1.7        pk 		else
    407       1.17   mycroft 			SET(lflag, ICANON);
    408       1.18   mycroft 		switch (ISSET(flags, ANYP)) {
    409       1.18   mycroft 		case 0:
    410       1.18   mycroft 			CLR(cflag, PARENB);
    411       1.18   mycroft 			break;
    412       1.18   mycroft 		case ANYP:
    413       1.18   mycroft 			SET(cflag, PARENB);
    414       1.18   mycroft 			CLR(iflag, INPCK);
    415       1.18   mycroft 			break;
    416       1.18   mycroft 		case EVENP:
    417       1.18   mycroft 			SET(cflag, PARENB);
    418       1.18   mycroft 			SET(iflag, INPCK);
    419       1.18   mycroft 			CLR(cflag, PARODD);
    420       1.18   mycroft 			break;
    421       1.18   mycroft 		case ODDP:
    422       1.18   mycroft 			SET(cflag, PARENB);
    423       1.18   mycroft 			SET(iflag, INPCK);
    424       1.18   mycroft 			SET(cflag, PARODD);
    425       1.18   mycroft 			break;
    426       1.18   mycroft 		}
    427        1.8        pk 	}
    428        1.8        pk 
    429       1.17   mycroft 	/* Nothing we can do with CRTBS. */
    430       1.17   mycroft 	if (ISSET(flags, PRTERA))
    431       1.17   mycroft 		SET(lflag, ECHOPRT);
    432       1.17   mycroft 	else
    433       1.17   mycroft 		CLR(lflag, ECHOPRT);
    434       1.17   mycroft 	if (ISSET(flags, CRTERA))
    435       1.17   mycroft 		SET(lflag, ECHOE);
    436       1.17   mycroft 	else
    437       1.17   mycroft 		CLR(lflag, ECHOE);
    438       1.17   mycroft 	/* Nothing we can do with TILDE. */
    439       1.17   mycroft 	if (ISSET(flags, MDMBUF))
    440       1.17   mycroft 		SET(cflag, MDMBUF);
    441       1.17   mycroft 	else
    442       1.17   mycroft 		CLR(cflag, MDMBUF);
    443       1.17   mycroft 	if (ISSET(flags, NOHANG))
    444       1.17   mycroft 		CLR(cflag, HUPCL);
    445       1.17   mycroft 	else
    446       1.17   mycroft 		SET(cflag, HUPCL);
    447       1.17   mycroft 	if (ISSET(flags, CRTKIL))
    448       1.17   mycroft 		SET(lflag, ECHOKE);
    449       1.17   mycroft 	else
    450       1.17   mycroft 		CLR(lflag, ECHOKE);
    451       1.17   mycroft 	if (ISSET(flags, CTLECH))
    452       1.17   mycroft 		SET(lflag, ECHOCTL);
    453       1.17   mycroft 	else
    454       1.17   mycroft 		CLR(lflag, ECHOCTL);
    455       1.17   mycroft 	if (!ISSET(flags, DECCTQ))
    456       1.17   mycroft 		SET(iflag, IXANY);
    457       1.17   mycroft 	else
    458       1.17   mycroft 		CLR(iflag, IXANY);
    459       1.17   mycroft 	CLR(lflag, TOSTOP|FLUSHO|PENDIN|NOFLSH);
    460       1.17   mycroft 	SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
    461       1.17   mycroft 
    462       1.17   mycroft 	if (ISSET(flags, RAW|LITOUT|PASS8)) {
    463       1.18   mycroft 		CLR(cflag, CSIZE);
    464       1.17   mycroft 		SET(cflag, CS8);
    465       1.17   mycroft 		if (!ISSET(flags, RAW|PASS8))
    466       1.17   mycroft 			SET(iflag, ISTRIP);
    467        1.8        pk 		else
    468       1.17   mycroft 			CLR(iflag, ISTRIP);
    469       1.17   mycroft 		if (!ISSET(flags, RAW|LITOUT))
    470       1.17   mycroft 			SET(oflag, OPOST);
    471        1.8        pk 		else
    472       1.17   mycroft 			CLR(oflag, OPOST);
    473        1.8        pk 	} else {
    474       1.17   mycroft 		CLR(cflag, CSIZE);
    475       1.18   mycroft 		SET(cflag, CS7);
    476       1.17   mycroft 		SET(iflag, ISTRIP);
    477       1.17   mycroft 		SET(oflag, OPOST);
    478        1.7        pk 	}
    479        1.7        pk 
    480        1.7        pk 	tmode.c_iflag = iflag;
    481        1.7        pk 	tmode.c_oflag = oflag;
    482        1.7        pk 	tmode.c_cflag = cflag;
    483        1.7        pk 	tmode.c_lflag = lflag;
    484        1.1       cgd }
    485        1.7        pk #endif
    486        1.1       cgd 
    487        1.7        pk #ifdef XXX_DELAY
    488        1.1       cgd struct delayval {
    489        1.1       cgd 	unsigned	delay;		/* delay in ms */
    490        1.1       cgd 	int		bits;
    491        1.1       cgd };
    492        1.1       cgd 
    493        1.1       cgd /*
    494        1.1       cgd  * below are random guesses, I can't be bothered checking
    495        1.1       cgd  */
    496        1.1       cgd 
    497        1.1       cgd struct delayval	crdelay[] = {
    498        1.9        pk 	{ 1,		CR1 },
    499        1.9        pk 	{ 2,		CR2 },
    500        1.9        pk 	{ 3,		CR3 },
    501        1.9        pk 	{ 83,		CR1 },
    502        1.9        pk 	{ 166,		CR2 },
    503        1.9        pk 	{ 0,		CR3 },
    504        1.1       cgd };
    505        1.1       cgd 
    506        1.1       cgd struct delayval nldelay[] = {
    507        1.9        pk 	{ 1,		NL1 },		/* special, calculated */
    508        1.9        pk 	{ 2,		NL2 },
    509        1.9        pk 	{ 3,		NL3 },
    510        1.9        pk 	{ 100,		NL2 },
    511        1.9        pk 	{ 0,		NL3 },
    512        1.1       cgd };
    513        1.1       cgd 
    514        1.1       cgd struct delayval	bsdelay[] = {
    515        1.9        pk 	{ 1,		BS1 },
    516        1.9        pk 	{ 0,		0 },
    517        1.1       cgd };
    518        1.1       cgd 
    519        1.1       cgd struct delayval	ffdelay[] = {
    520        1.9        pk 	{ 1,		FF1 },
    521        1.9        pk 	{ 1750,		FF1 },
    522        1.9        pk 	{ 0,		FF1 },
    523        1.1       cgd };
    524        1.1       cgd 
    525        1.1       cgd struct delayval	tbdelay[] = {
    526        1.9        pk 	{ 1,		 TAB1 },
    527        1.9        pk 	{ 2,		 TAB2 },
    528        1.9        pk 	{ 3,		XTABS },	/* this is expand tabs */
    529        1.9        pk 	{ 100,		 TAB1 },
    530        1.9        pk 	{ 0,		 TAB2 },
    531        1.1       cgd };
    532        1.1       cgd 
    533        1.9        pk int
    534       1.25   thorpej delaybits(void)
    535        1.1       cgd {
    536       1.23       mrg 	int f;
    537        1.1       cgd 
    538        1.1       cgd 	f  = adelay(CD, crdelay);
    539        1.1       cgd 	f |= adelay(ND, nldelay);
    540        1.1       cgd 	f |= adelay(FD, ffdelay);
    541        1.1       cgd 	f |= adelay(TD, tbdelay);
    542        1.1       cgd 	f |= adelay(BD, bsdelay);
    543        1.1       cgd 	return (f);
    544        1.1       cgd }
    545        1.1       cgd 
    546        1.9        pk int
    547       1.25   thorpej adelay(int ms, struct delayval *dp)
    548        1.1       cgd {
    549        1.1       cgd 	if (ms == 0)
    550        1.1       cgd 		return (0);
    551        1.1       cgd 	while (dp->delay && ms > dp->delay)
    552        1.1       cgd 		dp++;
    553        1.1       cgd 	return (dp->bits);
    554        1.1       cgd }
    555        1.7        pk #endif
    556        1.1       cgd 
    557       1.20   thorpej char	editedhost[MAXHOSTNAMELEN];
    558        1.1       cgd 
    559        1.9        pk void
    560  1.33.40.1      yamt edithost(const char *pat)
    561        1.1       cgd {
    562       1.23       mrg 	char *host = HN;
    563       1.23       mrg 	char *res = editedhost;
    564        1.1       cgd 
    565        1.1       cgd 	if (!pat)
    566        1.1       cgd 		pat = "";
    567        1.1       cgd 	while (*pat) {
    568        1.1       cgd 		switch (*pat) {
    569        1.1       cgd 
    570        1.1       cgd 		case '#':
    571        1.1       cgd 			if (*host)
    572        1.1       cgd 				host++;
    573        1.1       cgd 			break;
    574        1.1       cgd 
    575        1.1       cgd 		case '@':
    576        1.1       cgd 			if (*host)
    577        1.1       cgd 				*res++ = *host++;
    578        1.1       cgd 			break;
    579        1.1       cgd 
    580        1.1       cgd 		default:
    581        1.1       cgd 			*res++ = *pat;
    582        1.1       cgd 			break;
    583        1.1       cgd 
    584        1.1       cgd 		}
    585        1.1       cgd 		if (res == &editedhost[sizeof editedhost - 1]) {
    586        1.1       cgd 			*res = '\0';
    587        1.1       cgd 			return;
    588        1.1       cgd 		}
    589        1.1       cgd 		pat++;
    590        1.1       cgd 	}
    591        1.1       cgd 	if (*host)
    592       1.33  christos 		(void)strncpy(res, host,
    593       1.33  christos 		    sizeof editedhost - (res - editedhost) - 1);
    594        1.1       cgd 	else
    595        1.1       cgd 		*res = '\0';
    596        1.1       cgd 	editedhost[sizeof editedhost - 1] = '\0';
    597        1.1       cgd }
    598        1.1       cgd 
    599        1.9        pk void
    600       1.25   thorpej makeenv(char *env[])
    601        1.1       cgd {
    602        1.1       cgd 	static char termbuf[128] = "TERM=";
    603       1.23       mrg 	char *p, *q;
    604       1.23       mrg 	char **ep;
    605        1.1       cgd 
    606        1.1       cgd 	ep = env;
    607        1.1       cgd 	if (TT && *TT) {
    608       1.33  christos 		(void)strlcat(termbuf, TT, sizeof(termbuf));
    609        1.1       cgd 		*ep++ = termbuf;
    610        1.1       cgd 	}
    611       1.22     mikel 	if ((p = EV) != NULL) {
    612        1.1       cgd 		q = p;
    613       1.22     mikel 		while ((q = strchr(q, ',')) != NULL) {
    614        1.1       cgd 			*q++ = '\0';
    615        1.1       cgd 			*ep++ = p;
    616        1.1       cgd 			p = q;
    617        1.1       cgd 		}
    618        1.1       cgd 		if (*p)
    619        1.1       cgd 			*ep++ = p;
    620        1.1       cgd 	}
    621        1.1       cgd 	*ep = (char *)0;
    622        1.1       cgd }
    623        1.1       cgd 
    624        1.1       cgd /*
    625        1.1       cgd  * This speed select mechanism is written for the Develcon DATASWITCH.
    626        1.1       cgd  * The Develcon sends a string of the form "B{speed}\n" at a predefined
    627        1.1       cgd  * baud rate. This string indicates the user's actual speed.
    628        1.1       cgd  * The routine below returns the terminal type mapped from derived speed.
    629        1.1       cgd  */
    630        1.1       cgd struct	portselect {
    631  1.33.40.1      yamt 	const char *ps_baud;
    632  1.33.40.1      yamt 	const char *ps_type;
    633        1.1       cgd } portspeeds[] = {
    634        1.1       cgd 	{ "B110",	"std.110" },
    635        1.1       cgd 	{ "B134",	"std.134" },
    636        1.1       cgd 	{ "B150",	"std.150" },
    637        1.1       cgd 	{ "B300",	"std.300" },
    638        1.1       cgd 	{ "B600",	"std.600" },
    639        1.1       cgd 	{ "B1200",	"std.1200" },
    640        1.1       cgd 	{ "B2400",	"std.2400" },
    641        1.1       cgd 	{ "B4800",	"std.4800" },
    642        1.1       cgd 	{ "B9600",	"std.9600" },
    643        1.1       cgd 	{ "B19200",	"std.19200" },
    644  1.33.40.1      yamt 	{ NULL, NULL }
    645        1.1       cgd };
    646        1.1       cgd 
    647  1.33.40.1      yamt const char *
    648       1.25   thorpej portselector(void)
    649        1.1       cgd {
    650  1.33.40.1      yamt 	char c, baud[20];
    651  1.33.40.1      yamt 	const char *type = "default";
    652       1.23       mrg 	struct portselect *ps;
    653  1.33.40.1      yamt 	size_t len;
    654        1.1       cgd 
    655       1.33  christos 	(void)alarm(5*60);
    656        1.1       cgd 	for (len = 0; len < sizeof (baud) - 1; len++) {
    657        1.1       cgd 		if (read(STDIN_FILENO, &c, 1) <= 0)
    658        1.1       cgd 			break;
    659        1.1       cgd 		c &= 0177;
    660        1.1       cgd 		if (c == '\n' || c == '\r')
    661        1.1       cgd 			break;
    662        1.1       cgd 		if (c == 'B')
    663        1.1       cgd 			len = 0;	/* in case of leading garbage */
    664        1.1       cgd 		baud[len] = c;
    665        1.1       cgd 	}
    666        1.1       cgd 	baud[len] = '\0';
    667        1.1       cgd 	for (ps = portspeeds; ps->ps_baud; ps++)
    668        1.1       cgd 		if (strcmp(ps->ps_baud, baud) == 0) {
    669        1.1       cgd 			type = ps->ps_type;
    670        1.1       cgd 			break;
    671        1.1       cgd 		}
    672       1.33  christos 	(void)sleep(2);	/* wait for connection to complete */
    673        1.1       cgd 	return (type);
    674        1.1       cgd }
    675        1.1       cgd 
    676        1.1       cgd /*
    677        1.1       cgd  * This auto-baud speed select mechanism is written for the Micom 600
    678        1.1       cgd  * portselector. Selection is done by looking at how the character '\r'
    679        1.1       cgd  * is garbled at the different speeds.
    680        1.1       cgd  */
    681        1.1       cgd #include <sys/time.h>
    682        1.1       cgd 
    683  1.33.40.1      yamt const char *
    684       1.25   thorpej autobaud(void)
    685        1.1       cgd {
    686       1.26   mycroft 	struct pollfd set[1];
    687       1.26   mycroft 	struct timespec timeout;
    688  1.33.40.1      yamt 	char c;
    689  1.33.40.1      yamt 	const char *type = "9600-baud";
    690        1.1       cgd 
    691       1.14        pk 	(void)tcflush(0, TCIOFLUSH);
    692       1.26   mycroft 	set[0].fd = STDIN_FILENO;
    693       1.26   mycroft 	set[0].events = POLLIN;
    694       1.26   mycroft 	if (poll(set, 1, 5000) <= 0)
    695        1.1       cgd 		return (type);
    696       1.24       mjl 	if (read(STDIN_FILENO, &c, 1) != 1)
    697        1.1       cgd 		return (type);
    698        1.1       cgd 	timeout.tv_sec = 0;
    699       1.26   mycroft 	timeout.tv_nsec = 20000;
    700       1.26   mycroft 	(void)nanosleep(&timeout, NULL);
    701       1.14        pk 	(void)tcflush(0, TCIOFLUSH);
    702        1.1       cgd 	switch (c & 0377) {
    703        1.1       cgd 
    704        1.1       cgd 	case 0200:		/* 300-baud */
    705        1.1       cgd 		type = "300-baud";
    706        1.1       cgd 		break;
    707        1.1       cgd 
    708        1.1       cgd 	case 0346:		/* 1200-baud */
    709        1.1       cgd 		type = "1200-baud";
    710        1.1       cgd 		break;
    711        1.1       cgd 
    712        1.1       cgd 	case  015:		/* 2400-baud */
    713        1.1       cgd 	case 0215:
    714        1.1       cgd 		type = "2400-baud";
    715        1.1       cgd 		break;
    716        1.1       cgd 
    717        1.1       cgd 	default:		/* 4800-baud */
    718        1.1       cgd 		type = "4800-baud";
    719        1.1       cgd 		break;
    720        1.1       cgd 
    721        1.1       cgd 	case 0377:		/* 9600-baud */
    722        1.1       cgd 		type = "9600-baud";
    723        1.1       cgd 		break;
    724        1.1       cgd 	}
    725        1.1       cgd 	return (type);
    726        1.1       cgd }
    727