action_list_graphs.c: Implement real simple HTML output.
[collection4.git] / graph_list.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <time.h>
5 #include <errno.h>
6
7 #include "graph_list.h"
8 #include "common.h"
9
10 #define UPDATE_INTERVAL 10
11
12 static graph_list_t *graph_list = NULL;
13 static size_t graph_list_length = 0;
14 static time_t gl_last_update = 0;
15
16 static void gl_clear_entry (graph_list_t *gl) /* {{{ */
17 {
18   if (gl == NULL)
19     return;
20
21   free (gl->host);
22   free (gl->plugin);
23   free (gl->plugin_instance);
24   free (gl->type);
25   free (gl->type_instance);
26
27   gl->host = NULL;
28   gl->plugin = NULL;
29   gl->plugin_instance = NULL;
30   gl->type = NULL;
31   gl->type_instance = NULL;
32 } /* }}} void gl_clear_entry */
33
34 static void gl_clear (void)
35 {
36   size_t i;
37
38   for (i = 0; i < graph_list_length; i++)
39     gl_clear_entry (graph_list + i);
40
41   free (graph_list);
42   graph_list = NULL;
43   graph_list_length = 0;
44   gl_last_update = 0;
45 } /* }}} void gl_clear */
46
47 static int gl_add_copy (graph_list_t *gl) /* {{{ */
48 {
49   graph_list_t *ptr;
50   int status;
51
52   if (gl == NULL)
53     return (EINVAL);
54
55   ptr = realloc (graph_list, sizeof (*graph_list) * (graph_list_length + 1));
56   if (ptr == NULL)
57     return (ENOMEM);
58   graph_list = ptr;
59
60   ptr = graph_list + graph_list_length;
61   memset (ptr, 0, sizeof (*ptr));
62   ptr->host = NULL;
63   ptr->plugin = NULL;
64   ptr->plugin_instance = NULL;
65   ptr->type = NULL;
66   ptr->type_instance = NULL;
67
68 #define DUP_OR_BREAK(member) do {                    \
69   ptr->member = NULL;                                \
70   if (gl->member != NULL)                            \
71   {                                                  \
72     ptr->member = strdup (gl->member);               \
73     if (ptr->member == NULL)                         \
74       break;                                         \
75   }                                                  \
76 } while (0)
77
78   status = ENOMEM;
79   do
80   {
81     DUP_OR_BREAK(host);
82     DUP_OR_BREAK(plugin);
83     DUP_OR_BREAK(plugin_instance);
84     DUP_OR_BREAK(type);
85     DUP_OR_BREAK(type_instance);
86
87     status = 0;
88   } while (0);
89
90 #undef DUP_OR_BREAK
91
92   if (status != 0)
93   {
94     free (ptr->host);
95     free (ptr->plugin);
96     free (ptr->plugin_instance);
97     free (ptr->type);
98     free (ptr->type_instance);
99     return (status);
100   }
101
102   graph_list_length++;
103   return (0);
104 } /* }}} int gl_add_copy */
105
106 static int callback_type (const char *type, void *user_data) /* {{{ */
107 {
108   graph_list_t *gl;
109   int status;
110
111   if ((type == NULL) || (user_data == NULL))
112     return (EINVAL);
113
114   gl = user_data;
115   if ((gl->type != NULL) || (gl->type_instance != NULL))
116     return (EINVAL);
117
118   gl->type = strdup (type);
119   if (gl->type == NULL)
120     return (ENOMEM);
121
122   gl->type_instance = strchr (gl->type, '-');
123   if (gl->type_instance != NULL)
124   {
125     *gl->type_instance = 0;
126     gl->type_instance++;
127   }
128
129   status = gl_add_copy (gl);
130
131   free (gl->type);
132   gl->type = NULL;
133   gl->type_instance = NULL;
134
135   return (status);
136 } /* }}} int callback_type */
137
138 static int callback_plugin (const char *plugin, void *user_data) /* {{{ */
139 {
140   graph_list_t *gl;
141   int status;
142
143   if ((plugin == NULL) || (user_data == NULL))
144     return (EINVAL);
145
146   gl = user_data;
147   if ((gl->plugin != NULL) || (gl->plugin_instance != NULL))
148     return (EINVAL);
149
150   gl->plugin = strdup (plugin);
151   if (gl->plugin == NULL)
152     return (ENOMEM);
153
154   gl->plugin_instance = strchr (gl->plugin, '-');
155   if (gl->plugin_instance != NULL)
156   {
157     *gl->plugin_instance = 0;
158     gl->plugin_instance++;
159   }
160
161   status = foreach_type (gl->host, plugin, callback_type, gl);
162
163   free (gl->plugin);
164   gl->plugin = NULL;
165   gl->plugin_instance = NULL;
166
167   return (status);
168 } /* }}} int callback_plugin */
169
170 static int callback_host (const char *host, void *user_data) /* {{{ */
171 {
172   graph_list_t *gl;
173   int status;
174
175   if ((host == NULL) || (user_data == NULL))
176     return (EINVAL);
177
178   gl = user_data;
179   if (gl->host != NULL)
180     return (EINVAL);
181
182   gl->host = strdup (host);
183   if (gl->host == NULL)
184     return (ENOMEM);
185
186   status =  foreach_plugin (host, callback_plugin, gl);
187
188   free (gl->host);
189   gl->host = NULL;
190
191   return (status);
192 } /* }}} int callback_host */
193
194 int gl_update (void) /* {{{ */
195 {
196   time_t now;
197   graph_list_t gl;
198   int status;
199
200   now = time (NULL);
201
202   if ((gl_last_update + UPDATE_INTERVAL) >= now)
203     return (0);
204
205   gl_clear ();
206
207   memset (&gl, 0, sizeof (gl));
208   gl.host = NULL;
209   gl.plugin = NULL;
210   gl.plugin_instance = NULL;
211   gl.type = NULL;
212   gl.type_instance = NULL;
213
214   /* TODO: Free old list */
215
216   status = foreach_host (callback_host, &gl);
217   return (status);
218 } /* }}} int gl_update */
219
220 int gl_foreach (gl_callback callback, void *user_data) /* {{{ */
221 {
222   size_t i;
223
224   for (i = 0; i < graph_list_length; i++)
225   {
226     int status;
227
228     status = (*callback) (graph_list + i, user_data);
229     if (status != 0)
230       return (status);
231   }
232
233   return (0);
234 } /* }}} int gl_foreach */
235
236 /* vim: set sw=2 sts=2 et fdm=marker : */