From 825b39f9a024ed8da91ab364d7c541bac7e7e331 Mon Sep 17 00:00:00 2001 From: imp Date: Sun, 20 Oct 2002 22:15:17 +0000 Subject: 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 --- sbin/devd/Makefile | 16 ++++ sbin/devd/devd-generic | 26 ++++++ sbin/devd/devd.8 | 88 +++++++++++++++++++ sbin/devd/devd.c | 223 +++++++++++++++++++++++++++++++++++++++++++++++++ sbin/devd/devd.conf | 92 ++++++++++++++++++++ sbin/devd/devd.conf.5 | 133 +++++++++++++++++++++++++++++ sbin/devd/devd.h | 48 +++++++++++ sbin/devd/parse.y | 137 ++++++++++++++++++++++++++++++ sbin/devd/token.l | 89 ++++++++++++++++++++ 9 files changed, 852 insertions(+) create mode 100644 sbin/devd/Makefile create mode 100644 sbin/devd/devd-generic create mode 100644 sbin/devd/devd.8 create mode 100644 sbin/devd/devd.c create mode 100644 sbin/devd/devd.conf create mode 100644 sbin/devd/devd.conf.5 create mode 100644 sbin/devd/devd.h create mode 100644 sbin/devd/parse.y create mode 100644 sbin/devd/token.l 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 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 +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 . + * 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 + +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 . + * 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 + +%} + +%union { + char *str; + int i; +} + +%token SEMICOLON BEGINBLOCK ENDBLOCK COMMA +%token NUMBER +%token STRING +%token ID +%token OPTIONS SET DIRECTORY PID_FILE DEVICE_NAME ACTION MATCH +%token ATTACH DETACH NOMATCH + +%type id +%type number +%type 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 . + * 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 +#include +#include +#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); +} -- cgit v1.1