2 * collection4 - graph_list.c
3 * Copyright (C) 2010 Florian octo Forster
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
21 * Florian octo Forster <ff at octo.it>
32 #include "graph_list.h"
34 #include "filesystem.h"
36 #include "graph_config.h"
37 #include "graph_def.h"
38 #include "graph_ident.h"
39 #include "utils_cgi.h"
40 #include "utils_search.h"
43 #include <fcgi_stdio.h>
48 #define UPDATE_INTERVAL 900
53 static graph_config_t **gl_active = NULL;
54 static size_t gl_active_num = 0;
56 static graph_config_t **gl_staging = NULL;
57 static size_t gl_staging_num = 0;
59 /* Graphs created on-the-fly for files which don't match any existing graph
61 static graph_config_t **gl_dynamic = NULL;
62 static size_t gl_dynamic_num = 0;
64 static char **host_list = NULL;
65 static size_t host_list_len = 0;
67 static time_t gl_last_update = 0;
72 static int gl_add_graph_internal (graph_config_t *cfg, /* {{{ */
73 graph_config_t ***gl_array, size_t *gl_array_num)
77 #define ARRAY_PTR (*gl_array)
78 #define ARRAY_SIZE (*gl_array_num)
83 tmp = realloc (ARRAY_PTR, sizeof (*ARRAY_PTR) * (ARRAY_SIZE + 1));
88 ARRAY_PTR[ARRAY_SIZE] = cfg;
95 } /* }}} int gl_add_graph_internal */
97 static void gl_destroy (graph_config_t ***gl_array, /* {{{ */
102 if ((gl_array == NULL) || (gl_array_num == NULL))
105 #define ARRAY_PTR (*gl_array)
106 #define ARRAY_SIZE (*gl_array_num)
108 for (i = 0; i < ARRAY_SIZE; i++)
110 graph_destroy (ARRAY_PTR[i]);
119 } /* }}} void gl_destroy */
121 static int gl_register_host (const char *host) /* {{{ */
129 for (i = 0; i < host_list_len; i++)
130 if (strcmp (host_list[i], host) == 0)
133 tmp = realloc (host_list, sizeof (*host_list) * (host_list_len + 1));
138 host_list[host_list_len] = strdup (host);
139 if (host_list[host_list_len] == NULL)
144 } /* }}} int gl_register_host */
146 static int gl_clear_hosts (void) /* {{{ */
150 for (i = 0; i < host_list_len; i++)
158 } /* }}} int gl_clear_hosts */
160 static int gl_compare_hosts (const void *v0, const void *v1) /* {{{ */
162 return (strcmp (*(char * const *) v0, *(char * const *) v1));
163 } /* }}} int gl_compare_hosts */
165 static int gl_register_file (const graph_ident_t *file, /* {{{ */
166 __attribute__((unused)) void *user_data)
172 for (i = 0; i < gl_active_num; i++)
174 graph_config_t *cfg = gl_active[i];
177 if (!graph_ident_matches (cfg, file))
180 status = graph_add_file (cfg, file);
193 cfg = graph_create (file);
194 gl_add_graph_internal (cfg, &gl_dynamic, &gl_dynamic_num);
195 graph_add_file (cfg, file);
198 gl_register_host (ident_get_host (file));
201 } /* }}} int gl_register_file */
203 static const char *get_part_from_param (const char *prim_key, /* {{{ */
208 val = param (prim_key);
212 return (param (sec_key));
213 } /* }}} const char *get_part_from_param */
215 static int gl_clear_instances (void) /* {{{ */
219 for (i = 0; i < gl_active_num; i++)
220 graph_clear_instances (gl_active[i]);
223 } /* }}} int gl_clear_instances */
228 int gl_add_graph (graph_config_t *cfg) /* {{{ */
230 return (gl_add_graph_internal (cfg, &gl_staging, &gl_staging_num));
231 } /* }}} int gl_add_graph */
233 int gl_config_submit (void) /* {{{ */
235 graph_config_t **old;
239 old_num = gl_active_num;
241 gl_active = gl_staging;
242 gl_active_num = gl_staging_num;
247 gl_destroy (&old, &old_num);
250 } /* }}} int graph_config_submit */
252 int gl_graph_get_all (graph_callback_t callback, /* {{{ */
257 if (callback == NULL)
262 for (i = 0; i < gl_active_num; i++)
266 status = (*callback) (gl_active[i], user_data);
271 for (i = 0; i < gl_dynamic_num; i++)
275 status = (*callback) (gl_dynamic[i], user_data);
281 } /* }}} int gl_graph_get_all */
283 graph_config_t *gl_graph_get_selected (void) /* {{{ */
285 const char *host = get_part_from_param ("graph_host", "host");
286 const char *plugin = get_part_from_param ("graph_plugin", "plugin");
287 const char *plugin_instance = get_part_from_param ("graph_plugin_instance", "plugin_instance");
288 const char *type = get_part_from_param ("graph_type", "type");
289 const char *type_instance = get_part_from_param ("graph_type_instance", "type_instance");
290 graph_ident_t *ident;
294 || (plugin == NULL) || (plugin_instance == NULL)
295 || (type == NULL) || (type_instance == NULL))
298 ident = ident_create (host, plugin, plugin_instance, type, type_instance);
302 for (i = 0; i < gl_active_num; i++)
304 if (graph_compare (gl_active[i], ident) != 0)
307 ident_destroy (ident);
308 return (gl_active[i]);
311 for (i = 0; i < gl_dynamic_num; i++)
313 if (graph_compare (gl_dynamic[i], ident) != 0)
316 ident_destroy (ident);
317 return (gl_dynamic[i]);
320 ident_destroy (ident);
322 } /* }}} graph_config_t *gl_graph_get_selected */
324 /* gl_instance_get_all, gl_graph_instance_get_all {{{ */
325 struct gl_inst_callback_data /* {{{ */
328 graph_inst_callback_t callback;
330 }; /* }}} struct gl_inst_callback_data */
332 static int gl_inst_callback_handler (graph_instance_t *inst, /* {{{ */
335 struct gl_inst_callback_data *data = user_data;
337 return ((*data->callback) (data->cfg, inst, data->user_data));
338 } /* }}} int gl_inst_callback_handler */
340 int gl_graph_instance_get_all (graph_config_t *cfg, /* {{{ */
341 graph_inst_callback_t callback, void *user_data)
343 struct gl_inst_callback_data data =
350 if ((cfg == NULL) || (callback == NULL))
353 return (graph_inst_foreach (cfg, gl_inst_callback_handler, &data));
354 } /* }}} int gl_graph_instance_get_all */
356 int gl_instance_get_all (graph_inst_callback_t callback, /* {{{ */
363 for (i = 0; i < gl_active_num; i++)
367 status = gl_graph_instance_get_all (gl_active[i], callback, user_data);
372 for (i = 0; i < gl_dynamic_num; i++)
376 status = gl_graph_instance_get_all (gl_dynamic[i], callback, user_data);
382 } /* }}} int gl_instance_get_all */
383 /* }}} gl_instance_get_all, gl_graph_instance_get_all */
385 int gl_search (search_info_t *si, /* {{{ */
386 graph_inst_callback_t callback, void *user_data)
389 graph_ident_t *ident;
391 if ((si == NULL) || (callback == NULL))
394 if (search_has_selector (si))
396 ident = search_to_ident (si);
399 fprintf (stderr, "gl_search: search_to_ident failed\n");
408 for (i = 0; i < gl_active_num; i++)
412 if ((ident != NULL) && !graph_ident_intersect (gl_active[i], ident))
415 status = graph_search_inst (gl_active[i], si,
416 /* callback = */ callback,
417 /* user data = */ user_data);
422 for (i = 0; i < gl_dynamic_num; i++)
426 if ((ident != NULL) && !graph_ident_intersect (gl_dynamic[i], ident))
429 status = graph_search_inst (gl_dynamic[i], si,
430 /* callback = */ callback,
431 /* user data = */ user_data);
437 } /* }}} int gl_search */
439 int gl_search_string (const char *term, graph_inst_callback_t callback, /* {{{ */
444 for (i = 0; i < gl_active_num; i++)
448 status = graph_search_inst_string (gl_active[i], term,
449 /* callback = */ callback,
450 /* user data = */ user_data);
455 for (i = 0; i < gl_dynamic_num; i++)
459 status = graph_search_inst_string (gl_dynamic[i], term,
460 /* callback = */ callback,
461 /* user data = */ user_data);
467 } /* }}} int gl_search_string */
469 int gl_search_field (graph_ident_field_t field, /* {{{ */
470 const char *field_value,
471 graph_inst_callback_t callback, void *user_data)
475 if ((field_value == NULL) || (callback == NULL))
478 for (i = 0; i < gl_active_num; i++)
482 status = graph_inst_search_field (gl_active[i],
484 /* callback = */ callback,
485 /* user data = */ user_data);
490 for (i = 0; i < gl_dynamic_num; i++)
494 status = graph_inst_search_field (gl_dynamic[i],
496 /* callback = */ callback,
497 /* user data = */ user_data);
503 } /* }}} int gl_search_field */
505 int gl_foreach_host (int (*callback) (const char *host, void *user_data), /* {{{ */
511 for (i = 0; i < host_list_len; i++)
513 status = (*callback) (host_list[i], user_data);
519 } /* }}} int gl_foreach_host */
521 int gl_update (void) /* {{{ */
528 printf ("Content-Type: text/plain\n\n");
533 if ((gl_last_update + UPDATE_INTERVAL) >= now)
537 gl_clear_instances ();
539 gl_destroy (&gl_dynamic, &gl_dynamic_num);
541 graph_read_config ();
543 status = fs_scan (/* callback = */ gl_register_file, /* user data = */ NULL);
545 if (host_list_len > 0)
546 qsort (host_list, host_list_len, sizeof (*host_list),
549 gl_last_update = now;
551 for (i = 0; i < gl_active_num; i++)
552 graph_sort_instances (gl_active[i]);
555 } /* }}} int gl_update */
557 /* vim: set sw=2 sts=2 et fdm=marker : */