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