fixed open failure debug message in load_secrets
[strongswan.git] / src / manager / xml.c
1 /*
2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <string.h>
17
18 #include "xml.h"
19
20 #include <libxml/parser.h>
21 #include <libxml/tree.h>
22
23
24 typedef struct private_xml_t private_xml_t;
25
26 /**
27 * private data of xml
28 */
29 struct private_xml_t {
30
31 /**
32 * public functions
33 */
34 xml_t public;
35
36 /**
37 * root node of this xml (part)
38 */
39 xmlNode *node;
40
41 /**
42 * document, only for root xml_t
43 */
44 xmlDoc *doc;
45
46 /**
47 * Root xml_t*
48 */
49 private_xml_t *root;
50
51 /**
52 * number of enumerator instances
53 */
54 int enums;
55 };
56
57 /**
58 * child element enumerator
59 */
60 typedef struct {
61 /** enumerator interface */
62 enumerator_t e;
63 /** current child context (returned to enumerate() caller) */
64 private_xml_t child;
65 /** currently processing node */
66 xmlNode *node;
67 } child_enum_t;
68
69 /**
70 * Implementation of xml_t.children().enumerate().
71 */
72 static bool child_enumerate(child_enum_t *e, private_xml_t **child,
73 char **name, char **value)
74 {
75 while (e->node && e->node->type != XML_ELEMENT_NODE)
76 {
77 e->node = e->node->next;
78 }
79 if (e->node)
80 {
81 xmlNode *text;
82
83 text = e->node->children;
84 *value = NULL;
85
86 while (text && text->type != XML_TEXT_NODE)
87 {
88 text = text->next;
89 }
90 if (text)
91 {
92 *value = text->content;
93 }
94 *name = (char*)e->node->name;
95 *child = &e->child;
96 e->child.node = e->node->children;
97 e->node = e->node->next;
98 return TRUE;
99 }
100 return FALSE;
101 }
102
103 /**
104 * Implementation of xml_t.get_attribute.
105 */
106 static char* get_attribute(private_xml_t *this, char *name)
107 {
108 return NULL;
109 }
110
111 /**
112 * destroy enumerator, and complete tree if this was the last enumerator
113 */
114 static void child_destroy(child_enum_t *this)
115 {
116 if (--this->child.root->enums == 0)
117 {
118 xmlFreeDoc(this->child.root->doc);
119 free(this->child.root);
120 }
121 free(this);
122 }
123
124 /**
125 * Implementation of xml_t.children.
126 */
127 static enumerator_t* children(private_xml_t *this)
128 {
129 child_enum_t *ce = malloc_thing(child_enum_t);
130 ce->e.enumerate = (void*)child_enumerate;
131 ce->e.destroy = (void*)child_destroy;
132 ce->node = this->node;
133 ce->child.public.children = (void*)children;
134 ce->child.public.get_attribute = (void*)get_attribute;
135 ce->child.node = NULL;
136 ce->child.doc = this->doc;
137 ce->child.root = this->root;
138 this->root->enums++;
139 return &ce->e;
140 }
141
142 /*
143 * see header file
144 */
145 xml_t *xml_create(char *xml)
146 {
147 private_xml_t *this = malloc_thing(private_xml_t);
148
149 this->public.get_attribute = (char*(*)(xml_t*,char*))get_attribute;
150 this->public.children = (enumerator_t*(*)(xml_t*))children;
151
152 this->doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0);
153 if (this->doc == NULL)
154 {
155 free(this);
156 return NULL;
157 }
158 this->node = xmlDocGetRootElement(this->doc);
159 this->root = this;
160 this->enums = 0;
161
162 return &this->public;
163 }
164