#include "common.h"
#include "plugin.h"
#include "configfile.h"
-#include "network.h"
-#include "utils_debug.h"
#define ESCAPE_NULL(str) ((str) == NULL ? "(null)" : (str))
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;
* 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[] =
{
static cf_global_option_t cf_global_options[] =
{
- {"BaseDir", NULL, PKGLOCALSTATEDIR},
- {"LogFile", NULL, LOGFILE},
- {"PIDFile", NULL, PIDFILE}
+ {"BaseDir", NULL, PKGLOCALSTATEDIR},
+ {"PIDFile", NULL, PIDFILE},
+ {"Hostname", NULL, NULL},
+ {"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);
int ret;
int i;
- DBG ("type = %s, key = %s, value = %s",
+ DEBUG ("type = %s, key = %s, value = %s",
ESCAPE_NULL(type),
ESCAPE_NULL(orig_key),
ESCAPE_NULL(orig_value));
if ((cf_cb = cf_search (type)) == NULL)
{
- syslog (LOG_WARNING, "Plugin `%s' did not register a callback.", type);
+ WARNING ("Plugin `%s' did not register a callback.", type);
return (-1);
}
}
if (i >= cf_cb->keys_num)
- syslog (LOG_WARNING, "Plugin `%s' did not register for value `%s'.", type, key);
+ WARNING ("Plugin `%s' did not register for value `%s'.", type, key);
free (key);
free (value);
- DBG ("return (%i)", ret);
+ DEBUG ("return (%i)", ret);
return (ret);
} /* int cf_dispatch */
{
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)
{
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
- {DBG ("No nested config blocks allow for plugins. Yet.");}
+ {DEBUG ("No nested config blocks allow for this plugin.");}
}
return (0);
{
int i;
+ DEBUG ("option = %s; value = %s;", option, value);
+
for (i = 0; i < cf_global_options_num; i++)
if (strcasecmp (cf_global_options[i].key, option) == 0)
break;
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);
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 *),
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;
conf = oconfig_parse_file (filename);
if (conf == NULL)
{
- syslog (LOG_ERR, "Unable to read config file %s.", filename);
+ ERROR ("Unable to read config file %s.", filename);
return (-1);
}