graph_def.c: Implement the "Stack" and "Area" options.
[collection4.git] / graph_ident.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <strings.h>
4 #include <errno.h>
5 #include <limits.h> /* PATH_MAX */
6
7 #include "graph_ident.h"
8 #include "common.h"
9
10 #define IS_ANY(str) (((str) != NULL) && (strcasecmp (ANY_TOKEN, (str)) == 0))
11 #define IS_ALL(str) (((str) != NULL) && (strcasecmp (ALL_TOKEN, (str)) == 0))
12
13 /*
14  * Data types
15  */
16 struct graph_ident_s /* {{{ */
17 {
18   char *host;
19   char *plugin;
20   char *plugin_instance;
21   char *type;
22   char *type_instance;
23 }; /* }}} struct graph_ident_s */
24
25 /*
26  * Private functions
27  */
28 static char *part_copy_with_selector (const char *selector, /* {{{ */
29     const char *part, unsigned int flags)
30 {
31   if ((selector == NULL) || (part == NULL))
32     return (NULL);
33
34   if ((flags & IDENT_FLAG_REPLACE_ANY) && IS_ANY (part))
35     return (NULL);
36
37   if ((flags & IDENT_FLAG_REPLACE_ALL) && IS_ALL (part))
38     return (NULL);
39
40   /* Replace the ANY and ALL flags if requested and if the selecter actually
41    * *is* that flag. */
42   if (IS_ANY (selector))
43   {
44     if (flags & IDENT_FLAG_REPLACE_ANY)
45       return (strdup (part));
46     else
47       return (strdup (selector));
48   }
49
50   if (IS_ALL (selector))
51   {
52     if (flags & IDENT_FLAG_REPLACE_ALL)
53       return (strdup (part));
54     else
55       return (strdup (selector));
56   }
57
58   if (strcmp (selector, part) != 0)
59     return (NULL);
60
61   /* Otherwise (no replacement), return a copy of the selector. */
62   return (strdup (selector));
63 } /* }}} char *part_copy_with_selector */
64
65 static _Bool part_matches (const char *selector, /* {{{ */
66     const char *part)
67 {
68   if ((selector == NULL) && (part == NULL))
69     return (1);
70
71   if (selector == NULL) /* && (part != NULL) */
72     return (0);
73
74   if (IS_ANY(selector) || IS_ALL(selector))
75     return (1);
76
77   if (part == NULL) /* && (selector != NULL) */
78     return (0);
79
80   if (strcmp (selector, part) == 0)
81     return (1);
82
83   return (0);
84 } /* }}} _Bool part_matches */
85
86 /*
87  * Public functions
88  */
89 graph_ident_t *ident_create (const char *host, /* {{{ */
90     const char *plugin, const char *plugin_instance,
91     const char *type, const char *type_instance)
92 {
93   graph_ident_t *ret;
94
95   if ((host == NULL)
96       || (plugin == NULL) || (plugin_instance == NULL)
97       || (type == NULL) || (type_instance == NULL))
98     return (NULL);
99
100   ret = malloc (sizeof (*ret));
101   if (ret == NULL)
102     return (NULL);
103   memset (ret, 0, sizeof (*ret));
104
105   ret->host = NULL;
106   ret->host = NULL;
107   ret->plugin = NULL;
108   ret->plugin_instance = NULL;
109   ret->type = NULL;
110   ret->type_instance = NULL;
111
112 #define COPY_PART(p) do {        \
113   ret->p = strdup (p);           \
114   if (ret->p == NULL)            \
115   {                              \
116     free (ret->host);            \
117     free (ret->plugin);          \
118     free (ret->plugin_instance); \
119     free (ret->type);            \
120     free (ret->type_instance);   \
121     free (ret);                  \
122     return (NULL);               \
123   }                              \
124 } while (0)
125
126   COPY_PART(host);
127   COPY_PART(plugin);
128   COPY_PART(plugin_instance);
129   COPY_PART(type);
130   COPY_PART(type_instance);
131
132 #undef COPY_PART
133
134   return (ret);
135 } /* }}} graph_ident_t *ident_create */
136
137 graph_ident_t *ident_clone (const graph_ident_t *ident) /* {{{ */
138 {
139   return (ident_create (ident->host,
140         ident->plugin, ident->plugin_instance,
141         ident->type, ident->type_instance));
142 } /* }}} graph_ident_t *ident_clone */
143
144 graph_ident_t *ident_copy_with_selector (const graph_ident_t *selector, /* {{{ */
145     const graph_ident_t *ident, unsigned int flags)
146 {
147   graph_ident_t *ret;
148
149   if ((selector == NULL) || (ident == NULL))
150     return (NULL);
151
152   ret = malloc (sizeof (*ret));
153   if (ret == NULL)
154     return (NULL);
155   memset (ret, 0, sizeof (*ret));
156   ret->host = NULL;
157   ret->plugin = NULL;
158   ret->plugin_instance = NULL;
159   ret->type = NULL;
160   ret->type_instance = NULL;
161
162 #define COPY_PART(p) do {                                  \
163   ret->p = part_copy_with_selector (selector->p, ident->p, flags); \
164   if (ret->p == NULL)                                      \
165   {                                                        \
166     free (ret->host);                                      \
167     free (ret->plugin);                                    \
168     free (ret->plugin_instance);                           \
169     free (ret->type);                                      \
170     free (ret->type_instance);                             \
171     return (NULL);                                         \
172   }                                                        \
173 } while (0)
174
175   COPY_PART (host);
176   COPY_PART (plugin);
177   COPY_PART (plugin_instance);
178   COPY_PART (type);
179   COPY_PART (type_instance);
180
181 #undef COPY_PART
182
183   return (ret);
184 } /* }}} graph_ident_t *ident_copy_with_selector */
185
186 void ident_destroy (graph_ident_t *ident) /* {{{ */
187 {
188   if (ident == NULL)
189     return;
190
191   free (ident->host);
192   free (ident->plugin);
193   free (ident->plugin_instance);
194   free (ident->type);
195   free (ident->type_instance);
196
197   free (ident);
198 } /* }}} void ident_destroy */
199
200 /* ident_get_* methods {{{ */
201 const char *ident_get_host (graph_ident_t *ident) /* {{{ */
202 {
203   if (ident == NULL)
204     return (NULL);
205
206   return (ident->host);
207 } /* }}} char *ident_get_host */
208
209 const char *ident_get_plugin (graph_ident_t *ident) /* {{{ */
210 {
211   if (ident == NULL)
212     return (NULL);
213
214   return (ident->plugin);
215 } /* }}} char *ident_get_plugin */
216
217 const char *ident_get_plugin_instance (graph_ident_t *ident) /* {{{ */
218 {
219   if (ident == NULL)
220     return (NULL);
221
222   return (ident->plugin_instance);
223 } /* }}} char *ident_get_plugin_instance */
224
225 const char *ident_get_type (graph_ident_t *ident) /* {{{ */
226 {
227   if (ident == NULL)
228     return (NULL);
229
230   return (ident->type);
231 } /* }}} char *ident_get_type */
232
233 const char *ident_get_type_instance (graph_ident_t *ident) /* {{{ */
234 {
235   if (ident == NULL)
236     return (NULL);
237
238   return (ident->type_instance);
239 } /* }}} char *ident_get_type_instance */
240 /* }}} ident_get_* methods */
241
242 /* ident_set_* methods {{{ */
243 int ident_set_host (graph_ident_t *ident, const char *host) /* {{{ */
244 {
245   char *tmp;
246
247   if ((ident == NULL) || (host == NULL))
248     return (EINVAL);
249
250   tmp = strdup (host);
251   if (tmp == NULL)
252     return (ENOMEM);
253
254   free (ident->host);
255   ident->host = tmp;
256
257   return (0);
258 } /* }}} int ident_set_host */
259
260 int ident_set_plugin (graph_ident_t *ident, const char *plugin) /* {{{ */
261 {
262   char *tmp;
263
264   if ((ident == NULL) || (plugin == NULL))
265     return (EINVAL);
266
267   tmp = strdup (plugin);
268   if (tmp == NULL)
269     return (ENOMEM);
270
271   free (ident->plugin);
272   ident->plugin = tmp;
273
274   return (0);
275 } /* }}} int ident_set_plugin */
276
277 int ident_set_plugin_instance (graph_ident_t *ident, const char *plugin_instance) /* {{{ */
278 {
279   char *tmp;
280
281   if ((ident == NULL) || (plugin_instance == NULL))
282     return (EINVAL);
283
284   tmp = strdup (plugin_instance);
285   if (tmp == NULL)
286     return (ENOMEM);
287
288   free (ident->plugin_instance);
289   ident->plugin_instance = tmp;
290
291   return (0);
292 } /* }}} int ident_set_plugin_instance */
293
294 int ident_set_type (graph_ident_t *ident, const char *type) /* {{{ */
295 {
296   char *tmp;
297
298   if ((ident == NULL) || (type == NULL))
299     return (EINVAL);
300
301   tmp = strdup (type);
302   if (tmp == NULL)
303     return (ENOMEM);
304
305   free (ident->type);
306   ident->type = tmp;
307
308   return (0);
309 } /* }}} int ident_set_type */
310
311 int ident_set_type_instance (graph_ident_t *ident, const char *type_instance) /* {{{ */
312 {
313   char *tmp;
314
315   if ((ident == NULL) || (type_instance == NULL))
316     return (EINVAL);
317
318   tmp = strdup (type_instance);
319   if (tmp == NULL)
320     return (ENOMEM);
321
322   free (ident->type_instance);
323   ident->type_instance = tmp;
324
325   return (0);
326 } /* }}} int ident_set_type_instance */
327
328 /* }}} ident_set_* methods */
329
330 int ident_compare (const graph_ident_t *i0, /* {{{ */
331     const graph_ident_t *i1)
332 {
333   int status;
334
335 #define COMPARE_PART(p) do {       \
336   status = strcmp (i0->p, i1->p);  \
337   if (status != 0)                 \
338     return (status);               \
339 } while (0)
340
341   COMPARE_PART (host);
342   COMPARE_PART (plugin);
343   COMPARE_PART (plugin_instance);
344   COMPARE_PART (type);
345   COMPARE_PART (type_instance);
346
347 #undef COMPARE_PART
348
349   return (0);
350 } /* }}} int ident_compare */
351
352 _Bool ident_matches (const graph_ident_t *selector, /* {{{ */
353     const graph_ident_t *ident)
354 {
355   if ((selector == NULL) && (ident == NULL))
356     return (0);
357   else if (selector == NULL)
358     return (-1);
359   else if (ident == NULL)
360     return (1);
361
362   if (!part_matches (selector->host, ident->host))
363     return (0);
364
365   if (!part_matches (selector->plugin, ident->plugin))
366     return (0);
367
368   if (!part_matches (selector->plugin_instance, ident->plugin_instance))
369     return (0);
370
371   if (!part_matches (selector->type, ident->type))
372     return (0);
373
374   if (!part_matches (selector->type_instance, ident->type_instance))
375     return (0);
376
377   return (1);
378 } /* }}} _Bool ident_matches */
379
380 char *ident_to_string (const graph_ident_t *ident) /* {{{ */
381 {
382   char buffer[PATH_MAX];
383
384   buffer[0] = 0;
385
386   strlcat (buffer, ident->host, sizeof (buffer));
387   strlcat (buffer, "/", sizeof (buffer));
388   strlcat (buffer, ident->plugin, sizeof (buffer));
389   if (ident->plugin_instance[0] != 0)
390   {
391     strlcat (buffer, "-", sizeof (buffer));
392     strlcat (buffer, ident->plugin_instance, sizeof (buffer));
393   }
394   strlcat (buffer, "/", sizeof (buffer));
395   strlcat (buffer, ident->type, sizeof (buffer));
396   if (ident->type_instance[0] != 0)
397   {
398     strlcat (buffer, "-", sizeof (buffer));
399     strlcat (buffer, ident->type_instance, sizeof (buffer));
400   }
401
402   return (strdup (buffer));
403 } /* }}} char *ident_to_string */
404
405 char *ident_to_file (const graph_ident_t *ident) /* {{{ */
406 {
407   char buffer[PATH_MAX];
408
409   buffer[0] = 0;
410
411   strlcat (buffer, DATA_DIR, sizeof (buffer));
412   strlcat (buffer, "/", sizeof (buffer));
413
414   strlcat (buffer, ident->host, sizeof (buffer));
415   strlcat (buffer, "/", sizeof (buffer));
416   strlcat (buffer, ident->plugin, sizeof (buffer));
417   if (ident->plugin_instance[0] != 0)
418   {
419     strlcat (buffer, "-", sizeof (buffer));
420     strlcat (buffer, ident->plugin_instance, sizeof (buffer));
421   }
422   strlcat (buffer, "/", sizeof (buffer));
423   strlcat (buffer, ident->type, sizeof (buffer));
424   if (ident->type_instance[0] != 0)
425   {
426     strlcat (buffer, "-", sizeof (buffer));
427     strlcat (buffer, ident->type_instance, sizeof (buffer));
428   }
429
430   strlcat (buffer, ".rrd", sizeof (buffer));
431
432   return (strdup (buffer));
433 } /* }}} char *ident_to_file */
434
435 char *ident_to_json (const graph_ident_t *ident) /* {{{ */
436 {
437   char buffer[4096];
438
439   buffer[0] = 0;
440
441   strlcat (buffer, "{\"host\":\"", sizeof (buffer));
442   strlcat (buffer, ident->host, sizeof (buffer));
443   strlcat (buffer, "\",\"plugin\":\"", sizeof (buffer));
444   strlcat (buffer, ident->plugin, sizeof (buffer));
445   strlcat (buffer, "\",\"plugin_instance\":\"", sizeof (buffer));
446   strlcat (buffer, ident->plugin_instance, sizeof (buffer));
447   strlcat (buffer, "\",\"type\":\"", sizeof (buffer));
448   strlcat (buffer, ident->type, sizeof (buffer));
449   strlcat (buffer, "\",\"type_instance\":\"", sizeof (buffer));
450   strlcat (buffer, ident->type_instance, sizeof (buffer));
451   strlcat (buffer, "\"}", sizeof (buffer));
452
453   return (strdup (buffer));
454 } /* }}} char *ident_to_json */
455
456 /* vim: set sw=2 sts=2 et fdm=marker : */
457