6ed9c172c6e9a566fc0135c003be8a2191d96830
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 "utils_array.h"
33 #include <fcgiapp.h>
34 #include <fcgi_stdio.h>
36 struct search_info_s
37 {
38 char *host;
39 char *plugin;
40 char *plugin_instance;
41 char *type;
42 char *type_instance;
44 str_array_t *terms;
45 };
47 /*
48 * Private functions
49 */
50 static char *read_quoted_string (const char **buffer) /* {{{ */
51 {
52 const char *ptr = *buffer;
53 char *ret;
54 size_t ret_len;
56 if (ptr[0] != '"')
57 return (NULL);
58 ptr++;
60 ret_len = 0;
61 while ((*ptr != '"') && (*ptr != 0))
62 {
63 ret_len++;
65 if (*ptr == '\\')
66 ptr += 2;
67 else
68 ptr++;
69 }
71 if ((ret_len < 1) || (*ptr != '"'))
72 return (NULL);
74 ret = malloc (ret_len + 1);
75 if (ret == NULL)
76 return (NULL);
78 ptr = *buffer + 1;
79 ret_len = 0;
80 while ((*ptr != '"') && (*ptr != 0))
81 {
82 if (*ptr == '"')
83 break;
85 if (*ptr == '\\')
86 ptr++;
88 ret[ret_len] = *ptr;
90 ptr++;
91 ret_len++;
92 }
94 /* terminate string */
95 ret[ret_len] = 0;
97 /* "ptr" points to the '"' sign, so advance one more */
98 ptr++;
99 *buffer = ptr;
101 return (ret);
102 } /* }}} char *read_quoted_string */
104 static char *read_unquoted_word (const char **buffer) /* {{{ */
105 {
106 const char *ptr = *buffer;
107 char *ret;
108 size_t ret_len;
110 ret_len = 0;
111 while (!isspace ((int) ptr[ret_len]) && (ptr[ret_len] != 0))
112 ret_len++;
114 if (ret_len < 1)
115 return (NULL);
117 ret = malloc (ret_len + 1);
118 if (ret == NULL)
119 return (NULL);
121 memcpy (ret, ptr, ret_len);
122 ret[ret_len] = 0;
124 ptr += ret_len;
125 *buffer = ptr;
127 return (ret);
128 } /* }}} char *read_unquoted_word */
130 static char *next_token (const char **buffer) /* {{{ */
131 {
132 const char *ptr = *buffer;
133 char *ret;
135 while (isspace ((int) (*ptr)))
136 ptr++;
138 if (ptr[0] == 0)
139 return (NULL);
140 else if (ptr[0] == '"')
141 {
142 ret = read_quoted_string (&ptr);
143 if (ret != NULL)
144 {
145 *buffer = ptr;
146 return (ret);
147 }
148 }
150 ret = read_unquoted_word (&ptr);
151 if (ret != NULL)
152 *buffer = ptr;
154 return (ret);
155 } /* }}} char *next_token */
157 static int store_token_field (char **field, const char *token) /* {{{ */
158 {
159 char *copy;
161 if ((field == NULL) || (token == NULL))
162 return (EINVAL);
164 copy = strdup (token);
165 if (copy == NULL)
166 return (ENOMEM);
168 free (*field);
169 *field = copy;
171 return (0);
172 } /* }}} int store_token_field */
174 static int store_token (search_info_t *si, const char *token) /* {{{ */
175 {
176 if (strncmp ("host:", token, strlen ("host:")) == 0)
177 return (store_token_field (&si->host, token + strlen ("host:")));
178 else if (strncmp ("plugin:", token, strlen ("plugin:")) == 0)
179 return (store_token_field (&si->plugin, token + strlen ("plugin:")));
180 else if (strncmp ("plugin_instance:", token, strlen ("plugin_instance:")) == 0)
181 return (store_token_field (&si->plugin_instance, token + strlen ("plugin_instance:")));
182 else if (strncmp ("type:", token, strlen ("type:")) == 0)
183 return (store_token_field (&si->type, token + strlen ("type:")));
184 else if (strncmp ("type_instance:", token, strlen ("type_instance:")) == 0)
185 return (store_token_field (&si->type_instance, token + strlen ("type_instance:")));
187 return (array_append (si->terms, token));
188 } /* }}} int store_token */
190 /*
191 * Public functions
192 */
193 search_info_t *search_parse (const char *search) /* {{{ */
194 {
195 const char *ptr;
196 char *token;
197 search_info_t *si;
199 si = malloc (sizeof (*si));
200 if (si == NULL)
201 return (NULL);
202 memset (si, 0, sizeof (*si));
204 si->terms = array_create ();
205 if (si->terms == NULL)
206 {
207 free (si);
208 return (NULL);
209 }
211 ptr = search;
213 while ((token = next_token (&ptr)) != NULL)
214 {
215 store_token (si, token);
216 free (token);
217 }
219 return (si);
220 } /* }}} search_info_t *search_parse */
222 void search_destroy (search_info_t *si) /* {{{ */
223 {
224 if (si == NULL)
225 return;
227 free (si->host);
228 free (si->plugin);
229 free (si->plugin_instance);
230 free (si->type);
231 free (si->type_instance);
233 array_destroy (si->terms);
234 } /* }}} void search_destroy */
236 /* vim: set sw=2 sts=2 et fdm=marker : */