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