--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "graph.h"
+#include "graph_list.h"
+#include "graph_ident.h"
+#include "graph_def.h"
+#include "graph_config.h"
+#include "common.h"
+#include "filesystem.h"
+#include "utils_params.h"
+
+#include <fcgiapp.h>
+#include <fcgi_stdio.h>
+
+/*
+ * Data types
+ */
+struct graph_config_s /* {{{ */
+{
+ graph_ident_t *select;
+
+ char *title;
+ char *vertical_label;
+
+ graph_def_t *defs;
+
+ graph_instance_t *instances;
+}; /* }}} struct graph_config_s */
+
+/*
+ * Private functions
+ */
+static graph_instance_t *graph_find_instance (graph_config_t *cfg, /* {{{ */
+ const graph_ident_t *ident)
+{
+ if ((cfg == NULL) || (ident == NULL))
+ return (NULL);
+
+ return (inst_find_matching (cfg->instances, ident));
+} /* }}} graph_instance_t *graph_find_instance */
+
+/*
+ * Config functions
+ */
+static graph_ident_t *graph_config_get_selector (const oconfig_item_t *ci) /* {{{ */
+{
+ char *host = NULL;
+ char *plugin = NULL;
+ char *plugin_instance = NULL;
+ char *type = NULL;
+ char *type_instance = NULL;
+ graph_ident_t *ret;
+ int i;
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child;
+
+ child = ci->children + i;
+
+ if (strcasecmp ("Host", child->key) == 0)
+ graph_config_get_string (child, &host);
+ else if (strcasecmp ("Plugin", child->key) == 0)
+ graph_config_get_string (child, &plugin);
+ else if (strcasecmp ("PluginInstance", child->key) == 0)
+ graph_config_get_string (child, &plugin_instance);
+ else if (strcasecmp ("Type", child->key) == 0)
+ graph_config_get_string (child, &type);
+ else if (strcasecmp ("TypeInstance", child->key) == 0)
+ graph_config_get_string (child, &type_instance);
+ /* else: ignore all other directives here. */
+ } /* for */
+
+ ret = ident_create (host, plugin, plugin_instance, type, type_instance);
+
+ free (host);
+ free (plugin);
+ free (plugin_instance);
+ free (type);
+ free (type_instance);
+
+ return (ret);
+} /* }}} int graph_config_get_selector */
+
+/*
+ * Global functions
+ */
+graph_config_t *graph_create (const graph_ident_t *selector) /* {{{ */
+{
+ graph_config_t *cfg;
+
+ cfg = malloc (sizeof (*cfg));
+ if (cfg == NULL)
+ return (NULL);
+ memset (cfg, 0, sizeof (*cfg));
+
+ if (selector != NULL)
+ cfg->select = ident_clone (selector);
+ else
+ cfg->select = NULL;
+
+ cfg->title = NULL;
+ cfg->vertical_label = NULL;
+ cfg->defs = NULL;
+ cfg->instances = NULL;
+
+ return (cfg);
+} /* }}} int graph_create */
+
+void graph_destroy (graph_config_t *cfg) /* {{{ */
+{
+ if (cfg == NULL)
+ return;
+
+ ident_destroy (cfg->select);
+
+ free (cfg->title);
+ free (cfg->vertical_label);
+
+ def_destroy (cfg->defs);
+ inst_destroy (cfg->instances);
+} /* }}} void graph_destroy */
+
+int graph_config_add (const oconfig_item_t *ci) /* {{{ */
+{
+ graph_ident_t *select;
+ graph_config_t *cfg = NULL;
+ int i;
+
+ select = graph_config_get_selector (ci);
+ if (select == NULL)
+ return (EINVAL);
+
+ cfg = graph_create (/* selector = */ NULL);
+ if (cfg == NULL)
+ return (ENOMEM);
+
+ cfg->select = select;
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child;
+
+ child = ci->children + i;
+
+ if (strcasecmp ("Title", child->key) == 0)
+ graph_config_get_string (child, &cfg->title);
+ else if (strcasecmp ("VerticalLabel", child->key) == 0)
+ graph_config_get_string (child, &cfg->vertical_label);
+ else if (strcasecmp ("DEF", child->key) == 0)
+ def_config (cfg, child);
+ } /* for */
+
+ gl_add_graph (cfg);
+
+ return (0);
+} /* }}} graph_config_add */
+
+int graph_add_file (graph_config_t *cfg, const graph_ident_t *file) /* {{{ */
+{
+ graph_instance_t *inst;
+
+ inst = graph_find_instance (cfg, file);
+ if (inst == NULL)
+ {
+ inst = inst_create (cfg, file);
+ if (inst == NULL)
+ return (ENOMEM);
+
+ if (cfg->instances == NULL)
+ cfg->instances = inst;
+ else
+ inst_append (cfg->instances, inst);
+ }
+
+ return (inst_add_file (inst, file));
+} /* }}} int graph_add_file */
+
+int gl_graph_get_title (graph_config_t *cfg, /* {{{ */
+ char *buffer, size_t buffer_size)
+{
+ if ((cfg == NULL) || (buffer == NULL) || (buffer_size < 1))
+ return (EINVAL);
+
+ if (cfg->title == NULL)
+ cfg->title = ident_to_string (cfg->select);
+
+ if (cfg->title == NULL)
+ return (ENOMEM);
+
+ strncpy (buffer, cfg->title, buffer_size);
+ buffer[buffer_size - 1] = 0;
+
+ return (0);
+} /* }}} int gl_graph_get_title */
+
+graph_ident_t *gl_graph_get_selector (graph_config_t *cfg) /* {{{ */
+{
+ if (cfg == NULL)
+ return (NULL);
+
+ return (ident_clone (cfg->select));
+} /* }}} graph_ident_t *gl_graph_get_selector */
+
+graph_instance_t *gl_graph_get_instances (graph_config_t *cfg) /* {{{ */
+{
+ if (cfg == NULL)
+ return (NULL);
+
+ return (cfg->instances);
+} /* }}} graph_instance_t *gl_graph_get_instances */
+
+graph_def_t *gl_graph_get_defs (graph_config_t *cfg) /* {{{ */
+{
+ if (cfg == NULL)
+ return (NULL);
+
+ return (cfg->defs);
+} /* }}} graph_def_t *gl_graph_get_defs */
+
+int gl_graph_add_def (graph_config_t *cfg, graph_def_t *def) /* {{{ */
+{
+ if ((cfg == NULL) || (def == NULL))
+ return (EINVAL);
+
+ if (cfg->defs == NULL)
+ {
+ cfg->defs = def;
+ return (0);
+ }
+
+ return (def_append (cfg->defs, def));
+} /* }}} int gl_graph_add_def */
+
+_Bool graph_matches (graph_config_t *cfg, const graph_ident_t *ident) /* {{{ */
+{
+ if ((cfg == NULL) || (ident == NULL))
+ return (0);
+
+ return (ident_matches (cfg->select, ident));
+} /* }}} _Bool graph_matches */
+
+int graph_compare (graph_config_t *cfg, const graph_ident_t *ident) /* {{{ */
+{
+ if ((cfg == NULL) || (ident == NULL))
+ return (0);
+
+ return (ident_compare (cfg->select, ident));
+} /* }}} int graph_compare */
+
+int graph_clear_instances (graph_config_t *cfg) /* {{{ */
+{
+ if (cfg == NULL)
+ return (EINVAL);
+
+ inst_destroy (cfg->instances);
+ cfg->instances = NULL;
+
+ return (0);
+} /* }}} int graph_clear_instances */
+
+/* vim: set sw=2 sts=2 et fdm=marker : */
}; /* }}} */
typedef struct gl_ident_stage_s gl_ident_stage_t;
-struct graph_config_s /* {{{ */
-{
- graph_ident_t *select;
-
- char *title;
- char *vertical_label;
-
- graph_def_t *defs;
-
- graph_instance_t *instances;
-
- graph_config_t *next;
-}; /* }}} struct graph_config_s */
-
/*
* Global variables
*/
-static graph_config_t *graph_config_head = NULL;
-static graph_config_t *graph_config_staging = NULL;
+static graph_config_t **gl_active = NULL;
+static size_t gl_active_num = 0;
+
+static graph_config_t **gl_staging = NULL;
+static size_t gl_staging_num = 0;
static time_t gl_last_update = 0;
} /* }}} int strcmp_s */
#endif
-/*
- * Copy part of an identifier. If the "template" value is ANY_TOKEN, "value" is
- * copied and returned. This function is used when creating graph_instance_t
- * from graph_config_t.
- */
-
-static graph_instance_t *graph_find_instance (graph_config_t *cfg, /* {{{ */
- const graph_ident_t *ident)
-{
- if ((cfg == NULL) || (ident == NULL))
- return (NULL);
-
- return (inst_find_matching (cfg->instances, ident));
-} /* }}} graph_instance_t *graph_find_instance */
-
-static int graph_add_file (graph_config_t *cfg, const graph_ident_t *file) /* {{{ */
+int gl_add_graph_internal (graph_config_t *cfg, /* {{{ */
+ graph_config_t ***gl_array, size_t *gl_array_num)
{
- graph_instance_t *inst;
+ graph_config_t **tmp;
- inst = graph_find_instance (cfg, file);
- if (inst == NULL)
- {
- inst = inst_create (cfg, file);
- if (inst == NULL)
- return (ENOMEM);
-
- if (cfg->instances == NULL)
- cfg->instances = inst;
- else
- inst_append (cfg->instances, inst);
- }
-
- return (inst_add_file (inst, file));
-} /* }}} int graph_add_file */
-
-static int graph_append (graph_config_t **head, /* {{{ */
- graph_config_t *cfg)
-{
- graph_config_t *last;
+#define ARRAY_PTR (*gl_array)
+#define ARRAY_SIZE (*gl_array_num)
if (cfg == NULL)
return (EINVAL);
- if (head == NULL)
- head = &graph_config_head;
-
- if (*head == NULL)
- {
- *head = cfg;
- return (0);
- }
+ tmp = realloc (ARRAY_PTR, sizeof (*ARRAY_PTR) * (ARRAY_SIZE + 1));
+ if (tmp == NULL)
+ return (ENOMEM);
+ ARRAY_PTR = tmp;
- last = *head;
- while (last->next != NULL)
- last = last->next;
+ ARRAY_PTR[ARRAY_SIZE] = cfg;
+ ARRAY_SIZE++;
- last->next = cfg;
+#undef ARRAY_SIZE
+#undef ARRAY_PTR
return (0);
-} /* }}} int graph_append */
-
-static graph_config_t *graph_create (const graph_ident_t *selector) /* {{{ */
-{
- graph_config_t *cfg;
-
- cfg = malloc (sizeof (*cfg));
- if (cfg == NULL)
- return (NULL);
- memset (cfg, 0, sizeof (*cfg));
-
- if (selector != NULL)
- cfg->select = ident_clone (selector);
- else
- cfg->select = NULL;
-
- cfg->title = NULL;
- cfg->vertical_label = NULL;
- cfg->defs = NULL;
- cfg->instances = NULL;
- cfg->next = NULL;
-
- return (cfg);
-} /* }}} int graph_create */
-
-static void graph_destroy (graph_config_t *cfg) /* {{{ */
-{
- graph_config_t *next;
-
- if (cfg == NULL)
- return;
-
- next = cfg->next;
-
- ident_destroy (cfg->select);
-
- free (cfg->title);
- free (cfg->vertical_label);
-
- def_destroy (cfg->defs);
- inst_destroy (cfg->instances);
-
- graph_destroy (next);
-} /* }}} void graph_destroy */
+} /* }}} int gl_add_graph_internal */
static int gl_register_file (const graph_ident_t *file, /* {{{ */
__attribute__((unused)) void *user_data)
{
graph_config_t *cfg;
int num_graphs = 0;
+ size_t i;
- for (cfg = graph_config_head; cfg != NULL; cfg = cfg->next)
+ for (i = 0; i < gl_active_num; i++)
{
+ graph_config_t *cfg = gl_active[i];
int status;
- if (!ident_matches (cfg->select, file))
+ if (!graph_matches (cfg, file))
continue;
status = graph_add_file (cfg, file);
if (num_graphs == 0)
{
cfg = graph_create (file);
- graph_append (/* head = */ NULL, cfg);
+ gl_add_graph_internal (cfg, &gl_active, &gl_active_num);
graph_add_file (cfg, file);
}
static int gl_clear_instances (void) /* {{{ */
{
- graph_config_t *cfg;
+ size_t i;
- for (cfg = graph_config_head; cfg != NULL; cfg = cfg->next)
- {
- inst_destroy (cfg->instances);
- cfg->instances = NULL;
- }
+ for (i = 0; i < gl_active_num; i++)
+ graph_clear_instances (gl_active[i]);
return (0);
} /* }}} int gl_clear_instances */
/*
- * Config functions
+ * Global functions
*/
-static graph_ident_t *graph_config_get_selector (const oconfig_item_t *ci) /* {{{ */
+int gl_add_graph (graph_config_t *cfg) /* {{{ */
{
- char *host = NULL;
- char *plugin = NULL;
- char *plugin_instance = NULL;
- char *type = NULL;
- char *type_instance = NULL;
- graph_ident_t *ret;
- int i;
-
- for (i = 0; i < ci->children_num; i++)
- {
- oconfig_item_t *child;
-
- child = ci->children + i;
-
- if (strcasecmp ("Host", child->key) == 0)
- graph_config_get_string (child, &host);
- else if (strcasecmp ("Plugin", child->key) == 0)
- graph_config_get_string (child, &plugin);
- else if (strcasecmp ("PluginInstance", child->key) == 0)
- graph_config_get_string (child, &plugin_instance);
- else if (strcasecmp ("Type", child->key) == 0)
- graph_config_get_string (child, &type);
- else if (strcasecmp ("TypeInstance", child->key) == 0)
- graph_config_get_string (child, &type_instance);
- /* else: ignore all other directives here. */
- } /* for */
-
- ret = ident_create (host, plugin, plugin_instance, type, type_instance);
-
- free (host);
- free (plugin);
- free (plugin_instance);
- free (type);
- free (type_instance);
-
- return (ret);
-} /* }}} int graph_config_get_selector */
+ return (gl_add_graph_internal (cfg, &gl_staging, &gl_staging_num));
+} /* }}} int gl_add_graph */
-/*
- * Global functions
- */
-int graph_config_add (const oconfig_item_t *ci) /* {{{ */
+int graph_config_submit (void) /* {{{ */
{
- graph_ident_t *select;
- graph_config_t *cfg = NULL;
- int i;
+ graph_config_t **old;
+ size_t old_num;
+ size_t i;
- select = graph_config_get_selector (ci);
- if (select == NULL)
- return (EINVAL);
+ old = gl_active;
+ old_num = gl_active_num;
- cfg = graph_create (/* selector = */ NULL);
- if (cfg == NULL)
- return (ENOMEM);
+ gl_active = gl_staging;
+ gl_active_num = gl_staging_num;
- cfg->select = select;
+ gl_staging = NULL;
+ gl_staging_num = 0;
- for (i = 0; i < ci->children_num; i++)
+ for (i = 0; i < old_num; i++)
{
- oconfig_item_t *child;
-
- child = ci->children + i;
-
- if (strcasecmp ("Title", child->key) == 0)
- graph_config_get_string (child, &cfg->title);
- else if (strcasecmp ("VerticalLabel", child->key) == 0)
- graph_config_get_string (child, &cfg->vertical_label);
- else if (strcasecmp ("DEF", child->key) == 0)
- def_config (cfg, child);
- } /* for */
-
- graph_append (&graph_config_staging, cfg);
-
- return (0);
-} /* }}} graph_config_add */
-
-int graph_config_submit (void) /* {{{ */
-{
- graph_config_t *tmp;
-
- tmp = graph_config_head;
- graph_config_head = graph_config_staging;
- graph_config_staging = NULL;
-
- graph_destroy (tmp);
+ graph_destroy (old[i]);
+ old[i] = NULL;
+ }
+ free (old);
return (0);
} /* }}} int graph_config_submit */
int gl_graph_get_all (gl_cfg_callback callback, /* {{{ */
void *user_data)
{
- graph_config_t *cfg;
+ size_t i;
if (callback == NULL)
return (EINVAL);
gl_update ();
- for (cfg = graph_config_head; cfg != NULL; cfg = cfg->next)
+ for (i = 0; i < gl_active_num; i++)
{
int status;
- status = (*callback) (cfg, user_data);
+ status = (*callback) (gl_active[i], user_data);
if (status != 0)
return (status);
}
const char *type = get_part_from_param ("graph_type", "type");
const char *type_instance = get_part_from_param ("graph_type_instance", "type_instance");
graph_ident_t *ident;
- graph_config_t *cfg;
+ size_t i;
if ((host == NULL)
|| (plugin == NULL) || (plugin_instance == NULL)
gl_update ();
- for (cfg = graph_config_head; cfg != NULL; cfg = cfg->next)
+ for (i = 0; i < gl_active_num; i++)
{
- if (ident_compare (ident, cfg->select) != 0)
+ if (graph_compare (gl_active[i], ident) != 0)
continue;
ident_destroy (ident);
- return (cfg);
+ return (gl_active[i]);
}
ident_destroy (ident);
if ((cfg == NULL) || (callback == NULL))
return (EINVAL);
- return (inst_foreach (cfg->instances, gl_inst_callback_handler, &data));
+ return (inst_foreach (gl_graph_get_instances (cfg),
+ gl_inst_callback_handler, &data));
} /* }}} int gl_graph_instance_get_all */
int gl_instance_get_all (gl_inst_callback callback, /* {{{ */
void *user_data)
{
- graph_config_t *cfg;
+ size_t i;
gl_update ();
- for (cfg = graph_config_head; cfg != NULL; cfg = cfg->next)
+ for (i = 0; i < gl_active_num; i++)
{
int status;
- status = gl_graph_instance_get_all (cfg, callback, user_data);
+ status = gl_graph_instance_get_all (gl_active[i], callback, user_data);
if (status != 0)
return (status);
}
} /* }}} int gl_instance_get_all */
/* }}} gl_instance_get_all, gl_graph_instance_get_all */
-int gl_graph_get_title (graph_config_t *cfg, /* {{{ */
- char *buffer, size_t buffer_size)
-{
- if ((cfg == NULL) || (buffer == NULL) || (buffer_size < 1))
- return (EINVAL);
-
- if (cfg->title == NULL)
- cfg->title = ident_to_string (cfg->select);
-
- if (cfg->title == NULL)
- return (ENOMEM);
-
- strncpy (buffer, cfg->title, buffer_size);
- buffer[buffer_size - 1] = 0;
-
- return (0);
-} /* }}} int gl_graph_get_title */
-
-graph_ident_t *gl_graph_get_selector (graph_config_t *cfg) /* {{{ */
-{
- if (cfg == NULL)
- return (NULL);
-
- return (ident_clone (cfg->select));
-} /* }}} graph_ident_t *gl_graph_get_selector */
-
-graph_instance_t *gl_graph_get_instances (graph_config_t *cfg) /* {{{ */
-{
- if (cfg == NULL)
- return (NULL);
-
- return (cfg->instances);
-} /* }}} graph_instance_t *gl_graph_get_instances */
-
-graph_def_t *gl_graph_get_defs (graph_config_t *cfg) /* {{{ */
-{
- if (cfg == NULL)
- return (NULL);
-
- return (cfg->defs);
-} /* }}} graph_def_t *gl_graph_get_defs */
-
-int gl_graph_add_def (graph_config_t *cfg, graph_def_t *def) /* {{{ */
-{
- if ((cfg == NULL) || (def == NULL))
- return (EINVAL);
-
- if (cfg->defs == NULL)
- {
- cfg->defs = def;
- return (0);
- }
-
- return (def_append (cfg->defs, def));
-} /* }}} int gl_graph_add_def */
-
int gl_update (void) /* {{{ */
{
time_t now;