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