From b1db196953713dd09c499a3edf81347bd903c19e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 3 Nov 2009 18:44:02 +0100 Subject: one step closer to dynamically loadable parsers This is a milestone commit, which adds new code that breaks nothing, but also does not add any visible change. Just prep work... --- runtime/module-template.h | 14 +++- runtime/modules.c | 31 ++++++++- runtime/modules.h | 9 ++- runtime/parser.c | 165 ++++++++++++++++++++++++++++++++++++++++++++-- runtime/parser.h | 39 ++++++++--- runtime/queue.c | 1 - runtime/rsyslog.h | 4 ++ runtime/ruleset.h | 1 + runtime/syslogd-types.h | 5 +- tools/Makefile.am | 1 + tools/pmrfc5424.c | 9 +++ tools/pmrfc5424.h | 33 ++++++++++ tools/syslogd.c | 4 ++ 13 files changed, 290 insertions(+), 26 deletions(-) create mode 100644 tools/pmrfc5424.h diff --git a/runtime/module-template.h b/runtime/module-template.h index b136b6a3..18aad650 100644 --- a/runtime/module-template.h +++ b/runtime/module-template.h @@ -412,6 +412,8 @@ static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())\ CODEqueryEtryPt_STD_MOD_QUERIES \ else if(!strcmp((char*) name, "parse")) {\ *pEtryPoint = parse;\ + } else if(!strcmp((char*) name, "GetParserName")) {\ + *pEtryPoint = GetParserName;\ } /* modInit() @@ -604,7 +606,6 @@ static rsRetVal doHUP(instanceData __attribute__((unused)) *pData)\ } - /* parse() - main entry point of parser modules */ #define BEGINparse \ @@ -620,5 +621,16 @@ static rsRetVal parse(msg_t *pMsg)\ } +/* function to specify the parser name. This is done via a single command which + * receives a ANSI string as parameter. + */ +#define PARSER_NAME(x) \ +static rsRetVal GetParserName(uchar **ppSz)\ +{\ + *ppSz = UCHAR_CONSTANT(x);\ + return RS_RET_OK;\ +} + + /* vim:set ai: */ diff --git a/runtime/modules.c b/runtime/modules.c index 5321c5e8..41645a27 100644 --- a/runtime/modules.c +++ b/runtime/modules.c @@ -11,7 +11,7 @@ * * File begun on 2007-07-22 by RGerhards * - * Copyright 2007 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * @@ -57,10 +57,12 @@ #include "cfsysline.h" #include "modules.h" #include "errmsg.h" +#include "parser.h" /* static data */ DEFobjStaticHelpers DEFobjCurrIf(errmsg) +DEFobjCurrIf(parser) /* we must ensure that only one thread at one time tries to load or unload * modules, otherwise we may see race conditions. This first came up with @@ -94,7 +96,6 @@ static rsRetVal dummyEndTransaction() } static rsRetVal dummyIsCompatibleWithFeature() { -dbgprintf("XXX: dummy isCompatibleWithFeature called!\n"); return RS_RET_INCOMPATIBLE; } @@ -403,10 +404,13 @@ finalize_it: static rsRetVal doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_t*), uchar *name, void *pModHdlr) { - DEFiRet; rsRetVal localRet; modInfo_t *pNew = NULL; + uchar *pParserName; + parser_t *pParser; /* used for parser modules */ + rsRetVal (*GetParserName)(uchar**); rsRetVal (*modGetType)(eModType_t *pType); + DEFiRet; assert(modInit != NULL); @@ -476,7 +480,27 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_ case eMOD_LIB: break; case eMOD_PARSER: + /* first, we need to obtain the parser object. We could not do that during + * init as that would have caused class bootstrap issues which are not + * absolutely necessary. Note that we can call objUse() multiple times, it + * handles that. + */ + CHKiRet(objUse(parser, CORE_COMPONENT)); + /* here, we create a new parser object */ CHKiRet((*pNew->modQueryEtryPt)((uchar*)"parse", &pNew->mod.pm.parse)); + CHKiRet((*pNew->modQueryEtryPt)((uchar*)"GetParserName", &GetParserName)); + CHKiRet(GetParserName(&pParserName)); + CHKiRet(parser.Construct(&pParser)); + + /* check some features */ + localRet = pNew->isCompatibleWithFeature(sFEATUREAtomaticSanitazion); + if(localRet == RS_RET_OK){ + CHKiRet(parser.SetDoSanitazion(pParser, TRUE)); + } + + CHKiRet(parser.SetName(pParser, pParserName)); + CHKiRet(parser.SetModPtr(pParser, pNew)); + CHKiRet(parser.ConstructFinalize(pParser)); break; } @@ -873,6 +897,7 @@ BEGINObjClassExit(module, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MA CODESTARTObjClassExit(module) /* release objects we no longer need */ objRelease(errmsg, CORE_COMPONENT); + objRelease(parser, CORE_COMPONENT); /* We have a problem in our reference counting, which leads to this function * being called too early. This usually is no problem, but if we destroy * the mutex object, we get into trouble. So rather than finding the root cause, diff --git a/runtime/modules.h b/runtime/modules.h index e92760b8..62f86ded 100644 --- a/runtime/modules.h +++ b/runtime/modules.h @@ -12,7 +12,7 @@ * * File begun on 2007-07-22 by RGerhards * - * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007-2009 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * @@ -74,7 +74,7 @@ typedef enum eModLinkType_ { eMOD_LINK_ALL /* special: all linkage types, e.g. for unload */ } eModLinkType_t; -typedef struct modInfo_s { +struct modInfo_s { struct modInfo_s *pPrev; /* support for creating a double linked module list */ struct modInfo_s *pNext; /* support for creating a linked module list */ int iIFVers; /* Interface version of module */ @@ -130,7 +130,7 @@ typedef struct modInfo_s { */ modUsr_t *pModUsrRoot; # endif -} modInfo_t; +}; /* interfaces */ BEGINinterface(module) /* name must also be changed in ENDinterface macro! */ @@ -156,6 +156,5 @@ extern uchar *pModDir; /* read-only after startup */ #endif /* #ifndef MODULES_H_INCLUDED */ -/* - * vi:set ai: +/* vi:set ai: */ diff --git a/runtime/parser.c b/runtime/parser.c index e2ad69e4..f59d1974 100644 --- a/runtime/parser.c +++ b/runtime/parser.c @@ -55,20 +55,113 @@ DEFobjCurrIf(datetime) /* static data */ static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */ + /* config data */ static uchar cCCEscapeChar = '#';/* character to be used to start an escape sequence for control chars */ static int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */ static int bDropTrailingLF = 1; /* drop trailing LF's on reception? */ +/* we create a small helper list of parsers so that we can obtain their + * handles if the config needs one. This is also used to unload all modules on + * shutdown. + */ +parserList_t *pParsLstRoot = NULL; + + +/* intialize (but NOT allocate) a parser list. Primarily meant as a hook + * which can be used to extend the list in the future. So far, just sets + * it to NULL. + */ +static rsRetVal +InitParserList(parserList_t **pListRoot) +{ + *pListRoot = NULL; + return RS_RET_OK; +} + -/* we need to provide standard constructors and destructors, even though - * we only have static methods. The framework requires that. +/* Add a parser to the list. We use a VERY simple and ineffcient algorithm, + * but it is employed only for a few milliseconds during config processing. So + * I prefer to keep it very simple and with simple data structures. Unfortunately, + * we need to preserve the order, but I don't like to add a tail pointer as that + * would require a container object. So I do the extra work to skip to the tail + * when adding elements... + * rgerhards, 2009-11-03 */ +static rsRetVal +AddParserToList(parserList_t **ppListRoot, parser_t *pParser) +{ + parserList_t *pThis; + parserList_t *pTail; + DEFiRet; + + CHKmalloc(pThis = MALLOC(sizeof(parserList_t))); + pThis->pParser = pParser; + pThis->pNext = NULL; + + if(*ppListRoot == NULL) { + pThis->pNext = *ppListRoot; + *ppListRoot = pThis; + } else { + /* find tail first */ + for(pTail = *ppListRoot ; pTail->pNext != NULL ; pTail = pTail->pNext) + /* just search, do nothing else */; + /* add at tail */ + pTail->pNext = pThis; + } + +finalize_it: + RETiRet; +} + + +/* find a parser based on the provided name */ +static rsRetVal +FindParser(parser_t **ppParser, uchar *pName) +{ + parserList_t *pThis; + DEFiRet; + + for(pThis = pParsLstRoot ; pThis != NULL ; pThis = pThis->pNext) { + if(ustrcmp(pThis->pParser->pName, pName) == 0) { + *ppParser = pThis->pParser; + FINALIZE; /* found it, iRet still eq. OK! */ + } + } + + iRet = RS_RET_PARSER_NOT_FOUND; + +finalize_it: + RETiRet; +} + + +/* --- END helper functions for parser list handling --- */ + + BEGINobjConstruct(parser) /* be sure to specify the object type also in END macro! */ ENDobjConstruct(parser) +/* ConstructionFinalizer. The most important chore is to add the parser object + * to our global list of available parsers. + * rgerhards, 2009-11-03 + */ +rsRetVal parserConstructFinalize(parser_t *pThis) +{ + DEFiRet; + + ISOBJ_TYPE_assert(pThis, parser); + CHKiRet(AddParserToList(&pParsLstRoot, pThis)); + DBGPRINTF("parser '%s' added to list of available parser\n", pThis->pName); + +finalize_it: + RETiRet; +} + BEGINobjDestruct(parser) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(parser) + free(pThis->pName); + //TODO: free module! ENDobjDestruct(parser) /***************************RFC 5425 PARSER ******************************************************/ @@ -536,7 +629,7 @@ finalize_it: * rgerhards, 2007-09-14 */ static inline rsRetVal -sanitizeMessage(msg_t *pMsg) +SanitizeMsg(msg_t *pMsg) { DEFiRet; uchar *pszMsg; @@ -656,7 +749,7 @@ ParseMsg(msg_t *pMsg) if(pMsg->iLenRawMsg == 0) ABORT_FINALIZE(RS_RET_EMPTY_MSG); - CHKiRet(sanitizeMessage(pMsg)); + CHKiRet(SanitizeMsg(pMsg)); /* we needed to sanitize first, because we otherwise do not have a C-string we can print... */ DBGPRINTF("msg parser: flags %x, from '%s', msg '%s'\n", pMsg->msgFlags, getRcvFrom(pMsg), pMsg->pszRawMsg); @@ -712,6 +805,54 @@ finalize_it: RETiRet; } +/* set the parser name - string is copied over, call can continue to use it, + * but must free it if desired. + */ +static rsRetVal +SetName(parser_t *pThis, uchar *name) +{ + DEFiRet; + + ISOBJ_TYPE_assert(pThis, parser); + assert(name != NULL); + + if(pThis->pName != NULL) { + free(pThis->pName); + pThis->pName = NULL; + } + + CHKmalloc(pThis->pName = ustrdup(name)); + +finalize_it: + RETiRet; +} + + +/* set a pointer to "our" module. Note that no module + * pointer must already be set. + */ +static rsRetVal +SetModPtr(parser_t *pThis, modInfo_t *pMod) +{ + ISOBJ_TYPE_assert(pThis, parser); + assert(pMod != NULL); + assert(pThis->pModule == NULL); + pThis->pModule = pMod; + return RS_RET_OK; +} + + +/* Specify if we should do standard message sanitazion before we pass the data + * down to the parser. + */ +static rsRetVal +SetDoSanitazion(parser_t *pThis, int bDoIt) +{ + ISOBJ_TYPE_assert(pThis, parser); + pThis->bDoSanitazion = bDoIt; + return RS_RET_OK; +} + /* queryInterface function-- rgerhards, 2009-11-03 */ @@ -726,7 +867,17 @@ CODESTARTobjQueryInterface(parser) * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ + pIf->Construct = parserConstruct; + pIf->ConstructFinalize = parserConstructFinalize; + pIf->Destruct = parserDestruct; + pIf->SetName = SetName; + pIf->SetModPtr = SetModPtr; + pIf->SetDoSanitazion = SetDoSanitazion; pIf->ParseMsg = ParseMsg; + pIf->SanitizeMsg = SanitizeMsg; + pIf->InitParserList = InitParserList; + pIf->AddParserToList = AddParserToList; + pIf->FindParser = FindParser; finalize_it: ENDobjQueryInterface(parser) @@ -750,8 +901,8 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus * before anything else is called inside this class. * rgerhards, 2009-11-02 */ -//BEGINObjClassInit(parser, 1, OBJ_IS_CORE_MODULE) /* class, version */ -BEGINAbstractObjClassInit(parser, 1, OBJ_IS_CORE_MODULE) /* class, version */ +BEGINObjClassInit(parser, 1, OBJ_IS_CORE_MODULE) /* class, version */ +//BEGINAbstractObjClassInit(parser, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(errmsg, CORE_COMPONENT)); @@ -763,5 +914,7 @@ BEGINAbstractObjClassInit(parser, 1, OBJ_IS_CORE_MODULE) /* class, version */ CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); + + InitParserList(&pParsLstRoot); ENDObjClassInit(parser) diff --git a/runtime/parser.h b/runtime/parser.h index d5d9243d..47521f63 100644 --- a/runtime/parser.h +++ b/runtime/parser.h @@ -1,8 +1,6 @@ /* header for parser.c - * This is not yet an object, but contains all those code necessary to - * parse syslog messages. * - * Copyright 2008 Rainer Gerhards and Adiscon GmbH. + * Copyright 2008,2009 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * @@ -21,18 +19,43 @@ * * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ -#ifndef INCLUDED_PARSE_H -#define INCLUDED_PARSE_H +#ifndef INCLUDED_PARSER_H +#define INCLUDED_PARSER_H + + +/* we create a small helper object, a list of parsers, that we can use to + * build a chain of them whereever this is needed (initially thought to be + * used in ruleset.c as well as ourselvs). + */ +struct parserList_s { + parser_t *pParser; + parserList_t *pNext; +}; + /* the parser object, a dummy because we have only static methods */ -typedef struct parser_s { +struct parser_s { BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */ -} parser_t; + uchar *pName; /* name of this parser */ + modInfo_t *pModule; /* pointer to parser's module */ + bool bDoSanitazion; /* do standard message sanitazion before calling parser? */ +}; /* interfaces */ BEGINinterface(parser) /* name must also be changed in ENDinterface macro! */ INTERFACEObjDebugPrint(var); + rsRetVal (*Construct)(parser_t **ppThis); + rsRetVal (*ConstructFinalize)(parser_t *pThis); + rsRetVal (*Destruct)(parser_t **ppThis); + rsRetVal (*SetName)(parser_t *pThis, uchar *name); + rsRetVal (*SetModPtr)(parser_t *pThis, modInfo_t *pMod); + rsRetVal (*SetDoSanitazion)(parser_t *pThis, int); + rsRetVal (*FindParser)(parser_t **ppThis, uchar*name); + rsRetVal (*InitParserList)(parserList_t **pListRoot); + rsRetVal (*AddParserToList)(parserList_t **pListRoot, parser_t *pParser); + /* static functions */ rsRetVal (*ParseMsg)(msg_t *pMsg); + rsRetVal (*SanitizeMsg)(msg_t *pMsg); ENDinterface(parser) #define parserCURR_IF_VERSION 1 /* increment whenever you change the interface above! */ @@ -41,4 +64,4 @@ ENDinterface(parser) PROTOTYPEObj(parser); -#endif /* #ifndef INCLUDED_PARSE_H */ +#endif /* #ifndef INCLUDED_PARSER_H */ diff --git a/runtime/queue.c b/runtime/queue.c index d219d74d..ed4ba83e 100644 --- a/runtime/queue.c +++ b/runtime/queue.c @@ -1690,7 +1690,6 @@ ConsumerDA(qqueue_t *pThis, wti_t *pWti) /* iterate over returned results and enqueue them in DA queue */ for(i = 0 ; i < pWti->batch.nElem && !pThis->bShutdownImmediate ; i++) { - //for(i = 0 ; i < pWti->batch.nElem ; i++) { /* TODO: we must add a generic "addRef" mechanism, because the disk queue enqueue destructs * the message. So far, we simply assume we always have msg_t, what currently is always the case. * rgerhards, 2009-05-28 diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h index ef323c7d..4d029c08 100644 --- a/runtime/rsyslog.h +++ b/runtime/rsyslog.h @@ -134,6 +134,9 @@ typedef struct vmstk_s vmstk_t; typedef struct batch_obj_s batch_obj_t; typedef struct batch_s batch_t; typedef struct wtp_s wtp_t; +typedef struct modInfo_s modInfo_t; +typedef struct parser_s parser_t; +typedef struct parserList_s parserList_t; typedef rsRetVal (*prsf_t)(struct vmstk_s*, int); /* pointer to a RainerScript function */ typedef uint64 qDeqID; /* queue Dequeue order ID. 32 bits is considered dangerously few */ @@ -404,6 +407,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth RS_RET_NO_MSG_PASSING = -2156,/**< output module interface parameter passing mode "MSG" is not available but required */ RS_RET_RULESET_NOT_FOUND = -2157,/**< a required ruleset could not be found */ RS_RET_NO_RULESET= -2158,/**< no ruleset name as specified where one was needed */ + RS_RET_PARSER_NOT_FOUND = -2159,/**< parser with the specified name was not found */ /* RainerScript error messages (range 1000.. 1999) */ RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */ diff --git a/runtime/ruleset.h b/runtime/ruleset.h index deea9405..6c8f64b5 100644 --- a/runtime/ruleset.h +++ b/runtime/ruleset.h @@ -34,6 +34,7 @@ struct ruleset_s { linkedList_t llRules; /* this is NOT a pointer - no typo here ;) */ uchar *pszName; /* name of our ruleset */ qqueue_t *pQueue; /* "main" message queue, if the ruleset has its own (else NULL) */ + parserList_t *pParserLst;/* list of parsers to use for this ruleset */ }; /* interfaces */ diff --git a/runtime/syslogd-types.h b/runtime/syslogd-types.h index 161ee06f..49eeaa6a 100644 --- a/runtime/syslogd-types.h +++ b/runtime/syslogd-types.h @@ -56,8 +56,9 @@ * applications I do not yet envision. -- rgerhards, 2007-07-24 */ typedef enum _syslogFeature { - sFEATURERepeatedMsgReduction = 1, - sFEATURENonCancelInputTermination = 2 + sFEATURERepeatedMsgReduction = 1, /* for output modules */ + sFEATURENonCancelInputTermination = 2, /* for input modules */ + sFEATUREAtomaticSanitazion = 3 /* for parser modules */ } syslogFeature; /* we define our own facility and severities */ diff --git a/tools/Makefile.am b/tools/Makefile.am index 233061e6..1dff4b45 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -16,6 +16,7 @@ rsyslogd_SOURCES = \ omdiscard.c \ omdiscard.h \ pmrfc5424.c \ + pmrfc5424.h \ iminternal.c \ iminternal.h \ pidfile.c \ diff --git a/tools/pmrfc5424.c b/tools/pmrfc5424.c index 61b2aff9..acc21817 100644 --- a/tools/pmrfc5424.c +++ b/tools/pmrfc5424.c @@ -38,14 +38,18 @@ #include "module-template.h" #include "glbl.h" #include "errmsg.h" +#include "parser.h" +#include "unicode-helper.h" MODULE_TYPE_PARSER +PARSER_NAME("rsyslog.rfc5424") /* internal structures */ DEF_PMOD_STATIC_DATA DEFobjCurrIf(errmsg) DEFobjCurrIf(glbl) +DEFobjCurrIf(parser) /* config data */ @@ -66,6 +70,7 @@ CODESTARTmodExit /* release what we no longer need */ objRelease(errmsg, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); + objRelease(parser, CORE_COMPONENT); ENDmodExit @@ -82,6 +87,10 @@ CODESTARTmodInit CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(errmsg, CORE_COMPONENT)); + CHKiRet(objUse(parser, CORE_COMPONENT)); + + dbgprintf("rfc5424 parser init called\n"); + dbgprintf("GetParserName addr %p\n", GetParserName); ENDmodInit /* vim:set ai: diff --git a/tools/pmrfc5424.h b/tools/pmrfc5424.h new file mode 100644 index 00000000..df2a1c81 --- /dev/null +++ b/tools/pmrfc5424.h @@ -0,0 +1,33 @@ +/* pmrfc5424.h + * These are the definitions for the RFCC5424 parser module. + * + * File begun on 2009-11-03 by RGerhards + * + * Copyright 2009 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see . + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#ifndef PMRFC54254_H_INCLUDED +#define PMRFC54254_H_INCLUDED 1 + +/* prototypes */ +rsRetVal modInitpmrfc5424(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar*, rsRetVal (**)()), modInfo_t*); + +#endif /* #ifndef PMRFC54254_H_INCLUDED */ +/* vi:set ai: + */ diff --git a/tools/syslogd.c b/tools/syslogd.c index c1277d3e..3fb54467 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -125,6 +125,7 @@ #include "omfwd.h" #include "omfile.h" #include "omdiscard.h" +#include "pmrfc5424.h" #include "threads.h" #include "wti.h" #include "queue.h" @@ -1913,6 +1914,9 @@ static rsRetVal loadBuildInModules(void) */ CHKiRet(module.doModInit(modInitUsrMsg, (uchar*) "builtin-usrmsg", NULL)); + /* load build-in parser modules */ + CHKiRet(module.doModInit(modInitpmrfc5424, UCHAR_CONSTANT("builtin-pmrfc5424"), NULL)); + /* ok, initialization of the command handler probably does not 100% belong right in * this space here. However, with the current design, this is actually quite a good * place to put it. We might decide to shuffle it around later, but for the time -- cgit