1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2002-2003 M. Warner Losh <imp@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 */ 29 30 #ifndef DEVD_HH 31 #define DEVD_HH 32 33 class config; 34 35 /** 36 * var_list is a collection of variables. These collections of variables 37 * are stacked up and popped down for each event that we have to process. 38 * We have multiple levels so that we can push variables that are unique 39 * to the event in question, in addition to having global variables. This 40 * allows for future flexibility. 41 */ 42 class var_list 43 { 44 public: 45 /** Set a variable in this var list. 46 */ 47 void set_variable(const std::string &var, const std::string &val); 48 /** Get the variable out of this, and no other, var_list. If 49 * no variable of %var is set, then %bogus will be returned. 50 */ 51 const std::string &get_variable(const std::string &var) const; 52 /** Is there a variable of %var set in this table? 53 */ 54 bool is_set(const std::string &var) const; 55 /** A completely bogus string. 56 */ 57 static const std::string bogus; 58 static const std::string nothing; 59 60 private: 61 std::string fix_value(const std::string &val) const; 62 63 std::map<std::string, std::string> _vars; 64 }; 65 66 /** 67 * eps is short for event_proc_single. It is a single entry in an 68 * event_proc. Each keyword needs its own subclass from eps. 69 */ 70 struct eps 71 { 72 public: 73 virtual ~eps() {} 74 /** Does this eps match the current config? 75 */ 76 virtual bool do_match(config &) = 0; 77 /** Perform some action for this eps. 78 */ 79 virtual bool do_action(config &) = 0; 80 }; 81 82 /** 83 * match is the subclass used to match an individual variable. Its 84 * actions are nops. 85 */ 86 class match : public eps 87 { 88 public: 89 match(config &, const char *var, const char *re); 90 virtual ~match(); 91 virtual bool do_match(config &); 92 virtual bool do_action(config &) { return true; } 93 private: 94 bool _inv; 95 std::string _var; 96 std::string _re; 97 regex_t _regex; 98 }; 99 100 /** 101 * media is the subclass used to match an individual variable. Its 102 * actions are nops. 103 */ 104 class media : public eps 105 { 106 public: 107 media(config &, const char *var, const char *type); 108 virtual ~media(); 109 virtual bool do_match(config &); 110 virtual bool do_action(config &) { return true; } 111 private: 112 std::string _var; 113 int _type; 114 }; 115 116 /** 117 * action is used to fork a process. It matches everything. 118 */ 119 class action : public eps 120 { 121 public: 122 action(const char *cmd); 123 virtual ~action(); 124 virtual bool do_match(config &) { return true; } 125 virtual bool do_action(config &); 126 private: 127 std::string _cmd; 128 }; 129 130 struct event_proc 131 { 132 public: 133 event_proc(); 134 virtual ~event_proc(); 135 int get_priority() const { return (_prio); } 136 void set_priority(int prio) { _prio = prio; } 137 void add(eps *); 138 bool matches(config &) const; 139 bool run(config &) const; 140 private: 141 int _prio; 142 std::vector<eps *> _epsvec; 143 }; 144 145 class config 146 { 147 public: 148 config() { push_var_table(); } 149 virtual ~config() { reset(); } 150 void add_attach(int, event_proc *); 151 void add_detach(int, event_proc *); 152 void add_directory(const char *); 153 void add_nomatch(int, event_proc *); 154 void add_notify(int, event_proc *); 155 void set_pidfile(const char *); 156 void reset(); 157 void parse(); 158 void close_pidfile(); 159 void open_pidfile(); 160 void write_pidfile(); 161 void remove_pidfile(); 162 void push_var_table(); 163 void pop_var_table(); 164 void set_variable(const char *var, const char *val); 165 const std::string &get_variable(const std::string &var); 166 const std::string expand_string(const char * var, 167 const char * prepend = NULL, const char * append = NULL); 168 char *set_vars(char *); 169 void find_and_execute(char); 170 protected: 171 void sort_vector(std::vector<event_proc *> &); 172 void parse_one_file(const char *fn); 173 void parse_files_in_dir(const char *dirname); 174 void expand_one(const char *&src, std::string &dst, bool is_shell); 175 std::string shell_quote(const std::string &s); 176 bool is_id_char(char) const; 177 bool chop_var(char *&buffer, char *&lhs, char *&rhs) const; 178 private: 179 std::vector<std::string> _dir_list; 180 std::string _pidfile; 181 std::vector<var_list *> _var_list_table; 182 std::vector<event_proc *> _attach_list; 183 std::vector<event_proc *> _detach_list; 184 std::vector<event_proc *> _nomatch_list; 185 std::vector<event_proc *> _notify_list; 186 }; 187 188 #endif /* DEVD_HH */ 189