1 /*
2 * SysDB - src/daemon/config.c
3 * Copyright (C) 2012 Sebastian 'tokkee' Harl <sh@tokkee.org>
4 * All rights reserved.
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 COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
28 #include "sysdb.h"
29 #include "core/plugin.h"
30 #include "core/error.h"
31 #include "core/time.h"
33 #include "daemon/config.h"
35 #include "liboconfig/oconfig.h"
36 #include "liboconfig/utils.h"
38 #include <assert.h>
39 #include <strings.h>
41 /*
42 * private variables
43 */
45 static sdb_time_t default_interval = 0;
47 /*
48 * private helper functions
49 */
51 static int
52 config_get_interval(oconfig_item_t *ci, sdb_time_t *interval)
53 {
54 double interval_dbl = 0.0;
56 assert(ci && interval);
58 if (oconfig_get_number(ci, &interval_dbl)) {
59 sdb_log(SDB_LOG_ERR, "config: Interval requires "
60 "a single numeric argument\n"
61 "\tUsage: Interval SECONDS");
62 return -1;
63 }
65 if (interval_dbl <= 0.0) {
66 sdb_log(SDB_LOG_ERR, "config: Invalid interval: %f\n"
67 "\tInterval may not be less than or equal to zero.",
68 interval_dbl);
69 return -1;
70 }
72 *interval = DOUBLE_TO_SDB_TIME(interval_dbl);
73 return 0;
74 } /* config_get_interval */
76 /*
77 * token parser
78 */
80 typedef struct {
81 char *name;
82 int (*dispatcher)(oconfig_item_t *);
83 } token_parser_t;
85 static int
86 daemon_set_interval(oconfig_item_t *ci)
87 {
88 return config_get_interval(ci, &default_interval);
89 } /* daemon_set_interval */
91 static int
92 daemon_load_plugin(oconfig_item_t *ci)
93 {
94 char *name;
95 int i;
97 if (oconfig_get_string(ci, &name)) {
98 sdb_log(SDB_LOG_ERR, "config: LoadPlugin requires a single "
99 "string argument\n"
100 "\tUsage: LoadPlugin PLUGIN");
101 return -1;
102 }
104 for (i = 0; i < ci->children_num; ++i) {
105 oconfig_item_t *child = ci->children + i;
107 /* we don't currently support any options */
108 sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' "
109 "inside 'LoadPlugin' -- see the documentation for "
110 "details.", child->key);
111 continue;
112 }
114 return sdb_plugin_load(name, NULL);
115 } /* daemon_load_plugin */
117 static int
118 daemon_load_backend(oconfig_item_t *ci)
119 {
120 sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT;
122 char plugin_name[1024];
123 char *name;
125 int i;
127 ctx.interval = default_interval;
129 if (oconfig_get_string(ci, &name)) {
130 sdb_log(SDB_LOG_ERR, "config: LoadBackend requires a single "
131 "string argument\n"
132 "\tUsage: LoadBackend BACKEND");
133 return -1;
134 }
136 snprintf(plugin_name, sizeof(plugin_name), "backend::%s", name);
138 for (i = 0; i < ci->children_num; ++i) {
139 oconfig_item_t *child = ci->children + i;
141 if (! strcasecmp(child->key, "Interval")) {
142 if (config_get_interval(child, &ctx.interval))
143 return -1;
144 }
145 else {
146 sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' "
147 "inside 'LoadBackend' -- see the documentation for "
148 "details.", child->key);
149 continue;
150 }
151 }
153 return sdb_plugin_load(plugin_name, &ctx);
154 } /* daemon_load_backend */
156 static int
157 daemon_configure_plugin(oconfig_item_t *ci)
158 {
159 char *name;
161 assert(ci);
163 if (oconfig_get_string(ci, &name)) {
164 sdb_log(SDB_LOG_ERR, "config: %s requires a single "
165 "string argument\n"
166 "\tUsage: LoadBackend BACKEND",
167 ci->key);
168 return -1;
169 }
171 return sdb_plugin_configure(name, ci);
172 } /* daemon_configure_backend */
174 static token_parser_t token_parser_list[] = {
175 { "Interval", daemon_set_interval },
176 { "LoadPlugin", daemon_load_plugin },
177 { "LoadBackend", daemon_load_backend },
178 { "Backend", daemon_configure_plugin },
179 { "Plugin", daemon_configure_plugin },
180 { NULL, NULL },
181 };
183 /*
184 * public API
185 */
187 int
188 daemon_parse_config(const char *filename)
189 {
190 oconfig_item_t *ci;
191 int retval = 0, i;
193 ci = oconfig_parse_file(filename);
194 if (! ci)
195 return -1;
197 for (i = 0; i < ci->children_num; ++i) {
198 oconfig_item_t *child = ci->children + i;
199 int status = 1, j;
201 for (j = 0; token_parser_list[j].name; ++j) {
202 if (! strcasecmp(token_parser_list[j].name, child->key))
203 status = token_parser_list[j].dispatcher(child);
204 }
206 if (status) {
207 sdb_error_set("config: Failed to parse option '%s'\n",
208 child->key);
209 if (status > 0)
210 sdb_error_append("\tUnknown option '%s' -- "
211 "see the documentation for details\n",
212 child->key);
213 sdb_error_chomp();
214 sdb_error_log(SDB_LOG_ERR);
215 retval = -1;
216 }
217 }
218 return retval;
219 } /* daemon_parse_config */
221 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */