1114086Simp/*-
2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3330449Seadler *
4114086Simp * Copyright (c) 2002-2003 M. Warner Losh.
5114086Simp * All rights reserved.
6114086Simp *
7114086Simp * Redistribution and use in source and binary forms, with or without
8114086Simp * modification, are permitted provided that the following conditions
9114086Simp * are met:
10114086Simp * 1. Redistributions of source code must retain the above copyright
11114086Simp *    notice, this list of conditions and the following disclaimer.
12114086Simp * 2. Redistributions in binary form must reproduce the above copyright
13114086Simp *    notice, this list of conditions and the following disclaimer in the
14114086Simp *    documentation and/or other materials provided with the distribution.
15114086Simp *
16114086Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17114086Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18114086Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19114086Simp * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20114086Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21114086Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22114086Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23114086Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24114086Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25114086Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26114086Simp * SUCH DAMAGE.
27114086Simp *
28114086Simp * $FreeBSD: stable/11/sbin/devd/devd.hh 330449 2018-03-05 07:26:05Z eadler $
29114086Simp */
30114086Simp
31114086Simp#ifndef DEVD_HH
32114086Simp#define DEVD_HH
33114086Simp
34114086Simpclass config;
35114086Simp
36114086Simp/**
37114086Simp * var_list is a collection of variables.  These collections of variables
38114086Simp * are stacked up and popped down for each event that we have to process.
39114086Simp * We have multiple levels so that we can push variables that are unique
40114086Simp * to the event in question, in addition to having global variables.  This
41114086Simp * allows for future flexibility.
42114086Simp */
43114086Simpclass var_list
44114086Simp{
45114086Simppublic:
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 */
68228618Sdimstruct eps
69114086Simp{
70114086Simppublic:
71114086Simp	virtual ~eps() {}
72114086Simp	/** Does this eps match the current config?
73114086Simp	 */
74114086Simp	virtual bool do_match(config &) = 0;
75114086Simp	/** Perform some action for this eps.
76114086Simp	 */
77114086Simp	virtual bool do_action(config &) = 0;
78114086Simp};
79114086Simp
80114086Simp/**
81114086Simp * match is the subclass used to match an individual variable.  Its
82114086Simp * actions are nops.
83114086Simp */
84114086Simpclass match : public eps
85114086Simp{
86114086Simppublic:
87114086Simp	match(config &, const char *var, const char *re);
88114086Simp	virtual ~match();
89114086Simp	virtual bool do_match(config &);
90114086Simp	virtual bool do_action(config &) { return true; }
91114086Simpprivate:
92246134Sian	bool _inv;
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
128228618Sdimstruct 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 *);
136243930Seadler	bool matches(config &) const;
137243930Seadler	bool run(config &) const;
138114086Simpprivate:
139114086Simp	int _prio;
140114086Simp	std::vector<eps *> _epsvec;
141114086Simp};
142114086Simp
143114086Simpclass config
144114086Simp{
145114086Simppublic:
146247757Seadler	config() { 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();
156209583Simp	void close_pidfile();
157155073Spjd	void open_pidfile();
158155073Spjd	void write_pidfile();
159155073Spjd	void remove_pidfile();
160114086Simp	void push_var_table();
161114086Simp	void pop_var_table();
162114086Simp	void set_variable(const char *var, const char *val);
163114086Simp	const std::string &get_variable(const std::string &var);
164246134Sian	const std::string expand_string(const char * var,
165246134Sian	    const char * prepend = NULL, const char * append = NULL);
166114086Simp	char *set_vars(char *);
167114086Simp	void find_and_execute(char);
168114086Simpprotected:
169114086Simp	void sort_vector(std::vector<event_proc *> &);
170114086Simp	void parse_one_file(const char *fn);
171114086Simp	void parse_files_in_dir(const char *dirname);
172114086Simp	void expand_one(const char *&src, std::string &dst);
173243930Seadler	bool is_id_char(char) const;
174247751Seadler	bool chop_var(char *&buffer, char *&lhs, char *&rhs) const;
175114086Simpprivate:
176114086Simp	std::vector<std::string> _dir_list;
177114086Simp	std::string _pidfile;
178114086Simp	std::vector<var_list *> _var_list_table;
179114086Simp	std::vector<event_proc *> _attach_list;
180114086Simp	std::vector<event_proc *> _detach_list;
181114086Simp	std::vector<event_proc *> _nomatch_list;
182121487Simp	std::vector<event_proc *> _notify_list;
183114086Simp};
184114086Simp
185114086Simp#endif /* DEVD_HH */
186