devd.hh revision 174824
1114086Simp/*-
2114086Simp * Copyright (c) 2002-2003 M. Warner Losh.
3114086Simp * All rights reserved.
4114086Simp *
5114086Simp * Redistribution and use in source and binary forms, with or without
6114086Simp * modification, are permitted provided that the following conditions
7114086Simp * are met:
8114086Simp * 1. Redistributions of source code must retain the above copyright
9114086Simp *    notice, this list of conditions and the following disclaimer.
10114086Simp * 2. Redistributions in binary form must reproduce the above copyright
11114086Simp *    notice, this list of conditions and the following disclaimer in the
12114086Simp *    documentation and/or other materials provided with the distribution.
13114086Simp *
14114086Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15114086Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16114086Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17114086Simp * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18114086Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19114086Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20114086Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21114086Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22114086Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23114086Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24114086Simp * SUCH DAMAGE.
25114086Simp *
26114086Simp * $FreeBSD: head/sbin/devd/devd.hh 174824 2007-12-21 01:00:04Z imp $
27114086Simp */
28114086Simp
29114086Simp#ifndef DEVD_HH
30114086Simp#define DEVD_HH
31114086Simp
32114086Simpclass config;
33114086Simp
34114086Simp/**
35114086Simp * var_list is a collection of variables.  These collections of variables
36114086Simp * are stacked up and popped down for each event that we have to process.
37114086Simp * We have multiple levels so that we can push variables that are unique
38114086Simp * to the event in question, in addition to having global variables.  This
39114086Simp * allows for future flexibility.
40114086Simp */
41114086Simpclass var_list
42114086Simp{
43114086Simppublic:
44114086Simp	var_list() {}
45114086Simp	virtual ~var_list() {}
46114086Simp	/** Set a variable in this var list.
47114086Simp	 */
48114086Simp	void set_variable(const std::string &var, const std::string &val);
49114086Simp	/** Get the variable out of this, and no other, var_list.  If
50114086Simp	 * no variable of %var is set, then %bogus will be returned.
51114086Simp	 */
52114086Simp	const std::string &get_variable(const std::string &var) const;
53114086Simp	/** Is there a variable of %var set in thi stable?
54114086Simp	 */
55114086Simp	bool is_set(const std::string &var) const;
56114086Simp	/** A completely bogus string.
57114086Simp	 */
58114086Simp	static const std::string bogus;
59114086Simp	static const std::string nothing;
60114086Simpprivate:
61114086Simp	std::map<std::string, std::string> _vars;
62114086Simp};
63114086Simp
64114086Simp/**
65114086Simp * eps is short for event_proc_single.  It is a single entry in an
66114086Simp * event_proc.  Each keyword needs its own subclass from eps.
67114086Simp */
68114086Simpclass eps
69114086Simp{
70114086Simppublic:
71114086Simp	eps() {}
72114086Simp	virtual ~eps() {}
73114086Simp	/** Does this eps match the current config?
74114086Simp	 */
75114086Simp	virtual bool do_match(config &) = 0;
76114086Simp	/** Perform some action for this eps.
77114086Simp	 */
78114086Simp	virtual bool do_action(config &) = 0;
79114086Simp};
80114086Simp
81114086Simp/**
82114086Simp * match is the subclass used to match an individual variable.  Its
83114086Simp * actions are nops.
84114086Simp */
85114086Simpclass match : public eps
86114086Simp{
87114086Simppublic:
88114086Simp	match(config &, const char *var, const char *re);
89114086Simp	virtual ~match();
90114086Simp	virtual bool do_match(config &);
91114086Simp	virtual bool do_action(config &) { return true; }
92114086Simpprivate:
93114086Simp	std::string _var;
94114086Simp	std::string _re;
95114086Simp	regex_t _regex;
96114086Simp};
97114086Simp
98114086Simp/**
99147874Simp * media is the subclass used to match an individual variable.  Its
100147874Simp * actions are nops.
101147874Simp */
102147874Simpclass media : public eps
103147874Simp{
104147874Simppublic:
105147874Simp	media(config &, const char *var, const char *type);
106147874Simp	virtual ~media();
107147874Simp	virtual bool do_match(config &);
108147874Simp	virtual bool do_action(config &) { return true; }
109147874Simpprivate:
110147874Simp	std::string _var;
111147874Simp	int _type;
112147874Simp};
113147874Simp
114147874Simp/**
115114086Simp * action is used to fork a process.  It matches everything.
116114086Simp */
117114086Simpclass action : public eps
118114086Simp{
119114086Simppublic:
120114086Simp	action(const char *cmd);
121114086Simp	virtual ~action();
122114086Simp	virtual bool do_match(config &) { return true; }
123114086Simp	virtual bool do_action(config &);
124114086Simpprivate:
125114086Simp	std::string _cmd;
126114086Simp};
127114086Simp
128114086Simpclass event_proc
129114086Simp{
130114086Simppublic:
131114086Simp	event_proc();
132114086Simp	virtual ~event_proc();
133114086Simp	int get_priority() const { return (_prio); }
134114086Simp	void set_priority(int prio) { _prio = prio; }
135114086Simp	void add(eps *);
136114086Simp	bool matches(config &);
137114086Simp	bool run(config &);
138114086Simpprivate:
139114086Simp	int _prio;
140114086Simp	std::vector<eps *> _epsvec;
141114086Simp};
142114086Simp
143114086Simpclass config
144114086Simp{
145114086Simppublic:
146174824Simp	config() { _pidfile = ""; push_var_table(); }
147114086Simp	virtual ~config() { reset(); }
148114086Simp	void add_attach(int, event_proc *);
149114086Simp	void add_detach(int, event_proc *);
150114086Simp	void add_directory(const char *);
151114086Simp	void add_nomatch(int, event_proc *);
152121487Simp	void add_notify(int, event_proc *);
153114086Simp	void set_pidfile(const char *);
154114086Simp	void reset();
155114086Simp	void parse();
156155073Spjd	void open_pidfile();
157155073Spjd	void write_pidfile();
158155073Spjd	void remove_pidfile();
159114086Simp	void push_var_table();
160114086Simp	void pop_var_table();
161114086Simp	void set_variable(const char *var, const char *val);
162114086Simp	const std::string &get_variable(const std::string &var);
163114086Simp	const std::string expand_string(const std::string &var);
164114086Simp	char *set_vars(char *);
165114086Simp	void find_and_execute(char);
166114086Simpprotected:
167114086Simp	void sort_vector(std::vector<event_proc *> &);
168114086Simp	void parse_one_file(const char *fn);
169114086Simp	void parse_files_in_dir(const char *dirname);
170114086Simp	void expand_one(const char *&src, std::string &dst);
171114086Simp	bool is_id_char(char);
172114086Simp	bool chop_var(char *&buffer, char *&lhs, char *&rhs);
173114086Simpprivate:
174114086Simp	std::vector<std::string> _dir_list;
175114086Simp	std::string _pidfile;
176114086Simp	std::vector<var_list *> _var_list_table;
177114086Simp	std::vector<event_proc *> _attach_list;
178114086Simp	std::vector<event_proc *> _detach_list;
179114086Simp	std::vector<event_proc *> _nomatch_list;
180121487Simp	std::vector<event_proc *> _notify_list;
181114086Simp};
182114086Simp
183114086Simp#endif /* DEVD_HH */
184