map.c revision 9888
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 351590Srgrimesstatic char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/9/93"; 361590Srgrimes#endif /* not lint */ 371590Srgrimes 381590Srgrimes#include <sys/types.h> 391590Srgrimes#include <termios.h> 401590Srgrimes#include <errno.h> 411590Srgrimes#include <stdlib.h> 421590Srgrimes#include <string.h> 431590Srgrimes#include "extern.h" 441590Srgrimes 452599Sacheextern speed_t Ospeed; 462599Sachespeed_t baudrate __P((char *)); 471590Srgrimes 481590Srgrimes/* Baud rate conditionals for mapping. */ 491590Srgrimes#define GT 0x01 501590Srgrimes#define EQ 0x02 511590Srgrimes#define LT 0x04 521590Srgrimes#define NOT 0x08 531590Srgrimes#define GE (GT | EQ) 541590Srgrimes#define LE (LT | EQ) 551590Srgrimes 561590Srgrimestypedef struct map { 571590Srgrimes struct map *next; /* Linked list of maps. */ 581590Srgrimes char *porttype; /* Port type, or "" for any. */ 591590Srgrimes char *type; /* Terminal type to select. */ 601590Srgrimes int conditional; /* Baud rate conditionals bitmask. */ 612599Sache speed_t speed; /* Baud rate to compare against. */ 621590Srgrimes} MAP; 631590Srgrimes 641590SrgrimesMAP *cur, *maplist; 651590Srgrimes 661590Srgrimes/* 671590Srgrimes * Syntax for -m: 681590Srgrimes * [port-type][test baudrate]:terminal-type 691590Srgrimes * The baud rate tests are: >, <, @, =, ! 701590Srgrimes */ 711590Srgrimesvoid 721590Srgrimesadd_mapping(port, arg) 731590Srgrimes char *port, *arg; 741590Srgrimes{ 751590Srgrimes MAP *mapp; 761590Srgrimes char *copy, *p, *termp; 771590Srgrimes 781590Srgrimes copy = strdup(arg); 791590Srgrimes mapp = malloc((u_int)sizeof(MAP)); 801590Srgrimes if (copy == NULL || mapp == NULL) 811590Srgrimes err("%s", strerror(errno)); 821590Srgrimes mapp->next = NULL; 831590Srgrimes if (maplist == NULL) 841590Srgrimes cur = maplist = mapp; 851590Srgrimes else { 861590Srgrimes cur->next = mapp; 871590Srgrimes cur = mapp; 881590Srgrimes } 891590Srgrimes 901590Srgrimes mapp->porttype = arg; 911590Srgrimes mapp->conditional = 0; 921590Srgrimes 931590Srgrimes arg = strpbrk(arg, "><@=!:"); 941590Srgrimes 951590Srgrimes if (arg == NULL) { /* [?]term */ 961590Srgrimes mapp->type = mapp->porttype; 971590Srgrimes mapp->porttype = NULL; 981590Srgrimes goto done; 991590Srgrimes } 1001590Srgrimes 1011590Srgrimes if (arg == mapp->porttype) /* [><@=! baud]:term */ 1021590Srgrimes termp = mapp->porttype = NULL; 1031590Srgrimes else 1041590Srgrimes termp = arg; 1051590Srgrimes 1061590Srgrimes for (;; ++arg) /* Optional conditionals. */ 1071590Srgrimes switch(*arg) { 1081590Srgrimes case '<': 1091590Srgrimes if (mapp->conditional & GT) 1101590Srgrimes goto badmopt; 1111590Srgrimes mapp->conditional |= LT; 1121590Srgrimes break; 1131590Srgrimes case '>': 1141590Srgrimes if (mapp->conditional & LT) 1151590Srgrimes goto badmopt; 1161590Srgrimes mapp->conditional |= GT; 1171590Srgrimes break; 1181590Srgrimes case '@': 1191590Srgrimes case '=': /* Not documented. */ 1201590Srgrimes mapp->conditional |= EQ; 1211590Srgrimes break; 1221590Srgrimes case '!': 1231590Srgrimes mapp->conditional |= NOT; 1241590Srgrimes break; 1251590Srgrimes default: 1261590Srgrimes goto next; 1271590Srgrimes } 1281590Srgrimes 1291590Srgrimesnext: if (*arg == ':') { 1301590Srgrimes if (mapp->conditional) 1311590Srgrimes goto badmopt; 1321590Srgrimes ++arg; 1331590Srgrimes } else { /* Optional baudrate. */ 1341590Srgrimes arg = index(p = arg, ':'); 1351590Srgrimes if (arg == NULL) 1361590Srgrimes goto badmopt; 1371590Srgrimes *arg++ = '\0'; 1381590Srgrimes mapp->speed = baudrate(p); 1391590Srgrimes } 1401590Srgrimes 1411590Srgrimes if (*arg == NULL) /* Non-optional type. */ 1421590Srgrimes goto badmopt; 1431590Srgrimes 1441590Srgrimes mapp->type = arg; 1451590Srgrimes 1461590Srgrimes /* Terminate porttype, if specified. */ 1471590Srgrimes if (termp != NULL) 1481590Srgrimes *termp = '\0'; 1491590Srgrimes 1501590Srgrimes /* If a NOT conditional, reverse the test. */ 1511590Srgrimes if (mapp->conditional & NOT) 1521590Srgrimes mapp->conditional = ~mapp->conditional & (EQ | GT | LT); 1531590Srgrimes 1541590Srgrimes /* If user specified a port with an option flag, set it. */ 1551590Srgrimesdone: if (port) { 1561590Srgrimes if (mapp->porttype) 1571590Srgrimesbadmopt: err("illegal -m option format: %s", copy); 1581590Srgrimes mapp->porttype = port; 1591590Srgrimes } 1601590Srgrimes 1611590Srgrimes#ifdef MAPDEBUG 1621590Srgrimes (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); 1631590Srgrimes (void)printf("type: %s\n", mapp->type); 1641590Srgrimes (void)printf("conditional: "); 1651590Srgrimes p = ""; 1661590Srgrimes if (mapp->conditional & GT) { 1671590Srgrimes (void)printf("GT"); 1681590Srgrimes p = "/"; 1691590Srgrimes } 1701590Srgrimes if (mapp->conditional & EQ) { 1711590Srgrimes (void)printf("%sEQ", p); 1721590Srgrimes p = "/"; 1731590Srgrimes } 1741590Srgrimes if (mapp->conditional & LT) 1751590Srgrimes (void)printf("%sLT", p); 1761590Srgrimes (void)printf("\nspeed: %d\n", mapp->speed); 1771590Srgrimes#endif 1781590Srgrimes} 1791590Srgrimes 1801590Srgrimes/* 1811590Srgrimes * Return the type of terminal to use for a port of type 'type', as specified 1821590Srgrimes * by the first applicable mapping in 'map'. If no mappings apply, return 1831590Srgrimes * 'type'. 1841590Srgrimes */ 1851590Srgrimeschar * 1861590Srgrimesmapped(type) 1871590Srgrimes char *type; 1881590Srgrimes{ 1891590Srgrimes MAP *mapp; 1901590Srgrimes int match; 1911590Srgrimes 1921590Srgrimes for (mapp = maplist; mapp; mapp = mapp->next) 1931590Srgrimes if (mapp->porttype == NULL || !strcmp(mapp->porttype, type)) { 1941590Srgrimes switch (mapp->conditional) { 1951590Srgrimes case 0: /* No test specified. */ 1961590Srgrimes match = 1; 1971590Srgrimes break; 1981590Srgrimes case EQ: 1992599Sache match = (Ospeed == mapp->speed); 2001590Srgrimes break; 2011590Srgrimes case GE: 2022599Sache match = (Ospeed >= mapp->speed); 2031590Srgrimes break; 2041590Srgrimes case GT: 2052599Sache match = (Ospeed > mapp->speed); 2061590Srgrimes break; 2071590Srgrimes case LE: 2082599Sache match = (Ospeed <= mapp->speed); 2091590Srgrimes break; 2101590Srgrimes case LT: 2112599Sache match = (Ospeed < mapp->speed); 2121590Srgrimes break; 2131590Srgrimes } 2141590Srgrimes if (match) 2151590Srgrimes return (mapp->type); 2161590Srgrimes } 2171590Srgrimes /* No match found; return given type. */ 2181590Srgrimes return (type); 2191590Srgrimes} 2201590Srgrimes 2211590Srgrimestypedef struct speeds { 2221590Srgrimes char *string; 2232599Sache speed_t speed; 2241590Srgrimes} SPEEDS; 2251590Srgrimes 2261590SrgrimesSPEEDS speeds[] = { 2271590Srgrimes "0", B0, 2281590Srgrimes "134.5", B134, 2291590Srgrimes "exta", B19200, 2301590Srgrimes "extb", B38400, 2311590Srgrimes NULL 2321590Srgrimes}; 2331590Srgrimes 2342599Sachespeed_t 2351590Srgrimesbaudrate(rate) 2361590Srgrimes char *rate; 2371590Srgrimes{ 2381590Srgrimes SPEEDS *sp; 2399888Sache speed_t speed; 2401590Srgrimes 2411590Srgrimes /* The baudrate number can be preceded by a 'B', which is ignored. */ 2421590Srgrimes if (*rate == 'B') 2431590Srgrimes ++rate; 2441590Srgrimes 2451590Srgrimes for (sp = speeds; sp->string; ++sp) 2461590Srgrimes if (!strcasecmp(rate, sp->string)) 2471590Srgrimes return (sp->speed); 2489888Sache speed = atol(rate); 2499888Sache if (speed == 0) 2509888Sache err("unknown baud rate %s", rate); 2519888Sache return speed; 2521590Srgrimes} 253