15b9c547cSRui Paulo /*
25b9c547cSRui Paulo * Generic XML helper functions
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
115b9c547cSRui Paulo #include "common.h"
125b9c547cSRui Paulo #include "xml-utils.h"
135b9c547cSRui Paulo
145b9c547cSRui Paulo
get_node_uri_iter(struct xml_node_ctx * ctx,xml_node_t * root,char * uri)155b9c547cSRui Paulo static xml_node_t * get_node_uri_iter(struct xml_node_ctx *ctx,
165b9c547cSRui Paulo xml_node_t *root, char *uri)
175b9c547cSRui Paulo {
185b9c547cSRui Paulo char *end;
195b9c547cSRui Paulo xml_node_t *node;
205b9c547cSRui Paulo const char *name;
215b9c547cSRui Paulo
225b9c547cSRui Paulo end = strchr(uri, '/');
235b9c547cSRui Paulo if (end)
245b9c547cSRui Paulo *end++ = '\0';
255b9c547cSRui Paulo
265b9c547cSRui Paulo node = root;
275b9c547cSRui Paulo xml_node_for_each_sibling(ctx, node) {
285b9c547cSRui Paulo xml_node_for_each_check(ctx, node);
295b9c547cSRui Paulo name = xml_node_get_localname(ctx, node);
305b9c547cSRui Paulo if (strcasecmp(name, uri) == 0)
315b9c547cSRui Paulo break;
325b9c547cSRui Paulo }
335b9c547cSRui Paulo
345b9c547cSRui Paulo if (node == NULL)
355b9c547cSRui Paulo return NULL;
365b9c547cSRui Paulo
375b9c547cSRui Paulo if (end) {
385b9c547cSRui Paulo return get_node_uri_iter(ctx, xml_node_first_child(ctx, node),
395b9c547cSRui Paulo end);
405b9c547cSRui Paulo }
415b9c547cSRui Paulo
425b9c547cSRui Paulo return node;
435b9c547cSRui Paulo }
445b9c547cSRui Paulo
455b9c547cSRui Paulo
get_node_uri(struct xml_node_ctx * ctx,xml_node_t * root,const char * uri)465b9c547cSRui Paulo xml_node_t * get_node_uri(struct xml_node_ctx *ctx, xml_node_t *root,
475b9c547cSRui Paulo const char *uri)
485b9c547cSRui Paulo {
495b9c547cSRui Paulo char *search;
505b9c547cSRui Paulo xml_node_t *node;
515b9c547cSRui Paulo
525b9c547cSRui Paulo search = os_strdup(uri);
535b9c547cSRui Paulo if (search == NULL)
545b9c547cSRui Paulo return NULL;
555b9c547cSRui Paulo
565b9c547cSRui Paulo node = get_node_uri_iter(ctx, root, search);
575b9c547cSRui Paulo
585b9c547cSRui Paulo os_free(search);
595b9c547cSRui Paulo return node;
605b9c547cSRui Paulo }
615b9c547cSRui Paulo
625b9c547cSRui Paulo
get_node_iter(struct xml_node_ctx * ctx,xml_node_t * root,const char * path)635b9c547cSRui Paulo static xml_node_t * get_node_iter(struct xml_node_ctx *ctx,
645b9c547cSRui Paulo xml_node_t *root, const char *path)
655b9c547cSRui Paulo {
665b9c547cSRui Paulo char *end;
675b9c547cSRui Paulo xml_node_t *node;
685b9c547cSRui Paulo const char *name;
695b9c547cSRui Paulo
705b9c547cSRui Paulo end = os_strchr(path, '/');
715b9c547cSRui Paulo if (end)
725b9c547cSRui Paulo *end++ = '\0';
735b9c547cSRui Paulo
745b9c547cSRui Paulo xml_node_for_each_child(ctx, node, root) {
755b9c547cSRui Paulo xml_node_for_each_check(ctx, node);
765b9c547cSRui Paulo name = xml_node_get_localname(ctx, node);
775b9c547cSRui Paulo if (os_strcasecmp(name, path) == 0)
785b9c547cSRui Paulo break;
795b9c547cSRui Paulo }
805b9c547cSRui Paulo
815b9c547cSRui Paulo if (node == NULL)
825b9c547cSRui Paulo return NULL;
835b9c547cSRui Paulo if (end)
845b9c547cSRui Paulo return get_node_iter(ctx, node, end);
855b9c547cSRui Paulo return node;
865b9c547cSRui Paulo }
875b9c547cSRui Paulo
885b9c547cSRui Paulo
get_node(struct xml_node_ctx * ctx,xml_node_t * root,const char * path)895b9c547cSRui Paulo xml_node_t * get_node(struct xml_node_ctx *ctx, xml_node_t *root,
905b9c547cSRui Paulo const char *path)
915b9c547cSRui Paulo {
925b9c547cSRui Paulo char *search;
935b9c547cSRui Paulo xml_node_t *node;
945b9c547cSRui Paulo
955b9c547cSRui Paulo search = os_strdup(path);
965b9c547cSRui Paulo if (search == NULL)
975b9c547cSRui Paulo return NULL;
985b9c547cSRui Paulo
995b9c547cSRui Paulo node = get_node_iter(ctx, root, search);
1005b9c547cSRui Paulo
1015b9c547cSRui Paulo os_free(search);
1025b9c547cSRui Paulo return node;
1035b9c547cSRui Paulo }
1045b9c547cSRui Paulo
1055b9c547cSRui Paulo
get_child_node(struct xml_node_ctx * ctx,xml_node_t * root,const char * path)1065b9c547cSRui Paulo xml_node_t * get_child_node(struct xml_node_ctx *ctx, xml_node_t *root,
1075b9c547cSRui Paulo const char *path)
1085b9c547cSRui Paulo {
1095b9c547cSRui Paulo xml_node_t *node;
1105b9c547cSRui Paulo xml_node_t *match;
1115b9c547cSRui Paulo
1125b9c547cSRui Paulo xml_node_for_each_child(ctx, node, root) {
1135b9c547cSRui Paulo xml_node_for_each_check(ctx, node);
1145b9c547cSRui Paulo match = get_node(ctx, node, path);
1155b9c547cSRui Paulo if (match)
1165b9c547cSRui Paulo return match;
1175b9c547cSRui Paulo }
1185b9c547cSRui Paulo
1195b9c547cSRui Paulo return NULL;
1205b9c547cSRui Paulo }
1215b9c547cSRui Paulo
1225b9c547cSRui Paulo
node_from_file(struct xml_node_ctx * ctx,const char * name)1235b9c547cSRui Paulo xml_node_t * node_from_file(struct xml_node_ctx *ctx, const char *name)
1245b9c547cSRui Paulo {
1255b9c547cSRui Paulo xml_node_t *node;
1265b9c547cSRui Paulo char *buf, *buf2, *start;
1275b9c547cSRui Paulo size_t len;
1285b9c547cSRui Paulo
1295b9c547cSRui Paulo buf = os_readfile(name, &len);
1305b9c547cSRui Paulo if (buf == NULL)
1315b9c547cSRui Paulo return NULL;
1325b9c547cSRui Paulo buf2 = os_realloc(buf, len + 1);
1335b9c547cSRui Paulo if (buf2 == NULL) {
1345b9c547cSRui Paulo os_free(buf);
1355b9c547cSRui Paulo return NULL;
1365b9c547cSRui Paulo }
1375b9c547cSRui Paulo buf = buf2;
1385b9c547cSRui Paulo buf[len] = '\0';
1395b9c547cSRui Paulo
1405b9c547cSRui Paulo start = os_strstr(buf, "<!DOCTYPE ");
1415b9c547cSRui Paulo if (start) {
1425b9c547cSRui Paulo char *pos = start + 1;
1435b9c547cSRui Paulo int count = 1;
1445b9c547cSRui Paulo while (*pos) {
1455b9c547cSRui Paulo if (*pos == '<')
1465b9c547cSRui Paulo count++;
1475b9c547cSRui Paulo else if (*pos == '>') {
1485b9c547cSRui Paulo count--;
1495b9c547cSRui Paulo if (count == 0) {
1505b9c547cSRui Paulo pos++;
1515b9c547cSRui Paulo break;
1525b9c547cSRui Paulo }
1535b9c547cSRui Paulo }
1545b9c547cSRui Paulo pos++;
1555b9c547cSRui Paulo }
1565b9c547cSRui Paulo if (count == 0) {
1575b9c547cSRui Paulo /* Remove DOCTYPE to allow the file to be parsed */
1585b9c547cSRui Paulo os_memset(start, ' ', pos - start);
1595b9c547cSRui Paulo }
1605b9c547cSRui Paulo }
1615b9c547cSRui Paulo
1625b9c547cSRui Paulo node = xml_node_from_buf(ctx, buf);
1635b9c547cSRui Paulo os_free(buf);
1645b9c547cSRui Paulo
1655b9c547cSRui Paulo return node;
1665b9c547cSRui Paulo }
1675b9c547cSRui Paulo
1685b9c547cSRui Paulo
node_to_file(struct xml_node_ctx * ctx,const char * fname,xml_node_t * node)1695b9c547cSRui Paulo int node_to_file(struct xml_node_ctx *ctx, const char *fname, xml_node_t *node)
1705b9c547cSRui Paulo {
1715b9c547cSRui Paulo FILE *f;
1725b9c547cSRui Paulo char *str;
1735b9c547cSRui Paulo
1745b9c547cSRui Paulo str = xml_node_to_str(ctx, node);
1755b9c547cSRui Paulo if (str == NULL)
1765b9c547cSRui Paulo return -1;
1775b9c547cSRui Paulo
1785b9c547cSRui Paulo f = fopen(fname, "w");
1795b9c547cSRui Paulo if (!f) {
1805b9c547cSRui Paulo os_free(str);
1815b9c547cSRui Paulo return -1;
1825b9c547cSRui Paulo }
1835b9c547cSRui Paulo
1845b9c547cSRui Paulo fprintf(f, "%s\n", str);
1855b9c547cSRui Paulo os_free(str);
1865b9c547cSRui Paulo fclose(f);
1875b9c547cSRui Paulo
1885b9c547cSRui Paulo return 0;
1895b9c547cSRui Paulo }
1905b9c547cSRui Paulo
1915b9c547cSRui Paulo
get_val(struct xml_node_ctx * ctx,xml_node_t * node)1925b9c547cSRui Paulo static char * get_val(struct xml_node_ctx *ctx, xml_node_t *node)
1935b9c547cSRui Paulo {
1945b9c547cSRui Paulo char *val, *pos;
1955b9c547cSRui Paulo
1965b9c547cSRui Paulo val = xml_node_get_text(ctx, node);
1975b9c547cSRui Paulo if (val == NULL)
1985b9c547cSRui Paulo return NULL;
1995b9c547cSRui Paulo pos = val;
2005b9c547cSRui Paulo while (*pos) {
2015b9c547cSRui Paulo if (*pos != ' ' && *pos != '\t' && *pos != '\r' && *pos != '\n')
2025b9c547cSRui Paulo return val;
2035b9c547cSRui Paulo pos++;
2045b9c547cSRui Paulo }
2055b9c547cSRui Paulo
2065b9c547cSRui Paulo return NULL;
2075b9c547cSRui Paulo }
2085b9c547cSRui Paulo
2095b9c547cSRui Paulo
add_path(const char * prev,const char * leaf)2105b9c547cSRui Paulo static char * add_path(const char *prev, const char *leaf)
2115b9c547cSRui Paulo {
2125b9c547cSRui Paulo size_t len;
2135b9c547cSRui Paulo char *new_uri;
2145b9c547cSRui Paulo
2155b9c547cSRui Paulo if (prev == NULL)
2165b9c547cSRui Paulo return NULL;
2175b9c547cSRui Paulo
2185b9c547cSRui Paulo len = os_strlen(prev) + 1 + os_strlen(leaf) + 1;
2195b9c547cSRui Paulo new_uri = os_malloc(len);
2205b9c547cSRui Paulo if (new_uri)
2215b9c547cSRui Paulo os_snprintf(new_uri, len, "%s/%s", prev, leaf);
2225b9c547cSRui Paulo
2235b9c547cSRui Paulo return new_uri;
2245b9c547cSRui Paulo }
2255b9c547cSRui Paulo
2265b9c547cSRui Paulo
node_to_tnds(struct xml_node_ctx * ctx,xml_node_t * out,xml_node_t * in,const char * uri)2275b9c547cSRui Paulo static void node_to_tnds(struct xml_node_ctx *ctx, xml_node_t *out,
2285b9c547cSRui Paulo xml_node_t *in, const char *uri)
2295b9c547cSRui Paulo {
2305b9c547cSRui Paulo xml_node_t *node;
2315b9c547cSRui Paulo xml_node_t *tnds;
2325b9c547cSRui Paulo const char *name;
2335b9c547cSRui Paulo char *val;
2345b9c547cSRui Paulo char *new_uri;
2355b9c547cSRui Paulo
2365b9c547cSRui Paulo xml_node_for_each_child(ctx, node, in) {
2375b9c547cSRui Paulo xml_node_for_each_check(ctx, node);
2385b9c547cSRui Paulo name = xml_node_get_localname(ctx, node);
2395b9c547cSRui Paulo
2405b9c547cSRui Paulo tnds = xml_node_create(ctx, out, NULL, "Node");
2415b9c547cSRui Paulo if (tnds == NULL)
2425b9c547cSRui Paulo return;
2435b9c547cSRui Paulo xml_node_create_text(ctx, tnds, NULL, "NodeName", name);
2445b9c547cSRui Paulo
2455b9c547cSRui Paulo if (uri)
2465b9c547cSRui Paulo xml_node_create_text(ctx, tnds, NULL, "Path", uri);
2475b9c547cSRui Paulo
2485b9c547cSRui Paulo val = get_val(ctx, node);
249*85732ac8SCy Schubert if (val || !xml_node_first_child(ctx, node))
250*85732ac8SCy Schubert xml_node_create_text(ctx, tnds, NULL, "Value",
251*85732ac8SCy Schubert val ? val : "");
2525b9c547cSRui Paulo xml_node_get_text_free(ctx, val);
2535b9c547cSRui Paulo
2545b9c547cSRui Paulo new_uri = add_path(uri, name);
2555b9c547cSRui Paulo node_to_tnds(ctx, new_uri ? out : tnds, node, new_uri);
2565b9c547cSRui Paulo os_free(new_uri);
2575b9c547cSRui Paulo }
2585b9c547cSRui Paulo }
2595b9c547cSRui Paulo
2605b9c547cSRui Paulo
add_ddfname(struct xml_node_ctx * ctx,xml_node_t * parent,const char * urn)2615b9c547cSRui Paulo static int add_ddfname(struct xml_node_ctx *ctx, xml_node_t *parent,
2625b9c547cSRui Paulo const char *urn)
2635b9c547cSRui Paulo {
2645b9c547cSRui Paulo xml_node_t *node;
2655b9c547cSRui Paulo
2665b9c547cSRui Paulo node = xml_node_create(ctx, parent, NULL, "RTProperties");
2675b9c547cSRui Paulo if (node == NULL)
2685b9c547cSRui Paulo return -1;
2695b9c547cSRui Paulo node = xml_node_create(ctx, node, NULL, "Type");
2705b9c547cSRui Paulo if (node == NULL)
2715b9c547cSRui Paulo return -1;
2725b9c547cSRui Paulo xml_node_create_text(ctx, node, NULL, "DDFName", urn);
2735b9c547cSRui Paulo return 0;
2745b9c547cSRui Paulo }
2755b9c547cSRui Paulo
2765b9c547cSRui Paulo
mo_to_tnds(struct xml_node_ctx * ctx,xml_node_t * mo,int use_path,const char * urn,const char * ns_uri)2775b9c547cSRui Paulo xml_node_t * mo_to_tnds(struct xml_node_ctx *ctx, xml_node_t *mo,
2785b9c547cSRui Paulo int use_path, const char *urn, const char *ns_uri)
2795b9c547cSRui Paulo {
2805b9c547cSRui Paulo xml_node_t *root;
2815b9c547cSRui Paulo xml_node_t *node;
2825b9c547cSRui Paulo const char *name;
2835b9c547cSRui Paulo
2845b9c547cSRui Paulo root = xml_node_create_root(ctx, ns_uri, NULL, NULL, "MgmtTree");
2855b9c547cSRui Paulo if (root == NULL)
2865b9c547cSRui Paulo return NULL;
2875b9c547cSRui Paulo
2885b9c547cSRui Paulo xml_node_create_text(ctx, root, NULL, "VerDTD", "1.2");
2895b9c547cSRui Paulo
2905b9c547cSRui Paulo name = xml_node_get_localname(ctx, mo);
2915b9c547cSRui Paulo
2925b9c547cSRui Paulo node = xml_node_create(ctx, root, NULL, "Node");
2935b9c547cSRui Paulo if (node == NULL)
2945b9c547cSRui Paulo goto fail;
2955b9c547cSRui Paulo xml_node_create_text(ctx, node, NULL, "NodeName", name);
2965b9c547cSRui Paulo if (urn)
2975b9c547cSRui Paulo add_ddfname(ctx, node, urn);
2985b9c547cSRui Paulo
2995b9c547cSRui Paulo node_to_tnds(ctx, use_path ? root : node, mo, use_path ? name : NULL);
3005b9c547cSRui Paulo
3015b9c547cSRui Paulo return root;
3025b9c547cSRui Paulo
3035b9c547cSRui Paulo fail:
3045b9c547cSRui Paulo xml_node_free(ctx, root);
3055b9c547cSRui Paulo return NULL;
3065b9c547cSRui Paulo }
3075b9c547cSRui Paulo
3085b9c547cSRui Paulo
get_first_child_node(struct xml_node_ctx * ctx,xml_node_t * node,const char * name)3095b9c547cSRui Paulo static xml_node_t * get_first_child_node(struct xml_node_ctx *ctx,
3105b9c547cSRui Paulo xml_node_t *node,
3115b9c547cSRui Paulo const char *name)
3125b9c547cSRui Paulo {
3135b9c547cSRui Paulo const char *lname;
3145b9c547cSRui Paulo xml_node_t *child;
3155b9c547cSRui Paulo
3165b9c547cSRui Paulo xml_node_for_each_child(ctx, child, node) {
3175b9c547cSRui Paulo xml_node_for_each_check(ctx, child);
3185b9c547cSRui Paulo lname = xml_node_get_localname(ctx, child);
3195b9c547cSRui Paulo if (os_strcasecmp(lname, name) == 0)
3205b9c547cSRui Paulo return child;
3215b9c547cSRui Paulo }
3225b9c547cSRui Paulo
3235b9c547cSRui Paulo return NULL;
3245b9c547cSRui Paulo }
3255b9c547cSRui Paulo
3265b9c547cSRui Paulo
get_node_text(struct xml_node_ctx * ctx,xml_node_t * node,const char * node_name)3275b9c547cSRui Paulo static char * get_node_text(struct xml_node_ctx *ctx, xml_node_t *node,
3285b9c547cSRui Paulo const char *node_name)
3295b9c547cSRui Paulo {
3305b9c547cSRui Paulo node = get_first_child_node(ctx, node, node_name);
3315b9c547cSRui Paulo if (node == NULL)
3325b9c547cSRui Paulo return NULL;
3335b9c547cSRui Paulo return xml_node_get_text(ctx, node);
3345b9c547cSRui Paulo }
3355b9c547cSRui Paulo
3365b9c547cSRui Paulo
add_mo_node(struct xml_node_ctx * ctx,xml_node_t * root,xml_node_t * node,const char * uri)3375b9c547cSRui Paulo static xml_node_t * add_mo_node(struct xml_node_ctx *ctx, xml_node_t *root,
3385b9c547cSRui Paulo xml_node_t *node, const char *uri)
3395b9c547cSRui Paulo {
3405b9c547cSRui Paulo char *nodename, *value, *path;
3415b9c547cSRui Paulo xml_node_t *parent;
3425b9c547cSRui Paulo
3435b9c547cSRui Paulo nodename = get_node_text(ctx, node, "NodeName");
3445b9c547cSRui Paulo if (nodename == NULL)
3455b9c547cSRui Paulo return NULL;
3465b9c547cSRui Paulo value = get_node_text(ctx, node, "Value");
3475b9c547cSRui Paulo
3485b9c547cSRui Paulo if (root == NULL) {
3495b9c547cSRui Paulo root = xml_node_create_root(ctx, NULL, NULL, NULL,
3505b9c547cSRui Paulo nodename);
3515b9c547cSRui Paulo if (root && value)
3525b9c547cSRui Paulo xml_node_set_text(ctx, root, value);
3535b9c547cSRui Paulo } else {
3545b9c547cSRui Paulo if (uri == NULL) {
3555b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename);
3565b9c547cSRui Paulo xml_node_get_text_free(ctx, value);
3575b9c547cSRui Paulo return NULL;
3585b9c547cSRui Paulo }
3595b9c547cSRui Paulo path = get_node_text(ctx, node, "Path");
3605b9c547cSRui Paulo if (path)
3615b9c547cSRui Paulo uri = path;
3625b9c547cSRui Paulo parent = get_node_uri(ctx, root, uri);
3635b9c547cSRui Paulo xml_node_get_text_free(ctx, path);
3645b9c547cSRui Paulo if (parent == NULL) {
3655b9c547cSRui Paulo printf("Could not find URI '%s'\n", uri);
3665b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename);
3675b9c547cSRui Paulo xml_node_get_text_free(ctx, value);
3685b9c547cSRui Paulo return NULL;
3695b9c547cSRui Paulo }
3705b9c547cSRui Paulo if (value)
3715b9c547cSRui Paulo xml_node_create_text(ctx, parent, NULL, nodename,
3725b9c547cSRui Paulo value);
3735b9c547cSRui Paulo else
3745b9c547cSRui Paulo xml_node_create(ctx, parent, NULL, nodename);
3755b9c547cSRui Paulo }
3765b9c547cSRui Paulo
3775b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename);
3785b9c547cSRui Paulo xml_node_get_text_free(ctx, value);
3795b9c547cSRui Paulo
3805b9c547cSRui Paulo return root;
3815b9c547cSRui Paulo }
3825b9c547cSRui Paulo
3835b9c547cSRui Paulo
tnds_to_mo_iter(struct xml_node_ctx * ctx,xml_node_t * root,xml_node_t * node,const char * uri)3845b9c547cSRui Paulo static xml_node_t * tnds_to_mo_iter(struct xml_node_ctx *ctx, xml_node_t *root,
3855b9c547cSRui Paulo xml_node_t *node, const char *uri)
3865b9c547cSRui Paulo {
3875b9c547cSRui Paulo xml_node_t *child;
3885b9c547cSRui Paulo const char *name;
3895b9c547cSRui Paulo char *nodename;
3905b9c547cSRui Paulo
3915b9c547cSRui Paulo xml_node_for_each_sibling(ctx, node) {
3925b9c547cSRui Paulo xml_node_for_each_check(ctx, node);
3935b9c547cSRui Paulo
3945b9c547cSRui Paulo nodename = get_node_text(ctx, node, "NodeName");
3955b9c547cSRui Paulo if (nodename == NULL)
3965b9c547cSRui Paulo return NULL;
3975b9c547cSRui Paulo
3985b9c547cSRui Paulo name = xml_node_get_localname(ctx, node);
3995b9c547cSRui Paulo if (strcmp(name, "Node") == 0) {
4005b9c547cSRui Paulo if (root && !uri) {
4015b9c547cSRui Paulo printf("Invalid TNDS tree structure - "
4025b9c547cSRui Paulo "multiple top level nodes\n");
4035b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename);
4045b9c547cSRui Paulo return NULL;
4055b9c547cSRui Paulo }
4065b9c547cSRui Paulo root = add_mo_node(ctx, root, node, uri);
4075b9c547cSRui Paulo }
4085b9c547cSRui Paulo
4095b9c547cSRui Paulo child = get_first_child_node(ctx, node, "Node");
4105b9c547cSRui Paulo if (child) {
4115b9c547cSRui Paulo if (uri == NULL)
4125b9c547cSRui Paulo tnds_to_mo_iter(ctx, root, child, nodename);
4135b9c547cSRui Paulo else {
4145b9c547cSRui Paulo char *new_uri;
4155b9c547cSRui Paulo new_uri = add_path(uri, nodename);
4165b9c547cSRui Paulo tnds_to_mo_iter(ctx, root, child, new_uri);
4175b9c547cSRui Paulo os_free(new_uri);
4185b9c547cSRui Paulo }
4195b9c547cSRui Paulo }
4205b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename);
4215b9c547cSRui Paulo }
4225b9c547cSRui Paulo
4235b9c547cSRui Paulo return root;
4245b9c547cSRui Paulo }
4255b9c547cSRui Paulo
4265b9c547cSRui Paulo
tnds_to_mo(struct xml_node_ctx * ctx,xml_node_t * tnds)4275b9c547cSRui Paulo xml_node_t * tnds_to_mo(struct xml_node_ctx *ctx, xml_node_t *tnds)
4285b9c547cSRui Paulo {
4295b9c547cSRui Paulo const char *name;
4305b9c547cSRui Paulo xml_node_t *node;
4315b9c547cSRui Paulo
4325b9c547cSRui Paulo name = xml_node_get_localname(ctx, tnds);
4335b9c547cSRui Paulo if (name == NULL || os_strcmp(name, "MgmtTree") != 0)
4345b9c547cSRui Paulo return NULL;
4355b9c547cSRui Paulo
4365b9c547cSRui Paulo node = get_first_child_node(ctx, tnds, "Node");
4375b9c547cSRui Paulo if (!node)
4385b9c547cSRui Paulo return NULL;
4395b9c547cSRui Paulo return tnds_to_mo_iter(ctx, NULL, node, NULL);
4405b9c547cSRui Paulo }
4415b9c547cSRui Paulo
4425b9c547cSRui Paulo
soap_build_envelope(struct xml_node_ctx * ctx,xml_node_t * node)4435b9c547cSRui Paulo xml_node_t * soap_build_envelope(struct xml_node_ctx *ctx, xml_node_t *node)
4445b9c547cSRui Paulo {
4455b9c547cSRui Paulo xml_node_t *envelope, *body;
4465b9c547cSRui Paulo xml_namespace_t *ns;
4475b9c547cSRui Paulo
4485b9c547cSRui Paulo envelope = xml_node_create_root(
4495b9c547cSRui Paulo ctx, "http://www.w3.org/2003/05/soap-envelope", "soap12", &ns,
4505b9c547cSRui Paulo "Envelope");
4515b9c547cSRui Paulo if (envelope == NULL)
4525b9c547cSRui Paulo return NULL;
4535b9c547cSRui Paulo body = xml_node_create(ctx, envelope, ns, "Body");
4545b9c547cSRui Paulo xml_node_add_child(ctx, body, node);
4555b9c547cSRui Paulo return envelope;
4565b9c547cSRui Paulo }
4575b9c547cSRui Paulo
4585b9c547cSRui Paulo
soap_get_body(struct xml_node_ctx * ctx,xml_node_t * soap)4595b9c547cSRui Paulo xml_node_t * soap_get_body(struct xml_node_ctx *ctx, xml_node_t *soap)
4605b9c547cSRui Paulo {
4615b9c547cSRui Paulo xml_node_t *body, *child;
4625b9c547cSRui Paulo
4635b9c547cSRui Paulo body = get_node_uri(ctx, soap, "Envelope/Body");
4645b9c547cSRui Paulo if (body == NULL)
4655b9c547cSRui Paulo return NULL;
4665b9c547cSRui Paulo xml_node_for_each_child(ctx, child, body) {
4675b9c547cSRui Paulo xml_node_for_each_check(ctx, child);
4685b9c547cSRui Paulo return child;
4695b9c547cSRui Paulo }
4705b9c547cSRui Paulo return NULL;
4715b9c547cSRui Paulo }
472