map.c revision 146752
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 3487701Smarkm#include <sys/cdefs.h> 3587701Smarkm 3687701Smarkm__FBSDID("$FreeBSD: head/usr.bin/tset/map.c 146752 2005-05-29 15:49:53Z charnier $"); 3787701Smarkm 381590Srgrimes#ifndef lint 3987701Smarkmstatic const char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/9/93"; 4028370Scharnier#endif 411590Srgrimes 421590Srgrimes#include <sys/types.h> 4387701Smarkm 4428370Scharnier#include <err.h> 451590Srgrimes#include <stdlib.h> 461590Srgrimes#include <string.h> 4728370Scharnier#include <termios.h> 4887701Smarkm 491590Srgrimes#include "extern.h" 501590Srgrimes 512599Sacheextern speed_t Ospeed; 5292922Simpspeed_t tset_baudrate(char *); 531590Srgrimes 541590Srgrimes/* Baud rate conditionals for mapping. */ 551590Srgrimes#define GT 0x01 561590Srgrimes#define EQ 0x02 571590Srgrimes#define LT 0x04 581590Srgrimes#define NOT 0x08 591590Srgrimes#define GE (GT | EQ) 601590Srgrimes#define LE (LT | EQ) 611590Srgrimes 621590Srgrimestypedef struct map { 631590Srgrimes struct map *next; /* Linked list of maps. */ 641590Srgrimes char *porttype; /* Port type, or "" for any. */ 651590Srgrimes char *type; /* Terminal type to select. */ 661590Srgrimes int conditional; /* Baud rate conditionals bitmask. */ 672599Sache speed_t speed; /* Baud rate to compare against. */ 681590Srgrimes} MAP; 691590Srgrimes 701590SrgrimesMAP *cur, *maplist; 711590Srgrimes 721590Srgrimes/* 731590Srgrimes * Syntax for -m: 741590Srgrimes * [port-type][test baudrate]:terminal-type 751590Srgrimes * The baud rate tests are: >, <, @, =, ! 761590Srgrimes */ 771590Srgrimesvoid 781590Srgrimesadd_mapping(port, arg) 7987701Smarkm const char *port; 8087701Smarkm char *arg; 811590Srgrimes{ 821590Srgrimes MAP *mapp; 831590Srgrimes char *copy, *p, *termp; 841590Srgrimes 851590Srgrimes copy = strdup(arg); 8696785Sjmallett mapp = malloc(sizeof(MAP)); 871590Srgrimes if (copy == NULL || mapp == NULL) 8828370Scharnier errx(1, "malloc"); 891590Srgrimes mapp->next = NULL; 901590Srgrimes if (maplist == NULL) 911590Srgrimes cur = maplist = mapp; 921590Srgrimes else { 931590Srgrimes cur->next = mapp; 941590Srgrimes cur = mapp; 951590Srgrimes } 961590Srgrimes 971590Srgrimes mapp->porttype = arg; 981590Srgrimes mapp->conditional = 0; 991590Srgrimes 1001590Srgrimes arg = strpbrk(arg, "><@=!:"); 1011590Srgrimes 1021590Srgrimes if (arg == NULL) { /* [?]term */ 1031590Srgrimes mapp->type = mapp->porttype; 1041590Srgrimes mapp->porttype = NULL; 1051590Srgrimes goto done; 1061590Srgrimes } 1071590Srgrimes 1081590Srgrimes if (arg == mapp->porttype) /* [><@=! baud]:term */ 1091590Srgrimes termp = mapp->porttype = NULL; 1101590Srgrimes else 1111590Srgrimes termp = arg; 1121590Srgrimes 1131590Srgrimes for (;; ++arg) /* Optional conditionals. */ 1141590Srgrimes switch(*arg) { 1151590Srgrimes case '<': 1161590Srgrimes if (mapp->conditional & GT) 1171590Srgrimes goto badmopt; 1181590Srgrimes mapp->conditional |= LT; 1191590Srgrimes break; 1201590Srgrimes case '>': 1211590Srgrimes if (mapp->conditional & LT) 1221590Srgrimes goto badmopt; 1231590Srgrimes mapp->conditional |= GT; 1241590Srgrimes break; 1251590Srgrimes case '@': 1261590Srgrimes case '=': /* Not documented. */ 1271590Srgrimes mapp->conditional |= EQ; 1281590Srgrimes break; 1291590Srgrimes case '!': 1301590Srgrimes mapp->conditional |= NOT; 1311590Srgrimes break; 1321590Srgrimes default: 1331590Srgrimes goto next; 1341590Srgrimes } 1351590Srgrimes 1361590Srgrimesnext: if (*arg == ':') { 1371590Srgrimes if (mapp->conditional) 1381590Srgrimes goto badmopt; 1391590Srgrimes ++arg; 1401590Srgrimes } else { /* Optional baudrate. */ 1411590Srgrimes arg = index(p = arg, ':'); 1421590Srgrimes if (arg == NULL) 1431590Srgrimes goto badmopt; 1441590Srgrimes *arg++ = '\0'; 14550638Speter mapp->speed = tset_baudrate(p); 1461590Srgrimes } 1471590Srgrimes 14829574Sphk if (*arg == '\0') /* Non-optional type. */ 1491590Srgrimes goto badmopt; 1501590Srgrimes 1511590Srgrimes mapp->type = arg; 1521590Srgrimes 1531590Srgrimes /* Terminate porttype, if specified. */ 1541590Srgrimes if (termp != NULL) 1551590Srgrimes *termp = '\0'; 1561590Srgrimes 1571590Srgrimes /* If a NOT conditional, reverse the test. */ 1581590Srgrimes if (mapp->conditional & NOT) 1591590Srgrimes mapp->conditional = ~mapp->conditional & (EQ | GT | LT); 1601590Srgrimes 1611590Srgrimes /* If user specified a port with an option flag, set it. */ 1621590Srgrimesdone: if (port) { 1631590Srgrimes if (mapp->porttype) 16428370Scharnierbadmopt: errx(1, "illegal -m option format: %s", copy); 16587701Smarkm mapp->porttype = strdup(port); 1661590Srgrimes } 1671590Srgrimes 1681590Srgrimes#ifdef MAPDEBUG 1691590Srgrimes (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); 1701590Srgrimes (void)printf("type: %s\n", mapp->type); 1711590Srgrimes (void)printf("conditional: "); 1721590Srgrimes p = ""; 1731590Srgrimes if (mapp->conditional & GT) { 1741590Srgrimes (void)printf("GT"); 1751590Srgrimes p = "/"; 1761590Srgrimes } 1771590Srgrimes if (mapp->conditional & EQ) { 1781590Srgrimes (void)printf("%sEQ", p); 1791590Srgrimes p = "/"; 1801590Srgrimes } 1811590Srgrimes if (mapp->conditional & LT) 1821590Srgrimes (void)printf("%sLT", p); 1831590Srgrimes (void)printf("\nspeed: %d\n", mapp->speed); 1841590Srgrimes#endif 1851590Srgrimes} 1861590Srgrimes 1871590Srgrimes/* 1881590Srgrimes * Return the type of terminal to use for a port of type 'type', as specified 1891590Srgrimes * by the first applicable mapping in 'map'. If no mappings apply, return 1901590Srgrimes * 'type'. 1911590Srgrimes */ 19287701Smarkmconst char * 1931590Srgrimesmapped(type) 19487701Smarkm const char *type; 1951590Srgrimes{ 1961590Srgrimes MAP *mapp; 1971590Srgrimes int match; 1981590Srgrimes 199146752Scharnier match = 0; 2001590Srgrimes for (mapp = maplist; mapp; mapp = mapp->next) 2011590Srgrimes if (mapp->porttype == NULL || !strcmp(mapp->porttype, type)) { 2021590Srgrimes switch (mapp->conditional) { 2031590Srgrimes case 0: /* No test specified. */ 2041590Srgrimes match = 1; 2051590Srgrimes break; 2061590Srgrimes case EQ: 2072599Sache match = (Ospeed == mapp->speed); 2081590Srgrimes break; 2091590Srgrimes case GE: 2102599Sache match = (Ospeed >= mapp->speed); 2111590Srgrimes break; 2121590Srgrimes case GT: 2132599Sache match = (Ospeed > mapp->speed); 2141590Srgrimes break; 2151590Srgrimes case LE: 2162599Sache match = (Ospeed <= mapp->speed); 2171590Srgrimes break; 2181590Srgrimes case LT: 2192599Sache match = (Ospeed < mapp->speed); 2201590Srgrimes break; 2211590Srgrimes } 2221590Srgrimes if (match) 2231590Srgrimes return (mapp->type); 2241590Srgrimes } 2251590Srgrimes /* No match found; return given type. */ 2261590Srgrimes return (type); 2271590Srgrimes} 2281590Srgrimes 2291590Srgrimestypedef struct speeds { 23087701Smarkm const char *string; 2312599Sache speed_t speed; 2321590Srgrimes} SPEEDS; 2331590Srgrimes 2341590SrgrimesSPEEDS speeds[] = { 23587701Smarkm { "0", B0 }, 23687701Smarkm { "134.5", B134 }, 23787701Smarkm { "exta", B19200 }, 23887701Smarkm { "extb", B38400 }, 23987701Smarkm { NULL, 0 } 2401590Srgrimes}; 2411590Srgrimes 2422599Sachespeed_t 24350638Spetertset_baudrate(rate) 2441590Srgrimes char *rate; 2451590Srgrimes{ 2461590Srgrimes SPEEDS *sp; 2479888Sache speed_t speed; 2481590Srgrimes 2491590Srgrimes /* The baudrate number can be preceded by a 'B', which is ignored. */ 2501590Srgrimes if (*rate == 'B') 2511590Srgrimes ++rate; 2521590Srgrimes 2531590Srgrimes for (sp = speeds; sp->string; ++sp) 2541590Srgrimes if (!strcasecmp(rate, sp->string)) 2551590Srgrimes return (sp->speed); 2569888Sache speed = atol(rate); 2579888Sache if (speed == 0) 25828370Scharnier errx(1, "unknown baud rate %s", rate); 2599888Sache return speed; 2601590Srgrimes} 261