X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fconfigfile.c;h=f4e9c604fe26cafd75ee04620158b11f5aed6726;hb=c8ec3924c92ad3ca15229e8e923eaece64221337;hp=d636c8c70f55249f9d3e6f8b7217c3a7ab3bcbbf;hpb=05b7b7e327b01a33da39f5550694294fd0d29849;p=collectd.git diff --git a/src/configfile.c b/src/configfile.c index d636c8c7..f4e9c604 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -27,7 +27,6 @@ #include "common.h" #include "plugin.h" #include "configfile.h" -#include "network.h" #define ESCAPE_NULL(str) ((str) == NULL ? "(null)" : (str)) @@ -43,6 +42,13 @@ typedef struct cf_callback struct cf_callback *next; } cf_callback_t; +typedef struct cf_complex_callback_s +{ + char *type; + int (*callback) (oconfig_item_t *); + struct cf_complex_callback_s *next; +} cf_complex_callback_t; + typedef struct cf_value_map_s { char *key; @@ -66,6 +72,7 @@ static int dispatch_value_loadplugin (const oconfig_item_t *ci); * Private variables */ static cf_callback_t *first_callback = NULL; +static cf_complex_callback_t *complex_callback_head = NULL; static cf_value_map_t cf_value_map[] = { @@ -79,7 +86,9 @@ static cf_global_option_t cf_global_options[] = {"BaseDir", NULL, PKGLOCALSTATEDIR}, {"PIDFile", NULL, PIDFILE}, {"Hostname", NULL, NULL}, - {"Interval", NULL, "10"} + {"Interval", NULL, "10"}, + {"ReadThreads", NULL, "5"}, + {"TypesDB", NULL, PLUGINDIR"/types.db"} /* FIXME: Configure path */ }; static int cf_global_options_num = STATIC_ARRAY_LEN (cf_global_options); @@ -155,11 +164,18 @@ static int dispatch_global_option (const oconfig_item_t *ci) { if (ci->values_num != 1) return (-1); - if (ci->values[0].type != OCONFIG_TYPE_STRING) - return (-1); + if (ci->values[0].type == OCONFIG_TYPE_STRING) + return (global_option_set (ci->key, ci->values[0].value.string)); + else if (ci->values[0].type == OCONFIG_TYPE_NUMBER) + { + char tmp[128]; + snprintf (tmp, sizeof (tmp), "%lf", ci->values[0].value.number); + tmp[127] = '\0'; + return (global_option_set (ci->key, tmp)); + } - return (global_option_set (ci->key, ci->values[0].value.string)); -} + return (-1); +} /* int dispatch_global_option */ static int dispatch_value_plugindir (const oconfig_item_t *ci) { @@ -249,21 +265,29 @@ static int dispatch_block_plugin (oconfig_item_t *ci) int i; char *name; + cf_complex_callback_t *cb; + if (strcasecmp (ci->key, "Plugin") != 0) return (-1); - if (ci->values_num != 1) + if (ci->values_num < 1) return (-1); if (ci->values[0].type != OCONFIG_TYPE_STRING) return (-1); name = ci->values[0].value.string; + /* Check for a complex callback first */ + for (cb = complex_callback_head; cb != NULL; cb = cb->next) + if (strcasecmp (name, cb->type) == 0) + return (cb->callback (ci)); + + /* Hm, no complex plugin found. Dispatch the values one by one */ for (i = 0; i < ci->children_num; i++) { if (ci->children[i].children == NULL) dispatch_value_plugin (name, ci->children + i); else - {DEBUG ("No nested config blocks allow for plugins. Yet.");} + {DEBUG ("No nested config blocks allow for this plugin.");} } return (0); @@ -294,8 +318,7 @@ int global_option_set (const char *option, const char *value) if (i >= cf_global_options_num) return (-1); - if (cf_global_options[i].value != NULL) - free (cf_global_options[i].value); + sfree (cf_global_options[i].value); if (value != NULL) cf_global_options[i].value = strdup (value); @@ -338,7 +361,27 @@ void cf_unregister (const char *type) free (this); break; } -} +} /* void cf_unregister */ + +void cf_unregister_complex (const char *type) +{ + cf_complex_callback_t *this, *prev; + + for (prev = NULL, this = complex_callback_head; + this != NULL; + prev = this, this = this->next) + if (strcasecmp (this->type, type) == 0) + { + if (prev == NULL) + complex_callback_head = this->next; + else + prev->next = this->next; + + sfree (this->type); + sfree (this); + break; + } +} /* void cf_unregister */ void cf_register (const char *type, int (*callback) (const char *, const char *), @@ -362,6 +405,39 @@ void cf_register (const char *type, first_callback = cf_cb; } /* void cf_register */ +int cf_register_complex (const char *type, int (*callback) (oconfig_item_t *)) +{ + cf_complex_callback_t *new; + + new = (cf_complex_callback_t *) malloc (sizeof (cf_complex_callback_t)); + if (new == NULL) + return (-1); + + new->type = strdup (type); + if (new->type == NULL) + { + sfree (new); + return (-1); + } + + new->callback = callback; + new->next = NULL; + + if (complex_callback_head == NULL) + { + complex_callback_head = new; + } + else + { + cf_complex_callback_t *last = complex_callback_head; + while (last->next != NULL) + last = last->next; + last->next = new; + } + + return (0); +} /* int cf_register_complex */ + int cf_read (char *filename) { oconfig_item_t *conf;