152052Sbostic /*-
2*63080Sbostic * Copyright (c) 1991, 1993
3*63080Sbostic * The Regents of the University of California. All rights reserved.
452052Sbostic *
552052Sbostic * %sccs.include.redist.c%
652052Sbostic */
752052Sbostic
852052Sbostic #ifndef lint
9*63080Sbostic static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 06/09/93";
1052052Sbostic #endif /* not lint */
1152052Sbostic
1252052Sbostic #include <sys/types.h>
1352052Sbostic #include <termios.h>
1452052Sbostic #include <errno.h>
1552052Sbostic #include <stdlib.h>
1652052Sbostic #include <string.h>
1752052Sbostic #include "extern.h"
1852052Sbostic
1952052Sbostic int baudrate __P((char *));
2052052Sbostic
2152052Sbostic /* Baud rate conditionals for mapping. */
2252052Sbostic #define GT 0x01
2352052Sbostic #define EQ 0x02
2452052Sbostic #define LT 0x04
2552052Sbostic #define NOT 0x08
2652052Sbostic #define GE (GT | EQ)
2752052Sbostic #define LE (LT | EQ)
2852052Sbostic
2952052Sbostic typedef struct map {
3052052Sbostic struct map *next; /* Linked list of maps. */
3152052Sbostic char *porttype; /* Port type, or "" for any. */
3252052Sbostic char *type; /* Terminal type to select. */
3352052Sbostic int conditional; /* Baud rate conditionals bitmask. */
3452052Sbostic int speed; /* Baud rate to compare against. */
3552052Sbostic } MAP;
3652052Sbostic
3752052Sbostic MAP *cur, *maplist;
3852052Sbostic
3952052Sbostic /*
4052052Sbostic * Syntax for -m:
4152052Sbostic * [port-type][test baudrate]:terminal-type
4252052Sbostic * The baud rate tests are: >, <, @, =, !
4352052Sbostic */
4452052Sbostic void
add_mapping(port,arg)4552064Sbostic add_mapping(port, arg)
4652064Sbostic char *port, *arg;
4752052Sbostic {
4852052Sbostic MAP *mapp;
4952052Sbostic char *copy, *p, *termp;
5052052Sbostic
5152052Sbostic copy = strdup(arg);
5252052Sbostic mapp = malloc((u_int)sizeof(MAP));
5352052Sbostic if (copy == NULL || mapp == NULL)
5452052Sbostic err("%s", strerror(errno));
5552052Sbostic mapp->next = NULL;
5652052Sbostic if (maplist == NULL)
5752052Sbostic cur = maplist = mapp;
5852052Sbostic else {
5952052Sbostic cur->next = mapp;
6052052Sbostic cur = mapp;
6152052Sbostic }
6252052Sbostic
6352052Sbostic mapp->porttype = arg;
6452052Sbostic mapp->conditional = 0;
6552052Sbostic
6652052Sbostic arg = strpbrk(arg, "><@=!:");
6752052Sbostic
6852052Sbostic if (arg == NULL) { /* [?]term */
6952052Sbostic mapp->type = mapp->porttype;
7052052Sbostic mapp->porttype = NULL;
7152064Sbostic goto done;
7252052Sbostic }
7352052Sbostic
7452052Sbostic if (arg == mapp->porttype) /* [><@=! baud]:term */
7552052Sbostic termp = mapp->porttype = NULL;
7652052Sbostic else
7752052Sbostic termp = arg;
7852052Sbostic
7952052Sbostic for (;; ++arg) /* Optional conditionals. */
8052052Sbostic switch(*arg) {
8152052Sbostic case '<':
8252052Sbostic if (mapp->conditional & GT)
8352052Sbostic goto badmopt;
8452052Sbostic mapp->conditional |= LT;
8552052Sbostic break;
8652052Sbostic case '>':
8752052Sbostic if (mapp->conditional & LT)
8852052Sbostic goto badmopt;
8952052Sbostic mapp->conditional |= GT;
9052052Sbostic break;
9152052Sbostic case '@':
9252052Sbostic case '=': /* Not documented. */
9352052Sbostic mapp->conditional |= EQ;
9452052Sbostic break;
9552052Sbostic case '!':
9652052Sbostic mapp->conditional |= NOT;
9752052Sbostic break;
9852052Sbostic default:
9952052Sbostic goto next;
10052052Sbostic }
10152052Sbostic
10252052Sbostic next: if (*arg == ':') {
10352052Sbostic if (mapp->conditional)
10452052Sbostic goto badmopt;
10552052Sbostic ++arg;
10652052Sbostic } else { /* Optional baudrate. */
10752052Sbostic arg = index(p = arg, ':');
10852052Sbostic if (arg == NULL)
10952052Sbostic goto badmopt;
11052052Sbostic *arg++ = '\0';
11152052Sbostic mapp->speed = baudrate(p);
11252052Sbostic }
11352052Sbostic
11452052Sbostic if (*arg == NULL) /* Non-optional type. */
11552064Sbostic goto badmopt;
11652052Sbostic
11752052Sbostic mapp->type = arg;
11852052Sbostic
11952052Sbostic /* Terminate porttype, if specified. */
12052052Sbostic if (termp != NULL)
12152052Sbostic *termp = '\0';
12252052Sbostic
12352052Sbostic /* If a NOT conditional, reverse the test. */
12452052Sbostic if (mapp->conditional & NOT)
12552052Sbostic mapp->conditional = ~mapp->conditional & (EQ | GT | LT);
12652052Sbostic
12752064Sbostic /* If user specified a port with an option flag, set it. */
12852064Sbostic done: if (port) {
12952064Sbostic if (mapp->porttype)
13052064Sbostic badmopt: err("illegal -m option format: %s", copy);
13152064Sbostic mapp->porttype = port;
13252064Sbostic }
13352064Sbostic
13452052Sbostic #ifdef MAPDEBUG
13552064Sbostic (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY");
13652052Sbostic (void)printf("type: %s\n", mapp->type);
13752052Sbostic (void)printf("conditional: ");
13852052Sbostic p = "";
13952052Sbostic if (mapp->conditional & GT) {
14052052Sbostic (void)printf("GT");
14152052Sbostic p = "/";
14252052Sbostic }
14352052Sbostic if (mapp->conditional & EQ) {
14452052Sbostic (void)printf("%sEQ", p);
14552052Sbostic p = "/";
14652052Sbostic }
14752052Sbostic if (mapp->conditional & LT)
14852052Sbostic (void)printf("%sLT", p);
14952052Sbostic (void)printf("\nspeed: %d\n", mapp->speed);
15052052Sbostic #endif
15152052Sbostic }
15252052Sbostic
15352052Sbostic /*
15452052Sbostic * Return the type of terminal to use for a port of type 'type', as specified
15552052Sbostic * by the first applicable mapping in 'map'. If no mappings apply, return
15652052Sbostic * 'type'.
15752052Sbostic */
15852052Sbostic char *
mapped(type)15952052Sbostic mapped(type)
16052052Sbostic char *type;
16152052Sbostic {
16252052Sbostic MAP *mapp;
16352052Sbostic int match;
16452052Sbostic
16552052Sbostic for (mapp = maplist; mapp; mapp = mapp->next)
16652052Sbostic if (mapp->porttype == NULL || !strcmp(mapp->porttype, type)) {
16752052Sbostic switch (mapp->conditional) {
16852052Sbostic case 0: /* No test specified. */
16952052Sbostic match = 1;
17052052Sbostic break;
17152052Sbostic case EQ:
17252052Sbostic match = (ospeed == mapp->speed);
17352052Sbostic break;
17452052Sbostic case GE:
17552052Sbostic match = (ospeed >= mapp->speed);
17652052Sbostic break;
17752052Sbostic case GT:
17852052Sbostic match = (ospeed > mapp->speed);
17952052Sbostic break;
18052052Sbostic case LE:
18152052Sbostic match = (ospeed <= mapp->speed);
18252052Sbostic break;
18352052Sbostic case LT:
18452052Sbostic match = (ospeed < mapp->speed);
18552052Sbostic break;
18652052Sbostic }
18752052Sbostic if (match)
18852052Sbostic return (mapp->type);
18952052Sbostic }
19052052Sbostic /* No match found; return given type. */
19152052Sbostic return (type);
19252052Sbostic }
19352052Sbostic
19452052Sbostic typedef struct speeds {
19552052Sbostic char *string;
19652052Sbostic int speed;
19752052Sbostic } SPEEDS;
19852052Sbostic
19952052Sbostic SPEEDS speeds[] = {
20052052Sbostic "0", B0,
20152052Sbostic "50", B50,
20252052Sbostic "75", B75,
20352052Sbostic "110", B110,
20452052Sbostic "134", B134,
20552052Sbostic "134.5", B134,
20652052Sbostic "150", B150,
20752052Sbostic "200", B200,
20852052Sbostic "300", B300,
20952052Sbostic "600", B600,
21052052Sbostic "1200", B1200,
21152052Sbostic "1800", B1800,
21252052Sbostic "2400", B2400,
21352052Sbostic "4800", B4800,
21452052Sbostic "9600", B9600,
21552052Sbostic "19200", B19200,
21652052Sbostic "38400", B38400,
21752052Sbostic "exta", B19200,
21852052Sbostic "extb", B38400,
21952052Sbostic NULL
22052052Sbostic };
22152052Sbostic
22252052Sbostic int
baudrate(rate)22352052Sbostic baudrate(rate)
22452052Sbostic char *rate;
22552052Sbostic {
22652052Sbostic SPEEDS *sp;
22752052Sbostic
22852052Sbostic /* The baudrate number can be preceded by a 'B', which is ignored. */
22952052Sbostic if (*rate == 'B')
23052052Sbostic ++rate;
23152052Sbostic
23252052Sbostic for (sp = speeds; sp->string; ++sp)
23352052Sbostic if (!strcasecmp(rate, sp->string))
23452052Sbostic return (sp->speed);
23552052Sbostic err("unknown baud rate %s", rate);
23652052Sbostic /* NOTREACHED */
23752052Sbostic }
238