aa157e6df6307d925bd8a173535de22cec9f67dc
1 /**
2 * collection4 - utils_search.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 <string.h>
27 #include <ctype.h>
28 #include <errno.h>
30 #include "utils_search.h"
31 #include "graph_instance.h"
32 #include "utils_array.h"
34 #include <fcgiapp.h>
35 #include <fcgi_stdio.h>
37 struct search_info_s
38 {
39 char *host;
40 char *plugin;
41 char *plugin_instance;
42 char *type;
43 char *type_instance;
45 str_array_t *terms;
46 };
48 /*
49 * Private functions
50 */
51 static char *read_quoted_string (const char **buffer) /* {{{ */
52 {
53 const char *ptr = *buffer;
54 char *ret;
55 size_t ret_len;
57 if (ptr[0] != '"')
58 return (NULL);
59 ptr++;
61 ret_len = 0;
62 while ((*ptr != '"') && (*ptr != 0))
63 {
64 ret_len++;
66 if (*ptr == '\\')
67 ptr += 2;
68 else
69 ptr++;
70 }
72 if ((ret_len < 1) || (*ptr != '"'))
73 return (NULL);
75 ret = malloc (ret_len + 1);
76 if (ret == NULL)
77 return (NULL);
79 ptr = *buffer + 1;
80 ret_len = 0;
81 while ((*ptr != '"') && (*ptr != 0))
82 {
83 if (*ptr == '"')
84 break;
86 if (*ptr == '\\')
87 ptr++;
89 ret[ret_len] = *ptr;
91 ptr++;
92 ret_len++;
93 }
95 /* terminate string */
96 ret[ret_len] = 0;
98 /* "ptr" points to the '"' sign, so advance one more */
99 ptr++;
100 *buffer = ptr;
102 return (ret);
103 } /* }}} char *read_quoted_string */
105 static char *read_unquoted_word (const char **buffer) /* {{{ */
106 {
107 const char *ptr = *buffer;
108 char *ret;
109 size_t ret_len;
111 ret_len = 0;
112 while (!isspace ((int) ptr[ret_len]) && (ptr[ret_len] != 0))
113 ret_len++;
115 if (ret_len < 1)
116 return (NULL);
118 ret = malloc (ret_len + 1);
119 if (ret == NULL)
120 return (NULL);
122 memcpy (ret, ptr, ret_len);
123 ret[ret_len] = 0;
125 ptr += ret_len;
126 *buffer = ptr;
128 return (ret);
129 } /* }}} char *read_unquoted_word */
131 static char *next_token (const char **buffer) /* {{{ */
132 {
133 const char *ptr = *buffer;
134 char *ret;
136 while (isspace ((int) (*ptr)))
137 ptr++;
139 if (ptr[0] == 0)
140 return (NULL);
141 else if (ptr[0] == '"')
142 {
143 ret = read_quoted_string (&ptr);
144 if (ret != NULL)
145 {
146 *buffer = ptr;
147 return (ret);
148 }
149 }
151 ret = read_unquoted_word (&ptr);
152 if (ret != NULL)
153 *buffer = ptr;
155 return (ret);
156 } /* }}} char *next_token */
158 static int store_token_field (char **field, const char *token) /* {{{ */
159 {
160 char *copy;
162 if ((field == NULL) || (token == NULL))
163 return (EINVAL);
165 copy = strdup (token);
166 if (copy == NULL)
167 return (ENOMEM);
169 free (*field);
170 *field = copy;
172 return (0);
173 } /* }}} int store_token_field */
175 static int store_token (search_info_t *si, const char *token) /* {{{ */
176 {
177 if (strncmp ("host:", token, strlen ("host:")) == 0)
178 return (store_token_field (&si->host, token + strlen ("host:")));
179 else if (strncmp ("plugin:", token, strlen ("plugin:")) == 0)
180 return (store_token_field (&si->plugin, token + strlen ("plugin:")));
181 else if (strncmp ("plugin_instance:", token, strlen ("plugin_instance:")) == 0)
182 return (store_token_field (&si->plugin_instance, token + strlen ("plugin_instance:")));
183 else if (strncmp ("type:", token, strlen ("type:")) == 0)
184 return (store_token_field (&si->type, token + strlen ("type:")));
185 else if (strncmp ("type_instance:", token, strlen ("type_instance:")) == 0)
186 return (store_token_field (&si->type_instance, token + strlen ("type_instance:")));
188 return (array_append (si->terms, token));
189 } /* }}} int store_token */
191 /*
192 * Public functions
193 */
194 search_info_t *search_parse (const char *search) /* {{{ */
195 {
196 const char *ptr;
197 char *token;
198 search_info_t *si;
200 si = malloc (sizeof (*si));
201 if (si == NULL)
202 return (NULL);
203 memset (si, 0, sizeof (*si));
205 si->terms = array_create ();
206 if (si->terms == NULL)
207 {
208 free (si);
209 return (NULL);
210 }
212 ptr = search;
214 while ((token = next_token (&ptr)) != NULL)
215 {
216 store_token (si, token);
217 free (token);
218 }
220 return (si);
221 } /* }}} search_info_t *search_parse */
223 void search_destroy (search_info_t *si) /* {{{ */
224 {
225 if (si == NULL)
226 return;
228 free (si->host);
229 free (si->plugin);
230 free (si->plugin_instance);
231 free (si->type);
232 free (si->type_instance);
234 array_destroy (si->terms);
235 } /* }}} void search_destroy */
237 _Bool search_has_selector (search_info_t *si) /* {{{ */
238 {
239 if (si == NULL)
240 return (0);
242 if ((si->host != NULL)
243 || (si->plugin != NULL) || (si->plugin_instance != NULL)
244 || (si->type != NULL) || (si->type_instance != NULL))
245 return (1);
247 return (0);
248 } /* }}} _Bool search_has_selector */
250 graph_ident_t *search_to_ident (search_info_t *si) /* {{{ */
251 {
252 if (si == NULL)
253 return (NULL);
255 return (ident_create ((si->host == NULL) ? ANY_TOKEN : si->host,
256 (si->plugin == NULL) ? ANY_TOKEN : si->plugin,
257 (si->plugin_instance == NULL) ? ANY_TOKEN : si->plugin_instance,
258 (si->type == NULL) ? ANY_TOKEN : si->type,
259 (si->type_instance == NULL) ? ANY_TOKEN : si->type_instance));
260 } /* }}} graph_ident_t *search_to_ident */
262 _Bool search_graph_title_matches (search_info_t *si, /* {{{ */
263 const char *title)
264 {
265 char **argv;
266 int argc;
267 int i;
269 if ((si == NULL) || (title == NULL))
270 return (0);
272 if (si->terms == NULL)
273 return (1);
275 argc = array_argc (si->terms);
276 argv = array_argv (si->terms);
277 for (i = 0; i < argc; i++)
278 if (strstr (title, argv[i]) == NULL)
279 return (0);
281 return (1);
282 } /* }}} _Bool search_graph_title_matches */
284 _Bool search_graph_inst_matches (search_info_t *si, /* {{{ */
285 graph_config_t *cfg, graph_instance_t *inst,
286 const char *title)
287 {
288 char **argv;
289 int argc;
290 int i;
292 if ((si == NULL) || (cfg == NULL) || (inst == NULL))
293 return (0);
295 if ((si->host != NULL)
296 && !inst_matches_field (inst, GIF_HOST, si->host))
297 return (0);
298 else if ((si->plugin != NULL)
299 && !inst_matches_field (inst, GIF_PLUGIN, si->plugin))
300 return (0);
301 else if ((si->plugin_instance != NULL)
302 && !inst_matches_field (inst, GIF_PLUGIN_INSTANCE, si->plugin_instance))
303 return (0);
304 else if ((si->type != NULL)
305 && !inst_matches_field (inst, GIF_TYPE, si->type))
306 return (0);
307 else if ((si->type_instance != NULL)
308 && !inst_matches_field (inst, GIF_TYPE_INSTANCE, si->type_instance))
309 return (0);
311 if (si->terms == NULL)
312 return (1);
314 argc = array_argc (si->terms);
315 argv = array_argv (si->terms);
316 for (i = 0; i < argc; i++)
317 {
318 if (inst_matches_string (cfg, inst, argv[i]))
319 continue;
321 if ((title != NULL) && (strstr (title, argv[i]) != NULL))
322 continue;
324 return (0);
325 }
327 return (1);
328 } /* }}} _Bool search_graph_inst_matches */
330 /* vim: set sw=2 sts=2 et fdm=marker : */