62a4ed335cd8ed92f166ea83b50fa952a9b92fc2
[collection4.git] / src / graph_list.c
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>
8
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_cgi.h"
16
17 #include <fcgiapp.h>
18 #include <fcgi_stdio.h>
19
20 /*
21  * Defines
22  */
23 #define UPDATE_INTERVAL 10
24
25 /*
26  * Global variables
27  */
28 static graph_config_t **gl_active = NULL;
29 static size_t gl_active_num = 0;
30
31 static graph_config_t **gl_staging = NULL;
32 static size_t gl_staging_num = 0;
33
34 static time_t gl_last_update = 0;
35
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;
43
44 #define ARRAY_PTR  (*gl_array)
45 #define ARRAY_SIZE (*gl_array_num)
46
47   if (cfg == NULL)
48     return (EINVAL);
49
50   tmp = realloc (ARRAY_PTR, sizeof (*ARRAY_PTR) * (ARRAY_SIZE + 1));
51   if (tmp == NULL)
52     return (ENOMEM);
53   ARRAY_PTR = tmp;
54
55   ARRAY_PTR[ARRAY_SIZE] = cfg;
56   ARRAY_SIZE++;
57
58 #undef ARRAY_SIZE
59 #undef ARRAY_PTR
60
61   return (0);
62 } /* }}} int gl_add_graph_internal */
63
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;
70
71   for (i = 0; i < gl_active_num; i++)
72   {
73     graph_config_t *cfg = gl_active[i];
74     int status;
75
76     if (!graph_matches (cfg, file))
77       continue;
78
79     status = graph_add_file (cfg, file);
80     if (status != 0)
81     {
82       /* report error */;
83     }
84     else
85     {
86       num_graphs++;
87     }
88   }
89
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   }
96
97   return (0);
98 } /* }}} int gl_register_file */
99
100 static const char *get_part_from_param (const char *prim_key, /* {{{ */
101     const char *sec_key)
102 {
103   const char *val;
104
105   val = param (prim_key);
106   if (val != NULL)
107     return (val);
108   
109   return (param (sec_key));
110 } /* }}} const char *get_part_from_param */
111
112 static int gl_clear_instances (void) /* {{{ */
113 {
114   size_t i;
115
116   for (i = 0; i < gl_active_num; i++)
117     graph_clear_instances (gl_active[i]);
118
119   return (0);
120 } /* }}} int gl_clear_instances */
121
122
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 */
130
131 int gl_config_submit (void) /* {{{ */
132 {
133   graph_config_t **old;
134   size_t old_num;
135   size_t i;
136
137   old = gl_active;
138   old_num = gl_active_num;
139
140   gl_active = gl_staging;
141   gl_active_num = gl_staging_num;
142
143   gl_staging = NULL;
144   gl_staging_num = 0;
145
146   for (i = 0; i < old_num; i++)
147   {
148     graph_destroy (old[i]);
149     old[i] = NULL;
150   }
151   free (old);
152
153   return (0);
154 } /* }}} int graph_config_submit */
155
156 int gl_graph_get_all (graph_callback_t callback, /* {{{ */
157     void *user_data)
158 {
159   size_t i;
160
161   if (callback == NULL)
162     return (EINVAL);
163
164   gl_update ();
165
166   for (i = 0; i < gl_active_num; i++)
167   {
168     int status;
169
170     status = (*callback) (gl_active[i], user_data);
171     if (status != 0)
172       return (status);
173   }
174
175   return (0);
176 } /* }}} int gl_graph_get_all */
177
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;
187
188   if ((host == NULL)
189       || (plugin == NULL) || (plugin_instance == NULL)
190       || (type == NULL) || (type_instance == NULL))
191     return (NULL);
192
193   ident = ident_create (host, plugin, plugin_instance, type, type_instance);
194
195   gl_update ();
196
197   for (i = 0; i < gl_active_num; i++)
198   {
199     if (graph_compare (gl_active[i], ident) != 0)
200       continue;
201
202     ident_destroy (ident);
203     return (gl_active[i]);
204   }
205
206   ident_destroy (ident);
207   return (NULL);
208 } /* }}} graph_config_t *gl_graph_get_selected */
209
210 /* gl_instance_get_all, gl_graph_instance_get_all {{{ */
211 struct gl_inst_callback_data /* {{{ */
212 {
213   graph_config_t *cfg;
214   graph_inst_callback_t callback;
215   void *user_data;
216 }; /* }}} struct gl_inst_callback_data */
217
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;
222
223   return ((*data->callback) (data->cfg, inst, data->user_data));
224 } /* }}} int gl_inst_callback_handler */
225
226 int gl_graph_instance_get_all (graph_config_t *cfg, /* {{{ */
227     graph_inst_callback_t callback, void *user_data)
228 {
229   struct gl_inst_callback_data data =
230   {
231     cfg,
232     callback,
233     user_data
234   };
235
236   if ((cfg == NULL) || (callback == NULL))
237     return (EINVAL);
238
239   return (graph_inst_foreach (cfg, gl_inst_callback_handler, &data));
240 } /* }}} int gl_graph_instance_get_all */
241
242 int gl_instance_get_all (graph_inst_callback_t callback, /* {{{ */
243     void *user_data)
244 {
245   size_t i;
246
247   gl_update ();
248
249   for (i = 0; i < gl_active_num; i++)
250   {
251     int status;
252
253     status = gl_graph_instance_get_all (gl_active[i], callback, user_data);
254     if (status != 0)
255       return (status);
256   }
257
258   return (0);
259 } /* }}} int gl_instance_get_all */
260 /* }}} gl_instance_get_all, gl_graph_instance_get_all */
261
262 int gl_search (const char *term, graph_inst_callback_t callback, /* {{{ */
263     void *user_data)
264 {
265   size_t i;
266
267   for (i = 0; i < gl_active_num; i++)
268   {
269     int status;
270
271     status = graph_inst_search (gl_active[i], term,
272         /* callback  = */ callback,
273         /* user data = */ user_data);
274     if (status != 0)
275       return (status);
276   }
277
278   return (0);
279 } /* }}} int gl_search */
280
281 int gl_update (void) /* {{{ */
282 {
283   time_t now;
284   int status;
285
286   /*
287   printf ("Content-Type: text/plain\n\n");
288   */
289
290   now = time (NULL);
291
292   if ((gl_last_update + UPDATE_INTERVAL) >= now)
293     return (0);
294
295   graph_read_config ();
296
297   gl_clear_instances ();
298   status = fs_scan (/* callback = */ gl_register_file, /* user data = */ NULL);
299
300   gl_last_update = now;
301
302   return (status);
303 } /* }}} int gl_update */
304
305 /* vim: set sw=2 sts=2 et fdm=marker : */