1 /* $OSSEC, os_xml_access.c, v0.3, 2005/02/11, Daniel B. Cid$ */
3 /* Copyright (C) 2009 Trend Micro Inc.
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
21 #include "os_xml_internal.h"
24 /* Internal functions */
25 static char **_GetElements(const OS_XML *_lxml, const char **element_name,XML_TYPE type) __attribute__((nonnull(1)));
26 static char **_GetElementContent(OS_XML *_lxml, const char **element_name, const char *attr) __attribute__((nonnull(1,2)));
29 /* OS_ElementExist: v1.0: 2005/02/26
30 * Check if a element exists
31 * The element_name must be NULL terminated (last char)
33 unsigned int OS_ElementExist(const OS_XML *_lxml, const char **element_name)
35 unsigned int i=0,j=0,matched=0,totalmatch=0;
37 if(element_name[0] == NULL)
40 for(i=0,j=0;i<_lxml->cur;i++)
42 if(element_name[j] == NULL)
44 if((_lxml->tp[i] == XML_ELEM)&&(_lxml->rl[i] == j))
46 if(strcmp(_lxml->el[i],element_name[j]) == 0)
50 if(element_name[j] == NULL)
58 if((matched == 1) &&(j > _lxml->rl[i])&&
59 (_lxml->tp[i] == XML_ELEM))
69 /* RootElementExist: v1.0: 2005/02/26
70 * Check if a root element exists
72 unsigned int OS_RootElementExist(const OS_XML *_lxml, const char *element_name)
74 const char *(elements[])={element_name,NULL};
75 return(OS_ElementExist(_lxml,elements));
79 /* GetAttributes: v.0.1: 2005/03/01
80 * Get the attributes of the element_name
82 char **OS_GetAttributes(const OS_XML *_lxml, const char **element_name)
84 return(_GetElements(_lxml,element_name,XML_ATTR));
90 /* GetElements: v0.1: 2005/03/01
91 * Get the elements children of the element_name
93 char **OS_GetElements(const OS_XML *_lxml, const char **element_name)
95 return(_GetElements(_lxml, element_name,XML_ELEM));
101 /* _GetElements: v0.1: 2005/03/01
102 * Get the elements or attributes (internal use)
104 static char **_GetElements(const OS_XML *_lxml, const char **element_name,XML_TYPE type)
106 unsigned i=0,j=0,k=0,matched=0,ready=0;
110 if((type == XML_ELEM) && (element_name == NULL))
113 for(i=0,j=0;i<_lxml->cur;i++)
115 if((ready != 1) &&(element_name[j] == NULL))
126 if((ready == 1)&&(_lxml->tp[i] == type))
128 if(((type == XML_ATTR)&&(_lxml->rl[i] == j-1)
129 &&(_lxml->el[i] != NULL))||
130 ((type == XML_ELEM)&&(_lxml->rl[i] == j)&&
131 (_lxml->el[i] != NULL)))
133 size_t el_size = strlen(_lxml->el[i])+1;
134 ret_tmp = (char**)realloc(ret,(k+2)*sizeof(char *));
139 ret[k]=(char*)calloc(el_size,sizeof(char));
144 strncpy(ret[k],_lxml->el[i],el_size-1);
149 else if((_lxml->tp[i] == XML_ELEM)&&(_lxml->rl[i] == j)&&
150 (element_name[j] != NULL))
152 if(strcmp(_lxml->el[i],element_name[j]) == 0)
162 if(((_lxml->tp[i]==XML_ATTR)&&(j > _lxml->rl[i]+1))||
163 ((_lxml->tp[i] == XML_ELEM)&&(j > _lxml->rl[i])))
167 if(element_name == NULL)
190 /* OS_GetOneContentforElement: v0.1: 2005/03/01
191 * Get one value for a specific element.
193 char *OS_GetOneContentforElement(OS_XML *_lxml, const char **element_name)
196 char *uniqret = NULL;
200 ret = _GetElementContent(_lxml, element_name, NULL);
224 /* OS_GetElementContent: v0.1: 2005/03/01
225 * Get all values for a specific element
227 char **OS_GetElementContent(OS_XML *_lxml, const char **element_name)
230 return(_GetElementContent(_lxml, element_name, NULL));
234 /* OS_GetContents: v0.1: 2005/03/01
235 * Get the contents for a specific element
236 * Use element_name = NULL to start the state
238 char **OS_GetContents(OS_XML *_lxml, const char **element_name)
240 if(element_name == NULL)
245 return(_GetElementContent(_lxml, element_name, NULL));
250 /* OS_GetAttributeContent: v0.1: 2005/03/01
251 * Get one value for a specific attribute
253 char *OS_GetAttributeContent(OS_XML *_lxml, const char **element_name,
254 const char *attribute_name)
256 char *uniqret = NULL;
261 ret = _GetElementContent(_lxml, element_name,attribute_name);
271 while(ret[i] != NULL)
281 /* _GetElementContent: v0.1: 2005/03/01
282 * Get the values for an element or attribute
284 static char **_GetElementContent(OS_XML *_lxml, const char **element_name, const char *attr)
287 unsigned int j = 0,k = 0,l = 0,matched = 0;
291 if(_lxml->fol >= 0 && (unsigned int)_lxml->fol == _lxml->cur)
299 for(i=_lxml->fol;i>=0;i--)
302 if(_lxml->rl[i] == 0)
312 /* Looping through all nodes */
313 for(j=0,l=(unsigned int)i; l<_lxml->cur; l++)
315 if(element_name[j] == NULL)
321 /* Setting maximum depth of 16. */
326 /* If the type is not an element and the relation doesn't match,
329 if((_lxml->tp[l] != XML_ELEM) || (_lxml->rl[l] != j))
331 /* If the node relation is higher than we currently xml
332 * node, zero the position and look at it again (i--).
347 /* If the element name matches what we are looking for. */
348 else if(element_name[j] != NULL && strcmp(_lxml->el[l], element_name[j]) == 0)
353 /* Get content if we are at the end of the array. */
354 if(element_name[j] == NULL)
356 /* If we have an attribute to match. */
360 for(m=l+1; m<_lxml->cur; m++)
362 if(_lxml->tp[m] == XML_ELEM)
367 if(strcmp(attr, _lxml->el[m]) == 0)
375 if(_lxml->ct[l] != NULL)
377 /* Increasing the size of the array. */
378 ret_tmp = (char**) realloc(ret,(k+2) * sizeof(char*));
385 /* Adding new entry. */
386 ret[k] = strdup(_lxml->ct[l]);
401 else if(_lxml->fol != 0)
403 _lxml->fol = (int) l+1;
408 /* Setting new array pointer. */
409 if((l<_lxml->cur-1) && (_lxml->tp[l+1] == XML_ELEM))