15b9c547cSRui Paulo /*
25b9c547cSRui Paulo * XML wrapper for libxml2
35b9c547cSRui Paulo * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
45b9c547cSRui Paulo *
55b9c547cSRui Paulo * This software may be distributed under the terms of the BSD license.
65b9c547cSRui Paulo * See README for more details.
75b9c547cSRui Paulo */
85b9c547cSRui Paulo
95b9c547cSRui Paulo #include "includes.h"
105b9c547cSRui Paulo #define LIBXML_VALID_ENABLED
115b9c547cSRui Paulo #include <libxml/tree.h>
125b9c547cSRui Paulo #include <libxml/xmlschemastypes.h>
135b9c547cSRui Paulo
145b9c547cSRui Paulo #include "common.h"
155b9c547cSRui Paulo #include "base64.h"
165b9c547cSRui Paulo #include "xml-utils.h"
175b9c547cSRui Paulo
185b9c547cSRui Paulo
195b9c547cSRui Paulo struct xml_node_ctx {
205b9c547cSRui Paulo void *ctx;
215b9c547cSRui Paulo };
225b9c547cSRui Paulo
235b9c547cSRui Paulo
245b9c547cSRui Paulo struct str_buf {
255b9c547cSRui Paulo char *buf;
265b9c547cSRui Paulo size_t len;
275b9c547cSRui Paulo };
285b9c547cSRui Paulo
295b9c547cSRui Paulo #define MAX_STR 1000
305b9c547cSRui Paulo
add_str(void * ctx_ptr,const char * fmt,...)315b9c547cSRui Paulo static void add_str(void *ctx_ptr, const char *fmt, ...)
325b9c547cSRui Paulo {
335b9c547cSRui Paulo struct str_buf *str = ctx_ptr;
345b9c547cSRui Paulo va_list ap;
355b9c547cSRui Paulo char *n;
365b9c547cSRui Paulo int len;
375b9c547cSRui Paulo
385b9c547cSRui Paulo n = os_realloc(str->buf, str->len + MAX_STR + 2);
395b9c547cSRui Paulo if (n == NULL)
405b9c547cSRui Paulo return;
415b9c547cSRui Paulo str->buf = n;
425b9c547cSRui Paulo
435b9c547cSRui Paulo va_start(ap, fmt);
445b9c547cSRui Paulo len = vsnprintf(str->buf + str->len, MAX_STR, fmt, ap);
455b9c547cSRui Paulo va_end(ap);
465b9c547cSRui Paulo if (len >= MAX_STR)
475b9c547cSRui Paulo len = MAX_STR - 1;
485b9c547cSRui Paulo str->len += len;
495b9c547cSRui Paulo str->buf[str->len] = '\0';
505b9c547cSRui Paulo }
515b9c547cSRui Paulo
525b9c547cSRui Paulo
xml_validate(struct xml_node_ctx * ctx,xml_node_t * node,const char * xml_schema_fname,char ** ret_err)535b9c547cSRui Paulo int xml_validate(struct xml_node_ctx *ctx, xml_node_t *node,
545b9c547cSRui Paulo const char *xml_schema_fname, char **ret_err)
555b9c547cSRui Paulo {
565b9c547cSRui Paulo xmlDocPtr doc;
575b9c547cSRui Paulo xmlNodePtr n;
585b9c547cSRui Paulo xmlSchemaParserCtxtPtr pctx;
595b9c547cSRui Paulo xmlSchemaValidCtxtPtr vctx;
605b9c547cSRui Paulo xmlSchemaPtr schema;
615b9c547cSRui Paulo int ret;
625b9c547cSRui Paulo struct str_buf errors;
635b9c547cSRui Paulo
645b9c547cSRui Paulo if (ret_err)
655b9c547cSRui Paulo *ret_err = NULL;
665b9c547cSRui Paulo
675b9c547cSRui Paulo doc = xmlNewDoc((xmlChar *) "1.0");
685b9c547cSRui Paulo if (doc == NULL)
695b9c547cSRui Paulo return -1;
705b9c547cSRui Paulo n = xmlDocCopyNode((xmlNodePtr) node, doc, 1);
715b9c547cSRui Paulo if (n == NULL) {
725b9c547cSRui Paulo xmlFreeDoc(doc);
735b9c547cSRui Paulo return -1;
745b9c547cSRui Paulo }
755b9c547cSRui Paulo xmlDocSetRootElement(doc, n);
765b9c547cSRui Paulo
775b9c547cSRui Paulo os_memset(&errors, 0, sizeof(errors));
785b9c547cSRui Paulo
795b9c547cSRui Paulo pctx = xmlSchemaNewParserCtxt(xml_schema_fname);
805b9c547cSRui Paulo xmlSchemaSetParserErrors(pctx, (xmlSchemaValidityErrorFunc) add_str,
815b9c547cSRui Paulo (xmlSchemaValidityWarningFunc) add_str,
825b9c547cSRui Paulo &errors);
835b9c547cSRui Paulo schema = xmlSchemaParse(pctx);
845b9c547cSRui Paulo xmlSchemaFreeParserCtxt(pctx);
855b9c547cSRui Paulo
865b9c547cSRui Paulo vctx = xmlSchemaNewValidCtxt(schema);
875b9c547cSRui Paulo xmlSchemaSetValidErrors(vctx, (xmlSchemaValidityErrorFunc) add_str,
885b9c547cSRui Paulo (xmlSchemaValidityWarningFunc) add_str,
895b9c547cSRui Paulo &errors);
905b9c547cSRui Paulo
915b9c547cSRui Paulo ret = xmlSchemaValidateDoc(vctx, doc);
925b9c547cSRui Paulo xmlSchemaFreeValidCtxt(vctx);
935b9c547cSRui Paulo xmlFreeDoc(doc);
945b9c547cSRui Paulo xmlSchemaFree(schema);
955b9c547cSRui Paulo
965b9c547cSRui Paulo if (ret == 0) {
975b9c547cSRui Paulo os_free(errors.buf);
985b9c547cSRui Paulo return 0;
995b9c547cSRui Paulo } else if (ret > 0) {
1005b9c547cSRui Paulo if (ret_err)
1015b9c547cSRui Paulo *ret_err = errors.buf;
1025b9c547cSRui Paulo else
1035b9c547cSRui Paulo os_free(errors.buf);
1045b9c547cSRui Paulo return -1;
1055b9c547cSRui Paulo } else {
1065b9c547cSRui Paulo if (ret_err)
1075b9c547cSRui Paulo *ret_err = errors.buf;
1085b9c547cSRui Paulo else
1095b9c547cSRui Paulo os_free(errors.buf);
1105b9c547cSRui Paulo return -1;
1115b9c547cSRui Paulo }
1125b9c547cSRui Paulo }
1135b9c547cSRui Paulo
1145b9c547cSRui Paulo
xml_validate_dtd(struct xml_node_ctx * ctx,xml_node_t * node,const char * dtd_fname,char ** ret_err)1155b9c547cSRui Paulo int xml_validate_dtd(struct xml_node_ctx *ctx, xml_node_t *node,
1165b9c547cSRui Paulo const char *dtd_fname, char **ret_err)
1175b9c547cSRui Paulo {
1185b9c547cSRui Paulo xmlDocPtr doc;
1195b9c547cSRui Paulo xmlNodePtr n;
1205b9c547cSRui Paulo xmlValidCtxt vctx;
1215b9c547cSRui Paulo xmlDtdPtr dtd;
1225b9c547cSRui Paulo int ret;
1235b9c547cSRui Paulo struct str_buf errors;
1245b9c547cSRui Paulo
1255b9c547cSRui Paulo if (ret_err)
1265b9c547cSRui Paulo *ret_err = NULL;
1275b9c547cSRui Paulo
1285b9c547cSRui Paulo doc = xmlNewDoc((xmlChar *) "1.0");
1295b9c547cSRui Paulo if (doc == NULL)
1305b9c547cSRui Paulo return -1;
1315b9c547cSRui Paulo n = xmlDocCopyNode((xmlNodePtr) node, doc, 1);
1325b9c547cSRui Paulo if (n == NULL) {
1335b9c547cSRui Paulo xmlFreeDoc(doc);
1345b9c547cSRui Paulo return -1;
1355b9c547cSRui Paulo }
1365b9c547cSRui Paulo xmlDocSetRootElement(doc, n);
1375b9c547cSRui Paulo
1385b9c547cSRui Paulo os_memset(&errors, 0, sizeof(errors));
1395b9c547cSRui Paulo
1405b9c547cSRui Paulo dtd = xmlParseDTD(NULL, (const xmlChar *) dtd_fname);
1415b9c547cSRui Paulo if (dtd == NULL) {
1425b9c547cSRui Paulo xmlFreeDoc(doc);
1435b9c547cSRui Paulo return -1;
1445b9c547cSRui Paulo }
1455b9c547cSRui Paulo
1465b9c547cSRui Paulo os_memset(&vctx, 0, sizeof(vctx));
1475b9c547cSRui Paulo vctx.userData = &errors;
1485b9c547cSRui Paulo vctx.error = add_str;
1495b9c547cSRui Paulo vctx.warning = add_str;
1505b9c547cSRui Paulo ret = xmlValidateDtd(&vctx, doc, dtd);
1515b9c547cSRui Paulo xmlFreeDoc(doc);
1525b9c547cSRui Paulo xmlFreeDtd(dtd);
1535b9c547cSRui Paulo
1545b9c547cSRui Paulo if (ret == 1) {
1555b9c547cSRui Paulo os_free(errors.buf);
1565b9c547cSRui Paulo return 0;
1575b9c547cSRui Paulo } else {
1585b9c547cSRui Paulo if (ret_err)
1595b9c547cSRui Paulo *ret_err = errors.buf;
1605b9c547cSRui Paulo else
1615b9c547cSRui Paulo os_free(errors.buf);
1625b9c547cSRui Paulo return -1;
1635b9c547cSRui Paulo }
1645b9c547cSRui Paulo }
1655b9c547cSRui Paulo
1665b9c547cSRui Paulo
xml_node_free(struct xml_node_ctx * ctx,xml_node_t * node)1675b9c547cSRui Paulo void xml_node_free(struct xml_node_ctx *ctx, xml_node_t *node)
1685b9c547cSRui Paulo {
1695b9c547cSRui Paulo xmlFreeNode((xmlNodePtr) node);
1705b9c547cSRui Paulo }
1715b9c547cSRui Paulo
1725b9c547cSRui Paulo
xml_node_get_parent(struct xml_node_ctx * ctx,xml_node_t * node)1735b9c547cSRui Paulo xml_node_t * xml_node_get_parent(struct xml_node_ctx *ctx, xml_node_t *node)
1745b9c547cSRui Paulo {
1755b9c547cSRui Paulo return (xml_node_t *) ((xmlNodePtr) node)->parent;
1765b9c547cSRui Paulo }
1775b9c547cSRui Paulo
1785b9c547cSRui Paulo
xml_node_from_buf(struct xml_node_ctx * ctx,const char * buf)1795b9c547cSRui Paulo xml_node_t * xml_node_from_buf(struct xml_node_ctx *ctx, const char *buf)
1805b9c547cSRui Paulo {
1815b9c547cSRui Paulo xmlDocPtr doc;
1825b9c547cSRui Paulo xmlNodePtr node;
1835b9c547cSRui Paulo
1845b9c547cSRui Paulo doc = xmlParseMemory(buf, strlen(buf));
1855b9c547cSRui Paulo if (doc == NULL)
1865b9c547cSRui Paulo return NULL;
1875b9c547cSRui Paulo node = xmlDocGetRootElement(doc);
1885b9c547cSRui Paulo node = xmlCopyNode(node, 1);
1895b9c547cSRui Paulo xmlFreeDoc(doc);
1905b9c547cSRui Paulo
1915b9c547cSRui Paulo return (xml_node_t *) node;
1925b9c547cSRui Paulo }
1935b9c547cSRui Paulo
1945b9c547cSRui Paulo
xml_node_get_localname(struct xml_node_ctx * ctx,xml_node_t * node)1955b9c547cSRui Paulo const char * xml_node_get_localname(struct xml_node_ctx *ctx,
1965b9c547cSRui Paulo xml_node_t *node)
1975b9c547cSRui Paulo {
1985b9c547cSRui Paulo return (const char *) ((xmlNodePtr) node)->name;
1995b9c547cSRui Paulo }
2005b9c547cSRui Paulo
2015b9c547cSRui Paulo
xml_node_to_str(struct xml_node_ctx * ctx,xml_node_t * node)2025b9c547cSRui Paulo char * xml_node_to_str(struct xml_node_ctx *ctx, xml_node_t *node)
2035b9c547cSRui Paulo {
2045b9c547cSRui Paulo xmlChar *buf;
2055b9c547cSRui Paulo int bufsiz;
2065b9c547cSRui Paulo char *ret, *pos;
2075b9c547cSRui Paulo xmlNodePtr n = (xmlNodePtr) node;
2085b9c547cSRui Paulo xmlDocPtr doc;
2095b9c547cSRui Paulo
2105b9c547cSRui Paulo doc = xmlNewDoc((xmlChar *) "1.0");
2115b9c547cSRui Paulo n = xmlDocCopyNode(n, doc, 1);
2125b9c547cSRui Paulo xmlDocSetRootElement(doc, n);
2135b9c547cSRui Paulo xmlDocDumpFormatMemory(doc, &buf, &bufsiz, 0);
2145b9c547cSRui Paulo xmlFreeDoc(doc);
215780fb4a2SCy Schubert if (!buf)
216780fb4a2SCy Schubert return NULL;
2175b9c547cSRui Paulo pos = (char *) buf;
2185b9c547cSRui Paulo if (strncmp(pos, "<?xml", 5) == 0) {
2195b9c547cSRui Paulo pos = strchr(pos, '>');
2205b9c547cSRui Paulo if (pos)
2215b9c547cSRui Paulo pos++;
2225b9c547cSRui Paulo while (pos && (*pos == '\r' || *pos == '\n'))
2235b9c547cSRui Paulo pos++;
2245b9c547cSRui Paulo }
2255b9c547cSRui Paulo if (pos)
2265b9c547cSRui Paulo ret = os_strdup(pos);
2275b9c547cSRui Paulo else
2285b9c547cSRui Paulo ret = NULL;
2295b9c547cSRui Paulo xmlFree(buf);
2305b9c547cSRui Paulo
2315b9c547cSRui Paulo if (ret) {
2325b9c547cSRui Paulo pos = ret;
2335b9c547cSRui Paulo if (pos[0]) {
2345b9c547cSRui Paulo while (pos[1])
2355b9c547cSRui Paulo pos++;
2365b9c547cSRui Paulo }
2375b9c547cSRui Paulo while (pos >= ret && *pos == '\n')
2385b9c547cSRui Paulo *pos-- = '\0';
2395b9c547cSRui Paulo }
2405b9c547cSRui Paulo
2415b9c547cSRui Paulo return ret;
2425b9c547cSRui Paulo }
2435b9c547cSRui Paulo
2445b9c547cSRui Paulo
xml_node_detach(struct xml_node_ctx * ctx,xml_node_t * node)2455b9c547cSRui Paulo void xml_node_detach(struct xml_node_ctx *ctx, xml_node_t *node)
2465b9c547cSRui Paulo {
2475b9c547cSRui Paulo xmlUnlinkNode((xmlNodePtr) node);
2485b9c547cSRui Paulo }
2495b9c547cSRui Paulo
2505b9c547cSRui Paulo
xml_node_add_child(struct xml_node_ctx * ctx,xml_node_t * parent,xml_node_t * child)2515b9c547cSRui Paulo void xml_node_add_child(struct xml_node_ctx *ctx, xml_node_t *parent,
2525b9c547cSRui Paulo xml_node_t *child)
2535b9c547cSRui Paulo {
2545b9c547cSRui Paulo xmlAddChild((xmlNodePtr) parent, (xmlNodePtr) child);
2555b9c547cSRui Paulo }
2565b9c547cSRui Paulo
2575b9c547cSRui Paulo
xml_node_create_root(struct xml_node_ctx * ctx,const char * ns_uri,const char * ns_prefix,xml_namespace_t ** ret_ns,const char * name)2585b9c547cSRui Paulo xml_node_t * xml_node_create_root(struct xml_node_ctx *ctx, const char *ns_uri,
2595b9c547cSRui Paulo const char *ns_prefix,
2605b9c547cSRui Paulo xml_namespace_t **ret_ns, const char *name)
2615b9c547cSRui Paulo {
2625b9c547cSRui Paulo xmlNodePtr node;
2635b9c547cSRui Paulo xmlNsPtr ns = NULL;
2645b9c547cSRui Paulo
2655b9c547cSRui Paulo node = xmlNewNode(NULL, (const xmlChar *) name);
2665b9c547cSRui Paulo if (node == NULL)
2675b9c547cSRui Paulo return NULL;
2685b9c547cSRui Paulo if (ns_uri) {
2695b9c547cSRui Paulo ns = xmlNewNs(node, (const xmlChar *) ns_uri,
2705b9c547cSRui Paulo (const xmlChar *) ns_prefix);
2715b9c547cSRui Paulo xmlSetNs(node, ns);
2725b9c547cSRui Paulo }
2735b9c547cSRui Paulo
2745b9c547cSRui Paulo if (ret_ns)
2755b9c547cSRui Paulo *ret_ns = (xml_namespace_t *) ns;
2765b9c547cSRui Paulo
2775b9c547cSRui Paulo return (xml_node_t *) node;
2785b9c547cSRui Paulo }
2795b9c547cSRui Paulo
2805b9c547cSRui Paulo
xml_node_create(struct xml_node_ctx * ctx,xml_node_t * parent,xml_namespace_t * ns,const char * name)2815b9c547cSRui Paulo xml_node_t * xml_node_create(struct xml_node_ctx *ctx, xml_node_t *parent,
2825b9c547cSRui Paulo xml_namespace_t *ns, const char *name)
2835b9c547cSRui Paulo {
2845b9c547cSRui Paulo xmlNodePtr node;
2855b9c547cSRui Paulo node = xmlNewChild((xmlNodePtr) parent, (xmlNsPtr) ns,
2865b9c547cSRui Paulo (const xmlChar *) name, NULL);
2875b9c547cSRui Paulo return (xml_node_t *) node;
2885b9c547cSRui Paulo }
2895b9c547cSRui Paulo
2905b9c547cSRui Paulo
xml_node_create_text(struct xml_node_ctx * ctx,xml_node_t * parent,xml_namespace_t * ns,const char * name,const char * value)2915b9c547cSRui Paulo xml_node_t * xml_node_create_text(struct xml_node_ctx *ctx,
2925b9c547cSRui Paulo xml_node_t *parent, xml_namespace_t *ns,
2935b9c547cSRui Paulo const char *name, const char *value)
2945b9c547cSRui Paulo {
2955b9c547cSRui Paulo xmlNodePtr node;
2965b9c547cSRui Paulo node = xmlNewTextChild((xmlNodePtr) parent, (xmlNsPtr) ns,
2975b9c547cSRui Paulo (const xmlChar *) name, (const xmlChar *) value);
2985b9c547cSRui Paulo return (xml_node_t *) node;
2995b9c547cSRui Paulo }
3005b9c547cSRui Paulo
3015b9c547cSRui Paulo
xml_node_create_text_ns(struct xml_node_ctx * ctx,xml_node_t * parent,const char * ns_uri,const char * name,const char * value)3025b9c547cSRui Paulo xml_node_t * xml_node_create_text_ns(struct xml_node_ctx *ctx,
3035b9c547cSRui Paulo xml_node_t *parent, const char *ns_uri,
3045b9c547cSRui Paulo const char *name, const char *value)
3055b9c547cSRui Paulo {
3065b9c547cSRui Paulo xmlNodePtr node;
3075b9c547cSRui Paulo xmlNsPtr ns;
3085b9c547cSRui Paulo
3095b9c547cSRui Paulo node = xmlNewTextChild((xmlNodePtr) parent, NULL,
3105b9c547cSRui Paulo (const xmlChar *) name, (const xmlChar *) value);
3115b9c547cSRui Paulo ns = xmlNewNs(node, (const xmlChar *) ns_uri, NULL);
3125b9c547cSRui Paulo xmlSetNs(node, ns);
3135b9c547cSRui Paulo return (xml_node_t *) node;
3145b9c547cSRui Paulo }
3155b9c547cSRui Paulo
3165b9c547cSRui Paulo
xml_node_set_text(struct xml_node_ctx * ctx,xml_node_t * node,const char * value)3175b9c547cSRui Paulo void xml_node_set_text(struct xml_node_ctx *ctx, xml_node_t *node,
3185b9c547cSRui Paulo const char *value)
3195b9c547cSRui Paulo {
3205b9c547cSRui Paulo /* TODO: escape XML special chars in value */
3215b9c547cSRui Paulo xmlNodeSetContent((xmlNodePtr) node, (xmlChar *) value);
3225b9c547cSRui Paulo }
3235b9c547cSRui Paulo
3245b9c547cSRui Paulo
xml_node_add_attr(struct xml_node_ctx * ctx,xml_node_t * node,xml_namespace_t * ns,const char * name,const char * value)3255b9c547cSRui Paulo int xml_node_add_attr(struct xml_node_ctx *ctx, xml_node_t *node,
3265b9c547cSRui Paulo xml_namespace_t *ns, const char *name, const char *value)
3275b9c547cSRui Paulo {
3285b9c547cSRui Paulo xmlAttrPtr attr;
3295b9c547cSRui Paulo
3305b9c547cSRui Paulo if (ns) {
3315b9c547cSRui Paulo attr = xmlNewNsProp((xmlNodePtr) node, (xmlNsPtr) ns,
3325b9c547cSRui Paulo (const xmlChar *) name,
3335b9c547cSRui Paulo (const xmlChar *) value);
3345b9c547cSRui Paulo } else {
3355b9c547cSRui Paulo attr = xmlNewProp((xmlNodePtr) node, (const xmlChar *) name,
3365b9c547cSRui Paulo (const xmlChar *) value);
3375b9c547cSRui Paulo }
3385b9c547cSRui Paulo
3395b9c547cSRui Paulo return attr ? 0 : -1;
3405b9c547cSRui Paulo }
3415b9c547cSRui Paulo
3425b9c547cSRui Paulo
xml_node_get_attr_value(struct xml_node_ctx * ctx,xml_node_t * node,char * name)3435b9c547cSRui Paulo char * xml_node_get_attr_value(struct xml_node_ctx *ctx, xml_node_t *node,
3445b9c547cSRui Paulo char *name)
3455b9c547cSRui Paulo {
3465b9c547cSRui Paulo return (char *) xmlGetNoNsProp((xmlNodePtr) node,
3475b9c547cSRui Paulo (const xmlChar *) name);
3485b9c547cSRui Paulo }
3495b9c547cSRui Paulo
3505b9c547cSRui Paulo
xml_node_get_attr_value_ns(struct xml_node_ctx * ctx,xml_node_t * node,const char * ns_uri,char * name)3515b9c547cSRui Paulo char * xml_node_get_attr_value_ns(struct xml_node_ctx *ctx, xml_node_t *node,
3525b9c547cSRui Paulo const char *ns_uri, char *name)
3535b9c547cSRui Paulo {
3545b9c547cSRui Paulo return (char *) xmlGetNsProp((xmlNodePtr) node, (const xmlChar *) name,
3555b9c547cSRui Paulo (const xmlChar *) ns_uri);
3565b9c547cSRui Paulo }
3575b9c547cSRui Paulo
3585b9c547cSRui Paulo
xml_node_get_attr_value_free(struct xml_node_ctx * ctx,char * val)3595b9c547cSRui Paulo void xml_node_get_attr_value_free(struct xml_node_ctx *ctx, char *val)
3605b9c547cSRui Paulo {
3615b9c547cSRui Paulo if (val)
3625b9c547cSRui Paulo xmlFree((xmlChar *) val);
3635b9c547cSRui Paulo }
3645b9c547cSRui Paulo
3655b9c547cSRui Paulo
xml_node_first_child(struct xml_node_ctx * ctx,xml_node_t * parent)3665b9c547cSRui Paulo xml_node_t * xml_node_first_child(struct xml_node_ctx *ctx,
3675b9c547cSRui Paulo xml_node_t *parent)
3685b9c547cSRui Paulo {
3695b9c547cSRui Paulo return (xml_node_t *) ((xmlNodePtr) parent)->children;
3705b9c547cSRui Paulo }
3715b9c547cSRui Paulo
3725b9c547cSRui Paulo
xml_node_next_sibling(struct xml_node_ctx * ctx,xml_node_t * node)3735b9c547cSRui Paulo xml_node_t * xml_node_next_sibling(struct xml_node_ctx *ctx,
3745b9c547cSRui Paulo xml_node_t *node)
3755b9c547cSRui Paulo {
3765b9c547cSRui Paulo return (xml_node_t *) ((xmlNodePtr) node)->next;
3775b9c547cSRui Paulo }
3785b9c547cSRui Paulo
3795b9c547cSRui Paulo
xml_node_is_element(struct xml_node_ctx * ctx,xml_node_t * node)3805b9c547cSRui Paulo int xml_node_is_element(struct xml_node_ctx *ctx, xml_node_t *node)
3815b9c547cSRui Paulo {
3825b9c547cSRui Paulo return ((xmlNodePtr) node)->type == XML_ELEMENT_NODE;
3835b9c547cSRui Paulo }
3845b9c547cSRui Paulo
3855b9c547cSRui Paulo
xml_node_get_text(struct xml_node_ctx * ctx,xml_node_t * node)3865b9c547cSRui Paulo char * xml_node_get_text(struct xml_node_ctx *ctx, xml_node_t *node)
3875b9c547cSRui Paulo {
3885b9c547cSRui Paulo if (xmlChildElementCount((xmlNodePtr) node) > 0)
3895b9c547cSRui Paulo return NULL;
3905b9c547cSRui Paulo return (char *) xmlNodeGetContent((xmlNodePtr) node);
3915b9c547cSRui Paulo }
3925b9c547cSRui Paulo
3935b9c547cSRui Paulo
xml_node_get_text_free(struct xml_node_ctx * ctx,char * val)3945b9c547cSRui Paulo void xml_node_get_text_free(struct xml_node_ctx *ctx, char *val)
3955b9c547cSRui Paulo {
3965b9c547cSRui Paulo if (val)
3975b9c547cSRui Paulo xmlFree((xmlChar *) val);
3985b9c547cSRui Paulo }
3995b9c547cSRui Paulo
4005b9c547cSRui Paulo
xml_node_get_base64_text(struct xml_node_ctx * ctx,xml_node_t * node,int * ret_len)4015b9c547cSRui Paulo char * xml_node_get_base64_text(struct xml_node_ctx *ctx, xml_node_t *node,
4025b9c547cSRui Paulo int *ret_len)
4035b9c547cSRui Paulo {
4045b9c547cSRui Paulo char *txt;
4055b9c547cSRui Paulo unsigned char *ret;
4065b9c547cSRui Paulo size_t len;
4075b9c547cSRui Paulo
4085b9c547cSRui Paulo txt = xml_node_get_text(ctx, node);
4095b9c547cSRui Paulo if (txt == NULL)
4105b9c547cSRui Paulo return NULL;
4115b9c547cSRui Paulo
412*c1d255d3SCy Schubert ret = base64_decode(txt, strlen(txt), &len);
4135b9c547cSRui Paulo if (ret_len)
4145b9c547cSRui Paulo *ret_len = len;
4155b9c547cSRui Paulo xml_node_get_text_free(ctx, txt);
4165b9c547cSRui Paulo if (ret == NULL)
4175b9c547cSRui Paulo return NULL;
4185b9c547cSRui Paulo txt = os_malloc(len + 1);
4195b9c547cSRui Paulo if (txt == NULL) {
4205b9c547cSRui Paulo os_free(ret);
4215b9c547cSRui Paulo return NULL;
4225b9c547cSRui Paulo }
4235b9c547cSRui Paulo os_memcpy(txt, ret, len);
4245b9c547cSRui Paulo txt[len] = '\0';
4255b9c547cSRui Paulo return txt;
4265b9c547cSRui Paulo }
4275b9c547cSRui Paulo
4285b9c547cSRui Paulo
xml_node_copy(struct xml_node_ctx * ctx,xml_node_t * node)4295b9c547cSRui Paulo xml_node_t * xml_node_copy(struct xml_node_ctx *ctx, xml_node_t *node)
4305b9c547cSRui Paulo {
4315b9c547cSRui Paulo if (node == NULL)
4325b9c547cSRui Paulo return NULL;
4335b9c547cSRui Paulo return (xml_node_t *) xmlCopyNode((xmlNodePtr) node, 1);
4345b9c547cSRui Paulo }
4355b9c547cSRui Paulo
4365b9c547cSRui Paulo
xml_node_init_ctx(void * upper_ctx,const void * env)4375b9c547cSRui Paulo struct xml_node_ctx * xml_node_init_ctx(void *upper_ctx,
4385b9c547cSRui Paulo const void *env)
4395b9c547cSRui Paulo {
4405b9c547cSRui Paulo struct xml_node_ctx *xctx;
4415b9c547cSRui Paulo
4425b9c547cSRui Paulo xctx = os_zalloc(sizeof(*xctx));
4435b9c547cSRui Paulo if (xctx == NULL)
4445b9c547cSRui Paulo return NULL;
4455b9c547cSRui Paulo xctx->ctx = upper_ctx;
4465b9c547cSRui Paulo
4475b9c547cSRui Paulo LIBXML_TEST_VERSION
4485b9c547cSRui Paulo
4495b9c547cSRui Paulo return xctx;
4505b9c547cSRui Paulo }
4515b9c547cSRui Paulo
4525b9c547cSRui Paulo
xml_node_deinit_ctx(struct xml_node_ctx * ctx)4535b9c547cSRui Paulo void xml_node_deinit_ctx(struct xml_node_ctx *ctx)
4545b9c547cSRui Paulo {
4555b9c547cSRui Paulo xmlSchemaCleanupTypes();
4565b9c547cSRui Paulo xmlCleanupParser();
4575b9c547cSRui Paulo xmlMemoryDump();
4585b9c547cSRui Paulo os_free(ctx);
4595b9c547cSRui Paulo }
460