1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <strings.h>
6 #include <errno.h>
7 #include <limits.h> /* PATH_MAX */
8 #include <sys/types.h>
9 #include <sys/stat.h>
11 #include "graph_ident.h"
12 #include "common.h"
13 #include "filesystem.h"
15 #include <fcgiapp.h>
16 #include <fcgi_stdio.h>
18 /*
19 * Data types
20 */
21 struct graph_ident_s /* {{{ */
22 {
23 char *host;
24 char *plugin;
25 char *plugin_instance;
26 char *type;
27 char *type_instance;
28 }; /* }}} struct graph_ident_s */
30 /*
31 * Private functions
32 */
33 static char *part_copy_with_selector (const char *selector, /* {{{ */
34 const char *part, unsigned int flags)
35 {
36 if ((selector == NULL) || (part == NULL))
37 return (NULL);
39 if ((flags & IDENT_FLAG_REPLACE_ANY) && IS_ANY (part))
40 return (NULL);
42 if ((flags & IDENT_FLAG_REPLACE_ALL) && IS_ALL (part))
43 return (NULL);
45 /* Replace the ANY and ALL flags if requested and if the selecter actually
46 * *is* that flag. */
47 if (IS_ANY (selector))
48 {
49 if (flags & IDENT_FLAG_REPLACE_ANY)
50 return (strdup (part));
51 else
52 return (strdup (selector));
53 }
55 if (IS_ALL (selector))
56 {
57 if (flags & IDENT_FLAG_REPLACE_ALL)
58 return (strdup (part));
59 else
60 return (strdup (selector));
61 }
63 if (strcmp (selector, part) != 0)
64 return (NULL);
66 /* Otherwise (no replacement), return a copy of the selector. */
67 return (strdup (selector));
68 } /* }}} char *part_copy_with_selector */
70 static _Bool part_matches (const char *selector, /* {{{ */
71 const char *part)
72 {
73 if ((selector == NULL) && (part == NULL))
74 return (1);
76 if (selector == NULL) /* && (part != NULL) */
77 return (0);
79 if (IS_ANY(selector) || IS_ALL(selector))
80 return (1);
82 if (part == NULL) /* && (selector != NULL) */
83 return (0);
85 if (strcmp (selector, part) == 0)
86 return (1);
88 return (0);
89 } /* }}} _Bool part_matches */
91 /*
92 * Public functions
93 */
94 graph_ident_t *ident_create (const char *host, /* {{{ */
95 const char *plugin, const char *plugin_instance,
96 const char *type, const char *type_instance)
97 {
98 graph_ident_t *ret;
100 if ((host == NULL)
101 || (plugin == NULL) || (plugin_instance == NULL)
102 || (type == NULL) || (type_instance == NULL))
103 return (NULL);
105 ret = malloc (sizeof (*ret));
106 if (ret == NULL)
107 return (NULL);
108 memset (ret, 0, sizeof (*ret));
110 ret->host = NULL;
111 ret->host = NULL;
112 ret->plugin = NULL;
113 ret->plugin_instance = NULL;
114 ret->type = NULL;
115 ret->type_instance = NULL;
117 #define COPY_PART(p) do { \
118 ret->p = strdup (p); \
119 if (ret->p == NULL) \
120 { \
121 free (ret->host); \
122 free (ret->plugin); \
123 free (ret->plugin_instance); \
124 free (ret->type); \
125 free (ret->type_instance); \
126 free (ret); \
127 return (NULL); \
128 } \
129 } while (0)
131 COPY_PART(host);
132 COPY_PART(plugin);
133 COPY_PART(plugin_instance);
134 COPY_PART(type);
135 COPY_PART(type_instance);
137 #undef COPY_PART
139 return (ret);
140 } /* }}} graph_ident_t *ident_create */
142 graph_ident_t *ident_clone (const graph_ident_t *ident) /* {{{ */
143 {
144 return (ident_create (ident->host,
145 ident->plugin, ident->plugin_instance,
146 ident->type, ident->type_instance));
147 } /* }}} graph_ident_t *ident_clone */
149 graph_ident_t *ident_copy_with_selector (const graph_ident_t *selector, /* {{{ */
150 const graph_ident_t *ident, unsigned int flags)
151 {
152 graph_ident_t *ret;
154 if ((selector == NULL) || (ident == NULL))
155 return (NULL);
157 ret = malloc (sizeof (*ret));
158 if (ret == NULL)
159 return (NULL);
160 memset (ret, 0, sizeof (*ret));
161 ret->host = NULL;
162 ret->plugin = NULL;
163 ret->plugin_instance = NULL;
164 ret->type = NULL;
165 ret->type_instance = NULL;
167 #define COPY_PART(p) do { \
168 ret->p = part_copy_with_selector (selector->p, ident->p, flags); \
169 if (ret->p == NULL) \
170 { \
171 free (ret->host); \
172 free (ret->plugin); \
173 free (ret->plugin_instance); \
174 free (ret->type); \
175 free (ret->type_instance); \
176 return (NULL); \
177 } \
178 } while (0)
180 COPY_PART (host);
181 COPY_PART (plugin);
182 COPY_PART (plugin_instance);
183 COPY_PART (type);
184 COPY_PART (type_instance);
186 #undef COPY_PART
188 return (ret);
189 } /* }}} graph_ident_t *ident_copy_with_selector */
191 void ident_destroy (graph_ident_t *ident) /* {{{ */
192 {
193 if (ident == NULL)
194 return;
196 free (ident->host);
197 free (ident->plugin);
198 free (ident->plugin_instance);
199 free (ident->type);
200 free (ident->type_instance);
202 free (ident);
203 } /* }}} void ident_destroy */
205 /* ident_get_* methods {{{ */
206 const char *ident_get_host (const graph_ident_t *ident) /* {{{ */
207 {
208 if (ident == NULL)
209 return (NULL);
211 return (ident->host);
212 } /* }}} char *ident_get_host */
214 const char *ident_get_plugin (const graph_ident_t *ident) /* {{{ */
215 {
216 if (ident == NULL)
217 return (NULL);
219 return (ident->plugin);
220 } /* }}} char *ident_get_plugin */
222 const char *ident_get_plugin_instance (const graph_ident_t *ident) /* {{{ */
223 {
224 if (ident == NULL)
225 return (NULL);
227 return (ident->plugin_instance);
228 } /* }}} char *ident_get_plugin_instance */
230 const char *ident_get_type (const graph_ident_t *ident) /* {{{ */
231 {
232 if (ident == NULL)
233 return (NULL);
235 return (ident->type);
236 } /* }}} char *ident_get_type */
238 const char *ident_get_type_instance (const graph_ident_t *ident) /* {{{ */
239 {
240 if (ident == NULL)
241 return (NULL);
243 return (ident->type_instance);
244 } /* }}} char *ident_get_type_instance */
246 const char *ident_get_field (const graph_ident_t *ident, /* {{{ */
247 graph_ident_field_t field)
248 {
249 if ((ident == NULL) || (field >= _GIF_LAST))
250 return (NULL);
252 if (field == GIF_HOST)
253 return (ident->host);
254 else if (field == GIF_PLUGIN)
255 return (ident->plugin);
256 else if (field == GIF_PLUGIN_INSTANCE)
257 return (ident->plugin_instance);
258 else if (field == GIF_TYPE)
259 return (ident->type);
260 else if (field == GIF_TYPE_INSTANCE)
261 return (ident->type_instance);
262 else
263 return (NULL); /* never reached */
264 } /* }}} const char *ident_get_field */
265 /* }}} ident_get_* methods */
267 /* ident_set_* methods {{{ */
268 int ident_set_host (graph_ident_t *ident, const char *host) /* {{{ */
269 {
270 char *tmp;
272 if ((ident == NULL) || (host == NULL))
273 return (EINVAL);
275 tmp = strdup (host);
276 if (tmp == NULL)
277 return (ENOMEM);
279 free (ident->host);
280 ident->host = tmp;
282 return (0);
283 } /* }}} int ident_set_host */
285 int ident_set_plugin (graph_ident_t *ident, const char *plugin) /* {{{ */
286 {
287 char *tmp;
289 if ((ident == NULL) || (plugin == NULL))
290 return (EINVAL);
292 tmp = strdup (plugin);
293 if (tmp == NULL)
294 return (ENOMEM);
296 free (ident->plugin);
297 ident->plugin = tmp;
299 return (0);
300 } /* }}} int ident_set_plugin */
302 int ident_set_plugin_instance (graph_ident_t *ident, const char *plugin_instance) /* {{{ */
303 {
304 char *tmp;
306 if ((ident == NULL) || (plugin_instance == NULL))
307 return (EINVAL);
309 tmp = strdup (plugin_instance);
310 if (tmp == NULL)
311 return (ENOMEM);
313 free (ident->plugin_instance);
314 ident->plugin_instance = tmp;
316 return (0);
317 } /* }}} int ident_set_plugin_instance */
319 int ident_set_type (graph_ident_t *ident, const char *type) /* {{{ */
320 {
321 char *tmp;
323 if ((ident == NULL) || (type == NULL))
324 return (EINVAL);
326 tmp = strdup (type);
327 if (tmp == NULL)
328 return (ENOMEM);
330 free (ident->type);
331 ident->type = tmp;
333 return (0);
334 } /* }}} int ident_set_type */
336 int ident_set_type_instance (graph_ident_t *ident, const char *type_instance) /* {{{ */
337 {
338 char *tmp;
340 if ((ident == NULL) || (type_instance == NULL))
341 return (EINVAL);
343 tmp = strdup (type_instance);
344 if (tmp == NULL)
345 return (ENOMEM);
347 free (ident->type_instance);
348 ident->type_instance = tmp;
350 return (0);
351 } /* }}} int ident_set_type_instance */
353 /* }}} ident_set_* methods */
355 int ident_compare (const graph_ident_t *i0, /* {{{ */
356 const graph_ident_t *i1)
357 {
358 int status;
360 #define COMPARE_PART(p) do { \
361 status = strcmp (i0->p, i1->p); \
362 if (status != 0) \
363 return (status); \
364 } while (0)
366 COMPARE_PART (host);
367 COMPARE_PART (plugin);
368 COMPARE_PART (plugin_instance);
369 COMPARE_PART (type);
370 COMPARE_PART (type_instance);
372 #undef COMPARE_PART
374 return (0);
375 } /* }}} int ident_compare */
377 _Bool ident_matches (const graph_ident_t *selector, /* {{{ */
378 const graph_ident_t *ident)
379 {
380 if ((selector == NULL) && (ident == NULL))
381 return (0);
382 else if (selector == NULL)
383 return (-1);
384 else if (ident == NULL)
385 return (1);
387 if (!part_matches (selector->host, ident->host))
388 return (0);
390 if (!part_matches (selector->plugin, ident->plugin))
391 return (0);
393 if (!part_matches (selector->plugin_instance, ident->plugin_instance))
394 return (0);
396 if (!part_matches (selector->type, ident->type))
397 return (0);
399 if (!part_matches (selector->type_instance, ident->type_instance))
400 return (0);
402 return (1);
403 } /* }}} _Bool ident_matches */
405 char *ident_to_string (const graph_ident_t *ident) /* {{{ */
406 {
407 char buffer[PATH_MAX];
409 buffer[0] = 0;
411 strlcat (buffer, ident->host, sizeof (buffer));
412 strlcat (buffer, "/", sizeof (buffer));
413 strlcat (buffer, ident->plugin, sizeof (buffer));
414 if (ident->plugin_instance[0] != 0)
415 {
416 strlcat (buffer, "-", sizeof (buffer));
417 strlcat (buffer, ident->plugin_instance, sizeof (buffer));
418 }
419 strlcat (buffer, "/", sizeof (buffer));
420 strlcat (buffer, ident->type, sizeof (buffer));
421 if (ident->type_instance[0] != 0)
422 {
423 strlcat (buffer, "-", sizeof (buffer));
424 strlcat (buffer, ident->type_instance, sizeof (buffer));
425 }
427 return (strdup (buffer));
428 } /* }}} char *ident_to_string */
430 char *ident_to_file (const graph_ident_t *ident) /* {{{ */
431 {
432 char buffer[PATH_MAX];
434 buffer[0] = 0;
436 strlcat (buffer, DATA_DIR, sizeof (buffer));
437 strlcat (buffer, "/", sizeof (buffer));
439 strlcat (buffer, ident->host, sizeof (buffer));
440 strlcat (buffer, "/", sizeof (buffer));
441 strlcat (buffer, ident->plugin, sizeof (buffer));
442 if (ident->plugin_instance[0] != 0)
443 {
444 strlcat (buffer, "-", sizeof (buffer));
445 strlcat (buffer, ident->plugin_instance, sizeof (buffer));
446 }
447 strlcat (buffer, "/", sizeof (buffer));
448 strlcat (buffer, ident->type, sizeof (buffer));
449 if (ident->type_instance[0] != 0)
450 {
451 strlcat (buffer, "-", sizeof (buffer));
452 strlcat (buffer, ident->type_instance, sizeof (buffer));
453 }
455 strlcat (buffer, ".rrd", sizeof (buffer));
457 return (strdup (buffer));
458 } /* }}} char *ident_to_file */
460 char *ident_to_json (const graph_ident_t *ident) /* {{{ */
461 {
462 char buffer[4096];
464 buffer[0] = 0;
466 strlcat (buffer, "{\"host\":\"", sizeof (buffer));
467 strlcat (buffer, ident->host, sizeof (buffer));
468 strlcat (buffer, "\",\"plugin\":\"", sizeof (buffer));
469 strlcat (buffer, ident->plugin, sizeof (buffer));
470 strlcat (buffer, "\",\"plugin_instance\":\"", sizeof (buffer));
471 strlcat (buffer, ident->plugin_instance, sizeof (buffer));
472 strlcat (buffer, "\",\"type\":\"", sizeof (buffer));
473 strlcat (buffer, ident->type, sizeof (buffer));
474 strlcat (buffer, "\",\"type_instance\":\"", sizeof (buffer));
475 strlcat (buffer, ident->type_instance, sizeof (buffer));
476 strlcat (buffer, "\"}", sizeof (buffer));
478 return (strdup (buffer));
479 } /* }}} char *ident_to_json */
481 time_t ident_get_mtime (const graph_ident_t *ident) /* {{{ */
482 {
483 char *file;
484 struct stat statbuf;
485 int status;
487 if (ident == NULL)
488 return (0);
490 file = ident_to_file (ident);
491 if (file == NULL)
492 return (0);
494 memset (&statbuf, 0, sizeof (statbuf));
495 status = stat (file, &statbuf);
496 if (status != 0)
497 {
498 fprintf (stderr, "ident_get_mtime: stat'ing file \"%s\" failed: %s\n",
499 file, strerror (errno));
500 return (0);
501 }
503 free (file);
504 return (statbuf.st_mtime);
505 } /* }}} time_t ident_get_mtime */
507 /* vim: set sw=2 sts=2 et fdm=marker : */