-rw-r--r-- | src/configuration.cc | 5 |
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> |
2 | using namespace std; | 2 | using 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 | ||
10 | configuration::configuration() | 10 | configuration::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 | ||
15 | enum dc_ctx { | 15 | enum dc_ctx { |
16 | DCC_ROOT = 1, | 16 | DCC_ROOT = 1, |
17 | DCC_PROCESS = 2 | 17 | DCC_PROCESS = 2 |
18 | }; | 18 | }; |
19 | struct dc_context { | 19 | struct 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 | ||
28 | static DOTCONF_CB(dco_check_interval) { dc_context *dcc = (dc_context*)ctx; | 28 | static 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 | } |
32 | static DOTCONF_CB(dco_daemonize) { dc_context *dcc = (dc_context*)ctx; | 32 | static 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 | ||
37 | static DOTCONF_CB(dco_pid_file) { dc_context *dcc = (dc_context*)ctx; | 37 | static 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 | } |
50 | static DOTCONF_CB(dco_mailto_header) { dc_context *dcc = (dc_context*)ctx; | 50 | static 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 | } |
67 | static DOTCONF_CB(dco_notify) { dc_context *dcc = (dc_context*)ctx; | 67 | static 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 | ||
81 | static DOTCONF_CB(dco_process) { dc_context *dcc = (dc_context*)ctx; | 81 | static 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 | } |
89 | static DOTCONF_CB(dco__process) { dc_context *dcc = (dc_context*)ctx; | 89 | static 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 | ||
95 | static DOTCONF_CB(dco_process_name) { dc_context *dcc = (dc_context*)ctx; | ||
96 | dcc->ps->process_name = cmd->data.str; | ||
97 | return NULL; | ||
98 | } | ||
95 | static DOTCONF_CB(dco_restart_command) { dc_context *dcc = (dc_context*)ctx; | 99 | static 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 | } |
99 | static DOTCONF_CB(dco_user) { dc_context *dcc = (dc_context*)ctx; | 103 | static 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 | } |
103 | static DOTCONF_CB(dco_group) { dc_context *dcc = (dc_context*)ctx; | 107 | static 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 | } |
107 | static DOTCONF_CB(dco_chroot) { dc_context *dcc = (dc_context*)ctx; | 111 | static 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 | ||
112 | static const configoption_t dc_options[] = { | 116 | static 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 | ||
127 | static const char *dc_context_checker(command_t *cmd,unsigned long mask) { | 132 | static 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 | } |
133 | static FUNC_ERRORHANDLER(dc_error_handler) { | 138 | static 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 | ||
137 | void configuration::parse(const string& cfile) { | 142 | void 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 | } |