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