1*3054f218SWarner Losh /*- 2*3054f218SWarner Losh * Copyright (c) 2002 M. Warner Losh. 3*3054f218SWarner Losh * All rights reserved. 4*3054f218SWarner Losh * 5*3054f218SWarner Losh * Redistribution and use in source and binary forms, with or without 6*3054f218SWarner Losh * modification, are permitted provided that the following conditions 7*3054f218SWarner Losh * are met: 8*3054f218SWarner Losh * 1. Redistributions of source code must retain the above copyright 9*3054f218SWarner Losh * notice, this list of conditions and the following disclaimer. 10*3054f218SWarner Losh * 2. Redistributions in binary form must reproduce the above copyright 11*3054f218SWarner Losh * notice, this list of conditions and the following disclaimer in the 12*3054f218SWarner Losh * documentation and/or other materials provided with the distribution. 13*3054f218SWarner Losh * 14*3054f218SWarner Losh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*3054f218SWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*3054f218SWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*3054f218SWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*3054f218SWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*3054f218SWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*3054f218SWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*3054f218SWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*3054f218SWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*3054f218SWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*3054f218SWarner Losh * SUCH DAMAGE. 25*3054f218SWarner Losh */ 26*3054f218SWarner Losh 27*3054f218SWarner Losh /* 28*3054f218SWarner Losh * DEVD control daemon. 29*3054f218SWarner Losh */ 30*3054f218SWarner Losh 31*3054f218SWarner Losh // TODO list: 32*3054f218SWarner Losh // o rewrite the main loop: 33*3054f218SWarner Losh // - expand variables 34*3054f218SWarner Losh // - find best match 35*3054f218SWarner Losh // - execute it. 36*3054f218SWarner Losh // o need to insert the event_proc structures in order of priority. 37*3054f218SWarner Losh // bigger numbers mean higher priority. 38*3054f218SWarner Losh // o devd.conf and devd man pages need a lot of help: 39*3054f218SWarner Losh // - devd.conf needs to lose the warning about zone files. 40*3054f218SWarner Losh // - devd.conf needs more details on the supported statements. 41*3054f218SWarner Losh // - devd.conf needs an example or two. 42*3054f218SWarner Losh 43*3054f218SWarner Losh #include <sys/cdefs.h> 44*3054f218SWarner Losh __FBSDID("$FreeBSD$"); 45*3054f218SWarner Losh 46*3054f218SWarner Losh #include <sys/param.h> 47*3054f218SWarner Losh #include <sys/types.h> 48*3054f218SWarner Losh 49*3054f218SWarner Losh #include <dirent.h> 50*3054f218SWarner Losh #include <errno.h> 51*3054f218SWarner Losh #include <err.h> 52*3054f218SWarner Losh #include <fcntl.h> 53*3054f218SWarner Losh #include <stdlib.h> 54*3054f218SWarner Losh #include <stdio.h> 55*3054f218SWarner Losh #include <string.h> 56*3054f218SWarner Losh #include <unistd.h> 57*3054f218SWarner Losh 58*3054f218SWarner Losh #include <map> 59*3054f218SWarner Losh #include <string> 60*3054f218SWarner Losh #include <vector> 61*3054f218SWarner Losh 62*3054f218SWarner Losh #include "devd.h" 63*3054f218SWarner Losh 64*3054f218SWarner Losh #define CF "/etc/devd.conf" 65*3054f218SWarner Losh 66*3054f218SWarner Losh using namespace std; 67*3054f218SWarner Losh 68*3054f218SWarner Losh extern FILE *yyin; 69*3054f218SWarner Losh extern int lineno; 70*3054f218SWarner Losh 71*3054f218SWarner Losh int dflag; 72*3054f218SWarner Losh int romeo_must_die = 0; 73*3054f218SWarner Losh 74*3054f218SWarner Losh static void event_loop(void); 75*3054f218SWarner Losh static void usage(void); 76*3054f218SWarner Losh 77*3054f218SWarner Losh class config; 78*3054f218SWarner Losh 79*3054f218SWarner Losh 80*3054f218SWarner Losh class var_list 81*3054f218SWarner Losh { 82*3054f218SWarner Losh public: 83*3054f218SWarner Losh var_list() {} 84*3054f218SWarner Losh virtual ~var_list() {} 85*3054f218SWarner Losh void set_variable(const string &var, const string &val); 86*3054f218SWarner Losh const string &get_variable(const string &var) const; 87*3054f218SWarner Losh bool is_set(const string &var) const; 88*3054f218SWarner Losh static const string bogus; 89*3054f218SWarner Losh static const string nothing; 90*3054f218SWarner Losh private: 91*3054f218SWarner Losh map<string, string> _vars; 92*3054f218SWarner Losh }; 93*3054f218SWarner Losh 94*3054f218SWarner Losh class eps 95*3054f218SWarner Losh { 96*3054f218SWarner Losh public: 97*3054f218SWarner Losh eps() {} 98*3054f218SWarner Losh virtual ~eps() {} 99*3054f218SWarner Losh virtual bool do_match(config &) = 0; 100*3054f218SWarner Losh virtual bool do_action(config &) = 0; 101*3054f218SWarner Losh }; 102*3054f218SWarner Losh 103*3054f218SWarner Losh class match : public eps 104*3054f218SWarner Losh { 105*3054f218SWarner Losh public: 106*3054f218SWarner Losh match(const char *var, const char *re); 107*3054f218SWarner Losh virtual ~match(); 108*3054f218SWarner Losh virtual bool do_match(config &); 109*3054f218SWarner Losh virtual bool do_action(config &) { return true; } 110*3054f218SWarner Losh private: 111*3054f218SWarner Losh string _var; 112*3054f218SWarner Losh string _re; 113*3054f218SWarner Losh }; 114*3054f218SWarner Losh 115*3054f218SWarner Losh class action : public eps 116*3054f218SWarner Losh { 117*3054f218SWarner Losh public: 118*3054f218SWarner Losh action(const char *cmd); 119*3054f218SWarner Losh virtual ~action(); 120*3054f218SWarner Losh virtual bool do_match(config &) { return true; } 121*3054f218SWarner Losh virtual bool do_action(config &); 122*3054f218SWarner Losh private: 123*3054f218SWarner Losh string _cmd; 124*3054f218SWarner Losh }; 125*3054f218SWarner Losh 126*3054f218SWarner Losh class event_proc 127*3054f218SWarner Losh { 128*3054f218SWarner Losh public: 129*3054f218SWarner Losh event_proc(); 130*3054f218SWarner Losh virtual ~event_proc(); 131*3054f218SWarner Losh int get_priority() { return (_prio); } 132*3054f218SWarner Losh void set_priority(int prio) { _prio = prio; } 133*3054f218SWarner Losh void add(eps *); 134*3054f218SWarner Losh bool matches(config &); 135*3054f218SWarner Losh bool run(config &); 136*3054f218SWarner Losh private: 137*3054f218SWarner Losh int _prio; 138*3054f218SWarner Losh vector<eps *> _epsvec; 139*3054f218SWarner Losh }; 140*3054f218SWarner Losh 141*3054f218SWarner Losh class config 142*3054f218SWarner Losh { 143*3054f218SWarner Losh public: 144*3054f218SWarner Losh config() : _pidfile("") { push_var_table(); } 145*3054f218SWarner Losh virtual ~config() { reset(); } 146*3054f218SWarner Losh void add_attach(int, event_proc *); 147*3054f218SWarner Losh void add_detach(int, event_proc *); 148*3054f218SWarner Losh void add_directory(const char *); 149*3054f218SWarner Losh void add_nomatch(int, event_proc *); 150*3054f218SWarner Losh void set_pidfile(const char *); 151*3054f218SWarner Losh void reset(); 152*3054f218SWarner Losh void parse(); 153*3054f218SWarner Losh void drop_pidfile(); 154*3054f218SWarner Losh void push_var_table(); 155*3054f218SWarner Losh void pop_var_table(); 156*3054f218SWarner Losh void set_variable(const char *var, const char *val); 157*3054f218SWarner Losh const string &get_variable(const string &var); 158*3054f218SWarner Losh const string &expand_string(const string &var); 159*3054f218SWarner Losh protected: 160*3054f218SWarner Losh void parse_one_file(const char *fn); 161*3054f218SWarner Losh void parse_files_in_dir(const char *dirname); 162*3054f218SWarner Losh private: 163*3054f218SWarner Losh vector<string> _dir_list; 164*3054f218SWarner Losh string _pidfile; 165*3054f218SWarner Losh vector<var_list *> _var_list_table; 166*3054f218SWarner Losh vector<event_proc *> _attach_list; 167*3054f218SWarner Losh vector<event_proc *> _detach_list; 168*3054f218SWarner Losh vector<event_proc *> _nomatch_list; 169*3054f218SWarner Losh }; 170*3054f218SWarner Losh 171*3054f218SWarner Losh config cfg; 172*3054f218SWarner Losh 173*3054f218SWarner Losh event_proc::event_proc() : _prio(-1) 174*3054f218SWarner Losh { 175*3054f218SWarner Losh // nothing 176*3054f218SWarner Losh } 177*3054f218SWarner Losh 178*3054f218SWarner Losh event_proc::~event_proc() 179*3054f218SWarner Losh { 180*3054f218SWarner Losh vector<eps *>::const_iterator i; 181*3054f218SWarner Losh 182*3054f218SWarner Losh for (i = _epsvec.begin(); i != _epsvec.end(); i++) 183*3054f218SWarner Losh delete *i; 184*3054f218SWarner Losh _epsvec.clear(); 185*3054f218SWarner Losh } 186*3054f218SWarner Losh 187*3054f218SWarner Losh void 188*3054f218SWarner Losh event_proc::add(eps *eps) 189*3054f218SWarner Losh { 190*3054f218SWarner Losh _epsvec.push_back(eps); 191*3054f218SWarner Losh } 192*3054f218SWarner Losh 193*3054f218SWarner Losh bool 194*3054f218SWarner Losh event_proc::matches(config &c) 195*3054f218SWarner Losh { 196*3054f218SWarner Losh vector<eps *>::const_iterator i; 197*3054f218SWarner Losh 198*3054f218SWarner Losh for (i = _epsvec.begin(); i != _epsvec.end(); i++) 199*3054f218SWarner Losh if (!(*i)->do_match(c)) 200*3054f218SWarner Losh return (false); 201*3054f218SWarner Losh return (true); 202*3054f218SWarner Losh } 203*3054f218SWarner Losh 204*3054f218SWarner Losh bool 205*3054f218SWarner Losh event_proc::run(config &c) 206*3054f218SWarner Losh { 207*3054f218SWarner Losh vector<eps *>::const_iterator i; 208*3054f218SWarner Losh 209*3054f218SWarner Losh for (i = _epsvec.begin(); i != _epsvec.end(); i++) 210*3054f218SWarner Losh if (!(*i)->do_action(c)) 211*3054f218SWarner Losh return (false); 212*3054f218SWarner Losh return (true); 213*3054f218SWarner Losh } 214*3054f218SWarner Losh 215*3054f218SWarner Losh action::action(const char *cmd) 216*3054f218SWarner Losh : _cmd(cmd) 217*3054f218SWarner Losh { 218*3054f218SWarner Losh // nothing 219*3054f218SWarner Losh } 220*3054f218SWarner Losh 221*3054f218SWarner Losh action::~action() 222*3054f218SWarner Losh { 223*3054f218SWarner Losh // nothing 224*3054f218SWarner Losh } 225*3054f218SWarner Losh 226*3054f218SWarner Losh bool 227*3054f218SWarner Losh action::do_action(config &) 228*3054f218SWarner Losh { 229*3054f218SWarner Losh // this is lame because we don't expand variables. 230*3054f218SWarner Losh // xxx 231*3054f218SWarner Losh ::system(_cmd.c_str()); 232*3054f218SWarner Losh return (true); 233*3054f218SWarner Losh } 234*3054f218SWarner Losh 235*3054f218SWarner Losh match::match(const char *var, const char *re) 236*3054f218SWarner Losh : _var(var), _re(re) 237*3054f218SWarner Losh { 238*3054f218SWarner Losh // nothing 239*3054f218SWarner Losh } 240*3054f218SWarner Losh 241*3054f218SWarner Losh match::~match() 242*3054f218SWarner Losh { 243*3054f218SWarner Losh // nothing 244*3054f218SWarner Losh } 245*3054f218SWarner Losh 246*3054f218SWarner Losh bool 247*3054f218SWarner Losh match::do_match(config &) 248*3054f218SWarner Losh { 249*3054f218SWarner Losh // XXX 250*3054f218SWarner Losh return false; 251*3054f218SWarner Losh } 252*3054f218SWarner Losh 253*3054f218SWarner Losh const string var_list::bogus = "_$_$_$_$_B_O_G_U_S_$_$_$_$_"; 254*3054f218SWarner Losh const string var_list::nothing = ""; 255*3054f218SWarner Losh 256*3054f218SWarner Losh const string & 257*3054f218SWarner Losh var_list::get_variable(const string &var) const 258*3054f218SWarner Losh { 259*3054f218SWarner Losh map<string, string>::const_iterator i; 260*3054f218SWarner Losh 261*3054f218SWarner Losh i = _vars.find(var); 262*3054f218SWarner Losh if (i == _vars.end()) 263*3054f218SWarner Losh return var_list::bogus; 264*3054f218SWarner Losh return (i->second); 265*3054f218SWarner Losh } 266*3054f218SWarner Losh 267*3054f218SWarner Losh bool 268*3054f218SWarner Losh var_list::is_set(const string &var) const 269*3054f218SWarner Losh { 270*3054f218SWarner Losh return (_vars.find(var) != _vars.end()); 271*3054f218SWarner Losh } 272*3054f218SWarner Losh 273*3054f218SWarner Losh void 274*3054f218SWarner Losh var_list::set_variable(const string &var, const string &val) 275*3054f218SWarner Losh { 276*3054f218SWarner Losh _vars[var] = val; 277*3054f218SWarner Losh } 278*3054f218SWarner Losh 279*3054f218SWarner Losh void 280*3054f218SWarner Losh config::reset(void) 281*3054f218SWarner Losh { 282*3054f218SWarner Losh _dir_list.clear(); 283*3054f218SWarner Losh _var_list_table.clear(); 284*3054f218SWarner Losh // XXX need to cleanup _{attach,detach,nomatch}_list 285*3054f218SWarner Losh } 286*3054f218SWarner Losh 287*3054f218SWarner Losh void 288*3054f218SWarner Losh config::parse_one_file(const char *fn) 289*3054f218SWarner Losh { 290*3054f218SWarner Losh if (dflag) 291*3054f218SWarner Losh printf("Parsing %s\n", fn); 292*3054f218SWarner Losh yyin = fopen(fn, "r"); 293*3054f218SWarner Losh if (yyin == NULL) 294*3054f218SWarner Losh err(1, "Cannot open config file %s", fn); 295*3054f218SWarner Losh if (yyparse() != 0) 296*3054f218SWarner Losh errx(1, "Cannot parse %s at line %d", fn, lineno); 297*3054f218SWarner Losh fclose(yyin); 298*3054f218SWarner Losh } 299*3054f218SWarner Losh 300*3054f218SWarner Losh void 301*3054f218SWarner Losh config::parse_files_in_dir(const char *dirname) 302*3054f218SWarner Losh { 303*3054f218SWarner Losh DIR *dirp; 304*3054f218SWarner Losh struct dirent *dp; 305*3054f218SWarner Losh char path[PATH_MAX]; 306*3054f218SWarner Losh 307*3054f218SWarner Losh if (dflag) 308*3054f218SWarner Losh printf("Parsing files in %s\n", dirname); 309*3054f218SWarner Losh dirp = opendir(dirname); 310*3054f218SWarner Losh if (dirp == NULL) 311*3054f218SWarner Losh return; 312*3054f218SWarner Losh readdir(dirp); /* Skip . */ 313*3054f218SWarner Losh readdir(dirp); /* Skip .. */ 314*3054f218SWarner Losh while ((dp = readdir(dirp)) != NULL) { 315*3054f218SWarner Losh if (strcmp(dp->d_name + dp->d_namlen - 5, ".conf") == 0) { 316*3054f218SWarner Losh snprintf(path, sizeof(path), "%s/%s", 317*3054f218SWarner Losh dirname, dp->d_name); 318*3054f218SWarner Losh parse_one_file(path); 319*3054f218SWarner Losh } 320*3054f218SWarner Losh } 321*3054f218SWarner Losh } 322*3054f218SWarner Losh 323*3054f218SWarner Losh void 324*3054f218SWarner Losh config::parse(void) 325*3054f218SWarner Losh { 326*3054f218SWarner Losh vector<string>::const_iterator i; 327*3054f218SWarner Losh 328*3054f218SWarner Losh parse_one_file(CF); 329*3054f218SWarner Losh for (i = _dir_list.begin(); i != _dir_list.end(); i++) 330*3054f218SWarner Losh parse_files_in_dir((*i).c_str()); 331*3054f218SWarner Losh } 332*3054f218SWarner Losh 333*3054f218SWarner Losh void 334*3054f218SWarner Losh config::drop_pidfile() 335*3054f218SWarner Losh { 336*3054f218SWarner Losh FILE *fp; 337*3054f218SWarner Losh 338*3054f218SWarner Losh if (_pidfile == "") 339*3054f218SWarner Losh return; 340*3054f218SWarner Losh fp = fopen(_pidfile.c_str(), "w"); 341*3054f218SWarner Losh if (fp == NULL) 342*3054f218SWarner Losh return; 343*3054f218SWarner Losh fprintf(fp, "%d\n", getpid()); 344*3054f218SWarner Losh fclose(fp); 345*3054f218SWarner Losh } 346*3054f218SWarner Losh 347*3054f218SWarner Losh void 348*3054f218SWarner Losh config::add_attach(int prio, event_proc *p) 349*3054f218SWarner Losh { 350*3054f218SWarner Losh p->set_priority(prio); 351*3054f218SWarner Losh _attach_list.push_back(p); 352*3054f218SWarner Losh } 353*3054f218SWarner Losh 354*3054f218SWarner Losh void 355*3054f218SWarner Losh config::add_detach(int prio, event_proc *p) 356*3054f218SWarner Losh { 357*3054f218SWarner Losh p->set_priority(prio); 358*3054f218SWarner Losh _detach_list.push_back(p); 359*3054f218SWarner Losh } 360*3054f218SWarner Losh 361*3054f218SWarner Losh void 362*3054f218SWarner Losh config::add_directory(const char *dir) 363*3054f218SWarner Losh { 364*3054f218SWarner Losh _dir_list.push_back(string(dir)); 365*3054f218SWarner Losh } 366*3054f218SWarner Losh 367*3054f218SWarner Losh void 368*3054f218SWarner Losh config::add_nomatch(int prio, event_proc *p) 369*3054f218SWarner Losh { 370*3054f218SWarner Losh p->set_priority(prio); 371*3054f218SWarner Losh _nomatch_list.push_back(p); 372*3054f218SWarner Losh } 373*3054f218SWarner Losh 374*3054f218SWarner Losh void 375*3054f218SWarner Losh config::set_pidfile(const char *fn) 376*3054f218SWarner Losh { 377*3054f218SWarner Losh _pidfile = string(fn); 378*3054f218SWarner Losh } 379*3054f218SWarner Losh 380*3054f218SWarner Losh void 381*3054f218SWarner Losh config::push_var_table() 382*3054f218SWarner Losh { 383*3054f218SWarner Losh var_list *vl; 384*3054f218SWarner Losh 385*3054f218SWarner Losh vl = new var_list(); 386*3054f218SWarner Losh _var_list_table.push_back(vl); 387*3054f218SWarner Losh } 388*3054f218SWarner Losh 389*3054f218SWarner Losh void 390*3054f218SWarner Losh config::pop_var_table() 391*3054f218SWarner Losh { 392*3054f218SWarner Losh delete _var_list_table.back(); 393*3054f218SWarner Losh _var_list_table.pop_back(); 394*3054f218SWarner Losh } 395*3054f218SWarner Losh 396*3054f218SWarner Losh void 397*3054f218SWarner Losh config::set_variable(const char *var, const char *val) 398*3054f218SWarner Losh { 399*3054f218SWarner Losh _var_list_table.back()->set_variable(var, val); 400*3054f218SWarner Losh } 401*3054f218SWarner Losh 402*3054f218SWarner Losh const string & 403*3054f218SWarner Losh config::get_variable(const string &var) 404*3054f218SWarner Losh { 405*3054f218SWarner Losh vector<var_list *>::reverse_iterator i; 406*3054f218SWarner Losh 407*3054f218SWarner Losh for (i = _var_list_table.rbegin(); i != _var_list_table.rend(); i++) { 408*3054f218SWarner Losh if ((*i)->is_set(var)) 409*3054f218SWarner Losh return (var); 410*3054f218SWarner Losh } 411*3054f218SWarner Losh return (var_list::nothing); 412*3054f218SWarner Losh } 413*3054f218SWarner Losh 414*3054f218SWarner Losh const string & 415*3054f218SWarner Losh config::expand_string(const string &) 416*3054f218SWarner Losh { 417*3054f218SWarner Losh return var_list::bogus; 418*3054f218SWarner Losh } 419*3054f218SWarner Losh 420*3054f218SWarner Losh 421*3054f218SWarner Losh static void 422*3054f218SWarner Losh process_event(const char *buffer) 423*3054f218SWarner Losh { 424*3054f218SWarner Losh char type; 425*3054f218SWarner Losh char cmd[1024]; 426*3054f218SWarner Losh char *sp; 427*3054f218SWarner Losh 428*3054f218SWarner Losh // XXX should involve config 429*3054f218SWarner Losh // XXX and set some variables 430*3054f218SWarner Losh // XXX run the list and so forth 431*3054f218SWarner Losh 432*3054f218SWarner Losh // Ignore unknown devices for now. 433*3054f218SWarner Losh if (*buffer == '?') 434*3054f218SWarner Losh return; 435*3054f218SWarner Losh type = *buffer++; 436*3054f218SWarner Losh sp = strchr(buffer, ' '); 437*3054f218SWarner Losh if (sp == NULL) 438*3054f218SWarner Losh return; /* Can't happen? */ 439*3054f218SWarner Losh *sp = '\0'; 440*3054f218SWarner Losh snprintf(cmd, sizeof(cmd), "/etc/devd-generic %s %s", buffer, 441*3054f218SWarner Losh type == '+' ? "start" : "stop"); 442*3054f218SWarner Losh if (dflag) 443*3054f218SWarner Losh printf("Trying '%s'\n", cmd); 444*3054f218SWarner Losh system(cmd); 445*3054f218SWarner Losh } 446*3054f218SWarner Losh 447*3054f218SWarner Losh static void 448*3054f218SWarner Losh event_loop(void) 449*3054f218SWarner Losh { 450*3054f218SWarner Losh int rv; 451*3054f218SWarner Losh int fd; 452*3054f218SWarner Losh char buffer[DEVCTL_MAXBUF]; 453*3054f218SWarner Losh 454*3054f218SWarner Losh fd = open(PATH_DEVCTL, O_RDONLY); 455*3054f218SWarner Losh if (fd == -1) 456*3054f218SWarner Losh err(1, "Can't open devctl"); 457*3054f218SWarner Losh if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) 458*3054f218SWarner Losh err(1, "Can't set close-on-exec flag"); 459*3054f218SWarner Losh while (1) { 460*3054f218SWarner Losh if (romeo_must_die) 461*3054f218SWarner Losh break; 462*3054f218SWarner Losh rv = read(fd, buffer, sizeof(buffer) - 1); 463*3054f218SWarner Losh if (rv > 0) { 464*3054f218SWarner Losh buffer[rv] = '\0'; 465*3054f218SWarner Losh while (buffer[--rv] == '\n') 466*3054f218SWarner Losh buffer[rv] = '\0'; 467*3054f218SWarner Losh process_event(buffer); 468*3054f218SWarner Losh } else if (rv < 0) { 469*3054f218SWarner Losh if (errno != EINTR) 470*3054f218SWarner Losh break; 471*3054f218SWarner Losh } else { 472*3054f218SWarner Losh /* EOF */ 473*3054f218SWarner Losh break; 474*3054f218SWarner Losh } 475*3054f218SWarner Losh } 476*3054f218SWarner Losh close(fd); 477*3054f218SWarner Losh } 478*3054f218SWarner Losh 479*3054f218SWarner Losh /* 480*3054f218SWarner Losh * functions that the parser uses. 481*3054f218SWarner Losh */ 482*3054f218SWarner Losh void 483*3054f218SWarner Losh add_attach(int prio, event_proc *p) 484*3054f218SWarner Losh { 485*3054f218SWarner Losh cfg.add_attach(prio, p); 486*3054f218SWarner Losh } 487*3054f218SWarner Losh 488*3054f218SWarner Losh void 489*3054f218SWarner Losh add_detach(int prio, event_proc *p) 490*3054f218SWarner Losh { 491*3054f218SWarner Losh cfg.add_detach(prio, p); 492*3054f218SWarner Losh } 493*3054f218SWarner Losh 494*3054f218SWarner Losh void 495*3054f218SWarner Losh add_directory(const char *dir) 496*3054f218SWarner Losh { 497*3054f218SWarner Losh cfg.add_directory(dir); 498*3054f218SWarner Losh free(const_cast<char *>(dir)); 499*3054f218SWarner Losh } 500*3054f218SWarner Losh 501*3054f218SWarner Losh void 502*3054f218SWarner Losh add_nomatch(int prio, event_proc *p) 503*3054f218SWarner Losh { 504*3054f218SWarner Losh cfg.add_nomatch(prio, p); 505*3054f218SWarner Losh } 506*3054f218SWarner Losh 507*3054f218SWarner Losh event_proc * 508*3054f218SWarner Losh add_to_event_proc(event_proc *ep, eps *eps) 509*3054f218SWarner Losh { 510*3054f218SWarner Losh if (ep == NULL) 511*3054f218SWarner Losh ep = new event_proc(); 512*3054f218SWarner Losh ep->add(eps); 513*3054f218SWarner Losh return (ep); 514*3054f218SWarner Losh } 515*3054f218SWarner Losh 516*3054f218SWarner Losh eps * 517*3054f218SWarner Losh new_action(const char *cmd) 518*3054f218SWarner Losh { 519*3054f218SWarner Losh eps *e = new action(cmd); 520*3054f218SWarner Losh free(const_cast<char *>(cmd)); 521*3054f218SWarner Losh return (e); 522*3054f218SWarner Losh } 523*3054f218SWarner Losh 524*3054f218SWarner Losh eps * 525*3054f218SWarner Losh new_match(const char *var, const char *re) 526*3054f218SWarner Losh { 527*3054f218SWarner Losh eps *e = new match(var, re); 528*3054f218SWarner Losh free(const_cast<char *>(var)); 529*3054f218SWarner Losh free(const_cast<char *>(re)); 530*3054f218SWarner Losh return (e); 531*3054f218SWarner Losh } 532*3054f218SWarner Losh 533*3054f218SWarner Losh void 534*3054f218SWarner Losh set_pidfile(const char *name) 535*3054f218SWarner Losh { 536*3054f218SWarner Losh cfg.set_pidfile(name); 537*3054f218SWarner Losh free(const_cast<char *>(name)); 538*3054f218SWarner Losh } 539*3054f218SWarner Losh 540*3054f218SWarner Losh void 541*3054f218SWarner Losh set_variable(const char *var, const char *val) 542*3054f218SWarner Losh { 543*3054f218SWarner Losh cfg.set_variable(var, val); 544*3054f218SWarner Losh free(const_cast<char *>(var)); 545*3054f218SWarner Losh free(const_cast<char *>(val)); 546*3054f218SWarner Losh } 547*3054f218SWarner Losh 548*3054f218SWarner Losh 549*3054f218SWarner Losh 550*3054f218SWarner Losh static void 551*3054f218SWarner Losh gensighand(int) 552*3054f218SWarner Losh { 553*3054f218SWarner Losh romeo_must_die++; 554*3054f218SWarner Losh _exit(0); 555*3054f218SWarner Losh } 556*3054f218SWarner Losh 557*3054f218SWarner Losh static void 558*3054f218SWarner Losh usage() 559*3054f218SWarner Losh { 560*3054f218SWarner Losh fprintf(stderr, "usage: %s [-d]", getprogname()); 561*3054f218SWarner Losh exit(1); 562*3054f218SWarner Losh } 563*3054f218SWarner Losh 564*3054f218SWarner Losh /* 565*3054f218SWarner Losh * main 566*3054f218SWarner Losh */ 567*3054f218SWarner Losh int 568*3054f218SWarner Losh main(int argc, char **argv) 569*3054f218SWarner Losh { 570*3054f218SWarner Losh int ch; 571*3054f218SWarner Losh 572*3054f218SWarner Losh while ((ch = getopt(argc, argv, "d")) != -1) { 573*3054f218SWarner Losh switch (ch) { 574*3054f218SWarner Losh case 'd': 575*3054f218SWarner Losh dflag++; 576*3054f218SWarner Losh break; 577*3054f218SWarner Losh default: 578*3054f218SWarner Losh usage(); 579*3054f218SWarner Losh } 580*3054f218SWarner Losh } 581*3054f218SWarner Losh 582*3054f218SWarner Losh cfg.parse(); 583*3054f218SWarner Losh if (!dflag) 584*3054f218SWarner Losh daemon(0, 0); 585*3054f218SWarner Losh cfg.drop_pidfile(); 586*3054f218SWarner Losh signal(SIGHUP, gensighand); 587*3054f218SWarner Losh signal(SIGINT, gensighand); 588*3054f218SWarner Losh signal(SIGTERM, gensighand); 589*3054f218SWarner Losh event_loop(); 590*3054f218SWarner Losh return (0); 591*3054f218SWarner Losh } 592