Code

Merged branch 'master' of git://git.tokkee.org/sysdb.
[sysdb.git] / src / daemon / config.c
index 0b7cc77bfd9a7a6a6bc8e1acd1f5f93f353389f4..906f4c5e61989c62e400dafc894de18c41ae4239 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * syscollector - src/daemon_config.c
+ * SysDB - src/daemon/config.c
  * Copyright (C) 2012 Sebastian 'tokkee' Harl <sh@tokkee.org>
  * All rights reserved.
  *
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "syscollector.h"
+#include "sysdb.h"
 #include "core/plugin.h"
-#include "utils/time.h"
+#include "core/time.h"
+#include "utils/error.h"
 
 #include "daemon/config.h"
 
 #include "liboconfig/utils.h"
 
 #include <assert.h>
+#include <errno.h>
+
+#include <stdlib.h>
+#include <string.h>
 #include <strings.h>
 
+/*
+ * Parser error values:
+ *  - Values less than zero indicate an error in the daemon or libsysdb.
+ *  - Zero indicates success.
+ *  - Any other values indicate parsing errors.
+ */
+
+enum {
+       ERR_UNKNOWN_OPTION = 1,
+       ERR_UNKNOWN_ARG    = 2,
+       ERR_INVALID_ARG    = 3,
+       ERR_PARSE_FAILED   = 4,
+};
+
 /*
  * private variables
  */
 
-static sc_time_t default_interval = 0;
+static sdb_time_t default_interval = 0;
 
 /*
  * private helper functions
  */
 
 static int
-config_get_interval(oconfig_item_t *ci, sc_time_t *interval)
+config_get_interval(oconfig_item_t *ci, sdb_time_t *interval)
 {
        double interval_dbl = 0.0;
 
        assert(ci && interval);
 
        if (oconfig_get_number(ci, &interval_dbl)) {
-               fprintf(stderr, "config: Interval requires "
+               sdb_log(SDB_LOG_ERR, "config: Interval requires "
                                "a single numeric argument\n"
-                               "\tUsage: Interval SECONDS\n");
-               return -1;
+                               "\tUsage: Interval SECONDS");
+               return ERR_INVALID_ARG;
        }
 
        if (interval_dbl <= 0.0) {
-               fprintf(stderr, "config: Invalid interval: %f\n"
-                               "\tInterval may not be less than or equal to zero.\n",
+               sdb_log(SDB_LOG_ERR, "config: Invalid interval: %f\n"
+                               "\tInterval may not be less than or equal to zero.",
                                interval_dbl);
-               return -1;
+               return ERR_INVALID_ARG;
        }
 
-       *interval = DOUBLE_TO_SC_TIME(interval_dbl);
+       *interval = DOUBLE_TO_SDB_TIME(interval_dbl);
        return 0;
 } /* config_get_interval */
 
+/*
+ * public parse results
+ */
+
+char **listen_addresses = NULL;
+size_t listen_addresses_num = 0;
+
 /*
  * token parser
  */
@@ -81,52 +107,111 @@ typedef struct {
        int (*dispatcher)(oconfig_item_t *);
 } token_parser_t;
 
+static int
+daemon_add_listener(oconfig_item_t *ci)
+{
+       char **tmp;
+       char *address;
+
+       if (oconfig_get_string(ci, &address)) {
+               sdb_log(SDB_LOG_ERR, "config: Listen requires a single "
+                               "string argument\n"
+                               "\tUsage: Listen ADDRESS");
+               return ERR_INVALID_ARG;
+       }
+
+       tmp = realloc(listen_addresses,
+                       (listen_addresses_num + 1) * sizeof(*listen_addresses));
+       if (! tmp) {
+               char buf[1024];
+               sdb_log(SDB_LOG_ERR, "config: Failed to allocate memory: %s",
+                               sdb_strerror(errno, buf, sizeof(buf)));
+               return -1;
+       }
+
+       tmp[listen_addresses_num] = strdup(address);
+       if (! tmp[listen_addresses_num]) {
+               char buf[1024];
+               sdb_log(SDB_LOG_ERR, "config: Failed to allocate memory: %s",
+                               sdb_strerror(errno, buf, sizeof(buf)));
+               return -1;
+       }
+
+       listen_addresses = tmp;
+       ++listen_addresses_num;
+       return 0;
+} /* daemon_add_listener */
+
 static int
 daemon_set_interval(oconfig_item_t *ci)
 {
        return config_get_interval(ci, &default_interval);
 } /* daemon_set_interval */
 
+static int
+daemon_load_plugin(oconfig_item_t *ci)
+{
+       char *name;
+       int i;
+
+       if (oconfig_get_string(ci, &name)) {
+               sdb_log(SDB_LOG_ERR, "config: LoadPlugin requires a single "
+                               "string argument\n"
+                               "\tUsage: LoadPlugin PLUGIN");
+               return ERR_INVALID_ARG;
+       }
+
+       for (i = 0; i < ci->children_num; ++i) {
+               oconfig_item_t *child = ci->children + i;
+
+               /* we don't currently support any options */
+               sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' "
+                               "inside 'LoadPlugin' -- see the documentation for "
+                               "details.", child->key);
+               continue;
+       }
+
+       /* returns a negative value on error */
+       return sdb_plugin_load(name, NULL);
+} /* daemon_load_plugin */
+
 static int
 daemon_load_backend(oconfig_item_t *ci)
 {
+       sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT;
+
        char  plugin_name[1024];
        char *name;
 
-       sc_plugin_ctx_t ctx = SC_PLUGIN_CTX_INIT;
-       sc_plugin_ctx_t old_ctx;
-
-       int status, i;
+       int i;
 
        ctx.interval = default_interval;
 
        if (oconfig_get_string(ci, &name)) {
-               fprintf(stderr, "config: LoadBackend requires a single "
+               sdb_log(SDB_LOG_ERR, "config: LoadBackend requires a single "
                                "string argument\n"
-                               "\tUsage: LoadBackend BACKEND\n");
-               return -1;
+                               "\tUsage: LoadBackend BACKEND");
+               return ERR_INVALID_ARG;
        }
 
-       snprintf(plugin_name, sizeof(plugin_name), "backend/%s", name);
+       snprintf(plugin_name, sizeof(plugin_name), "backend::%s", name);
 
        for (i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *child = ci->children + i;
 
                if (! strcasecmp(child->key, "Interval")) {
                        if (config_get_interval(child, &ctx.interval))
-                               return -1;
+                               return ERR_INVALID_ARG;
                }
                else {
-                       fprintf(stderr, "config: Unknown option '%s' inside 'LoadBackend' "
-                                       "-- see the documentation for details.\n", child->key);
-                       return -1;
+                       sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' "
+                                       "inside 'LoadBackend' -- see the documentation for "
+                                       "details.", child->key);
+                       continue;
                }
        }
 
-       old_ctx = sc_plugin_set_ctx(ctx);
-       status = sc_plugin_load(plugin_name);
-       sc_plugin_set_ctx(old_ctx);
-       return status;
+       return sdb_plugin_load(plugin_name, &ctx);
 } /* daemon_load_backend */
 
 static int
@@ -137,18 +222,20 @@ daemon_configure_plugin(oconfig_item_t *ci)
        assert(ci);
 
        if (oconfig_get_string(ci, &name)) {
-               fprintf(stderr, "config: %s requires a single "
+               sdb_log(SDB_LOG_ERR, "config: %s requires a single "
                                "string argument\n"
-                               "\tUsage: LoadBackend BACKEND\n",
+                               "\tUsage: LoadBackend BACKEND",
                                ci->key);
-               return -1;
+               return ERR_INVALID_ARG;
        }
 
-       return sc_plugin_configure(name, ci);
+       return sdb_plugin_configure(name, ci);
 } /* daemon_configure_backend */
 
 static token_parser_t token_parser_list[] = {
+       { "Listen", daemon_add_listener },
        { "Interval", daemon_set_interval },
+       { "LoadPlugin", daemon_load_plugin },
        { "LoadBackend", daemon_load_backend },
        { "Backend", daemon_configure_plugin },
        { "Plugin", daemon_configure_plugin },
@@ -167,11 +254,11 @@ daemon_parse_config(const char *filename)
 
        ci = oconfig_parse_file(filename);
        if (! ci)
-               return -1;
+               return ERR_PARSE_FAILED;
 
        for (i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *child = ci->children + i;
-               int status = 1, j;
+               int status = ERR_UNKNOWN_OPTION, j;
 
                for (j = 0; token_parser_list[j].name; ++j) {
                        if (! strcasecmp(token_parser_list[j].name, child->key))
@@ -179,13 +266,15 @@ daemon_parse_config(const char *filename)
                }
 
                if (status) {
-                       fprintf(stderr, "config: Failed to parse option '%s'\n",
+                       sdb_error_set("config: Failed to parse option '%s'\n",
                                        child->key);
-                       if (status > 0)
-                               fprintf(stderr, "\tUnknown option '%s' -- "
+                       if (status == ERR_UNKNOWN_OPTION)
+                               sdb_error_append("\tUnknown option '%s' -- "
                                                "see the documentation for details\n",
                                                child->key);
-                       retval = -1;
+                       sdb_error_chomp();
+                       sdb_error_log(SDB_LOG_ERR);
+                       retval = status;
                }
        }
        return retval;