f3c182d6b5f7d3dd1b62d21c94cdb40ed9302952
[ossec-hids.git] / decode-xml.c
1 /* @(#) $Id: ./src/analysisd/decoders/decode-xml.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All rights reserved.
6  *
7  * This program is a free software; you can redistribute it
8  * and/or modify it under the terms of the GNU General Public
9  * License (version 2) as published by the FSF - Free Software
10  * Foundation.
11  *
12  * License details at the LICENSE file included with OSSEC or
13  * online at: http://www.ossec.net/en/licensing.html
14  */
15
16
17 #include "shared.h"
18 #include "os_regex/os_regex.h"
19 #include "os_xml/os_xml.h"
20
21
22 #include "analysisd.h"
23 #include "eventinfo.h"
24 #include "decoder.h"
25 #include "plugin_decoders.h"
26
27
28 #ifdef TESTRULE
29   #undef XML_LDECODER
30   #define XML_LDECODER "etc/local_decoder.xml"
31 #endif
32
33
34 /* Internal functions */
35 char *_loadmemory(char *at, char *str);
36 OSStore *os_decoder_store = NULL;
37
38
39 /* Gets decoder id */
40 int getDecoderfromlist(char *name)
41 {
42     if(os_decoder_store)
43     {
44         return(OSStore_GetPosition(os_decoder_store, name));
45     }
46
47     return(0);
48 }
49
50
51 /* Adds decoder id */
52 int addDecoder2list(char *name)
53 {
54     if(os_decoder_store == NULL)
55     {
56         os_decoder_store = OSStore_Create();
57         if(os_decoder_store == NULL)
58         {
59             merror(LIST_ERROR, ARGV0);
60             return(0);
61         }
62     }
63
64     /* Storing data */
65     if(!OSStore_Put(os_decoder_store, name, NULL))
66     {
67         merror(LIST_ADD_ERROR, ARGV0);
68         return(0);
69     }
70
71     return(1);
72 }
73
74
75 /* Set decoder ids */
76 int os_setdecoderids(char *p_name)
77 {
78     OSDecoderNode *node;
79     OSDecoderNode *child_node;
80     OSDecoderInfo *nnode;
81
82
83     node = OS_GetFirstOSDecoder(p_name);
84
85
86     /* Return if no node...
87      * This shouldn't happen here anyways.
88      */
89     if(!node)
90         return(0);
91
92     do
93     {
94         int p_id = 0;
95         char *p_name;
96
97         nnode = node->osdecoder;
98         nnode->id = getDecoderfromlist(nnode->name);
99
100         /* Id can noit be 0 */
101         if(nnode->id == 0)
102         {
103             return(0);
104         }
105
106         child_node = node->child;
107
108         if(!child_node)
109         {
110             continue;
111         }
112
113
114         /* Setting parent id */
115         p_id = nnode->id;
116         p_name = nnode->name;
117
118
119         /* Also setting on the child nodes */
120         while(child_node)
121         {
122             nnode = child_node->osdecoder;
123
124             if(nnode->use_own_name)
125             {
126                 nnode->id = getDecoderfromlist(nnode->name);
127             }
128             else
129             {
130                 nnode->id = p_id;
131
132                 /* Setting parent name */
133                 nnode->name = p_name;
134             }
135
136
137             /* Id can noit be 0 */
138             if(nnode->id == 0)
139             {
140                 return(0);
141             }
142             child_node = child_node->next;
143         }
144     }while((node=node->next) != NULL);
145
146     return(1);
147 }
148
149
150 /* Read attributes */
151 int ReadDecodeAttrs(char **names, char **values)
152 {
153     if(!names || !values)
154         return(0);
155
156     if(!names[0] || !values[0])
157     {
158         return(0);
159     }
160
161     if(strcmp(names[0], "offset") == 0)
162     {
163         int offset = 0;
164
165         /* Offsets can be: after_parent, after_prematch
166          * or after_regex.
167          */
168         if(strcmp(values[0],"after_parent") == 0)
169         {
170             offset |= AFTER_PARENT;
171         }
172         else if(strcmp(values[0],"after_prematch") == 0)
173         {
174             offset |= AFTER_PREMATCH;
175         }
176         else if(strcmp(values[0],"after_regex") == 0)
177         {
178             offset |= AFTER_PREVREGEX;
179         }
180         else
181         {
182             merror(INV_OFFSET, ARGV0, values[0]);
183             offset |= AFTER_ERROR;
184         }
185
186         return(offset);
187     }
188
189     /* Invalid attribute */
190     merror(INV_ATTR, ARGV0, names[0]);
191     return(AFTER_ERROR);
192 }
193
194
195 /* ReaddecodeXML */
196 int ReadDecodeXML(char *file)
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 */