6840ec8b862c374cab590b1f11da78f652621b88
[ossec-hids.git] / src / analysisd / decoders / decode-xml.c
1 /* @(#) $Id$ */
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  * 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     debug1("ReadDecoderXML File = %s", file);
199     OS_XML xml;
200     XML_NODE node = NULL;
201
202     /* XML variables */ 
203     /* These are the available options for the rule configuration */
204     
205     char *xml_plugindecoder = "plugin_decoder";
206     char *xml_decoder = "decoder";
207     char *xml_decoder_name = "name";
208     char *xml_decoder_status = "status";
209     char *xml_usename = "use_own_name";
210     char *xml_parent = "parent";
211     char *xml_program_name = "program_name";
212     char *xml_prematch = "prematch";
213     char *xml_regex = "regex";
214     char *xml_order = "order";
215     char *xml_type = "type";
216     char *xml_fts = "fts";
217     char *xml_ftscomment = "ftscomment";
218
219     int i = 0;
220     OSDecoderInfo *NULL_Decoder_tmp = NULL;
221     
222      
223     /* Reading the XML */       
224     if((i = OS_ReadXML(file,&xml)) < 0)
225     {
226         if((i == -2) && (strcmp(file, XML_LDECODER) == 0))
227         {
228             return(-2);
229         }
230         
231         merror(XML_ERROR, ARGV0, file, xml.err, xml.err_line);
232         return(0);
233     }
234
235     
236     /* Applying any variable found */
237     if(OS_ApplyVariables(&xml) != 0)
238     {
239         merror(XML_ERROR_VAR, ARGV0, file, xml.err);
240         return(0);
241     }
242
243
244     /* Getting the root elements */
245     node = OS_GetElementsbyNode(&xml, NULL);
246     if(!node)
247     {
248         if(strcmp(file, XML_LDECODER) != 0)
249         {
250             merror(XML_ELEMNULL, ARGV0);
251             return(0);
252         }
253
254         return(-2);
255     }
256
257
258     /* Zeroing NULL_decoder */
259     os_calloc(1, sizeof(OSDecoderInfo), NULL_Decoder_tmp);
260     NULL_Decoder_tmp->id = 0;
261     NULL_Decoder_tmp->type = SYSLOG;
262     NULL_Decoder_tmp->name = NULL;
263     NULL_Decoder_tmp->fts = 0;
264     NULL_Decoder = (void *)NULL_Decoder_tmp;
265
266
267     
268     i = 0;
269     while(node[i])
270     {
271         XML_NODE elements = NULL;
272         OSDecoderInfo *pi;
273
274         int j = 0;
275         char *regex;
276         char *prematch;
277         char *p_name;
278
279         
280         if(!node[i]->element || 
281             strcasecmp(node[i]->element, xml_decoder) != 0)
282         {
283             merror(XML_INVELEM, ARGV0, node[i]->element);
284             return(0);
285         }
286        
287
288         /* Getting name */
289         if((!node[i]->attributes) || (!node[i]->values)||
290            (!node[i]->values[0])  || (!node[i]->attributes[0])||
291            (strcasecmp(node[i]->attributes[0],xml_decoder_name)!= 0))
292         {
293             merror(XML_INVELEM, ARGV0, node[i]->element);
294             return(0);
295         }
296
297         
298         /* Checking for additional entries */
299         if(node[i]->attributes[1] && node[i]->values[1])
300         {
301             if(strcasecmp(node[i]->attributes[0],xml_decoder_status)!= 0)
302             {
303                 merror(XML_INVELEM, ARGV0, node[i]->element);
304                 return(0);
305             }
306             
307             if(node[i]->attributes[2])
308             {
309                 merror(XML_INVELEM, ARGV0, node[i]->element);
310                 return(0);
311             }
312         }
313
314          
315         /* Getting decoder options */
316         elements = OS_GetElementsbyNode(&xml,node[i]);
317         if(elements == NULL)
318         {
319             merror(XML_ELEMNULL, ARGV0);
320             return(0);
321         }
322
323         /* Creating the OSDecoderInfo */
324         pi = (OSDecoderInfo *)calloc(1,sizeof(OSDecoderInfo));
325         if(pi == NULL)
326         {
327             merror(MEM_ERROR,ARGV0);
328             return(0);
329         }
330         
331         
332         /* Default values to the list */
333         pi->parent = NULL;
334         pi->id = 0;
335         pi->name = strdup(node[i]->values[0]);
336         pi->order = NULL;
337         pi->plugindecoder = NULL;
338         pi->fts = 0;
339         pi->type = SYSLOG;
340         pi->prematch = NULL;
341         pi->program_name = NULL;
342         pi->regex = NULL;
343         pi->use_own_name = 0;
344         pi->get_next = 0;
345         pi->regex_offset = 0;
346         pi->prematch_offset = 0;
347         
348         regex = NULL;
349         prematch = NULL;
350         p_name = NULL;
351        
352        
353         /* Checking if strdup worked */
354         if(!pi->name)
355         {
356             merror(MEM_ERROR, ARGV0);
357             return(0);
358         }
359         
360         /* Add decoder */
361         if(!addDecoder2list(pi->name))
362         {
363             merror(MEM_ERROR, ARGV0);
364             return(0);
365         }
366
367         /* Looping on all the elements */
368         while(elements[j])
369         {
370             if(!elements[j]->element)
371             {
372                 merror(XML_ELEMNULL, ARGV0);
373                 return(0);
374             }
375             else if(!elements[j]->content)
376             {
377                 merror(XML_VALUENULL, ARGV0, elements[j]->element);
378                 return(0);
379             }
380                                                                                                                     
381             /* Checking if it is a child of a rule */
382             else if(strcasecmp(elements[j]->element, xml_parent) == 0)
383             {
384                 pi->parent = _loadmemory(pi->parent, elements[j]->content);
385             }
386             
387             /* Getting the regex */
388             else if(strcasecmp(elements[j]->element,xml_regex) == 0)
389             {
390                 int r_offset;
391                 r_offset = ReadDecodeAttrs(elements[j]->attributes,
392                                            elements[j]->values);
393                 
394                 if(r_offset & AFTER_ERROR)
395                 {
396                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
397                     return(0);
398                 }
399                 
400                 /* Only the first regex entry may have an offset */ 
401                 if(regex && r_offset)
402                 {
403                     merror(DUP_REGEX, ARGV0, pi->name);
404                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
405                     return(0);
406                 }
407                 
408                 /* regex offset */
409                 if(r_offset)
410                 {
411                     pi->regex_offset = r_offset;
412                 }
413                 
414                 /* Assign regex */
415                 regex =
416                     _loadmemory(regex,
417                             elements[j]->content);
418             }
419             
420             /* Getting the pre match */
421             else if(strcasecmp(elements[j]->element,xml_prematch)==0)
422             {
423                 int r_offset;
424                 
425                 r_offset = ReadDecodeAttrs(
426                                       elements[j]->attributes,
427                                       elements[j]->values);
428
429                 if(r_offset & AFTER_ERROR)
430                 {
431                     ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name);
432                 }
433
434                 
435                 /* Only the first prematch entry may have an offset */
436                 if(prematch && r_offset)
437                 {
438                     merror(DUP_REGEX, ARGV0, pi->name);
439                     ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name);
440                 }
441
442                 if(r_offset)
443                 {
444                     pi->prematch_offset = r_offset;
445                 }
446                 
447                 prematch =
448                     _loadmemory(prematch,
449                             elements[j]->content);
450             }
451
452             /* Getting program name */
453             else if(strcasecmp(elements[j]->element,xml_program_name) == 0)
454             {
455                 p_name = _loadmemory(p_name, elements[j]->content);
456             }
457
458             /* Getting the fts comment */
459             else if(strcasecmp(elements[j]->element,xml_ftscomment)==0)
460             {
461             }
462
463             else if(strcasecmp(elements[j]->element,xml_usename)==0)
464             {
465                 if(strcmp(elements[j]->content,"true") == 0)
466                     pi->use_own_name = 1;
467             }
468
469             else if(strcasecmp(elements[j]->element, xml_plugindecoder) == 0)
470             {
471                 int ed_c = 0;
472                 for(ed_c = 0; plugin_decoders[ed_c] != NULL; ed_c++)
473                 {
474                     if(strcmp(plugin_decoders[ed_c], 
475                               elements[j]->content) == 0)
476                     {
477                         /* Initializing plugin */
478                         void (*dec_init)() = plugin_decoders_init[ed_c];
479
480                         dec_init();
481                         pi->plugindecoder = plugin_decoders_exec[ed_c];
482                         break;
483                     }
484                 }
485
486                 /* Decoder not found */
487                 if(pi->plugindecoder == NULL)
488                 {
489                     merror(INV_DECOPTION, ARGV0, elements[j]->element,
490                                           elements[j]->content);
491                     return(0);
492                 }
493             }
494                                                                                 
495             
496             /* Getting the type */
497             else if(strcmp(elements[j]->element, xml_type) == 0)
498             {
499                 if(strcmp(elements[j]->content, "firewall") == 0)
500                     pi->type = FIREWALL;
501                 else if(strcmp(elements[j]->content, "ids") == 0)
502                     pi->type = IDS;
503                 else if(strcmp(elements[j]->content, "web-log") == 0)
504                     pi->type = WEBLOG;    
505                 else if(strcmp(elements[j]->content, "syslog") == 0)
506                     pi->type = SYSLOG;
507                 else if(strcmp(elements[j]->content, "squid") == 0)
508                     pi->type = SQUID;
509                 else if(strcmp(elements[j]->content, "windows") == 0)
510                     pi->type = WINDOWS;        
511                 else if(strcmp(elements[j]->content, "host-information") == 0)
512                     pi->type = HOST_INFO;
513                 else if(strcmp(elements[j]->content, "ossec") == 0)
514                     pi->type = OSSEC_RL;    
515                 else
516                 {
517                     merror("%s: Invalid decoder type '%s'.",
518                                ARGV0, elements[j]->content);
519                     return(0);
520                 }
521             }
522                          
523             /* Getting the order */
524             else if(strcasecmp(elements[j]->element,xml_order)==0)
525             {
526                 char **norder, **s_norder;
527                 int order_int = 0;
528                 
529                 /* Maximum number is 8 for the order */
530                 norder = OS_StrBreak(',',elements[j]->content, 8);
531                 s_norder = norder;
532                 os_calloc(8, sizeof(void *), pi->order);
533
534
535                 /* Initializing the function pointers */
536                 while(order_int < 8)
537                 {
538                     pi->order[order_int] = NULL;
539                     order_int++;
540                 }
541                 order_int = 0;
542                 
543
544                 /* Checking the values from the order */
545                 while(*norder)
546                 {
547                     if(strstr(*norder, "dstuser") != NULL)
548                     {
549                         pi->order[order_int] = (void *)DstUser_FP;
550                     }
551                     else if(strstr(*norder, "srcuser") != NULL)
552                     {
553                         pi->order[order_int] = (void *)SrcUser_FP;
554                     }
555                     /* User is an alias to dstuser */
556                     else if(strstr(*norder, "user") != NULL)
557                     {
558                         pi->order[order_int] = (void *)DstUser_FP;
559                     }
560                     else if(strstr(*norder, "srcip") != NULL)
561                     {
562                         pi->order[order_int] = (void *)SrcIP_FP;
563                     }
564                     else if(strstr(*norder, "dstip") != NULL)
565                     {
566                         pi->order[order_int] = (void *)DstIP_FP;
567                     }
568                     else if(strstr(*norder, "srcport") != NULL)
569                     {
570                         pi->order[order_int] = (void *)SrcPort_FP;
571                     }
572                     else if(strstr(*norder, "dstport") != NULL)
573                     {
574                         pi->order[order_int] = (void *)DstPort_FP;
575                     }
576                     else if(strstr(*norder, "protocol") != NULL)
577                     {
578                         pi->order[order_int] = (void *)Protocol_FP;
579                     }
580                     else if(strstr(*norder, "action") != NULL)
581                     {
582                         pi->order[order_int] = (void *)Action_FP;
583                     }
584                     else if(strstr(*norder, "id") != NULL)
585                     {
586                         pi->order[order_int] = (void *)ID_FP;
587                     }
588                     else if(strstr(*norder, "url") != NULL)
589                     {
590                         pi->order[order_int] = (void *)Url_FP;
591                     }
592                     else if(strstr(*norder, "data") != NULL)
593                     {
594                         pi->order[order_int] = (void *)Data_FP;
595                     }
596                     else if(strstr(*norder, "extra_data") != NULL)
597                     {
598                         pi->order[order_int] = (void *)Data_FP;
599                     }
600                     else if(strstr(*norder, "status") != NULL)
601                     {
602                         pi->order[order_int] = (void *)Status_FP;
603                     }
604                     else if(strstr(*norder, "system_name") != NULL)
605                     {
606                         pi->order[order_int] = (void *)SystemName_FP;
607                     }
608                     else
609                     {
610                         ErrorExit("decode-xml: Wrong field '%s' in the order"
611                                   " of decoder '%s'",*norder,pi->name);
612                     }
613
614                     free(*norder);
615                     norder++;
616
617                     order_int++;
618                 }
619
620                 free(s_norder);
621             }
622             
623             /* Getting the fts order */
624             else if(strcasecmp(elements[j]->element,xml_fts)==0)
625             {
626                 char **norder;
627                 char **s_norder;
628                 
629                 /* Maximum number is 8 for the fts */
630                 norder = OS_StrBreak(',',elements[j]->content, 8);
631                 if(norder == NULL)
632                     ErrorExit(MEM_ERROR,ARGV0);
633                 
634                 
635                 /* Saving the initial point to free later */
636                 s_norder = norder;
637                 
638                     
639                 /* Checking the values from the fts */
640                 while(*norder)
641                 {
642                     if(strstr(*norder, "dstuser") != NULL)
643                     {
644                         pi->fts|=FTS_DSTUSER;
645                     }
646                     if(strstr(*norder, "user") != NULL)
647                     {
648                         pi->fts|=FTS_DSTUSER;
649                     }
650                     else if(strstr(*norder, "srcuser") != NULL)
651                     {
652                         pi->fts|=FTS_SRCUSER;
653                     }
654                     else if(strstr(*norder, "srcip") != NULL)
655                     {
656                         pi->fts|=FTS_SRCIP;
657                     }
658                     else if(strstr(*norder, "dstip") != NULL)
659                     {
660                         pi->fts|=FTS_DSTIP;
661                     }
662                     else if(strstr(*norder, "id") != NULL)
663                     {
664                         pi->fts|=FTS_ID;
665                     }
666                     else if(strstr(*norder, "location") != NULL)
667                     {
668                         pi->fts|=FTS_LOCATION;
669                     }
670                     else if(strstr(*norder, "data") != NULL)
671                     {
672                         pi->fts|=FTS_DATA;
673                     }
674                     else if(strstr(*norder, "extra_data") != NULL)
675                     {
676                         pi->fts|=FTS_DATA;
677                     }
678                     else if(strstr(*norder, "system_name") != NULL)
679                     {
680                         pi->fts|=FTS_SYSTEMNAME;
681                     }
682                     else if(strstr(*norder, "name") != NULL)
683                     {
684                         pi->fts|=FTS_NAME;
685                     }
686                     else
687                     {
688                         ErrorExit("decode-xml: Wrong field '%s' in the fts"
689                                   " decoder '%s'",*norder, pi->name);
690                     }
691
692                     free(*norder);
693                     norder++;
694                 }
695
696                 /* Clearing the memory here */
697                 free(s_norder);
698             }
699             else
700             {
701                 merror("%s: Invalid element '%s' for "
702                         "decoder '%s'",
703                         ARGV0,
704                         elements[j]->element,
705                         node[i]->element);
706                 return(0);
707             }
708
709             /* NEXT */
710             j++;
711             
712         } /* while(elements[j]) */
713         
714         OS_ClearNode(elements);
715         
716
717         /* Prematch must be set */
718         if(!prematch && !pi->parent && !p_name)
719         {
720             merror(DECODE_NOPRE, ARGV0, pi->name);
721             merror(DEC_REGEX_ERROR, ARGV0, pi->name);
722             return(0);
723         }
724
725         /* If pi->regex is not set, fts must not be set too */
726         if((!regex && (pi->fts || pi->order)) || (regex && !pi->order))
727         {
728             merror(DEC_REGEX_ERROR, ARGV0, pi->name);
729             return(0);
730         }
731         
732
733         /* For the offsets */
734         if(pi->regex_offset & AFTER_PARENT && !pi->parent)
735         {
736             merror(INV_OFFSET, ARGV0, "after_parent");
737             merror(DEC_REGEX_ERROR, ARGV0, pi->name);
738             return(0);
739         }
740         
741         if(pi->regex_offset & AFTER_PREMATCH)
742         {
743             /* If after_prematch is set, but rule have
744              * no parent, set AFTER_PARENT and unset
745              * pre_match.
746              */
747             if(!pi->parent)
748             {
749                 pi->regex_offset = 0;
750                 pi->regex_offset|= AFTER_PARENT;
751             }
752             else if(!prematch)
753             {
754                 merror(INV_OFFSET, ARGV0, "after_prematch");
755                 merror(DEC_REGEX_ERROR, ARGV0, pi->name);
756                 return(0);
757             }
758         }
759         
760         /* For the after_regex offset */
761         if(pi->regex_offset & AFTER_PREVREGEX)
762         {
763             if(!pi->parent || !regex)
764             {
765                 merror(INV_OFFSET, ARGV0, "after_regex");
766                 merror(DEC_REGEX_ERROR, ARGV0, pi->name);
767                 return(0);
768             }
769         }
770         
771
772         /* Checking the prematch offset */
773         if(pi->prematch_offset)
774         {
775             /* Only the after parent is allowed */
776             if(pi->prematch_offset & AFTER_PARENT)
777             {
778                 if(!pi->parent)
779                 {
780                     merror(INV_OFFSET, ARGV0, "after_parent");
781                     merror(DEC_REGEX_ERROR, ARGV0, pi->name);
782                     return(0);
783                 }
784             }
785             else
786             {
787                 merror(DEC_REGEX_ERROR, ARGV0, pi->name);
788                 return(0);
789             }
790         }
791
792         
793         /* Compiling the regex/prematch */
794         if(prematch)
795         {
796             os_calloc(1, sizeof(OSRegex), pi->prematch);
797             if(!OSRegex_Compile(prematch, pi->prematch, 0))
798             {
799                 merror(REGEX_COMPILE, ARGV0, prematch, pi->prematch->error);
800                 return(0);
801             }
802
803             free(prematch);
804         }
805         
806         /* Compiling the p_name */
807         if(p_name)
808         {
809             os_calloc(1, sizeof(OSMatch), pi->program_name);
810             if(!OSMatch_Compile(p_name, pi->program_name, 0))
811             {
812                 merror(REGEX_COMPILE, ARGV0, p_name, pi->program_name->error);
813                 return(0);
814             }
815
816             free(p_name);
817         }
818         
819         /* We may not have the pi->regex */
820         if(regex)
821         {
822             os_calloc(1, sizeof(OSRegex), pi->regex);
823             if(!OSRegex_Compile(regex, pi->regex, OS_RETURN_SUBSTRING))
824             {
825                 merror(REGEX_COMPILE, ARGV0, regex, pi->regex->error);
826                 return(0);
827             }
828
829             /* We must have the sub_strings to retrieve the nodes */
830             if(!pi->regex->sub_strings)
831             {
832                 merror(REGEX_SUBS, ARGV0, regex);
833                 return(0);
834             }
835
836             free(regex);
837         }
838
839
840         /* Validating arguments */
841         if(pi->plugindecoder && (pi->regex || pi->order))
842         {
843             merror(DECODE_ADD, ARGV0, pi->name);
844             return(0);
845         }
846         
847         /* Adding osdecoder to the list */
848         if(!OS_AddOSDecoder(pi))
849         {
850             merror(DECODER_ERROR, ARGV0);        
851             return(0);
852         }
853
854         i++;
855     } /* while (node[i]) */
856
857
858     /* Cleaning  node and XML structures */
859     OS_ClearNode(node);
860
861     
862     OS_ClearXML(&xml);
863
864
865     /* Done over here */
866     return(1);
867 }
868
869
870
871 int SetDecodeXML()
872 {    
873     /* Adding rootcheck decoder to list */
874     addDecoder2list(ROOTCHECK_MOD);
875     addDecoder2list(SYSCHECK_MOD);
876     addDecoder2list(SYSCHECK_MOD2);
877     addDecoder2list(SYSCHECK_MOD3);
878     addDecoder2list(SYSCHECK_NEW);
879     addDecoder2list(SYSCHECK_DEL);
880     addDecoder2list(HOSTINFO_NEW);
881     addDecoder2list(HOSTINFO_MOD);
882
883
884     /* Setting ids - for our two lists */
885     if(!os_setdecoderids(NULL))
886     {
887         merror(DECODER_ERROR, ARGV0);
888         return(0);
889     }
890     if(!os_setdecoderids(ARGV0))
891     {
892         merror(DECODER_ERROR, ARGV0);
893         return(0);
894     }
895
896
897     /* Done over here */
898     return(1);
899 }
900
901
902 /* _loadmemory: v0.1
903  * Allocate memory at "*at" and copy *str to it.
904  * If *at already exist, realloc the memory and cat str
905  * on it.
906  * It will return the new string
907  */
908 char *_loadmemory(char *at, char *str)
909 {
910     if(at == NULL)
911     {
912         int strsize = 0;
913         if((strsize = strlen(str)) < OS_SIZE_1024)
914         {
915             at = calloc(strsize+1,sizeof(char));
916             if(at == NULL)
917             {
918                 merror(MEM_ERROR,ARGV0);
919                 return(NULL);
920             }
921             strncpy(at,str,strsize);
922             return(at);
923         }
924         else
925         {
926             merror(SIZE_ERROR,ARGV0,str);
927             return(NULL);
928         }
929     }
930     /* At is not null. Need to reallocat its memory and copy str to it */
931     else
932     {
933         int strsize = strlen(str);
934         int atsize = strlen(at);
935         int finalsize = atsize+strsize+1;
936         if(finalsize > OS_SIZE_1024)
937         {
938             merror(SIZE_ERROR,ARGV0,str);
939             return(NULL);
940         }
941         at = realloc(at, (finalsize +1)*sizeof(char));
942         if(at == NULL)
943         {
944             merror(MEM_ERROR,ARGV0);
945             return(NULL);
946         }
947         strncat(at,str,strsize);
948         at[finalsize - 1] = '\0';
949
950         return(at);
951     }
952     return(NULL);
953 }
954
955 /* EOF */