Rewrite and simplify dhcpleasectl(8).
authorflorian <florian@openbsd.org>
Wed, 15 Sep 2021 15:18:23 +0000 (15:18 +0000)
committerflorian <florian@openbsd.org>
Wed, 15 Sep 2021 15:18:23 +0000 (15:18 +0000)
With this

dhcpleasectl em0

does the same as

dhclient em0

used to do. To please people's muscle memory one can be aliased to the other.

earlier version OK benno

with lots of help massaging the output & OK deraadt

sbin/dhcpleased/engine.c
usr.sbin/dhcpleasectl/Makefile
usr.sbin/dhcpleasectl/dhcpleasectl.8
usr.sbin/dhcpleasectl/dhcpleasectl.c
usr.sbin/dhcpleasectl/parser.c [deleted file]
usr.sbin/dhcpleasectl/parser.h [deleted file]

index 3e28c63..40574ef 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: engine.c,v 1.26 2021/09/15 06:08:01 florian Exp $     */
+/*     $OpenBSD: engine.c,v 1.27 2021/09/15 15:18:23 florian Exp $     */
 
 /*
  * Copyright (c) 2017, 2021 Florian Obser <florian@openbsd.org>
@@ -591,16 +591,11 @@ engine_showinfo_ctl(struct imsg *imsg, uint32_t if_index)
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_INTERFACE_INFO:
-               if (if_index == 0) {
-                       LIST_FOREACH (iface, &dhcpleased_interfaces, entries)
-                               send_interface_info(iface, imsg->hdr.pid);
-               } else {
-                       if ((iface = get_dhcpleased_iface_by_id(if_index)) !=
-                           NULL)
-                               send_interface_info(iface, imsg->hdr.pid);
-               }
-               engine_imsg_compose_frontend(IMSG_CTL_END, imsg->hdr.pid, NULL,
-                   0);
+               if ((iface = get_dhcpleased_iface_by_id(if_index)) != NULL)
+                       send_interface_info(iface, imsg->hdr.pid);
+               else
+                       engine_imsg_compose_frontend(IMSG_CTL_END,
+                           imsg->hdr.pid, NULL, 0);
                break;
        default:
                log_debug("%s: error handling imsg", __func__);
index af564dd..dbd0a96 100644 (file)
@@ -1,7 +1,7 @@
-#      $OpenBSD: Makefile,v 1.1 2021/02/26 16:16:37 florian Exp $
+#      $OpenBSD: Makefile,v 1.2 2021/09/15 15:18:23 florian Exp $
 
 PROG=  dhcpleasectl
-SRCS=  dhcpleasectl.c parser.c
+SRCS=  dhcpleasectl.c
 
 MAN=   dhcpleasectl.8
 
index e23b66d..73fe181 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: dhcpleasectl.8,v 1.2 2021/08/23 18:09:05 florian Exp $
+.\"    $OpenBSD: dhcpleasectl.8,v 1.3 2021/09/15 15:18:23 florian Exp $
 .\"
 .\" Copyright (c) 2021 Florian Obser <florian@openbsd.org>
 .\" Copyright (c) 2016 Kenneth R Westerback <kwesterback@gmail.com>
@@ -16,7 +16,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: August 23 2021 $
+.Dd $Mdocdate: September 15 2021 $
 .Dt DHCPLEASECTL 8
 .Os
 .Sh NAME
 .Nd control the dhcpleased daemon
 .Sh SYNOPSIS
 .Nm
+.Op Fl l
 .Op Fl s Ar socket
-.Ar command
-.Op Ar argument ...
+.Op Fl w Ar maxwait
+.Ar interfacename
 .Sh DESCRIPTION
 The
 .Nm
-program controls the
+program instructs the
 .Xr dhcpleased 8
-daemon.
+daemon to request a new lease.
 .Pp
 The following options are available:
 .Bl -tag -width Ds
+.It Fl l
+List the configured lease on
+.Ar interfacename
+instead of requesting a new lease.
 .It Fl s Ar socket
 Use
 .Ar socket
@@ -43,27 +48,15 @@ instead of the default
 .Pa /dev/dhcpleased.sock
 to communicate with
 .Xr dhcpleased 8 .
-.El
-.Pp
-The following commands are available:
-.Bl -tag -width Ds
-.It Cm log brief
-Disable verbose debug logging.
-.It Cm log verbose
-Enable verbose debug logging.
-.It Cm send request Ar interfacename
-Send a DHCP request on interface
-.Ar interfacename
-to force a renew of the lease.
-.It Cm show interface Op Ar interfacename
-Display status about network interfaces.
-If
+.It Fl w Ar maxwait
+Specify the maximum number of seconds to wait for
 .Ar interfacename
-is specified, only information relative to
-.Ar interfacename
-is shown.
-Otherwise information on all interfaces is shown.
+to be configured.
+The default is to wait 10 seconds unless
+.Fl l
+is specified.
 .El
+.Pp
 .Sh FILES
 .Bl -tag -width "/dev/dhcpleased.sockXX" -compact
 .It Pa /dev/dhcpleased.sock
index 0edabf1..786208a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpleasectl.c,v 1.5 2021/07/26 09:26:36 florian Exp $        */
+/*     $OpenBSD: dhcpleasectl.c,v 1.6 2021/09/15 15:18:23 florian Exp $        */
 
 /*
  * Copyright (c) 2021 Florian Obser <florian@openbsd.org>
  */
 
 #include <sys/types.h>
+#include <sys/ioctl.h>
 #include <sys/queue.h>
 #include <sys/socket.h>
+#include <sys/time.h>
 #include <sys/un.h>
+
 #include <arpa/inet.h>
 
 #include <net/if.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
 
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
-#include <netinet6/nd6.h>
 
 #include <err.h>
 #include <errno.h>
 #include <event.h>
 #include <imsg.h>
-#include <netdb.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <unistd.h>
 
 #include "dhcpleased.h"
-#include "frontend.h"
-#include "parser.h"
 
 __dead void     usage(void);
-int             show_interface_msg(struct imsg *);
+void            show_interface_msg(struct ctl_engine_info *);
 
 struct imsgbuf *ibuf;
 
@@ -57,7 +56,7 @@ usage(void)
 {
        extern char *__progname;
 
-       fprintf(stderr, "usage: %s [-s socket] command [argument ...]\n",
+       fprintf(stderr, "usage: %s [-l] [-s socket] [-w seconds] interface\n",
            __progname);
        exit(1);
 }
@@ -66,20 +65,31 @@ int
 main(int argc, char *argv[])
 {
        struct sockaddr_un       sun;
-       struct parse_result     *res;
        struct imsg              imsg;
+       struct ctl_engine_info  *cei;
        int                      ctl_sock;
-       int                      done = 0;
-       int                      n, verbose = 0;
-       int                      ch;
+       int                      n, lFlag = 0, maxwait_set = 0, didot = 0;
+       int                      ch, if_index = 0, maxwait = 10, bound = 0;
        char                    *sockname;
+       const char              *errstr;
 
        sockname = _PATH_DHCPLEASED_SOCKET;
-       while ((ch = getopt(argc, argv, "s:")) != -1) {
+       while ((ch = getopt(argc, argv, "ls:w:")) != -1) {
                switch (ch) {
+               case 'l':
+                       lFlag = 1;
+                       break;
                case 's':
                        sockname = optarg;
                        break;
+               case 'w':
+                       maxwait_set = 1;
+                       maxwait = strtonum(optarg, 1, INT_MAX, &errstr);
+                       if (errstr)
+                               errx(1, "maxwait value is %s: %s",
+                                   errstr, optarg);
+                       break;
+
                default:
                        usage();
                }
@@ -87,12 +97,48 @@ main(int argc, char *argv[])
        argc -= optind;
        argv += optind;
 
-       if (pledge("stdio unix", NULL) == -1)
-               err(1, "pledge");
+       if (argc != 1)
+               usage();
 
-       /* Parse command line. */
-       if ((res = parse(argc, argv)) == NULL)
-               exit(1);
+       if ((if_index = if_nametoindex(argv[0])) == 0)
+               errx(1, "unknown interface");
+
+       if (!lFlag) {
+               struct ifreq     ifr, ifr_x;
+               int              ioctl_sock;
+
+               if ((ioctl_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+                       err(1, NULL);
+
+               strlcpy(ifr.ifr_name, argv[0], sizeof(ifr.ifr_name));
+               strlcpy(ifr_x.ifr_name, argv[0], sizeof(ifr.ifr_name));
+
+               if (ioctl(ioctl_sock, SIOCGIFFLAGS, &ifr) == -1)
+                       err(1, "SIOCGIFFLAGS");
+
+               if (ioctl(ioctl_sock, SIOCGIFXFLAGS, &ifr_x) == -1)
+                       err(1, "SIOCGIFFLAGS");
+
+               if (!(ifr.ifr_flags & IFF_UP) ||
+                   !(ifr_x.ifr_flags & IFXF_AUTOCONF4)) {
+                       if (geteuid())
+                               errx(1, "need root privileges");
+               }
+
+               if (!(ifr.ifr_flags & IFF_UP)) {
+                       ifr.ifr_flags |= IFF_UP;
+                       if (ioctl(ioctl_sock, SIOCSIFFLAGS, &ifr) == -1)
+                               err(1, "SIOCSIFFLAGS");
+               }
+               if (!(ifr_x.ifr_flags & IFXF_AUTOCONF4)) {
+                       ifr_x.ifr_flags |= IFXF_AUTOCONF4;
+                       if (ioctl(ioctl_sock, SIOCSIFXFLAGS, &ifr_x) == -1)
+                               err(1, "SIOCSIFFLAGS");
+               }
+       }
+
+       if (lFlag && !maxwait_set)
+               maxwait = 0;
 
        /* Connect to control socket. */
        if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
@@ -111,63 +157,60 @@ main(int argc, char *argv[])
        if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
                err(1, NULL);
        imsg_init(ibuf, ctl_sock);
-       done = 0;
-
-       /* Process user request. */
-       switch (res->action) {
-       case RELOAD:
-               imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
-               printf("reload request sent.\n");
-               done = 1;
-               break;
-       case LOG_VERBOSE:
-               verbose = 1;
-               /* FALLTHROUGH */
-       case LOG_BRIEF:
-               imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1,
-                   &verbose, sizeof(verbose));
-               printf("logging request sent.\n");
-               done = 1;
-               break;
-       case SHOW_INTERFACE:
-               imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE_INFO, 0, 0, -1,
-                   &res->if_index, sizeof(res->if_index));
-               break;
-       case SEND_REQUEST:
+
+       if (!lFlag) {
                imsg_compose(ibuf, IMSG_CTL_SEND_REQUEST, 0, 0, -1,
-                   &res->if_index, sizeof(res->if_index));
-               done = 1;
-               break;
-       default:
-               usage();
+                   &if_index, sizeof(if_index));
+               while (ibuf->w.queued)
+                       if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
+                               err(1, "write error");
+
        }
 
-       while (ibuf->w.queued)
-               if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
-                       err(1, "write error");
+       for(;;) {
+               imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE_INFO, 0, 0, -1,
+                   &if_index, sizeof(if_index));
+
+               while (ibuf->w.queued)
+                       if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
+                               err(1, "write error");
+
 
-       while (!done) {
                if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
                        errx(1, "imsg_read error");
                if (n == 0)
                        errx(1, "pipe closed");
 
-               while (!done) {
-                       if ((n = imsg_get(ibuf, &imsg)) == -1)
-                               errx(1, "imsg_get error");
-                       if (n == 0)
-                               break;
+               if ((n = imsg_get(ibuf, &imsg)) == -1)
+                       errx(1, "imsg_get error");
+               if (n == 0)
+                       break;
 
-                       switch (res->action) {
-                       case SHOW_INTERFACE:
-                               done = show_interface_msg(&imsg);
-                               break;
-                       default:
+               if (imsg.hdr.type == IMSG_CTL_END) {
+                       if (lFlag)
+                               errx(1, "non-autoconf interface %s", argv[0]);
+                       else if (--maxwait < 0)
                                break;
-                       }
+                       else
+                               continue;
+               }
+
+               cei = imsg.data;
+               if (strcmp(cei->state, "Bound") == 0)
+                       bound = 1;
 
-                       imsg_free(&imsg);
+               if (bound || --maxwait < 0) {
+                       if (didot)
+                               putchar('\n');
+                       show_interface_msg(cei);
+                       break;
+               } else {
+                       didot = 1;
+                       putchar('.');
+                       fflush(stdout);
                }
+               imsg_free(&imsg);
+               sleep(1);
        }
        close(ctl_sock);
        free(ibuf);
@@ -175,108 +218,102 @@ main(int argc, char *argv[])
        return (0);
 }
 
-int
-show_interface_msg(struct imsg *imsg)
+void
+show_interface_msg(struct ctl_engine_info *cei)
 {
-       static int               if_count = 0;
-       struct ctl_engine_info  *cei;
        struct timespec          now, diff;
-       time_t                   y, d, h, m, s;
+       time_t                   d, h, m, s;
        int                      i;
        char                     buf[IF_NAMESIZE], *bufp;
        char                     ipbuf[INET_ADDRSTRLEN];
        char                     maskbuf[INET_ADDRSTRLEN];
        char                     gwbuf[INET_ADDRSTRLEN];
 
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_SHOW_INTERFACE_INFO:
-               cei = imsg->data;
-
-               if (if_count++ > 0)
-                       printf("\n");
-
-               bufp = if_indextoname(cei->if_index, buf);
-               printf("%s [%s]:\n", bufp != NULL ? bufp : "unknown",
-                   cei->state);
+       bufp = if_indextoname(cei->if_index, buf);
+       printf("%s [%s]\n", bufp != NULL ? bufp : "unknown", cei->state);
+       memset(ipbuf, 0, sizeof(ipbuf));
+       if (cei->requested_ip.s_addr != INADDR_ANY) {
+               clock_gettime(CLOCK_MONOTONIC, &now);
+               timespecsub(&now, &cei->request_time, &diff);
                memset(ipbuf, 0, sizeof(ipbuf));
-               if (cei->server_identifier.s_addr != INADDR_ANY) {
-                       if (inet_ntop(AF_INET, &cei->server_identifier, ipbuf,
-                           sizeof(ipbuf)) == NULL)
-                               ipbuf[0] = '\0';
-               } else if (cei->dhcp_server.s_addr != INADDR_ANY) {
-                       if (inet_ntop(AF_INET, &cei->dhcp_server, ipbuf,
-                           sizeof(ipbuf)) == NULL)
-                               ipbuf[0] = '\0';
-               }
-               if (ipbuf[0] != '\0')
-                       printf("\tserver: %s\n", ipbuf);
-               if (cei->requested_ip.s_addr != INADDR_ANY) {
-                       clock_gettime(CLOCK_MONOTONIC, &now);
-                       timespecsub(&now, &cei->request_time, &diff);
-                       memset(ipbuf, 0, sizeof(ipbuf));
-                       memset(maskbuf, 0, sizeof(maskbuf));
-                       memset(gwbuf, 0, sizeof(gwbuf));
-                       if (inet_ntop(AF_INET, &cei->requested_ip, ipbuf,
+               memset(maskbuf, 0, sizeof(maskbuf));
+               memset(gwbuf, 0, sizeof(gwbuf));
+               if (inet_ntop(AF_INET, &cei->requested_ip, ipbuf,
+                   sizeof(ipbuf)) == NULL)
+                       ipbuf[0] = '\0';
+               if (inet_ntop(AF_INET, &cei->mask, maskbuf, sizeof(maskbuf))
+                   == NULL)
+                       maskbuf[0] = '\0';
+               printf("\tinet %s netmask %s\n", ipbuf, maskbuf);
+               for (i = 0; i < cei->routes_len; i++) {
+                       if (inet_ntop(AF_INET, &cei->routes[i].dst, ipbuf,
                            sizeof(ipbuf)) == NULL)
                                ipbuf[0] = '\0';
-                       if (inet_ntop(AF_INET, &cei->mask, maskbuf,
+                       if (inet_ntop(AF_INET, &cei->routes[i].mask, maskbuf,
                            sizeof(maskbuf)) == NULL)
                                maskbuf[0] = '\0';
-                       printf("\t    IP: %s/%s\n", ipbuf, maskbuf);
-                       for (i = 0; i < cei->routes_len; i++) {
-                               if (inet_ntop(AF_INET, &cei->routes[i].dst,
+                       if (inet_ntop(AF_INET, &cei->routes[i].gw,
+                           gwbuf, sizeof(gwbuf)) == NULL)
+                               gwbuf[0] = '\0';
+
+                       if (cei->routes[i].dst.s_addr == INADDR_ANY
+                           && cei->routes[i].mask.s_addr == INADDR_ANY)
+                               printf("\tdefault gateway %s\n", gwbuf);
+                       else
+                               printf("\troute %s/%d gateway %s\n",
+                                   ipbuf, 33 -
+                                   ffs(ntohl(cei->routes[i].mask.s_addr)),
+                                   gwbuf);
+               }
+               if (cei->nameservers[0].s_addr != INADDR_ANY) {
+                       printf("\tnameservers");
+                       for (i = 0; i < MAX_RDNS_COUNT &&
+                                cei->nameservers[i].s_addr != INADDR_ANY;
+                            i++) {
+                               if (inet_ntop(AF_INET, &cei->nameservers[i],
                                    ipbuf, sizeof(ipbuf)) == NULL)
-                                       ipbuf[0] = '\0';
-                               if (inet_ntop(AF_INET, &cei->routes[i].mask,
-                                   maskbuf, sizeof(maskbuf)) == NULL)
-                                       maskbuf[0] = '\0';
-                               if (inet_ntop(AF_INET, &cei->routes[i].gw,
-                                   gwbuf, sizeof(gwbuf)) == NULL)
-                                       gwbuf[0] = '\0';
-
-                               printf("\t%s\t%s/%s - %s\n", i == 0 ? "routes:"
-                                   : "", ipbuf, maskbuf, gwbuf);
-                       }
-                       if (cei->nameservers[0].s_addr != INADDR_ANY) {
-                               printf("\t   DNS:");
-                               for (i = 0; i < MAX_RDNS_COUNT &&
-                                   cei->nameservers[i].s_addr != INADDR_ANY;
-                                   i++) {
-                                       if (inet_ntop(AF_INET,
-                                           &cei->nameservers[i], ipbuf,
-                                           sizeof(ipbuf)) == NULL)
-                                               continue;
-                                       printf(" %s", ipbuf);
-                               }
-                               printf("\n");
+                                       continue;
+                               printf(" %s", ipbuf);
                        }
-                       s = cei->lease_time - diff.tv_sec;
-                       if (s < 0)
-                               s = 0;
-                       y = s / 31556926; s -= y * 31556926;
-                       d = s / 86400; s -= d * 86400;
-                       h = s / 3600; s -= h * 3600;
-                       m = s / 60; s -= m * 60;
-
-                       printf("\t lease: ");
-                       if (y > 0)
-                               printf("%lldy ", y);
-                       if (d > 0)
-                               printf("%lldd ", d);
-                       if (h > 0)
-                               printf("%lldh ", h);
-                       if (m > 0)
-                               printf("%lldm ", m);
-                       if (s > 0)
-                               printf("%llds ", s);
                        printf("\n");
                }
-               break;
-       case IMSG_CTL_END:
-               return (1);
-       default:
-               break;
+               s = cei->lease_time - diff.tv_sec;
+               if (s < 0)
+                       s = 0;
+
+               if ( s > 86400 ) {
+                       d = s / 86400;
+
+                       /* round up */
+                       if (s - d * 86400 > 43200)
+                               d++;
+                       printf("\tlease %lld days\n", d);
+               } else if (s > 3600) {
+                       h = s / 3600;
+
+                       /* round up */
+                       if (s - h * 3600 > 1800)
+                               h++;
+                       printf("\tlease %lld hours\n", h);
+               } else if (s > 60) {
+                       m = s / 60;
+
+                       /* round up */
+                       if (s - m * 60 > 30)
+                               m++;
+                       printf("\tlease %lld minutes\n", m);
+               } else
+                       printf("\tlease %lld seconds\n", s);
        }
-
-       return (0);
+       if (cei->server_identifier.s_addr != INADDR_ANY) {
+               if (inet_ntop(AF_INET, &cei->server_identifier, ipbuf,
+                   sizeof(ipbuf)) == NULL)
+                       ipbuf[0] = '\0';
+       } else if (cei->dhcp_server.s_addr != INADDR_ANY) {
+               if (inet_ntop(AF_INET, &cei->dhcp_server, ipbuf, sizeof(ipbuf))
+                   == NULL)
+                       ipbuf[0] = '\0';
+       }
+       if (ipbuf[0] != '\0')
+               printf("\tdhcp server %s\n", ipbuf);
 }
diff --git a/usr.sbin/dhcpleasectl/parser.c b/usr.sbin/dhcpleasectl/parser.c
deleted file mode 100644 (file)
index c77621e..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*     $OpenBSD: parser.c,v 1.2 2021/07/26 09:26:36 florian Exp $      */
-
-/*
- * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
- * Copyright (c) 2003, 2004 Henning Brauer <henning@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 <arpa/inet.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <err.h>
-#include <errno.h>
-#include <event.h>
-#include <imsg.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "dhcpleased.h"
-#include "parser.h"
-
-enum token_type {
-       NOTOKEN,
-       ENDTOKEN,
-       INTERFACENAME,
-       KEYWORD
-};
-
-struct token {
-       enum token_type          type;
-       const char              *keyword;
-       int                      value;
-       const struct token      *next;
-};
-
-static const struct token t_main[];
-static const struct token t_log[];
-static const struct token t_show[];
-static const struct token t_show_interface[];
-static const struct token t_send[];
-static const struct token t_send_request[];
-
-static const struct token t_main[] = {
-       {KEYWORD,       "reload",       RELOAD,         NULL},
-       {KEYWORD,       "show",         SHOW,           t_show},
-       {KEYWORD,       "log",          NONE,           t_log},
-       {KEYWORD,       "send",         NONE,           t_send},
-       {ENDTOKEN,      "",             NONE,           NULL}
-};
-
-static const struct token t_log[] = {
-       {KEYWORD,       "verbose",      LOG_VERBOSE,    NULL},
-       {KEYWORD,       "brief",        LOG_BRIEF,      NULL},
-       {ENDTOKEN,      "",             NONE,           NULL}
-};
-
-static const struct token t_show[] = {
-       {KEYWORD,       "interface",    SHOW_INTERFACE,  t_show_interface},
-       {ENDTOKEN,      "",             NONE,           NULL}
-};
-
-static const struct token t_send[] = {
-       {KEYWORD,       "request",      SEND_REQUEST,   t_send_request},
-       {ENDTOKEN,      "",             NONE,           NULL}
-};
-static const struct token t_send_request[] = {
-       {INTERFACENAME, "",             SEND_REQUEST,   NULL},
-       {ENDTOKEN,      "",             NONE,           NULL}
-};
-
-static const struct token t_show_interface[] = {
-       {NOTOKEN,       "",             NONE,           NULL},
-       {INTERFACENAME, "",             SHOW_INTERFACE, NULL},
-       {ENDTOKEN,      "",             NONE,           NULL}
-};
-
-static const struct token *match_token(const char *, const struct token *,
-    struct parse_result *);
-static void show_valid_args(const struct token *);
-
-struct parse_result *
-parse(int argc, char *argv[])
-{
-       static struct parse_result      res;
-       const struct token      *table = t_main;
-       const struct token      *match;
-
-       memset(&res, 0, sizeof(res));
-
-       while (argc >= 0) {
-               if ((match = match_token(argv[0], table, &res)) == NULL) {
-                       fprintf(stderr, "valid commands/args:\n");
-                       show_valid_args(table);
-                       return (NULL);
-               }
-
-               argc--;
-               argv++;
-
-               if (match->type == NOTOKEN || match->next == NULL)
-                       break;
-
-               table = match->next;
-       }
-
-       if (argc > 0) {
-               fprintf(stderr, "superfluous argument: %s\n", argv[0]);
-               return (NULL);
-       }
-
-       return (&res);
-}
-
-static const struct token *
-match_token(const char *word, const struct token *table,
-    struct parse_result *res)
-{
-       u_int                    i, match;
-       const struct token      *t = NULL;
-
-       match = 0;
-
-       for (i = 0; table[i].type != ENDTOKEN; i++) {
-               switch (table[i].type) {
-               case NOTOKEN:
-                       if (word == NULL || strlen(word) == 0) {
-                               match++;
-                               t = &table[i];
-                       }
-                       break;
-               case INTERFACENAME:
-                       if (!match && word != NULL && strlen(word) > 0) {
-                               if ((res->if_index = if_nametoindex(word)) == 0)
-                                       errx(1, "unknown interface");
-                               match++;
-                               t = &table[i];
-                               if (t->value)
-                                       res->action = t->value;
-                       }
-                       break;
-               case KEYWORD:
-                       if (word != NULL && strncmp(word, table[i].keyword,
-                           strlen(word)) == 0) {
-                               match++;
-                               t = &table[i];
-                               if (t->value)
-                                       res->action = t->value;
-                       }
-                       break;
-               case ENDTOKEN:
-                       break;
-               }
-       }
-
-       if (match != 1) {
-               if (word == NULL)
-                       fprintf(stderr, "missing argument:\n");
-               else if (match > 1)
-                       fprintf(stderr, "ambiguous argument: %s\n", word);
-               else if (match < 1)
-                       fprintf(stderr, "unknown argument: %s\n", word);
-               return (NULL);
-       }
-
-       return (t);
-}
-
-static void
-show_valid_args(const struct token *table)
-{
-       int     i;
-
-       for (i = 0; table[i].type != ENDTOKEN; i++) {
-               switch (table[i].type) {
-               case NOTOKEN:
-                       fprintf(stderr, "  <cr>\n");
-                       break;
-               case INTERFACENAME:
-                       fprintf(stderr, " <interface>\n");
-                       break;
-               case KEYWORD:
-                       fprintf(stderr, "  %s\n", table[i].keyword);
-                       break;
-               case ENDTOKEN:
-                       break;
-               }
-       }
-}
diff --git a/usr.sbin/dhcpleasectl/parser.h b/usr.sbin/dhcpleasectl/parser.h
deleted file mode 100644 (file)
index 4c4a89c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*     $OpenBSD: parser.h,v 1.2 2021/07/26 09:26:36 florian Exp $      */
-
-/*
- * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
- * Copyright (c) 2003, 2004 Henning Brauer <henning@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.
- */
-
-enum actions {
-       NONE,
-       LOG_VERBOSE,
-       LOG_BRIEF,
-       SHOW,
-       SHOW_INTERFACE,
-       SEND_REQUEST,
-       RELOAD
-};
-
-struct parse_result {
-       enum actions    action;
-       uint32_t        if_index;
-};
-
-struct parse_result    *parse(int, char *[]);