xref: /freebsd/sbin/devd/devd.hh (revision b3e76948)
16aeeca8eSWarner Losh /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
4f86e6000SWarner Losh  * Copyright (c) 2002-2003 M. Warner Losh <imp@FreeBSD.org>
56aeeca8eSWarner Losh  *
66aeeca8eSWarner Losh  * Redistribution and use in source and binary forms, with or without
76aeeca8eSWarner Losh  * modification, are permitted provided that the following conditions
86aeeca8eSWarner Losh  * are met:
96aeeca8eSWarner Losh  * 1. Redistributions of source code must retain the above copyright
106aeeca8eSWarner Losh  *    notice, this list of conditions and the following disclaimer.
116aeeca8eSWarner Losh  * 2. Redistributions in binary form must reproduce the above copyright
126aeeca8eSWarner Losh  *    notice, this list of conditions and the following disclaimer in the
136aeeca8eSWarner Losh  *    documentation and/or other materials provided with the distribution.
146aeeca8eSWarner Losh  *
156aeeca8eSWarner Losh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
166aeeca8eSWarner Losh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
176aeeca8eSWarner Losh  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
186aeeca8eSWarner Losh  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
196aeeca8eSWarner Losh  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
206aeeca8eSWarner Losh  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
216aeeca8eSWarner Losh  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
226aeeca8eSWarner Losh  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
236aeeca8eSWarner Losh  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
246aeeca8eSWarner Losh  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
256aeeca8eSWarner Losh  * SUCH DAMAGE.
266aeeca8eSWarner Losh  */
276aeeca8eSWarner Losh 
286aeeca8eSWarner Losh #ifndef DEVD_HH
296aeeca8eSWarner Losh #define DEVD_HH
306aeeca8eSWarner Losh 
316aeeca8eSWarner Losh class config;
326aeeca8eSWarner Losh 
336aeeca8eSWarner Losh /**
346aeeca8eSWarner Losh  * var_list is a collection of variables.  These collections of variables
356aeeca8eSWarner Losh  * are stacked up and popped down for each event that we have to process.
366aeeca8eSWarner Losh  * We have multiple levels so that we can push variables that are unique
376aeeca8eSWarner Losh  * to the event in question, in addition to having global variables.  This
386aeeca8eSWarner Losh  * allows for future flexibility.
396aeeca8eSWarner Losh  */
406aeeca8eSWarner Losh class var_list
416aeeca8eSWarner Losh {
426aeeca8eSWarner Losh public:
436aeeca8eSWarner Losh 	/** Set a variable in this var list.
446aeeca8eSWarner Losh 	 */
456aeeca8eSWarner Losh 	void set_variable(const std::string &var, const std::string &val);
466aeeca8eSWarner Losh 	/** Get the variable out of this, and no other, var_list.  If
476aeeca8eSWarner Losh 	 * no variable of %var is set, then %bogus will be returned.
486aeeca8eSWarner Losh 	 */
496aeeca8eSWarner Losh 	const std::string &get_variable(const std::string &var) const;
506aeeca8eSWarner Losh 	/** Is there a variable of %var set in this table?
516aeeca8eSWarner Losh 	 */
526aeeca8eSWarner Losh 	bool is_set(const std::string &var) const;
536aeeca8eSWarner Losh 	/** A completely bogus string.
546aeeca8eSWarner Losh 	 */
556aeeca8eSWarner Losh 	static const std::string bogus;
566aeeca8eSWarner Losh 	static const std::string nothing;
57192af3b7SWarner Losh 
586aeeca8eSWarner Losh private:
59416823b1SWarner Losh 	std::string fix_value(const std::string &val) const;
60192af3b7SWarner Losh 
616aeeca8eSWarner Losh 	std::map<std::string, std::string> _vars;
626aeeca8eSWarner Losh };
636aeeca8eSWarner Losh 
646aeeca8eSWarner Losh /**
656aeeca8eSWarner Losh  * eps is short for event_proc_single.  It is a single entry in an
666aeeca8eSWarner Losh  * event_proc.  Each keyword needs its own subclass from eps.
676aeeca8eSWarner Losh  */
68b884d5e8SDimitry Andric struct eps
696aeeca8eSWarner Losh {
706aeeca8eSWarner Losh public:
~epseps716aeeca8eSWarner Losh 	virtual ~eps() {}
726aeeca8eSWarner Losh 	/** Does this eps match the current config?
736aeeca8eSWarner Losh 	 */
746aeeca8eSWarner Losh 	virtual bool do_match(config &) = 0;
756aeeca8eSWarner Losh 	/** Perform some action for this eps.
766aeeca8eSWarner Losh 	 */
776aeeca8eSWarner Losh 	virtual bool do_action(config &) = 0;
786aeeca8eSWarner Losh };
796aeeca8eSWarner Losh 
806aeeca8eSWarner Losh /**
816aeeca8eSWarner Losh  * match is the subclass used to match an individual variable.  Its
826aeeca8eSWarner Losh  * actions are nops.
836aeeca8eSWarner Losh  */
846aeeca8eSWarner Losh class match : public eps
856aeeca8eSWarner Losh {
866aeeca8eSWarner Losh public:
876aeeca8eSWarner Losh 	match(config &, const char *var, const char *re);
886aeeca8eSWarner Losh 	virtual ~match();
896aeeca8eSWarner Losh 	virtual bool do_match(config &);
do_action(config &)906aeeca8eSWarner Losh 	virtual bool do_action(config &) { return true; }
916aeeca8eSWarner Losh private:
925dfc0f6cSIan Lepore 	bool _inv;
936aeeca8eSWarner Losh 	std::string _var;
946aeeca8eSWarner Losh 	std::string _re;
956aeeca8eSWarner Losh 	regex_t _regex;
966aeeca8eSWarner Losh };
976aeeca8eSWarner Losh 
986aeeca8eSWarner Losh /**
99cd70782bSWarner Losh  * media is the subclass used to match an individual variable.  Its
100cd70782bSWarner Losh  * actions are nops.
101cd70782bSWarner Losh  */
102cd70782bSWarner Losh class media : public eps
103cd70782bSWarner Losh {
104cd70782bSWarner Losh public:
105cd70782bSWarner Losh 	media(config &, const char *var, const char *type);
106cd70782bSWarner Losh 	virtual ~media();
107cd70782bSWarner Losh 	virtual bool do_match(config &);
do_action(config &)108cd70782bSWarner Losh 	virtual bool do_action(config &) { return true; }
109cd70782bSWarner Losh private:
110cd70782bSWarner Losh 	std::string _var;
111cd70782bSWarner Losh 	int _type;
112cd70782bSWarner Losh };
113cd70782bSWarner Losh 
114cd70782bSWarner Losh /**
1156aeeca8eSWarner Losh  * action is used to fork a process.  It matches everything.
1166aeeca8eSWarner Losh  */
1176aeeca8eSWarner Losh class action : public eps
1186aeeca8eSWarner Losh {
1196aeeca8eSWarner Losh public:
1206aeeca8eSWarner Losh 	action(const char *cmd);
1216aeeca8eSWarner Losh 	virtual ~action();
do_match(config &)1226aeeca8eSWarner Losh 	virtual bool do_match(config &) { return true; }
1236aeeca8eSWarner Losh 	virtual bool do_action(config &);
1246aeeca8eSWarner Losh private:
1256aeeca8eSWarner Losh 	std::string _cmd;
1266aeeca8eSWarner Losh };
1276aeeca8eSWarner Losh 
128b884d5e8SDimitry Andric struct event_proc
1296aeeca8eSWarner Losh {
1306aeeca8eSWarner Losh public:
1316aeeca8eSWarner Losh 	event_proc();
1326aeeca8eSWarner Losh 	virtual ~event_proc();
get_priorityevent_proc1336aeeca8eSWarner Losh 	int get_priority() const { return (_prio); }
set_priorityevent_proc1346aeeca8eSWarner Losh 	void set_priority(int prio) { _prio = prio; }
1356aeeca8eSWarner Losh 	void add(eps *);
136ef370346SEitan Adler 	bool matches(config &) const;
137ef370346SEitan Adler 	bool run(config &) const;
1386aeeca8eSWarner Losh private:
1396aeeca8eSWarner Losh 	int _prio;
1406aeeca8eSWarner Losh 	std::vector<eps *> _epsvec;
1416aeeca8eSWarner Losh };
1426aeeca8eSWarner Losh 
1436aeeca8eSWarner Losh class config
1446aeeca8eSWarner Losh {
1456aeeca8eSWarner Losh public:
config()1466d58c721SEitan Adler 	config() { push_var_table(); }
~config()1477548968aSEitan Adler 	virtual ~config() { reset(); }
1486aeeca8eSWarner Losh 	void add_attach(int, event_proc *);
1496aeeca8eSWarner Losh 	void add_detach(int, event_proc *);
1506aeeca8eSWarner Losh 	void add_directory(const char *);
1516aeeca8eSWarner Losh 	void add_nomatch(int, event_proc *);
152842ccec5SWarner Losh 	void add_notify(int, event_proc *);
1536aeeca8eSWarner Losh 	void set_pidfile(const char *);
1546aeeca8eSWarner Losh 	void reset();
1556aeeca8eSWarner Losh 	void parse();
156b8f92ce4SWarner Losh 	void close_pidfile();
1571a0cc6b1SPawel Jakub Dawidek 	void open_pidfile();
1581a0cc6b1SPawel Jakub Dawidek 	void write_pidfile();
1591a0cc6b1SPawel Jakub Dawidek 	void remove_pidfile();
1606aeeca8eSWarner Losh 	void push_var_table();
1616aeeca8eSWarner Losh 	void pop_var_table();
1626aeeca8eSWarner Losh 	void set_variable(const char *var, const char *val);
1636aeeca8eSWarner Losh 	const std::string &get_variable(const std::string &var);
1645dfc0f6cSIan Lepore 	const std::string expand_string(const char * var,
1655dfc0f6cSIan Lepore 	    const char * prepend = NULL, const char * append = NULL);
1666aeeca8eSWarner Losh 	char *set_vars(char *);
1676aeeca8eSWarner Losh 	void find_and_execute(char);
1686aeeca8eSWarner Losh protected:
1696aeeca8eSWarner Losh 	void sort_vector(std::vector<event_proc *> &);
1706aeeca8eSWarner Losh 	void parse_one_file(const char *fn);
1716aeeca8eSWarner Losh 	void parse_files_in_dir(const char *dirname);
1726577e8c4SWarner Losh 	void expand_one(const char *&src, std::string &dst, bool is_shell);
17354aa4076SWarner Losh 	std::string shell_quote(const std::string &s);
174ef370346SEitan Adler 	bool is_id_char(char) const;
17511fd1366SEitan Adler 	bool chop_var(char *&buffer, char *&lhs, char *&rhs) const;
1766aeeca8eSWarner Losh private:
1776aeeca8eSWarner Losh 	std::vector<std::string> _dir_list;
1786aeeca8eSWarner Losh 	std::string _pidfile;
1796aeeca8eSWarner Losh 	std::vector<var_list *> _var_list_table;
1806aeeca8eSWarner Losh 	std::vector<event_proc *> _attach_list;
1816aeeca8eSWarner Losh 	std::vector<event_proc *> _detach_list;
1826aeeca8eSWarner Losh 	std::vector<event_proc *> _nomatch_list;
183842ccec5SWarner Losh 	std::vector<event_proc *> _notify_list;
1846aeeca8eSWarner Losh };
1856aeeca8eSWarner Losh 
1866aeeca8eSWarner Losh #endif /* DEVD_HH */
187