Merge pull request #1596 from rubenk/fix-a-few-more-prototypes
[collectd.git] / src / configfile.c
index 88bed1c..8139c63 100644 (file)
@@ -69,7 +69,7 @@ typedef struct cf_complex_callback_s
 typedef struct cf_value_map_s
 {
        char *key;
-       int (*func) (const oconfig_item_t *);
+       int (*func) (oconfig_item_t *);
 } cf_value_map_t;
 
 typedef struct cf_global_option_s
@@ -82,9 +82,10 @@ typedef struct cf_global_option_s
 /*
  * Prototypes of callback functions
  */
-static int dispatch_value_typesdb (const oconfig_item_t *ci);
-static int dispatch_value_plugindir (const oconfig_item_t *ci);
-static int dispatch_loadplugin (const oconfig_item_t *ci);
+static int dispatch_value_typesdb (oconfig_item_t *ci);
+static int dispatch_value_plugindir (oconfig_item_t *ci);
+static int dispatch_loadplugin (oconfig_item_t *ci);
+static int dispatch_block_plugin (oconfig_item_t *ci);
 
 /*
  * Private variables
@@ -96,7 +97,8 @@ static cf_value_map_t cf_value_map[] =
 {
        {"TypesDB",    dispatch_value_typesdb},
        {"PluginDir",  dispatch_value_plugindir},
-       {"LoadPlugin", dispatch_loadplugin}
+       {"LoadPlugin", dispatch_loadplugin},
+       {"Plugin",     dispatch_block_plugin}
 };
 static int cf_value_map_num = STATIC_ARRAY_SIZE (cf_value_map);
 
@@ -109,8 +111,8 @@ static cf_global_option_t cf_global_options[] =
        {"Interval",    NULL, NULL},
        {"ReadThreads", NULL, "5"},
        {"WriteThreads", NULL, "5"},
-       {"WriteQueueLengthLimitHigh", NULL, NULL},
-       {"WriteQueueLengthLimitLow", NULL, NULL},
+       {"WriteQueueLimitHigh", NULL, NULL},
+       {"WriteQueueLimitLow", NULL, NULL},
        {"Timeout",     NULL, "2"},
        {"AutoLoadPlugin", NULL, "false"},
        {"PreCacheChain",  NULL, "PreCache"},
@@ -148,9 +150,12 @@ static int cf_dispatch (const char *type, const char *orig_key,
        int ret;
        int i;
 
+       if (orig_key == NULL)
+               return (EINVAL);
+
        DEBUG ("type = %s, key = %s, value = %s",
                        ESCAPE_NULL(type),
-                       ESCAPE_NULL(orig_key),
+                       orig_key,
                        ESCAPE_NULL(orig_value));
 
        if ((cf_cb = cf_search (type)) == NULL)
@@ -191,8 +196,6 @@ static int cf_dispatch (const char *type, const char *orig_key,
        free (key);
        free (value);
 
-       DEBUG ("cf_dispatch: return (%i)", ret);
-
        return (ret);
 } /* int cf_dispatch */
 
@@ -219,7 +222,7 @@ static int dispatch_global_option (const oconfig_item_t *ci)
        return (-1);
 } /* int dispatch_global_option */
 
-static int dispatch_value_typesdb (const oconfig_item_t *ci)
+static int dispatch_value_typesdb (oconfig_item_t *ci)
 {
        int i = 0;
 
@@ -245,7 +248,7 @@ static int dispatch_value_typesdb (const oconfig_item_t *ci)
        return (0);
 } /* int dispatch_value_typesdb */
 
-static int dispatch_value_plugindir (const oconfig_item_t *ci)
+static int dispatch_value_plugindir (oconfig_item_t *ci)
 {
        assert (strcasecmp (ci->key, "PluginDir") == 0);
        
@@ -258,7 +261,7 @@ static int dispatch_value_plugindir (const oconfig_item_t *ci)
        return (0);
 }
 
-static int dispatch_loadplugin (const oconfig_item_t *ci)
+static int dispatch_loadplugin (oconfig_item_t *ci)
 {
        int i;
        const char *name;
@@ -344,7 +347,7 @@ static int dispatch_value_plugin (const char *plugin, oconfig_item_t *ci)
        return (cf_dispatch (plugin, ci->key, buffer_ptr));
 } /* int dispatch_value_plugin */
 
-static int dispatch_value (const oconfig_item_t *ci)
+static int dispatch_value (oconfig_item_t *ci)
 {
        int ret = -2;
        int i;
@@ -384,9 +387,19 @@ static int dispatch_block_plugin (oconfig_item_t *ci)
 
        if (IS_TRUE (global_option_get ("AutoLoadPlugin")))
        {
+               plugin_ctx_t ctx;
+               plugin_ctx_t old_ctx;
                int status;
 
+               /* default to the global interval set before loading this plugin */
+               memset (&ctx, 0, sizeof (ctx));
+               ctx.interval = cf_get_default_interval ();
+
+               old_ctx = plugin_set_ctx (ctx);
                status = plugin_load (name, /* flags = */ 0);
+               /* reset to the "global" context */
+               plugin_set_ctx (old_ctx);
+
                if (status != 0)
                {
                        ERROR ("Automatically loading plugin \"%s\" failed "
@@ -477,6 +490,12 @@ static int cf_ci_replace_child (oconfig_item_t *dst, oconfig_item_t *src,
 
        /* Resize the memory containing the children to be big enough to hold
         * all children. */
+       if (dst->children_num + src->children_num - 1 == 0)
+       {
+               dst->children_num = 0;
+               return (0);
+       }
+
        temp = (oconfig_item_t *) realloc (dst->children,
                        sizeof (oconfig_item_t)
                        * (dst->children_num + src->children_num - 1));
@@ -591,7 +610,11 @@ static int cf_include_all (oconfig_item_t *root, int depth)
                        return (-1);
 
                /* Now replace the i'th child in `root' with `new'. */
-               cf_ci_replace_child (root, new, i);
+               if (cf_ci_replace_child (root, new, i) < 0) {
+                       sfree (new->values);
+                       sfree (new);
+                       return (-1);
+               }
 
                /* ... and go back to the new i'th child. */
                --i;
@@ -680,6 +703,7 @@ static oconfig_item_t *cf_read_dir (const char *dir,
        if (root == NULL)
        {
                ERROR ("configfile: malloc failed.");
+               closedir (dh);
                return (NULL);
        }
        memset (root, 0, sizeof (oconfig_item_t));
@@ -699,6 +723,7 @@ static oconfig_item_t *cf_read_dir (const char *dir,
                        ERROR ("configfile: Not including `%s/%s' because its"
                                        " name is too long.",
                                        dir, de->d_name);
+                       closedir (dh);
                        for (i = 0; i < filenames_num; ++i)
                                free (filenames[i]);
                        free (filenames);
@@ -711,6 +736,7 @@ static oconfig_item_t *cf_read_dir (const char *dir,
                                filenames_num * sizeof (*filenames));
                if (tmp == NULL) {
                        ERROR ("configfile: realloc failed.");
+                       closedir (dh);
                        for (i = 0; i < filenames_num - 1; ++i)
                                free (filenames[i]);
                        free (filenames);
@@ -722,6 +748,12 @@ static oconfig_item_t *cf_read_dir (const char *dir,
                filenames[filenames_num - 1] = sstrdup (name);
        }
 
+       if (filenames == NULL)
+       {
+               closedir (dh);
+               return (root);
+       }
+
        qsort ((void *) filenames, filenames_num, sizeof (*filenames),
                        cf_compare_string);
 
@@ -745,11 +777,12 @@ static oconfig_item_t *cf_read_dir (const char *dir,
                free (name);
        }
 
+       closedir (dh);
        free(filenames);
        return (root);
 } /* oconfig_item_t *cf_read_dir */
 
-/* 
+/*
  * cf_read_generic
  *
  * Path is stat'ed and either cf_read_file or cf_read_dir is called
@@ -917,6 +950,23 @@ const char *global_option_get (const char *option)
                        : cf_global_options[i].def);
 } /* char *global_option_get */
 
+long global_option_get_long (const char *option, long default_value)
+{
+               const char *str;
+               long value;
+
+               str = global_option_get (option);
+               if (NULL == str)
+                       return (default_value);
+
+               errno = 0;
+               value = strtol (str, /* endptr = */ NULL, /* base = */ 0);
+               if (errno != 0)
+                       return (default_value);
+
+               return (value);
+} /* char *global_option_get_long */
+
 cdtime_t cf_get_default_interval (void)
 {
   char const *str = global_option_get ("Interval");