Port pamusb-agent and pamusb-conf to UDisks.
[pam_usb.git] / src / xpath.c
blob27b88c89a99a2acd3cb05fa6e4ec124c57fce801
1 /*
2 * Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
4 * This file is part of the pam_usb project. pam_usb is free software;
5 * you can redistribute it and/or modify it under the terms of the GNU General
6 * Public License version 2, as published by the Free Software Foundation.
8 * pam_usb is distributed in the hope that it will be useful, but WITHOUT ANY
9 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11 * details.
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place, Suite 330, Boston, MA 02111-1307 USA
18 #include <libxml/xpath.h>
19 #include <ctype.h>
20 #include <string.h>
21 #include "xpath.h"
22 #include "log.h"
24 static xmlXPathObject *pusb_xpath_match(xmlDocPtr doc, const char *path)
26 xmlXPathContext *context = NULL;
27 xmlXPathObject *result = NULL;
29 context = xmlXPathNewContext(doc);
30 if (context == NULL)
32 log_error("Unable to create XML context\n");
33 return (NULL);
35 result = xmlXPathEvalExpression((xmlChar *)path, context);
36 xmlXPathFreeContext(context);
37 if (result == NULL)
39 log_error("Error in xmlXPathEvalExpression\n");
40 return (NULL);
42 if (xmlXPathNodeSetIsEmpty(result->nodesetval))
44 xmlXPathFreeObject(result);
45 return (NULL);
47 return (result);
50 static int pusb_xpath_strip_string(char *dest, const char *src,
51 size_t size)
53 int first_char = -1;
54 int last_char = -1;
55 int i;
57 for (i = 0; src[i]; ++i)
59 if (isspace(src[i]))
60 continue ;
62 if (first_char == -1)
63 first_char = i;
64 last_char = i;
67 if (first_char == -1 || last_char == -1)
68 return (0);
70 if ((last_char - first_char) > (size - 1))
71 return (0);
73 memset(dest, 0x0, size);
74 strncpy(dest, &(src[first_char]), last_char - first_char + 1);
75 return (1);
78 int pusb_xpath_get_string(xmlDocPtr doc, const char *path,
79 char *value, size_t size)
81 xmlXPathObject *result = NULL;
82 xmlNode *node = NULL;
83 xmlChar *result_string = NULL;
85 if (!(result = pusb_xpath_match(doc, path)))
86 return (0);
88 if (result->nodesetval->nodeNr > 1)
90 xmlXPathFreeObject(result);
91 log_debug("Syntax error: %s: more than one record found\n", path);
92 return (0);
95 node = result->nodesetval->nodeTab[0]->xmlChildrenNode;
96 result_string = xmlNodeListGetString(doc, node, 1);
97 if (!result_string)
99 xmlXPathFreeObject(result);
100 log_debug("Empty value for %s\n", path);
101 return (0);
103 if (!pusb_xpath_strip_string(value, (const char *)result_string, size))
105 xmlFree(result_string);
106 xmlXPathFreeObject(result);
107 log_debug("Result for %s (%s) is too long (max: %d)\n",
108 path, (const char *)result_string, size);
109 return (0);
111 xmlFree(result_string);
112 xmlXPathFreeObject(result);
113 return (1);
116 int pusb_xpath_get_string_from(xmlDocPtr doc,
117 const char *base,
118 const char *path,
119 char *value, size_t size)
121 char *xpath = NULL;
122 size_t xpath_size;
123 int retval;
125 xpath_size = strlen(base) + strlen(path) + 1;
126 if (!(xpath = malloc(xpath_size)))
128 log_error("malloc error !\n");
129 return (0);
131 memset(xpath, 0x00, xpath_size);
132 snprintf(xpath, xpath_size, "%s%s", base, path);
133 retval = pusb_xpath_get_string(doc, xpath, value, size);
134 if (retval)
135 log_debug("%s%s -> %s\n", base, path, value);
136 free(xpath);
137 return (retval);
140 int pusb_xpath_get_bool(xmlDocPtr doc, const char *path, int *value)
142 char ret[6]; /* strlen("false") + 1 */
144 if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
145 return (0);
147 if (!strcmp(ret, "true"))
149 *value = 1;
150 return (1);
153 if (!strcmp(ret, "false"))
155 *value = 0;
156 return (1);
159 log_debug("Expecting a boolean, got %s\n", ret);
160 return (0);
163 int pusb_xpath_get_bool_from(xmlDocPtr doc,
164 const char *base,
165 const char *path,
166 int *value)
168 char *xpath = NULL;
169 size_t xpath_size;
170 int retval;
172 xpath_size = strlen(base) + strlen(path) + 1;
173 if (!(xpath = malloc(xpath_size)))
175 log_error("malloc error!\n");
176 return (0);
178 memset(xpath, 0x00, xpath_size);
179 snprintf(xpath, xpath_size, "%s%s", base, path);
180 retval = pusb_xpath_get_bool(doc, xpath, value);
181 free(xpath);
182 return (retval);
185 int pusb_xpath_get_time(xmlDocPtr doc, const char *path, time_t *value)
187 char ret[64];
188 char *last;
189 int coef;
191 if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
192 return (0);
194 last = &(ret[strlen(ret) - 1]);
195 coef = 1;
196 if (*last == 's')
197 coef = 1;
198 else if (*last == 'm')
199 coef = 60;
200 else if (*last == 'h')
201 coef = 3600;
202 else if (*last == 'd')
203 coef = 3600 * 24;
204 else
205 if (!isdigit(*last))
207 log_debug("Expecting a time modifier, got %c\n", *last);
208 return (0);
210 if (!isdigit(*last))
211 *last = '\0';
212 *value = atoi(ret) * coef;
214 return (0);
217 int pusb_xpath_get_time_from(xmlDocPtr doc,
218 const char *base,
219 const char *path,
220 time_t *value)
222 char *xpath = NULL;
223 size_t xpath_size;
224 int retval;
226 xpath_size = strlen(base) + strlen(path) + 1;
227 if (!(xpath = malloc(xpath_size)))
229 log_error("malloc error!\n");
230 return (0);
232 memset(xpath, 0x00, xpath_size);
233 snprintf(xpath, xpath_size, "%s%s", base, path);
234 retval = pusb_xpath_get_time(doc, xpath, value);
235 free(xpath);
236 return (retval);
239 int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value)
241 char ret[64];
243 if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
244 return (0);
245 *value = atoi(ret);
246 return (1);
249 int pusb_xpath_get_int_from(xmlDocPtr doc,
250 const char *base,
251 const char *path,
252 int *value)
254 char *xpath = NULL;
255 size_t xpath_size;
256 int retval;
258 xpath_size = strlen(base) + strlen(path) + 1;
259 if (!(xpath = malloc(xpath_size)))
261 log_error("malloc error!\n");
262 return (0);
264 memset(xpath, 0x00, xpath_size);
265 snprintf(xpath, xpath_size, "%s%s", base, path);
266 retval = pusb_xpath_get_int(doc, xpath, value);
267 free(xpath);
268 return (retval);