1 /* Copyright (C) 2009 Trend Micro Inc.
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
15 #include "os_xml_internal.h"
18 static char **_GetElements(const OS_XML *_lxml, const char **element_name, XML_TYPE type) __attribute__((nonnull(1)));
19 static char **_GetElementContent(OS_XML *_lxml, const char **element_name, const char *attr) __attribute__((nonnull(1, 2)));
22 /* Check if a element exists
23 * The element_name must be NULL terminated (last char)
25 unsigned int OS_ElementExist(const OS_XML *_lxml, const char **element_name)
27 unsigned int i = 0, j = 0, matched = 0, totalmatch = 0;
29 if (element_name[0] == NULL) {
33 for (i = 0, j = 0; i < _lxml->cur; i++) {
34 if (element_name[j] == NULL) {
37 if ((_lxml->tp[i] == XML_ELEM) && (_lxml->rl[i] == j)) {
38 if (strcmp(_lxml->el[i], element_name[j]) == 0) {
41 if (element_name[j] == NULL) {
48 if ((matched == 1) && (j > _lxml->rl[i]) &&
49 (_lxml->tp[i] == XML_ELEM)) {
57 /* Check if a root element exists */
58 unsigned int OS_RootElementExist(const OS_XML *_lxml, const char *element_name)
60 const char *(elements[]) = {element_name, NULL};
61 return (OS_ElementExist(_lxml, elements));
64 /* Get the attributes of the element_name */
65 char **OS_GetAttributes(const OS_XML *_lxml, const char **element_name)
67 return (_GetElements(_lxml, element_name, XML_ATTR));
70 /* Get the elements children of the element_name */
71 char **OS_GetElements(const OS_XML *_lxml, const char **element_name)
73 return (_GetElements(_lxml, element_name, XML_ELEM));
76 /* Get the elements or attributes (internal use) */
77 static char **_GetElements(const OS_XML *_lxml, const char **element_name, XML_TYPE type)
79 unsigned i = 0, j = 0, k = 0, matched = 0, ready = 0;
81 char **ret_tmp = NULL;
83 if ((type == XML_ELEM) && (element_name == NULL)) {
87 for (i = 0, j = 0; i < _lxml->cur; i++) {
88 if ((ready != 1) && (element_name[j] == NULL)) {
100 if ((ready == 1) && (_lxml->tp[i] == type)) {
101 if (((type == XML_ATTR) && (_lxml->rl[i] == j - 1)
102 && (_lxml->el[i] != NULL)) ||
103 ((type == XML_ELEM) && (_lxml->rl[i] == j) &&
104 (_lxml->el[i] != NULL))) {
105 size_t el_size = strlen(_lxml->el[i]) + 1;
106 ret_tmp = (char **)realloc(ret, (k + 2) * sizeof(char *));
107 if (ret_tmp == NULL) {
112 ret[k] = (char *)calloc(el_size, sizeof(char));
113 if (ret[k] == NULL) {
116 strncpy(ret[k], _lxml->el[i], el_size - 1);
121 else if ((_lxml->tp[i] == XML_ELEM) && (_lxml->rl[i] == j) &&
122 (element_name[j] != NULL)) {
123 if (strcmp(_lxml->el[i], element_name[j]) == 0) {
131 if (((_lxml->tp[i] == XML_ATTR) && (j > _lxml->rl[i] + 1)) ||
132 ((_lxml->tp[i] == XML_ELEM) && (j > _lxml->rl[i]))) {
135 if (element_name == NULL) {
157 /* Get one value for a specific element */
158 char *OS_GetOneContentforElement(OS_XML *_lxml, const char **element_name)
161 char *uniqret = NULL;
165 ret = _GetElementContent(_lxml, element_name, NULL);
170 if (ret[0] != NULL) {
185 /* Get all values for a specific element */
186 char **OS_GetElementContent(OS_XML *_lxml, const char **element_name)
189 return (_GetElementContent(_lxml, element_name, NULL));
192 /* Get the contents for a specific element
193 * Use element_name = NULL to start the state
195 char **OS_GetContents(OS_XML *_lxml, const char **element_name)
197 if (element_name == NULL) {
201 return (_GetElementContent(_lxml, element_name, NULL));
204 /* Get one value for a specific attribute */
205 char *OS_GetAttributeContent(OS_XML *_lxml, const char **element_name,
206 const char *attribute_name)
208 char *uniqret = NULL;
213 ret = _GetElementContent(_lxml, element_name, attribute_name);
217 if (ret[0] != NULL) {
222 while (ret[i] != NULL) {
230 /* Get the values for an element or attribute */
231 static char **_GetElementContent(OS_XML *_lxml, const char **element_name, const char *attr)
234 unsigned int j = 0, k = 0, l = 0, matched = 0;
238 if (_lxml->fol >= 0 && (unsigned int)_lxml->fol == _lxml->cur) {
243 if (_lxml->fol > 0) {
244 for (i = _lxml->fol; i >= 0; i--) {
246 if (_lxml->rl[i] == 0) {
255 /* Loop over all nodes */
256 for (j = 0, l = (unsigned int)i; l < _lxml->cur; l++) {
257 if (element_name[j] == NULL) {
263 /* Set maximum depth of 16 */
268 /* If the type is not an element and the relation doesn't match,
271 if ((_lxml->tp[l] != XML_ELEM) || (_lxml->rl[l] != j)) {
272 /* If the node relation is higher than the current xml
273 * node, zero the position and look at it again (i--).
275 if (j > _lxml->rl[l]) {
284 /* If the element name matches what we are looking for */
285 else if (element_name[j] != NULL && strcmp(_lxml->el[l], element_name[j]) == 0) {
289 /* Get content if we are at the end of the array */
290 if (element_name[j] == NULL) {
291 /* If we have an attribute to match */
294 for (m = l + 1; m < _lxml->cur; m++) {
295 if (_lxml->tp[m] == XML_ELEM) {
299 if (strcmp(attr, _lxml->el[m]) == 0) {
306 if (_lxml->ct[l] != NULL) {
307 /* Increase the size of the array */
308 ret_tmp = (char **) realloc(ret, (k + 2) * sizeof(char *));
309 if (ret_tmp == NULL) {
315 ret[k] = strdup(_lxml->ct[l]);
317 if (ret[k] == NULL) {
328 else if (_lxml->fol != 0) {
329 _lxml->fol = (int) l + 1;
334 /* Set new array pointer */
335 if ((l < _lxml->cur - 1) && (_lxml->tp[l + 1] == XML_ELEM)) {
336 j = _lxml->rl[l + 1];
342 if (j > _lxml->rl[l]) {