src/configfile.[ch]: Implement "cf_util_get_string".
[collectd.git] / src / configfile.c
index f9ade29..df04289 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/configfile.c
- * Copyright (C) 2005-2008  Florian octo Forster
+ * Copyright (C) 2005-2009  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
@@ -98,7 +98,9 @@ static cf_global_option_t cf_global_options[] =
        {"Hostname",    NULL, NULL},
        {"FQDNLookup",  NULL, "false"},
        {"Interval",    NULL, "10"},
-       {"ReadThreads", NULL, "5"}
+       {"ReadThreads", NULL, "5"},
+       {"PreCacheChain",  NULL, "PreCache"},
+       {"PostCacheChain", NULL, "PostCache"}
 };
 static int cf_global_options_num = STATIC_ARRAY_LEN (cf_global_options);
 
@@ -170,7 +172,7 @@ static int cf_dispatch (const char *type, const char *orig_key,
        free (key);
        free (value);
 
-       DEBUG ("return (%i)", ret);
+       DEBUG ("cf_dispatch: return (%i)", ret);
 
        return (ret);
 } /* int cf_dispatch */
@@ -206,13 +208,18 @@ static int dispatch_value_typesdb (const oconfig_item_t *ci)
 
        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);
        }
@@ -329,7 +336,15 @@ static int dispatch_block_plugin (oconfig_item_t *ci)
                if (ci->children[i].children == NULL)
                        dispatch_value_plugin (name, ci->children + i);
                else
-                       {DEBUG ("No nested config blocks allowed for this plugin.");}
+               {
+                       WARNING ("There is a `%s' block within the "
+                                       "configuration for the %s plugin. "
+                                       "The plugin either only expects "
+                                       "\"simple\" configuration statements "
+                                       "or wasn't loaded using `LoadPlugin'."
+                                       " Please check your configuration.",
+                                       ci->children[i].key, name);
+               }
        }
 
        return (0);
@@ -371,12 +386,12 @@ static int cf_ci_replace_child (oconfig_item_t *dst, oconfig_item_t *src,
        temp = NULL;
 
        /* If (src->children_num == 0) the array size is decreased. If offset
-        * is _not_ the last element, (offset < (src->children_num - 1)), then
+        * is _not_ the last element, (offset < (dst->children_num - 1)), then
         * we need to move the trailing elements before resizing the array. */
-       if ((src->children_num == 0) && (offset < (src->children_num - 1)))
+       if ((src->children_num == 0) && (offset < (dst->children_num - 1)))
        {
-               int nmemb = src->children_num - (offset + 1);
-               memmove (src->children + offset, src->children + offset + 1,
+               int nmemb = dst->children_num - (offset + 1);
+               memmove (dst->children + offset, dst->children + offset + 1,
                                sizeof (oconfig_item_t) * nmemb);
        }
 
@@ -408,7 +423,7 @@ static int cf_ci_replace_child (oconfig_item_t *dst, oconfig_item_t *src,
                                sizeof (oconfig_item_t) * nmemb);
        }
 
-       /* Last but not least: If there are new childrem, copy them to the
+       /* Last but not least: If there are new children, copy them to the
         * memory reserved for them. */
        if (src->children_num > 0)
        {
@@ -484,6 +499,9 @@ static int cf_include_all (oconfig_item_t *root, int depth)
                /* Now replace the i'th child in `root' with `new'. */
                cf_ci_replace_child (root, new, i);
 
+               /* ... and go back to the new i'th child. */
+               --i;
+
                sfree (new->values);
                sfree (new);
        } /* for (i = 0; i < root->children_num; i++) */
@@ -553,7 +571,7 @@ static oconfig_item_t *cf_read_dir (const char *dir, int depth)
 
                status = ssnprintf (name, sizeof (name), "%s/%s",
                                dir, de->d_name);
-               if (status >= sizeof (name))
+               if ((status < 0) || ((size_t) status >= sizeof (name)))
                {
                        ERROR ("configfile: Not including `%s/%s' because its"
                                        " name is too long.",
@@ -628,7 +646,7 @@ static oconfig_item_t *cf_read_generic (const char *path, int depth)
        int status;
        const char *path_ptr;
        wordexp_t we;
-       int i;
+       size_t i;
 
        if (depth >= CF_MAX_DEPTH)
        {
@@ -899,3 +917,28 @@ int cf_read (char *filename)
 
        return (0);
 } /* int cf_read */
+
+/* Assures the config option is a string, duplicates it and returns the copy in
+ * "ret_string". If necessary "*ret_string" is freed first. Returns zero upon
+ * success. */
+int cf_util_get_string (const oconfig_item_t *ci, char **ret_string) /* {{{ */
+{
+       char *string;
+
+       if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
+       {
+               ERROR ("cf_util_get_string: The %s plugin requires "
+                               "exactly one string argument.", ci->key);
+               return (-1);
+       }
+
+       string = strdup (ci->values[0].value.string);
+       if (string == NULL)
+               return (-1);
+
+       if (*ret_string != NULL)
+               sfree (*ret_string);
+       *ret_string = string;
+
+       return (0);
+} /* }}} int cf_util_get_string */