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