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