summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2002-10-20 22:15:17 +0000
committerimp <imp@FreeBSD.org>2002-10-20 22:15:17 +0000
commit825b39f9a024ed8da91ab364d7c541bac7e7e331 (patch)
tree954513bd65030a15f07190abce08b977298b5a38 /sbin
parentd862ecfee8a2ae2fa2c34cbf7f45762df54e50c4 (diff)
downloadFreeBSD-src-825b39f9a024ed8da91ab364d7c541bac7e7e331.zip
FreeBSD-src-825b39f9a024ed8da91ab364d7c541bac7e7e331.tar.gz
devd. A daemon that hooks into the kernel's /dev/devctl to produce
arbitrary commands when devices come and go in the device tree (which is different than the /dev directory). This is an initial version. Much of the planned power isn't here. Instead of doing the full matching, we always run /etc/devd-generic. /etc/devd.generic will go away at some point, I think. I'm committing it in this early state so I can start getting feedback from early adapters. Approved by: re
Diffstat (limited to 'sbin')
-rw-r--r--sbin/devd/Makefile16
-rw-r--r--sbin/devd/devd-generic26
-rw-r--r--sbin/devd/devd.888
-rw-r--r--sbin/devd/devd.c223
-rw-r--r--sbin/devd/devd.conf92
-rw-r--r--sbin/devd/devd.conf.5133
-rw-r--r--sbin/devd/devd.h48
-rw-r--r--sbin/devd/parse.y137
-rw-r--r--sbin/devd/token.l89
9 files changed, 852 insertions, 0 deletions
diff --git a/sbin/devd/Makefile b/sbin/devd/Makefile
new file mode 100644
index 0000000..899cf3c
--- /dev/null
+++ b/sbin/devd/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+PROG= devd
+SRCS= devd.c token.l parse.y y.tab.h
+MAN= devd.8
+WARNS?= 5
+
+DPADD= ${LIBL}
+LDADD= -ll
+
+YFLAGS+=-v
+CFLAGS+=-I. -I${.CURDIR}
+
+CLEANFILES= y.output
+
+.include <bsd.prog.mk>
diff --git a/sbin/devd/devd-generic b/sbin/devd/devd-generic
new file mode 100644
index 0000000..c75779d
--- /dev/null
+++ b/sbin/devd/devd-generic
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+# Script called by devd(8) whenever a device appears or disappears.
+#
+# XXX this is a temporary hack that will go away soon
+
+dev="$1"
+startstop="$2"
+
+driver="${dev%%[0-9]*}"
+unit="${dev##*[^0-9]}"
+
+if [ -z "$driver" -o -z "$unit" ]; then
+ echo "cannot parse device \"$dev\"" 1>&2
+ exit 1
+fi
+
+case "$driver" in
+an|ar|awi|bge|cm|cnw|cs|dc|de|ed|el|em|ep|ex|fe|fxp|gem|gx|hme|ie|lge|lnc|my| \
+ nge|pcn|ray|rl|sf|sis|sk|sn|snc|ste|ti|tl|tx|txp|vr|vx|wb|wi|xe|xl)
+ # An ethernet interface; call pccard_ether to do the real work
+ /etc/pccard_ether "$dev" "$startstop"
+ ;;
+esac
diff --git a/sbin/devd/devd.8 b/sbin/devd/devd.8
new file mode 100644
index 0000000..1d22da2
--- /dev/null
+++ b/sbin/devd/devd.8
@@ -0,0 +1,88 @@
+.\"
+.\" Copyright (c) 2002 M. Warner Losh.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 17, 2002
+.Dt DEVD 8
+.Os
+.Sh NAME
+.Nm devd
+.Nd "Device state change daemon"
+.Sh SYNOPSIS
+.Nm
+.Op Fl d
+.Sh DESCRIPTION
+The
+.Nm
+daemon provides a way to have userland programs run when certain
+kernel events happen.
+.Pp
+The following options are accepted.
+.Bl -tag -width indent
+.It Fl d
+Enable debugging messages and run in the foreground instead of
+becoming a daemon.
+.El
+.Sh IMPLEMENTATION NOTES
+.Nm
+is a system daemon.
+It runs in the background all the time.
+When ever a device is added to or removed from the device tree, devd
+will cause a certain action to take place.
+In addition, when a device that is not matched enters the system, devd
+will also perform an action.
+.Pp
+.Nm
+hooks into the
+.Xr devctl 4
+device driver.
+This device driver has hooks into the device configuration system.
+When nodes are added or deleted from the tree, this device will
+deliver information about the even to
+.Nm .
+Once
+.Nm
+has parsed the message, it will search its action list for that kind
+of event, and perform the action with the highest matching value.
+For most mundane uses, the default handlers are adequate.
+However, for more advanced users, the power is present to tweak every
+aspect of what happens.
+.Pp
+.Nm reads /etc/devd.conf, and that drives the rest of the process.
+While the format of this file is described in
+.Xr devd.conf 5
+some basics are covered here.
+In the options section, one can define multiple directories to search
+for config files.
+All files in each of these directories are parsed.
+These files are intended to be installed by third party vendors that
+wish to hook into the devd system without modifying the user's other
+config files.
+.Sh SEE ALSO
+.Xr devctl 4 ,
+.Xr devd.conf 5
+.Sh AUTHORS
+.An M. Warner Losh
diff --git a/sbin/devd/devd.c b/sbin/devd/devd.c
new file mode 100644
index 0000000..d607232
--- /dev/null
+++ b/sbin/devd/devd.c
@@ -0,0 +1,223 @@
+/*-
+ * Copyright (c) 2002 M. Warner Losh.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * DEVD control daemon.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "devd.h"
+
+#define CF "/etc/devd.conf"
+
+extern FILE *yyin;
+extern int lineno;
+
+int dflag;
+int romeo_must_die = 0;
+struct file_list_head dirlist = TAILQ_HEAD_INITIALIZER(dirlist);
+
+static void event_loop(void);
+static void parse(void);
+static void parse_config_file(const char *fn);
+static void parse_files_in_dir(const char *dirname);
+static void reset_config(void);
+static void usage(void);
+
+void
+add_directory(const char *dir)
+{
+ struct file_list *elm;
+
+ elm = malloc(sizeof(*elm));
+ elm->path = strdup(dir);
+ TAILQ_INSERT_TAIL(&dirlist, elm, fl_link);
+}
+
+static void
+reset_config(void)
+{
+ struct file_list *flp;
+
+ TAILQ_FOREACH(flp, &dirlist, fl_link) {
+ free(flp->path);
+ free(flp);
+ }
+}
+
+static void
+parse_config_file(const char *fn)
+{
+ if (dflag)
+ printf("Parsing %s\n", fn);
+ yyin = fopen(fn, "r");
+ if (yyin == NULL)
+ err(1, "Cannot open config file %s", fn);
+ if (yyparse() != 0)
+ errx(1, "Cannot parse %s at line %d", fn, lineno);
+ fclose(yyin);
+}
+
+static void
+parse_files_in_dir(const char *dirname)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ char path[PATH_MAX];
+
+ if (dflag)
+ printf("Parsing files in %s\n", dirname);
+ dirp = opendir(dirname);
+ if (dirp == NULL)
+ return;
+ readdir(dirp); /* Skip . */
+ readdir(dirp); /* Skip .. */
+ while ((dp = readdir(dirp)) != NULL) {
+ if (strcmp(dp->d_name + dp->d_namlen - 5, ".conf") == 0) {
+ snprintf(path, sizeof(path), "%s/%s",
+ dirname, dp->d_name);
+ parse_config_file(path);
+ }
+ }
+}
+
+static void
+parse(void)
+{
+ struct file_list *flp;
+
+ parse_config_file(CF);
+ TAILQ_FOREACH(flp, &dirlist, fl_link) {
+ parse_files_in_dir(flp->path);
+ }
+}
+
+static void
+process_event(const char *buffer)
+{
+ char type;
+ char cmd[1024];
+ char *sp;
+
+ // Ignore unknown devices for now.
+ if (*buffer == '?')
+ return;
+ type = *buffer++;
+ sp = strchr(buffer, ' ');
+ if (sp == NULL)
+ return; /* Can't happen? */
+ *sp = '\0';
+ snprintf(cmd, sizeof(cmd), "/etc/devd-generic %s %s", buffer,
+ type == '+' ? "start" : "stop");
+ if (dflag)
+ printf("Trying '%s'\n", cmd);
+ system(cmd);
+}
+
+static void
+event_loop(void)
+{
+ int rv;
+ int fd;
+ char buffer[1024 + 1]; /* XXX */
+
+ fd = open("/dev/devctl", O_RDONLY); /* XXX */
+ if (fd == -1)
+ err(1, "Can't open devctl");
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0)
+ err(1, "Can't set close-on-exec flag");
+ while (1) {
+ if (romeo_must_die)
+ break;
+ rv = read(fd, buffer, sizeof(buffer) - 1);
+ if (rv > 0) {
+ buffer[rv] = '\0';
+ while (buffer[--rv] == '\n')
+ buffer[rv] = '\0';
+ process_event(buffer);
+ } else if (rv < 0) {
+ if (errno != EINTR)
+ break;
+ } else {
+ /* EOF */
+ break;
+ }
+ }
+ close(fd);
+}
+
+static void
+gensighand(int foo __unused)
+{
+ romeo_must_die++;
+}
+
+static void
+usage()
+{
+ fprintf(stderr, "usage: %s [-d]", getprogname());
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch;
+
+ while ((ch = getopt(argc, argv, "d")) != -1) {
+ switch (ch) {
+ case 'd':
+ dflag++;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ reset_config();
+ parse();
+ if (!dflag)
+ daemon(0, 0);
+ event_loop();
+ signal(SIGHUP, gensighand);
+ signal(SIGINT, gensighand);
+ signal(SIGTERM, gensighand);
+ return (0);
+}
diff --git a/sbin/devd/devd.conf b/sbin/devd/devd.conf
new file mode 100644
index 0000000..33d271e
--- /dev/null
+++ b/sbin/devd/devd.conf
@@ -0,0 +1,92 @@
+// $FreeBSD$
+//
+// Refer to devd.conf(5) and devd(8) man pages for the details on how to
+// run and configure devd.
+//
+
+// NB: All regular expressions have an implicit ^$ around them.
+
+options {
+ // Each directory directive adds a directory the list of directories
+ // that we scan for files. Files are read-in in the order that they
+ // are returned from readdir(3). The rule-sets are combined to
+ // create a DFA that's used to match events to actions.
+ directory "/etc/devd";
+ directory "/usr/local/etc/devd";
+ pid-file "/var/run/devd.pid";
+
+ // Setup some shorthand for regex that we use later in the file.
+ set ethernet-nic-regex
+ "(an|ar|aue|awi|bge|cm|cnw|cs|cue|dc|de|ed|el|em|ep|ex|\
+ fe|fxp|gem|gx|hme|ie|kue|lge|lnc|my|nge|pcn|ray|rl|\
+ sf|sis|sk|sn|snc|ste|ti|tl|tx|txp|vr|vx|wb|wi|xe|xl)[0-9]+";
+ set scsi-controller-regex
+ "(adv|advw|aic|aha|ahb|ahc|ahd|bt|ct|iir|isp|mly|mpt|ncv|nsp|\
+ stg|sym|wds)[0-9]+";
+};
+
+// Note that the attach/detach with the highest value wins, so that one can
+// override these general rules.
+
+// NB: device-name is shorthand for 'match device-name'
+
+//
+// For ethernet like devices, the default is to run dhclient. Due to
+// a historical accident, the name of this script it called pccard_ether
+//
+attach 0 {
+ device-name "$ethernet-nic-regex";
+ action "/etc/pccard_ether $device-name start";
+};
+
+detach 0 {
+ device-name "$ethernet-nic-regex";
+ action "/etc/pccard_ether $device-name stop";
+};
+
+// An entry like this might be in a different file, but is included here
+// as an example of how to override things. Normally 'ed20' would match
+// the above attach/detach stuff, but the value of 100 makes it
+// ed20 is hard wired to 1.2.3.4
+attach 100 {
+ device-name "ed20";
+ action "ifconfig $device-name inet 1.2.3.4 netmask 0xffff0000";
+};
+detach 100 {
+ device-name "ed20";
+};
+
+//
+// Rescan scsi device-names on attach, but not detach.
+//
+attach 0 {
+ device-name "$scsi-controller-regex";
+ action "camcontrol rescan all";
+};
+
+// Don't even try to second guess what to do about drivers that don't
+// match here. Instead, pass it off to a smart script to deal.
+nomatch 0 {
+ action "/usr/local/bin/smart-loader $pnpinfo $location $bus";
+};
+
+// The following might be an example of something that a vendor might
+// install if you were to add their device. This might reside in
+// /usr/local/etc/devd/deqna.conf. A deqna is, in this hypothetical
+// example, a pccard ethernet-like device. Students of history may
+// know other devices by this name, and will get the in-jokes in this
+// entry.
+nomatch 10 {
+ match "bus" "pccard[0-9]+";
+ match "manufacturer" "0x1234";
+ match "product" "0x2323";
+ action "kldload if_deqna";
+};
+attach 10 {
+ device-name "^deqna[0-9]+";
+ action "/etc/pccard_ether $device-name start";
+};
+detach 10 {
+ device-name "^deqna[0-9]+";
+ action "/etc/pccard_ether $device-name stop";
+};
diff --git a/sbin/devd/devd.conf.5 b/sbin/devd/devd.conf.5
new file mode 100644
index 0000000..10c0e5d
--- /dev/null
+++ b/sbin/devd/devd.conf.5
@@ -0,0 +1,133 @@
+.\"
+.\" Copyright (c) 2002 M. Warner Losh
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.\" The section on comments was taken from named.conf.5, which has the
+.\" following copyright:
+.\" Copyright (c) 1999-2000 by Internet Software Consortium
+.\"
+.\" 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+.\" ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+.\" CONSORTIUM 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.
+.Dd October 17, 2002
+.Dt DEVD.CONF 5
+.Os
+.Sh NAME
+.Nm devd.conf
+.Nd configuration file for
+.Xr devdd 8
+.Sh OVERVIEW
+.Ss General Syntax
+A
+.Xr devd 8
+configuration consists of two general features, statements
+and comments.
+All statements end with a semicolon.
+Many statements can contain substatements, which are each also
+terminated with a semicolon.
+.Pp
+The following statements are supported:
+.Bl -tag -width 0n
+.It Ic options
+specifies various options and parameters for the operation of
+.Xr devd 8 .
+.It Ic attach
+specifies various matching criteria and actions to perform when
+a newly attached device matches said criteria.
+.It Ic detach
+specifies various matching criteria and actions to perform when
+a newly attached device matches said criteria.
+.It Ic nomatch
+specifies various matching criteria and actions to perform when
+no device driver currently loaded in the kernel claims a (new)
+device.
+.El
+.Pp
+Statements may occur in any order in the config file, and may be
+repated as often as required.
+Further details on the syntax and meaning of each statement, and their
+substatements is explained below.
+.Pp
+Comments may appear anywhere that whitespace may appear in a BIND
+configuration file. To appeal to programmers of all kinds, they can
+be written in C, C++, or shell/perl constructs.
+.Pp
+C-style comments start with the two characters
+.Li /*
+(slash, star) and end with
+.Li */
+(star, slash).
+Because they are completely delimited with these characters,
+they can be used to comment only a portion of a line or to span
+multiple lines.
+.Pp
+C-style comments cannot be nested. For example, the following is
+not valid because the entire comment ends with the first
+.Li */ :
+.Bd -literal -offset indent
+/* This is the start of a comment.
+ This is still part of the comment.
+/* This is an incorrect attempt at nesting a comment. */
+ This is no longer in any comment. */
+.Ed
+.Pp
+C++-style comments start with the two characters
+.Li //
+(slash, slash) and continue to the end of the physical line.
+They cannot be continued across multiple physical lines; to have
+one logical comment span multiple lines, each line must use the
+.Li //
+pair. For example:
+.Bd -literal -offset indent
+// This is the start of a comment. The next line
+// is a new comment, even though it is logically
+// part of the previous comment.
+.Ed
+.Pp
+.Em WARNING :
+you cannot use the
+.Li ;
+(semicolon) character to start a comment such as you would in a zone
+file. The semicolon indicates the end of a configuration statement,
+so whatever follows it will be interpreted as the start of the next
+statement.
+.Sh FILES
+.Bl -tag -width 0n -compact
+.It Pa /etc/devd.conf
+The
+.Nm devd
+configuration file.
+.El
+.Sh SEE ALSO
+.Xr devd 8
diff --git a/sbin/devd/devd.h b/sbin/devd/devd.h
new file mode 100644
index 0000000..b35b16c
--- /dev/null
+++ b/sbin/devd/devd.h
@@ -0,0 +1,48 @@
+/*-
+ * DEVD (Device action daemon)
+ *
+ * Copyright (c) 2002 M. Warner Losh <imp@freebsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/queue.h>
+
+int yylex(void);
+void yyerror(const char *s);
+int yyparse(void);
+void add_directory(const char *);
+
+struct file_list
+{
+ char *path;
+ TAILQ_ENTRY(file_list) fl_link;
+};
+
+TAILQ_HEAD(file_list_head, file_list);
+
+extern struct file_list_head dirlist;
+
+
diff --git a/sbin/devd/parse.y b/sbin/devd/parse.y
new file mode 100644
index 0000000..53c9a05
--- /dev/null
+++ b/sbin/devd/parse.y
@@ -0,0 +1,137 @@
+%{
+/*-
+ * DEVD (Device action daemon)
+ *
+ * Copyright (c) 2002 M. Warner Losh <imp@freebsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "devd.h"
+#include <stdio.h>
+
+%}
+
+%union {
+ char *str;
+ int i;
+}
+
+%token SEMICOLON BEGINBLOCK ENDBLOCK COMMA
+%token <i> NUMBER
+%token <str> STRING
+%token <str> ID
+%token OPTIONS SET DIRECTORY PID_FILE DEVICE_NAME ACTION MATCH
+%token ATTACH DETACH NOMATCH
+
+%type <str> id
+%type <i> number
+%type <str> string
+
+%%
+
+config_file
+ : config_list
+ ;
+
+config_list
+ : config
+ | config_list config
+ ;
+
+config
+ : option_block
+ | attach_block
+ | detach_block
+ | nomatch_block
+ ;
+
+option_block
+ : OPTIONS BEGINBLOCK options ENDBLOCK SEMICOLON
+ ;
+
+options
+ : option
+ | options option
+
+option
+ : directory_option
+ | pid_file_option
+ | set_option
+ ;
+
+directory_option
+ : DIRECTORY string SEMICOLON { add_directory($2); }
+ ;
+
+pid_file_option
+ : PID_FILE string SEMICOLON
+ ;
+
+set_option
+ : SET id string SEMICOLON
+ ;
+
+attach_block
+ : ATTACH number BEGINBLOCK match_or_action_list ENDBLOCK SEMICOLON
+ ;
+
+detach_block
+ : DETACH number BEGINBLOCK match_or_action_list ENDBLOCK SEMICOLON
+ ;
+
+nomatch_block
+ : NOMATCH number BEGINBLOCK match_or_action_list ENDBLOCK SEMICOLON
+ ;
+
+match_or_action_list
+ : match_or_action
+ | match_or_action_list match_or_action
+ ;
+
+match_or_action
+ : match
+ | action
+ ;
+
+match
+ : MATCH string string SEMICOLON
+ | DEVICE_NAME string SEMICOLON
+ ;
+
+action
+ : ACTION string SEMICOLON
+ ;
+
+number
+ : NUMBER { $$ = $1; }
+
+string
+ : STRING { $$ = $1; }
+
+id
+ : ID { $$ = $1; }
+
+%%
diff --git a/sbin/devd/token.l b/sbin/devd/token.l
new file mode 100644
index 0000000..233abec
--- /dev/null
+++ b/sbin/devd/token.l
@@ -0,0 +1,89 @@
+%{
+/*-
+ * DEVD (Device action daemon)
+ *
+ * Copyright (c) 2002 M. Warner Losh <imp@freebsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include "devd.h"
+#include "y.tab.h"
+
+int lineno = 1;
+#define YY_NO_UNPUT
+
+%}
+
+%%
+
+[ \t]+ ;
+\n lineno++;
+; { return SEMICOLON; }
+\/\/.*$ ;
+\/\*(.|\n)*\*\/ ;
+\{ { return BEGINBLOCK; }
+\} { return ENDBLOCK; }
+[0-9]+ { yylval.i = atoi(yytext); return NUMBER; }
+\"[^"]+\" {
+ int len = strlen(yytext) - 2;
+ if ((yylval.str = (char *) malloc(len + 1)) == NULL)
+ goto out;
+ memcpy(yylval.str, yytext + 1, len);
+ yylval.str[len] = '\0';
+ out:;
+ return STRING;
+ }
+
+
+options { return OPTIONS; }
+set { return SET; }
+directory { return DIRECTORY; }
+pid-file { return PID_FILE; }
+attach { return ATTACH; }
+detach { return DETACH; }
+device-name { return DEVICE_NAME; }
+action { return ACTION; }
+match { return MATCH; }
+nomatch { return NOMATCH; }
+[A-Za-z][A-Za-z0-9-]* {
+ int len = strlen(yytext);
+ if ((yylval.str = (char *) malloc(len + 1)) == NULL)
+ goto out2;
+ memcpy(yylval.str, yytext + 1, len);
+ yylval.str[len] = '\0';
+ out2:;
+ return ID;
+ }
+%%
+
+void
+yyerror(const char *s)
+{
+ syslog(LOG_ERR, "line %d: %s%s %s.\n", lineno, yytext, yytext?":":"", s);
+}
OpenPOWER on IntegriCloud