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