1 /**
2 * collection4 - graph_ident.c
3 * Copyright (C) 2010 Florian octo Forster
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
19 *
20 * Authors:
21 * Florian octo Forster <ff at octo.it>
22 **/
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <strings.h>
29 #include <errno.h>
30 #include <limits.h> /* PATH_MAX */
31 #include <sys/types.h>
32 #include <sys/stat.h>
34 #include "graph_ident.h"
35 #include "common.h"
36 #include "filesystem.h"
38 #include <fcgiapp.h>
39 #include <fcgi_stdio.h>
41 /*
42 * Data types
43 */
44 struct graph_ident_s /* {{{ */
45 {
46 char *host;
47 char *plugin;
48 char *plugin_instance;
49 char *type;
50 char *type_instance;
51 }; /* }}} struct graph_ident_s */
53 /*
54 * Private functions
55 */
56 static char *part_copy_with_selector (const char *selector, /* {{{ */
57 const char *part, unsigned int flags)
58 {
59 if ((selector == NULL) || (part == NULL))
60 return (NULL);
62 if ((flags & IDENT_FLAG_REPLACE_ANY) && IS_ANY (part))
63 return (NULL);
65 if ((flags & IDENT_FLAG_REPLACE_ALL) && IS_ALL (part))
66 return (NULL);
68 /* Replace the ANY and ALL flags if requested and if the selecter actually
69 * *is* that flag. */
70 if (IS_ANY (selector))
71 {
72 if (flags & IDENT_FLAG_REPLACE_ANY)
73 return (strdup (part));
74 else
75 return (strdup (selector));
76 }
78 if (IS_ALL (selector))
79 {
80 if (flags & IDENT_FLAG_REPLACE_ALL)
81 return (strdup (part));
82 else
83 return (strdup (selector));
84 }
86 if (strcmp (selector, part) != 0)
87 return (NULL);
89 /* Otherwise (no replacement), return a copy of the selector. */
90 return (strdup (selector));
91 } /* }}} char *part_copy_with_selector */
93 static _Bool part_matches (const char *selector, /* {{{ */
94 const char *part)
95 {
96 if ((selector == NULL) && (part == NULL))
97 return (1);
99 if (selector == NULL) /* && (part != NULL) */
100 return (0);
102 if (IS_ANY(selector) || IS_ALL(selector))
103 return (1);
105 if (part == NULL) /* && (selector != NULL) */
106 return (0);
108 if (strcmp (selector, part) == 0)
109 return (1);
111 return (0);
112 } /* }}} _Bool part_matches */
114 /*
115 * Public functions
116 */
117 graph_ident_t *ident_create (const char *host, /* {{{ */
118 const char *plugin, const char *plugin_instance,
119 const char *type, const char *type_instance)
120 {
121 graph_ident_t *ret;
123 if ((host == NULL)
124 || (plugin == NULL) || (plugin_instance == NULL)
125 || (type == NULL) || (type_instance == NULL))
126 return (NULL);
128 ret = malloc (sizeof (*ret));
129 if (ret == NULL)
130 return (NULL);
131 memset (ret, 0, sizeof (*ret));
133 ret->host = NULL;
134 ret->host = NULL;
135 ret->plugin = NULL;
136 ret->plugin_instance = NULL;
137 ret->type = NULL;
138 ret->type_instance = NULL;
140 #define COPY_PART(p) do { \
141 ret->p = strdup (p); \
142 if (ret->p == NULL) \
143 { \
144 free (ret->host); \
145 free (ret->plugin); \
146 free (ret->plugin_instance); \
147 free (ret->type); \
148 free (ret->type_instance); \
149 free (ret); \
150 return (NULL); \
151 } \
152 } while (0)
154 COPY_PART(host);
155 COPY_PART(plugin);
156 COPY_PART(plugin_instance);
157 COPY_PART(type);
158 COPY_PART(type_instance);
160 #undef COPY_PART
162 return (ret);
163 } /* }}} graph_ident_t *ident_create */
165 graph_ident_t *ident_clone (const graph_ident_t *ident) /* {{{ */
166 {
167 return (ident_create (ident->host,
168 ident->plugin, ident->plugin_instance,
169 ident->type, ident->type_instance));
170 } /* }}} graph_ident_t *ident_clone */
172 graph_ident_t *ident_copy_with_selector (const graph_ident_t *selector, /* {{{ */
173 const graph_ident_t *ident, unsigned int flags)
174 {
175 graph_ident_t *ret;
177 if ((selector == NULL) || (ident == NULL))
178 return (NULL);
180 ret = malloc (sizeof (*ret));
181 if (ret == NULL)
182 return (NULL);
183 memset (ret, 0, sizeof (*ret));
184 ret->host = NULL;
185 ret->plugin = NULL;
186 ret->plugin_instance = NULL;
187 ret->type = NULL;
188 ret->type_instance = NULL;
190 #define COPY_PART(p) do { \
191 ret->p = part_copy_with_selector (selector->p, ident->p, flags); \
192 if (ret->p == NULL) \
193 { \
194 free (ret->host); \
195 free (ret->plugin); \
196 free (ret->plugin_instance); \
197 free (ret->type); \
198 free (ret->type_instance); \
199 return (NULL); \
200 } \
201 } while (0)
203 COPY_PART (host);
204 COPY_PART (plugin);
205 COPY_PART (plugin_instance);
206 COPY_PART (type);
207 COPY_PART (type_instance);
209 #undef COPY_PART
211 return (ret);
212 } /* }}} graph_ident_t *ident_copy_with_selector */
214 void ident_destroy (graph_ident_t *ident) /* {{{ */
215 {
216 if (ident == NULL)
217 return;
219 free (ident->host);
220 free (ident->plugin);
221 free (ident->plugin_instance);
222 free (ident->type);
223 free (ident->type_instance);
225 free (ident);
226 } /* }}} void ident_destroy */
228 /* ident_get_* methods {{{ */
229 const char *ident_get_host (const graph_ident_t *ident) /* {{{ */
230 {
231 if (ident == NULL)
232 return (NULL);
234 return (ident->host);
235 } /* }}} char *ident_get_host */
237 const char *ident_get_plugin (const graph_ident_t *ident) /* {{{ */
238 {
239 if (ident == NULL)
240 return (NULL);
242 return (ident->plugin);
243 } /* }}} char *ident_get_plugin */
245 const char *ident_get_plugin_instance (const graph_ident_t *ident) /* {{{ */
246 {
247 if (ident == NULL)
248 return (NULL);
250 return (ident->plugin_instance);
251 } /* }}} char *ident_get_plugin_instance */
253 const char *ident_get_type (const graph_ident_t *ident) /* {{{ */
254 {
255 if (ident == NULL)
256 return (NULL);
258 return (ident->type);
259 } /* }}} char *ident_get_type */
261 const char *ident_get_type_instance (const graph_ident_t *ident) /* {{{ */
262 {
263 if (ident == NULL)
264 return (NULL);
266 return (ident->type_instance);
267 } /* }}} char *ident_get_type_instance */
269 const char *ident_get_field (const graph_ident_t *ident, /* {{{ */
270 graph_ident_field_t field)
271 {
272 if ((ident == NULL) || (field >= _GIF_LAST))
273 return (NULL);
275 if (field == GIF_HOST)
276 return (ident->host);
277 else if (field == GIF_PLUGIN)
278 return (ident->plugin);
279 else if (field == GIF_PLUGIN_INSTANCE)
280 return (ident->plugin_instance);
281 else if (field == GIF_TYPE)
282 return (ident->type);
283 else if (field == GIF_TYPE_INSTANCE)
284 return (ident->type_instance);
285 else
286 return (NULL); /* never reached */
287 } /* }}} const char *ident_get_field */
288 /* }}} ident_get_* methods */
290 /* ident_set_* methods {{{ */
291 int ident_set_host (graph_ident_t *ident, const char *host) /* {{{ */
292 {
293 char *tmp;
295 if ((ident == NULL) || (host == NULL))
296 return (EINVAL);
298 tmp = strdup (host);
299 if (tmp == NULL)
300 return (ENOMEM);
302 free (ident->host);
303 ident->host = tmp;
305 return (0);
306 } /* }}} int ident_set_host */
308 int ident_set_plugin (graph_ident_t *ident, const char *plugin) /* {{{ */
309 {
310 char *tmp;
312 if ((ident == NULL) || (plugin == NULL))
313 return (EINVAL);
315 tmp = strdup (plugin);
316 if (tmp == NULL)
317 return (ENOMEM);
319 free (ident->plugin);
320 ident->plugin = tmp;
322 return (0);
323 } /* }}} int ident_set_plugin */
325 int ident_set_plugin_instance (graph_ident_t *ident, const char *plugin_instance) /* {{{ */
326 {
327 char *tmp;
329 if ((ident == NULL) || (plugin_instance == NULL))
330 return (EINVAL);
332 tmp = strdup (plugin_instance);
333 if (tmp == NULL)
334 return (ENOMEM);
336 free (ident->plugin_instance);
337 ident->plugin_instance = tmp;
339 return (0);
340 } /* }}} int ident_set_plugin_instance */
342 int ident_set_type (graph_ident_t *ident, const char *type) /* {{{ */
343 {
344 char *tmp;
346 if ((ident == NULL) || (type == NULL))
347 return (EINVAL);
349 tmp = strdup (type);
350 if (tmp == NULL)
351 return (ENOMEM);
353 free (ident->type);
354 ident->type = tmp;
356 return (0);
357 } /* }}} int ident_set_type */
359 int ident_set_type_instance (graph_ident_t *ident, const char *type_instance) /* {{{ */
360 {
361 char *tmp;
363 if ((ident == NULL) || (type_instance == NULL))
364 return (EINVAL);
366 tmp = strdup (type_instance);
367 if (tmp == NULL)
368 return (ENOMEM);
370 free (ident->type_instance);
371 ident->type_instance = tmp;
373 return (0);
374 } /* }}} int ident_set_type_instance */
376 /* }}} ident_set_* methods */
378 int ident_compare (const graph_ident_t *i0, /* {{{ */
379 const graph_ident_t *i1)
380 {
381 int status;
383 #define COMPARE_PART(p) do { \
384 status = strcmp (i0->p, i1->p); \
385 if (status != 0) \
386 return (status); \
387 } while (0)
389 COMPARE_PART (host);
390 COMPARE_PART (plugin);
391 COMPARE_PART (plugin_instance);
392 COMPARE_PART (type);
393 COMPARE_PART (type_instance);
395 #undef COMPARE_PART
397 return (0);
398 } /* }}} int ident_compare */
400 _Bool ident_matches (const graph_ident_t *selector, /* {{{ */
401 const graph_ident_t *ident)
402 {
403 if ((selector == NULL) || (ident == NULL))
404 return (0);
406 if (!part_matches (selector->host, ident->host))
407 return (0);
409 if (!part_matches (selector->plugin, ident->plugin))
410 return (0);
412 if (!part_matches (selector->plugin_instance, ident->plugin_instance))
413 return (0);
415 if (!part_matches (selector->type, ident->type))
416 return (0);
418 if (!part_matches (selector->type_instance, ident->type_instance))
419 return (0);
421 return (1);
422 } /* }}} _Bool ident_matches */
424 char *ident_to_string (const graph_ident_t *ident) /* {{{ */
425 {
426 char buffer[PATH_MAX];
428 buffer[0] = 0;
430 strlcat (buffer, ident->host, sizeof (buffer));
431 strlcat (buffer, "/", sizeof (buffer));
432 strlcat (buffer, ident->plugin, sizeof (buffer));
433 if (ident->plugin_instance[0] != 0)
434 {
435 strlcat (buffer, "-", sizeof (buffer));
436 strlcat (buffer, ident->plugin_instance, sizeof (buffer));
437 }
438 strlcat (buffer, "/", sizeof (buffer));
439 strlcat (buffer, ident->type, sizeof (buffer));
440 if (ident->type_instance[0] != 0)
441 {
442 strlcat (buffer, "-", sizeof (buffer));
443 strlcat (buffer, ident->type_instance, sizeof (buffer));
444 }
446 return (strdup (buffer));
447 } /* }}} char *ident_to_string */
449 char *ident_to_file (const graph_ident_t *ident) /* {{{ */
450 {
451 char buffer[PATH_MAX];
453 buffer[0] = 0;
455 strlcat (buffer, DATA_DIR, sizeof (buffer));
456 strlcat (buffer, "/", sizeof (buffer));
458 strlcat (buffer, ident->host, sizeof (buffer));
459 strlcat (buffer, "/", sizeof (buffer));
460 strlcat (buffer, ident->plugin, sizeof (buffer));
461 if (ident->plugin_instance[0] != 0)
462 {
463 strlcat (buffer, "-", sizeof (buffer));
464 strlcat (buffer, ident->plugin_instance, sizeof (buffer));
465 }
466 strlcat (buffer, "/", sizeof (buffer));
467 strlcat (buffer, ident->type, sizeof (buffer));
468 if (ident->type_instance[0] != 0)
469 {
470 strlcat (buffer, "-", sizeof (buffer));
471 strlcat (buffer, ident->type_instance, sizeof (buffer));
472 }
474 strlcat (buffer, ".rrd", sizeof (buffer));
476 return (strdup (buffer));
477 } /* }}} char *ident_to_file */
479 char *ident_to_json (const graph_ident_t *ident) /* {{{ */
480 {
481 char buffer[4096];
483 buffer[0] = 0;
485 strlcat (buffer, "{\"host\":\"", sizeof (buffer));
486 strlcat (buffer, ident->host, sizeof (buffer));
487 strlcat (buffer, "\",\"plugin\":\"", sizeof (buffer));
488 strlcat (buffer, ident->plugin, sizeof (buffer));
489 strlcat (buffer, "\",\"plugin_instance\":\"", sizeof (buffer));
490 strlcat (buffer, ident->plugin_instance, sizeof (buffer));
491 strlcat (buffer, "\",\"type\":\"", sizeof (buffer));
492 strlcat (buffer, ident->type, sizeof (buffer));
493 strlcat (buffer, "\",\"type_instance\":\"", sizeof (buffer));
494 strlcat (buffer, ident->type_instance, sizeof (buffer));
495 strlcat (buffer, "\"}", sizeof (buffer));
497 return (strdup (buffer));
498 } /* }}} char *ident_to_json */
500 time_t ident_get_mtime (const graph_ident_t *ident) /* {{{ */
501 {
502 char *file;
503 struct stat statbuf;
504 int status;
506 if (ident == NULL)
507 return (0);
509 file = ident_to_file (ident);
510 if (file == NULL)
511 return (0);
513 memset (&statbuf, 0, sizeof (statbuf));
514 status = stat (file, &statbuf);
515 if (status != 0)
516 {
517 fprintf (stderr, "ident_get_mtime: stat'ing file \"%s\" failed: %s\n",
518 file, strerror (errno));
519 return (0);
520 }
522 free (file);
523 return (statbuf.st_mtime);
524 } /* }}} time_t ident_get_mtime */
526 /* vim: set sw=2 sts=2 et fdm=marker : */