devd.cc revision 259362
1/*-
2 * Copyright (c) 2002-2010 M. Warner Losh.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * my_system is a variation on lib/libc/stdlib/system.c:
27 *
28 * Copyright (c) 1988, 1993
29 *	The Regents of the University of California.  All rights reserved.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 * 1. Redistributions of source code must retain the above copyright
35 *    notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 *    notice, this list of conditions and the following disclaimer in the
38 *    documentation and/or other materials provided with the distribution.
39 * 4. Neither the name of the University nor the names of its contributors
40 *    may be used to endorse or promote products derived from this software
41 *    without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
54 */
55
56/*
57 * DEVD control daemon.
58 */
59
60// TODO list:
61//	o devd.conf and devd man pages need a lot of help:
62//	  - devd needs to document the unix domain socket
63//	  - devd.conf needs more details on the supported statements.
64
65#include <sys/cdefs.h>
66__FBSDID("$FreeBSD: head/sbin/devd/devd.cc 259362 2013-12-13 22:58:57Z asomers $");
67
68#include <sys/param.h>
69#include <sys/socket.h>
70#include <sys/stat.h>
71#include <sys/sysctl.h>
72#include <sys/types.h>
73#include <sys/wait.h>
74#include <sys/un.h>
75
76#include <cctype>
77#include <cerrno>
78#include <cstdlib>
79#include <cstdio>
80#include <csignal>
81#include <cstring>
82#include <cstdarg>
83
84#include <dirent.h>
85#include <err.h>
86#include <fcntl.h>
87#include <libutil.h>
88#include <paths.h>
89#include <poll.h>
90#include <regex.h>
91#include <syslog.h>
92#include <unistd.h>
93
94#include <algorithm>
95#include <map>
96#include <string>
97#include <list>
98#include <vector>
99
100#include "devd.h"		/* C compatible definitions */
101#include "devd.hh"		/* C++ class definitions */
102
103#define PIPE "/var/run/devd.pipe"
104#define CF "/etc/devd.conf"
105#define SYSCTL "hw.bus.devctl_disable"
106
107/*
108 * Since the client socket is nonblocking, we must increase its send buffer to
109 * handle brief event storms.  On FreeBSD, AF_UNIX sockets don't have a receive
110 * buffer, so the client can't increate the buffersize by itself.
111 *
112 * For example, when creating a ZFS pool, devd emits one 165 character
113 * resource.fs.zfs.statechange message for each vdev in the pool.  A 64k
114 * buffer has enough space for almost 400 drives, which would be very large but
115 * not impossibly large pool.  A 128k buffer has enough space for 794 drives,
116 * which is more than can fit in a rack with modern technology.
117 */
118#define CLIENT_BUFSIZE 131072
119
120using namespace std;
121
122extern FILE *yyin;
123extern int lineno;
124
125static const char notify = '!';
126static const char nomatch = '?';
127static const char attach = '+';
128static const char detach = '-';
129
130static struct pidfh *pfh;
131
132int dflag;
133int nflag;
134static unsigned total_events = 0;
135static volatile sig_atomic_t got_siginfo = 0;
136static volatile sig_atomic_t romeo_must_die = 0;
137
138static const char *configfile = CF;
139
140static void devdlog(int priority, const char* message, ...)
141	__printflike(2, 3);
142static void event_loop(void);
143static void usage(void);
144
145template <class T> void
146delete_and_clear(vector<T *> &v)
147{
148	typename vector<T *>::const_iterator i;
149
150	for (i = v.begin(); i != v.end(); ++i)
151		delete *i;
152	v.clear();
153}
154
155config cfg;
156
157event_proc::event_proc() : _prio(-1)
158{
159	_epsvec.reserve(4);
160}
161
162event_proc::~event_proc()
163{
164	delete_and_clear(_epsvec);
165}
166
167void
168event_proc::add(eps *eps)
169{
170	_epsvec.push_back(eps);
171}
172
173bool
174event_proc::matches(config &c) const
175{
176	vector<eps *>::const_iterator i;
177
178	for (i = _epsvec.begin(); i != _epsvec.end(); ++i)
179		if (!(*i)->do_match(c))
180			return (false);
181	return (true);
182}
183
184bool
185event_proc::run(config &c) const
186{
187	vector<eps *>::const_iterator i;
188
189	for (i = _epsvec.begin(); i != _epsvec.end(); ++i)
190		if (!(*i)->do_action(c))
191			return (false);
192	return (true);
193}
194
195action::action(const char *cmd)
196	: _cmd(cmd)
197{
198	// nothing
199}
200
201action::~action()
202{
203	// nothing
204}
205
206static int
207my_system(const char *command)
208{
209	pid_t pid, savedpid;
210	int pstat;
211	struct sigaction ign, intact, quitact;
212	sigset_t newsigblock, oldsigblock;
213
214	if (!command)		/* just checking... */
215		return (1);
216
217	/*
218	 * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save
219	 * existing signal dispositions.
220	 */
221	ign.sa_handler = SIG_IGN;
222	::sigemptyset(&ign.sa_mask);
223	ign.sa_flags = 0;
224	::sigaction(SIGINT, &ign, &intact);
225	::sigaction(SIGQUIT, &ign, &quitact);
226	::sigemptyset(&newsigblock);
227	::sigaddset(&newsigblock, SIGCHLD);
228	::sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
229	switch (pid = ::fork()) {
230	case -1:			/* error */
231		break;
232	case 0:				/* child */
233		/*
234		 * Restore original signal dispositions and exec the command.
235		 */
236		::sigaction(SIGINT, &intact, NULL);
237		::sigaction(SIGQUIT,  &quitact, NULL);
238		::sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
239		/*
240		 * Close the PID file, and all other open descriptors.
241		 * Inherit std{in,out,err} only.
242		 */
243		cfg.close_pidfile();
244		::closefrom(3);
245		::execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL);
246		::_exit(127);
247	default:			/* parent */
248		savedpid = pid;
249		do {
250			pid = ::wait4(savedpid, &pstat, 0, (struct rusage *)0);
251		} while (pid == -1 && errno == EINTR);
252		break;
253	}
254	::sigaction(SIGINT, &intact, NULL);
255	::sigaction(SIGQUIT,  &quitact, NULL);
256	::sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
257	return (pid == -1 ? -1 : pstat);
258}
259
260bool
261action::do_action(config &c)
262{
263	string s = c.expand_string(_cmd.c_str());
264	devdlog(LOG_INFO, "Executing '%s'\n", s.c_str());
265	my_system(s.c_str());
266	return (true);
267}
268
269match::match(config &c, const char *var, const char *re) :
270	_inv(re[0] == '!'),
271	_var(var),
272	_re(c.expand_string(_inv ? re + 1 : re, "^", "$"))
273{
274	regcomp(&_regex, _re.c_str(), REG_EXTENDED | REG_NOSUB | REG_ICASE);
275}
276
277match::~match()
278{
279	regfree(&_regex);
280}
281
282bool
283match::do_match(config &c)
284{
285	const string &value = c.get_variable(_var);
286	bool retval;
287
288	/*
289	 * This function gets called WAY too often to justify calling syslog()
290	 * each time, even at LOG_DEBUG.  Because if syslogd isn't running, it
291	 * can consume excessive amounts of systime inside of connect().  Only
292	 * log when we're in -d mode.
293	 */
294	if (dflag) {
295		devdlog(LOG_DEBUG, "Testing %s=%s against %s, invert=%d\n",
296		    _var.c_str(), value.c_str(), _re.c_str(), _inv);
297	}
298
299	retval = (regexec(&_regex, value.c_str(), 0, NULL, 0) == 0);
300	if (_inv == 1)
301		retval = (retval == 0) ? 1 : 0;
302
303	return (retval);
304}
305
306#include <sys/sockio.h>
307#include <net/if.h>
308#include <net/if_media.h>
309
310media::media(config &, const char *var, const char *type)
311	: _var(var), _type(-1)
312{
313	static struct ifmedia_description media_types[] = {
314		{ IFM_ETHER,		"Ethernet" },
315		{ IFM_TOKEN,		"Tokenring" },
316		{ IFM_FDDI,		"FDDI" },
317		{ IFM_IEEE80211,	"802.11" },
318		{ IFM_ATM,		"ATM" },
319		{ -1,			"unknown" },
320		{ 0, NULL },
321	};
322	for (int i = 0; media_types[i].ifmt_string != NULL; ++i)
323		if (strcasecmp(type, media_types[i].ifmt_string) == 0) {
324			_type = media_types[i].ifmt_word;
325			break;
326		}
327}
328
329media::~media()
330{
331}
332
333bool
334media::do_match(config &c)
335{
336	string value;
337	struct ifmediareq ifmr;
338	bool retval;
339	int s;
340
341	// Since we can be called from both a device attach/detach
342	// context where device-name is defined and what we want,
343	// as well as from a link status context, where subsystem is
344	// the name of interest, first try device-name and fall back
345	// to subsystem if none exists.
346	value = c.get_variable("device-name");
347	if (value.empty())
348		value = c.get_variable("subsystem");
349	devdlog(LOG_DEBUG, "Testing media type of %s against 0x%x\n",
350		    value.c_str(), _type);
351
352	retval = false;
353
354	s = socket(PF_INET, SOCK_DGRAM, 0);
355	if (s >= 0) {
356		memset(&ifmr, 0, sizeof(ifmr));
357		strncpy(ifmr.ifm_name, value.c_str(), sizeof(ifmr.ifm_name));
358
359		if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0 &&
360		    ifmr.ifm_status & IFM_AVALID) {
361			devdlog(LOG_DEBUG, "%s has media type 0x%x\n",
362				    value.c_str(), IFM_TYPE(ifmr.ifm_active));
363			retval = (IFM_TYPE(ifmr.ifm_active) == _type);
364		} else if (_type == -1) {
365			devdlog(LOG_DEBUG, "%s has unknown media type\n",
366				    value.c_str());
367			retval = true;
368		}
369		close(s);
370	}
371
372	return (retval);
373}
374
375const string var_list::bogus = "_$_$_$_$_B_O_G_U_S_$_$_$_$_";
376const string var_list::nothing = "";
377
378const string &
379var_list::get_variable(const string &var) const
380{
381	map<string, string>::const_iterator i;
382
383	i = _vars.find(var);
384	if (i == _vars.end())
385		return (var_list::bogus);
386	return (i->second);
387}
388
389bool
390var_list::is_set(const string &var) const
391{
392	return (_vars.find(var) != _vars.end());
393}
394
395void
396var_list::set_variable(const string &var, const string &val)
397{
398	/*
399	 * This function gets called WAY too often to justify calling syslog()
400	 * each time, even at LOG_DEBUG.  Because if syslogd isn't running, it
401	 * can consume excessive amounts of systime inside of connect().  Only
402	 * log when we're in -d mode.
403	 */
404	if (dflag)
405		devdlog(LOG_DEBUG, "setting %s=%s\n", var.c_str(), val.c_str());
406	_vars[var] = val;
407}
408
409void
410config::reset(void)
411{
412	_dir_list.clear();
413	delete_and_clear(_var_list_table);
414	delete_and_clear(_attach_list);
415	delete_and_clear(_detach_list);
416	delete_and_clear(_nomatch_list);
417	delete_and_clear(_notify_list);
418}
419
420void
421config::parse_one_file(const char *fn)
422{
423	devdlog(LOG_DEBUG, "Parsing %s\n", fn);
424	yyin = fopen(fn, "r");
425	if (yyin == NULL)
426		err(1, "Cannot open config file %s", fn);
427	lineno = 1;
428	if (yyparse() != 0)
429		errx(1, "Cannot parse %s at line %d", fn, lineno);
430	fclose(yyin);
431}
432
433void
434config::parse_files_in_dir(const char *dirname)
435{
436	DIR *dirp;
437	struct dirent *dp;
438	char path[PATH_MAX];
439
440	devdlog(LOG_DEBUG, "Parsing files in %s\n", dirname);
441	dirp = opendir(dirname);
442	if (dirp == NULL)
443		return;
444	readdir(dirp);		/* Skip . */
445	readdir(dirp);		/* Skip .. */
446	while ((dp = readdir(dirp)) != NULL) {
447		if (strcmp(dp->d_name + dp->d_namlen - 5, ".conf") == 0) {
448			snprintf(path, sizeof(path), "%s/%s",
449			    dirname, dp->d_name);
450			parse_one_file(path);
451		}
452	}
453	closedir(dirp);
454}
455
456class epv_greater {
457public:
458	int operator()(event_proc *const&l1, event_proc *const&l2) const
459	{
460		return (l1->get_priority() > l2->get_priority());
461	}
462};
463
464void
465config::sort_vector(vector<event_proc *> &v)
466{
467	stable_sort(v.begin(), v.end(), epv_greater());
468}
469
470void
471config::parse(void)
472{
473	vector<string>::const_iterator i;
474
475	parse_one_file(configfile);
476	for (i = _dir_list.begin(); i != _dir_list.end(); ++i)
477		parse_files_in_dir((*i).c_str());
478	sort_vector(_attach_list);
479	sort_vector(_detach_list);
480	sort_vector(_nomatch_list);
481	sort_vector(_notify_list);
482}
483
484void
485config::open_pidfile()
486{
487	pid_t otherpid;
488
489	if (_pidfile.empty())
490		return;
491	pfh = pidfile_open(_pidfile.c_str(), 0600, &otherpid);
492	if (pfh == NULL) {
493		if (errno == EEXIST)
494			errx(1, "devd already running, pid: %d", (int)otherpid);
495		warn("cannot open pid file");
496	}
497}
498
499void
500config::write_pidfile()
501{
502
503	pidfile_write(pfh);
504}
505
506void
507config::close_pidfile()
508{
509
510	pidfile_close(pfh);
511}
512
513void
514config::remove_pidfile()
515{
516
517	pidfile_remove(pfh);
518}
519
520void
521config::add_attach(int prio, event_proc *p)
522{
523	p->set_priority(prio);
524	_attach_list.push_back(p);
525}
526
527void
528config::add_detach(int prio, event_proc *p)
529{
530	p->set_priority(prio);
531	_detach_list.push_back(p);
532}
533
534void
535config::add_directory(const char *dir)
536{
537	_dir_list.push_back(string(dir));
538}
539
540void
541config::add_nomatch(int prio, event_proc *p)
542{
543	p->set_priority(prio);
544	_nomatch_list.push_back(p);
545}
546
547void
548config::add_notify(int prio, event_proc *p)
549{
550	p->set_priority(prio);
551	_notify_list.push_back(p);
552}
553
554void
555config::set_pidfile(const char *fn)
556{
557	_pidfile = fn;
558}
559
560void
561config::push_var_table()
562{
563	var_list *vl;
564
565	vl = new var_list();
566	_var_list_table.push_back(vl);
567	devdlog(LOG_DEBUG, "Pushing table\n");
568}
569
570void
571config::pop_var_table()
572{
573	delete _var_list_table.back();
574	_var_list_table.pop_back();
575	devdlog(LOG_DEBUG, "Popping table\n");
576}
577
578void
579config::set_variable(const char *var, const char *val)
580{
581	_var_list_table.back()->set_variable(var, val);
582}
583
584const string &
585config::get_variable(const string &var)
586{
587	vector<var_list *>::reverse_iterator i;
588
589	for (i = _var_list_table.rbegin(); i != _var_list_table.rend(); ++i) {
590		if ((*i)->is_set(var))
591			return ((*i)->get_variable(var));
592	}
593	return (var_list::nothing);
594}
595
596bool
597config::is_id_char(char ch) const
598{
599	return (ch != '\0' && (isalpha(ch) || isdigit(ch) || ch == '_' ||
600	    ch == '-'));
601}
602
603void
604config::expand_one(const char *&src, string &dst)
605{
606	int count;
607	string buffer;
608
609	src++;
610	// $$ -> $
611	if (*src == '$') {
612		dst += *src++;
613		return;
614	}
615
616	// $(foo) -> $(foo)
617	// Not sure if I want to support this or not, so for now we just pass
618	// it through.
619	if (*src == '(') {
620		dst += '$';
621		count = 1;
622		/* If the string ends before ) is matched , return. */
623		while (count > 0 && *src) {
624			if (*src == ')')
625				count--;
626			else if (*src == '(')
627				count++;
628			dst += *src++;
629		}
630		return;
631	}
632
633	// $[^A-Za-z] -> $\1
634	if (!isalpha(*src)) {
635		dst += '$';
636		dst += *src++;
637		return;
638	}
639
640	// $var -> replace with value
641	do {
642		buffer += *src++;
643	} while (is_id_char(*src));
644	dst.append(get_variable(buffer));
645}
646
647const string
648config::expand_string(const char *src, const char *prepend, const char *append)
649{
650	const char *var_at;
651	string dst;
652
653	/*
654	 * 128 bytes is enough for 2427 of 2438 expansions that happen
655	 * while parsing config files, as tested on 2013-01-30.
656	 */
657	dst.reserve(128);
658
659	if (prepend != NULL)
660		dst = prepend;
661
662	for (;;) {
663		var_at = strchr(src, '$');
664		if (var_at == NULL) {
665			dst.append(src);
666			break;
667		}
668		dst.append(src, var_at - src);
669		src = var_at;
670		expand_one(src, dst);
671	}
672
673	if (append != NULL)
674		dst.append(append);
675
676	return (dst);
677}
678
679bool
680config::chop_var(char *&buffer, char *&lhs, char *&rhs) const
681{
682	char *walker;
683
684	if (*buffer == '\0')
685		return (false);
686	walker = lhs = buffer;
687	while (is_id_char(*walker))
688		walker++;
689	if (*walker != '=')
690		return (false);
691	walker++;		// skip =
692	if (*walker == '"') {
693		walker++;	// skip "
694		rhs = walker;
695		while (*walker && *walker != '"')
696			walker++;
697		if (*walker != '"')
698			return (false);
699		rhs[-2] = '\0';
700		*walker++ = '\0';
701	} else {
702		rhs = walker;
703		while (*walker && !isspace(*walker))
704			walker++;
705		if (*walker != '\0')
706			*walker++ = '\0';
707		rhs[-1] = '\0';
708	}
709	while (isspace(*walker))
710		walker++;
711	buffer = walker;
712	return (true);
713}
714
715
716char *
717config::set_vars(char *buffer)
718{
719	char *lhs;
720	char *rhs;
721
722	while (1) {
723		if (!chop_var(buffer, lhs, rhs))
724			break;
725		set_variable(lhs, rhs);
726	}
727	return (buffer);
728}
729
730void
731config::find_and_execute(char type)
732{
733	vector<event_proc *> *l;
734	vector<event_proc *>::const_iterator i;
735	const char *s;
736
737	switch (type) {
738	default:
739		return;
740	case notify:
741		l = &_notify_list;
742		s = "notify";
743		break;
744	case nomatch:
745		l = &_nomatch_list;
746		s = "nomatch";
747		break;
748	case attach:
749		l = &_attach_list;
750		s = "attach";
751		break;
752	case detach:
753		l = &_detach_list;
754		s = "detach";
755		break;
756	}
757	devdlog(LOG_DEBUG, "Processing %s event\n", s);
758	for (i = l->begin(); i != l->end(); ++i) {
759		if ((*i)->matches(*this)) {
760			(*i)->run(*this);
761			break;
762		}
763	}
764
765}
766
767
768static void
769process_event(char *buffer)
770{
771	char type;
772	char *sp;
773
774	sp = buffer + 1;
775	devdlog(LOG_INFO, "Processing event '%s'\n", buffer);
776	type = *buffer++;
777	cfg.push_var_table();
778	// No match doesn't have a device, and the format is a little
779	// different, so handle it separately.
780	switch (type) {
781	case notify:
782		sp = cfg.set_vars(sp);
783		break;
784	case nomatch:
785		//? at location pnp-info on bus
786		sp = strchr(sp, ' ');
787		if (sp == NULL)
788			return;	/* Can't happen? */
789		*sp++ = '\0';
790		while (isspace(*sp))
791			sp++;
792		if (strncmp(sp, "at ", 3) == 0)
793			sp += 3;
794		sp = cfg.set_vars(sp);
795		while (isspace(*sp))
796			sp++;
797		if (strncmp(sp, "on ", 3) == 0)
798			cfg.set_variable("bus", sp + 3);
799		break;
800	case attach:	/*FALLTHROUGH*/
801	case detach:
802		sp = strchr(sp, ' ');
803		if (sp == NULL)
804			return;	/* Can't happen? */
805		*sp++ = '\0';
806		cfg.set_variable("device-name", buffer);
807		while (isspace(*sp))
808			sp++;
809		if (strncmp(sp, "at ", 3) == 0)
810			sp += 3;
811		sp = cfg.set_vars(sp);
812		while (isspace(*sp))
813			sp++;
814		if (strncmp(sp, "on ", 3) == 0)
815			cfg.set_variable("bus", sp + 3);
816		break;
817	}
818
819	cfg.find_and_execute(type);
820	cfg.pop_var_table();
821}
822
823int
824create_socket(const char *name)
825{
826	int fd, slen;
827	struct sockaddr_un sun;
828
829	if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0)
830		err(1, "socket");
831	bzero(&sun, sizeof(sun));
832	sun.sun_family = AF_UNIX;
833	strlcpy(sun.sun_path, name, sizeof(sun.sun_path));
834	slen = SUN_LEN(&sun);
835	unlink(name);
836	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
837	    	err(1, "fcntl");
838	if (::bind(fd, (struct sockaddr *) & sun, slen) < 0)
839		err(1, "bind");
840	listen(fd, 4);
841	chown(name, 0, 0);	/* XXX - root.wheel */
842	chmod(name, 0666);
843	return (fd);
844}
845
846unsigned int max_clients = 10;	/* Default, can be overriden on cmdline. */
847unsigned int num_clients;
848list<int> clients;
849
850void
851notify_clients(const char *data, int len)
852{
853	list<int>::iterator i;
854
855	/*
856	 * Deliver the data to all clients.  Throw clients overboard at the
857	 * first sign of trouble.  This reaps clients who've died or closed
858	 * their sockets, and also clients who are alive but failing to keep up
859	 * (or who are maliciously not reading, to consume buffer space in
860	 * kernel memory or tie up the limited number of available connections).
861	 */
862	for (i = clients.begin(); i != clients.end(); ) {
863		if (write(*i, data, len) != len) {
864			--num_clients;
865			close(*i);
866			i = clients.erase(i);
867			devdlog(LOG_WARNING, "notify_clients: write() failed; "
868			    "dropping unresponsive client\n");
869		} else
870			++i;
871	}
872}
873
874void
875check_clients(void)
876{
877	int s;
878	struct pollfd pfd;
879	list<int>::iterator i;
880
881	/*
882	 * Check all existing clients to see if any of them have disappeared.
883	 * Normally we reap clients when we get an error trying to send them an
884	 * event.  This check eliminates the problem of an ever-growing list of
885	 * zombie clients because we're never writing to them on a system
886	 * without frequent device-change activity.
887	 */
888	pfd.events = 0;
889	for (i = clients.begin(); i != clients.end(); ) {
890		pfd.fd = *i;
891		s = poll(&pfd, 1, 0);
892		if ((s < 0 && s != EINTR ) ||
893		    (s > 0 && (pfd.revents & POLLHUP))) {
894			--num_clients;
895			close(*i);
896			i = clients.erase(i);
897			devdlog(LOG_NOTICE, "check_clients:  "
898			    "dropping disconnected client\n");
899		} else
900			++i;
901	}
902}
903
904void
905new_client(int fd)
906{
907	int s;
908	int sndbuf_size;
909
910	/*
911	 * First go reap any zombie clients, then accept the connection, and
912	 * shut down the read side to stop clients from consuming kernel memory
913	 * by sending large buffers full of data we'll never read.
914	 */
915	check_clients();
916	s = accept(fd, NULL, NULL);
917	if (s != -1) {
918		sndbuf_size = CLIENT_BUFSIZE;
919		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf_size,
920		    sizeof(sndbuf_size)))
921			err(1, "setsockopt");
922		shutdown(s, SHUT_RD);
923		clients.push_back(s);
924		++num_clients;
925	} else
926		err(1, "accept");
927}
928
929static void
930event_loop(void)
931{
932	int rv;
933	int fd;
934	char buffer[DEVCTL_MAXBUF];
935	int once = 0;
936	int server_fd, max_fd;
937	int accepting;
938	timeval tv;
939	fd_set fds;
940
941	fd = open(PATH_DEVCTL, O_RDONLY | O_CLOEXEC);
942	if (fd == -1)
943		err(1, "Can't open devctl device %s", PATH_DEVCTL);
944	server_fd = create_socket(PIPE);
945	accepting = 1;
946	max_fd = max(fd, server_fd) + 1;
947	while (!romeo_must_die) {
948		if (!once && !dflag && !nflag) {
949			// Check to see if we have any events pending.
950			tv.tv_sec = 0;
951			tv.tv_usec = 0;
952			FD_ZERO(&fds);
953			FD_SET(fd, &fds);
954			rv = select(fd + 1, &fds, &fds, &fds, &tv);
955			// No events -> we've processed all pending events
956			if (rv == 0) {
957				devdlog(LOG_DEBUG, "Calling daemon\n");
958				cfg.remove_pidfile();
959				cfg.open_pidfile();
960				daemon(0, 0);
961				cfg.write_pidfile();
962				once++;
963			}
964		}
965		/*
966		 * When we've already got the max number of clients, stop
967		 * accepting new connections (don't put server_fd in the set),
968		 * shrink the accept() queue to reject connections quickly, and
969		 * poll the existing clients more often, so that we notice more
970		 * quickly when any of them disappear to free up client slots.
971		 */
972		FD_ZERO(&fds);
973		FD_SET(fd, &fds);
974		if (num_clients < max_clients) {
975			if (!accepting) {
976				listen(server_fd, max_clients);
977				accepting = 1;
978			}
979			FD_SET(server_fd, &fds);
980			tv.tv_sec = 60;
981			tv.tv_usec = 0;
982		} else {
983			if (accepting) {
984				listen(server_fd, 0);
985				accepting = 0;
986			}
987			tv.tv_sec = 2;
988			tv.tv_usec = 0;
989		}
990		rv = select(max_fd, &fds, NULL, NULL, &tv);
991		if (got_siginfo) {
992			devdlog(LOG_NOTICE, "Events received so far=%u\n",
993			    total_events);
994			got_siginfo = 0;
995		}
996		if (rv == -1) {
997			if (errno == EINTR)
998				continue;
999			err(1, "select");
1000		} else if (rv == 0)
1001			check_clients();
1002		if (FD_ISSET(fd, &fds)) {
1003			rv = read(fd, buffer, sizeof(buffer) - 1);
1004			if (rv > 0) {
1005				total_events++;
1006				if (rv == sizeof(buffer) - 1) {
1007					devdlog(LOG_WARNING, "Warning: "
1008					    "available event data exceeded "
1009					    "buffer space\n");
1010				}
1011				notify_clients(buffer, rv);
1012				buffer[rv] = '\0';
1013				while (buffer[--rv] == '\n')
1014					buffer[rv] = '\0';
1015				process_event(buffer);
1016			} else if (rv < 0) {
1017				if (errno != EINTR)
1018					break;
1019			} else {
1020				/* EOF */
1021				break;
1022			}
1023		}
1024		if (FD_ISSET(server_fd, &fds))
1025			new_client(server_fd);
1026	}
1027	close(fd);
1028}
1029
1030/*
1031 * functions that the parser uses.
1032 */
1033void
1034add_attach(int prio, event_proc *p)
1035{
1036	cfg.add_attach(prio, p);
1037}
1038
1039void
1040add_detach(int prio, event_proc *p)
1041{
1042	cfg.add_detach(prio, p);
1043}
1044
1045void
1046add_directory(const char *dir)
1047{
1048	cfg.add_directory(dir);
1049	free(const_cast<char *>(dir));
1050}
1051
1052void
1053add_nomatch(int prio, event_proc *p)
1054{
1055	cfg.add_nomatch(prio, p);
1056}
1057
1058void
1059add_notify(int prio, event_proc *p)
1060{
1061	cfg.add_notify(prio, p);
1062}
1063
1064event_proc *
1065add_to_event_proc(event_proc *ep, eps *eps)
1066{
1067	if (ep == NULL)
1068		ep = new event_proc();
1069	ep->add(eps);
1070	return (ep);
1071}
1072
1073eps *
1074new_action(const char *cmd)
1075{
1076	eps *e = new action(cmd);
1077	free(const_cast<char *>(cmd));
1078	return (e);
1079}
1080
1081eps *
1082new_match(const char *var, const char *re)
1083{
1084	eps *e = new match(cfg, var, re);
1085	free(const_cast<char *>(var));
1086	free(const_cast<char *>(re));
1087	return (e);
1088}
1089
1090eps *
1091new_media(const char *var, const char *re)
1092{
1093	eps *e = new media(cfg, var, re);
1094	free(const_cast<char *>(var));
1095	free(const_cast<char *>(re));
1096	return (e);
1097}
1098
1099void
1100set_pidfile(const char *name)
1101{
1102	cfg.set_pidfile(name);
1103	free(const_cast<char *>(name));
1104}
1105
1106void
1107set_variable(const char *var, const char *val)
1108{
1109	cfg.set_variable(var, val);
1110	free(const_cast<char *>(var));
1111	free(const_cast<char *>(val));
1112}
1113
1114
1115
1116static void
1117gensighand(int)
1118{
1119	romeo_must_die = 1;
1120}
1121
1122/*
1123 * SIGINFO handler.  Will print useful statistics to the syslog or stderr
1124 * as appropriate
1125 */
1126static void
1127siginfohand(int)
1128{
1129	got_siginfo = 1;
1130}
1131
1132/*
1133 * Local logging function.  Prints to syslog if we're daemonized; stderr
1134 * otherwise.
1135 */
1136static void
1137devdlog(int priority, const char* fmt, ...)
1138{
1139	va_list argp;
1140
1141	va_start(argp, fmt);
1142	if (dflag)
1143		vfprintf(stderr, fmt, argp);
1144	else
1145		vsyslog(priority, fmt, argp);
1146	va_end(argp);
1147}
1148
1149static void
1150usage()
1151{
1152	fprintf(stderr, "usage: %s [-dn] [-l connlimit] [-f file]\n",
1153	    getprogname());
1154	exit(1);
1155}
1156
1157static void
1158check_devd_enabled()
1159{
1160	int val = 0;
1161	size_t len;
1162
1163	len = sizeof(val);
1164	if (sysctlbyname(SYSCTL, &val, &len, NULL, 0) != 0)
1165		errx(1, "devctl sysctl missing from kernel!");
1166	if (val) {
1167		warnx("Setting " SYSCTL " to 0");
1168		val = 0;
1169		sysctlbyname(SYSCTL, NULL, NULL, &val, sizeof(val));
1170	}
1171}
1172
1173/*
1174 * main
1175 */
1176int
1177main(int argc, char **argv)
1178{
1179	int ch;
1180
1181	check_devd_enabled();
1182	while ((ch = getopt(argc, argv, "df:l:n")) != -1) {
1183		switch (ch) {
1184		case 'd':
1185			dflag++;
1186			break;
1187		case 'f':
1188			configfile = optarg;
1189			break;
1190		case 'l':
1191			max_clients = MAX(1, strtoul(optarg, NULL, 0));
1192			break;
1193		case 'n':
1194			nflag++;
1195			break;
1196		default:
1197			usage();
1198		}
1199	}
1200
1201	cfg.parse();
1202	if (!dflag && nflag) {
1203		cfg.open_pidfile();
1204		daemon(0, 0);
1205		cfg.write_pidfile();
1206	}
1207	signal(SIGPIPE, SIG_IGN);
1208	signal(SIGHUP, gensighand);
1209	signal(SIGINT, gensighand);
1210	signal(SIGTERM, gensighand);
1211	signal(SIGINFO, siginfohand);
1212	event_loop();
1213	return (0);
1214}
1215