new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / os_xml / os_xml_node_access.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All rights reserved.
3  *
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
7  * Foundation
8  */
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13
14 #include "os_xml.h"
15 #include "os_xml_internal.h"
16
17
18 /* Clear the Node structure */
19 void OS_ClearNode(xml_node **node)
20 {
21     if (node) {
22         int i = 0;
23         while (node[i]) {
24             if (node[i]->element) {
25                 free(node[i]->element);
26             }
27             if (node[i]->content) {
28                 free(node[i]->content);
29             }
30             if (node[i]->attributes) {
31                 int j = 0;
32                 while (node[i]->attributes[j]) {
33                     free(node[i]->attributes[j]);
34                     j++;
35                 }
36                 free(node[i]->attributes);
37             }
38             if (node[i]->values) {
39                 int j = 0;
40                 while (node[i]->values[j]) {
41                     free(node[i]->values[j]);
42                     j++;
43                 }
44                 free(node[i]->values);
45             }
46
47             node[i]->element = NULL;
48             node[i]->content = NULL;
49             node[i]->attributes = NULL;
50             node[i]->values = NULL;
51             free(node[i]);
52             node[i] = NULL;
53             i++;
54         }
55         free(node);
56     }
57 }
58
59
60 /* Get the elements by node */
61 xml_node **OS_GetElementsbyNode(const OS_XML *_lxml, const xml_node *node)
62 {
63     unsigned int i, k = 0, m;
64     xml_node **ret = NULL;
65     xml_node **ret_tmp = NULL;
66
67     if (node == NULL) {
68         m = 0;
69         i = 0;
70     } else {
71         i = node->key;
72         m = _lxml->rl[i++] + 1;
73     }
74
75     for (; i < _lxml->cur; i++) {
76         if (_lxml->tp[i] == XML_ELEM) {
77             if ((_lxml->rl[i] == m) && (_lxml->el[i] != NULL)) {
78                 unsigned int l = i + 1;
79                 /* Allocate for xml_node ** */
80                 ret_tmp = (xml_node **)realloc(ret, (k + 2) * sizeof(xml_node *));
81                 if (ret_tmp == NULL) {
82                     goto fail;
83                 }
84                 ret = ret_tmp;
85
86                 /* Allocate for the xml_node * */
87                 ret[k] = (xml_node *)calloc(1, sizeof(xml_node));
88                 ret[k + 1] = NULL;
89                 if (ret[k] == NULL) {
90                     goto fail;
91                 }
92
93                 ret[k]->element = NULL;
94                 ret[k]->content = NULL;
95                 ret[k]->attributes = NULL;
96                 ret[k]->values = NULL;
97
98                 /* Get element */
99                 ret[k]->element = strdup(_lxml->el[i]);
100                 if (ret[k]->element == NULL) {
101                     goto fail;
102                 }
103
104                 /* Get content */
105                 if (_lxml->ct[i]) {
106                     ret[k]->content = strdup(_lxml->ct[i]);
107                     if (ret[k]->content == NULL) {
108                         goto fail;
109                     }
110                 }
111                 /* Assign key */
112                 ret[k]->key = i;
113
114                 /* Get attributes */
115                 while (l < _lxml->cur) {
116                     if ((_lxml->tp[l] == XML_ATTR) && (_lxml->rl[l] == m) &&
117                             (_lxml->el[l]) && (_lxml->ct[l])) {
118                         char **tmp;
119                         tmp = (char **)realloc(ret[k]->attributes, (l - i + 1) * sizeof(char *));
120                         if (tmp == NULL) {
121                             goto fail;
122                         }
123                         ret[k]->attributes = tmp;
124                         ret[k]->attributes[l - i] = NULL;
125                         tmp = (char **)realloc(ret[k]->values, (l - i + 1) * sizeof(char *));
126                         if (tmp == NULL) {
127                             goto fail;
128                         }
129                         ret[k]->values = tmp;
130                         ret[k]->values[l - i] = NULL;
131
132                         ret[k]->attributes[l - i - 1] = strdup(_lxml->el[l]);
133                         ret[k]->values[l - i - 1] = strdup(_lxml->ct[l]);
134                         if (!(ret[k]->attributes[l - i - 1]) ||
135                                 !(ret[k]->values[l - i - 1])) {
136                             goto fail;
137                         }
138                         l++;
139                     } else {
140                         break;
141                     }
142                 }
143                 k++;
144                 continue;
145             }
146         }
147         if ((_lxml->tp[i] == XML_ELEM) && (m > _lxml->rl[i])) {
148             if (node == NULL) {
149                 continue;
150             } else {
151                 break;
152             }
153         }
154     }
155
156     return (ret);
157
158 fail:
159     OS_ClearNode(ret);
160     return (NULL);
161 }
162