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; 71*18587b84SEdward Tomasz Napierala static char path_gettytab[PATH_MAX]; 72*18587b84SEdward Tomasz Napierala char *dba[2]; 7304a59e67SDavid Nugent 7404a59e67SDavid Nugent static int firsttime = 1; 7504a59e67SDavid Nugent 76*18587b84SEdward Tomasz Napierala strlcpy(path_gettytab, _PATH_GETTYTAB, sizeof(path_gettytab)); 77*18587b84SEdward Tomasz Napierala dba[0] = path_gettytab; 7873906f57SPedro F. Giffuni dba[1] = NULL; 79ea022d16SRodney W. Grimes 8004a59e67SDavid Nugent if (firsttime) { 8104a59e67SDavid Nugent /* 8204a59e67SDavid Nugent * we need to strdup() anything in the strings array 8304a59e67SDavid Nugent * initially in order to simplify things later 8404a59e67SDavid Nugent */ 85ea022d16SRodney W. Grimes for (sp = gettystrs; sp->field; sp++) 8604a59e67SDavid Nugent if (sp->value != NULL) { 8704a59e67SDavid Nugent /* handle these ones more carefully */ 8804a59e67SDavid Nugent if (sp >= &gettystrs[4] && sp <= &gettystrs[6]) 8904a59e67SDavid Nugent l = 2; 9004a59e67SDavid Nugent else 9104a59e67SDavid Nugent l = strlen(sp->value) + 1; 9204a59e67SDavid Nugent if ((p = malloc(l)) != NULL) { 9304a59e67SDavid Nugent strncpy(p, sp->value, l); 9404a59e67SDavid Nugent p[l-1] = '\0'; 9504a59e67SDavid Nugent } 9604a59e67SDavid Nugent /* 9704a59e67SDavid Nugent * replace, even if NULL, else we'll 9804a59e67SDavid Nugent * have problems with free()ing static mem 9904a59e67SDavid Nugent */ 10004a59e67SDavid Nugent sp->value = p; 10104a59e67SDavid Nugent } 10204a59e67SDavid Nugent firsttime = 0; 10304a59e67SDavid Nugent } 10404a59e67SDavid Nugent 105*18587b84SEdward Tomasz Napierala switch (cgetent(&buf, dba, name)) { 10604a59e67SDavid Nugent case 1: 107*18587b84SEdward Tomasz Napierala syslog(LOG_ERR, "getty: couldn't resolve 'tc=' in gettytab '%s'", name); 108*18587b84SEdward Tomasz Napierala return; 10904a59e67SDavid Nugent case 0: 11004a59e67SDavid Nugent break; 11104a59e67SDavid Nugent case -1: 112*18587b84SEdward Tomasz Napierala syslog(LOG_ERR, "getty: unknown gettytab entry '%s'", name); 113*18587b84SEdward Tomasz Napierala return; 11404a59e67SDavid Nugent case -2: 115*18587b84SEdward Tomasz Napierala syslog(LOG_ERR, "getty: retrieving gettytab entry '%s': %m", name); 116*18587b84SEdward Tomasz Napierala return; 11704a59e67SDavid Nugent case -3: 118*18587b84SEdward Tomasz Napierala syslog(LOG_ERR, "getty: recursive 'tc=' reference gettytab entry '%s'", name); 119*18587b84SEdward Tomasz Napierala return; 12004a59e67SDavid Nugent default: 121*18587b84SEdward Tomasz Napierala syslog(LOG_ERR, "getty: unexpected cgetent() error for entry '%s'", name); 12204a59e67SDavid Nugent return; 12304a59e67SDavid Nugent } 12404a59e67SDavid Nugent 12504a59e67SDavid Nugent for (sp = gettystrs; sp->field; sp++) { 126076ec402SEdward Tomasz Napierala if ((l = cgetstr(buf, sp->field, &p)) >= 0) { 12704a59e67SDavid Nugent if (sp->value) { 12804a59e67SDavid Nugent /* prefer existing value */ 12904a59e67SDavid Nugent if (strcmp(p, sp->value) != 0) 13004a59e67SDavid Nugent free(sp->value); 13104a59e67SDavid Nugent else { 13204a59e67SDavid Nugent free(p); 13304a59e67SDavid Nugent p = sp->value; 13404a59e67SDavid Nugent } 13504a59e67SDavid Nugent } 13604a59e67SDavid Nugent sp->value = p; 13704a59e67SDavid Nugent } else if (l == -1) { 13804a59e67SDavid Nugent free(sp->value); 13904a59e67SDavid Nugent sp->value = NULL; 14004a59e67SDavid Nugent } 14104a59e67SDavid Nugent } 14204a59e67SDavid Nugent 143ea022d16SRodney W. Grimes for (np = gettynums; np->field; np++) { 144076ec402SEdward Tomasz Napierala if (cgetnum(buf, np->field, &n) == -1) 145ea022d16SRodney W. Grimes np->set = 0; 146ea022d16SRodney W. Grimes else { 147ea022d16SRodney W. Grimes np->set = 1; 148ea022d16SRodney W. Grimes np->value = n; 149ea022d16SRodney W. Grimes } 150ea022d16SRodney W. Grimes } 15104a59e67SDavid Nugent 152ea022d16SRodney W. Grimes for (fp = gettyflags; fp->field; fp++) { 153076ec402SEdward Tomasz Napierala if (cgetcap(buf, fp->field, ':') == NULL) 154ea022d16SRodney W. Grimes fp->set = 0; 155ea022d16SRodney W. Grimes else { 156ea022d16SRodney W. Grimes fp->set = 1; 157cae66988SJoerg Wunsch fp->value = 1 ^ fp->invrt; 158ea022d16SRodney W. Grimes } 159ea022d16SRodney W. Grimes } 160ea022d16SRodney W. Grimes } 161ea022d16SRodney W. Grimes 162cae66988SJoerg Wunsch void 16395289b27SWarner Losh gendefaults(void) 164ea022d16SRodney W. Grimes { 16595289b27SWarner Losh struct gettystrs *sp; 16695289b27SWarner Losh struct gettynums *np; 16795289b27SWarner Losh struct gettyflags *fp; 168ea022d16SRodney W. Grimes 169ea022d16SRodney W. Grimes for (sp = gettystrs; sp->field; sp++) 170ea022d16SRodney W. Grimes if (sp->value) 17104a59e67SDavid Nugent sp->defalt = strdup(sp->value); 172ea022d16SRodney W. Grimes for (np = gettynums; np->field; np++) 173ea022d16SRodney W. Grimes if (np->set) 174ea022d16SRodney W. Grimes np->defalt = np->value; 175ea022d16SRodney W. Grimes for (fp = gettyflags; fp->field; fp++) 176ea022d16SRodney W. Grimes if (fp->set) 177ea022d16SRodney W. Grimes fp->defalt = fp->value; 178ea022d16SRodney W. Grimes else 179ea022d16SRodney W. Grimes fp->defalt = fp->invrt; 180ea022d16SRodney W. Grimes } 181ea022d16SRodney W. Grimes 182cae66988SJoerg Wunsch void 18395289b27SWarner Losh setdefaults(void) 184ea022d16SRodney W. Grimes { 18595289b27SWarner Losh struct gettystrs *sp; 18695289b27SWarner Losh struct gettynums *np; 18795289b27SWarner Losh struct gettyflags *fp; 188ea022d16SRodney W. Grimes 189ea022d16SRodney W. Grimes for (sp = gettystrs; sp->field; sp++) 190ea022d16SRodney W. Grimes if (!sp->value) 19104a59e67SDavid Nugent sp->value = !sp->defalt ? sp->defalt 19204a59e67SDavid Nugent : strdup(sp->defalt); 193ea022d16SRodney W. Grimes for (np = gettynums; np->field; np++) 194ea022d16SRodney W. Grimes if (!np->set) 195ea022d16SRodney W. Grimes np->value = np->defalt; 196ea022d16SRodney W. Grimes for (fp = gettyflags; fp->field; fp++) 197ea022d16SRodney W. Grimes if (!fp->set) 198ea022d16SRodney W. Grimes fp->value = fp->defalt; 199ea022d16SRodney W. Grimes } 200ea022d16SRodney W. Grimes 201ea022d16SRodney W. Grimes static char ** 202ea022d16SRodney W. Grimes charnames[] = { 203ea022d16SRodney W. Grimes &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK, 204ea022d16SRodney W. Grimes &SU, &DS, &RP, &FL, &WE, &LN, 0 205ea022d16SRodney W. Grimes }; 206ea022d16SRodney W. Grimes 207ea022d16SRodney W. Grimes static char * 208ea022d16SRodney W. Grimes charvars[] = { 209cae66988SJoerg Wunsch &tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR], 210cae66988SJoerg Wunsch &tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP], 211cae66988SJoerg Wunsch &tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP], 212cae66988SJoerg Wunsch &tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD], 213bc13b10eSPedro F. Giffuni &tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], 0 214ea022d16SRodney W. Grimes }; 215ea022d16SRodney W. Grimes 216cae66988SJoerg Wunsch void 21795289b27SWarner Losh setchars(void) 218ea022d16SRodney W. Grimes { 21995289b27SWarner Losh int i; 22095289b27SWarner Losh const char *p; 221ea022d16SRodney W. Grimes 222ea022d16SRodney W. Grimes for (i = 0; charnames[i]; i++) { 223ea022d16SRodney W. Grimes p = *charnames[i]; 224ea022d16SRodney W. Grimes if (p && *p) 225ea022d16SRodney W. Grimes *charvars[i] = *p; 226ea022d16SRodney W. Grimes else 227cae66988SJoerg Wunsch *charvars[i] = _POSIX_VDISABLE; 228ea022d16SRodney W. Grimes } 229ea022d16SRodney W. Grimes } 230ea022d16SRodney W. Grimes 231cae66988SJoerg Wunsch /* Macros to clear/set/test flags. */ 232cae66988SJoerg Wunsch #define SET(t, f) (t) |= (f) 233cae66988SJoerg Wunsch #define CLR(t, f) (t) &= ~(f) 234cae66988SJoerg Wunsch #define ISSET(t, f) ((t) & (f)) 235cae66988SJoerg Wunsch 236cae66988SJoerg Wunsch void 23795289b27SWarner Losh set_flags(int n) 238ea022d16SRodney W. Grimes { 23995289b27SWarner Losh tcflag_t iflag, oflag, cflag, lflag; 240cae66988SJoerg Wunsch 241ea022d16SRodney W. Grimes 242ea022d16SRodney W. Grimes switch (n) { 243ea022d16SRodney W. Grimes case 0: 244cae66988SJoerg Wunsch if (C0set && I0set && L0set && O0set) { 245cae66988SJoerg Wunsch tmode.c_cflag = C0; 246cae66988SJoerg Wunsch tmode.c_iflag = I0; 247cae66988SJoerg Wunsch tmode.c_lflag = L0; 248cae66988SJoerg Wunsch tmode.c_oflag = O0; 249cae66988SJoerg Wunsch return; 250cae66988SJoerg Wunsch } 251ea022d16SRodney W. Grimes break; 252ea022d16SRodney W. Grimes case 1: 253cae66988SJoerg Wunsch if (C1set && I1set && L1set && O1set) { 254cae66988SJoerg Wunsch tmode.c_cflag = C1; 255cae66988SJoerg Wunsch tmode.c_iflag = I1; 256cae66988SJoerg Wunsch tmode.c_lflag = L1; 257cae66988SJoerg Wunsch tmode.c_oflag = O1; 258cae66988SJoerg Wunsch return; 259cae66988SJoerg Wunsch } 260ea022d16SRodney W. Grimes break; 261ea022d16SRodney W. Grimes default: 262cae66988SJoerg Wunsch if (C2set && I2set && L2set && O2set) { 263cae66988SJoerg Wunsch tmode.c_cflag = C2; 264cae66988SJoerg Wunsch tmode.c_iflag = I2; 265cae66988SJoerg Wunsch tmode.c_lflag = L2; 266cae66988SJoerg Wunsch tmode.c_oflag = O2; 267cae66988SJoerg Wunsch return; 268cae66988SJoerg Wunsch } 269ea022d16SRodney W. Grimes break; 270ea022d16SRodney W. Grimes } 271ea022d16SRodney W. Grimes 272cae66988SJoerg Wunsch iflag = omode.c_iflag; 273cae66988SJoerg Wunsch oflag = omode.c_oflag; 274cae66988SJoerg Wunsch cflag = omode.c_cflag; 275cae66988SJoerg Wunsch lflag = omode.c_lflag; 276ea022d16SRodney W. Grimes 277cae66988SJoerg Wunsch if (NP) { 278cae66988SJoerg Wunsch CLR(cflag, CSIZE|PARENB); 279cae66988SJoerg Wunsch SET(cflag, CS8); 280cae66988SJoerg Wunsch CLR(iflag, ISTRIP|INPCK|IGNPAR); 281cae66988SJoerg Wunsch } else if (AP || EP || OP) { 282cae66988SJoerg Wunsch CLR(cflag, CSIZE); 283cae66988SJoerg Wunsch SET(cflag, CS7|PARENB); 284cae66988SJoerg Wunsch SET(iflag, ISTRIP); 285cae66988SJoerg Wunsch if (OP && !EP) { 286cae66988SJoerg Wunsch SET(iflag, INPCK|IGNPAR); 287cae66988SJoerg Wunsch SET(cflag, PARODD); 288ea022d16SRodney W. Grimes if (AP) 289cae66988SJoerg Wunsch CLR(iflag, INPCK); 290cae66988SJoerg Wunsch } else if (EP && !OP) { 291cae66988SJoerg Wunsch SET(iflag, INPCK|IGNPAR); 292cae66988SJoerg Wunsch CLR(cflag, PARODD); 293cae66988SJoerg Wunsch if (AP) 294cae66988SJoerg Wunsch CLR(iflag, INPCK); 295cae66988SJoerg Wunsch } else if (AP || (EP && OP)) { 296cae66988SJoerg Wunsch CLR(iflag, INPCK|IGNPAR); 297cae66988SJoerg Wunsch CLR(cflag, PARODD); 298cae66988SJoerg Wunsch } 299cae66988SJoerg Wunsch } /* else, leave as is */ 300ea022d16SRodney W. Grimes 301cae66988SJoerg Wunsch #if 0 302ea022d16SRodney W. Grimes if (UC) 303ea022d16SRodney W. Grimes f |= LCASE; 304cae66988SJoerg Wunsch #endif 305ea022d16SRodney W. Grimes 306cae66988SJoerg Wunsch if (HC) 307cae66988SJoerg Wunsch SET(cflag, HUPCL); 308ea022d16SRodney W. Grimes else 309cae66988SJoerg Wunsch CLR(cflag, HUPCL); 310cae66988SJoerg Wunsch 311cae66988SJoerg Wunsch if (MB) 312cae66988SJoerg Wunsch SET(cflag, MDMBUF); 313cae66988SJoerg Wunsch else 314cae66988SJoerg Wunsch CLR(cflag, MDMBUF); 315cae66988SJoerg Wunsch 316fe552114SDavid Nugent if (HW) 317fe552114SDavid Nugent SET(cflag, CRTSCTS); 318fe552114SDavid Nugent else 319fe552114SDavid Nugent CLR(cflag, CRTSCTS); 320fe552114SDavid Nugent 321cae66988SJoerg Wunsch if (NL) { 322cae66988SJoerg Wunsch SET(iflag, ICRNL); 323cae66988SJoerg Wunsch SET(oflag, ONLCR|OPOST); 324cae66988SJoerg Wunsch } else { 325cae66988SJoerg Wunsch CLR(iflag, ICRNL); 326cae66988SJoerg Wunsch CLR(oflag, ONLCR); 327ea022d16SRodney W. Grimes } 328ea022d16SRodney W. Grimes 329ea022d16SRodney W. Grimes if (!HT) 330cae66988SJoerg Wunsch SET(oflag, OXTABS|OPOST); 331cae66988SJoerg Wunsch else 332cae66988SJoerg Wunsch CLR(oflag, OXTABS); 333ea022d16SRodney W. Grimes 334cae66988SJoerg Wunsch #ifdef XXX_DELAY 335cae66988SJoerg Wunsch SET(f, delaybits()); 336cae66988SJoerg Wunsch #endif 337ea022d16SRodney W. Grimes 338cae66988SJoerg Wunsch if (n == 1) { /* read mode flags */ 339cae66988SJoerg Wunsch if (RW) { 340cae66988SJoerg Wunsch iflag = 0; 341cae66988SJoerg Wunsch CLR(oflag, OPOST); 342cae66988SJoerg Wunsch CLR(cflag, CSIZE|PARENB); 343cae66988SJoerg Wunsch SET(cflag, CS8); 344cae66988SJoerg Wunsch lflag = 0; 345cae66988SJoerg Wunsch } else { 346cae66988SJoerg Wunsch CLR(lflag, ICANON); 347cae66988SJoerg Wunsch } 348cae66988SJoerg Wunsch goto out; 349ea022d16SRodney W. Grimes } 350ea022d16SRodney W. Grimes 351cae66988SJoerg Wunsch if (n == 0) 352cae66988SJoerg Wunsch goto out; 353cae66988SJoerg Wunsch 354cae66988SJoerg Wunsch #if 0 355cae66988SJoerg Wunsch if (CB) 356cae66988SJoerg Wunsch SET(f, CRTBS); 357cae66988SJoerg Wunsch #endif 358cae66988SJoerg Wunsch 359cae66988SJoerg Wunsch if (CE) 360cae66988SJoerg Wunsch SET(lflag, ECHOE); 361cae66988SJoerg Wunsch else 362cae66988SJoerg Wunsch CLR(lflag, ECHOE); 363cae66988SJoerg Wunsch 364cae66988SJoerg Wunsch if (CK) 365cae66988SJoerg Wunsch SET(lflag, ECHOKE); 366cae66988SJoerg Wunsch else 367cae66988SJoerg Wunsch CLR(lflag, ECHOKE); 368cae66988SJoerg Wunsch 369cae66988SJoerg Wunsch if (PE) 370cae66988SJoerg Wunsch SET(lflag, ECHOPRT); 371cae66988SJoerg Wunsch else 372cae66988SJoerg Wunsch CLR(lflag, ECHOPRT); 373cae66988SJoerg Wunsch 374cae66988SJoerg Wunsch if (EC) 375cae66988SJoerg Wunsch SET(lflag, ECHO); 376cae66988SJoerg Wunsch else 377cae66988SJoerg Wunsch CLR(lflag, ECHO); 378cae66988SJoerg Wunsch 379cae66988SJoerg Wunsch if (XC) 380cae66988SJoerg Wunsch SET(lflag, ECHOCTL); 381cae66988SJoerg Wunsch else 382cae66988SJoerg Wunsch CLR(lflag, ECHOCTL); 383cae66988SJoerg Wunsch 384cae66988SJoerg Wunsch if (DX) 385cae66988SJoerg Wunsch SET(lflag, IXANY); 386cae66988SJoerg Wunsch else 387cae66988SJoerg Wunsch CLR(lflag, IXANY); 388cae66988SJoerg Wunsch 389cae66988SJoerg Wunsch out: 390cae66988SJoerg Wunsch tmode.c_iflag = iflag; 391cae66988SJoerg Wunsch tmode.c_oflag = oflag; 392cae66988SJoerg Wunsch tmode.c_cflag = cflag; 393cae66988SJoerg Wunsch tmode.c_lflag = lflag; 394cae66988SJoerg Wunsch } 395cae66988SJoerg Wunsch 396cae66988SJoerg Wunsch 397cae66988SJoerg Wunsch #ifdef XXX_DELAY 398ea022d16SRodney W. Grimes struct delayval { 399ea022d16SRodney W. Grimes unsigned delay; /* delay in ms */ 400ea022d16SRodney W. Grimes int bits; 401ea022d16SRodney W. Grimes }; 402ea022d16SRodney W. Grimes 403ea022d16SRodney W. Grimes /* 404ea022d16SRodney W. Grimes * below are random guesses, I can't be bothered checking 405ea022d16SRodney W. Grimes */ 406ea022d16SRodney W. Grimes 407ea022d16SRodney W. Grimes struct delayval crdelay[] = { 408cae66988SJoerg Wunsch { 1, CR1 }, 409cae66988SJoerg Wunsch { 2, CR2 }, 410cae66988SJoerg Wunsch { 3, CR3 }, 411cae66988SJoerg Wunsch { 83, CR1 }, 412cae66988SJoerg Wunsch { 166, CR2 }, 413cae66988SJoerg Wunsch { 0, CR3 }, 414ea022d16SRodney W. Grimes }; 415ea022d16SRodney W. Grimes 416ea022d16SRodney W. Grimes struct delayval nldelay[] = { 417cae66988SJoerg Wunsch { 1, NL1 }, /* special, calculated */ 418cae66988SJoerg Wunsch { 2, NL2 }, 419cae66988SJoerg Wunsch { 3, NL3 }, 420cae66988SJoerg Wunsch { 100, NL2 }, 421cae66988SJoerg Wunsch { 0, NL3 }, 422ea022d16SRodney W. Grimes }; 423ea022d16SRodney W. Grimes 424ea022d16SRodney W. Grimes struct delayval bsdelay[] = { 425cae66988SJoerg Wunsch { 1, BS1 }, 426cae66988SJoerg Wunsch { 0, 0 }, 427ea022d16SRodney W. Grimes }; 428ea022d16SRodney W. Grimes 429ea022d16SRodney W. Grimes struct delayval ffdelay[] = { 430cae66988SJoerg Wunsch { 1, FF1 }, 431cae66988SJoerg Wunsch { 1750, FF1 }, 432cae66988SJoerg Wunsch { 0, FF1 }, 433ea022d16SRodney W. Grimes }; 434ea022d16SRodney W. Grimes 435ea022d16SRodney W. Grimes struct delayval tbdelay[] = { 436cae66988SJoerg Wunsch { 1, TAB1 }, 437cae66988SJoerg Wunsch { 2, TAB2 }, 438cae66988SJoerg Wunsch { 3, XTABS }, /* this is expand tabs */ 439cae66988SJoerg Wunsch { 100, TAB1 }, 440cae66988SJoerg Wunsch { 0, TAB2 }, 441ea022d16SRodney W. Grimes }; 442ea022d16SRodney W. Grimes 443cae66988SJoerg Wunsch int 44495289b27SWarner Losh delaybits(void) 445ea022d16SRodney W. Grimes { 44695289b27SWarner Losh int f; 447ea022d16SRodney W. Grimes 448ea022d16SRodney W. Grimes f = adelay(CD, crdelay); 449ea022d16SRodney W. Grimes f |= adelay(ND, nldelay); 450ea022d16SRodney W. Grimes f |= adelay(FD, ffdelay); 451ea022d16SRodney W. Grimes f |= adelay(TD, tbdelay); 452ea022d16SRodney W. Grimes f |= adelay(BD, bsdelay); 453ea022d16SRodney W. Grimes return (f); 454ea022d16SRodney W. Grimes } 455ea022d16SRodney W. Grimes 456cae66988SJoerg Wunsch int 45795289b27SWarner Losh adelay(int ms, struct delayval *dp) 458ea022d16SRodney W. Grimes { 459ea022d16SRodney W. Grimes if (ms == 0) 460ea022d16SRodney W. Grimes return (0); 461ea022d16SRodney W. Grimes while (dp->delay && ms > dp->delay) 462ea022d16SRodney W. Grimes dp++; 463ea022d16SRodney W. Grimes return (dp->bits); 464ea022d16SRodney W. Grimes } 465cae66988SJoerg Wunsch #endif 466ea022d16SRodney W. Grimes 467c568fce9SAndrey A. Chernov char editedhost[MAXHOSTNAMELEN]; 468ea022d16SRodney W. Grimes 469cae66988SJoerg Wunsch void 470f73ff060SAlexey Dokuchaev edithost(const char *pattern) 471ea022d16SRodney W. Grimes { 472f73ff060SAlexey Dokuchaev regex_t regex; 473f73ff060SAlexey Dokuchaev regmatch_t *match; 474f73ff060SAlexey Dokuchaev int found; 475ea022d16SRodney W. Grimes 476f73ff060SAlexey Dokuchaev if (pattern == NULL || *pattern == '\0') 477f73ff060SAlexey Dokuchaev goto copyasis; 478f73ff060SAlexey Dokuchaev if (regcomp(®ex, pattern, REG_EXTENDED) != 0) 479f73ff060SAlexey Dokuchaev goto copyasis; 480ea022d16SRodney W. Grimes 481f73ff060SAlexey Dokuchaev match = calloc(regex.re_nsub + 1, sizeof(*match)); 482f73ff060SAlexey Dokuchaev if (match == NULL) { 483f73ff060SAlexey Dokuchaev regfree(®ex); 484f73ff060SAlexey Dokuchaev goto copyasis; 485ea022d16SRodney W. Grimes } 486f73ff060SAlexey Dokuchaev 487f73ff060SAlexey Dokuchaev found = !regexec(®ex, HN, regex.re_nsub + 1, match, 0); 488f73ff060SAlexey Dokuchaev if (found) { 489f73ff060SAlexey Dokuchaev size_t subex, totalsize; 490f73ff060SAlexey Dokuchaev 491f73ff060SAlexey Dokuchaev /* 492f73ff060SAlexey Dokuchaev * We found a match. If there were no parenthesized 493f73ff060SAlexey Dokuchaev * subexpressions in the pattern, use entire matched 494f73ff060SAlexey Dokuchaev * string as ``editedhost''; otherwise use the first 495f73ff060SAlexey Dokuchaev * matched subexpression. 496f73ff060SAlexey Dokuchaev */ 497f73ff060SAlexey Dokuchaev subex = !!regex.re_nsub; 498f73ff060SAlexey Dokuchaev totalsize = match[subex].rm_eo - match[subex].rm_so + 1; 499f73ff060SAlexey Dokuchaev strlcpy(editedhost, HN + match[subex].rm_so, totalsize > 500f73ff060SAlexey Dokuchaev sizeof(editedhost) ? sizeof(editedhost) : totalsize); 501f73ff060SAlexey Dokuchaev } 502f73ff060SAlexey Dokuchaev free(match); 503f73ff060SAlexey Dokuchaev regfree(®ex); 504f73ff060SAlexey Dokuchaev if (found) 505ea022d16SRodney W. Grimes return; 506f73ff060SAlexey Dokuchaev /* 507f73ff060SAlexey Dokuchaev * In case of any errors, or if the pattern did not match, pass 508f73ff060SAlexey Dokuchaev * the original hostname as is. 509f73ff060SAlexey Dokuchaev */ 510f73ff060SAlexey Dokuchaev copyasis: 511f73ff060SAlexey Dokuchaev strlcpy(editedhost, HN, sizeof(editedhost)); 512ea022d16SRodney W. Grimes } 513ea022d16SRodney W. Grimes 514cae66988SJoerg Wunsch static struct speedtab { 515ea022d16SRodney W. Grimes int speed; 516ea022d16SRodney W. Grimes int uxname; 517ea022d16SRodney W. Grimes } speedtab[] = { 518cae66988SJoerg Wunsch { 50, B50 }, 519cae66988SJoerg Wunsch { 75, B75 }, 520cae66988SJoerg Wunsch { 110, B110 }, 521cae66988SJoerg Wunsch { 134, B134 }, 522cae66988SJoerg Wunsch { 150, B150 }, 523cae66988SJoerg Wunsch { 200, B200 }, 524cae66988SJoerg Wunsch { 300, B300 }, 525cae66988SJoerg Wunsch { 600, B600 }, 526cae66988SJoerg Wunsch { 1200, B1200 }, 527cae66988SJoerg Wunsch { 1800, B1800 }, 528cae66988SJoerg Wunsch { 2400, B2400 }, 529cae66988SJoerg Wunsch { 4800, B4800 }, 530cae66988SJoerg Wunsch { 9600, B9600 }, 531cae66988SJoerg Wunsch { 19200, EXTA }, 532cae66988SJoerg Wunsch { 19, EXTA }, /* for people who say 19.2K */ 533cae66988SJoerg Wunsch { 38400, EXTB }, 534cae66988SJoerg Wunsch { 38, EXTB }, 535cae66988SJoerg Wunsch { 7200, EXTB }, /* alternative */ 536cae66988SJoerg Wunsch { 57600, B57600 }, 537cae66988SJoerg Wunsch { 115200, B115200 }, 538ee98a93fSPoul-Henning Kamp { 230400, B230400 }, 5391776dc9fSEdward Tomasz Napierala { 0, 0 } 540ea022d16SRodney W. Grimes }; 541ea022d16SRodney W. Grimes 542cae66988SJoerg Wunsch int 54395289b27SWarner Losh speed(int val) 544ea022d16SRodney W. Grimes { 54595289b27SWarner Losh struct speedtab *sp; 546ea022d16SRodney W. Grimes 547ee98a93fSPoul-Henning Kamp if (val <= B230400) 548ea022d16SRodney W. Grimes return (val); 549ea022d16SRodney W. Grimes 550ea022d16SRodney W. Grimes for (sp = speedtab; sp->speed; sp++) 551ea022d16SRodney W. Grimes if (sp->speed == val) 552ea022d16SRodney W. Grimes return (sp->uxname); 553ea022d16SRodney W. Grimes 554ea022d16SRodney W. Grimes return (B300); /* default in impossible cases */ 555ea022d16SRodney W. Grimes } 556ea022d16SRodney W. Grimes 557cae66988SJoerg Wunsch void 55895289b27SWarner Losh makeenv(char *env[]) 559ea022d16SRodney W. Grimes { 560ea022d16SRodney W. Grimes static char termbuf[128] = "TERM="; 56195289b27SWarner Losh char *p, *q; 56295289b27SWarner Losh char **ep; 563ea022d16SRodney W. Grimes 564ea022d16SRodney W. Grimes ep = env; 565ea022d16SRodney W. Grimes if (TT && *TT) { 5666e76e16fSKris Kennaway strlcat(termbuf, TT, sizeof(termbuf)); 567ea022d16SRodney W. Grimes *ep++ = termbuf; 568ea022d16SRodney W. Grimes } 569cae66988SJoerg Wunsch if ((p = EV)) { 570ea022d16SRodney W. Grimes q = p; 571cae66988SJoerg Wunsch while ((q = strchr(q, ','))) { 572ea022d16SRodney W. Grimes *q++ = '\0'; 573ea022d16SRodney W. Grimes *ep++ = p; 574ea022d16SRodney W. Grimes p = q; 575ea022d16SRodney W. Grimes } 576ea022d16SRodney W. Grimes if (*p) 577ea022d16SRodney W. Grimes *ep++ = p; 578ea022d16SRodney W. Grimes } 579ea022d16SRodney W. Grimes *ep = (char *)0; 580ea022d16SRodney W. Grimes } 581ea022d16SRodney W. Grimes 582ea022d16SRodney W. Grimes /* 583ea022d16SRodney W. Grimes * This speed select mechanism is written for the Develcon DATASWITCH. 584ea022d16SRodney W. Grimes * The Develcon sends a string of the form "B{speed}\n" at a predefined 585ea022d16SRodney W. Grimes * baud rate. This string indicates the user's actual speed. 586ea022d16SRodney W. Grimes * The routine below returns the terminal type mapped from derived speed. 587ea022d16SRodney W. Grimes */ 5889c33cc93SEdward Tomasz Napierala static struct portselect { 589cae66988SJoerg Wunsch const char *ps_baud; 590cae66988SJoerg Wunsch const char *ps_type; 591ea022d16SRodney W. Grimes } portspeeds[] = { 592ea022d16SRodney W. Grimes { "B110", "std.110" }, 593ea022d16SRodney W. Grimes { "B134", "std.134" }, 594ea022d16SRodney W. Grimes { "B150", "std.150" }, 595ea022d16SRodney W. Grimes { "B300", "std.300" }, 596ea022d16SRodney W. Grimes { "B600", "std.600" }, 597ea022d16SRodney W. Grimes { "B1200", "std.1200" }, 598ea022d16SRodney W. Grimes { "B2400", "std.2400" }, 599ea022d16SRodney W. Grimes { "B4800", "std.4800" }, 600ea022d16SRodney W. Grimes { "B9600", "std.9600" }, 601ea022d16SRodney W. Grimes { "B19200", "std.19200" }, 60273906f57SPedro F. Giffuni { NULL, NULL } 603ea022d16SRodney W. Grimes }; 604ea022d16SRodney W. Grimes 605cae66988SJoerg Wunsch const char * 60695289b27SWarner Losh portselector(void) 607ea022d16SRodney W. Grimes { 608cae66988SJoerg Wunsch char c, baud[20]; 609cae66988SJoerg Wunsch const char *type = "default"; 61095289b27SWarner Losh struct portselect *ps; 61173906f57SPedro F. Giffuni size_t len; 612ea022d16SRodney W. Grimes 613ea022d16SRodney W. Grimes alarm(5*60); 614ea022d16SRodney W. Grimes for (len = 0; len < sizeof (baud) - 1; len++) { 615ea022d16SRodney W. Grimes if (read(STDIN_FILENO, &c, 1) <= 0) 616ea022d16SRodney W. Grimes break; 617ea022d16SRodney W. Grimes c &= 0177; 618ea022d16SRodney W. Grimes if (c == '\n' || c == '\r') 619ea022d16SRodney W. Grimes break; 620ea022d16SRodney W. Grimes if (c == 'B') 621ea022d16SRodney W. Grimes len = 0; /* in case of leading garbage */ 622ea022d16SRodney W. Grimes baud[len] = c; 623ea022d16SRodney W. Grimes } 624ea022d16SRodney W. Grimes baud[len] = '\0'; 625ea022d16SRodney W. Grimes for (ps = portspeeds; ps->ps_baud; ps++) 626ea022d16SRodney W. Grimes if (strcmp(ps->ps_baud, baud) == 0) { 627ea022d16SRodney W. Grimes type = ps->ps_type; 628ea022d16SRodney W. Grimes break; 629ea022d16SRodney W. Grimes } 630ea022d16SRodney W. Grimes sleep(2); /* wait for connection to complete */ 631ea022d16SRodney W. Grimes return (type); 632ea022d16SRodney W. Grimes } 633ea022d16SRodney W. Grimes 634ea022d16SRodney W. Grimes /* 635ea022d16SRodney W. Grimes * This auto-baud speed select mechanism is written for the Micom 600 636ea022d16SRodney W. Grimes * portselector. Selection is done by looking at how the character '\r' 637ea022d16SRodney W. Grimes * is garbled at the different speeds. 638ea022d16SRodney W. Grimes */ 639cae66988SJoerg Wunsch const char * 64095289b27SWarner Losh autobaud(void) 641ea022d16SRodney W. Grimes { 642a3e4b982SPedro F. Giffuni struct pollfd set[1]; 643a3e4b982SPedro F. Giffuni struct timespec timeout; 644cae66988SJoerg Wunsch char c; 645cae66988SJoerg Wunsch const char *type = "9600-baud"; 646ea022d16SRodney W. Grimes 647cae66988SJoerg Wunsch (void)tcflush(0, TCIOFLUSH); 648a3e4b982SPedro F. Giffuni set[0].fd = STDIN_FILENO; 649a3e4b982SPedro F. Giffuni set[0].events = POLLIN; 650a3e4b982SPedro F. Giffuni if (poll(set, 1, 5000) <= 0) 651ea022d16SRodney W. Grimes return (type); 652ea022d16SRodney W. Grimes if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char)) 653ea022d16SRodney W. Grimes return (type); 654ea022d16SRodney W. Grimes timeout.tv_sec = 0; 655a3e4b982SPedro F. Giffuni timeout.tv_nsec = 20000; 656a3e4b982SPedro F. Giffuni (void)nanosleep(&timeout, NULL); 657cae66988SJoerg Wunsch (void)tcflush(0, TCIOFLUSH); 658ea022d16SRodney W. Grimes switch (c & 0377) { 659ea022d16SRodney W. Grimes 660ea022d16SRodney W. Grimes case 0200: /* 300-baud */ 661ea022d16SRodney W. Grimes type = "300-baud"; 662ea022d16SRodney W. Grimes break; 663ea022d16SRodney W. Grimes 664ea022d16SRodney W. Grimes case 0346: /* 1200-baud */ 665ea022d16SRodney W. Grimes type = "1200-baud"; 666ea022d16SRodney W. Grimes break; 667ea022d16SRodney W. Grimes 668ea022d16SRodney W. Grimes case 015: /* 2400-baud */ 669ea022d16SRodney W. Grimes case 0215: 670ea022d16SRodney W. Grimes type = "2400-baud"; 671ea022d16SRodney W. Grimes break; 672ea022d16SRodney W. Grimes 673ea022d16SRodney W. Grimes default: /* 4800-baud */ 674ea022d16SRodney W. Grimes type = "4800-baud"; 675ea022d16SRodney W. Grimes break; 676ea022d16SRodney W. Grimes 677ea022d16SRodney W. Grimes case 0377: /* 9600-baud */ 678ea022d16SRodney W. Grimes type = "9600-baud"; 679ea022d16SRodney W. Grimes break; 680ea022d16SRodney W. Grimes } 681ea022d16SRodney W. Grimes return (type); 682ea022d16SRodney W. Grimes } 683