summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2009-11-03 18:44:02 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2009-11-03 18:44:02 +0100
commitb1db196953713dd09c499a3edf81347bd903c19e (patch)
tree7c4d1d4a92337f0cd1538c7cd9bc77904901ce8d
parent6f511cecfae3592f271627ebcb41e6a8c4f831e9 (diff)
downloadrsyslog-b1db196953713dd09c499a3edf81347bd903c19e.tar.gz
rsyslog-b1db196953713dd09c499a3edf81347bd903c19e.tar.xz
rsyslog-b1db196953713dd09c499a3edf81347bd903c19e.zip
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...
-rw-r--r--runtime/module-template.h14
-rw-r--r--runtime/modules.c31
-rw-r--r--runtime/modules.h9
-rw-r--r--runtime/parser.c165
-rw-r--r--runtime/parser.h39
-rw-r--r--runtime/queue.c1
-rw-r--r--runtime/rsyslog.h4
-rw-r--r--runtime/ruleset.h1
-rw-r--r--runtime/syslogd-types.h5
-rw-r--r--tools/Makefile.am1
-rw-r--r--tools/pmrfc5424.c9
-rw-r--r--tools/pmrfc5424.h33
-rw-r--r--tools/syslogd.c4
13 files changed, 290 insertions, 26 deletions
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 <http://www.gnu.org/licenses/>.
+ *
+ * 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