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
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>
24 static xmlXPathObject
*pusb_xpath_match(xmlDocPtr doc
, const char *path
)
26 xmlXPathContext
*context
= NULL
;
27 xmlXPathObject
*result
= NULL
;
29 context
= xmlXPathNewContext(doc
);
32 log_error("Unable to create XML context\n");
35 result
= xmlXPathEvalExpression((xmlChar
*)path
, context
);
36 xmlXPathFreeContext(context
);
39 log_error("Error in xmlXPathEvalExpression\n");
42 if (xmlXPathNodeSetIsEmpty(result
->nodesetval
))
44 xmlXPathFreeObject(result
);
50 static int pusb_xpath_strip_string(char *dest
, const char *src
,
57 for (i
= 0; src
[i
]; ++i
)
67 if (first_char
== -1 || last_char
== -1)
70 if ((last_char
- first_char
) > (size
- 1))
73 memset(dest
, 0x0, size
);
74 strncpy(dest
, &(src
[first_char
]), last_char
- first_char
+ 1);
78 int pusb_xpath_get_string(xmlDocPtr doc
, const char *path
,
79 char *value
, size_t size
)
81 xmlXPathObject
*result
= NULL
;
83 xmlChar
*result_string
= NULL
;
85 if (!(result
= pusb_xpath_match(doc
, path
)))
88 if (result
->nodesetval
->nodeNr
> 1)
90 xmlXPathFreeObject(result
);
91 log_debug("Syntax error: %s: more than one record found\n", path
);
95 node
= result
->nodesetval
->nodeTab
[0]->xmlChildrenNode
;
96 result_string
= xmlNodeListGetString(doc
, node
, 1);
99 xmlXPathFreeObject(result
);
100 log_debug("Empty value for %s\n", path
);
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
);
111 xmlFree(result_string
);
112 xmlXPathFreeObject(result
);
116 int pusb_xpath_get_string_from(xmlDocPtr doc
,
119 char *value
, size_t size
)
125 xpath_size
= strlen(base
) + strlen(path
) + 1;
126 if (!(xpath
= malloc(xpath_size
)))
128 log_error("malloc error !\n");
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
);
135 log_debug("%s%s -> %s\n", base
, path
, value
);
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
)))
147 if (!strcmp(ret
, "true"))
153 if (!strcmp(ret
, "false"))
159 log_debug("Expecting a boolean, got %s\n", ret
);
163 int pusb_xpath_get_bool_from(xmlDocPtr doc
,
172 xpath_size
= strlen(base
) + strlen(path
) + 1;
173 if (!(xpath
= malloc(xpath_size
)))
175 log_error("malloc error!\n");
178 memset(xpath
, 0x00, xpath_size
);
179 snprintf(xpath
, xpath_size
, "%s%s", base
, path
);
180 retval
= pusb_xpath_get_bool(doc
, xpath
, value
);
185 int pusb_xpath_get_time(xmlDocPtr doc
, const char *path
, time_t *value
)
191 if (!pusb_xpath_get_string(doc
, path
, ret
, sizeof(ret
)))
194 last
= &(ret
[strlen(ret
) - 1]);
198 else if (*last
== 'm')
200 else if (*last
== 'h')
202 else if (*last
== 'd')
207 log_debug("Expecting a time modifier, got %c\n", *last
);
212 *value
= atoi(ret
) * coef
;
217 int pusb_xpath_get_time_from(xmlDocPtr doc
,
226 xpath_size
= strlen(base
) + strlen(path
) + 1;
227 if (!(xpath
= malloc(xpath_size
)))
229 log_error("malloc error!\n");
232 memset(xpath
, 0x00, xpath_size
);
233 snprintf(xpath
, xpath_size
, "%s%s", base
, path
);
234 retval
= pusb_xpath_get_time(doc
, xpath
, value
);
239 int pusb_xpath_get_int(xmlDocPtr doc
, const char *path
, int *value
)
243 if (!pusb_xpath_get_string(doc
, path
, ret
, sizeof(ret
)))
249 int pusb_xpath_get_int_from(xmlDocPtr doc
,
258 xpath_size
= strlen(base
) + strlen(path
) + 1;
259 if (!(xpath
= malloc(xpath_size
)))
261 log_error("malloc error!\n");
264 memset(xpath
, 0x00, xpath_size
);
265 snprintf(xpath
, xpath_size
, "%s%s", base
, path
);
266 retval
= pusb_xpath_get_int(doc
, xpath
, value
);