1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <inttypes.h>
5 #include <string.h>
6 #include <time.h>
7 #include <errno.h>
9 #include "graph_list.h"
10 #include "graph.h"
11 #include "graph_ident.h"
12 #include "graph_def.h"
13 #include "graph_config.h"
14 #include "common.h"
15 #include "filesystem.h"
16 #include "utils_cgi.h"
18 #include <fcgiapp.h>
19 #include <fcgi_stdio.h>
21 /*
22 * Defines
23 */
24 #define UPDATE_INTERVAL 10
26 /*
27 * Global variables
28 */
29 static graph_config_t **gl_active = NULL;
30 static size_t gl_active_num = 0;
32 static graph_config_t **gl_staging = NULL;
33 static size_t gl_staging_num = 0;
35 static time_t gl_last_update = 0;
37 /*
38 * Private functions
39 */
40 int gl_add_graph_internal (graph_config_t *cfg, /* {{{ */
41 graph_config_t ***gl_array, size_t *gl_array_num)
42 {
43 graph_config_t **tmp;
45 #define ARRAY_PTR (*gl_array)
46 #define ARRAY_SIZE (*gl_array_num)
48 if (cfg == NULL)
49 return (EINVAL);
51 tmp = realloc (ARRAY_PTR, sizeof (*ARRAY_PTR) * (ARRAY_SIZE + 1));
52 if (tmp == NULL)
53 return (ENOMEM);
54 ARRAY_PTR = tmp;
56 ARRAY_PTR[ARRAY_SIZE] = cfg;
57 ARRAY_SIZE++;
59 #undef ARRAY_SIZE
60 #undef ARRAY_PTR
62 return (0);
63 } /* }}} int gl_add_graph_internal */
65 static int gl_register_file (const graph_ident_t *file, /* {{{ */
66 __attribute__((unused)) void *user_data)
67 {
68 graph_config_t *cfg;
69 int num_graphs = 0;
70 size_t i;
72 for (i = 0; i < gl_active_num; i++)
73 {
74 graph_config_t *cfg = gl_active[i];
75 int status;
77 if (!graph_matches_ident (cfg, file))
78 continue;
80 status = graph_add_file (cfg, file);
81 if (status != 0)
82 {
83 /* report error */;
84 }
85 else
86 {
87 num_graphs++;
88 }
89 }
91 if (num_graphs == 0)
92 {
93 cfg = graph_create (file);
94 gl_add_graph_internal (cfg, &gl_active, &gl_active_num);
95 graph_add_file (cfg, file);
96 }
98 return (0);
99 } /* }}} int gl_register_file */
101 static const char *get_part_from_param (const char *prim_key, /* {{{ */
102 const char *sec_key)
103 {
104 const char *val;
106 val = param (prim_key);
107 if (val != NULL)
108 return (val);
110 return (param (sec_key));
111 } /* }}} const char *get_part_from_param */
113 static int gl_clear_instances (void) /* {{{ */
114 {
115 size_t i;
117 for (i = 0; i < gl_active_num; i++)
118 graph_clear_instances (gl_active[i]);
120 return (0);
121 } /* }}} int gl_clear_instances */
124 /*
125 * Global functions
126 */
127 int gl_add_graph (graph_config_t *cfg) /* {{{ */
128 {
129 return (gl_add_graph_internal (cfg, &gl_staging, &gl_staging_num));
130 } /* }}} int gl_add_graph */
132 int gl_config_submit (void) /* {{{ */
133 {
134 graph_config_t **old;
135 size_t old_num;
136 size_t i;
138 old = gl_active;
139 old_num = gl_active_num;
141 gl_active = gl_staging;
142 gl_active_num = gl_staging_num;
144 gl_staging = NULL;
145 gl_staging_num = 0;
147 for (i = 0; i < old_num; i++)
148 {
149 graph_destroy (old[i]);
150 old[i] = NULL;
151 }
152 free (old);
154 return (0);
155 } /* }}} int graph_config_submit */
157 int gl_graph_get_all (graph_callback_t callback, /* {{{ */
158 void *user_data)
159 {
160 size_t i;
162 if (callback == NULL)
163 return (EINVAL);
165 gl_update ();
167 for (i = 0; i < gl_active_num; i++)
168 {
169 int status;
171 status = (*callback) (gl_active[i], user_data);
172 if (status != 0)
173 return (status);
174 }
176 return (0);
177 } /* }}} int gl_graph_get_all */
179 graph_config_t *gl_graph_get_selected (void) /* {{{ */
180 {
181 const char *host = get_part_from_param ("graph_host", "host");
182 const char *plugin = get_part_from_param ("graph_plugin", "plugin");
183 const char *plugin_instance = get_part_from_param ("graph_plugin_instance", "plugin_instance");
184 const char *type = get_part_from_param ("graph_type", "type");
185 const char *type_instance = get_part_from_param ("graph_type_instance", "type_instance");
186 graph_ident_t *ident;
187 size_t i;
189 if ((host == NULL)
190 || (plugin == NULL) || (plugin_instance == NULL)
191 || (type == NULL) || (type_instance == NULL))
192 return (NULL);
194 ident = ident_create (host, plugin, plugin_instance, type, type_instance);
196 gl_update ();
198 for (i = 0; i < gl_active_num; i++)
199 {
200 if (graph_compare (gl_active[i], ident) != 0)
201 continue;
203 ident_destroy (ident);
204 return (gl_active[i]);
205 }
207 ident_destroy (ident);
208 return (NULL);
209 } /* }}} graph_config_t *gl_graph_get_selected */
211 /* gl_instance_get_all, gl_graph_instance_get_all {{{ */
212 struct gl_inst_callback_data /* {{{ */
213 {
214 graph_config_t *cfg;
215 graph_inst_callback_t callback;
216 void *user_data;
217 }; /* }}} struct gl_inst_callback_data */
219 static int gl_inst_callback_handler (graph_instance_t *inst, /* {{{ */
220 void *user_data)
221 {
222 struct gl_inst_callback_data *data = user_data;
224 return ((*data->callback) (data->cfg, inst, data->user_data));
225 } /* }}} int gl_inst_callback_handler */
227 int gl_graph_instance_get_all (graph_config_t *cfg, /* {{{ */
228 graph_inst_callback_t callback, void *user_data)
229 {
230 struct gl_inst_callback_data data =
231 {
232 cfg,
233 callback,
234 user_data
235 };
237 if ((cfg == NULL) || (callback == NULL))
238 return (EINVAL);
240 return (graph_inst_foreach (cfg, gl_inst_callback_handler, &data));
241 } /* }}} int gl_graph_instance_get_all */
243 int gl_instance_get_all (graph_inst_callback_t callback, /* {{{ */
244 void *user_data)
245 {
246 size_t i;
248 gl_update ();
250 for (i = 0; i < gl_active_num; i++)
251 {
252 int status;
254 status = gl_graph_instance_get_all (gl_active[i], callback, user_data);
255 if (status != 0)
256 return (status);
257 }
259 return (0);
260 } /* }}} int gl_instance_get_all */
261 /* }}} gl_instance_get_all, gl_graph_instance_get_all */
263 int gl_search (const char *term, graph_inst_callback_t callback, /* {{{ */
264 void *user_data)
265 {
266 size_t i;
268 for (i = 0; i < gl_active_num; i++)
269 {
270 int status;
272 status = graph_inst_search (gl_active[i], term,
273 /* callback = */ callback,
274 /* user data = */ user_data);
275 if (status != 0)
276 return (status);
277 }
279 return (0);
280 } /* }}} int gl_search */
282 int gl_search_field (graph_ident_field_t field, /* {{{ */
283 const char *field_value,
284 graph_inst_callback_t callback, void *user_data)
285 {
286 size_t i;
288 if ((field_value == NULL) || (callback == NULL))
289 return (EINVAL);
291 for (i = 0; i < gl_active_num; i++)
292 {
293 int status;
295 status = graph_inst_search_field (gl_active[i],
296 field, field_value,
297 /* callback = */ callback,
298 /* user data = */ user_data);
299 if (status != 0)
300 return (status);
301 }
303 return (0);
304 } /* }}} int gl_search_field */
306 int gl_update (void) /* {{{ */
307 {
308 time_t now;
309 int status;
311 /*
312 printf ("Content-Type: text/plain\n\n");
313 */
315 now = time (NULL);
317 if ((gl_last_update + UPDATE_INTERVAL) >= now)
318 return (0);
320 graph_read_config ();
322 gl_clear_instances ();
323 status = fs_scan (/* callback = */ gl_register_file, /* user data = */ NULL);
325 gl_last_update = now;
327 return (status);
328 } /* }}} int gl_update */
330 /* vim: set sw=2 sts=2 et fdm=marker : */