/**
* collectd - src/configfile.c
- * Copyright (C) 2005-2010 Florian octo Forster
+ * Copyright (C) 2005-2011 Florian octo Forster
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors:
- * Florian octo Forster <octo at verplant.org>
+ * Florian octo Forster <octo at collectd.org>
* Sebastian tokkee Harl <sh at tokkee.org>
**/
int (*callback) (const char *, const char *);
const char **keys;
int keys_num;
+ plugin_ctx_t ctx;
struct cf_callback *next;
} cf_callback_t;
{
char *type;
int (*callback) (oconfig_item_t *);
+ plugin_ctx_t ctx;
struct cf_complex_callback_s *next;
} cf_complex_callback_t;
const char *orig_value)
{
cf_callback_t *cf_cb;
+ plugin_ctx_t old_ctx;
char *key;
char *value;
int ret;
ret = -1;
+ old_ctx = plugin_set_ctx (cf_cb->ctx);
+
for (i = 0; i < cf_cb->keys_num; i++)
{
if ((cf_cb->keys[i] != NULL)
}
}
+ plugin_set_ctx (old_ctx);
+
if (i >= cf_cb->keys_num)
WARNING ("Plugin `%s' did not register for value `%s'.", type, key);
int i;
const char *name;
unsigned int flags = 0;
+ plugin_ctx_t ctx;
assert (strcasecmp (ci->key, "LoadPlugin") == 0);
if (ci->values_num != 1)
return (-1);
name = ci->values[0].value.string;
+ ctx.interval = 0;
/*
* XXX: Magic at work:
for (i = 0; i < ci->children_num; ++i) {
if (strcasecmp("Globals", ci->children[i].key) == 0)
cf_util_get_flag (ci->children + i, &flags, PLUGIN_FLAGS_GLOBAL);
+ else if (strcasecmp ("Interval", ci->children[i].key) == 0) {
+ double interval = 0.0;
+
+ if (cf_util_get_double (ci->children + i, &interval) != 0) {
+ /* cf_util_get_double will log an error */
+ continue;
+ }
+
+ ctx.interval = DOUBLE_TO_CDTIME_T (interval);
+ }
else {
WARNING("Ignoring unknown LoadPlugin option \"%s\" "
"for plugin \"%s\"",
}
}
+ plugin_set_ctx (ctx);
return (plugin_load (name, (uint32_t) flags));
} /* int dispatch_value_loadplugin */
/* 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));
+ {
+ plugin_ctx_t old_ctx;
+ int ret_val;
+
+ old_ctx = plugin_set_ctx (cb->ctx);
+ ret_val = (cb->callback (ci));
+ plugin_set_ctx (old_ctx);
+ return (ret_val);
+ }
+ }
/* Hm, no complex plugin found. Dispatch the values one by one */
for (i = 0; i < ci->children_num; i++)
cf_cb->callback = callback;
cf_cb->keys = keys;
cf_cb->keys_num = keys_num;
+ cf_cb->ctx = plugin_get_ctx ();
cf_cb->next = first_callback;
first_callback = cf_cb;
new->callback = callback;
new->next = NULL;
+ new->ctx = plugin_get_ctx ();
+
if (complex_callback_head == NULL)
{
complex_callback_head = new;
return (0);
} /* }}} int cf_util_get_int */
+int cf_util_get_double (const oconfig_item_t *ci, double *ret_value) /* {{{ */
+{
+ if ((ci == NULL) || (ret_value == NULL))
+ return (EINVAL);
+
+ if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
+ {
+ ERROR ("cf_util_get_double: The %s option requires "
+ "exactly one numeric argument.", ci->key);
+ return (-1);
+ }
+
+ *ret_value = ci->values[0].value.number;
+
+ return (0);
+} /* }}} int cf_util_get_double */
+
int cf_util_get_boolean (const oconfig_item_t *ci, _Bool *ret_bool) /* {{{ */
{
if ((ci == NULL) || (ret_bool == NULL))
return (0);
} /* }}} int cf_util_get_flag */
-/* Assures that the config option is a string. The string is then converted to
- * a port number using `service_name_to_port_number' and returned. Returns the
- * port number in the range [1-65535] or less than zero upon failure. */
+/* Assures that the config option is a string or a number if the correct range
+ * of 1-65535. The string is then converted to a port number using
+ * `service_name_to_port_number' and returned.
+ * Returns the port number in the range [1-65535] or less than zero upon
+ * failure. */
int cf_util_get_port_number (const oconfig_item_t *ci) /* {{{ */
{
- if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
+ int tmp;
+
+ if ((ci->values_num != 1)
+ || ((ci->values[0].type != OCONFIG_TYPE_STRING)
+ && (ci->values[0].type != OCONFIG_TYPE_NUMBER)))
{
- ERROR ("cf_util_get_port_number: The %s option requires "
+ ERROR ("cf_util_get_port_number: The \"%s\" option requires "
"exactly one string argument.", ci->key);
return (-1);
}
- return (service_name_to_port_number (ci->values[0].value.string));
+ if (ci->values[0].type == OCONFIG_TYPE_STRING)
+ return (service_name_to_port_number (ci->values[0].value.string));
+
+ assert (ci->values[0].type == OCONFIG_TYPE_NUMBER);
+ tmp = (int) (ci->values[0].value.number + 0.5);
+ if ((tmp < 1) || (tmp > 65535))
+ {
+ ERROR ("cf_util_get_port_number: The \"%s\" option requires "
+ "a service name or a port number. The number "
+ "you specified, %i, is not in the valid "
+ "range of 1-65535.",
+ ci->key, tmp);
+ return (-1);
+ }
+
+ return (tmp);
} /* }}} int cf_util_get_port_number */
int cf_util_get_cdtime (const oconfig_item_t *ci, cdtime_t *ret_value) /* {{{ */