*
* Authors:
* Florian octo Forster <octo at verplant.org>
+ * Sebastian tokkee Harl <sh at tokkee.org>
**/
#include "collectd.h"
for (i = 0; i < cf_cb->keys_num; i++)
{
- if (strcasecmp (cf_cb->keys[i], key) == 0)
+ if ((cf_cb->keys[i] != NULL)
+ && (strcasecmp (cf_cb->keys[i], key) == 0))
{
ret = (*cf_cb->callback) (key, value);
break;
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';
+ ssnprintf (tmp, sizeof (tmp), "%lf", ci->values[0].value.number);
return (global_option_set (ci->key, tmp));
}
else if (ci->values[0].type == OCONFIG_TYPE_BOOLEAN)
cf_default_typesdb = 0;
- if (ci->values_num < 1)
+ if (ci->values_num < 1) {
+ ERROR ("configfile: `TypesDB' needs at least one argument.");
return (-1);
+ }
for (i = 0; i < ci->values_num; ++i)
{
- if (OCONFIG_TYPE_STRING != ci->values[i].type)
+ if (OCONFIG_TYPE_STRING != ci->values[i].type) {
+ WARNING ("configfile: TypesDB: Skipping %i. argument which "
+ "is not a string.", i + 1);
continue;
+ }
read_types_list (ci->values[i].value.string);
}
int status = -1;
if (ci->values[i].type == OCONFIG_TYPE_STRING)
- status = snprintf (buffer_ptr, buffer_free, " %s",
+ status = ssnprintf (buffer_ptr, buffer_free, " %s",
ci->values[i].value.string);
else if (ci->values[i].type == OCONFIG_TYPE_NUMBER)
- status = snprintf (buffer_ptr, buffer_free, " %lf",
+ status = ssnprintf (buffer_ptr, buffer_free, " %lf",
ci->values[i].value.number);
else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN)
- status = snprintf (buffer_ptr, buffer_free, " %s",
+ status = ssnprintf (buffer_ptr, buffer_free, " %s",
ci->values[i].value.boolean
? "true" : "false");
buffer_ptr = buffer + 1;
return (cf_dispatch (plugin, ci->key, buffer_ptr));
-} /* int plugin_conf_dispatch */
+} /* int dispatch_value_plugin */
static int dispatch_value (const oconfig_item_t *ci)
{
if (ci->children[i].children == NULL)
dispatch_value_plugin (name, ci->children + i);
else
- {DEBUG ("No nested config blocks allow for this plugin.");}
+ {DEBUG ("No nested config blocks allowed for this plugin.");}
}
return (0);
{
oconfig_item_t *temp;
+ if ((src == NULL) || (src->children_num == 0))
+ return (0);
+
temp = (oconfig_item_t *) realloc (dst->children,
sizeof (oconfig_item_t)
* (dst->children_num + src->children_num));
return (root);
} /* oconfig_item_t *cf_read_file */
+static int cf_compare_string (const void *p1, const void *p2)
+{
+ return strcmp (*(const char **) p1, *(const char **) p2);
+}
+
static oconfig_item_t *cf_read_dir (const char *dir, int depth)
{
oconfig_item_t *root = NULL;
DIR *dh;
struct dirent *de;
- char name[1024];
+ char **filenames = NULL;
+ int filenames_num = 0;
int status;
+ int i;
assert (depth < CF_MAX_DEPTH);
while ((de = readdir (dh)) != NULL)
{
- oconfig_item_t *temp;
+ char name[1024];
+ char **tmp;
if ((de->d_name[0] == '.') || (de->d_name[0] == '\0'))
continue;
- status = snprintf (name, sizeof (name), "%s/%s",
+ status = ssnprintf (name, sizeof (name), "%s/%s",
dir, de->d_name);
if (status >= sizeof (name))
{
ERROR ("configfile: Not including `%s/%s' because its"
" name is too long.",
dir, de->d_name);
- continue;
+ for (i = 0; i < filenames_num; ++i)
+ free (filenames[i]);
+ free (filenames);
+ free (root);
+ return (NULL);
}
+ ++filenames_num;
+ tmp = (char **) realloc (filenames,
+ filenames_num * sizeof (*filenames));
+ if (tmp == NULL) {
+ ERROR ("configfile: realloc failed.");
+ for (i = 0; i < filenames_num - 1; ++i)
+ free (filenames[i]);
+ free (filenames);
+ free (root);
+ return (NULL);
+ }
+ filenames = tmp;
+
+ filenames[filenames_num - 1] = sstrdup (name);
+ }
+
+ qsort ((void *) filenames, filenames_num, sizeof (*filenames),
+ cf_compare_string);
+
+ for (i = 0; i < filenames_num; ++i)
+ {
+ oconfig_item_t *temp;
+ char *name = filenames[i];
+
temp = cf_read_generic (name, depth);
- if (temp == NULL)
- continue;
+ if (temp == NULL) {
+ int j;
+ for (j = i; j < filenames_num; ++j)
+ free (filenames[j]);
+ free (filenames);
+ oconfig_free (root);
+ return (NULL);
+ }
cf_ci_append_children (root, temp);
sfree (temp->children);
sfree (temp);
+
+ free (name);
}
+ free(filenames);
return (root);
} /* oconfig_item_t *cf_read_dir */
}
memset (root, '\0', sizeof (oconfig_item_t));
+ /* wordexp() might return a sorted list already. That's not
+ * documented though, so let's make sure we get what we want. */
+ qsort ((void *) we.we_wordv, we.we_wordc, sizeof (*we.we_wordv),
+ cf_compare_string);
+
for (i = 0; i < we.we_wordc; i++)
{
oconfig_item_t *temp;
ERROR ("configfile: stat (%s) failed: %s",
path_ptr,
sstrerror (errno, errbuf, sizeof (errbuf)));
+ oconfig_free (root);
return (NULL);
}
continue;
}
+ if (temp == NULL) {
+ oconfig_free (root);
+ return (NULL);
+ }
+
cf_ci_append_children (root, temp);
sfree (temp->children);
sfree (temp);
dispatch_block (conf->children + i);
}
+ oconfig_free (conf);
+
+ /* Read the default types.db if no `TypesDB' option was given. */
if (cf_default_typesdb)
- read_types_list (PLUGINDIR"/types.db"); /* FIXME: Configure path */
+ read_types_list (PLUGINDIR"/types.db");
+
return (0);
} /* int cf_read */