map.c revision 1591
1/*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/9/93"; 36#endif /* not lint */ 37 38#include <sys/types.h> 39#include <termios.h> 40#include <errno.h> 41#include <stdlib.h> 42#include <string.h> 43#include "extern.h" 44 45int baudrate __P((char *)); 46 47/* Baud rate conditionals for mapping. */ 48#define GT 0x01 49#define EQ 0x02 50#define LT 0x04 51#define NOT 0x08 52#define GE (GT | EQ) 53#define LE (LT | EQ) 54 55typedef struct map { 56 struct map *next; /* Linked list of maps. */ 57 char *porttype; /* Port type, or "" for any. */ 58 char *type; /* Terminal type to select. */ 59 int conditional; /* Baud rate conditionals bitmask. */ 60 int speed; /* Baud rate to compare against. */ 61} MAP; 62 63MAP *cur, *maplist; 64 65/* 66 * Syntax for -m: 67 * [port-type][test baudrate]:terminal-type 68 * The baud rate tests are: >, <, @, =, ! 69 */ 70void 71add_mapping(port, arg) 72 char *port, *arg; 73{ 74 MAP *mapp; 75 char *copy, *p, *termp; 76 77 copy = strdup(arg); 78 mapp = malloc((u_int)sizeof(MAP)); 79 if (copy == NULL || mapp == NULL) 80 err("%s", strerror(errno)); 81 mapp->next = NULL; 82 if (maplist == NULL) 83 cur = maplist = mapp; 84 else { 85 cur->next = mapp; 86 cur = mapp; 87 } 88 89 mapp->porttype = arg; 90 mapp->conditional = 0; 91 92 arg = strpbrk(arg, "><@=!:"); 93 94 if (arg == NULL) { /* [?]term */ 95 mapp->type = mapp->porttype; 96 mapp->porttype = NULL; 97 goto done; 98 } 99 100 if (arg == mapp->porttype) /* [><@=! baud]:term */ 101 termp = mapp->porttype = NULL; 102 else 103 termp = arg; 104 105 for (;; ++arg) /* Optional conditionals. */ 106 switch(*arg) { 107 case '<': 108 if (mapp->conditional & GT) 109 goto badmopt; 110 mapp->conditional |= LT; 111 break; 112 case '>': 113 if (mapp->conditional & LT) 114 goto badmopt; 115 mapp->conditional |= GT; 116 break; 117 case '@': 118 case '=': /* Not documented. */ 119 mapp->conditional |= EQ; 120 break; 121 case '!': 122 mapp->conditional |= NOT; 123 break; 124 default: 125 goto next; 126 } 127 128next: if (*arg == ':') { 129 if (mapp->conditional) 130 goto badmopt; 131 ++arg; 132 } else { /* Optional baudrate. */ 133 arg = index(p = arg, ':'); 134 if (arg == NULL) 135 goto badmopt; 136 *arg++ = '\0'; 137 mapp->speed = baudrate(p); 138 } 139 140 if (*arg == NULL) /* Non-optional type. */ 141 goto badmopt; 142 143 mapp->type = arg; 144 145 /* Terminate porttype, if specified. */ 146 if (termp != NULL) 147 *termp = '\0'; 148 149 /* If a NOT conditional, reverse the test. */ 150 if (mapp->conditional & NOT) 151 mapp->conditional = ~mapp->conditional & (EQ | GT | LT); 152 153 /* If user specified a port with an option flag, set it. */ 154done: if (port) { 155 if (mapp->porttype) 156badmopt: err("illegal -m option format: %s", copy); 157 mapp->porttype = port; 158 } 159 160#ifdef MAPDEBUG 161 (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); 162 (void)printf("type: %s\n", mapp->type); 163 (void)printf("conditional: "); 164 p = ""; 165 if (mapp->conditional & GT) { 166 (void)printf("GT"); 167 p = "/"; 168 } 169 if (mapp->conditional & EQ) { 170 (void)printf("%sEQ", p); 171 p = "/"; 172 } 173 if (mapp->conditional & LT) 174 (void)printf("%sLT", p); 175 (void)printf("\nspeed: %d\n", mapp->speed); 176#endif 177} 178 179/* 180 * Return the type of terminal to use for a port of type 'type', as specified 181 * by the first applicable mapping in 'map'. If no mappings apply, return 182 * 'type'. 183 */ 184char * 185mapped(type) 186 char *type; 187{ 188 MAP *mapp; 189 int match; 190 191 for (mapp = maplist; mapp; mapp = mapp->next) 192 if (mapp->porttype == NULL || !strcmp(mapp->porttype, type)) { 193 switch (mapp->conditional) { 194 case 0: /* No test specified. */ 195 match = 1; 196 break; 197 case EQ: 198 match = (ospeed == mapp->speed); 199 break; 200 case GE: 201 match = (ospeed >= mapp->speed); 202 break; 203 case GT: 204 match = (ospeed > mapp->speed); 205 break; 206 case LE: 207 match = (ospeed <= mapp->speed); 208 break; 209 case LT: 210 match = (ospeed < mapp->speed); 211 break; 212 } 213 if (match) 214 return (mapp->type); 215 } 216 /* No match found; return given type. */ 217 return (type); 218} 219 220typedef struct speeds { 221 char *string; 222 int speed; 223} SPEEDS; 224 225SPEEDS speeds[] = { 226 "0", B0, 227 "50", B50, 228 "75", B75, 229 "110", B110, 230 "134", B134, 231 "134.5", B134, 232 "150", B150, 233 "200", B200, 234 "300", B300, 235 "600", B600, 236 "1200", B1200, 237 "1800", B1800, 238 "2400", B2400, 239 "4800", B4800, 240 "9600", B9600, 241 "19200", B19200, 242 "38400", B38400, 243 "exta", B19200, 244 "extb", B38400, 245 NULL 246}; 247 248int 249baudrate(rate) 250 char *rate; 251{ 252 SPEEDS *sp; 253 254 /* The baudrate number can be preceded by a 'B', which is ignored. */ 255 if (*rate == 'B') 256 ++rate; 257 258 for (sp = speeds; sp->string; ++sp) 259 if (!strcasecmp(rate, sp->string)) 260 return (sp->speed); 261 err("unknown baud rate %s", rate); 262 /* NOTREACHED */ 263} 264