1ea022d16SRodney W. Grimes /* 2cae66988SJoerg Wunsch * Copyright (c) 1983, 1993 3cae66988SJoerg Wunsch * The Regents of the University of California. All rights reserved. 4ea022d16SRodney W. Grimes * 5ea022d16SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 6ea022d16SRodney W. Grimes * modification, are permitted provided that the following conditions 7ea022d16SRodney W. Grimes * are met: 8ea022d16SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 9ea022d16SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 10ea022d16SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 11ea022d16SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 12ea022d16SRodney W. Grimes * documentation and/or other materials provided with the distribution. 135efaea4cSChristian Brueffer * 3. Neither the name of the University nor the names of its contributors 14ea022d16SRodney W. Grimes * may be used to endorse or promote products derived from this software 15ea022d16SRodney W. Grimes * without specific prior written permission. 16ea022d16SRodney W. Grimes * 17ea022d16SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18ea022d16SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19ea022d16SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20ea022d16SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21ea022d16SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22ea022d16SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23ea022d16SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24ea022d16SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25ea022d16SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26ea022d16SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27ea022d16SRodney W. Grimes * SUCH DAMAGE. 28ea022d16SRodney W. Grimes */ 29ea022d16SRodney W. Grimes 30ea022d16SRodney W. Grimes #ifndef lint 31d748864dSPhilippe Charnier #if 0 32d748864dSPhilippe Charnier static char sccsid[] = "@(#)from: subr.c 8.1 (Berkeley) 6/4/93"; 33d748864dSPhilippe Charnier #endif 34d748864dSPhilippe Charnier static const char rcsid[] = 357f3dea24SPeter Wemm "$FreeBSD$"; 36ea022d16SRodney W. Grimes #endif /* not lint */ 37ea022d16SRodney W. Grimes 38ea022d16SRodney W. Grimes /* 39ea022d16SRodney W. Grimes * Melbourne getty. 40ea022d16SRodney W. Grimes */ 41d748864dSPhilippe Charnier #include <sys/ioctl.h> 42d748864dSPhilippe Charnier #include <sys/param.h> 43d748864dSPhilippe Charnier #include <sys/time.h> 44*a3e4b982SPedro F. Giffuni 45*a3e4b982SPedro F. Giffuni #include <poll.h> 46*a3e4b982SPedro F. Giffuni #include <stdlib.h> 47*a3e4b982SPedro F. Giffuni #include <string.h> 48d748864dSPhilippe Charnier #include <syslog.h> 49*a3e4b982SPedro F. Giffuni #include <termios.h> 50*a3e4b982SPedro F. Giffuni #include <unistd.h> 51ea022d16SRodney W. Grimes 52cae66988SJoerg Wunsch #include "gettytab.h" 53cae66988SJoerg Wunsch #include "pathnames.h" 54cae66988SJoerg Wunsch #include "extern.h" 55cae66988SJoerg Wunsch 56cae66988SJoerg Wunsch 57ea022d16SRodney W. Grimes 58ea022d16SRodney W. Grimes /* 59ea022d16SRodney W. Grimes * Get a table entry. 60ea022d16SRodney W. Grimes */ 61cae66988SJoerg Wunsch void 6295289b27SWarner Losh gettable(const char *name, char *buf) 63ea022d16SRodney W. Grimes { 6495289b27SWarner Losh struct gettystrs *sp; 6595289b27SWarner Losh struct gettynums *np; 6695289b27SWarner Losh struct gettyflags *fp; 67cae66988SJoerg Wunsch long n; 6804a59e67SDavid Nugent int l; 6904a59e67SDavid Nugent char *p; 7004a59e67SDavid Nugent char *msg = NULL; 71cae66988SJoerg Wunsch const char *dba[2]; 7204a59e67SDavid Nugent 7304a59e67SDavid Nugent static int firsttime = 1; 7404a59e67SDavid Nugent 75cae66988SJoerg Wunsch dba[0] = _PATH_GETTYTAB; 76cae66988SJoerg Wunsch dba[1] = 0; 77ea022d16SRodney W. Grimes 7804a59e67SDavid Nugent if (firsttime) { 7904a59e67SDavid Nugent /* 8004a59e67SDavid Nugent * we need to strdup() anything in the strings array 8104a59e67SDavid Nugent * initially in order to simplify things later 8204a59e67SDavid Nugent */ 83ea022d16SRodney W. Grimes for (sp = gettystrs; sp->field; sp++) 8404a59e67SDavid Nugent if (sp->value != NULL) { 8504a59e67SDavid Nugent /* handle these ones more carefully */ 8604a59e67SDavid Nugent if (sp >= &gettystrs[4] && sp <= &gettystrs[6]) 8704a59e67SDavid Nugent l = 2; 8804a59e67SDavid Nugent else 8904a59e67SDavid Nugent l = strlen(sp->value) + 1; 9004a59e67SDavid Nugent if ((p = malloc(l)) != NULL) { 9104a59e67SDavid Nugent strncpy(p, sp->value, l); 9204a59e67SDavid Nugent p[l-1] = '\0'; 9304a59e67SDavid Nugent } 9404a59e67SDavid Nugent /* 9504a59e67SDavid Nugent * replace, even if NULL, else we'll 9604a59e67SDavid Nugent * have problems with free()ing static mem 9704a59e67SDavid Nugent */ 9804a59e67SDavid Nugent sp->value = p; 9904a59e67SDavid Nugent } 10004a59e67SDavid Nugent firsttime = 0; 10104a59e67SDavid Nugent } 10204a59e67SDavid Nugent 10304a59e67SDavid Nugent switch (cgetent(&buf, (char **)dba, (char *)name)) { 10404a59e67SDavid Nugent case 1: 10504a59e67SDavid Nugent msg = "%s: couldn't resolve 'tc=' in gettytab '%s'"; 10604a59e67SDavid Nugent case 0: 10704a59e67SDavid Nugent break; 10804a59e67SDavid Nugent case -1: 10904a59e67SDavid Nugent msg = "%s: unknown gettytab entry '%s'"; 11004a59e67SDavid Nugent break; 11104a59e67SDavid Nugent case -2: 11204a59e67SDavid Nugent msg = "%s: retrieving gettytab entry '%s': %m"; 11304a59e67SDavid Nugent break; 11404a59e67SDavid Nugent case -3: 11504a59e67SDavid Nugent msg = "%s: recursive 'tc=' reference gettytab entry '%s'"; 11604a59e67SDavid Nugent break; 11704a59e67SDavid Nugent default: 11804a59e67SDavid Nugent msg = "%s: unexpected cgetent() error for entry '%s'"; 11904a59e67SDavid Nugent break; 12004a59e67SDavid Nugent } 12104a59e67SDavid Nugent 12204a59e67SDavid Nugent if (msg != NULL) { 12304a59e67SDavid Nugent syslog(LOG_ERR, msg, "getty", name); 12404a59e67SDavid Nugent return; 12504a59e67SDavid Nugent } 12604a59e67SDavid Nugent 12704a59e67SDavid Nugent for (sp = gettystrs; sp->field; sp++) { 1281cc15828SDavid Nugent if ((l = cgetstr(buf, (char*)sp->field, &p)) >= 0) { 12904a59e67SDavid Nugent if (sp->value) { 13004a59e67SDavid Nugent /* prefer existing value */ 13104a59e67SDavid Nugent if (strcmp(p, sp->value) != 0) 13204a59e67SDavid Nugent free(sp->value); 13304a59e67SDavid Nugent else { 13404a59e67SDavid Nugent free(p); 13504a59e67SDavid Nugent p = sp->value; 13604a59e67SDavid Nugent } 13704a59e67SDavid Nugent } 13804a59e67SDavid Nugent sp->value = p; 13904a59e67SDavid Nugent } else if (l == -1) { 14004a59e67SDavid Nugent free(sp->value); 14104a59e67SDavid Nugent sp->value = NULL; 14204a59e67SDavid Nugent } 14304a59e67SDavid Nugent } 14404a59e67SDavid Nugent 145ea022d16SRodney W. Grimes for (np = gettynums; np->field; np++) { 14604a59e67SDavid Nugent if (cgetnum(buf, (char*)np->field, &n) == -1) 147ea022d16SRodney W. Grimes np->set = 0; 148ea022d16SRodney W. Grimes else { 149ea022d16SRodney W. Grimes np->set = 1; 150ea022d16SRodney W. Grimes np->value = n; 151ea022d16SRodney W. Grimes } 152ea022d16SRodney W. Grimes } 15304a59e67SDavid Nugent 154ea022d16SRodney W. Grimes for (fp = gettyflags; fp->field; fp++) { 15504a59e67SDavid Nugent if (cgetcap(buf, (char *)fp->field, ':') == NULL) 156ea022d16SRodney W. Grimes fp->set = 0; 157ea022d16SRodney W. Grimes else { 158ea022d16SRodney W. Grimes fp->set = 1; 159cae66988SJoerg Wunsch fp->value = 1 ^ fp->invrt; 160ea022d16SRodney W. Grimes } 161ea022d16SRodney W. Grimes } 162ea022d16SRodney W. Grimes } 163ea022d16SRodney W. Grimes 164cae66988SJoerg Wunsch void 16595289b27SWarner Losh gendefaults(void) 166ea022d16SRodney W. Grimes { 16795289b27SWarner Losh struct gettystrs *sp; 16895289b27SWarner Losh struct gettynums *np; 16995289b27SWarner Losh struct gettyflags *fp; 170ea022d16SRodney W. Grimes 171ea022d16SRodney W. Grimes for (sp = gettystrs; sp->field; sp++) 172ea022d16SRodney W. Grimes if (sp->value) 17304a59e67SDavid Nugent sp->defalt = strdup(sp->value); 174ea022d16SRodney W. Grimes for (np = gettynums; np->field; np++) 175ea022d16SRodney W. Grimes if (np->set) 176ea022d16SRodney W. Grimes np->defalt = np->value; 177ea022d16SRodney W. Grimes for (fp = gettyflags; fp->field; fp++) 178ea022d16SRodney W. Grimes if (fp->set) 179ea022d16SRodney W. Grimes fp->defalt = fp->value; 180ea022d16SRodney W. Grimes else 181ea022d16SRodney W. Grimes fp->defalt = fp->invrt; 182ea022d16SRodney W. Grimes } 183ea022d16SRodney W. Grimes 184cae66988SJoerg Wunsch void 18595289b27SWarner Losh setdefaults(void) 186ea022d16SRodney W. Grimes { 18795289b27SWarner Losh struct gettystrs *sp; 18895289b27SWarner Losh struct gettynums *np; 18995289b27SWarner Losh struct gettyflags *fp; 190ea022d16SRodney W. Grimes 191ea022d16SRodney W. Grimes for (sp = gettystrs; sp->field; sp++) 192ea022d16SRodney W. Grimes if (!sp->value) 19304a59e67SDavid Nugent sp->value = !sp->defalt ? sp->defalt 19404a59e67SDavid Nugent : strdup(sp->defalt); 195ea022d16SRodney W. Grimes for (np = gettynums; np->field; np++) 196ea022d16SRodney W. Grimes if (!np->set) 197ea022d16SRodney W. Grimes np->value = np->defalt; 198ea022d16SRodney W. Grimes for (fp = gettyflags; fp->field; fp++) 199ea022d16SRodney W. Grimes if (!fp->set) 200ea022d16SRodney W. Grimes fp->value = fp->defalt; 201ea022d16SRodney W. Grimes } 202ea022d16SRodney W. Grimes 203ea022d16SRodney W. Grimes static char ** 204ea022d16SRodney W. Grimes charnames[] = { 205ea022d16SRodney W. Grimes &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK, 206ea022d16SRodney W. Grimes &SU, &DS, &RP, &FL, &WE, &LN, 0 207ea022d16SRodney W. Grimes }; 208ea022d16SRodney W. Grimes 209ea022d16SRodney W. Grimes static char * 210ea022d16SRodney W. Grimes charvars[] = { 211cae66988SJoerg Wunsch &tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR], 212cae66988SJoerg Wunsch &tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP], 213cae66988SJoerg Wunsch &tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP], 214cae66988SJoerg Wunsch &tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD], 215cae66988SJoerg Wunsch &tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], 0 216ea022d16SRodney W. Grimes }; 217ea022d16SRodney W. Grimes 218cae66988SJoerg Wunsch void 21995289b27SWarner Losh setchars(void) 220ea022d16SRodney W. Grimes { 22195289b27SWarner Losh int i; 22295289b27SWarner Losh const char *p; 223ea022d16SRodney W. Grimes 224ea022d16SRodney W. Grimes for (i = 0; charnames[i]; i++) { 225ea022d16SRodney W. Grimes p = *charnames[i]; 226ea022d16SRodney W. Grimes if (p && *p) 227ea022d16SRodney W. Grimes *charvars[i] = *p; 228ea022d16SRodney W. Grimes else 229cae66988SJoerg Wunsch *charvars[i] = _POSIX_VDISABLE; 230ea022d16SRodney W. Grimes } 231ea022d16SRodney W. Grimes } 232ea022d16SRodney W. Grimes 233cae66988SJoerg Wunsch /* Macros to clear/set/test flags. */ 234cae66988SJoerg Wunsch #define SET(t, f) (t) |= (f) 235cae66988SJoerg Wunsch #define CLR(t, f) (t) &= ~(f) 236cae66988SJoerg Wunsch #define ISSET(t, f) ((t) & (f)) 237cae66988SJoerg Wunsch 238cae66988SJoerg Wunsch void 23995289b27SWarner Losh set_flags(int n) 240ea022d16SRodney W. Grimes { 24195289b27SWarner Losh tcflag_t iflag, oflag, cflag, lflag; 242cae66988SJoerg Wunsch 243ea022d16SRodney W. Grimes 244ea022d16SRodney W. Grimes switch (n) { 245ea022d16SRodney W. Grimes case 0: 246cae66988SJoerg Wunsch if (C0set && I0set && L0set && O0set) { 247cae66988SJoerg Wunsch tmode.c_cflag = C0; 248cae66988SJoerg Wunsch tmode.c_iflag = I0; 249cae66988SJoerg Wunsch tmode.c_lflag = L0; 250cae66988SJoerg Wunsch tmode.c_oflag = O0; 251cae66988SJoerg Wunsch return; 252cae66988SJoerg Wunsch } 253ea022d16SRodney W. Grimes break; 254ea022d16SRodney W. Grimes case 1: 255cae66988SJoerg Wunsch if (C1set && I1set && L1set && O1set) { 256cae66988SJoerg Wunsch tmode.c_cflag = C1; 257cae66988SJoerg Wunsch tmode.c_iflag = I1; 258cae66988SJoerg Wunsch tmode.c_lflag = L1; 259cae66988SJoerg Wunsch tmode.c_oflag = O1; 260cae66988SJoerg Wunsch return; 261cae66988SJoerg Wunsch } 262ea022d16SRodney W. Grimes break; 263ea022d16SRodney W. Grimes default: 264cae66988SJoerg Wunsch if (C2set && I2set && L2set && O2set) { 265cae66988SJoerg Wunsch tmode.c_cflag = C2; 266cae66988SJoerg Wunsch tmode.c_iflag = I2; 267cae66988SJoerg Wunsch tmode.c_lflag = L2; 268cae66988SJoerg Wunsch tmode.c_oflag = O2; 269cae66988SJoerg Wunsch return; 270cae66988SJoerg Wunsch } 271ea022d16SRodney W. Grimes break; 272ea022d16SRodney W. Grimes } 273ea022d16SRodney W. Grimes 274cae66988SJoerg Wunsch iflag = omode.c_iflag; 275cae66988SJoerg Wunsch oflag = omode.c_oflag; 276cae66988SJoerg Wunsch cflag = omode.c_cflag; 277cae66988SJoerg Wunsch lflag = omode.c_lflag; 278ea022d16SRodney W. Grimes 279cae66988SJoerg Wunsch if (NP) { 280cae66988SJoerg Wunsch CLR(cflag, CSIZE|PARENB); 281cae66988SJoerg Wunsch SET(cflag, CS8); 282cae66988SJoerg Wunsch CLR(iflag, ISTRIP|INPCK|IGNPAR); 283cae66988SJoerg Wunsch } else if (AP || EP || OP) { 284cae66988SJoerg Wunsch CLR(cflag, CSIZE); 285cae66988SJoerg Wunsch SET(cflag, CS7|PARENB); 286cae66988SJoerg Wunsch SET(iflag, ISTRIP); 287cae66988SJoerg Wunsch if (OP && !EP) { 288cae66988SJoerg Wunsch SET(iflag, INPCK|IGNPAR); 289cae66988SJoerg Wunsch SET(cflag, PARODD); 290ea022d16SRodney W. Grimes if (AP) 291cae66988SJoerg Wunsch CLR(iflag, INPCK); 292cae66988SJoerg Wunsch } else if (EP && !OP) { 293cae66988SJoerg Wunsch SET(iflag, INPCK|IGNPAR); 294cae66988SJoerg Wunsch CLR(cflag, PARODD); 295cae66988SJoerg Wunsch if (AP) 296cae66988SJoerg Wunsch CLR(iflag, INPCK); 297cae66988SJoerg Wunsch } else if (AP || (EP && OP)) { 298cae66988SJoerg Wunsch CLR(iflag, INPCK|IGNPAR); 299cae66988SJoerg Wunsch CLR(cflag, PARODD); 300cae66988SJoerg Wunsch } 301cae66988SJoerg Wunsch } /* else, leave as is */ 302ea022d16SRodney W. Grimes 303cae66988SJoerg Wunsch #if 0 304ea022d16SRodney W. Grimes if (UC) 305ea022d16SRodney W. Grimes f |= LCASE; 306cae66988SJoerg Wunsch #endif 307ea022d16SRodney W. Grimes 308cae66988SJoerg Wunsch if (HC) 309cae66988SJoerg Wunsch SET(cflag, HUPCL); 310ea022d16SRodney W. Grimes else 311cae66988SJoerg Wunsch CLR(cflag, HUPCL); 312cae66988SJoerg Wunsch 313cae66988SJoerg Wunsch if (MB) 314cae66988SJoerg Wunsch SET(cflag, MDMBUF); 315cae66988SJoerg Wunsch else 316cae66988SJoerg Wunsch CLR(cflag, MDMBUF); 317cae66988SJoerg Wunsch 318fe552114SDavid Nugent if (HW) 319fe552114SDavid Nugent SET(cflag, CRTSCTS); 320fe552114SDavid Nugent else 321fe552114SDavid Nugent CLR(cflag, CRTSCTS); 322fe552114SDavid Nugent 323cae66988SJoerg Wunsch if (NL) { 324cae66988SJoerg Wunsch SET(iflag, ICRNL); 325cae66988SJoerg Wunsch SET(oflag, ONLCR|OPOST); 326cae66988SJoerg Wunsch } else { 327cae66988SJoerg Wunsch CLR(iflag, ICRNL); 328cae66988SJoerg Wunsch CLR(oflag, ONLCR); 329ea022d16SRodney W. Grimes } 330ea022d16SRodney W. Grimes 331ea022d16SRodney W. Grimes if (!HT) 332cae66988SJoerg Wunsch SET(oflag, OXTABS|OPOST); 333cae66988SJoerg Wunsch else 334cae66988SJoerg Wunsch CLR(oflag, OXTABS); 335ea022d16SRodney W. Grimes 336cae66988SJoerg Wunsch #ifdef XXX_DELAY 337cae66988SJoerg Wunsch SET(f, delaybits()); 338cae66988SJoerg Wunsch #endif 339ea022d16SRodney W. Grimes 340cae66988SJoerg Wunsch if (n == 1) { /* read mode flags */ 341cae66988SJoerg Wunsch if (RW) { 342cae66988SJoerg Wunsch iflag = 0; 343cae66988SJoerg Wunsch CLR(oflag, OPOST); 344cae66988SJoerg Wunsch CLR(cflag, CSIZE|PARENB); 345cae66988SJoerg Wunsch SET(cflag, CS8); 346cae66988SJoerg Wunsch lflag = 0; 347cae66988SJoerg Wunsch } else { 348cae66988SJoerg Wunsch CLR(lflag, ICANON); 349cae66988SJoerg Wunsch } 350cae66988SJoerg Wunsch goto out; 351ea022d16SRodney W. Grimes } 352ea022d16SRodney W. Grimes 353cae66988SJoerg Wunsch if (n == 0) 354cae66988SJoerg Wunsch goto out; 355cae66988SJoerg Wunsch 356cae66988SJoerg Wunsch #if 0 357cae66988SJoerg Wunsch if (CB) 358cae66988SJoerg Wunsch SET(f, CRTBS); 359cae66988SJoerg Wunsch #endif 360cae66988SJoerg Wunsch 361cae66988SJoerg Wunsch if (CE) 362cae66988SJoerg Wunsch SET(lflag, ECHOE); 363cae66988SJoerg Wunsch else 364cae66988SJoerg Wunsch CLR(lflag, ECHOE); 365cae66988SJoerg Wunsch 366cae66988SJoerg Wunsch if (CK) 367cae66988SJoerg Wunsch SET(lflag, ECHOKE); 368cae66988SJoerg Wunsch else 369cae66988SJoerg Wunsch CLR(lflag, ECHOKE); 370cae66988SJoerg Wunsch 371cae66988SJoerg Wunsch if (PE) 372cae66988SJoerg Wunsch SET(lflag, ECHOPRT); 373cae66988SJoerg Wunsch else 374cae66988SJoerg Wunsch CLR(lflag, ECHOPRT); 375cae66988SJoerg Wunsch 376cae66988SJoerg Wunsch if (EC) 377cae66988SJoerg Wunsch SET(lflag, ECHO); 378cae66988SJoerg Wunsch else 379cae66988SJoerg Wunsch CLR(lflag, ECHO); 380cae66988SJoerg Wunsch 381cae66988SJoerg Wunsch if (XC) 382cae66988SJoerg Wunsch SET(lflag, ECHOCTL); 383cae66988SJoerg Wunsch else 384cae66988SJoerg Wunsch CLR(lflag, ECHOCTL); 385cae66988SJoerg Wunsch 386cae66988SJoerg Wunsch if (DX) 387cae66988SJoerg Wunsch SET(lflag, IXANY); 388cae66988SJoerg Wunsch else 389cae66988SJoerg Wunsch CLR(lflag, IXANY); 390cae66988SJoerg Wunsch 391cae66988SJoerg Wunsch out: 392cae66988SJoerg Wunsch tmode.c_iflag = iflag; 393cae66988SJoerg Wunsch tmode.c_oflag = oflag; 394cae66988SJoerg Wunsch tmode.c_cflag = cflag; 395cae66988SJoerg Wunsch tmode.c_lflag = lflag; 396cae66988SJoerg Wunsch } 397cae66988SJoerg Wunsch 398cae66988SJoerg Wunsch 399cae66988SJoerg Wunsch #ifdef XXX_DELAY 400ea022d16SRodney W. Grimes struct delayval { 401ea022d16SRodney W. Grimes unsigned delay; /* delay in ms */ 402ea022d16SRodney W. Grimes int bits; 403ea022d16SRodney W. Grimes }; 404ea022d16SRodney W. Grimes 405ea022d16SRodney W. Grimes /* 406ea022d16SRodney W. Grimes * below are random guesses, I can't be bothered checking 407ea022d16SRodney W. Grimes */ 408ea022d16SRodney W. Grimes 409ea022d16SRodney W. Grimes struct delayval crdelay[] = { 410cae66988SJoerg Wunsch { 1, CR1 }, 411cae66988SJoerg Wunsch { 2, CR2 }, 412cae66988SJoerg Wunsch { 3, CR3 }, 413cae66988SJoerg Wunsch { 83, CR1 }, 414cae66988SJoerg Wunsch { 166, CR2 }, 415cae66988SJoerg Wunsch { 0, CR3 }, 416ea022d16SRodney W. Grimes }; 417ea022d16SRodney W. Grimes 418ea022d16SRodney W. Grimes struct delayval nldelay[] = { 419cae66988SJoerg Wunsch { 1, NL1 }, /* special, calculated */ 420cae66988SJoerg Wunsch { 2, NL2 }, 421cae66988SJoerg Wunsch { 3, NL3 }, 422cae66988SJoerg Wunsch { 100, NL2 }, 423cae66988SJoerg Wunsch { 0, NL3 }, 424ea022d16SRodney W. Grimes }; 425ea022d16SRodney W. Grimes 426ea022d16SRodney W. Grimes struct delayval bsdelay[] = { 427cae66988SJoerg Wunsch { 1, BS1 }, 428cae66988SJoerg Wunsch { 0, 0 }, 429ea022d16SRodney W. Grimes }; 430ea022d16SRodney W. Grimes 431ea022d16SRodney W. Grimes struct delayval ffdelay[] = { 432cae66988SJoerg Wunsch { 1, FF1 }, 433cae66988SJoerg Wunsch { 1750, FF1 }, 434cae66988SJoerg Wunsch { 0, FF1 }, 435ea022d16SRodney W. Grimes }; 436ea022d16SRodney W. Grimes 437ea022d16SRodney W. Grimes struct delayval tbdelay[] = { 438cae66988SJoerg Wunsch { 1, TAB1 }, 439cae66988SJoerg Wunsch { 2, TAB2 }, 440cae66988SJoerg Wunsch { 3, XTABS }, /* this is expand tabs */ 441cae66988SJoerg Wunsch { 100, TAB1 }, 442cae66988SJoerg Wunsch { 0, TAB2 }, 443ea022d16SRodney W. Grimes }; 444ea022d16SRodney W. Grimes 445cae66988SJoerg Wunsch int 44695289b27SWarner Losh delaybits(void) 447ea022d16SRodney W. Grimes { 44895289b27SWarner Losh int f; 449ea022d16SRodney W. Grimes 450ea022d16SRodney W. Grimes f = adelay(CD, crdelay); 451ea022d16SRodney W. Grimes f |= adelay(ND, nldelay); 452ea022d16SRodney W. Grimes f |= adelay(FD, ffdelay); 453ea022d16SRodney W. Grimes f |= adelay(TD, tbdelay); 454ea022d16SRodney W. Grimes f |= adelay(BD, bsdelay); 455ea022d16SRodney W. Grimes return (f); 456ea022d16SRodney W. Grimes } 457ea022d16SRodney W. Grimes 458cae66988SJoerg Wunsch int 45995289b27SWarner Losh adelay(int ms, struct delayval *dp) 460ea022d16SRodney W. Grimes { 461ea022d16SRodney W. Grimes if (ms == 0) 462ea022d16SRodney W. Grimes return (0); 463ea022d16SRodney W. Grimes while (dp->delay && ms > dp->delay) 464ea022d16SRodney W. Grimes dp++; 465ea022d16SRodney W. Grimes return (dp->bits); 466ea022d16SRodney W. Grimes } 467cae66988SJoerg Wunsch #endif 468ea022d16SRodney W. Grimes 469c568fce9SAndrey A. Chernov char editedhost[MAXHOSTNAMELEN]; 470ea022d16SRodney W. Grimes 471cae66988SJoerg Wunsch void 47295289b27SWarner Losh edithost(const char *pat) 473ea022d16SRodney W. Grimes { 47495289b27SWarner Losh const char *host = HN; 47595289b27SWarner Losh char *res = editedhost; 476ea022d16SRodney W. Grimes 477ea022d16SRodney W. Grimes if (!pat) 478ea022d16SRodney W. Grimes pat = ""; 479ea022d16SRodney W. Grimes while (*pat) { 480ea022d16SRodney W. Grimes switch (*pat) { 481ea022d16SRodney W. Grimes 482ea022d16SRodney W. Grimes case '#': 483ea022d16SRodney W. Grimes if (*host) 484ea022d16SRodney W. Grimes host++; 485ea022d16SRodney W. Grimes break; 486ea022d16SRodney W. Grimes 487ea022d16SRodney W. Grimes case '@': 488ea022d16SRodney W. Grimes if (*host) 489ea022d16SRodney W. Grimes *res++ = *host++; 490ea022d16SRodney W. Grimes break; 491ea022d16SRodney W. Grimes 492ea022d16SRodney W. Grimes default: 493ea022d16SRodney W. Grimes *res++ = *pat; 494ea022d16SRodney W. Grimes break; 495ea022d16SRodney W. Grimes 496ea022d16SRodney W. Grimes } 497ea022d16SRodney W. Grimes if (res == &editedhost[sizeof editedhost - 1]) { 498ea022d16SRodney W. Grimes *res = '\0'; 499ea022d16SRodney W. Grimes return; 500ea022d16SRodney W. Grimes } 501ea022d16SRodney W. Grimes pat++; 502ea022d16SRodney W. Grimes } 503ea022d16SRodney W. Grimes if (*host) 504ea022d16SRodney W. Grimes strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); 505ea022d16SRodney W. Grimes else 506ea022d16SRodney W. Grimes *res = '\0'; 507ea022d16SRodney W. Grimes editedhost[sizeof editedhost - 1] = '\0'; 508ea022d16SRodney W. Grimes } 509ea022d16SRodney W. Grimes 510cae66988SJoerg Wunsch static struct speedtab { 511ea022d16SRodney W. Grimes int speed; 512ea022d16SRodney W. Grimes int uxname; 513ea022d16SRodney W. Grimes } speedtab[] = { 514cae66988SJoerg Wunsch { 50, B50 }, 515cae66988SJoerg Wunsch { 75, B75 }, 516cae66988SJoerg Wunsch { 110, B110 }, 517cae66988SJoerg Wunsch { 134, B134 }, 518cae66988SJoerg Wunsch { 150, B150 }, 519cae66988SJoerg Wunsch { 200, B200 }, 520cae66988SJoerg Wunsch { 300, B300 }, 521cae66988SJoerg Wunsch { 600, B600 }, 522cae66988SJoerg Wunsch { 1200, B1200 }, 523cae66988SJoerg Wunsch { 1800, B1800 }, 524cae66988SJoerg Wunsch { 2400, B2400 }, 525cae66988SJoerg Wunsch { 4800, B4800 }, 526cae66988SJoerg Wunsch { 9600, B9600 }, 527cae66988SJoerg Wunsch { 19200, EXTA }, 528cae66988SJoerg Wunsch { 19, EXTA }, /* for people who say 19.2K */ 529cae66988SJoerg Wunsch { 38400, EXTB }, 530cae66988SJoerg Wunsch { 38, EXTB }, 531cae66988SJoerg Wunsch { 7200, EXTB }, /* alternative */ 532cae66988SJoerg Wunsch { 57600, B57600 }, 533cae66988SJoerg Wunsch { 115200, B115200 }, 534ee98a93fSPoul-Henning Kamp { 230400, B230400 }, 535cae66988SJoerg Wunsch { 0 } 536ea022d16SRodney W. Grimes }; 537ea022d16SRodney W. Grimes 538cae66988SJoerg Wunsch int 53995289b27SWarner Losh speed(int val) 540ea022d16SRodney W. Grimes { 54195289b27SWarner Losh struct speedtab *sp; 542ea022d16SRodney W. Grimes 543ee98a93fSPoul-Henning Kamp if (val <= B230400) 544ea022d16SRodney W. Grimes return (val); 545ea022d16SRodney W. Grimes 546ea022d16SRodney W. Grimes for (sp = speedtab; sp->speed; sp++) 547ea022d16SRodney W. Grimes if (sp->speed == val) 548ea022d16SRodney W. Grimes return (sp->uxname); 549ea022d16SRodney W. Grimes 550ea022d16SRodney W. Grimes return (B300); /* default in impossible cases */ 551ea022d16SRodney W. Grimes } 552ea022d16SRodney W. Grimes 553cae66988SJoerg Wunsch void 55495289b27SWarner Losh makeenv(char *env[]) 555ea022d16SRodney W. Grimes { 556ea022d16SRodney W. Grimes static char termbuf[128] = "TERM="; 55795289b27SWarner Losh char *p, *q; 55895289b27SWarner Losh char **ep; 559ea022d16SRodney W. Grimes 560ea022d16SRodney W. Grimes ep = env; 561ea022d16SRodney W. Grimes if (TT && *TT) { 5626e76e16fSKris Kennaway strlcat(termbuf, TT, sizeof(termbuf)); 563ea022d16SRodney W. Grimes *ep++ = termbuf; 564ea022d16SRodney W. Grimes } 565cae66988SJoerg Wunsch if ((p = EV)) { 566ea022d16SRodney W. Grimes q = p; 567cae66988SJoerg Wunsch while ((q = strchr(q, ','))) { 568ea022d16SRodney W. Grimes *q++ = '\0'; 569ea022d16SRodney W. Grimes *ep++ = p; 570ea022d16SRodney W. Grimes p = q; 571ea022d16SRodney W. Grimes } 572ea022d16SRodney W. Grimes if (*p) 573ea022d16SRodney W. Grimes *ep++ = p; 574ea022d16SRodney W. Grimes } 575ea022d16SRodney W. Grimes *ep = (char *)0; 576ea022d16SRodney W. Grimes } 577ea022d16SRodney W. Grimes 578ea022d16SRodney W. Grimes /* 579ea022d16SRodney W. Grimes * This speed select mechanism is written for the Develcon DATASWITCH. 580ea022d16SRodney W. Grimes * The Develcon sends a string of the form "B{speed}\n" at a predefined 581ea022d16SRodney W. Grimes * baud rate. This string indicates the user's actual speed. 582ea022d16SRodney W. Grimes * The routine below returns the terminal type mapped from derived speed. 583ea022d16SRodney W. Grimes */ 584ea022d16SRodney W. Grimes struct portselect { 585cae66988SJoerg Wunsch const char *ps_baud; 586cae66988SJoerg Wunsch const char *ps_type; 587ea022d16SRodney W. Grimes } portspeeds[] = { 588ea022d16SRodney W. Grimes { "B110", "std.110" }, 589ea022d16SRodney W. Grimes { "B134", "std.134" }, 590ea022d16SRodney W. Grimes { "B150", "std.150" }, 591ea022d16SRodney W. Grimes { "B300", "std.300" }, 592ea022d16SRodney W. Grimes { "B600", "std.600" }, 593ea022d16SRodney W. Grimes { "B1200", "std.1200" }, 594ea022d16SRodney W. Grimes { "B2400", "std.2400" }, 595ea022d16SRodney W. Grimes { "B4800", "std.4800" }, 596ea022d16SRodney W. Grimes { "B9600", "std.9600" }, 597ea022d16SRodney W. Grimes { "B19200", "std.19200" }, 598ea022d16SRodney W. Grimes { 0 } 599ea022d16SRodney W. Grimes }; 600ea022d16SRodney W. Grimes 601cae66988SJoerg Wunsch const char * 60295289b27SWarner Losh portselector(void) 603ea022d16SRodney W. Grimes { 604cae66988SJoerg Wunsch char c, baud[20]; 605cae66988SJoerg Wunsch const char *type = "default"; 60695289b27SWarner Losh struct portselect *ps; 607ea022d16SRodney W. Grimes int len; 608ea022d16SRodney W. Grimes 609ea022d16SRodney W. Grimes alarm(5*60); 610ea022d16SRodney W. Grimes for (len = 0; len < sizeof (baud) - 1; len++) { 611ea022d16SRodney W. Grimes if (read(STDIN_FILENO, &c, 1) <= 0) 612ea022d16SRodney W. Grimes break; 613ea022d16SRodney W. Grimes c &= 0177; 614ea022d16SRodney W. Grimes if (c == '\n' || c == '\r') 615ea022d16SRodney W. Grimes break; 616ea022d16SRodney W. Grimes if (c == 'B') 617ea022d16SRodney W. Grimes len = 0; /* in case of leading garbage */ 618ea022d16SRodney W. Grimes baud[len] = c; 619ea022d16SRodney W. Grimes } 620ea022d16SRodney W. Grimes baud[len] = '\0'; 621ea022d16SRodney W. Grimes for (ps = portspeeds; ps->ps_baud; ps++) 622ea022d16SRodney W. Grimes if (strcmp(ps->ps_baud, baud) == 0) { 623ea022d16SRodney W. Grimes type = ps->ps_type; 624ea022d16SRodney W. Grimes break; 625ea022d16SRodney W. Grimes } 626ea022d16SRodney W. Grimes sleep(2); /* wait for connection to complete */ 627ea022d16SRodney W. Grimes return (type); 628ea022d16SRodney W. Grimes } 629ea022d16SRodney W. Grimes 630ea022d16SRodney W. Grimes /* 631ea022d16SRodney W. Grimes * This auto-baud speed select mechanism is written for the Micom 600 632ea022d16SRodney W. Grimes * portselector. Selection is done by looking at how the character '\r' 633ea022d16SRodney W. Grimes * is garbled at the different speeds. 634ea022d16SRodney W. Grimes */ 635cae66988SJoerg Wunsch const char * 63695289b27SWarner Losh autobaud(void) 637ea022d16SRodney W. Grimes { 638*a3e4b982SPedro F. Giffuni struct pollfd set[1]; 639*a3e4b982SPedro F. Giffuni struct timespec timeout; 640cae66988SJoerg Wunsch char c; 641cae66988SJoerg Wunsch const char *type = "9600-baud"; 642ea022d16SRodney W. Grimes 643cae66988SJoerg Wunsch (void)tcflush(0, TCIOFLUSH); 644*a3e4b982SPedro F. Giffuni set[0].fd = STDIN_FILENO; 645*a3e4b982SPedro F. Giffuni set[0].events = POLLIN; 646*a3e4b982SPedro F. Giffuni if (poll(set, 1, 5000) <= 0) 647ea022d16SRodney W. Grimes return (type); 648ea022d16SRodney W. Grimes if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char)) 649ea022d16SRodney W. Grimes return (type); 650ea022d16SRodney W. Grimes timeout.tv_sec = 0; 651*a3e4b982SPedro F. Giffuni timeout.tv_nsec = 20000; 652*a3e4b982SPedro F. Giffuni (void)nanosleep(&timeout, NULL); 653cae66988SJoerg Wunsch (void)tcflush(0, TCIOFLUSH); 654ea022d16SRodney W. Grimes switch (c & 0377) { 655ea022d16SRodney W. Grimes 656ea022d16SRodney W. Grimes case 0200: /* 300-baud */ 657ea022d16SRodney W. Grimes type = "300-baud"; 658ea022d16SRodney W. Grimes break; 659ea022d16SRodney W. Grimes 660ea022d16SRodney W. Grimes case 0346: /* 1200-baud */ 661ea022d16SRodney W. Grimes type = "1200-baud"; 662ea022d16SRodney W. Grimes break; 663ea022d16SRodney W. Grimes 664ea022d16SRodney W. Grimes case 015: /* 2400-baud */ 665ea022d16SRodney W. Grimes case 0215: 666ea022d16SRodney W. Grimes type = "2400-baud"; 667ea022d16SRodney W. Grimes break; 668ea022d16SRodney W. Grimes 669ea022d16SRodney W. Grimes default: /* 4800-baud */ 670ea022d16SRodney W. Grimes type = "4800-baud"; 671ea022d16SRodney W. Grimes break; 672ea022d16SRodney W. Grimes 673ea022d16SRodney W. Grimes case 0377: /* 9600-baud */ 674ea022d16SRodney W. Grimes type = "9600-baud"; 675ea022d16SRodney W. Grimes break; 676ea022d16SRodney W. Grimes } 677ea022d16SRodney W. Grimes return (type); 678ea022d16SRodney W. Grimes } 679