-static int cf_dispatch (const char *type, const char *orig_key,
- const char *orig_value)
-{
- cf_callback_t *cf_cb;
- plugin_ctx_t old_ctx;
- char *key;
- char *value;
- int ret;
- int i = 0;
-
- if (orig_key == NULL)
- return (EINVAL);
-
- DEBUG ("type = %s, key = %s, value = %s",
- ESCAPE_NULL(type),
- orig_key,
- ESCAPE_NULL(orig_value));
-
- if ((cf_cb = cf_search (type)) == NULL)
- {
- WARNING ("Found a configuration for the `%s' plugin, but "
- "the plugin isn't loaded or didn't register "
- "a configuration callback.", type);
- return (-1);
- }
-
- if ((key = strdup (orig_key)) == NULL)
- return (1);
- if ((value = strdup (orig_value)) == NULL)
- {
- free (key);
- return (2);
- }
-
- 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)
- && (strcasecmp (cf_cb->keys[i], key) == 0))
- {
- ret = (*cf_cb->callback) (key, value);
- break;
- }
- }
-
- plugin_set_ctx (old_ctx);
-
- if (i >= cf_cb->keys_num)
- WARNING ("Plugin `%s' did not register for value `%s'.", type, key);
-
- free (key);
- free (value);
-
- return (ret);
-} /* int cf_dispatch */
-
-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 (global_option_set (ci->key, ci->values[0].value.string, 0));
- else if (ci->values[0].type == OCONFIG_TYPE_NUMBER)
- {
- char tmp[128];
- ssnprintf (tmp, sizeof (tmp), "%lf", ci->values[0].value.number);
- return (global_option_set (ci->key, tmp, 0));
- }
- else if (ci->values[0].type == OCONFIG_TYPE_BOOLEAN)
- {
- if (ci->values[0].value.boolean)
- return (global_option_set (ci->key, "true", 0));
- else
- return (global_option_set (ci->key, "false", 0));
- }
-
- return (-1);
+static int cf_dispatch_option(const cf_callback_t *cf_cb, oconfig_item_t *ci) {
+
+ const char *plugin = cf_cb->type;
+ const char *orig_key = ci->key;
+ if (orig_key == NULL)
+ return EINVAL;
+
+ /* (Re)construct string value for option */
+ char buffer[4096];
+ int buffer_free = sizeof(buffer);
+ char *buffer_ptr = buffer;
+
+ for (int i = 0; i < ci->values_num; i++) {
+ int status = -1;
+
+ if (ci->values[i].type == OCONFIG_TYPE_STRING)
+ status =
+ ssnprintf(buffer_ptr, buffer_free, " %s", ci->values[i].value.string);
+ else if (ci->values[i].type == OCONFIG_TYPE_NUMBER)
+ status = ssnprintf(buffer_ptr, buffer_free, " %lf",
+ ci->values[i].value.number);
+ else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN)
+ status = ssnprintf(buffer_ptr, buffer_free, " %s",
+ ci->values[i].value.boolean ? "true" : "false");
+
+ if ((status < 0) || (status >= buffer_free))
+ return -1;
+ buffer_free -= status;
+ buffer_ptr += status;
+ }
+
+ /* skip the initial space */
+ const char *orig_value = buffer + 1;
+
+ DEBUG("plugin = %s, key = %s, value = %s", ESCAPE_NULL(plugin), orig_key,
+ ESCAPE_NULL(orig_value));
+
+ char *key = strdup(orig_key);
+ if (key == NULL)
+ return 1;
+
+ char *value = strdup(orig_value);
+ if (value == NULL) {
+ free(key);
+ return 2;
+ }
+
+ int ret = -1;
+
+ plugin_ctx_t old_ctx = plugin_set_ctx(cf_cb->ctx);
+
+ int i;
+ for (i = 0; i < cf_cb->keys_num; i++) {
+ if ((cf_cb->keys[i] != NULL) && (strcasecmp(cf_cb->keys[i], key) == 0)) {
+ ret = (*cf_cb->callback)(key, value);
+ break;
+ }
+ }
+
+ plugin_set_ctx(old_ctx);
+
+ if (i >= cf_cb->keys_num)
+ WARNING("Plugin `%s' did not register for value `%s'.", plugin, key);
+
+ free(key);
+ free(value);
+
+ return ret;
+} /* int cf_dispatch_option */
+
+static int dispatch_global_option(const oconfig_item_t *ci) {
+ if (ci->values_num != 1) {
+ ERROR("configfile: Global option `%s' needs exactly one argument.",
+ ci->key);
+ return -1;
+ }
+
+ if (ci->values[0].type == OCONFIG_TYPE_STRING)
+ return global_option_set(ci->key, ci->values[0].value.string, 0);
+ else if (ci->values[0].type == OCONFIG_TYPE_NUMBER) {
+ char tmp[128];
+ ssnprintf(tmp, sizeof(tmp), "%lf", ci->values[0].value.number);
+ return global_option_set(ci->key, tmp, 0);
+ } else if (ci->values[0].type == OCONFIG_TYPE_BOOLEAN) {
+ if (ci->values[0].value.boolean)
+ return global_option_set(ci->key, "true", 0);
+ else
+ return global_option_set(ci->key, "false", 0);
+ }
+
+ ERROR("configfile: Global option `%s' argument has unknown type.", ci->key);
+
+ return -1;