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