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_ident.h"
11 #include "graph_def.h"
12 #include "graph_config.h"
13 #include "common.h"
14 #include "filesystem.h"
15 #include "utils_params.h"
17 #include <fcgiapp.h>
18 #include <fcgi_stdio.h>
20 /*
21 * Defines
22 */
23 #define UPDATE_INTERVAL 10
25 /*
26 * Global variables
27 */
28 static graph_config_t **gl_active = NULL;
29 static size_t gl_active_num = 0;
31 static graph_config_t **gl_staging = NULL;
32 static size_t gl_staging_num = 0;
34 static time_t gl_last_update = 0;
36 /*
37 * Private functions
38 */
39 int gl_add_graph_internal (graph_config_t *cfg, /* {{{ */
40 graph_config_t ***gl_array, size_t *gl_array_num)
41 {
42 graph_config_t **tmp;
44 #define ARRAY_PTR (*gl_array)
45 #define ARRAY_SIZE (*gl_array_num)
47 if (cfg == NULL)
48 return (EINVAL);
50 tmp = realloc (ARRAY_PTR, sizeof (*ARRAY_PTR) * (ARRAY_SIZE + 1));
51 if (tmp == NULL)
52 return (ENOMEM);
53 ARRAY_PTR = tmp;
55 ARRAY_PTR[ARRAY_SIZE] = cfg;
56 ARRAY_SIZE++;
58 #undef ARRAY_SIZE
59 #undef ARRAY_PTR
61 return (0);
62 } /* }}} int gl_add_graph_internal */
64 static int gl_register_file (const graph_ident_t *file, /* {{{ */
65 __attribute__((unused)) void *user_data)
66 {
67 graph_config_t *cfg;
68 int num_graphs = 0;
69 size_t i;
71 for (i = 0; i < gl_active_num; i++)
72 {
73 graph_config_t *cfg = gl_active[i];
74 int status;
76 if (!graph_matches (cfg, file))
77 continue;
79 status = graph_add_file (cfg, file);
80 if (status != 0)
81 {
82 /* report error */;
83 }
84 else
85 {
86 num_graphs++;
87 }
88 }
90 if (num_graphs == 0)
91 {
92 cfg = graph_create (file);
93 gl_add_graph_internal (cfg, &gl_active, &gl_active_num);
94 graph_add_file (cfg, file);
95 }
97 return (0);
98 } /* }}} int gl_register_file */
100 static const char *get_part_from_param (const char *prim_key, /* {{{ */
101 const char *sec_key)
102 {
103 const char *val;
105 val = param (prim_key);
106 if (val != NULL)
107 return (val);
109 return (param (sec_key));
110 } /* }}} const char *get_part_from_param */
112 static int gl_clear_instances (void) /* {{{ */
113 {
114 size_t i;
116 for (i = 0; i < gl_active_num; i++)
117 graph_clear_instances (gl_active[i]);
119 return (0);
120 } /* }}} int gl_clear_instances */
123 /*
124 * Global functions
125 */
126 int gl_add_graph (graph_config_t *cfg) /* {{{ */
127 {
128 return (gl_add_graph_internal (cfg, &gl_staging, &gl_staging_num));
129 } /* }}} int gl_add_graph */
131 int gl_config_submit (void) /* {{{ */
132 {
133 graph_config_t **old;
134 size_t old_num;
135 size_t i;
137 old = gl_active;
138 old_num = gl_active_num;
140 gl_active = gl_staging;
141 gl_active_num = gl_staging_num;
143 gl_staging = NULL;
144 gl_staging_num = 0;
146 for (i = 0; i < old_num; i++)
147 {
148 graph_destroy (old[i]);
149 old[i] = NULL;
150 }
151 free (old);
153 return (0);
154 } /* }}} int graph_config_submit */
156 int gl_graph_get_all (gl_cfg_callback callback, /* {{{ */
157 void *user_data)
158 {
159 size_t i;
161 if (callback == NULL)
162 return (EINVAL);
164 gl_update ();
166 for (i = 0; i < gl_active_num; i++)
167 {
168 int status;
170 status = (*callback) (gl_active[i], user_data);
171 if (status != 0)
172 return (status);
173 }
175 return (0);
176 } /* }}} int gl_graph_get_all */
178 graph_config_t *gl_graph_get_selected (void) /* {{{ */
179 {
180 const char *host = get_part_from_param ("graph_host", "host");
181 const char *plugin = get_part_from_param ("graph_plugin", "plugin");
182 const char *plugin_instance = get_part_from_param ("graph_plugin_instance", "plugin_instance");
183 const char *type = get_part_from_param ("graph_type", "type");
184 const char *type_instance = get_part_from_param ("graph_type_instance", "type_instance");
185 graph_ident_t *ident;
186 size_t i;
188 if ((host == NULL)
189 || (plugin == NULL) || (plugin_instance == NULL)
190 || (type == NULL) || (type_instance == NULL))
191 return (NULL);
193 ident = ident_create (host, plugin, plugin_instance, type, type_instance);
195 gl_update ();
197 for (i = 0; i < gl_active_num; i++)
198 {
199 if (graph_compare (gl_active[i], ident) != 0)
200 continue;
202 ident_destroy (ident);
203 return (gl_active[i]);
204 }
206 ident_destroy (ident);
207 return (NULL);
208 } /* }}} graph_config_t *gl_graph_get_selected */
210 /* gl_instance_get_all, gl_graph_instance_get_all {{{ */
211 struct gl_inst_callback_data /* {{{ */
212 {
213 graph_config_t *cfg;
214 gl_inst_callback callback;
215 void *user_data;
216 }; /* }}} struct gl_inst_callback_data */
218 static int gl_inst_callback_handler (graph_instance_t *inst, /* {{{ */
219 void *user_data)
220 {
221 struct gl_inst_callback_data *data = user_data;
223 return ((*data->callback) (data->cfg, inst, data->user_data));
224 } /* }}} int gl_inst_callback_handler */
226 int gl_graph_instance_get_all (graph_config_t *cfg, /* {{{ */
227 gl_inst_callback callback, void *user_data)
228 {
229 struct gl_inst_callback_data data =
230 {
231 cfg,
232 callback,
233 user_data
234 };
236 if ((cfg == NULL) || (callback == NULL))
237 return (EINVAL);
239 return (inst_foreach (graph_get_instances (cfg),
240 gl_inst_callback_handler, &data));
241 } /* }}} int gl_graph_instance_get_all */
243 int gl_instance_get_all (gl_inst_callback 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_update (void) /* {{{ */
264 {
265 time_t now;
266 int status;
268 /*
269 printf ("Content-Type: text/plain\n\n");
270 */
272 now = time (NULL);
274 if ((gl_last_update + UPDATE_INTERVAL) >= now)
275 return (0);
277 graph_read_config ();
279 gl_clear_instances ();
280 status = fs_scan (/* callback = */ gl_register_file, /* user data = */ NULL);
282 gl_last_update = now;
284 return (status);
285 } /* }}} int gl_update */
287 /* vim: set sw=2 sts=2 et fdm=marker : */