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: releng/10.3/sbin/devd/devd.hh 247760 2013-03-04 02:21:24Z eadler $
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	/** Set a variable in this var list.
45114086Simp	 */
46114086Simp	void set_variable(const std::string &var, const std::string &val);
47114086Simp	/** Get the variable out of this, and no other, var_list.  If
48114086Simp	 * no variable of %var is set, then %bogus will be returned.
49114086Simp	 */
50114086Simp	const std::string &get_variable(const std::string &var) const;
51114086Simp	/** Is there a variable of %var set in thi stable?
52114086Simp	 */
53114086Simp	bool is_set(const std::string &var) const;
54114086Simp	/** A completely bogus string.
55114086Simp	 */
56114086Simp	static const std::string bogus;
57114086Simp	static const std::string nothing;
58114086Simpprivate:
59114086Simp	std::map<std::string, std::string> _vars;
60114086Simp};
61114086Simp
62114086Simp/**
63114086Simp * eps is short for event_proc_single.  It is a single entry in an
64114086Simp * event_proc.  Each keyword needs its own subclass from eps.
65114086Simp */
66228618Sdimstruct eps
67114086Simp{
68114086Simppublic:
69114086Simp	virtual ~eps() {}
70114086Simp	/** Does this eps match the current config?
71114086Simp	 */
72114086Simp	virtual bool do_match(config &) = 0;
73114086Simp	/** Perform some action for this eps.
74114086Simp	 */
75114086Simp	virtual bool do_action(config &) = 0;
76114086Simp};
77114086Simp
78114086Simp/**
79114086Simp * match is the subclass used to match an individual variable.  Its
80114086Simp * actions are nops.
81114086Simp */
82114086Simpclass match : public eps
83114086Simp{
84114086Simppublic:
85114086Simp	match(config &, const char *var, const char *re);
86114086Simp	virtual ~match();
87114086Simp	virtual bool do_match(config &);
88114086Simp	virtual bool do_action(config &) { return true; }
89114086Simpprivate:
90246134Sian	bool _inv;
91114086Simp	std::string _var;
92114086Simp	std::string _re;
93114086Simp	regex_t _regex;
94114086Simp};
95114086Simp
96114086Simp/**
97147874Simp * media is the subclass used to match an individual variable.  Its
98147874Simp * actions are nops.
99147874Simp */
100147874Simpclass media : public eps
101147874Simp{
102147874Simppublic:
103147874Simp	media(config &, const char *var, const char *type);
104147874Simp	virtual ~media();
105147874Simp	virtual bool do_match(config &);
106147874Simp	virtual bool do_action(config &) { return true; }
107147874Simpprivate:
108147874Simp	std::string _var;
109147874Simp	int _type;
110147874Simp};
111147874Simp
112147874Simp/**
113114086Simp * action is used to fork a process.  It matches everything.
114114086Simp */
115114086Simpclass action : public eps
116114086Simp{
117114086Simppublic:
118114086Simp	action(const char *cmd);
119114086Simp	virtual ~action();
120114086Simp	virtual bool do_match(config &) { return true; }
121114086Simp	virtual bool do_action(config &);
122114086Simpprivate:
123114086Simp	std::string _cmd;
124114086Simp};
125114086Simp
126228618Sdimstruct event_proc
127114086Simp{
128114086Simppublic:
129114086Simp	event_proc();
130114086Simp	virtual ~event_proc();
131114086Simp	int get_priority() const { return (_prio); }
132114086Simp	void set_priority(int prio) { _prio = prio; }
133114086Simp	void add(eps *);
134243930Seadler	bool matches(config &) const;
135243930Seadler	bool run(config &) const;
136114086Simpprivate:
137114086Simp	int _prio;
138114086Simp	std::vector<eps *> _epsvec;
139114086Simp};
140114086Simp
141114086Simpclass config
142114086Simp{
143114086Simppublic:
144247757Seadler	config() { push_var_table(); }
145114086Simp	virtual ~config() { reset(); }
146114086Simp	void add_attach(int, event_proc *);
147114086Simp	void add_detach(int, event_proc *);
148114086Simp	void add_directory(const char *);
149114086Simp	void add_nomatch(int, event_proc *);
150121487Simp	void add_notify(int, event_proc *);
151114086Simp	void set_pidfile(const char *);
152114086Simp	void reset();
153114086Simp	void parse();
154209583Simp	void close_pidfile();
155155073Spjd	void open_pidfile();
156155073Spjd	void write_pidfile();
157155073Spjd	void remove_pidfile();
158114086Simp	void push_var_table();
159114086Simp	void pop_var_table();
160114086Simp	void set_variable(const char *var, const char *val);
161114086Simp	const std::string &get_variable(const std::string &var);
162246134Sian	const std::string expand_string(const char * var,
163246134Sian	    const char * prepend = NULL, const char * append = NULL);
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);
171243930Seadler	bool is_id_char(char) const;
172247751Seadler	bool chop_var(char *&buffer, char *&lhs, char *&rhs) const;
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