This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.bin / tset / map.c
CommitLineData
15637ed4
RG
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
35static char sccsid[] = "@(#)map.c 5.2 (Berkeley) 12/24/91";
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,
24957200
DG
245#ifdef B57600
246 "57600", B57600,
247#endif
248#ifdef B115200
249 "115200", B115200,
250#endif
15637ed4
RG
251 NULL
252};
253
254int
255baudrate(rate)
256 char *rate;
257{
258 SPEEDS *sp;
259
260 /* The baudrate number can be preceded by a 'B', which is ignored. */
261 if (*rate == 'B')
262 ++rate;
263
264 for (sp = speeds; sp->string; ++sp)
265 if (!strcasecmp(rate, sp->string))
266 return (sp->speed);
267 err("unknown baud rate %s", rate);
268 /* NOTREACHED */
269}