devd.hh revision 121487
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 121487 2003-10-24 22:02:29Z 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/**
99114086Simp * action is used to fork a process.  It matches everything.
100114086Simp */
101114086Simpclass action : public eps
102114086Simp{
103114086Simppublic:
104114086Simp	action(const char *cmd);
105114086Simp	virtual ~action();
106114086Simp	virtual bool do_match(config &) { return true; }
107114086Simp	virtual bool do_action(config &);
108114086Simpprivate:
109114086Simp	std::string _cmd;
110114086Simp};
111114086Simp
112114086Simpclass event_proc
113114086Simp{
114114086Simppublic:
115114086Simp	event_proc();
116114086Simp	virtual ~event_proc();
117114086Simp	int get_priority() const { return (_prio); }
118114086Simp	void set_priority(int prio) { _prio = prio; }
119114086Simp	void add(eps *);
120114086Simp	bool matches(config &);
121114086Simp	bool run(config &);
122114086Simpprivate:
123114086Simp	int _prio;
124114086Simp	std::vector<eps *> _epsvec;
125114086Simp};
126114086Simp
127114086Simpclass config
128114086Simp{
129114086Simppublic:
130114086Simp	config() : _pidfile("") { push_var_table(); }
131114086Simp	virtual ~config() { reset(); }
132114086Simp	void add_attach(int, event_proc *);
133114086Simp	void add_detach(int, event_proc *);
134114086Simp	void add_directory(const char *);
135114086Simp	void add_nomatch(int, event_proc *);
136121487Simp	void add_notify(int, event_proc *);
137114086Simp	void set_pidfile(const char *);
138114086Simp	void reset();
139114086Simp	void parse();
140114086Simp	void drop_pidfile();
141114086Simp	void push_var_table();
142114086Simp	void pop_var_table();
143114086Simp	void set_variable(const char *var, const char *val);
144114086Simp	const std::string &get_variable(const std::string &var);
145114086Simp	const std::string expand_string(const std::string &var);
146114086Simp	char *set_vars(char *);
147114086Simp	void find_and_execute(char);
148114086Simpprotected:
149114086Simp	void sort_vector(std::vector<event_proc *> &);
150114086Simp	void parse_one_file(const char *fn);
151114086Simp	void parse_files_in_dir(const char *dirname);
152114086Simp	void expand_one(const char *&src, std::string &dst);
153114086Simp	bool is_id_char(char);
154114086Simp	bool chop_var(char *&buffer, char *&lhs, char *&rhs);
155114086Simpprivate:
156114086Simp	std::vector<std::string> _dir_list;
157114086Simp	std::string _pidfile;
158114086Simp	std::vector<var_list *> _var_list_table;
159114086Simp	std::vector<event_proc *> _attach_list;
160114086Simp	std::vector<event_proc *> _detach_list;
161114086Simp	std::vector<event_proc *> _nomatch_list;
162121487Simp	std::vector<event_proc *> _notify_list;
163114086Simp};
164114086Simp
165114086Simp#endif /* DEVD_HH */
166