summaryrefslogtreecommitdiffabout
path: root/src/configuration.cc
Unidiff
Diffstat (limited to 'src/configuration.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--src/configuration.cc5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/configuration.cc b/src/configuration.cc
index eb010c1..edc8c04 100644
--- a/src/configuration.cc
+++ b/src/configuration.cc
@@ -1,149 +1,154 @@
1#include <stdexcept> 1#include <stdexcept>
2using namespace std; 2using namespace std;
3#include <dotconf.h> 3#include <dotconf.h>
4#include "configuration.h" 4#include "configuration.h"
5 5
6#ifndef DEFAULT_PID_FILE 6#ifndef DEFAULT_PID_FILE
7# define DEFAULT_PID_FILE "/var/run/dudki.pid" 7# define DEFAULT_PID_FILE "/var/run/dudki.pid"
8#endif 8#endif
9 9
10configuration::configuration() 10configuration::configuration()
11 : check_interval(60), pidfile(DEFAULT_PID_FILE), 11 : check_interval(60), pidfile(DEFAULT_PID_FILE),
12 daemonize(true) { 12 daemonize(true) {
13 } 13 }
14 14
15enum dc_ctx { 15enum dc_ctx {
16 DCC_ROOT = 1, 16 DCC_ROOT = 1,
17 DCC_PROCESS = 2 17 DCC_PROCESS = 2
18}; 18};
19struct dc_context { 19struct dc_context {
20 dc_ctx ctx; 20 dc_ctx ctx;
21 configuration* cf; 21 configuration* cf;
22 process* ps; 22 process* ps;
23 23
24 dc_context() 24 dc_context()
25 : ctx(DCC_ROOT), cf(NULL), ps(NULL) { } 25 : ctx(DCC_ROOT), cf(NULL), ps(NULL) { }
26}; 26};
27 27
28static DOTCONF_CB(dco_check_interval) { dc_context *dcc = (dc_context*)ctx; 28static DOTCONF_CB(dco_check_interval) { dc_context *dcc = (dc_context*)ctx;
29 dcc->cf->check_interval = cmd->data.value; 29 dcc->cf->check_interval = cmd->data.value;
30 return NULL; 30 return NULL;
31} 31}
32static DOTCONF_CB(dco_daemonize) { dc_context *dcc = (dc_context*)ctx; 32static DOTCONF_CB(dco_daemonize) { dc_context *dcc = (dc_context*)ctx;
33 dcc->cf->daemonize = cmd->data.value; 33 dcc->cf->daemonize = cmd->data.value;
34 return NULL; 34 return NULL;
35} 35}
36 36
37static DOTCONF_CB(dco_pid_file) { dc_context *dcc = (dc_context*)ctx; 37static DOTCONF_CB(dco_pid_file) { dc_context *dcc = (dc_context*)ctx;
38 switch(dcc->ctx) { 38 switch(dcc->ctx) {
39 case DCC_ROOT: 39 case DCC_ROOT:
40 dcc->cf->pidfile = cmd->data.str; 40 dcc->cf->pidfile = cmd->data.str;
41 break; 41 break;
42 case DCC_PROCESS: 42 case DCC_PROCESS:
43 dcc->ps->pidfile = cmd->data.str; 43 dcc->ps->pidfile = cmd->data.str;
44 break; 44 break;
45 default: 45 default:
46 return "Unexpected PidFile"; 46 return "Unexpected PidFile";
47 } 47 }
48 return NULL; 48 return NULL;
49} 49}
50static DOTCONF_CB(dco_mailto_header) { dc_context *dcc = (dc_context*)ctx; 50static DOTCONF_CB(dco_mailto_header) { dc_context *dcc = (dc_context*)ctx;
51 if(cmd->arg_count!=2) 51 if(cmd->arg_count!=2)
52 return "Invalid number of arguments"; 52 return "Invalid number of arguments";
53 string h = cmd->data.list[0]; 53 string h = cmd->data.list[0];
54 string v = cmd->data.list[1]; 54 string v = cmd->data.list[1];
55 switch(dcc->ctx) { 55 switch(dcc->ctx) {
56 case DCC_ROOT: 56 case DCC_ROOT:
57 dcc->cf->mailto_headers[h] = v; 57 dcc->cf->mailto_headers[h] = v;
58 break; 58 break;
59 case DCC_PROCESS: 59 case DCC_PROCESS:
60 dcc->ps->mailto_headers[h] = v; 60 dcc->ps->mailto_headers[h] = v;
61 break; 61 break;
62 default: 62 default:
63 return "Unexpected MailtoHeader"; 63 return "Unexpected MailtoHeader";
64 } 64 }
65 return NULL; 65 return NULL;
66} 66}
67static DOTCONF_CB(dco_notify) { dc_context *dcc = (dc_context*)ctx; 67static DOTCONF_CB(dco_notify) { dc_context *dcc = (dc_context*)ctx;
68 switch(dcc->ctx) { 68 switch(dcc->ctx) {
69 case DCC_ROOT: 69 case DCC_ROOT:
70 dcc->cf->notify = cmd->data.str; 70 dcc->cf->notify = cmd->data.str;
71 break; 71 break;
72 case DCC_PROCESS: 72 case DCC_PROCESS:
73 dcc->ps->notify = cmd->data.str; 73 dcc->ps->notify = cmd->data.str;
74 break; 74 break;
75 default: 75 default:
76 return "Unexpected Notify"; 76 return "Unexpected Notify";
77 } 77 }
78 return NULL; 78 return NULL;
79} 79}
80 80
81static DOTCONF_CB(dco_process) { dc_context *dcc = (dc_context*)ctx; 81static DOTCONF_CB(dco_process) { dc_context *dcc = (dc_context*)ctx;
82 string id = cmd->data.str; 82 string id = cmd->data.str;
83 if(id[id.length()-1]=='>') 83 if(id[id.length()-1]=='>')
84 id.erase(id.length()-1); 84 id.erase(id.length()-1);
85 dcc->ps = &(dcc->cf->processes[id]); 85 dcc->ps = &(dcc->cf->processes[id]);
86 dcc->ctx = DCC_PROCESS; 86 dcc->ctx = DCC_PROCESS;
87 return NULL; 87 return NULL;
88} 88}
89static DOTCONF_CB(dco__process) { dc_context *dcc = (dc_context*)ctx; 89static DOTCONF_CB(dco__process) { dc_context *dcc = (dc_context*)ctx;
90 dcc->ps = NULL; 90 dcc->ps = NULL;
91 dcc->ctx = DCC_ROOT; 91 dcc->ctx = DCC_ROOT;
92 return NULL; 92 return NULL;
93} 93}
94 94
95static DOTCONF_CB(dco_process_name) { dc_context *dcc = (dc_context*)ctx;
96 dcc->ps->process_name = cmd->data.str;
97 return NULL;
98}
95static DOTCONF_CB(dco_restart_command) { dc_context *dcc = (dc_context*)ctx; 99static DOTCONF_CB(dco_restart_command) { dc_context *dcc = (dc_context*)ctx;
96 dcc->ps->restart_cmd = cmd->data.str; 100 dcc->ps->restart_cmd = cmd->data.str;
97 return NULL; 101 return NULL;
98} 102}
99static DOTCONF_CB(dco_user) { dc_context *dcc = (dc_context*)ctx; 103static DOTCONF_CB(dco_user) { dc_context *dcc = (dc_context*)ctx;
100 dcc->ps->user = cmd->data.str; 104 dcc->ps->user = cmd->data.str;
101 return NULL; 105 return NULL;
102} 106}
103static DOTCONF_CB(dco_group) { dc_context *dcc = (dc_context*)ctx; 107static DOTCONF_CB(dco_group) { dc_context *dcc = (dc_context*)ctx;
104 dcc->ps->group = cmd->data.str; 108 dcc->ps->group = cmd->data.str;
105 return NULL; 109 return NULL;
106} 110}
107static DOTCONF_CB(dco_chroot) { dc_context *dcc = (dc_context*)ctx; 111static DOTCONF_CB(dco_chroot) { dc_context *dcc = (dc_context*)ctx;
108 dcc->ps->chroot = cmd->data.str; 112 dcc->ps->chroot = cmd->data.str;
109 return NULL; 113 return NULL;
110} 114}
111 115
112static const configoption_t dc_options[] = { 116static const configoption_t dc_options[] = {
113 { "CheckInterval", ARG_INT, dco_check_interval, NULL, DCC_ROOT }, 117 { "CheckInterval", ARG_INT, dco_check_interval, NULL, DCC_ROOT },
114 { "Daemonize", ARG_TOGGLE, dco_daemonize, NULL, DCC_ROOT }, 118 { "Daemonize", ARG_TOGGLE, dco_daemonize, NULL, DCC_ROOT },
115 { "PidFile", ARG_STR, dco_pid_file, NULL, DCC_ROOT|DCC_PROCESS }, 119 { "PidFile", ARG_STR, dco_pid_file, NULL, DCC_ROOT|DCC_PROCESS },
116 { "MailtoHeader", ARG_STR, dco_mailto_header, NULL, DCC_ROOT|DCC_PROCESS }, 120 { "MailtoHeader", ARG_STR, dco_mailto_header, NULL, DCC_ROOT|DCC_PROCESS },
117 { "Notify", ARG_STR, dco_notify, NULL, DCC_ROOT|DCC_PROCESS }, 121 { "Notify", ARG_STR, dco_notify, NULL, DCC_ROOT|DCC_PROCESS },
118 { "<Process", ARG_STR, dco_process, NULL, DCC_ROOT }, 122 { "<Process", ARG_STR, dco_process, NULL, DCC_ROOT },
123 { "ProcessName", ARG_STR, dco_process_name, NULL, DCC_PROCESS },
119 { "RestartCommand", ARG_STR, dco_restart_command, NULL, DCC_PROCESS }, 124 { "RestartCommand", ARG_STR, dco_restart_command, NULL, DCC_PROCESS },
120 { "User", ARG_STR, dco_user, NULL, DCC_PROCESS }, 125 { "User", ARG_STR, dco_user, NULL, DCC_PROCESS },
121 { "Group", ARG_STR, dco_group, NULL, DCC_PROCESS }, 126 { "Group", ARG_STR, dco_group, NULL, DCC_PROCESS },
122 { "Chroot", ARG_STR, dco_chroot, NULL, DCC_PROCESS }, 127 { "Chroot", ARG_STR, dco_chroot, NULL, DCC_PROCESS },
123 { "</Process>", ARG_NONE, dco__process, NULL, DCC_PROCESS }, 128 { "</Process>", ARG_NONE, dco__process, NULL, DCC_PROCESS },
124 LAST_OPTION 129 LAST_OPTION
125}; 130};
126 131
127static const char *dc_context_checker(command_t *cmd,unsigned long mask) { 132static const char *dc_context_checker(command_t *cmd,unsigned long mask) {
128 dc_context *dcc = (dc_context*)cmd->context; 133 dc_context *dcc = (dc_context*)cmd->context;
129 if( (mask==CTX_ALL) || ((mask&dcc->ctx)==dcc->ctx) ) 134 if( (mask==CTX_ALL) || ((mask&dcc->ctx)==dcc->ctx) )
130 return NULL; 135 return NULL;
131 return "misplaced option"; 136 return "misplaced option";
132} 137}
133static FUNC_ERRORHANDLER(dc_error_handler) { 138static FUNC_ERRORHANDLER(dc_error_handler) {
134 throw runtime_error(string("error parsing config file: ")+msg); 139 throw runtime_error(string("error parsing config file: ")+msg);
135} 140}
136 141
137void configuration::parse(const string& cfile) { 142void configuration::parse(const string& cfile) {
138 struct dc_context dcc; 143 struct dc_context dcc;
139 dcc.cf = this; 144 dcc.cf = this;
140 dcc.ctx = DCC_ROOT; 145 dcc.ctx = DCC_ROOT;
141 configfile_t *cf = dotconf_create((char*)cfile.c_str(),dc_options,(context_t*)&dcc,CASE_INSENSITIVE); 146 configfile_t *cf = dotconf_create((char*)cfile.c_str(),dc_options,(context_t*)&dcc,CASE_INSENSITIVE);
142 if(!cf) 147 if(!cf)
143 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to dotconf_create()"); 148 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to dotconf_create()");
144 cf->errorhandler = (dotconf_errorhandler_t) dc_error_handler; 149 cf->errorhandler = (dotconf_errorhandler_t) dc_error_handler;
145 cf->contextchecker = (dotconf_contextchecker_t) dc_context_checker; 150 cf->contextchecker = (dotconf_contextchecker_t) dc_context_checker;
146 if(!dotconf_command_loop(cf)) 151 if(!dotconf_command_loop(cf))
147 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to dotconf_command_loop()"); 152 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to dotconf_command_loop()");
148 dotconf_cleanup(cf); 153 dotconf_cleanup(cf);
149} 154}