Code

Merged branch 'master' of git://git.tokkee.org/sysdb.
[sysdb.git] / src / daemon / config.c
index 76955050837b2714011252e74e6dda78e7b660bc..906f4c5e61989c62e400dafc894de18c41ae4239 100644 (file)
@@ -27,8 +27,8 @@
 
 #include "sysdb.h"
 #include "core/plugin.h"
-#include "core/error.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
  */
@@ -59,20 +77,27 @@ config_get_interval(oconfig_item_t *ci, sdb_time_t *interval)
                sdb_log(SDB_LOG_ERR, "config: Interval requires "
                                "a single numeric argument\n"
                                "\tUsage: Interval SECONDS");
-               return -1;
+               return ERR_INVALID_ARG;
        }
 
        if (interval_dbl <= 0.0) {
                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_SDB_TIME(interval_dbl);
        return 0;
 } /* config_get_interval */
 
+/*
+ * public parse results
+ */
+
+char **listen_addresses = NULL;
+size_t listen_addresses_num = 0;
+
 /*
  * token parser
  */
@@ -82,6 +107,41 @@ 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)
 {
@@ -92,17 +152,13 @@ static int
 daemon_load_plugin(oconfig_item_t *ci)
 {
        char *name;
-
-       sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT;
-       sdb_plugin_ctx_t old_ctx;
-
-       int status, i;
+       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 -1;
+               return ERR_INVALID_ARG;
        }
 
        for (i = 0; i < ci->children_num; ++i) {
@@ -115,22 +171,19 @@ daemon_load_plugin(oconfig_item_t *ci)
                continue;
        }
 
-       old_ctx = sdb_plugin_set_ctx(ctx);
-       status = sdb_plugin_load(name);
-       sdb_plugin_set_ctx(old_ctx);
-       return status;
+       /* 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;
 
-       sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT;
-       sdb_plugin_ctx_t old_ctx;
-
-       int status, i;
+       int i;
 
        ctx.interval = default_interval;
 
@@ -138,7 +191,7 @@ daemon_load_backend(oconfig_item_t *ci)
                sdb_log(SDB_LOG_ERR, "config: LoadBackend requires a single "
                                "string argument\n"
                                "\tUsage: LoadBackend BACKEND");
-               return -1;
+               return ERR_INVALID_ARG;
        }
 
        snprintf(plugin_name, sizeof(plugin_name), "backend::%s", name);
@@ -148,7 +201,7 @@ daemon_load_backend(oconfig_item_t *ci)
 
                if (! strcasecmp(child->key, "Interval")) {
                        if (config_get_interval(child, &ctx.interval))
-                               return -1;
+                               return ERR_INVALID_ARG;
                }
                else {
                        sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' "
@@ -158,10 +211,7 @@ daemon_load_backend(oconfig_item_t *ci)
                }
        }
 
-       old_ctx = sdb_plugin_set_ctx(ctx);
-       status = sdb_plugin_load(plugin_name);
-       sdb_plugin_set_ctx(old_ctx);
-       return status;
+       return sdb_plugin_load(plugin_name, &ctx);
 } /* daemon_load_backend */
 
 static int
@@ -176,13 +226,14 @@ daemon_configure_plugin(oconfig_item_t *ci)
                                "string argument\n"
                                "\tUsage: LoadBackend BACKEND",
                                ci->key);
-               return -1;
+               return ERR_INVALID_ARG;
        }
 
        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 },
@@ -203,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))
@@ -217,13 +268,13 @@ daemon_parse_config(const char *filename)
                if (status) {
                        sdb_error_set("config: Failed to parse option '%s'\n",
                                        child->key);
-                       if (status > 0)
+                       if (status == ERR_UNKNOWN_OPTION)
                                sdb_error_append("\tUnknown option '%s' -- "
                                                "see the documentation for details\n",
                                                child->key);
                        sdb_error_chomp();
                        sdb_error_log(SDB_LOG_ERR);
-                       retval = -1;
+                       retval = status;
                }
        }
        return retval;