Imported Upstream version 2.7
[ossec-hids.git] / src / os_xml / os_xml_access.c
1 /*   $OSSEC, os_xml_access.c, v0.3, 2005/02/11, Daniel B. Cid$   */
2
3 /* Copyright (C) 2009 Trend Micro Inc.
4  * All rights reserved.
5  *
6  * This program is a free software; you can redistribute it
7  * and/or modify it under the terms of the GNU General Public
8  * License (version 2) as published by the FSF - Free Software
9  * Foundation
10  */
11
12 /* os_xml C Library.
13  */
14
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19
20 #include "os_xml.h"
21
22
23 /* Internal functions */
24 char **_GetElements(OS_XML *_lxml, char **element_name,int type);
25 char **_GetElementContent(OS_XML *_lxml, char **element_name, char *attr);
26
27
28 /* OS_ElementExist: v1.0: 2005/02/26
29  * Check if a element exists
30  * The element_name must be NULL terminated (last char)
31  */
32 int OS_ElementExist(OS_XML *_lxml, char **element_name)
33 {
34     int i=0,j=0,matched=0,totalmatch=0;
35
36     if(element_name == NULL)
37         return(0);
38
39     for(i=0,j=0;i<_lxml->cur;i++)
40     {
41         if(element_name[j] == NULL)
42             j=0;
43         if((_lxml->tp[i] == XML_ELEM)&&(_lxml->rl[i] == j))
44         {
45             if(strcmp(_lxml->el[i],element_name[j]) == 0)
46             {
47                 j++;
48                 matched=1;
49                 if(element_name[j] == NULL)
50                 {
51                     j=0;
52                     totalmatch++;
53                 }
54                 continue;
55             }
56         }
57         if((matched == 1) &&(j > _lxml->rl[i])&&
58                 (_lxml->tp[i] == XML_ELEM))
59         {
60             j=0;
61             matched=0;
62         }
63     }
64     return(totalmatch);
65 }
66
67
68 /* RootElementExist: v1.0: 2005/02/26
69  * Check if a root element exists
70  */
71 int OS_RootElementExist(OS_XML *_lxml, char *element_name)
72 {
73     char *(elements[])={element_name,NULL};
74     return(OS_ElementExist(_lxml,elements));
75 }
76
77
78 /* GetAttributes: v.0.1: 2005/03/01
79  * Get the attributes of the element_name
80  */
81 char **OS_GetAttributes(OS_XML *_lxml, char **element_name)
82 {
83     return(_GetElements(_lxml,element_name,XML_ATTR));
84 }
85
86
87
88
89 /* GetElements: v0.1: 2005/03/01
90  * Get the elements children of the element_name
91  */
92 char **OS_GetElements(OS_XML *_lxml, char **element_name)
93 {
94     return(_GetElements(_lxml, element_name,XML_ELEM));
95 }
96
97
98
99
100 /* _GetElements: v0.1: 2005/03/01
101  * Get the elements or attributes (internal use)
102  */
103 char **_GetElements(OS_XML *_lxml, char **element_name,int type)
104 {
105     int i=0,j=0,k=0,matched=0,ready=0,size=0;
106     char **ret=NULL;
107
108     if((type == XML_ELEM) && (element_name == NULL))
109         ready=1;
110
111     for(i=0,j=0;i<_lxml->cur;i++)
112     {
113         if((ready != 1) &&(element_name[j] == NULL))
114         {
115             if(matched ==1)
116                 ready=1;
117             else
118                 break;
119         }
120
121         if(j > 16)
122             return(ret);
123
124         if((ready == 1)&&(_lxml->tp[i] == type))
125         {
126             if(((type == XML_ATTR)&&(_lxml->rl[i] == j-1)
127                         &&(_lxml->el[i] != NULL))||
128                     ((type == XML_ELEM)&&(_lxml->rl[i] == j)&&
129                      (_lxml->el[i] != NULL)))
130             {
131                 int el_size = strlen(_lxml->el[i])+1;
132                 size+=el_size;
133                 ret = (char**)realloc(ret,(k+1)*sizeof(char *));
134                 if(ret == NULL)
135                     return(NULL);
136                 ret[k]=(char*)calloc(el_size,sizeof(char));
137                 if(ret[k] == NULL)
138                 {
139                     free(ret);
140                     return(NULL);
141                 }
142                 strncpy(ret[k],_lxml->el[i],el_size-1);
143                 k++;
144             }
145         }
146
147         else if((_lxml->tp[i] == XML_ELEM)&&(_lxml->rl[i] == j)&&
148                 (element_name[j] != NULL))
149         {
150             if(strcmp(_lxml->el[i],element_name[j]) == 0)
151             {
152                 j++;
153                 matched=1;
154                 continue;
155             }
156         }
157
158         if(matched == 1)
159         {
160             if(((_lxml->tp[i]==XML_ATTR)&&(j > _lxml->rl[i]+1))||
161                     ((_lxml->tp[i] == XML_ELEM)&&(j > _lxml->rl[i])))
162             {
163                 j=0;
164                 matched=0;
165                 if(element_name == NULL)
166                     ready=1;
167                 else
168                     ready=0;
169             }
170         }
171     }
172     if(ret ==NULL)
173         return(NULL);
174
175     ret = (char**)realloc(ret,(k+1)*sizeof(char *));
176     if(ret == NULL)
177         return(NULL);
178     ret[k]=NULL;
179     return(ret);
180 }
181
182
183
184 /* OS_GetOneContentforElement: v0.1: 2005/03/01
185  * Get one value for a specific element.
186  */
187 char *OS_GetOneContentforElement(OS_XML *_lxml, char **element_name)
188 {
189     int i = 1;
190     char *uniqret = NULL;
191     char **ret = NULL;
192
193     _lxml->fol = 0;
194     ret = _GetElementContent(_lxml, element_name, NULL);
195     if(ret == NULL)
196     {
197         return(NULL);
198     }
199
200     if(ret[0] != NULL)
201     {
202         uniqret = ret[0];
203     }
204
205     /* Freeing memory */
206     while(ret[i])
207     {
208         free(ret[i]);
209         ret[i] = NULL;
210         i++;
211     }
212     free(ret);
213
214     return(uniqret);
215 }
216
217
218 /* OS_GetElementContent: v0.1: 2005/03/01
219  * Get all values for a specific element
220  */
221 char **OS_GetElementContent(OS_XML *_lxml, char **element_name)
222 {
223     _lxml->fol=0;
224     return(_GetElementContent(_lxml, element_name, NULL));
225 }
226
227
228 /* OS_GetContents: v0.1: 2005/03/01
229  * Get the contents for a specific element
230  * Use element_name = NULL to start the state
231  */
232 char **OS_GetContents(OS_XML *_lxml, char **element_name)
233 {
234     if(element_name == NULL)
235     {
236         _lxml->fol = -1;
237         return(NULL);
238     }
239     return(_GetElementContent(_lxml, element_name, NULL));
240 }
241
242
243
244 /* OS_GetAttributeContent: v0.1: 2005/03/01
245  * Get one value for a specific attribute
246  */
247 char *OS_GetAttributeContent(OS_XML *_lxml, char **element_name,
248                                  char *attribute_name)
249 {
250     int success = 0;
251     char *uniqret = NULL;
252     char **ret = NULL;
253
254     _lxml->fol=0;
255
256     ret = _GetElementContent(_lxml, element_name,attribute_name);
257
258     if(ret == NULL)
259         return(NULL);
260
261     if(ret[0] != NULL)
262     {
263         int retsize= strlen(ret[0])+1;
264         if((retsize < XML_MAXSIZE) && (retsize > 0))
265         {
266             uniqret = (char *)calloc(retsize,sizeof(char));
267             if(uniqret != NULL)
268             {
269                 strncpy(uniqret, ret[0], retsize-1);
270                 success = 1;
271             }
272         }
273     }
274     while(1)
275     {
276         if(*ret == NULL)
277             break;
278         free(*ret++);   
279     }
280     if(success)
281         return(uniqret);
282
283     return(NULL);
284 }
285
286
287 /* _GetElementContent: v0.1: 2005/03/01
288  *  Get the values for an element or attribute
289  */
290 char **_GetElementContent(OS_XML *_lxml, char **element_name, char *attr)
291 {
292     int i = 0,j = 0,k = 0,matched = 0;
293     char **ret = NULL;
294
295     /* Element name can not be null. */
296     if(element_name == NULL)
297         return(NULL);
298
299     if(_lxml->fol == _lxml->cur)
300     {
301         _lxml->fol = 0;
302         return(NULL);
303     }
304
305     if(_lxml->fol > 0)
306     {
307         for(i=_lxml->fol;i>=0;i--)
308         {
309             _lxml->fol = i;
310             if(_lxml->rl[i] == 0)
311                 break;
312         }
313         i = _lxml->fol;
314     }
315     else
316     {
317         i = 0;
318     }
319
320
321     /* Looping through all nodes */
322     for(j=0; i<_lxml->cur; i++)
323     {
324         if(element_name[j] == NULL)
325         {
326             if(matched !=1)
327                 break;
328         }
329
330         /* Setting maximum depth of 16. */
331         if(j > 16)
332             return(NULL);
333
334
335         /* If the type is not an element and the relation doesn't match,
336          * keep going.
337          */
338         if((_lxml->tp[i] != XML_ELEM) || (_lxml->rl[i] != j))
339         {
340             /* If the node relation is higher than we currently xml
341              * node, zero the position and look at it again (i--).
342              */
343             if(j > _lxml->rl[i])
344             {
345                 j = 0;
346                 matched = 0;
347                 i--;
348             }
349             else
350             {
351                 continue;
352             }
353         }
354
355
356         /* If the element name matches what we are looking for. */
357         else if(strcmp(_lxml->el[i], element_name[j]) == 0)
358         {
359             j++;
360             matched = 1;
361
362             /* Get content if we are at the end of the array. */
363             if(element_name[j] == NULL)
364             {
365                 /* If we have an attribute to match. */ 
366                 if(attr != NULL)
367                 {
368                     int k=0;
369                     for(k=i+1; k<_lxml->cur; k++)
370                     {
371                         if(_lxml->tp[k] == XML_ELEM)
372                         {
373                             break;
374                         }
375
376                         if(strcmp(attr, _lxml->el[k]) == 0)
377                         {
378                             i = k;
379                             break;
380                         }
381                     }
382                 }
383
384                 if(_lxml->ct[i] != NULL)
385                 {
386                     /* Increasing the size of the array. */
387                     ret = (char**) realloc(ret,(k+2) * sizeof(char*));
388                     if(ret == NULL)
389                     {
390                         return(NULL);
391                     }
392
393                     /* Adding new entry. */
394                     ret[k] = strdup(_lxml->ct[i]);
395                     ret[k + 1] = NULL;
396                     if(ret[k] == NULL)
397                     {
398                         free(ret);
399                         return(NULL);
400                     }
401
402                     matched = 1;
403                     k++;
404
405                     if(attr != NULL)
406                     {
407                         break;
408                     }
409
410                     else if(_lxml->fol != 0)
411                     {
412                         _lxml->fol = i+1;
413                         break;
414                     }
415                 }
416
417                 /* Setting new array pointer. */
418                 if((i<_lxml->cur-1) && (_lxml->tp[i+1] == XML_ELEM))
419                 {
420                     j = _lxml->rl[i+1];
421                 }
422             }
423             continue;
424         }
425
426         if(j > _lxml->rl[i])
427         {
428             j = 0;
429             matched = 0;
430         }
431     }
432
433     if(ret == NULL)
434         return(NULL);
435
436     return(ret);
437 }
438
439 /* EOF */