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