1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * 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 35 /*static char sccsid[] = "from: @(#)map.c 5.2 (Berkeley) 12/24/91";*/ 36 static char rcsid[] = "$Id: map.c,v 1.2 1993/08/01 18:04:26 mycroft Exp $"; 37 #endif /* not lint */ 38 39 #include <sys/types.h> 40 #include <termios.h> 41 #include <errno.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include "extern.h" 45 46 int baudrate __P((char *)); 47 48 /* Baud rate conditionals for mapping. */ 49 #define GT 0x01 50 #define EQ 0x02 51 #define LT 0x04 52 #define NOT 0x08 53 #define GE (GT | EQ) 54 #define LE (LT | EQ) 55 56 typedef struct map { 57 struct map *next; /* Linked list of maps. */ 58 char *porttype; /* Port type, or "" for any. */ 59 char *type; /* Terminal type to select. */ 60 int conditional; /* Baud rate conditionals bitmask. */ 61 int speed; /* Baud rate to compare against. */ 62 } MAP; 63 64 MAP *cur, *maplist; 65 66 /* 67 * Syntax for -m: 68 * [port-type][test baudrate]:terminal-type 69 * The baud rate tests are: >, <, @, =, ! 70 */ 71 void 72 add_mapping(port, arg) 73 char *port, *arg; 74 { 75 MAP *mapp; 76 char *copy, *p, *termp; 77 78 copy = strdup(arg); 79 mapp = malloc((u_int)sizeof(MAP)); 80 if (copy == NULL || mapp == NULL) 81 err("%s", strerror(errno)); 82 mapp->next = NULL; 83 if (maplist == NULL) 84 cur = maplist = mapp; 85 else { 86 cur->next = mapp; 87 cur = mapp; 88 } 89 90 mapp->porttype = arg; 91 mapp->conditional = 0; 92 93 arg = strpbrk(arg, "><@=!:"); 94 95 if (arg == NULL) { /* [?]term */ 96 mapp->type = mapp->porttype; 97 mapp->porttype = NULL; 98 goto done; 99 } 100 101 if (arg == mapp->porttype) /* [><@=! baud]:term */ 102 termp = mapp->porttype = NULL; 103 else 104 termp = arg; 105 106 for (;; ++arg) /* Optional conditionals. */ 107 switch(*arg) { 108 case '<': 109 if (mapp->conditional & GT) 110 goto badmopt; 111 mapp->conditional |= LT; 112 break; 113 case '>': 114 if (mapp->conditional & LT) 115 goto badmopt; 116 mapp->conditional |= GT; 117 break; 118 case '@': 119 case '=': /* Not documented. */ 120 mapp->conditional |= EQ; 121 break; 122 case '!': 123 mapp->conditional |= NOT; 124 break; 125 default: 126 goto next; 127 } 128 129 next: if (*arg == ':') { 130 if (mapp->conditional) 131 goto badmopt; 132 ++arg; 133 } else { /* Optional baudrate. */ 134 arg = index(p = arg, ':'); 135 if (arg == NULL) 136 goto badmopt; 137 *arg++ = '\0'; 138 mapp->speed = baudrate(p); 139 } 140 141 if (*arg == NULL) /* Non-optional type. */ 142 goto badmopt; 143 144 mapp->type = arg; 145 146 /* Terminate porttype, if specified. */ 147 if (termp != NULL) 148 *termp = '\0'; 149 150 /* If a NOT conditional, reverse the test. */ 151 if (mapp->conditional & NOT) 152 mapp->conditional = ~mapp->conditional & (EQ | GT | LT); 153 154 /* If user specified a port with an option flag, set it. */ 155 done: if (port) { 156 if (mapp->porttype) 157 badmopt: err("illegal -m option format: %s", copy); 158 mapp->porttype = port; 159 } 160 161 #ifdef MAPDEBUG 162 (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); 163 (void)printf("type: %s\n", mapp->type); 164 (void)printf("conditional: "); 165 p = ""; 166 if (mapp->conditional & GT) { 167 (void)printf("GT"); 168 p = "/"; 169 } 170 if (mapp->conditional & EQ) { 171 (void)printf("%sEQ", p); 172 p = "/"; 173 } 174 if (mapp->conditional & LT) 175 (void)printf("%sLT", p); 176 (void)printf("\nspeed: %d\n", mapp->speed); 177 #endif 178 } 179 180 /* 181 * Return the type of terminal to use for a port of type 'type', as specified 182 * by the first applicable mapping in 'map'. If no mappings apply, return 183 * 'type'. 184 */ 185 char * 186 mapped(type) 187 char *type; 188 { 189 MAP *mapp; 190 int match; 191 192 for (mapp = maplist; mapp; mapp = mapp->next) 193 if (mapp->porttype == NULL || !strcmp(mapp->porttype, type)) { 194 switch (mapp->conditional) { 195 case 0: /* No test specified. */ 196 match = 1; 197 break; 198 case EQ: 199 match = (ospeed == mapp->speed); 200 break; 201 case GE: 202 match = (ospeed >= mapp->speed); 203 break; 204 case GT: 205 match = (ospeed > mapp->speed); 206 break; 207 case LE: 208 match = (ospeed <= mapp->speed); 209 break; 210 case LT: 211 match = (ospeed < mapp->speed); 212 break; 213 } 214 if (match) 215 return (mapp->type); 216 } 217 /* No match found; return given type. */ 218 return (type); 219 } 220 221 typedef struct speeds { 222 char *string; 223 int speed; 224 } SPEEDS; 225 226 SPEEDS speeds[] = { 227 "0", B0, 228 "50", B50, 229 "75", B75, 230 "110", B110, 231 "134", B134, 232 "134.5", B134, 233 "150", B150, 234 "200", B200, 235 "300", B300, 236 "600", B600, 237 "1200", B1200, 238 "1800", B1800, 239 "2400", B2400, 240 "4800", B4800, 241 "9600", B9600, 242 "19200", B19200, 243 "38400", B38400, 244 "exta", B19200, 245 "extb", B38400, 246 NULL 247 }; 248 249 int 250 baudrate(rate) 251 char *rate; 252 { 253 SPEEDS *sp; 254 255 /* The baudrate number can be preceded by a 'B', which is ignored. */ 256 if (*rate == 'B') 257 ++rate; 258 259 for (sp = speeds; sp->string; ++sp) 260 if (!strcasecmp(rate, sp->string)) 261 return (sp->speed); 262 err("unknown baud rate %s", rate); 263 /* NOTREACHED */ 264 } 265