1 /*
2 * syscollector - 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 "syscollector.h"
29 #include "core/plugin.h"
30 #include "utils/time.h"
32 #include "daemon/config.h"
34 #include "liboconfig/oconfig.h"
35 #include "liboconfig/utils.h"
37 #include <assert.h>
38 #include <strings.h>
40 /*
41 * private variables
42 */
44 static sc_time_t default_interval = 0;
46 /*
47 * private helper functions
48 */
50 static int
51 config_get_interval(oconfig_item_t *ci, sc_time_t *interval)
52 {
53 double interval_dbl = 0.0;
55 assert(ci && interval);
57 if (oconfig_get_number(ci, &interval_dbl)) {
58 fprintf(stderr, "config: Interval requires "
59 "a single numeric argument\n"
60 "\tUsage: Interval SECONDS\n");
61 return -1;
62 }
64 if (interval_dbl <= 0.0) {
65 fprintf(stderr, "config: Invalid interval: %f\n"
66 "\tInterval may not be less than or equal to zero.\n",
67 interval_dbl);
68 return -1;
69 }
71 *interval = DOUBLE_TO_SC_TIME(interval_dbl);
72 return 0;
73 } /* config_get_interval */
75 /*
76 * token parser
77 */
79 typedef struct {
80 char *name;
81 int (*dispatcher)(oconfig_item_t *);
82 } token_parser_t;
84 static int
85 daemon_set_interval(oconfig_item_t *ci)
86 {
87 return config_get_interval(ci, &default_interval);
88 } /* daemon_set_interval */
90 static int
91 daemon_load_backend(oconfig_item_t *ci)
92 {
93 char plugin_name[1024];
94 char *name;
96 sc_plugin_ctx_t ctx = SC_PLUGIN_CTX_INIT;
97 sc_plugin_ctx_t old_ctx;
99 int status, i;
101 ctx.interval = default_interval;
103 if (oconfig_get_string(ci, &name)) {
104 fprintf(stderr, "config: LoadBackend requires a single "
105 "string argument\n"
106 "\tUsage: LoadBackend BACKEND\n");
107 return -1;
108 }
110 snprintf(plugin_name, sizeof(plugin_name), "backend/%s", name);
112 for (i = 0; i < ci->children_num; ++i) {
113 oconfig_item_t *child = ci->children + i;
115 if (! strcasecmp(child->key, "Interval")) {
116 if (config_get_interval(child, &ctx.interval))
117 return -1;
118 }
119 else {
120 fprintf(stderr, "config: Unknown option '%s' inside 'LoadBackend' "
121 "-- see the documentation for details.\n", child->key);
122 return -1;
123 }
124 }
126 old_ctx = sc_plugin_set_ctx(ctx);
127 status = sc_plugin_load(plugin_name);
128 sc_plugin_set_ctx(old_ctx);
129 return status;
130 } /* daemon_load_backend */
132 static int
133 daemon_configure_plugin(oconfig_item_t *ci)
134 {
135 char *name;
137 assert(ci);
139 if (oconfig_get_string(ci, &name)) {
140 fprintf(stderr, "config: %s requires a single "
141 "string argument\n"
142 "\tUsage: LoadBackend BACKEND\n",
143 ci->key);
144 return -1;
145 }
147 return sc_plugin_configure(name, ci);
148 } /* daemon_configure_backend */
150 static token_parser_t token_parser_list[] = {
151 { "Interval", daemon_set_interval },
152 { "LoadBackend", daemon_load_backend },
153 { "Backend", daemon_configure_plugin },
154 { "Plugin", daemon_configure_plugin },
155 { NULL, NULL },
156 };
158 /*
159 * public API
160 */
162 int
163 daemon_parse_config(const char *filename)
164 {
165 oconfig_item_t *ci;
166 int retval = 0, i;
168 ci = oconfig_parse_file(filename);
169 if (! ci)
170 return -1;
172 for (i = 0; i < ci->children_num; ++i) {
173 oconfig_item_t *child = ci->children + i;
174 int status = 1, j;
176 for (j = 0; token_parser_list[j].name; ++j) {
177 if (! strcasecmp(token_parser_list[j].name, child->key))
178 status = token_parser_list[j].dispatcher(child);
179 }
181 if (status) {
182 fprintf(stderr, "config: Failed to parse option '%s'\n",
183 child->key);
184 if (status > 0)
185 fprintf(stderr, "\tUnknown option '%s' -- "
186 "see the documentation for details\n",
187 child->key);
188 retval = -1;
189 }
190 }
191 return retval;
192 } /* daemon_parse_config */
194 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */