aboutsummaryrefslogtreecommitdiffstats
path: root/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c335
1 files changed, 0 insertions, 335 deletions
diff --git a/parser.c b/parser.c
deleted file mode 100644
index 24b92094..00000000
--- a/parser.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/* $OpenBSD: parser.c,v 1.42 2020/01/06 11:02:38 gilles Exp $ */
-
-/*
- * Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <net/if.h>
-#include <arpa/inet.h>
-
-#include <err.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "parser.h"
-
-uint64_t text_to_evpid(const char *);
-uint32_t text_to_msgid(const char *);
-
-struct node {
- int type;
- const char *token;
- struct node *parent;
- TAILQ_ENTRY(node) entry;
- TAILQ_HEAD(, node) children;
- int (*cmd)(int, struct parameter*);
-};
-
-static struct node *root;
-
-static int text_to_sockaddr(struct sockaddr *, int, const char *);
-
-#define ARGVMAX 64
-
-int
-cmd_install(const char *pattern, int (*cmd)(int, struct parameter*))
-{
- struct node *node, *tmp;
- char *s, *str, *argv[ARGVMAX], **ap;
- int i, n;
-
- /* Tokenize */
- str = s = strdup(pattern);
- if (str == NULL)
- err(1, "strdup");
- n = 0;
- for (ap = argv; n < ARGVMAX && (*ap = strsep(&str, " \t")) != NULL;) {
- if (**ap != '\0') {
- ap++;
- n++;
- }
- }
- *ap = NULL;
-
- if (root == NULL) {
- root = calloc(1, sizeof (*root));
- TAILQ_INIT(&root->children);
- }
- node = root;
-
- for (i = 0; i < n; i++) {
- TAILQ_FOREACH(tmp, &node->children, entry) {
- if (!strcmp(tmp->token, argv[i])) {
- node = tmp;
- break;
- }
- }
- if (tmp == NULL) {
- tmp = calloc(1, sizeof (*tmp));
- TAILQ_INIT(&tmp->children);
- if (!strcmp(argv[i], "<str>"))
- tmp->type = P_STR;
- else if (!strcmp(argv[i], "<int>"))
- tmp->type = P_INT;
- else if (!strcmp(argv[i], "<msgid>"))
- tmp->type = P_MSGID;
- else if (!strcmp(argv[i], "<evpid>"))
- tmp->type = P_EVPID;
- else if (!strcmp(argv[i], "<routeid>"))
- tmp->type = P_ROUTEID;
- else if (!strcmp(argv[i], "<addr>"))
- tmp->type = P_ADDR;
- else
- tmp->type = P_TOKEN;
- tmp->token = strdup(argv[i]);
- tmp->parent = node;
- TAILQ_INSERT_TAIL(&node->children, tmp, entry);
- node = tmp;
- }
- }
-
- if (node->cmd)
- errx(1, "duplicate pattern: %s", pattern);
- node->cmd = cmd;
-
- free(s);
- return (n);
-}
-
-static int
-cmd_check(const char *str, struct node *node, struct parameter *res)
-{
- const char *e;
-
- switch (node->type) {
- case P_TOKEN:
- if (!strcmp(str, node->token))
- return (1);
- return (0);
-
- case P_STR:
- res->u.u_str = str;
- return (1);
-
- case P_INT:
- res->u.u_int = strtonum(str, INT_MIN, INT_MAX, &e);
- if (e)
- return (0);
- return (1);
-
- case P_MSGID:
- if (strlen(str) != 8)
- return (0);
- res->u.u_msgid = text_to_msgid(str);
- if (res->u.u_msgid == 0)
- return (0);
- return (1);
-
- case P_EVPID:
- if (strlen(str) != 16)
- return (0);
- res->u.u_evpid = text_to_evpid(str);
- if (res->u.u_evpid == 0)
- return (0);
- return (1);
-
- case P_ROUTEID:
- res->u.u_routeid = strtonum(str, 1, LLONG_MAX, &e);
- if (e)
- return (0);
- return (1);
-
- case P_ADDR:
- if (text_to_sockaddr((struct sockaddr *)&res->u.u_ss, PF_UNSPEC, str) == 0)
- return (1);
- return (0);
-
- default:
- errx(1, "bad token type: %d", node->type);
- return (0);
- }
-}
-
-int
-cmd_run(int argc, char **argv)
-{
- struct parameter param[ARGVMAX];
- struct node *node, *tmp, *stack[ARGVMAX], *best;
- int i, j, np;
-
- node = root;
- np = 0;
-
- for (i = 0; i < argc; i++) {
- TAILQ_FOREACH(tmp, &node->children, entry) {
- if (cmd_check(argv[i], tmp, &param[np])) {
- stack[i] = tmp;
- node = tmp;
- param[np].type = node->type;
- if (node->type != P_TOKEN)
- np++;
- break;
- }
- }
- if (tmp == NULL) {
- best = NULL;
- TAILQ_FOREACH(tmp, &node->children, entry) {
- if (tmp->type != P_TOKEN)
- continue;
- if (strstr(tmp->token, argv[i]) != tmp->token)
- continue;
- if (best)
- goto fail;
- best = tmp;
- }
- if (best == NULL)
- goto fail;
- stack[i] = best;
- node = best;
- param[np].type = node->type;
- if (node->type != P_TOKEN)
- np++;
- }
- }
-
- if (node->cmd == NULL)
- goto fail;
-
- return (node->cmd(np, np ? param : NULL));
-
-fail:
- if (TAILQ_FIRST(&node->children) == NULL) {
- fprintf(stderr, "invalid command\n");
- return (-1);
- }
-
- fprintf(stderr, "possibilities are:\n");
- TAILQ_FOREACH(tmp, &node->children, entry) {
- for (j = 0; j < i; j++)
- fprintf(stderr, "%s%s", j?" ":"", stack[j]->token);
- fprintf(stderr, "%s%s\n", i?" ":"", tmp->token);
- }
-
- return (-1);
-}
-
-int
-cmd_show_params(int argc, struct parameter *argv)
-{
- int i;
-
- for (i = 0; i < argc; i++) {
- switch(argv[i].type) {
- case P_STR:
- printf(" str:\"%s\"", argv[i].u.u_str);
- break;
- case P_INT:
- printf(" int:%d", argv[i].u.u_int);
- break;
- case P_MSGID:
- printf(" msgid:%08"PRIx32, argv[i].u.u_msgid);
- break;
- case P_EVPID:
- printf(" evpid:%016"PRIx64, argv[i].u.u_evpid);
- break;
- case P_ROUTEID:
- printf(" routeid:%016"PRIx64, argv[i].u.u_routeid);
- break;
- default:
- printf(" ???:%d", argv[i].type);
- }
- }
- printf ("\n");
- return (1);
-}
-
-static int
-text_to_sockaddr(struct sockaddr *sa, int family, const char *str)
-{
- struct in_addr ina;
- struct in6_addr in6a;
- struct sockaddr_in *in;
- struct sockaddr_in6 *in6;
- char *cp, *str2;
- const char *errstr;
-
- switch (family) {
- case PF_UNSPEC:
- if (text_to_sockaddr(sa, PF_INET, str) == 0)
- return (0);
- return text_to_sockaddr(sa, PF_INET6, str);
-
- case PF_INET:
- if (inet_pton(PF_INET, str, &ina) != 1)
- return (-1);
-
- in = (struct sockaddr_in *)sa;
- memset(in, 0, sizeof *in);
- in->sin_len = sizeof(struct sockaddr_in);
- in->sin_family = PF_INET;
- in->sin_addr.s_addr = ina.s_addr;
- return (0);
-
- case PF_INET6:
- cp = strchr(str, SCOPE_DELIMITER);
- if (cp) {
- str2 = strdup(str);
- if (str2 == NULL)
- return (-1);
- str2[cp - str] = '\0';
- if (inet_pton(PF_INET6, str2, &in6a) != 1) {
- free(str2);
- return (-1);
- }
- cp++;
- free(str2);
- } else if (inet_pton(PF_INET6, str, &in6a) != 1)
- return (-1);
-
- in6 = (struct sockaddr_in6 *)sa;
- memset(in6, 0, sizeof *in6);
- in6->sin6_len = sizeof(struct sockaddr_in6);
- in6->sin6_family = PF_INET6;
- in6->sin6_addr = in6a;
-
- if (cp == NULL)
- return (0);
-
- if (IN6_IS_ADDR_LINKLOCAL(&in6a) ||
- IN6_IS_ADDR_MC_LINKLOCAL(&in6a) ||
- IN6_IS_ADDR_MC_INTFACELOCAL(&in6a))
- if ((in6->sin6_scope_id = if_nametoindex(cp)))
- return (0);
-
- in6->sin6_scope_id = strtonum(cp, 0, UINT32_MAX, &errstr);
- if (errstr)
- return (-1);
- return (0);
-
- default:
- break;
- }
-
- return (-1);
-}