subr.c revision 56725
11592Srgrimes/* 215645Sjoerg * Copyright (c) 1983, 1993 315645Sjoerg * The Regents of the University of California. All rights reserved. 41592Srgrimes * 51592Srgrimes * Redistribution and use in source and binary forms, with or without 61592Srgrimes * modification, are permitted provided that the following conditions 71592Srgrimes * are met: 81592Srgrimes * 1. Redistributions of source code must retain the above copyright 91592Srgrimes * notice, this list of conditions and the following disclaimer. 101592Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111592Srgrimes * notice, this list of conditions and the following disclaimer in the 121592Srgrimes * documentation and/or other materials provided with the distribution. 131592Srgrimes * 3. All advertising materials mentioning features or use of this software 141592Srgrimes * must display the following acknowledgement: 151592Srgrimes * This product includes software developed by the University of 161592Srgrimes * California, Berkeley and its contributors. 171592Srgrimes * 4. Neither the name of the University nor the names of its contributors 181592Srgrimes * may be used to endorse or promote products derived from this software 191592Srgrimes * without specific prior written permission. 201592Srgrimes * 211592Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221592Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231592Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241592Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251592Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261592Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271592Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281592Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291592Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301592Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311592Srgrimes * SUCH DAMAGE. 321592Srgrimes */ 331592Srgrimes 341592Srgrimes#ifndef lint 3531331Scharnier#if 0 3631331Scharnierstatic char sccsid[] = "@(#)from: subr.c 8.1 (Berkeley) 6/4/93"; 3731331Scharnier#endif 3831331Scharnierstatic const char rcsid[] = 3950476Speter "$FreeBSD: head/libexec/getty/subr.c 56725 2000-01-28 07:12:03Z bde $"; 401592Srgrimes#endif /* not lint */ 411592Srgrimes 421592Srgrimes/* 431592Srgrimes * Melbourne getty. 441592Srgrimes */ 4515645Sjoerg#define COMPAT_43 4631331Scharnier#ifdef DEBUG 4731331Scharnier#include <stdio.h> 4831331Scharnier#endif 4915645Sjoerg#include <stdlib.h> 501592Srgrimes#include <string.h> 5115645Sjoerg#include <termios.h> 5231331Scharnier#include <unistd.h> 5315645Sjoerg#include <sys/ioctl.h> 5415645Sjoerg#include <sys/param.h> 5531331Scharnier#include <sys/time.h> 5625709Sdavidn#include <syslog.h> 5715645Sjoerg 581592Srgrimes#include "gettytab.h" 5915645Sjoerg#include "pathnames.h" 6015645Sjoerg#include "extern.h" 611592Srgrimes 621592Srgrimes 6315645Sjoerg#ifdef COMPAT_43 6415645Sjoergstatic void compatflags __P((long)); 6515645Sjoerg#endif 6615645Sjoerg 671592Srgrimes/* 681592Srgrimes * Get a table entry. 691592Srgrimes */ 7015645Sjoergvoid 7115645Sjoerggettable(name, buf) 7215645Sjoerg const char *name; 7315645Sjoerg char *buf; 741592Srgrimes{ 751592Srgrimes register struct gettystrs *sp; 761592Srgrimes register struct gettynums *np; 771592Srgrimes register struct gettyflags *fp; 7815645Sjoerg long n; 7925709Sdavidn int l; 8025709Sdavidn char *p; 8125709Sdavidn char *msg = NULL; 8215645Sjoerg const char *dba[2]; 8325709Sdavidn 8425709Sdavidn static int firsttime = 1; 8525709Sdavidn 8615645Sjoerg dba[0] = _PATH_GETTYTAB; 8715645Sjoerg dba[1] = 0; 881592Srgrimes 8925709Sdavidn if (firsttime) { 9025709Sdavidn /* 9125709Sdavidn * we need to strdup() anything in the strings array 9225709Sdavidn * initially in order to simplify things later 9325709Sdavidn */ 9425709Sdavidn for (sp = gettystrs; sp->field; sp++) 9525709Sdavidn if (sp->value != NULL) { 9625709Sdavidn /* handle these ones more carefully */ 9725709Sdavidn if (sp >= &gettystrs[4] && sp <= &gettystrs[6]) 9825709Sdavidn l = 2; 9925709Sdavidn else 10025709Sdavidn l = strlen(sp->value) + 1; 10125709Sdavidn if ((p = malloc(l)) != NULL) { 10225709Sdavidn strncpy(p, sp->value, l); 10325709Sdavidn p[l-1] = '\0'; 10425709Sdavidn } 10525709Sdavidn /* 10625709Sdavidn * replace, even if NULL, else we'll 10725709Sdavidn * have problems with free()ing static mem 10825709Sdavidn */ 10925709Sdavidn sp->value = p; 11025709Sdavidn } 11125709Sdavidn firsttime = 0; 11225709Sdavidn } 11325709Sdavidn 11425709Sdavidn switch (cgetent(&buf, (char **)dba, (char *)name)) { 11525709Sdavidn case 1: 11625709Sdavidn msg = "%s: couldn't resolve 'tc=' in gettytab '%s'"; 11725709Sdavidn case 0: 11825709Sdavidn break; 11925709Sdavidn case -1: 12025709Sdavidn msg = "%s: unknown gettytab entry '%s'"; 12125709Sdavidn break; 12225709Sdavidn case -2: 12325709Sdavidn msg = "%s: retrieving gettytab entry '%s': %m"; 12425709Sdavidn break; 12525709Sdavidn case -3: 12625709Sdavidn msg = "%s: recursive 'tc=' reference gettytab entry '%s'"; 12725709Sdavidn break; 12825709Sdavidn default: 12925709Sdavidn msg = "%s: unexpected cgetent() error for entry '%s'"; 13025709Sdavidn break; 13125709Sdavidn } 13225709Sdavidn 13325709Sdavidn if (msg != NULL) { 13425709Sdavidn syslog(LOG_ERR, msg, "getty", name); 1351592Srgrimes return; 13625709Sdavidn } 1371592Srgrimes 13825709Sdavidn for (sp = gettystrs; sp->field; sp++) { 13929045Sdavidn if ((l = cgetstr(buf, (char*)sp->field, &p)) >= 0) { 14025709Sdavidn if (sp->value) { 14125709Sdavidn /* prefer existing value */ 14225709Sdavidn if (strcmp(p, sp->value) != 0) 14325709Sdavidn free(sp->value); 14425709Sdavidn else { 14525709Sdavidn free(p); 14625709Sdavidn p = sp->value; 14725709Sdavidn } 14825709Sdavidn } 14925709Sdavidn sp->value = p; 15025709Sdavidn } else if (l == -1) { 15125709Sdavidn free(sp->value); 15225709Sdavidn sp->value = NULL; 15325709Sdavidn } 15425709Sdavidn } 15525709Sdavidn 1561592Srgrimes for (np = gettynums; np->field; np++) { 15725709Sdavidn if (cgetnum(buf, (char*)np->field, &n) == -1) 1581592Srgrimes np->set = 0; 1591592Srgrimes else { 1601592Srgrimes np->set = 1; 1611592Srgrimes np->value = n; 1621592Srgrimes } 1631592Srgrimes } 16425709Sdavidn 1651592Srgrimes for (fp = gettyflags; fp->field; fp++) { 16625709Sdavidn if (cgetcap(buf, (char *)fp->field, ':') == NULL) 1671592Srgrimes fp->set = 0; 1681592Srgrimes else { 1691592Srgrimes fp->set = 1; 17015645Sjoerg fp->value = 1 ^ fp->invrt; 1711592Srgrimes } 1721592Srgrimes } 17325709Sdavidn 17415645Sjoerg#ifdef DEBUG 17515645Sjoerg printf("name=\"%s\", buf=\"%s\"\r\n", name, buf); 17615645Sjoerg for (sp = gettystrs; sp->field; sp++) 17729045Sdavidn printf("cgetstr: %s=%s\r\n", sp->field, sp->value); 17815645Sjoerg for (np = gettynums; np->field; np++) 17915645Sjoerg printf("cgetnum: %s=%d\r\n", np->field, np->value); 18015645Sjoerg for (fp = gettyflags; fp->field; fp++) 18115645Sjoerg printf("cgetflags: %s='%c' set='%c'\r\n", fp->field, 18215645Sjoerg fp->value + '0', fp->set + '0'); 18315645Sjoerg#endif /* DEBUG */ 1841592Srgrimes} 1851592Srgrimes 18615645Sjoergvoid 1871592Srgrimesgendefaults() 1881592Srgrimes{ 1891592Srgrimes register struct gettystrs *sp; 1901592Srgrimes register struct gettynums *np; 1911592Srgrimes register struct gettyflags *fp; 1921592Srgrimes 1931592Srgrimes for (sp = gettystrs; sp->field; sp++) 1941592Srgrimes if (sp->value) 19525709Sdavidn sp->defalt = strdup(sp->value); 1961592Srgrimes for (np = gettynums; np->field; np++) 1971592Srgrimes if (np->set) 1981592Srgrimes np->defalt = np->value; 1991592Srgrimes for (fp = gettyflags; fp->field; fp++) 2001592Srgrimes if (fp->set) 2011592Srgrimes fp->defalt = fp->value; 2021592Srgrimes else 2031592Srgrimes fp->defalt = fp->invrt; 2041592Srgrimes} 2051592Srgrimes 20615645Sjoergvoid 2071592Srgrimessetdefaults() 2081592Srgrimes{ 2091592Srgrimes register struct gettystrs *sp; 2101592Srgrimes register struct gettynums *np; 2111592Srgrimes register struct gettyflags *fp; 2121592Srgrimes 2131592Srgrimes for (sp = gettystrs; sp->field; sp++) 2141592Srgrimes if (!sp->value) 21525709Sdavidn sp->value = !sp->defalt ? sp->defalt 21625709Sdavidn : strdup(sp->defalt); 2171592Srgrimes for (np = gettynums; np->field; np++) 2181592Srgrimes if (!np->set) 2191592Srgrimes np->value = np->defalt; 2201592Srgrimes for (fp = gettyflags; fp->field; fp++) 2211592Srgrimes if (!fp->set) 2221592Srgrimes fp->value = fp->defalt; 2231592Srgrimes} 2241592Srgrimes 2251592Srgrimesstatic char ** 2261592Srgrimescharnames[] = { 2271592Srgrimes &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK, 2281592Srgrimes &SU, &DS, &RP, &FL, &WE, &LN, 0 2291592Srgrimes}; 2301592Srgrimes 2311592Srgrimesstatic char * 2321592Srgrimescharvars[] = { 23315645Sjoerg &tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR], 23415645Sjoerg &tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP], 23515645Sjoerg &tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP], 23615645Sjoerg &tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD], 23715645Sjoerg &tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], 0 2381592Srgrimes}; 2391592Srgrimes 24015645Sjoergvoid 2411592Srgrimessetchars() 2421592Srgrimes{ 2431592Srgrimes register int i; 24415645Sjoerg register const char *p; 2451592Srgrimes 2461592Srgrimes for (i = 0; charnames[i]; i++) { 2471592Srgrimes p = *charnames[i]; 2481592Srgrimes if (p && *p) 2491592Srgrimes *charvars[i] = *p; 2501592Srgrimes else 25115645Sjoerg *charvars[i] = _POSIX_VDISABLE; 2521592Srgrimes } 2531592Srgrimes} 2541592Srgrimes 25515645Sjoerg/* Macros to clear/set/test flags. */ 25615645Sjoerg#define SET(t, f) (t) |= (f) 25715645Sjoerg#define CLR(t, f) (t) &= ~(f) 25815645Sjoerg#define ISSET(t, f) ((t) & (f)) 25915645Sjoerg 26015645Sjoergvoid 26156725Sbdeset_flags(n) 26215645Sjoerg int n; 2631592Srgrimes{ 26415645Sjoerg register tcflag_t iflag, oflag, cflag, lflag; 2651592Srgrimes 26615645Sjoerg#ifdef COMPAT_43 2671592Srgrimes switch (n) { 2681592Srgrimes case 0: 26915645Sjoerg if (F0set) { 27015645Sjoerg compatflags(F0); 27115645Sjoerg return; 27215645Sjoerg } 2731592Srgrimes break; 2741592Srgrimes case 1: 27515645Sjoerg if (F1set) { 27615645Sjoerg compatflags(F1); 27715645Sjoerg return; 27815645Sjoerg } 2791592Srgrimes break; 2801592Srgrimes default: 28115645Sjoerg if (F2set) { 28215645Sjoerg compatflags(F2); 28315645Sjoerg return; 28415645Sjoerg } 2851592Srgrimes break; 2861592Srgrimes } 28715645Sjoerg#endif 2881592Srgrimes 28915645Sjoerg switch (n) { 29015645Sjoerg case 0: 29115645Sjoerg if (C0set && I0set && L0set && O0set) { 29215645Sjoerg tmode.c_cflag = C0; 29315645Sjoerg tmode.c_iflag = I0; 29415645Sjoerg tmode.c_lflag = L0; 29515645Sjoerg tmode.c_oflag = O0; 29615645Sjoerg return; 29715645Sjoerg } 29815645Sjoerg break; 29915645Sjoerg case 1: 30015645Sjoerg if (C1set && I1set && L1set && O1set) { 30115645Sjoerg tmode.c_cflag = C1; 30215645Sjoerg tmode.c_iflag = I1; 30315645Sjoerg tmode.c_lflag = L1; 30415645Sjoerg tmode.c_oflag = O1; 30515645Sjoerg return; 30615645Sjoerg } 30715645Sjoerg break; 30815645Sjoerg default: 30915645Sjoerg if (C2set && I2set && L2set && O2set) { 31015645Sjoerg tmode.c_cflag = C2; 31115645Sjoerg tmode.c_iflag = I2; 31215645Sjoerg tmode.c_lflag = L2; 31315645Sjoerg tmode.c_oflag = O2; 31415645Sjoerg return; 31515645Sjoerg } 31615645Sjoerg break; 31715645Sjoerg } 3181592Srgrimes 31915645Sjoerg iflag = omode.c_iflag; 32015645Sjoerg oflag = omode.c_oflag; 32115645Sjoerg cflag = omode.c_cflag; 32215645Sjoerg lflag = omode.c_lflag; 3231592Srgrimes 32415645Sjoerg if (NP) { 32515645Sjoerg CLR(cflag, CSIZE|PARENB); 32615645Sjoerg SET(cflag, CS8); 32715645Sjoerg CLR(iflag, ISTRIP|INPCK|IGNPAR); 32815645Sjoerg } else if (AP || EP || OP) { 32915645Sjoerg CLR(cflag, CSIZE); 33015645Sjoerg SET(cflag, CS7|PARENB); 33115645Sjoerg SET(iflag, ISTRIP); 33215645Sjoerg if (OP && !EP) { 33315645Sjoerg SET(iflag, INPCK|IGNPAR); 33415645Sjoerg SET(cflag, PARODD); 33515645Sjoerg if (AP) 33615645Sjoerg CLR(iflag, INPCK); 33715645Sjoerg } else if (EP && !OP) { 33815645Sjoerg SET(iflag, INPCK|IGNPAR); 33915645Sjoerg CLR(cflag, PARODD); 34015645Sjoerg if (AP) 34115645Sjoerg CLR(iflag, INPCK); 34215645Sjoerg } else if (AP || (EP && OP)) { 34315645Sjoerg CLR(iflag, INPCK|IGNPAR); 34415645Sjoerg CLR(cflag, PARODD); 34515645Sjoerg } 34615645Sjoerg } /* else, leave as is */ 34715645Sjoerg 34815645Sjoerg#if 0 3491592Srgrimes if (UC) 3501592Srgrimes f |= LCASE; 35115645Sjoerg#endif 3521592Srgrimes 35315645Sjoerg if (HC) 35415645Sjoerg SET(cflag, HUPCL); 35515645Sjoerg else 35615645Sjoerg CLR(cflag, HUPCL); 3571592Srgrimes 35815645Sjoerg if (MB) 35915645Sjoerg SET(cflag, MDMBUF); 36015645Sjoerg else 36115645Sjoerg CLR(cflag, MDMBUF); 3621592Srgrimes 36322208Sdavidn if (HW) 36422208Sdavidn SET(cflag, CRTSCTS); 36522208Sdavidn else 36622208Sdavidn CLR(cflag, CRTSCTS); 36722208Sdavidn 36815645Sjoerg if (NL) { 36915645Sjoerg SET(iflag, ICRNL); 37015645Sjoerg SET(oflag, ONLCR|OPOST); 37115645Sjoerg } else { 37215645Sjoerg CLR(iflag, ICRNL); 37315645Sjoerg CLR(oflag, ONLCR); 3741592Srgrimes } 3751592Srgrimes 3761592Srgrimes if (!HT) 37715645Sjoerg SET(oflag, OXTABS|OPOST); 37815645Sjoerg else 37915645Sjoerg CLR(oflag, OXTABS); 3801592Srgrimes 38115645Sjoerg#ifdef XXX_DELAY 38215645Sjoerg SET(f, delaybits()); 38315645Sjoerg#endif 38415645Sjoerg 38515645Sjoerg if (n == 1) { /* read mode flags */ 38615645Sjoerg if (RW) { 38715645Sjoerg iflag = 0; 38815645Sjoerg CLR(oflag, OPOST); 38915645Sjoerg CLR(cflag, CSIZE|PARENB); 39015645Sjoerg SET(cflag, CS8); 39115645Sjoerg lflag = 0; 39215645Sjoerg } else { 39315645Sjoerg CLR(lflag, ICANON); 39415645Sjoerg } 39515645Sjoerg goto out; 39615645Sjoerg } 39715645Sjoerg 3981592Srgrimes if (n == 0) 39915645Sjoerg goto out; 4001592Srgrimes 40115645Sjoerg#if 0 4021592Srgrimes if (CB) 40315645Sjoerg SET(f, CRTBS); 40415645Sjoerg#endif 4051592Srgrimes 4061592Srgrimes if (CE) 40715645Sjoerg SET(lflag, ECHOE); 40815645Sjoerg else 40915645Sjoerg CLR(lflag, ECHOE); 4101592Srgrimes 4111592Srgrimes if (CK) 41215645Sjoerg SET(lflag, ECHOKE); 41315645Sjoerg else 41415645Sjoerg CLR(lflag, ECHOKE); 4151592Srgrimes 4161592Srgrimes if (PE) 41715645Sjoerg SET(lflag, ECHOPRT); 41815645Sjoerg else 41915645Sjoerg CLR(lflag, ECHOPRT); 4201592Srgrimes 4211592Srgrimes if (EC) 42215645Sjoerg SET(lflag, ECHO); 42315645Sjoerg else 42415645Sjoerg CLR(lflag, ECHO); 4251592Srgrimes 4261592Srgrimes if (XC) 42715645Sjoerg SET(lflag, ECHOCTL); 42815645Sjoerg else 42915645Sjoerg CLR(lflag, ECHOCTL); 4301592Srgrimes 4311592Srgrimes if (DX) 43215645Sjoerg SET(lflag, IXANY); 43315645Sjoerg else 43415645Sjoerg CLR(lflag, IXANY); 4351592Srgrimes 43615645Sjoergout: 43715645Sjoerg tmode.c_iflag = iflag; 43815645Sjoerg tmode.c_oflag = oflag; 43915645Sjoerg tmode.c_cflag = cflag; 44015645Sjoerg tmode.c_lflag = lflag; 4411592Srgrimes} 4421592Srgrimes 44315645Sjoerg#ifdef COMPAT_43 44415645Sjoerg/* 44515645Sjoerg * Old TTY => termios, snatched from <sys/kern/tty_compat.c> 44615645Sjoerg */ 44715645Sjoergvoid 44815645Sjoergcompatflags(flags) 44915645Sjoergregister long flags; 45015645Sjoerg{ 45115645Sjoerg register tcflag_t iflag, oflag, cflag, lflag; 45215645Sjoerg 45315645Sjoerg iflag = BRKINT|ICRNL|IMAXBEL|IXON|IXANY; 45415645Sjoerg oflag = OPOST|ONLCR|OXTABS; 45515645Sjoerg cflag = CREAD; 45615645Sjoerg lflag = ICANON|ISIG|IEXTEN; 45715645Sjoerg 45815645Sjoerg if (ISSET(flags, TANDEM)) 45915645Sjoerg SET(iflag, IXOFF); 46015645Sjoerg else 46115645Sjoerg CLR(iflag, IXOFF); 46215645Sjoerg if (ISSET(flags, ECHO)) 46315645Sjoerg SET(lflag, ECHO); 46415645Sjoerg else 46515645Sjoerg CLR(lflag, ECHO); 46615645Sjoerg if (ISSET(flags, CRMOD)) { 46715645Sjoerg SET(iflag, ICRNL); 46815645Sjoerg SET(oflag, ONLCR); 46915645Sjoerg } else { 47015645Sjoerg CLR(iflag, ICRNL); 47115645Sjoerg CLR(oflag, ONLCR); 47215645Sjoerg } 47315645Sjoerg if (ISSET(flags, XTABS)) 47415645Sjoerg SET(oflag, OXTABS); 47515645Sjoerg else 47615645Sjoerg CLR(oflag, OXTABS); 47715645Sjoerg 47815645Sjoerg 47915645Sjoerg if (ISSET(flags, RAW)) { 48015645Sjoerg iflag &= IXOFF; 48115645Sjoerg CLR(lflag, ISIG|ICANON|IEXTEN); 48215645Sjoerg CLR(cflag, PARENB); 48315645Sjoerg } else { 48415645Sjoerg SET(iflag, BRKINT|IXON|IMAXBEL); 48515645Sjoerg SET(lflag, ISIG|IEXTEN); 48615645Sjoerg if (ISSET(flags, CBREAK)) 48715645Sjoerg CLR(lflag, ICANON); 48815645Sjoerg else 48915645Sjoerg SET(lflag, ICANON); 49015645Sjoerg switch (ISSET(flags, ANYP)) { 49115645Sjoerg case 0: 49215645Sjoerg CLR(cflag, PARENB); 49315645Sjoerg break; 49415645Sjoerg case ANYP: 49515645Sjoerg SET(cflag, PARENB); 49615645Sjoerg CLR(iflag, INPCK); 49715645Sjoerg break; 49815645Sjoerg case EVENP: 49915645Sjoerg SET(cflag, PARENB); 50015645Sjoerg SET(iflag, INPCK); 50115645Sjoerg CLR(cflag, PARODD); 50215645Sjoerg break; 50315645Sjoerg case ODDP: 50415645Sjoerg SET(cflag, PARENB); 50515645Sjoerg SET(iflag, INPCK); 50615645Sjoerg SET(cflag, PARODD); 50715645Sjoerg break; 50815645Sjoerg } 50915645Sjoerg } 51015645Sjoerg 51115645Sjoerg /* Nothing we can do with CRTBS. */ 51215645Sjoerg if (ISSET(flags, PRTERA)) 51315645Sjoerg SET(lflag, ECHOPRT); 51415645Sjoerg else 51515645Sjoerg CLR(lflag, ECHOPRT); 51615645Sjoerg if (ISSET(flags, CRTERA)) 51715645Sjoerg SET(lflag, ECHOE); 51815645Sjoerg else 51915645Sjoerg CLR(lflag, ECHOE); 52015645Sjoerg /* Nothing we can do with TILDE. */ 52115645Sjoerg if (ISSET(flags, MDMBUF)) 52215645Sjoerg SET(cflag, MDMBUF); 52315645Sjoerg else 52415645Sjoerg CLR(cflag, MDMBUF); 52515645Sjoerg if (ISSET(flags, NOHANG)) 52615645Sjoerg CLR(cflag, HUPCL); 52715645Sjoerg else 52815645Sjoerg SET(cflag, HUPCL); 52915645Sjoerg if (ISSET(flags, CRTKIL)) 53015645Sjoerg SET(lflag, ECHOKE); 53115645Sjoerg else 53215645Sjoerg CLR(lflag, ECHOKE); 53315645Sjoerg if (ISSET(flags, CTLECH)) 53415645Sjoerg SET(lflag, ECHOCTL); 53515645Sjoerg else 53615645Sjoerg CLR(lflag, ECHOCTL); 53715645Sjoerg if (!ISSET(flags, DECCTQ)) 53815645Sjoerg SET(iflag, IXANY); 53915645Sjoerg else 54015645Sjoerg CLR(iflag, IXANY); 54115645Sjoerg CLR(lflag, TOSTOP|FLUSHO|PENDIN|NOFLSH); 54215645Sjoerg SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH)); 54315645Sjoerg 54415645Sjoerg if (ISSET(flags, RAW|LITOUT|PASS8)) { 54515645Sjoerg CLR(cflag, CSIZE); 54615645Sjoerg SET(cflag, CS8); 54715645Sjoerg if (!ISSET(flags, RAW|PASS8)) 54815645Sjoerg SET(iflag, ISTRIP); 54915645Sjoerg else 55015645Sjoerg CLR(iflag, ISTRIP); 55115645Sjoerg if (!ISSET(flags, RAW|LITOUT)) 55215645Sjoerg SET(oflag, OPOST); 55315645Sjoerg else 55415645Sjoerg CLR(oflag, OPOST); 55515645Sjoerg } else { 55615645Sjoerg CLR(cflag, CSIZE); 55715645Sjoerg SET(cflag, CS7); 55815645Sjoerg SET(iflag, ISTRIP); 55915645Sjoerg SET(oflag, OPOST); 56015645Sjoerg } 56115645Sjoerg 56215645Sjoerg tmode.c_iflag = iflag; 56315645Sjoerg tmode.c_oflag = oflag; 56415645Sjoerg tmode.c_cflag = cflag; 56515645Sjoerg tmode.c_lflag = lflag; 56615645Sjoerg} 56715645Sjoerg#endif 56815645Sjoerg 56915645Sjoerg#ifdef XXX_DELAY 5701592Srgrimesstruct delayval { 5711592Srgrimes unsigned delay; /* delay in ms */ 5721592Srgrimes int bits; 5731592Srgrimes}; 5741592Srgrimes 5751592Srgrimes/* 5761592Srgrimes * below are random guesses, I can't be bothered checking 5771592Srgrimes */ 5781592Srgrimes 5791592Srgrimesstruct delayval crdelay[] = { 58015645Sjoerg { 1, CR1 }, 58115645Sjoerg { 2, CR2 }, 58215645Sjoerg { 3, CR3 }, 58315645Sjoerg { 83, CR1 }, 58415645Sjoerg { 166, CR2 }, 58515645Sjoerg { 0, CR3 }, 5861592Srgrimes}; 5871592Srgrimes 5881592Srgrimesstruct delayval nldelay[] = { 58915645Sjoerg { 1, NL1 }, /* special, calculated */ 59015645Sjoerg { 2, NL2 }, 59115645Sjoerg { 3, NL3 }, 59215645Sjoerg { 100, NL2 }, 59315645Sjoerg { 0, NL3 }, 5941592Srgrimes}; 5951592Srgrimes 5961592Srgrimesstruct delayval bsdelay[] = { 59715645Sjoerg { 1, BS1 }, 59815645Sjoerg { 0, 0 }, 5991592Srgrimes}; 6001592Srgrimes 6011592Srgrimesstruct delayval ffdelay[] = { 60215645Sjoerg { 1, FF1 }, 60315645Sjoerg { 1750, FF1 }, 60415645Sjoerg { 0, FF1 }, 6051592Srgrimes}; 6061592Srgrimes 6071592Srgrimesstruct delayval tbdelay[] = { 60815645Sjoerg { 1, TAB1 }, 60915645Sjoerg { 2, TAB2 }, 61015645Sjoerg { 3, XTABS }, /* this is expand tabs */ 61115645Sjoerg { 100, TAB1 }, 61215645Sjoerg { 0, TAB2 }, 6131592Srgrimes}; 6141592Srgrimes 61515645Sjoergint 6161592Srgrimesdelaybits() 6171592Srgrimes{ 61815645Sjoerg register int f; 6191592Srgrimes 6201592Srgrimes f = adelay(CD, crdelay); 6211592Srgrimes f |= adelay(ND, nldelay); 6221592Srgrimes f |= adelay(FD, ffdelay); 6231592Srgrimes f |= adelay(TD, tbdelay); 6241592Srgrimes f |= adelay(BD, bsdelay); 6251592Srgrimes return (f); 6261592Srgrimes} 6271592Srgrimes 62815645Sjoergint 6291592Srgrimesadelay(ms, dp) 6301592Srgrimes register ms; 6311592Srgrimes register struct delayval *dp; 6321592Srgrimes{ 6331592Srgrimes if (ms == 0) 6341592Srgrimes return (0); 6351592Srgrimes while (dp->delay && ms > dp->delay) 6361592Srgrimes dp++; 6371592Srgrimes return (dp->bits); 6381592Srgrimes} 63915645Sjoerg#endif 6401592Srgrimes 64115645Sjoergchar editedhost[MAXHOSTNAMELEN]; 6421592Srgrimes 64315645Sjoergvoid 6441592Srgrimesedithost(pat) 64515645Sjoerg register const char *pat; 6461592Srgrimes{ 64715645Sjoerg register const char *host = HN; 6481592Srgrimes register char *res = editedhost; 6491592Srgrimes 6501592Srgrimes if (!pat) 6511592Srgrimes pat = ""; 6521592Srgrimes while (*pat) { 6531592Srgrimes switch (*pat) { 6541592Srgrimes 6551592Srgrimes case '#': 6561592Srgrimes if (*host) 6571592Srgrimes host++; 6581592Srgrimes break; 6591592Srgrimes 6601592Srgrimes case '@': 6611592Srgrimes if (*host) 6621592Srgrimes *res++ = *host++; 6631592Srgrimes break; 6641592Srgrimes 6651592Srgrimes default: 6661592Srgrimes *res++ = *pat; 6671592Srgrimes break; 6681592Srgrimes 6691592Srgrimes } 6701592Srgrimes if (res == &editedhost[sizeof editedhost - 1]) { 6711592Srgrimes *res = '\0'; 6721592Srgrimes return; 6731592Srgrimes } 6741592Srgrimes pat++; 6751592Srgrimes } 6761592Srgrimes if (*host) 6771592Srgrimes strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); 6781592Srgrimes else 6791592Srgrimes *res = '\0'; 6801592Srgrimes editedhost[sizeof editedhost - 1] = '\0'; 6811592Srgrimes} 6821592Srgrimes 68315645Sjoergstatic struct speedtab { 6841592Srgrimes int speed; 6851592Srgrimes int uxname; 6861592Srgrimes} speedtab[] = { 68715645Sjoerg { 50, B50 }, 68815645Sjoerg { 75, B75 }, 68915645Sjoerg { 110, B110 }, 69015645Sjoerg { 134, B134 }, 69115645Sjoerg { 150, B150 }, 69215645Sjoerg { 200, B200 }, 69315645Sjoerg { 300, B300 }, 69415645Sjoerg { 600, B600 }, 69515645Sjoerg { 1200, B1200 }, 69615645Sjoerg { 1800, B1800 }, 69715645Sjoerg { 2400, B2400 }, 69815645Sjoerg { 4800, B4800 }, 69915645Sjoerg { 9600, B9600 }, 70015645Sjoerg { 19200, EXTA }, 70115645Sjoerg { 19, EXTA }, /* for people who say 19.2K */ 70215645Sjoerg { 38400, EXTB }, 70315645Sjoerg { 38, EXTB }, 70415645Sjoerg { 7200, EXTB }, /* alternative */ 70515645Sjoerg { 57600, B57600 }, 70615645Sjoerg { 115200, B115200 }, 70737817Sphk { 230400, B230400 }, 70815645Sjoerg { 0 } 7091592Srgrimes}; 7101592Srgrimes 71115645Sjoergint 7121592Srgrimesspeed(val) 71315645Sjoerg int val; 7141592Srgrimes{ 7151592Srgrimes register struct speedtab *sp; 7161592Srgrimes 71737817Sphk if (val <= B230400) 7181592Srgrimes return (val); 7191592Srgrimes 7201592Srgrimes for (sp = speedtab; sp->speed; sp++) 7211592Srgrimes if (sp->speed == val) 7221592Srgrimes return (sp->uxname); 7238870Srgrimes 7241592Srgrimes return (B300); /* default in impossible cases */ 7251592Srgrimes} 7261592Srgrimes 72715645Sjoergvoid 7281592Srgrimesmakeenv(env) 7291592Srgrimes char *env[]; 7301592Srgrimes{ 7311592Srgrimes static char termbuf[128] = "TERM="; 7321592Srgrimes register char *p, *q; 7331592Srgrimes register char **ep; 7341592Srgrimes 7351592Srgrimes ep = env; 7361592Srgrimes if (TT && *TT) { 7371592Srgrimes strcat(termbuf, TT); 7381592Srgrimes *ep++ = termbuf; 7391592Srgrimes } 74015645Sjoerg if ((p = EV)) { 7411592Srgrimes q = p; 74215645Sjoerg while ((q = strchr(q, ','))) { 7431592Srgrimes *q++ = '\0'; 7441592Srgrimes *ep++ = p; 7451592Srgrimes p = q; 7461592Srgrimes } 7471592Srgrimes if (*p) 7481592Srgrimes *ep++ = p; 7491592Srgrimes } 7501592Srgrimes *ep = (char *)0; 7511592Srgrimes} 7521592Srgrimes 7531592Srgrimes/* 7541592Srgrimes * This speed select mechanism is written for the Develcon DATASWITCH. 7551592Srgrimes * The Develcon sends a string of the form "B{speed}\n" at a predefined 7561592Srgrimes * baud rate. This string indicates the user's actual speed. 7571592Srgrimes * The routine below returns the terminal type mapped from derived speed. 7581592Srgrimes */ 7591592Srgrimesstruct portselect { 76015645Sjoerg const char *ps_baud; 76115645Sjoerg const char *ps_type; 7621592Srgrimes} portspeeds[] = { 7631592Srgrimes { "B110", "std.110" }, 7641592Srgrimes { "B134", "std.134" }, 7651592Srgrimes { "B150", "std.150" }, 7661592Srgrimes { "B300", "std.300" }, 7671592Srgrimes { "B600", "std.600" }, 7681592Srgrimes { "B1200", "std.1200" }, 7691592Srgrimes { "B2400", "std.2400" }, 7701592Srgrimes { "B4800", "std.4800" }, 7711592Srgrimes { "B9600", "std.9600" }, 7721592Srgrimes { "B19200", "std.19200" }, 7731592Srgrimes { 0 } 7741592Srgrimes}; 7751592Srgrimes 77615645Sjoergconst char * 7771592Srgrimesportselector() 7781592Srgrimes{ 77915645Sjoerg char c, baud[20]; 78015645Sjoerg const char *type = "default"; 7811592Srgrimes register struct portselect *ps; 7821592Srgrimes int len; 7831592Srgrimes 7841592Srgrimes alarm(5*60); 7851592Srgrimes for (len = 0; len < sizeof (baud) - 1; len++) { 7861592Srgrimes if (read(STDIN_FILENO, &c, 1) <= 0) 7871592Srgrimes break; 7881592Srgrimes c &= 0177; 7891592Srgrimes if (c == '\n' || c == '\r') 7901592Srgrimes break; 7911592Srgrimes if (c == 'B') 7921592Srgrimes len = 0; /* in case of leading garbage */ 7931592Srgrimes baud[len] = c; 7941592Srgrimes } 7951592Srgrimes baud[len] = '\0'; 7961592Srgrimes for (ps = portspeeds; ps->ps_baud; ps++) 7971592Srgrimes if (strcmp(ps->ps_baud, baud) == 0) { 7981592Srgrimes type = ps->ps_type; 7991592Srgrimes break; 8001592Srgrimes } 8011592Srgrimes sleep(2); /* wait for connection to complete */ 8021592Srgrimes return (type); 8031592Srgrimes} 8041592Srgrimes 8051592Srgrimes/* 8061592Srgrimes * This auto-baud speed select mechanism is written for the Micom 600 8071592Srgrimes * portselector. Selection is done by looking at how the character '\r' 8081592Srgrimes * is garbled at the different speeds. 8091592Srgrimes */ 81015645Sjoergconst char * 8111592Srgrimesautobaud() 8121592Srgrimes{ 8131592Srgrimes int rfds; 8141592Srgrimes struct timeval timeout; 81515645Sjoerg char c; 81615645Sjoerg const char *type = "9600-baud"; 8171592Srgrimes 81815645Sjoerg (void)tcflush(0, TCIOFLUSH); 8191592Srgrimes rfds = 1 << 0; 8201592Srgrimes timeout.tv_sec = 5; 8211592Srgrimes timeout.tv_usec = 0; 8221592Srgrimes if (select(32, (fd_set *)&rfds, (fd_set *)NULL, 8231592Srgrimes (fd_set *)NULL, &timeout) <= 0) 8241592Srgrimes return (type); 8251592Srgrimes if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char)) 8261592Srgrimes return (type); 8271592Srgrimes timeout.tv_sec = 0; 8281592Srgrimes timeout.tv_usec = 20; 8291592Srgrimes (void) select(32, (fd_set *)NULL, (fd_set *)NULL, 8301592Srgrimes (fd_set *)NULL, &timeout); 83115645Sjoerg (void)tcflush(0, TCIOFLUSH); 8321592Srgrimes switch (c & 0377) { 8331592Srgrimes 8341592Srgrimes case 0200: /* 300-baud */ 8351592Srgrimes type = "300-baud"; 8361592Srgrimes break; 8371592Srgrimes 8381592Srgrimes case 0346: /* 1200-baud */ 8391592Srgrimes type = "1200-baud"; 8401592Srgrimes break; 8411592Srgrimes 8421592Srgrimes case 015: /* 2400-baud */ 8431592Srgrimes case 0215: 8441592Srgrimes type = "2400-baud"; 8451592Srgrimes break; 8461592Srgrimes 8471592Srgrimes default: /* 4800-baud */ 8481592Srgrimes type = "4800-baud"; 8491592Srgrimes break; 8501592Srgrimes 8511592Srgrimes case 0377: /* 9600-baud */ 8521592Srgrimes type = "9600-baud"; 8531592Srgrimes break; 8541592Srgrimes } 8551592Srgrimes return (type); 8561592Srgrimes} 857