Imported Upstream version 2.3
[ossec-hids.git] / src / analysisd / decoders / decode-xml.c
1 /* @(#) $Id: decode-xml.c,v 1.47 2009/06/24 17:06:23 dcid Exp $ */
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 3) as published by the FSF - Free Software
9  * Foundation.
10  *
11  * License details at the LICENSE file included with OSSEC or 
12  * online at: http://www.ossec.net/en/licensing.html
13  */
14
15
16 #include "shared.h"
17 #include "os_regex/os_regex.h"
18 #include "os_xml/os_xml.h"
19
20
21 #include "analysisd.h"
22 #include "eventinfo.h"
23 #include "decoder.h"
24 #include "plugin_decoders.h"
25
26
27 #ifdef TESTRULE
28   #undef XML_LDECODER
29   #define XML_LDECODER "etc/local_decoder.xml"
30 #endif
31
32
33 /* Internal functions */
34 char *_loadmemory(char *at, char *str);
35 OSStore *os_decoder_store = NULL;
36
37
38 /* Gets decoder id */
39 int getDecoderfromlist(char *name)
40 {
41     if(os_decoder_store)
42     {
43         return(OSStore_GetPosition(os_decoder_store, name));
44     }
45     
46     return(0);
47 }
48
49
50 /* Adds decoder id */
51 int addDecoder2list(char *name)
52 {
53     if(os_decoder_store == NULL)
54     {
55         os_decoder_store = OSStore_Create();
56         if(os_decoder_store == NULL)
57         {
58             merror(LIST_ERROR, ARGV0);
59             return(0);
60         }
61     }
62
63     /* Storing data */
64     if(!OSStore_Put(os_decoder_store, name, NULL))
65     {
66         merror(LIST_ADD_ERROR, ARGV0);
67         return(0);
68     }
69
70     return(1);
71 }
72
73
74 /* Set decoder ids */
75 int os_setdecoderids(char *p_name)
76 {
77     OSDecoderNode *node;
78     OSDecoderNode *child_node;
79     OSDecoderInfo *nnode;
80
81
82     node = OS_GetFirstOSDecoder(p_name);
83
84
85     /* Return if no node...
86      * This shouldn't happen here anyways.
87      */
88     if(!node)
89         return(0);
90
91     do
92     {
93         int p_id = 0;
94         char *p_name;
95         
96         nnode = node->osdecoder;
97         nnode->id = getDecoderfromlist(nnode->name);        
98         
99         /* Id can noit be 0 */
100         if(nnode->id == 0)
101         {
102             return(0);
103         }
104
105         child_node = node->child;
106
107         if(!child_node)
108         {
109             continue;
110         }
111
112
113         /* Setting parent id */
114         p_id = nnode->id;
115         p_name = nnode->name;
116
117
118         /* Also setting on the child nodes */
119         while(child_node)
120         {
121             nnode = child_node->osdecoder;
122
123             if(nnode->use_own_name)
124             {
125                 nnode->id = getDecoderfromlist(nnode->name);
126             }
127             else
128             {
129                 nnode->id = p_id;
130
131                 /* Setting parent name */
132                 nnode->name = p_name;
133             }
134             
135             
136             /* Id can noit be 0 */
137             if(nnode->id == 0)
138             {
139                 return(0);
140             }
141             child_node = child_node->next;
142         }
143     }while((node=node->next) != NULL);
144
145     return(1);
146 }
147
148
149 /* Read attributes */
150 int ReadDecodeAttrs(char **names, char **values)
151 {
152     if(!names || !values)
153         return(0);
154
155     if(!names[0] || !values[0])
156     {
157         return(0);
158     }
159     
160     if(strcmp(names[0], "offset") == 0)
161     {
162         int offset = 0;
163         
164         /* Offsets can be: after_parent, after_prematch
165          * or after_regex.
166          */
167         if(strcmp(values[0],"after_parent") == 0)
168         {
169             offset |= AFTER_PARENT;
170         }
171         else if(strcmp(values[0],"after_prematch") == 0)
172         {
173             offset |= AFTER_PREMATCH;
174         }
175         else if(strcmp(values[0],"after_regex") == 0)
176         {
177             offset |= AFTER_PREVREGEX;
178         }
179         else
180         {
181             merror(INV_OFFSET, ARGV0, values[0]);
182             offset |= AFTER_ERROR;
183         }
184         
185         return(offset);
186     }
187
188     /* Invalid attribute */
189     merror(INV_ATTR, ARGV0, names[0]);
190     return(AFTER_ERROR);
191 }
192
193
194 /* ReaddecodeXML */
195 int ReadDecodeXML(char *file)
196 {
197     
198     OS_XML xml;
199     XML_NODE node = NULL;
200
201     /* XML variables */ 
202     /* These are the available options for the rule configuration */
203     
204     char *xml_plugindecoder = "plugin_decoder";
205     char *xml_decoder = "decoder";
206     char *xml_decoder_name = "name";
207     char *xml_decoder_status = "status";
208     char *xml_usename = "use_own_name";
209     char *xml_parent = "parent";
210     char *xml_program_name = "program_name";
211     char *xml_prematch = "prematch";
212     char *xml_regex = "regex";
213     char *xml_order = "order";
214     char *xml_type = "type";
215     char *xml_fts = "fts";
216     char *xml_ftscomment = "ftscomment";
217
218     int i = 0;
219     OSDecoderInfo *NULL_Decoder_tmp = NULL;
220     
221      
222     /* Reading the XML */       
223     if((i = OS_ReadXML(file,&xml)) < 0)
224     {
225         if((i == -2) && (strcmp(file, XML_LDECODER) == 0))
226         {
227             return(-2);
228         }
229         
230         merror(XML_ERROR, ARGV0, file, xml.err, xml.err_line);
231         return(0);
232     }
233
234     
235     /* Applying any variable found */
236     if(OS_ApplyVariables(&xml) != 0)
237     {
238         merror(XML_ERROR_VAR, ARGV0, file, xml.err);
239         return(0);
240     }
241
242
243     /* Getting the root elements */
244     node = OS_GetElementsbyNode(&xml, NULL);
245     if(!node)
246     {
247         if(strcmp(file, XML_LDECODER) != 0)
248         {
249             merror(XML_ELEMNULL, ARGV0);
250             return(0);
251         }
252
253         return(-2);
254     }
255
256
257     /* Zeroing NULL_decoder */
258     os_calloc(1, sizeof(OSDecoderInfo), NULL_Decoder_tmp);
259     NULL_Decoder_tmp->id = 0;
260     NULL_Decoder_tmp->type = SYSLOG;
261     NULL_Decoder_tmp->name = NULL;
262     NULL_Decoder_tmp->fts = 0;
263     NULL_Decoder = (void *)NULL_Decoder_tmp;
264
265
266     
267     i = 0;
268     while(node[i])
269     {
270         XML_NODE elements = NULL;
271         OSDecoderInfo *pi;
272
273         int j = 0;
274         char *regex;
275         char *prematch;
276         char *p_name;
277
278         
279         if(!node[i]->element || 
280             strcasecmp(node[i]->element, xml_decoder) != 0)
281         {
282             merror(XML_INVELEM, ARGV0, node[i]->element);
283             return(0);
284         }
285        
286
287         /* Getting name */
288         if((!node[i]->attributes) || (!node[i]->values)||
289            (!node[i]->values[0])  || (!node[i]->attributes[0])||
290            (strcasecmp(node[i]->attributes[0],xml_decoder_name)!= 0))
291         {
292             merror(XML_INVELEM, ARGV0, node[i]->element);
293             return(0);
294         }
295
296         
297         /* Checking for additional entries */
298         if(node[i]->attributes[1] && node[i]->values[1])
299         {
300             if(strcasecmp(node[i]->attributes[0],xml_decoder_status)!= 0)
301             {
302                 merror(XML_INVELEM, ARGV0, node[i]->element);
303                 return(0);
304             }
305             
306             if(node[i]->attributes[2])
307             {
308                 merror(XML_INVELEM, ARGV0, node[i]->element);
309                 return(0);
310             }
311         }
312
313          
314         /* Getting decoder options */
315         elements = OS_GetElementsbyNode(&xml,node[i]);
316         if(elements == NULL)
317         {
318             merror(XML_ELEMNULL, ARGV0);
319             return(0);
320         }
321
322         /* Creating the OSDecoderInfo */
323         pi = (OSDecoderInfo *)calloc(1,sizeof(OSDecoderInfo));
324         if(pi == NULL)
325         {
326             merror(MEM_ERROR,ARGV0);
327             return(0);
328         }
329         
330         
331         /* Default values to the list */
332         pi->parent = NULL;
333         pi->id = 0;
334         pi->name = strdup(node[i]->values[0]);
335         pi->order = NULL;
336         pi->plugindecoder = NULL;
337         pi->fts = 0;
338         pi->type = SYSLOG;
339         pi->prematch = NULL;
340         pi->program_name = NULL;
341         pi->regex = NULL;
342         pi->use_own_name = 0;
343         pi->get_next = 0;
344         pi->regex_offset = 0;
345         pi->prematch_offset = 0;
346         
347         regex = NULL;
348         prematch = NULL;
349         p_name = NULL;
350        
351        
352         /* Checking if strdup worked */
353         if(!pi->name)
354         {
355             merror(MEM_ERROR, ARGV0);
356             return(0);
357         }
358         
359         /* Add decoder */
360         if(!addDecoder2list(pi->name))
361         {
362             merror(MEM_ERROR, ARGV0);
363             return(0);
364         }
365
366         /* Looping on all the elements */
367         while(elements[j])
368         {
369             if(!elements[j]->element)
370             {
371                 merror(XML_ELEMNULL, ARGV0);
372                 return(0);
373             }
374             else if(!elements[j]->content)
375             {
376                 merror(XML_VALUENULL, ARGV0, elements[j]->element);
377                 return(0);
378             }
379                                                                                                                     
380             /* Checking if it is a child of a rule */
381             else if(strcasecmp(elements[j]->element, xml_parent) == 0)
382             {
383                 pi->parent = _loadmemory(pi->parent, elements[j]->content);
384             }
385             
386             /* Getting the regex */
387             else if(strcasecmp(elements[j]->element,xml_regex) == 0)
388             {
389                 int r_offset;
390                 r_offset = ReadDecodeAttrs(elements[j]->attributes,
391                                            elements[j]->values);
392                 
393                 if(r_offset & AFTER_ERROR)
394                 {
395                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
396                     return(0);
397                 }
398                 
399                 /* Only the first regex entry may have an offset */ 
400                 if(regex && r_offset)
401                 {
402                     merror(DUP_REGEX, ARGV0, pi->name);
403                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
404                     return(0);
405                 }
406                 
407                 /* regex offset */
408                 if(r_offset)
409                 {
410                     pi->regex_offset = r_offset;
411                 }
412                 
413                 /* Assign regex */
414                 regex =
415                     _loadmemory(regex,
416                             elements[j]->content);
417             }
418             
419             /* Getting the pre match */
420             else if(strcasecmp(elements[j]->element,xml_prematch)==0)
421             {
422                 int r_offset;
423                 
424                 r_offset = ReadDecodeAttrs(
425                                       elements[j]->attributes,
426                                       elements[j]->values);
427
428                 if(r_offset & AFTER_ERROR)
429                 {
430                     ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name);
431                 }
432
433                 
434                 /* Only the first prematch entry may have an offset */
435                 if(prematch && r_offset)
436                 {
437                     merror(DUP_REGEX, ARGV0, pi->name);
438                     ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name);
439                 }
440
441                 if(r_offset)
442                 {
443                     pi->prematch_offset = r_offset;
444                 }
445                 
446                 prematch =
447                     _loadmemory(prematch,
448                             elements[j]->content);
449             }
450
451             /* Getting program name */
452             else if(strcasecmp(elements[j]->element,xml_program_name) == 0)
453             {
454                 p_name = _loadmemory(p_name, elements[j]->content);
455             }
456
457             /* Getting the fts comment */
458             else if(strcasecmp(elements[j]->element,xml_ftscomment)==0)
459             {
460             }
461
462             else if(strcasecmp(elements[j]->element,xml_usename)==0)
463             {
464                 if(strcmp(elements[j]->content,"true") == 0)
465                     pi->use_own_name = 1;
466             }
467
468             else if(strcasecmp(elements[j]->element, xml_plugindecoder) == 0)
469             {
470                 int ed_c = 0;
471                 for(ed_c = 0; plugin_decoders[ed_c] != NULL; ed_c++)
472                 {
473                     if(strcmp(plugin_decoders[ed_c], 
474                               elements[j]->content) == 0)
475                     {
476                         /* Initializing plugin */
477                         void (*dec_init)() = plugin_decoders_init[ed_c];
478
479                         dec_init();
480                         pi->plugindecoder = plugin_decoders_exec[ed_c];
481                         break;
482                     }
483                 }
484
485                 /* Decoder not found */
486                 if(pi->plugindecoder == NULL)
487                 {
488                     merror(INV_DECOPTION, ARGV0, elements[j]->element,
489                                           elements[j]->content);
490                     return(0);
491                 }
492             }
493                                                                                 
494             
495             /* Getting the type */
496             else if(strcmp(elements[j]->element, xml_type) == 0)
497             {
498                 if(strcmp(elements[j]->content, "firewall") == 0)
499                     pi->type = FIREWALL;
500                 else if(strcmp(elements[j]->content, "ids") == 0)
501                     pi->type = IDS;
502                 else if(strcmp(elements[j]->content, "web-log") == 0)
503                     pi->type = WEBLOG;    
504                 else if(strcmp(elements[j]->content, "syslog") == 0)
505                     pi->type = SYSLOG;
506                 else if(strcmp(elements[j]->content, "squid") == 0)
507                     pi->type = SQUID;
508                 else if(strcmp(elements[j]->content, "windows") == 0)
509                     pi->type = WINDOWS;        
510                 else if(strcmp(elements[j]->content, "host-information") == 0)
511                     pi->type = HOST_INFO;
512                 else if(strcmp(elements[j]->content, "ossec") == 0)
513                     pi->type = OSSEC_RL;    
514                 else
515                 {
516                     merror("%s: Invalid decoder type '%s'.",
517                                ARGV0, elements[j]->content);
518                     return(0);
519                 }
520             }
521                          
522             /* Getting the order */
523             else if(strcasecmp(elements[j]->element,xml_order)==0)
524             {
525                 char **norder, **s_norder;
526                 int order_int = 0;
527                 
528                 /* Maximum number is 8 for the order */
529                 norder = OS_StrBreak(',',elements[j]->content, 8);
530                 s_norder = norder;
531                 os_calloc(8, sizeof(void *), pi->order);
532
533
534                 /* Initializing the function pointers */
535                 while(order_int < 8)
536                 {
537                     pi->order[order_int] = NULL;
538                     order_int++;
539                 }
540                 order_int = 0;
541                 
542
543                 /* Checking the values from the order */
544                 while(*norder)
545                 {
546                     if(strstr(*norder, "dstuser") != NULL)
547                     {
548                         pi->order[order_int] = (void *)DstUser_FP;
549                     }
550                     else if(strstr(*norder, "srcuser") != NULL)
551                     {
552                         pi->order[order_int] = (void *)SrcUser_FP;
553                     }
554                     /* User is an alias to dstuser */
555                     else if(strstr(*norder, "user") != NULL)
556                     {
557                         pi->order[order_int] = (void *)DstUser_FP;
558                     }
559                     else if(strstr(*norder, "srcip") != NULL)
560                     {
561                         pi->order[order_int] = (void *)SrcIP_FP;
562                     }
563                     else if(strstr(*norder, "dstip") != NULL)
564                     {
565                         pi->order[order_int] = (void *)DstIP_FP;
566                     }
567                     else if(strstr(*norder, "srcport") != NULL)
568                     {
569                         pi->order[order_int] = (void *)SrcPort_FP;
570                     }
571                     else if(strstr(*norder, "dstport") != NULL)
572                     {
573                         pi->order[order_int] = (void *)DstPort_FP;
574                     }
575                     else if(strstr(*norder, "protocol") != NULL)
576                     {
577                         pi->order[order_int] = (void *)Protocol_FP;
578                     }
579                     else if(strstr(*norder, "action") != NULL)
580                     {
581                         pi->order[order_int] = (void *)Action_FP;
582                     }
583                     else if(strstr(*norder, "id") != NULL)
584                     {
585                         pi->order[order_int] = (void *)ID_FP;
586                     }
587                     else if(strstr(*norder, "url") != NULL)
588                     {
589                         pi->order[order_int] = (void *)Url_FP;
590                     }
591                     else if(strstr(*norder, "data") != NULL)
592                     {
593                         pi->order[order_int] = (void *)Data_FP;
594                     }
595                     else if(strstr(*norder, "extra_data") != NULL)
596                     {
597                         pi->order[order_int] = (void *)Data_FP;
598                     }
599                     else if(strstr(*norder, "status") != NULL)
600                     {
601                         pi->order[order_int] = (void *)Status_FP;
602                     }
603                     else if(strstr(*norder, "system_name") != NULL)
604                     {
605                         pi->order[order_int] = (void *)SystemName_FP;
606                     }
607                     else
608                     {
609                         ErrorExit("decode-xml: Wrong field '%s' in the order"
610                                   " of decoder '%s'",*norder,pi->name);
611                     }
612
613                     free(*norder);
614                     norder++;
615
616                     order_int++;
617                 }
618
619                 free(s_norder);
620             }
621             
622             /* Getting the fts order */
623             else if(strcasecmp(elements[j]->element,xml_fts)==0)
624             {
625                 char **norder;
626                 char **s_norder;
627                 
628                 /* Maximum number is 8 for the fts */
629                 norder = OS_StrBreak(',',elements[j]->content, 8);
630                 if(norder == NULL)
631                     ErrorExit(MEM_ERROR,ARGV0);
632                 
633                 
634                 /* Saving the initial point to free later */
635                 s_norder = norder;
636                 
637                     
638                 /* Checking the values from the fts */
639                 while(*norder)
640                 {
641                     if(strstr(*norder, "dstuser") != NULL)
642                     {
643                         pi->fts|=FTS_DSTUSER;
644                     }
645                     if(strstr(*norder, "user") != NULL)
646                     {
647                         pi->fts|=FTS_DSTUSER;
648                     }
649                     else if(strstr(*norder, "srcuser") != NULL)
650                     {
651                         pi->fts|=FTS_SRCUSER;
652                     }
653                     else if(strstr(*norder, "srcip") != NULL)
654                     {
655                         pi->fts|=FTS_SRCIP;
656                     }
657                     else if(strstr(*norder, "dstip") != NULL)
658                     {
659                         pi->fts|=FTS_DSTIP;
660                     }
661                     else if(strstr(*norder, "id") != NULL)
662                     {
663                         pi->fts|=FTS_ID;
664                     }
665                     else if(strstr(*norder, "location") != NULL)
666                     {
667                         pi->fts|=FTS_LOCATION;
668                     }
669                     else if(strstr(*norder, "data") != NULL)
670                     {
671                         pi->fts|=FTS_DATA;
672                     }
673                     else if(strstr(*norder, "extra_data") != NULL)
674                     {
675                         pi->fts|=FTS_DATA;
676                     }
677                     else if(strstr(*norder, "system_name") != NULL)
678                     {
679                         pi->fts|=FTS_SYSTEMNAME;
680                     }
681                     else if(strstr(*norder, "name") != NULL)
682                     {
683                         pi->fts|=FTS_NAME;
684                     }
685                     else
686                     {
687                         ErrorExit("decode-xml: Wrong field '%s' in the fts"
688                                   " decoder '%s'",*norder, pi->name);
689                     }
690
691                     free(*norder);
692                     norder++;
693                 }
694
695                 /* Clearing the memory here */
696                 free(s_norder);
697             }
698             else
699             {
700                 merror("%s: Invalid element '%s' for "
701                         "decoder '%s'",
702                         ARGV0,
703                         elements[j]->element,
704                         node[i]->element);
705                 return(0);
706             }
707
708             /* NEXT */
709             j++;
710             
711         } /* while(elements[j]) */
712         
713         OS_ClearNode(elements);
714         
715
716         /* Prematch must be set */
717         if(!prematch && !pi->parent && !p_name)
718         {
719             merror(DECODE_NOPRE, ARGV0, pi->name);
720             merror(DEC_REGEX_ERROR, ARGV0, pi->name);
721             return(0);
722         }
723
724         /* If pi->regex is not set, fts must not be set too */
725         if((!regex && (pi->fts || pi->order)) || (regex && !pi->order))
726         {
727             merror(DEC_REGEX_ERROR, ARGV0, pi->name);
728             return(0);
729         }
730         
731
732         /* For the offsets */
733         if(pi->regex_offset & AFTER_PARENT && !pi->parent)
734         {
735             merror(INV_OFFSET, ARGV0, "after_parent");
736             merror(DEC_REGEX_ERROR, ARGV0, pi->name);
737             return(0);
738         }
739         
740         if(pi->regex_offset & AFTER_PREMATCH)
741         {
742             /* If after_prematch is set, but rule have
743              * no parent, set AFTER_PARENT and unset
744              * pre_match.
745              */
746             if(!pi->parent)
747             {
748                 pi->regex_offset = 0;
749                 pi->regex_offset|= AFTER_PARENT;
750             }
751             else if(!prematch)
752             {
753                 merror(INV_OFFSET, ARGV0, "after_prematch");
754                 merror(DEC_REGEX_ERROR, ARGV0, pi->name);
755                 return(0);
756             }
757         }
758         
759         /* For the after_regex offset */
760         if(pi->regex_offset & AFTER_PREVREGEX)
761         {
762             if(!pi->parent || !regex)
763             {
764                 merror(INV_OFFSET, ARGV0, "after_regex");
765                 merror(DEC_REGEX_ERROR, ARGV0, pi->name);
766                 return(0);
767             }
768         }
769         
770
771         /* Checking the prematch offset */
772         if(pi->prematch_offset)
773         {
774             /* Only the after parent is allowed */
775             if(pi->prematch_offset & AFTER_PARENT)
776             {
777                 if(!pi->parent)
778                 {
779                     merror(INV_OFFSET, ARGV0, "after_parent");
780                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
781                     return(0);
782                 }
783             }
784             else
785             {
786                 merror(DEC_REGEX_ERROR, ARGV0, pi->name);
787                 return(0);
788             }
789         }
790
791         
792         /* Compiling the regex/prematch */
793         if(prematch)
794         {
795             os_calloc(1, sizeof(OSRegex), pi->prematch);
796             if(!OSRegex_Compile(prematch, pi->prematch, 0))
797             {
798                 merror(REGEX_COMPILE, ARGV0, prematch, pi->prematch->error);
799                 return(0);
800             }
801
802             free(prematch);
803         }
804         
805         /* Compiling the p_name */
806         if(p_name)
807         {
808             os_calloc(1, sizeof(OSMatch), pi->program_name);
809             if(!OSMatch_Compile(p_name, pi->program_name, 0))
810             {
811                 merror(REGEX_COMPILE, ARGV0, p_name, pi->program_name->error);
812                 return(0);
813             }
814
815             free(p_name);
816         }
817         
818         /* We may not have the pi->regex */
819         if(regex)
820         {
821             os_calloc(1, sizeof(OSRegex), pi->regex);
822             if(!OSRegex_Compile(regex, pi->regex, OS_RETURN_SUBSTRING))
823             {
824                 merror(REGEX_COMPILE, ARGV0, regex, pi->regex->error);
825                 return(0);
826             }
827
828             /* We must have the sub_strings to retrieve the nodes */
829             if(!pi->regex->sub_strings)
830             {
831                 merror(REGEX_SUBS, ARGV0, regex);
832                 return(0);
833             }
834
835             free(regex);
836         }
837
838
839         /* Validating arguments */
840         if(pi->plugindecoder && (pi->regex || pi->order))
841         {
842             merror(DECODE_ADD, ARGV0, pi->name);
843             return(0);
844         }
845         
846         /* Adding osdecoder to the list */
847         if(!OS_AddOSDecoder(pi))
848         {
849             merror(DECODER_ERROR, ARGV0);        
850             return(0);
851         }
852
853         i++;
854     } /* while (node[i]) */
855
856
857     /* Cleaning  node and XML structures */
858     OS_ClearNode(node);
859
860     
861     OS_ClearXML(&xml);
862
863
864     /* Done over here */
865     return(1);
866 }
867
868
869
870 int SetDecodeXML()
871 {    
872     /* Adding rootcheck decoder to list */
873     addDecoder2list(ROOTCHECK_MOD);
874     addDecoder2list(SYSCHECK_MOD);
875     addDecoder2list(SYSCHECK_MOD2);
876     addDecoder2list(SYSCHECK_MOD3);
877     addDecoder2list(SYSCHECK_NEW);
878     addDecoder2list(SYSCHECK_DEL);
879     addDecoder2list(HOSTINFO_NEW);
880     addDecoder2list(HOSTINFO_MOD);
881
882
883     /* Setting ids - for our two lists */
884     if(!os_setdecoderids(NULL))
885     {
886         merror(DECODER_ERROR, ARGV0);
887         return(0);
888     }
889     if(!os_setdecoderids(ARGV0))
890     {
891         merror(DECODER_ERROR, ARGV0);
892         return(0);
893     }
894
895
896     /* Done over here */
897     return(1);
898 }
899
900
901 /* _loadmemory: v0.1
902  * Allocate memory at "*at" and copy *str to it.
903  * If *at already exist, realloc the memory and cat str
904  * on it.
905  * It will return the new string
906  */
907 char *_loadmemory(char *at, char *str)
908 {
909     if(at == NULL)
910     {
911         int strsize = 0;
912         if((strsize = strlen(str)) < OS_SIZE_1024)
913         {
914             at = calloc(strsize+1,sizeof(char));
915             if(at == NULL)
916             {
917                 merror(MEM_ERROR,ARGV0);
918                 return(NULL);
919             }
920             strncpy(at,str,strsize);
921             return(at);
922         }
923         else
924         {
925             merror(SIZE_ERROR,ARGV0,str);
926             return(NULL);
927         }
928     }
929     /* At is not null. Need to reallocat its memory and copy str to it */
930     else
931     {
932         int strsize = strlen(str);
933         int atsize = strlen(at);
934         int finalsize = atsize+strsize+1;
935         if(finalsize > OS_SIZE_1024)
936         {
937             merror(SIZE_ERROR,ARGV0,str);
938             return(NULL);
939         }
940         at = realloc(at, (finalsize +1)*sizeof(char));
941         if(at == NULL)
942         {
943             merror(MEM_ERROR,ARGV0);
944             return(NULL);
945         }
946         strncat(at,str,strsize);
947         at[finalsize - 1] = '\0';
948
949         return(at);
950     }
951     return(NULL);
952 }
953
954 /* EOF */