map.c revision 50638
11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1991, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 3528370Scharnier#if 0 361590Srgrimesstatic char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/9/93"; 3728370Scharnier#endif 3828370Scharnierstatic const char rcsid[] = 3950477Speter "$FreeBSD: head/usr.bin/tset/map.c 50638 1999-08-30 08:27:31Z peter $"; 401590Srgrimes#endif /* not lint */ 411590Srgrimes 421590Srgrimes#include <sys/types.h> 4328370Scharnier#include <err.h> 441590Srgrimes#include <stdlib.h> 451590Srgrimes#include <string.h> 4628370Scharnier#include <termios.h> 471590Srgrimes#include "extern.h" 481590Srgrimes 492599Sacheextern speed_t Ospeed; 5050638Speterspeed_t tset_baudrate __P((char *)); 511590Srgrimes 521590Srgrimes/* Baud rate conditionals for mapping. */ 531590Srgrimes#define GT 0x01 541590Srgrimes#define EQ 0x02 551590Srgrimes#define LT 0x04 561590Srgrimes#define NOT 0x08 571590Srgrimes#define GE (GT | EQ) 581590Srgrimes#define LE (LT | EQ) 591590Srgrimes 601590Srgrimestypedef struct map { 611590Srgrimes struct map *next; /* Linked list of maps. */ 621590Srgrimes char *porttype; /* Port type, or "" for any. */ 631590Srgrimes char *type; /* Terminal type to select. */ 641590Srgrimes int conditional; /* Baud rate conditionals bitmask. */ 652599Sache speed_t speed; /* Baud rate to compare against. */ 661590Srgrimes} MAP; 671590Srgrimes 681590SrgrimesMAP *cur, *maplist; 691590Srgrimes 701590Srgrimes/* 711590Srgrimes * Syntax for -m: 721590Srgrimes * [port-type][test baudrate]:terminal-type 731590Srgrimes * The baud rate tests are: >, <, @, =, ! 741590Srgrimes */ 751590Srgrimesvoid 761590Srgrimesadd_mapping(port, arg) 771590Srgrimes char *port, *arg; 781590Srgrimes{ 791590Srgrimes MAP *mapp; 801590Srgrimes char *copy, *p, *termp; 811590Srgrimes 821590Srgrimes copy = strdup(arg); 831590Srgrimes mapp = malloc((u_int)sizeof(MAP)); 841590Srgrimes if (copy == NULL || mapp == NULL) 8528370Scharnier errx(1, "malloc"); 861590Srgrimes mapp->next = NULL; 871590Srgrimes if (maplist == NULL) 881590Srgrimes cur = maplist = mapp; 891590Srgrimes else { 901590Srgrimes cur->next = mapp; 911590Srgrimes cur = mapp; 921590Srgrimes } 931590Srgrimes 941590Srgrimes mapp->porttype = arg; 951590Srgrimes mapp->conditional = 0; 961590Srgrimes 971590Srgrimes arg = strpbrk(arg, "><@=!:"); 981590Srgrimes 991590Srgrimes if (arg == NULL) { /* [?]term */ 1001590Srgrimes mapp->type = mapp->porttype; 1011590Srgrimes mapp->porttype = NULL; 1021590Srgrimes goto done; 1031590Srgrimes } 1041590Srgrimes 1051590Srgrimes if (arg == mapp->porttype) /* [><@=! baud]:term */ 1061590Srgrimes termp = mapp->porttype = NULL; 1071590Srgrimes else 1081590Srgrimes termp = arg; 1091590Srgrimes 1101590Srgrimes for (;; ++arg) /* Optional conditionals. */ 1111590Srgrimes switch(*arg) { 1121590Srgrimes case '<': 1131590Srgrimes if (mapp->conditional & GT) 1141590Srgrimes goto badmopt; 1151590Srgrimes mapp->conditional |= LT; 1161590Srgrimes break; 1171590Srgrimes case '>': 1181590Srgrimes if (mapp->conditional & LT) 1191590Srgrimes goto badmopt; 1201590Srgrimes mapp->conditional |= GT; 1211590Srgrimes break; 1221590Srgrimes case '@': 1231590Srgrimes case '=': /* Not documented. */ 1241590Srgrimes mapp->conditional |= EQ; 1251590Srgrimes break; 1261590Srgrimes case '!': 1271590Srgrimes mapp->conditional |= NOT; 1281590Srgrimes break; 1291590Srgrimes default: 1301590Srgrimes goto next; 1311590Srgrimes } 1321590Srgrimes 1331590Srgrimesnext: if (*arg == ':') { 1341590Srgrimes if (mapp->conditional) 1351590Srgrimes goto badmopt; 1361590Srgrimes ++arg; 1371590Srgrimes } else { /* Optional baudrate. */ 1381590Srgrimes arg = index(p = arg, ':'); 1391590Srgrimes if (arg == NULL) 1401590Srgrimes goto badmopt; 1411590Srgrimes *arg++ = '\0'; 14250638Speter mapp->speed = tset_baudrate(p); 1431590Srgrimes } 1441590Srgrimes 14529574Sphk if (*arg == '\0') /* Non-optional type. */ 1461590Srgrimes goto badmopt; 1471590Srgrimes 1481590Srgrimes mapp->type = arg; 1491590Srgrimes 1501590Srgrimes /* Terminate porttype, if specified. */ 1511590Srgrimes if (termp != NULL) 1521590Srgrimes *termp = '\0'; 1531590Srgrimes 1541590Srgrimes /* If a NOT conditional, reverse the test. */ 1551590Srgrimes if (mapp->conditional & NOT) 1561590Srgrimes mapp->conditional = ~mapp->conditional & (EQ | GT | LT); 1571590Srgrimes 1581590Srgrimes /* If user specified a port with an option flag, set it. */ 1591590Srgrimesdone: if (port) { 1601590Srgrimes if (mapp->porttype) 16128370Scharnierbadmopt: errx(1, "illegal -m option format: %s", copy); 1621590Srgrimes mapp->porttype = port; 1631590Srgrimes } 1641590Srgrimes 1651590Srgrimes#ifdef MAPDEBUG 1661590Srgrimes (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); 1671590Srgrimes (void)printf("type: %s\n", mapp->type); 1681590Srgrimes (void)printf("conditional: "); 1691590Srgrimes p = ""; 1701590Srgrimes if (mapp->conditional & GT) { 1711590Srgrimes (void)printf("GT"); 1721590Srgrimes p = "/"; 1731590Srgrimes } 1741590Srgrimes if (mapp->conditional & EQ) { 1751590Srgrimes (void)printf("%sEQ", p); 1761590Srgrimes p = "/"; 1771590Srgrimes } 1781590Srgrimes if (mapp->conditional & LT) 1791590Srgrimes (void)printf("%sLT", p); 1801590Srgrimes (void)printf("\nspeed: %d\n", mapp->speed); 1811590Srgrimes#endif 1821590Srgrimes} 1831590Srgrimes 1841590Srgrimes/* 1851590Srgrimes * Return the type of terminal to use for a port of type 'type', as specified 1861590Srgrimes * by the first applicable mapping in 'map'. If no mappings apply, return 1871590Srgrimes * 'type'. 1881590Srgrimes */ 1891590Srgrimeschar * 1901590Srgrimesmapped(type) 1911590Srgrimes char *type; 1921590Srgrimes{ 1931590Srgrimes MAP *mapp; 1941590Srgrimes int match; 1951590Srgrimes 1961590Srgrimes for (mapp = maplist; mapp; mapp = mapp->next) 1971590Srgrimes if (mapp->porttype == NULL || !strcmp(mapp->porttype, type)) { 1981590Srgrimes switch (mapp->conditional) { 1991590Srgrimes case 0: /* No test specified. */ 2001590Srgrimes match = 1; 2011590Srgrimes break; 2021590Srgrimes case EQ: 2032599Sache match = (Ospeed == mapp->speed); 2041590Srgrimes break; 2051590Srgrimes case GE: 2062599Sache match = (Ospeed >= mapp->speed); 2071590Srgrimes break; 2081590Srgrimes case GT: 2092599Sache match = (Ospeed > mapp->speed); 2101590Srgrimes break; 2111590Srgrimes case LE: 2122599Sache match = (Ospeed <= mapp->speed); 2131590Srgrimes break; 2141590Srgrimes case LT: 2152599Sache match = (Ospeed < mapp->speed); 2161590Srgrimes break; 2171590Srgrimes } 2181590Srgrimes if (match) 2191590Srgrimes return (mapp->type); 2201590Srgrimes } 2211590Srgrimes /* No match found; return given type. */ 2221590Srgrimes return (type); 2231590Srgrimes} 2241590Srgrimes 2251590Srgrimestypedef struct speeds { 2261590Srgrimes char *string; 2272599Sache speed_t speed; 2281590Srgrimes} SPEEDS; 2291590Srgrimes 2301590SrgrimesSPEEDS speeds[] = { 2311590Srgrimes "0", B0, 2321590Srgrimes "134.5", B134, 2331590Srgrimes "exta", B19200, 2341590Srgrimes "extb", B38400, 2351590Srgrimes NULL 2361590Srgrimes}; 2371590Srgrimes 2382599Sachespeed_t 23950638Spetertset_baudrate(rate) 2401590Srgrimes char *rate; 2411590Srgrimes{ 2421590Srgrimes SPEEDS *sp; 2439888Sache speed_t speed; 2441590Srgrimes 2451590Srgrimes /* The baudrate number can be preceded by a 'B', which is ignored. */ 2461590Srgrimes if (*rate == 'B') 2471590Srgrimes ++rate; 2481590Srgrimes 2491590Srgrimes for (sp = speeds; sp->string; ++sp) 2501590Srgrimes if (!strcasecmp(rate, sp->string)) 2511590Srgrimes return (sp->speed); 2529888Sache speed = atol(rate); 2539888Sache if (speed == 0) 25428370Scharnier errx(1, "unknown baud rate %s", rate); 2559888Sache return speed; 2561590Srgrimes} 257