author | Michael Krelin <hacker@klever.net> | 2004-07-09 16:48:52 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2004-07-09 16:48:52 (UTC) |
commit | 9148dac885c0325636c2d33715ba248371706d0d (patch) (side-by-side diff) | |
tree | fd95d60f6fd051c3ad46a966882e2be48440452f /src/configuration.cc | |
download | dudki-9148dac885c0325636c2d33715ba248371706d0d.zip dudki-9148dac885c0325636c2d33715ba248371706d0d.tar.gz dudki-9148dac885c0325636c2d33715ba248371706d0d.tar.bz2 |
dudki: initial import into svn repository
-rw-r--r-- | src/configuration.cc | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/configuration.cc b/src/configuration.cc new file mode 100644 index 0000000..eb010c1 --- a/dev/null +++ b/src/configuration.cc @@ -0,0 +1,149 @@ +#include <stdexcept> +using namespace std; +#include <dotconf.h> +#include "configuration.h" + +#ifndef DEFAULT_PID_FILE +# define DEFAULT_PID_FILE "/var/run/dudki.pid" +#endif + +configuration::configuration() + : check_interval(60), pidfile(DEFAULT_PID_FILE), + daemonize(true) { + } + +enum dc_ctx { + DCC_ROOT = 1, + DCC_PROCESS = 2 +}; +struct dc_context { + dc_ctx ctx; + configuration* cf; + process* ps; + + dc_context() + : ctx(DCC_ROOT), cf(NULL), ps(NULL) { } +}; + +static DOTCONF_CB(dco_check_interval) { dc_context *dcc = (dc_context*)ctx; + dcc->cf->check_interval = cmd->data.value; + return NULL; +} +static DOTCONF_CB(dco_daemonize) { dc_context *dcc = (dc_context*)ctx; + dcc->cf->daemonize = cmd->data.value; + return NULL; +} + +static DOTCONF_CB(dco_pid_file) { dc_context *dcc = (dc_context*)ctx; + switch(dcc->ctx) { + case DCC_ROOT: + dcc->cf->pidfile = cmd->data.str; + break; + case DCC_PROCESS: + dcc->ps->pidfile = cmd->data.str; + break; + default: + return "Unexpected PidFile"; + } + return NULL; +} +static DOTCONF_CB(dco_mailto_header) { dc_context *dcc = (dc_context*)ctx; + if(cmd->arg_count!=2) + return "Invalid number of arguments"; + string h = cmd->data.list[0]; + string v = cmd->data.list[1]; + switch(dcc->ctx) { + case DCC_ROOT: + dcc->cf->mailto_headers[h] = v; + break; + case DCC_PROCESS: + dcc->ps->mailto_headers[h] = v; + break; + default: + return "Unexpected MailtoHeader"; + } + return NULL; +} +static DOTCONF_CB(dco_notify) { dc_context *dcc = (dc_context*)ctx; + switch(dcc->ctx) { + case DCC_ROOT: + dcc->cf->notify = cmd->data.str; + break; + case DCC_PROCESS: + dcc->ps->notify = cmd->data.str; + break; + default: + return "Unexpected Notify"; + } + return NULL; +} + +static DOTCONF_CB(dco_process) { dc_context *dcc = (dc_context*)ctx; + string id = cmd->data.str; + if(id[id.length()-1]=='>') + id.erase(id.length()-1); + dcc->ps = &(dcc->cf->processes[id]); + dcc->ctx = DCC_PROCESS; + return NULL; +} +static DOTCONF_CB(dco__process) { dc_context *dcc = (dc_context*)ctx; + dcc->ps = NULL; + dcc->ctx = DCC_ROOT; + return NULL; +} + +static DOTCONF_CB(dco_restart_command) { dc_context *dcc = (dc_context*)ctx; + dcc->ps->restart_cmd = cmd->data.str; + return NULL; +} +static DOTCONF_CB(dco_user) { dc_context *dcc = (dc_context*)ctx; + dcc->ps->user = cmd->data.str; + return NULL; +} +static DOTCONF_CB(dco_group) { dc_context *dcc = (dc_context*)ctx; + dcc->ps->group = cmd->data.str; + return NULL; +} +static DOTCONF_CB(dco_chroot) { dc_context *dcc = (dc_context*)ctx; + dcc->ps->chroot = cmd->data.str; + return NULL; +} + +static const configoption_t dc_options[] = { + { "CheckInterval", ARG_INT, dco_check_interval, NULL, DCC_ROOT }, + { "Daemonize", ARG_TOGGLE, dco_daemonize, NULL, DCC_ROOT }, + { "PidFile", ARG_STR, dco_pid_file, NULL, DCC_ROOT|DCC_PROCESS }, + { "MailtoHeader", ARG_STR, dco_mailto_header, NULL, DCC_ROOT|DCC_PROCESS }, + { "Notify", ARG_STR, dco_notify, NULL, DCC_ROOT|DCC_PROCESS }, + { "<Process", ARG_STR, dco_process, NULL, DCC_ROOT }, + { "RestartCommand", ARG_STR, dco_restart_command, NULL, DCC_PROCESS }, + { "User", ARG_STR, dco_user, NULL, DCC_PROCESS }, + { "Group", ARG_STR, dco_group, NULL, DCC_PROCESS }, + { "Chroot", ARG_STR, dco_chroot, NULL, DCC_PROCESS }, + { "</Process>", ARG_NONE, dco__process, NULL, DCC_PROCESS }, + LAST_OPTION +}; + +static const char *dc_context_checker(command_t *cmd,unsigned long mask) { + dc_context *dcc = (dc_context*)cmd->context; + if( (mask==CTX_ALL) || ((mask&dcc->ctx)==dcc->ctx) ) + return NULL; + return "misplaced option"; +} +static FUNC_ERRORHANDLER(dc_error_handler) { + throw runtime_error(string("error parsing config file: ")+msg); +} + +void configuration::parse(const string& cfile) { + struct dc_context dcc; + dcc.cf = this; + dcc.ctx = DCC_ROOT; + configfile_t *cf = dotconf_create((char*)cfile.c_str(),dc_options,(context_t*)&dcc,CASE_INSENSITIVE); + if(!cf) + throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to dotconf_create()"); + cf->errorhandler = (dotconf_errorhandler_t) dc_error_handler; + cf->contextchecker = (dotconf_contextchecker_t) dc_context_checker; + if(!dotconf_command_loop(cf)) + throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to dotconf_command_loop()"); + dotconf_cleanup(cf); +} |