1*5b9c547cSRui Paulo /* 2*5b9c547cSRui Paulo * Generic XML helper functions 3*5b9c547cSRui Paulo * Copyright (c) 2012-2013, Qualcomm Atheros, Inc. 4*5b9c547cSRui Paulo * 5*5b9c547cSRui Paulo * This software may be distributed under the terms of the BSD license. 6*5b9c547cSRui Paulo * See README for more details. 7*5b9c547cSRui Paulo */ 8*5b9c547cSRui Paulo 9*5b9c547cSRui Paulo #include "includes.h" 10*5b9c547cSRui Paulo 11*5b9c547cSRui Paulo #include "common.h" 12*5b9c547cSRui Paulo #include "xml-utils.h" 13*5b9c547cSRui Paulo 14*5b9c547cSRui Paulo 15*5b9c547cSRui Paulo static xml_node_t * get_node_uri_iter(struct xml_node_ctx *ctx, 16*5b9c547cSRui Paulo xml_node_t *root, char *uri) 17*5b9c547cSRui Paulo { 18*5b9c547cSRui Paulo char *end; 19*5b9c547cSRui Paulo xml_node_t *node; 20*5b9c547cSRui Paulo const char *name; 21*5b9c547cSRui Paulo 22*5b9c547cSRui Paulo end = strchr(uri, '/'); 23*5b9c547cSRui Paulo if (end) 24*5b9c547cSRui Paulo *end++ = '\0'; 25*5b9c547cSRui Paulo 26*5b9c547cSRui Paulo node = root; 27*5b9c547cSRui Paulo xml_node_for_each_sibling(ctx, node) { 28*5b9c547cSRui Paulo xml_node_for_each_check(ctx, node); 29*5b9c547cSRui Paulo name = xml_node_get_localname(ctx, node); 30*5b9c547cSRui Paulo if (strcasecmp(name, uri) == 0) 31*5b9c547cSRui Paulo break; 32*5b9c547cSRui Paulo } 33*5b9c547cSRui Paulo 34*5b9c547cSRui Paulo if (node == NULL) 35*5b9c547cSRui Paulo return NULL; 36*5b9c547cSRui Paulo 37*5b9c547cSRui Paulo if (end) { 38*5b9c547cSRui Paulo return get_node_uri_iter(ctx, xml_node_first_child(ctx, node), 39*5b9c547cSRui Paulo end); 40*5b9c547cSRui Paulo } 41*5b9c547cSRui Paulo 42*5b9c547cSRui Paulo return node; 43*5b9c547cSRui Paulo } 44*5b9c547cSRui Paulo 45*5b9c547cSRui Paulo 46*5b9c547cSRui Paulo xml_node_t * get_node_uri(struct xml_node_ctx *ctx, xml_node_t *root, 47*5b9c547cSRui Paulo const char *uri) 48*5b9c547cSRui Paulo { 49*5b9c547cSRui Paulo char *search; 50*5b9c547cSRui Paulo xml_node_t *node; 51*5b9c547cSRui Paulo 52*5b9c547cSRui Paulo search = os_strdup(uri); 53*5b9c547cSRui Paulo if (search == NULL) 54*5b9c547cSRui Paulo return NULL; 55*5b9c547cSRui Paulo 56*5b9c547cSRui Paulo node = get_node_uri_iter(ctx, root, search); 57*5b9c547cSRui Paulo 58*5b9c547cSRui Paulo os_free(search); 59*5b9c547cSRui Paulo return node; 60*5b9c547cSRui Paulo } 61*5b9c547cSRui Paulo 62*5b9c547cSRui Paulo 63*5b9c547cSRui Paulo static xml_node_t * get_node_iter(struct xml_node_ctx *ctx, 64*5b9c547cSRui Paulo xml_node_t *root, const char *path) 65*5b9c547cSRui Paulo { 66*5b9c547cSRui Paulo char *end; 67*5b9c547cSRui Paulo xml_node_t *node; 68*5b9c547cSRui Paulo const char *name; 69*5b9c547cSRui Paulo 70*5b9c547cSRui Paulo end = os_strchr(path, '/'); 71*5b9c547cSRui Paulo if (end) 72*5b9c547cSRui Paulo *end++ = '\0'; 73*5b9c547cSRui Paulo 74*5b9c547cSRui Paulo xml_node_for_each_child(ctx, node, root) { 75*5b9c547cSRui Paulo xml_node_for_each_check(ctx, node); 76*5b9c547cSRui Paulo name = xml_node_get_localname(ctx, node); 77*5b9c547cSRui Paulo if (os_strcasecmp(name, path) == 0) 78*5b9c547cSRui Paulo break; 79*5b9c547cSRui Paulo } 80*5b9c547cSRui Paulo 81*5b9c547cSRui Paulo if (node == NULL) 82*5b9c547cSRui Paulo return NULL; 83*5b9c547cSRui Paulo if (end) 84*5b9c547cSRui Paulo return get_node_iter(ctx, node, end); 85*5b9c547cSRui Paulo return node; 86*5b9c547cSRui Paulo } 87*5b9c547cSRui Paulo 88*5b9c547cSRui Paulo 89*5b9c547cSRui Paulo xml_node_t * get_node(struct xml_node_ctx *ctx, xml_node_t *root, 90*5b9c547cSRui Paulo const char *path) 91*5b9c547cSRui Paulo { 92*5b9c547cSRui Paulo char *search; 93*5b9c547cSRui Paulo xml_node_t *node; 94*5b9c547cSRui Paulo 95*5b9c547cSRui Paulo search = os_strdup(path); 96*5b9c547cSRui Paulo if (search == NULL) 97*5b9c547cSRui Paulo return NULL; 98*5b9c547cSRui Paulo 99*5b9c547cSRui Paulo node = get_node_iter(ctx, root, search); 100*5b9c547cSRui Paulo 101*5b9c547cSRui Paulo os_free(search); 102*5b9c547cSRui Paulo return node; 103*5b9c547cSRui Paulo } 104*5b9c547cSRui Paulo 105*5b9c547cSRui Paulo 106*5b9c547cSRui Paulo xml_node_t * get_child_node(struct xml_node_ctx *ctx, xml_node_t *root, 107*5b9c547cSRui Paulo const char *path) 108*5b9c547cSRui Paulo { 109*5b9c547cSRui Paulo xml_node_t *node; 110*5b9c547cSRui Paulo xml_node_t *match; 111*5b9c547cSRui Paulo 112*5b9c547cSRui Paulo xml_node_for_each_child(ctx, node, root) { 113*5b9c547cSRui Paulo xml_node_for_each_check(ctx, node); 114*5b9c547cSRui Paulo match = get_node(ctx, node, path); 115*5b9c547cSRui Paulo if (match) 116*5b9c547cSRui Paulo return match; 117*5b9c547cSRui Paulo } 118*5b9c547cSRui Paulo 119*5b9c547cSRui Paulo return NULL; 120*5b9c547cSRui Paulo } 121*5b9c547cSRui Paulo 122*5b9c547cSRui Paulo 123*5b9c547cSRui Paulo xml_node_t * node_from_file(struct xml_node_ctx *ctx, const char *name) 124*5b9c547cSRui Paulo { 125*5b9c547cSRui Paulo xml_node_t *node; 126*5b9c547cSRui Paulo char *buf, *buf2, *start; 127*5b9c547cSRui Paulo size_t len; 128*5b9c547cSRui Paulo 129*5b9c547cSRui Paulo buf = os_readfile(name, &len); 130*5b9c547cSRui Paulo if (buf == NULL) 131*5b9c547cSRui Paulo return NULL; 132*5b9c547cSRui Paulo buf2 = os_realloc(buf, len + 1); 133*5b9c547cSRui Paulo if (buf2 == NULL) { 134*5b9c547cSRui Paulo os_free(buf); 135*5b9c547cSRui Paulo return NULL; 136*5b9c547cSRui Paulo } 137*5b9c547cSRui Paulo buf = buf2; 138*5b9c547cSRui Paulo buf[len] = '\0'; 139*5b9c547cSRui Paulo 140*5b9c547cSRui Paulo start = os_strstr(buf, "<!DOCTYPE "); 141*5b9c547cSRui Paulo if (start) { 142*5b9c547cSRui Paulo char *pos = start + 1; 143*5b9c547cSRui Paulo int count = 1; 144*5b9c547cSRui Paulo while (*pos) { 145*5b9c547cSRui Paulo if (*pos == '<') 146*5b9c547cSRui Paulo count++; 147*5b9c547cSRui Paulo else if (*pos == '>') { 148*5b9c547cSRui Paulo count--; 149*5b9c547cSRui Paulo if (count == 0) { 150*5b9c547cSRui Paulo pos++; 151*5b9c547cSRui Paulo break; 152*5b9c547cSRui Paulo } 153*5b9c547cSRui Paulo } 154*5b9c547cSRui Paulo pos++; 155*5b9c547cSRui Paulo } 156*5b9c547cSRui Paulo if (count == 0) { 157*5b9c547cSRui Paulo /* Remove DOCTYPE to allow the file to be parsed */ 158*5b9c547cSRui Paulo os_memset(start, ' ', pos - start); 159*5b9c547cSRui Paulo } 160*5b9c547cSRui Paulo } 161*5b9c547cSRui Paulo 162*5b9c547cSRui Paulo node = xml_node_from_buf(ctx, buf); 163*5b9c547cSRui Paulo os_free(buf); 164*5b9c547cSRui Paulo 165*5b9c547cSRui Paulo return node; 166*5b9c547cSRui Paulo } 167*5b9c547cSRui Paulo 168*5b9c547cSRui Paulo 169*5b9c547cSRui Paulo int node_to_file(struct xml_node_ctx *ctx, const char *fname, xml_node_t *node) 170*5b9c547cSRui Paulo { 171*5b9c547cSRui Paulo FILE *f; 172*5b9c547cSRui Paulo char *str; 173*5b9c547cSRui Paulo 174*5b9c547cSRui Paulo str = xml_node_to_str(ctx, node); 175*5b9c547cSRui Paulo if (str == NULL) 176*5b9c547cSRui Paulo return -1; 177*5b9c547cSRui Paulo 178*5b9c547cSRui Paulo f = fopen(fname, "w"); 179*5b9c547cSRui Paulo if (!f) { 180*5b9c547cSRui Paulo os_free(str); 181*5b9c547cSRui Paulo return -1; 182*5b9c547cSRui Paulo } 183*5b9c547cSRui Paulo 184*5b9c547cSRui Paulo fprintf(f, "%s\n", str); 185*5b9c547cSRui Paulo os_free(str); 186*5b9c547cSRui Paulo fclose(f); 187*5b9c547cSRui Paulo 188*5b9c547cSRui Paulo return 0; 189*5b9c547cSRui Paulo } 190*5b9c547cSRui Paulo 191*5b9c547cSRui Paulo 192*5b9c547cSRui Paulo static char * get_val(struct xml_node_ctx *ctx, xml_node_t *node) 193*5b9c547cSRui Paulo { 194*5b9c547cSRui Paulo char *val, *pos; 195*5b9c547cSRui Paulo 196*5b9c547cSRui Paulo val = xml_node_get_text(ctx, node); 197*5b9c547cSRui Paulo if (val == NULL) 198*5b9c547cSRui Paulo return NULL; 199*5b9c547cSRui Paulo pos = val; 200*5b9c547cSRui Paulo while (*pos) { 201*5b9c547cSRui Paulo if (*pos != ' ' && *pos != '\t' && *pos != '\r' && *pos != '\n') 202*5b9c547cSRui Paulo return val; 203*5b9c547cSRui Paulo pos++; 204*5b9c547cSRui Paulo } 205*5b9c547cSRui Paulo 206*5b9c547cSRui Paulo return NULL; 207*5b9c547cSRui Paulo } 208*5b9c547cSRui Paulo 209*5b9c547cSRui Paulo 210*5b9c547cSRui Paulo static char * add_path(const char *prev, const char *leaf) 211*5b9c547cSRui Paulo { 212*5b9c547cSRui Paulo size_t len; 213*5b9c547cSRui Paulo char *new_uri; 214*5b9c547cSRui Paulo 215*5b9c547cSRui Paulo if (prev == NULL) 216*5b9c547cSRui Paulo return NULL; 217*5b9c547cSRui Paulo 218*5b9c547cSRui Paulo len = os_strlen(prev) + 1 + os_strlen(leaf) + 1; 219*5b9c547cSRui Paulo new_uri = os_malloc(len); 220*5b9c547cSRui Paulo if (new_uri) 221*5b9c547cSRui Paulo os_snprintf(new_uri, len, "%s/%s", prev, leaf); 222*5b9c547cSRui Paulo 223*5b9c547cSRui Paulo return new_uri; 224*5b9c547cSRui Paulo } 225*5b9c547cSRui Paulo 226*5b9c547cSRui Paulo 227*5b9c547cSRui Paulo static void node_to_tnds(struct xml_node_ctx *ctx, xml_node_t *out, 228*5b9c547cSRui Paulo xml_node_t *in, const char *uri) 229*5b9c547cSRui Paulo { 230*5b9c547cSRui Paulo xml_node_t *node; 231*5b9c547cSRui Paulo xml_node_t *tnds; 232*5b9c547cSRui Paulo const char *name; 233*5b9c547cSRui Paulo char *val; 234*5b9c547cSRui Paulo char *new_uri; 235*5b9c547cSRui Paulo 236*5b9c547cSRui Paulo xml_node_for_each_child(ctx, node, in) { 237*5b9c547cSRui Paulo xml_node_for_each_check(ctx, node); 238*5b9c547cSRui Paulo name = xml_node_get_localname(ctx, node); 239*5b9c547cSRui Paulo 240*5b9c547cSRui Paulo tnds = xml_node_create(ctx, out, NULL, "Node"); 241*5b9c547cSRui Paulo if (tnds == NULL) 242*5b9c547cSRui Paulo return; 243*5b9c547cSRui Paulo xml_node_create_text(ctx, tnds, NULL, "NodeName", name); 244*5b9c547cSRui Paulo 245*5b9c547cSRui Paulo if (uri) 246*5b9c547cSRui Paulo xml_node_create_text(ctx, tnds, NULL, "Path", uri); 247*5b9c547cSRui Paulo 248*5b9c547cSRui Paulo val = get_val(ctx, node); 249*5b9c547cSRui Paulo if (val) { 250*5b9c547cSRui Paulo xml_node_create_text(ctx, tnds, NULL, "Value", val); 251*5b9c547cSRui Paulo xml_node_get_text_free(ctx, val); 252*5b9c547cSRui Paulo } 253*5b9c547cSRui Paulo 254*5b9c547cSRui Paulo new_uri = add_path(uri, name); 255*5b9c547cSRui Paulo node_to_tnds(ctx, new_uri ? out : tnds, node, new_uri); 256*5b9c547cSRui Paulo os_free(new_uri); 257*5b9c547cSRui Paulo } 258*5b9c547cSRui Paulo } 259*5b9c547cSRui Paulo 260*5b9c547cSRui Paulo 261*5b9c547cSRui Paulo static int add_ddfname(struct xml_node_ctx *ctx, xml_node_t *parent, 262*5b9c547cSRui Paulo const char *urn) 263*5b9c547cSRui Paulo { 264*5b9c547cSRui Paulo xml_node_t *node; 265*5b9c547cSRui Paulo 266*5b9c547cSRui Paulo node = xml_node_create(ctx, parent, NULL, "RTProperties"); 267*5b9c547cSRui Paulo if (node == NULL) 268*5b9c547cSRui Paulo return -1; 269*5b9c547cSRui Paulo node = xml_node_create(ctx, node, NULL, "Type"); 270*5b9c547cSRui Paulo if (node == NULL) 271*5b9c547cSRui Paulo return -1; 272*5b9c547cSRui Paulo xml_node_create_text(ctx, node, NULL, "DDFName", urn); 273*5b9c547cSRui Paulo return 0; 274*5b9c547cSRui Paulo } 275*5b9c547cSRui Paulo 276*5b9c547cSRui Paulo 277*5b9c547cSRui Paulo xml_node_t * mo_to_tnds(struct xml_node_ctx *ctx, xml_node_t *mo, 278*5b9c547cSRui Paulo int use_path, const char *urn, const char *ns_uri) 279*5b9c547cSRui Paulo { 280*5b9c547cSRui Paulo xml_node_t *root; 281*5b9c547cSRui Paulo xml_node_t *node; 282*5b9c547cSRui Paulo const char *name; 283*5b9c547cSRui Paulo 284*5b9c547cSRui Paulo root = xml_node_create_root(ctx, ns_uri, NULL, NULL, "MgmtTree"); 285*5b9c547cSRui Paulo if (root == NULL) 286*5b9c547cSRui Paulo return NULL; 287*5b9c547cSRui Paulo 288*5b9c547cSRui Paulo xml_node_create_text(ctx, root, NULL, "VerDTD", "1.2"); 289*5b9c547cSRui Paulo 290*5b9c547cSRui Paulo name = xml_node_get_localname(ctx, mo); 291*5b9c547cSRui Paulo 292*5b9c547cSRui Paulo node = xml_node_create(ctx, root, NULL, "Node"); 293*5b9c547cSRui Paulo if (node == NULL) 294*5b9c547cSRui Paulo goto fail; 295*5b9c547cSRui Paulo xml_node_create_text(ctx, node, NULL, "NodeName", name); 296*5b9c547cSRui Paulo if (urn) 297*5b9c547cSRui Paulo add_ddfname(ctx, node, urn); 298*5b9c547cSRui Paulo 299*5b9c547cSRui Paulo node_to_tnds(ctx, use_path ? root : node, mo, use_path ? name : NULL); 300*5b9c547cSRui Paulo 301*5b9c547cSRui Paulo return root; 302*5b9c547cSRui Paulo 303*5b9c547cSRui Paulo fail: 304*5b9c547cSRui Paulo xml_node_free(ctx, root); 305*5b9c547cSRui Paulo return NULL; 306*5b9c547cSRui Paulo } 307*5b9c547cSRui Paulo 308*5b9c547cSRui Paulo 309*5b9c547cSRui Paulo static xml_node_t * get_first_child_node(struct xml_node_ctx *ctx, 310*5b9c547cSRui Paulo xml_node_t *node, 311*5b9c547cSRui Paulo const char *name) 312*5b9c547cSRui Paulo { 313*5b9c547cSRui Paulo const char *lname; 314*5b9c547cSRui Paulo xml_node_t *child; 315*5b9c547cSRui Paulo 316*5b9c547cSRui Paulo xml_node_for_each_child(ctx, child, node) { 317*5b9c547cSRui Paulo xml_node_for_each_check(ctx, child); 318*5b9c547cSRui Paulo lname = xml_node_get_localname(ctx, child); 319*5b9c547cSRui Paulo if (os_strcasecmp(lname, name) == 0) 320*5b9c547cSRui Paulo return child; 321*5b9c547cSRui Paulo } 322*5b9c547cSRui Paulo 323*5b9c547cSRui Paulo return NULL; 324*5b9c547cSRui Paulo } 325*5b9c547cSRui Paulo 326*5b9c547cSRui Paulo 327*5b9c547cSRui Paulo static char * get_node_text(struct xml_node_ctx *ctx, xml_node_t *node, 328*5b9c547cSRui Paulo const char *node_name) 329*5b9c547cSRui Paulo { 330*5b9c547cSRui Paulo node = get_first_child_node(ctx, node, node_name); 331*5b9c547cSRui Paulo if (node == NULL) 332*5b9c547cSRui Paulo return NULL; 333*5b9c547cSRui Paulo return xml_node_get_text(ctx, node); 334*5b9c547cSRui Paulo } 335*5b9c547cSRui Paulo 336*5b9c547cSRui Paulo 337*5b9c547cSRui Paulo static xml_node_t * add_mo_node(struct xml_node_ctx *ctx, xml_node_t *root, 338*5b9c547cSRui Paulo xml_node_t *node, const char *uri) 339*5b9c547cSRui Paulo { 340*5b9c547cSRui Paulo char *nodename, *value, *path; 341*5b9c547cSRui Paulo xml_node_t *parent; 342*5b9c547cSRui Paulo 343*5b9c547cSRui Paulo nodename = get_node_text(ctx, node, "NodeName"); 344*5b9c547cSRui Paulo if (nodename == NULL) 345*5b9c547cSRui Paulo return NULL; 346*5b9c547cSRui Paulo value = get_node_text(ctx, node, "Value"); 347*5b9c547cSRui Paulo 348*5b9c547cSRui Paulo if (root == NULL) { 349*5b9c547cSRui Paulo root = xml_node_create_root(ctx, NULL, NULL, NULL, 350*5b9c547cSRui Paulo nodename); 351*5b9c547cSRui Paulo if (root && value) 352*5b9c547cSRui Paulo xml_node_set_text(ctx, root, value); 353*5b9c547cSRui Paulo } else { 354*5b9c547cSRui Paulo if (uri == NULL) { 355*5b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename); 356*5b9c547cSRui Paulo xml_node_get_text_free(ctx, value); 357*5b9c547cSRui Paulo return NULL; 358*5b9c547cSRui Paulo } 359*5b9c547cSRui Paulo path = get_node_text(ctx, node, "Path"); 360*5b9c547cSRui Paulo if (path) 361*5b9c547cSRui Paulo uri = path; 362*5b9c547cSRui Paulo parent = get_node_uri(ctx, root, uri); 363*5b9c547cSRui Paulo xml_node_get_text_free(ctx, path); 364*5b9c547cSRui Paulo if (parent == NULL) { 365*5b9c547cSRui Paulo printf("Could not find URI '%s'\n", uri); 366*5b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename); 367*5b9c547cSRui Paulo xml_node_get_text_free(ctx, value); 368*5b9c547cSRui Paulo return NULL; 369*5b9c547cSRui Paulo } 370*5b9c547cSRui Paulo if (value) 371*5b9c547cSRui Paulo xml_node_create_text(ctx, parent, NULL, nodename, 372*5b9c547cSRui Paulo value); 373*5b9c547cSRui Paulo else 374*5b9c547cSRui Paulo xml_node_create(ctx, parent, NULL, nodename); 375*5b9c547cSRui Paulo } 376*5b9c547cSRui Paulo 377*5b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename); 378*5b9c547cSRui Paulo xml_node_get_text_free(ctx, value); 379*5b9c547cSRui Paulo 380*5b9c547cSRui Paulo return root; 381*5b9c547cSRui Paulo } 382*5b9c547cSRui Paulo 383*5b9c547cSRui Paulo 384*5b9c547cSRui Paulo static xml_node_t * tnds_to_mo_iter(struct xml_node_ctx *ctx, xml_node_t *root, 385*5b9c547cSRui Paulo xml_node_t *node, const char *uri) 386*5b9c547cSRui Paulo { 387*5b9c547cSRui Paulo xml_node_t *child; 388*5b9c547cSRui Paulo const char *name; 389*5b9c547cSRui Paulo char *nodename; 390*5b9c547cSRui Paulo 391*5b9c547cSRui Paulo xml_node_for_each_sibling(ctx, node) { 392*5b9c547cSRui Paulo xml_node_for_each_check(ctx, node); 393*5b9c547cSRui Paulo 394*5b9c547cSRui Paulo nodename = get_node_text(ctx, node, "NodeName"); 395*5b9c547cSRui Paulo if (nodename == NULL) 396*5b9c547cSRui Paulo return NULL; 397*5b9c547cSRui Paulo 398*5b9c547cSRui Paulo name = xml_node_get_localname(ctx, node); 399*5b9c547cSRui Paulo if (strcmp(name, "Node") == 0) { 400*5b9c547cSRui Paulo if (root && !uri) { 401*5b9c547cSRui Paulo printf("Invalid TNDS tree structure - " 402*5b9c547cSRui Paulo "multiple top level nodes\n"); 403*5b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename); 404*5b9c547cSRui Paulo return NULL; 405*5b9c547cSRui Paulo } 406*5b9c547cSRui Paulo root = add_mo_node(ctx, root, node, uri); 407*5b9c547cSRui Paulo } 408*5b9c547cSRui Paulo 409*5b9c547cSRui Paulo child = get_first_child_node(ctx, node, "Node"); 410*5b9c547cSRui Paulo if (child) { 411*5b9c547cSRui Paulo if (uri == NULL) 412*5b9c547cSRui Paulo tnds_to_mo_iter(ctx, root, child, nodename); 413*5b9c547cSRui Paulo else { 414*5b9c547cSRui Paulo char *new_uri; 415*5b9c547cSRui Paulo new_uri = add_path(uri, nodename); 416*5b9c547cSRui Paulo tnds_to_mo_iter(ctx, root, child, new_uri); 417*5b9c547cSRui Paulo os_free(new_uri); 418*5b9c547cSRui Paulo } 419*5b9c547cSRui Paulo } 420*5b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename); 421*5b9c547cSRui Paulo } 422*5b9c547cSRui Paulo 423*5b9c547cSRui Paulo return root; 424*5b9c547cSRui Paulo } 425*5b9c547cSRui Paulo 426*5b9c547cSRui Paulo 427*5b9c547cSRui Paulo xml_node_t * tnds_to_mo(struct xml_node_ctx *ctx, xml_node_t *tnds) 428*5b9c547cSRui Paulo { 429*5b9c547cSRui Paulo const char *name; 430*5b9c547cSRui Paulo xml_node_t *node; 431*5b9c547cSRui Paulo 432*5b9c547cSRui Paulo name = xml_node_get_localname(ctx, tnds); 433*5b9c547cSRui Paulo if (name == NULL || os_strcmp(name, "MgmtTree") != 0) 434*5b9c547cSRui Paulo return NULL; 435*5b9c547cSRui Paulo 436*5b9c547cSRui Paulo node = get_first_child_node(ctx, tnds, "Node"); 437*5b9c547cSRui Paulo if (!node) 438*5b9c547cSRui Paulo return NULL; 439*5b9c547cSRui Paulo return tnds_to_mo_iter(ctx, NULL, node, NULL); 440*5b9c547cSRui Paulo } 441*5b9c547cSRui Paulo 442*5b9c547cSRui Paulo 443*5b9c547cSRui Paulo xml_node_t * soap_build_envelope(struct xml_node_ctx *ctx, xml_node_t *node) 444*5b9c547cSRui Paulo { 445*5b9c547cSRui Paulo xml_node_t *envelope, *body; 446*5b9c547cSRui Paulo xml_namespace_t *ns; 447*5b9c547cSRui Paulo 448*5b9c547cSRui Paulo envelope = xml_node_create_root( 449*5b9c547cSRui Paulo ctx, "http://www.w3.org/2003/05/soap-envelope", "soap12", &ns, 450*5b9c547cSRui Paulo "Envelope"); 451*5b9c547cSRui Paulo if (envelope == NULL) 452*5b9c547cSRui Paulo return NULL; 453*5b9c547cSRui Paulo body = xml_node_create(ctx, envelope, ns, "Body"); 454*5b9c547cSRui Paulo xml_node_add_child(ctx, body, node); 455*5b9c547cSRui Paulo return envelope; 456*5b9c547cSRui Paulo } 457*5b9c547cSRui Paulo 458*5b9c547cSRui Paulo 459*5b9c547cSRui Paulo xml_node_t * soap_get_body(struct xml_node_ctx *ctx, xml_node_t *soap) 460*5b9c547cSRui Paulo { 461*5b9c547cSRui Paulo xml_node_t *body, *child; 462*5b9c547cSRui Paulo 463*5b9c547cSRui Paulo body = get_node_uri(ctx, soap, "Envelope/Body"); 464*5b9c547cSRui Paulo if (body == NULL) 465*5b9c547cSRui Paulo return NULL; 466*5b9c547cSRui Paulo xml_node_for_each_child(ctx, child, body) { 467*5b9c547cSRui Paulo xml_node_for_each_check(ctx, child); 468*5b9c547cSRui Paulo return child; 469*5b9c547cSRui Paulo } 470*5b9c547cSRui Paulo return NULL; 471*5b9c547cSRui Paulo } 472