Code

76955050837b2714011252e74e6dda78e7b660bc
[sysdb.git] / src / daemon / config.c
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;
96         sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT;
97         sdb_plugin_ctx_t old_ctx;
99         int status, i;
101         if (oconfig_get_string(ci, &name)) {
102                 sdb_log(SDB_LOG_ERR, "config: LoadPlugin requires a single "
103                                 "string argument\n"
104                                 "\tUsage: LoadPlugin PLUGIN");
105                 return -1;
106         }
108         for (i = 0; i < ci->children_num; ++i) {
109                 oconfig_item_t *child = ci->children + i;
111                 /* we don't currently support any options */
112                 sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' "
113                                 "inside 'LoadPlugin' -- see the documentation for "
114                                 "details.", child->key);
115                 continue;
116         }
118         old_ctx = sdb_plugin_set_ctx(ctx);
119         status = sdb_plugin_load(name);
120         sdb_plugin_set_ctx(old_ctx);
121         return status;
122 } /* daemon_load_plugin */
124 static int
125 daemon_load_backend(oconfig_item_t *ci)
127         char  plugin_name[1024];
128         char *name;
130         sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT;
131         sdb_plugin_ctx_t old_ctx;
133         int status, i;
135         ctx.interval = default_interval;
137         if (oconfig_get_string(ci, &name)) {
138                 sdb_log(SDB_LOG_ERR, "config: LoadBackend requires a single "
139                                 "string argument\n"
140                                 "\tUsage: LoadBackend BACKEND");
141                 return -1;
142         }
144         snprintf(plugin_name, sizeof(plugin_name), "backend::%s", name);
146         for (i = 0; i < ci->children_num; ++i) {
147                 oconfig_item_t *child = ci->children + i;
149                 if (! strcasecmp(child->key, "Interval")) {
150                         if (config_get_interval(child, &ctx.interval))
151                                 return -1;
152                 }
153                 else {
154                         sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' "
155                                         "inside 'LoadBackend' -- see the documentation for "
156                                         "details.", child->key);
157                         continue;
158                 }
159         }
161         old_ctx = sdb_plugin_set_ctx(ctx);
162         status = sdb_plugin_load(plugin_name);
163         sdb_plugin_set_ctx(old_ctx);
164         return status;
165 } /* daemon_load_backend */
167 static int
168 daemon_configure_plugin(oconfig_item_t *ci)
170         char *name;
172         assert(ci);
174         if (oconfig_get_string(ci, &name)) {
175                 sdb_log(SDB_LOG_ERR, "config: %s requires a single "
176                                 "string argument\n"
177                                 "\tUsage: LoadBackend BACKEND",
178                                 ci->key);
179                 return -1;
180         }
182         return sdb_plugin_configure(name, ci);
183 } /* daemon_configure_backend */
185 static token_parser_t token_parser_list[] = {
186         { "Interval", daemon_set_interval },
187         { "LoadPlugin", daemon_load_plugin },
188         { "LoadBackend", daemon_load_backend },
189         { "Backend", daemon_configure_plugin },
190         { "Plugin", daemon_configure_plugin },
191         { NULL, NULL },
192 };
194 /*
195  * public API
196  */
198 int
199 daemon_parse_config(const char *filename)
201         oconfig_item_t *ci;
202         int retval = 0, i;
204         ci = oconfig_parse_file(filename);
205         if (! ci)
206                 return -1;
208         for (i = 0; i < ci->children_num; ++i) {
209                 oconfig_item_t *child = ci->children + i;
210                 int status = 1, j;
212                 for (j = 0; token_parser_list[j].name; ++j) {
213                         if (! strcasecmp(token_parser_list[j].name, child->key))
214                                 status = token_parser_list[j].dispatcher(child);
215                 }
217                 if (status) {
218                         sdb_error_set("config: Failed to parse option '%s'\n",
219                                         child->key);
220                         if (status > 0)
221                                 sdb_error_append("\tUnknown option '%s' -- "
222                                                 "see the documentation for details\n",
223                                                 child->key);
224                         sdb_error_chomp();
225                         sdb_error_log(SDB_LOG_ERR);
226                         retval = -1;
227                 }
228         }
229         return retval;
230 } /* daemon_parse_config */
232 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */