summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-03-05 10:30:06 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2008-03-05 10:30:06 +0000
commit545346e697fe930b8b7b9bd0ede47890b26a4832 (patch)
treed0cfea13a087e00238107347dd3ffb7b9e20f31e
parent89fac41d646711e40a0549dfc197cdd7a7d5f18c (diff)
downloadrsyslog-545346e697fe930b8b7b9bd0ede47890b26a4832.tar.gz
rsyslog-545346e697fe930b8b7b9bd0ede47890b26a4832.tar.xz
rsyslog-545346e697fe930b8b7b9bd0ede47890b26a4832.zip
- changed modules.c calling conventions to be interface-based
- moved module loader from conf.c to module.c, where it belongs - made the necessary plumbing to auto-load library modules - upgraded debug system to include iRet in function exit message - changed module interface so that instances need only to be supported by output plugins (if we actually need them for input plugins, we can always add it again...) - milestone: first implementation of library modules (but do not get unloaded on exit/hup so far)
-rw-r--r--ChangeLog6
-rw-r--r--Makefile.am16
-rw-r--r--action.c7
-rw-r--r--conf.c71
-rw-r--r--conf.h1
-rw-r--r--debug.c10
-rw-r--r--debug.h7
-rw-r--r--module-template.h24
-rw-r--r--modules.c182
-rw-r--r--modules.h27
-rw-r--r--obj.c23
-rw-r--r--plugins/imfile/imfile.c17
-rw-r--r--plugins/imgssapi/imgssapi.c17
-rw-r--r--plugins/imklog/imklog.c12
-rw-r--r--plugins/immark/immark.c13
-rw-r--r--plugins/imtcp/imtcp.c15
-rw-r--r--plugins/imtemplate/imtemplate.c17
-rw-r--r--plugins/imudp/imudp.c13
-rw-r--r--plugins/imuxsock/imuxsock.c13
-rw-r--r--queue.c6
-rw-r--r--rsyslog.h4
-rw-r--r--syslogd.c36
-rw-r--r--tcps_sess.c1
-rw-r--r--tcpsrv.c28
-rw-r--r--vm.c2
25 files changed, 295 insertions, 273 deletions
diff --git a/ChangeLog b/ChangeLog
index 934ec9da..39f6195e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,11 +1,13 @@
---------------------------------------------------------------------------
----------------------------------------------------------------------------
-Version 3.12.1 (rgerhards), 2008-0?-??
+Version 3.12.1 (rgerhards), 2008-03-??
- improved debugging support; debug runtime options can now be set via
an environment variable
+- added library plugins, which can be automatically loaded
- bugfix: removed debugging code that I forgot to remove before releasing
3.12.0 (does not cause harm and happened only during startup)
+- added support for the MonitorWare syslog MIB to omsnmp
- internal code improvements (more code converted into classes)
+- internal code reworking of the imtcp/imgssapi module
---------------------------------------------------------------------------
Version 3.12.0 (rgerhards), 2008-02-28
- added full expression support for filters; filters can now contain
diff --git a/Makefile.am b/Makefile.am
index 83503390..ce9f80da 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,10 +3,6 @@ sbin_PROGRAMS = rfc3195d rsyslogd
rfc3195d_SOURCES = rfc3195d.c rsyslog.h
rsyslogd_SOURCES = \
- tcps_sess.c \
- tcps_sess.h \
- tcpsrv.c \
- tcpsrv.h \
syslogd.c \
syslogd.h \
sysvar.c \
@@ -101,6 +97,18 @@ libgssapi_misc_la_SOURCES = gss-misc.c gss-misc.h
libgssapi_misc_la_LIBADD = $(gss_libs)
endif
+# now come the library plugins
+pkglib_LTLIBRARIES = tcpsrv.la
+
+tcpsrv_la_SOURCES = \
+ tcps_sess.c \
+ tcps_sess.h \
+ tcpsrv.c \
+ tcpsrv.h
+tcpsrv_la_CPPFLAGS = $(pthreads_cflags) $(mudflap_cflags)
+tcpsrv_la_LDFLAGS = $(mudflap_libs) -module -avoid-version
+tcpsrv_la_LIBADD =
+
man_MANS = rfc3195d.8 rsyslogd.8 rsyslog.conf.5
EXTRA_DIST = \
diff --git a/action.c b/action.c
index 2580c2ac..21a0a3f5 100644
--- a/action.c
+++ b/action.c
@@ -46,6 +46,8 @@ rsRetVal actionCallDoAction(action_t *pAction, msg_t *pMsg);
/* object static data (once for all instances) */
DEFobjStaticHelpers
+DEFobjCurrIf(module)
+
static int glbliActionResumeInterval = 30;
int glbliActionResumeRetryCount = 0; /* how often should suspended actions be retried? */
@@ -334,7 +336,7 @@ rsRetVal actionDbgPrint(action_t *pThis)
{
DEFiRet;
- dbgprintf("%s: ", modGetStateName(pThis->pMod));
+ dbgprintf("%s: ", module.GetStateName(pThis->pMod));
pThis->pMod->dbgPrintInstInfo(pThis->pModData);
dbgprintf("\n\tInstance data: 0x%lx\n", (unsigned long) pThis->pModData);
dbgprintf("\tRepeatedMsgReduction: %d\n", pThis->f_ReduceRepeated);
@@ -523,7 +525,7 @@ actionWriteToAction(action_t *pAction)
pAction->f_pMsg = pMsg; /* use the new msg (pointer will be restored below) */
}
- dbgprintf("Called action, logging to %s", modGetStateName(pAction->pMod));
+ dbgprintf("Called action, logging to %s", module.GetStateName(pAction->pMod));
time(&pAction->f_time); /* we need this for message repeation processing */
@@ -682,6 +684,7 @@ rsRetVal actionClassInit(void)
DEFiRet;
/* request objects we use */
CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */
+ CHKiRet(objUse(module, CORE_COMPONENT));
finalize_it:
RETiRet;
diff --git a/conf.c b/conf.c
index e4fb362b..ff4f7d93 100644
--- a/conf.c
+++ b/conf.c
@@ -67,8 +67,7 @@ static rsRetVal processConfFile(uchar *pConfFile);
DEFobjStaticHelpers
DEFobjCurrIf(expr)
DEFobjCurrIf(ctok)
-
-uchar *pModDir = NULL; /* read-only after startup */
+DEFobjCurrIf(module)
/* The following global variables are used for building
* tag and host selector lines during startup and config reload.
@@ -216,27 +215,13 @@ finalize_it:
/* process a $ModLoad config line.
- * As of now, it is a dummy, that will later evolve into the
- * loader for plug-ins.
- * rgerhards, 2007-07-21
- * varmojfekoj added support for dynamically loadable modules on 2007-08-13
- * rgerhards, 2007-09-25: please note that the non-threadsafe function dlerror() is
- * called below. This is ok because modules are currently only loaded during
- * configuration file processing, which is executed on a single thread. Should we
- * change that design at any stage (what is unlikely), we need to find a
- * replacement.
*/
rsRetVal
doModLoad(uchar **pp, __attribute__((unused)) void* pVal)
{
DEFiRet;
uchar szName[512];
- uchar szPath[512];
- uchar errMsg[1024];
- uchar *pModName, *pModNameBase;
- uchar *pModNameDup;
- void *pModHdlr, *pModInit;
- modInfo_t *pModInfo;
+ uchar *pModName;
ASSERT(pp != NULL);
ASSERT(*pp != NULL);
@@ -259,54 +244,13 @@ doModLoad(uchar **pp, __attribute__((unused)) void* pVal)
else
pModName = szName;
- dbgprintf("Requested to load module '%s'\n", szName);
-
- if((pModNameDup = (uchar *) strdup((char *) pModName)) == NULL)
- ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
-
- pModNameBase = (uchar *) basename((char*)pModNameDup);
- pModInfo = modGetNxt(NULL);
- while(pModInfo != NULL) {
- if(!strcmp((char *) pModNameBase, (char *) modGetName(pModInfo))) {
- dbgprintf("Module '%s' already loaded\n", szName);
- free(pModNameDup);
- ABORT_FINALIZE(RS_RET_OK);
- }
- pModInfo = modGetNxt(pModInfo);
- }
- free(pModNameDup);
-
- if(*pModName == '/') {
- *szPath = '\0'; /* we do not need to append the path - its already in the module name */
- } else {
- strncpy((char *) szPath, (pModDir == NULL) ? _PATH_MODDIR : (char*) pModDir, sizeof(szPath));
- }
- strncat((char *) szPath, (char *) pModName, sizeof(szPath) - strlen((char*) szPath) - 1);
- if(!(pModHdlr = dlopen((char *) szPath, RTLD_NOW))) {
- snprintf((char *) errMsg, sizeof(errMsg), "could not load module '%s', dlopen: %s\n", szPath, dlerror());
- errMsg[sizeof(errMsg)/sizeof(uchar) - 1] = '\0';
- logerror((char *) errMsg);
- ABORT_FINALIZE(RS_RET_ERR);
- }
- if(!(pModInit = dlsym(pModHdlr, "modInit"))) {
- snprintf((char *) errMsg, sizeof(errMsg), "could not load module '%s', dlsym: %s\n", szPath, dlerror());
- errMsg[sizeof(errMsg)/sizeof(uchar) - 1] = '\0';
- logerror((char *) errMsg);
- dlclose(pModHdlr);
- ABORT_FINALIZE(RS_RET_ERR);
- }
- if((iRet = doModInit(pModInit, (uchar*) pModName, pModHdlr)) != RS_RET_OK) {
- snprintf((char *) errMsg, sizeof(errMsg), "could not load module '%s', rsyslog error %d\n", szPath, iRet);
- errMsg[sizeof(errMsg)/sizeof(uchar) - 1] = '\0';
- logerror((char *) errMsg);
- dlclose(pModHdlr);
- ABORT_FINALIZE(RS_RET_ERR);
- }
+ CHKiRet(module.Load(pModName));
finalize_it:
RETiRet;
}
+
/* parse and interpret a $-config line that starts with
* a name (this is common code). It is parsed to the name
* and then the proper sub-function is called to handle
@@ -1076,10 +1020,10 @@ static rsRetVal cflineDoAction(uchar **p, action_t **ppAction)
ASSERT(ppAction != NULL);
/* loop through all modules and see if one picks up the line */
- pMod = modGetNxtType(NULL, eMOD_OUT);
+ pMod = module.GetNxtType(NULL, eMOD_OUT);
while(pMod != NULL) {
iRet = pMod->mod.om.parseSelectorAct(p, &pModData, &pOMSR);
- dbgprintf("tried selector action for %s: %d\n", modGetName(pMod), iRet);
+ dbgprintf("tried selector action for %s: %d\n", module.GetName(pMod), iRet);
if(iRet == RS_RET_OK || iRet == RS_RET_SUSPENDED) {
if((iRet = addAction(&pAction, pMod, pModData, pOMSR, (iRet == RS_RET_SUSPENDED)? 1 : 0)) == RS_RET_OK) {
/* now check if the module is compatible with select features */
@@ -1103,7 +1047,7 @@ static rsRetVal cflineDoAction(uchar **p, action_t **ppAction)
dbgprintf("error %d parsing config line\n", (int) iRet);
break;
}
- pMod = modGetNxtType(pMod, eMOD_OUT);
+ pMod = module.GetNxtType(pMod, eMOD_OUT);
}
*ppAction = pAction;
@@ -1222,6 +1166,7 @@ BEGINAbstractObjClassInit(conf, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANG
/* request objects we use */
CHKiRet(objUse(expr, CORE_COMPONENT));
CHKiRet(objUse(ctok, CORE_COMPONENT));
+ CHKiRet(objUse(module, CORE_COMPONENT));
ENDObjClassInit(conf)
/* vi:set ai:
diff --git a/conf.h b/conf.h
index 6abee904..31ca27b3 100644
--- a/conf.h
+++ b/conf.h
@@ -46,7 +46,6 @@ PROTOTYPEObj(conf);
/* TODO: remove them below (means move the config init code) -- rgerhards, 2008-02-19 */
-extern uchar *pModDir; /* read-only after startup */
extern EHostnameCmpMode eDfltHostnameCmpMode;
extern cstr_t *pDfltHostnameCmp;
extern cstr_t *pDfltProgNameCmp;
diff --git a/debug.c b/debug.c
index f8a8841c..eb557be4 100644
--- a/debug.c
+++ b/debug.c
@@ -965,7 +965,7 @@ int dbgEntrFunc(dbgFuncDB_t *pFuncDB, int line)
/* handler called when a function is exited
*/
-void dbgExitFunc(dbgFuncDB_t *pFuncDB, int iStackPtrRestore)
+void dbgExitFunc(dbgFuncDB_t *pFuncDB, int iStackPtrRestore, int iRet)
{
dbgThrdInfo_t *pThrd = dbgGetThrdInfo();
@@ -974,8 +974,12 @@ void dbgExitFunc(dbgFuncDB_t *pFuncDB, int iStackPtrRestore)
assert(pFuncDB->magic == dbgFUNCDB_MAGIC);
dbgFuncDBPrintActiveMutexes(pFuncDB, "WARNING: mutex still owned by us as we exit function, mutex: ", pthread_self());
- if(bLogFuncFlow && dbgPrintNameIsInList((const uchar*)pFuncDB->file, printNameFileRoot))
- dbgprintf("%s:%d: %s: exit\n", pFuncDB->file, pFuncDB->line, pFuncDB->func);
+ if(bLogFuncFlow && dbgPrintNameIsInList((const uchar*)pFuncDB->file, printNameFileRoot)) {
+ if(iRet == RS_RET_NO_IRET)
+ dbgprintf("%s:%d: %s: exit: (no iRet)\n", pFuncDB->file, pFuncDB->line, pFuncDB->func);
+ else
+ dbgprintf("%s:%d: %s: exit: %d\n", pFuncDB->file, pFuncDB->line, pFuncDB->func, iRet);
+ }
pThrd->stackPtr = iStackPtrRestore;
if(pThrd->stackPtr < 0) {
dbgprintf("Stack pointer for thread %lx below 0 - resetting (some RETiRet still wrong!)\n", pthread_self());
diff --git a/debug.h b/debug.h
index f39f12a8..27587bd8 100644
--- a/debug.h
+++ b/debug.h
@@ -93,7 +93,7 @@ int dbgCondWait(pthread_cond_t *cond, pthread_mutex_t *pmut, dbgFuncDB_t *pFuncD
int dbgCondTimedWait(pthread_cond_t *cond, pthread_mutex_t *pmut, const struct timespec *abstime, dbgFuncDB_t *pFuncD, int ln, int iStackPtr);
void dbgFree(void *pMem, dbgFuncDB_t *pFuncDB, int ln, int iStackPtr);
int dbgEntrFunc(dbgFuncDB_t *pFuncDB, int line);
-void dbgExitFunc(dbgFuncDB_t *pFuncDB, int iStackPtrRestore);
+void dbgExitFunc(dbgFuncDB_t *pFuncDB, int iStackPtrRestore, int iRet);
void dbgSetExecLocation(int iStackPtr, int line);
void dbgSetThrdName(uchar *pszName);
void dbgPrintAllDebugInfo(void);
@@ -101,12 +101,13 @@ void dbgPrintAllDebugInfo(void);
/* macros */
#ifdef RTINST
# define BEGINfunc static dbgFuncDB_t dbgFuncDB=dbgFuncDB_t_INITIALIZER; int dbgCALLStaCK_POP_POINT = dbgEntrFunc(&dbgFuncDB,__LINE__);
-# define ENDfunc dbgExitFunc(&dbgFuncDB, dbgCALLStaCK_POP_POINT);
-// # define ASSERT(x) do { if(!(x)) dbgPrintAllDebugInfo(); assert(x); } while(0);
+# define ENDfunc dbgExitFunc(&dbgFuncDB, dbgCALLStaCK_POP_POINT, RS_RET_NO_IRET);
+# define ENDfuncIRet dbgExitFunc(&dbgFuncDB, dbgCALLStaCK_POP_POINT, iRet);
# define ASSERT(x) assert(x)
#else
# define BEGINfunc
# define ENDfunc
+# define ENDfuncIRet
# define ASSERT(x)
#endif
#ifdef RTINST
diff --git a/module-template.h b/module-template.h
index 458a837c..3dae7021 100644
--- a/module-template.h
+++ b/module-template.h
@@ -56,7 +56,7 @@ static rsRetVal modGetType(eModType_t *modType) \
#define MODULE_TYPE_INPUT MODULE_TYPE(eMOD_IN)
#define MODULE_TYPE_OUTPUT MODULE_TYPE(eMOD_OUT)
-#define MODULE_TYPE_LIB MODULE_TYPE(EMOD_LIB)
+#define MODULE_TYPE_LIB MODULE_TYPE(eMOD_LIB)
/* macro to define a unique module id. This must be able to fit in a void*. The
* module id must be unique inside a running rsyslogd application. It is used to
@@ -295,7 +295,10 @@ static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())\
#define ENDqueryEtryPt \
if(iRet == RS_RET_OK)\
- iRet = (*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;\
+ if(*pEtryPoint == NULL) { \
+ dbgprintf("entry point '%s' not present in module\n", name); \
+ iRet = RS_RET_MODULE_ENTRY_POINT_NOT_FOUND;\
+ } \
RETiRet;\
}
@@ -304,11 +307,7 @@ static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())\
* the module-type specific macros.
*/
#define CODEqueryEtryPt_STD_MOD_QUERIES \
- if(!strcmp((char*) name, "dbgPrintInstInfo")) {\
- *pEtryPoint = dbgPrintInstInfo;\
- } else if(!strcmp((char*) name, "freeInstance")) {\
- *pEtryPoint = freeInstance;\
- } else if(!strcmp((char*) name, "modExit")) {\
+ if(!strcmp((char*) name, "modExit")) {\
*pEtryPoint = modExit;\
} else if(!strcmp((char*) name, "modGetID")) {\
*pEtryPoint = modGetID;\
@@ -324,6 +323,10 @@ static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())\
CODEqueryEtryPt_STD_MOD_QUERIES \
else if(!strcmp((char*) name, "doAction")) {\
*pEtryPoint = doAction;\
+ } else if(!strcmp((char*) name, "dbgPrintInstInfo")) {\
+ *pEtryPoint = dbgPrintInstInfo;\
+ } else if(!strcmp((char*) name, "freeInstance")) {\
+ *pEtryPoint = freeInstance;\
} else if(!strcmp((char*) name, "parseSelectorAct")) {\
*pEtryPoint = parseSelectorAct;\
} else if(!strcmp((char*) name, "isCompatibleWithFeature")) {\
@@ -348,6 +351,13 @@ static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())\
*pEtryPoint = afterRun;\
}
+/* the following definition is the standard block for queryEtryPt for LIBRARY
+ * modules. This can be used if no specific handling (e.g. to cover version
+ * differences) is needed.
+ */
+#define CODEqueryEtryPt_STD_LIB_QUERIES \
+ CODEqueryEtryPt_STD_MOD_QUERIES
+
/* modInit()
* This has an extra parameter, which is the specific name of the modInit
* function. That is needed for built-in modules, which must have unique
diff --git a/modules.c b/modules.c
index 09ffca1a..cdaa2433 100644
--- a/modules.c
+++ b/modules.c
@@ -42,10 +42,16 @@
#include "cfsysline.h"
#include "modules.h"
+/* static data */
+DEFobjStaticHelpers
+
static modInfo_t *pLoadedModules = NULL; /* list of currently-loaded modules */
static modInfo_t *pLoadedModulesLast = NULL; /* tail-pointer */
static int bCfsyslineInitialized = 0;
+/* config settings */
+uchar *pModDir = NULL; /* read-only after startup */
+
/* Construct a new module object
*/
@@ -86,7 +92,7 @@ static void moduleDestruct(modInfo_t *pThis)
* Please note that the implementation as a query interface allows to take
* care of plug-in interface version differences. -- rgerhards, 2007-07-31
*/
-rsRetVal queryHostEtryPt(uchar *name, rsRetVal (**pEtryPoint)())
+static rsRetVal queryHostEtryPt(uchar *name, rsRetVal (**pEtryPoint)())
{
DEFiRet;
@@ -107,26 +113,26 @@ finalize_it:
}
+/* get the name of a module
+ */
+static uchar *modGetName(modInfo_t *pThis)
+{
+ return((pThis->pszName == NULL) ? (uchar*) "" : pThis->pszName);
+}
+
+
/* get the state-name of a module. The state name is its name
* together with a short description of the module state (which
* is pulled from the module itself.
* rgerhards, 2007-07-24
* TODO: the actual state name is not yet pulled
*/
-uchar *modGetStateName(modInfo_t *pThis)
+static uchar *modGetStateName(modInfo_t *pThis)
{
return(modGetName(pThis));
}
-/* get the name of a module
- */
-uchar *modGetName(modInfo_t *pThis)
-{
- return((pThis->pszName == NULL) ? (uchar*) "" : pThis->pszName);
-}
-
-
/* Add a module to the loaded module linked list
*/
static inline void
@@ -151,7 +157,7 @@ addModToList(modInfo_t *pThis)
* returned - then, the list is empty.
* rgerhards, 2007-07-23
*/
-modInfo_t *modGetNxt(modInfo_t *pThis)
+static modInfo_t *GetNxt(modInfo_t *pThis)
{
modInfo_t *pNew;
@@ -164,17 +170,17 @@ modInfo_t *modGetNxt(modInfo_t *pThis)
}
-/* this function is like modGetNxt(), but it returns pointers to
+/* this function is like GetNxt(), but it returns pointers to
* modules of specific type only. As we currently deal just with output modules,
* it is a dummy, to be filled with real code later.
* rgerhards, 2007-07-24
*/
-modInfo_t *modGetNxtType(modInfo_t *pThis, eModType_t rqtdType)
+static modInfo_t *GetNxtType(modInfo_t *pThis, eModType_t rqtdType)
{
modInfo_t *pMod = pThis;
do {
- pMod = modGetNxt(pMod);
+ pMod = GetNxt(pMod);
} while(!(pMod == NULL || pMod->eType == rqtdType)); /* warning: do ... while() */
return pMod;
@@ -209,7 +215,8 @@ finalize_it:
/* Add an already-loaded module to the module linked list. This function does
* everything needed to fully initialize the module.
*/
-rsRetVal doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)()), uchar *name, void *pModHdlr)
+static rsRetVal
+doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)()), uchar *name, void *pModHdlr)
{
DEFiRet;
modInfo_t *pNew = NULL;
@@ -228,7 +235,6 @@ rsRetVal doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)())
ABORT_FINALIZE(iRet);
}
-RUNLOG_VAR("%p", queryHostEtryPt);
CHKiRet((*modInit)(CURR_MOD_IF_VERSION, &pNew->iIFVers, &pNew->modQueryEtryPt, queryHostEtryPt));
if(pNew->iIFVers != CURR_MOD_IF_VERSION) {
@@ -246,10 +252,8 @@ RUNLOG_VAR("%p", queryHostEtryPt);
* rest of the data elements. First we load the interfaces common to all
* module types.
*/
- CHKiRet((*pNew->modQueryEtryPt)((uchar*)"dbgPrintInstInfo", &pNew->dbgPrintInstInfo));
CHKiRet((*pNew->modQueryEtryPt)((uchar*)"modGetID", &pNew->modGetID));
CHKiRet((*pNew->modQueryEtryPt)((uchar*)"modExit", &pNew->modExit));
- CHKiRet((*pNew->modQueryEtryPt)((uchar*)"freeInstance", &pNew->freeInstance));
/* ... and now the module-specific interfaces */
switch(pNew->eType) {
@@ -259,6 +263,8 @@ RUNLOG_VAR("%p", queryHostEtryPt);
CHKiRet((*pNew->modQueryEtryPt)((uchar*)"afterRun", &pNew->mod.im.afterRun));
break;
case eMOD_OUT:
+ CHKiRet((*pNew->modQueryEtryPt)((uchar*)"freeInstance", &pNew->freeInstance));
+ CHKiRet((*pNew->modQueryEtryPt)((uchar*)"dbgPrintInstInfo", &pNew->dbgPrintInstInfo));
CHKiRet((*pNew->modQueryEtryPt)((uchar*)"doAction", &pNew->mod.om.doAction));
CHKiRet((*pNew->modQueryEtryPt)((uchar*)"parseSelectorAct", &pNew->mod.om.parseSelectorAct));
CHKiRet((*pNew->modQueryEtryPt)((uchar*)"isCompatibleWithFeature", &pNew->isCompatibleWithFeature));
@@ -281,7 +287,7 @@ RUNLOG_VAR("%p", queryHostEtryPt);
addModToList(pNew);
finalize_it:
-
+RUNLOG_VAR("%d", iRet);
if(iRet != RS_RET_OK) {
if(pNew != NULL)
moduleDestruct(pNew);
@@ -295,11 +301,11 @@ finalize_it:
* This only works if the dbgprintf() subsystem is initialized.
* TODO: update for new input modules!
*/
-void modPrintList(void)
+static void modPrintList(void)
{
modInfo_t *pMod;
- pMod = modGetNxt(NULL);
+ pMod = GetNxt(NULL);
while(pMod != NULL) {
dbgprintf("Loaded Module: Name='%s', IFVersion=%d, ",
(char*) modGetName(pMod), pMod->iIFVers);
@@ -323,7 +329,7 @@ void modPrintList(void)
dbgprintf("\tdbgPrintInstInfo: 0x%lx\n", (unsigned long) pMod->dbgPrintInstInfo);
dbgprintf("\tfreeInstance: 0x%lx\n", (unsigned long) pMod->freeInstance);
dbgprintf("\n");
- pMod = modGetNxt(pMod); /* done, go next */
+ pMod = GetNxt(pMod); /* done, go next */
}
}
@@ -331,20 +337,25 @@ void modPrintList(void)
/* unload all modules and free module linked list
* rgerhards, 2007-08-09
*/
-rsRetVal modUnloadAndDestructAll(void)
+static rsRetVal modUnloadAndDestructAll(void)
{
DEFiRet;
modInfo_t *pMod;
modInfo_t *pModPrev;
- pMod = modGetNxt(NULL);
+ pMod = GetNxt(NULL);
while(pMod != NULL) {
pModPrev = pMod;
- pMod = modGetNxt(pModPrev); /* get next */
- /* now we can destroy the previous module */
- dbgprintf("Unloading module %s\n", modGetName(pModPrev));
- modPrepareUnload(pModPrev);
- moduleDestruct(pModPrev);
+ pMod = GetNxt(pModPrev); /* get next */
+ /* TODO: library modules are currently never unloaded! */
+ if(pModPrev->eType == eMOD_LIB) {
+ dbgprintf("NOT unloading library module %s\n", modGetName(pModPrev));
+ } else {
+ /* now we can destroy the previous module */
+ dbgprintf("Unloading module %s\n", modGetName(pModPrev));
+ modPrepareUnload(pModPrev);
+ moduleDestruct(pModPrev);
+ }
}
/* indicate list is now empty */
@@ -388,7 +399,7 @@ modUnlinkAndDestroy(modInfo_t *pThis, modInfo_t *pPrev)
/* unload dynamically loaded modules
*/
-rsRetVal modUnloadAndDestructDynamic(void)
+static rsRetVal modUnloadAndDestructDynamic(void)
{
DEFiRet;
modInfo_t *pMod;
@@ -396,10 +407,10 @@ rsRetVal modUnloadAndDestructDynamic(void)
modInfo_t *pModPrev; /* last module in active linked list */
pModPrev = NULL; /* we do not yet have a previous module */
- pMod = modGetNxt(NULL);
+ pMod = GetNxt(NULL);
while(pMod != NULL) {
pModCurr = pMod;
- pMod = modGetNxt(pModCurr); /* get next */
+ pMod = GetNxt(pModCurr); /* get next */
/* now we can destroy the previous module */
if(pModCurr->eLinkType != eMOD_LINK_STATIC) {
modUnlinkAndDestroy(pModCurr, pModPrev);
@@ -411,5 +422,112 @@ rsRetVal modUnloadAndDestructDynamic(void)
RETiRet;
}
+
+/* load a module and initialize it, based on doModLoad() from conf.c
+ * rgerhards, 2008-03-05
+ * varmojfekoj added support for dynamically loadable modules on 2007-08-13
+ * rgerhards, 2007-09-25: please note that the non-threadsafe function dlerror() is
+ * called below. This is ok because modules are currently only loaded during
+ * configuration file processing, which is executed on a single thread. Should we
+ * change that design at any stage (what is unlikely), we need to find a
+ * replacement.
+ */
+static rsRetVal
+Load(uchar *pModName)
+{
+ DEFiRet;
+
+ uchar szPath[512];
+ uchar errMsg[1024];
+ uchar *pModNameBase;
+ uchar *pModNameDup;
+ void *pModHdlr, *pModInit;
+ modInfo_t *pModInfo;
+
+ assert(pModName != NULL);
+ dbgprintf("Requested to load module '%s'\n", pModName);
+
+ if((pModNameDup = (uchar *) strdup((char *) pModName)) == NULL)
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+
+ pModNameBase = (uchar *) basename((char*)pModNameDup);
+ pModInfo = GetNxt(NULL);
+ while(pModInfo != NULL) {
+ if(!strcmp((char *) pModNameBase, (char *) modGetName(pModInfo))) {
+ dbgprintf("Module '%s' already loaded\n", pModName);
+ free(pModNameDup);
+ ABORT_FINALIZE(RS_RET_OK);
+ }
+ pModInfo = GetNxt(pModInfo);
+ }
+ free(pModNameDup);
+
+ if(*pModName == '/') {
+ *szPath = '\0'; /* we do not need to append the path - its already in the module name */
+ } else {
+ strncpy((char *) szPath, (pModDir == NULL) ? _PATH_MODDIR : (char*) pModDir, sizeof(szPath));
+ }
+ strncat((char *) szPath, (char *) pModName, sizeof(szPath) - strlen((char*) szPath) - 1);
+ if(!(pModHdlr = dlopen((char *) szPath, RTLD_NOW))) {
+ snprintf((char *) errMsg, sizeof(errMsg), "could not load module '%s', dlopen: %s\n", szPath, dlerror());
+ errMsg[sizeof(errMsg)/sizeof(uchar) - 1] = '\0';
+ logerror((char *) errMsg);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ if(!(pModInit = dlsym(pModHdlr, "modInit"))) {
+ snprintf((char *) errMsg, sizeof(errMsg), "could not load module '%s', dlsym: %s\n", szPath, dlerror());
+ errMsg[sizeof(errMsg)/sizeof(uchar) - 1] = '\0';
+ logerror((char *) errMsg);
+ dlclose(pModHdlr);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ if((iRet = doModInit(pModInit, (uchar*) pModName, pModHdlr)) != RS_RET_OK) {
+ snprintf((char *) errMsg, sizeof(errMsg), "could not load module '%s', rsyslog error %d\n", szPath, iRet);
+ errMsg[sizeof(errMsg)/sizeof(uchar) - 1] = '\0';
+ logerror((char *) errMsg);
+ dlclose(pModHdlr);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* queryInterface function
+ * rgerhards, 2008-03-05
+ */
+BEGINobjQueryInterface(module)
+CODESTARTobjQueryInterface(module)
+ if(pIf->ifVersion != moduleCURR_IF_VERSION) { /* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+ pIf->GetNxt = GetNxt;
+ pIf->GetNxtType = GetNxtType;
+ pIf->GetName = modGetName;
+ pIf->GetStateName = modGetStateName;
+ pIf->PrintList = modPrintList;
+ pIf->UnloadAndDestructAll = modUnloadAndDestructAll;
+ pIf->UnloadAndDestructDynamic = modUnloadAndDestructDynamic;
+ pIf->doModInit = doModInit;
+ pIf->Load = Load;
+finalize_it:
+ENDobjQueryInterface(module)
+
+
+/* Initialize our class. Must be called as the very first method
+ * before anything else is called inside this class.
+ * rgerhards, 2008-03-05
+ */
+BEGINAbstractObjClassInit(module, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANGE class also in END MACRO! */
+ /* request objects we use */
+ENDObjClassInit(module)
+
/* vi:set ai:
*/
diff --git a/modules.h b/modules.h
index a2011b17..2a26d5e3 100644
--- a/modules.h
+++ b/modules.h
@@ -102,15 +102,26 @@ typedef struct moduleInfo {
void *pModHdlr; /* handler to the dynamic library holding the module */
} modInfo_t;
+/* interfaces */
+BEGINinterface(module) /* name must also be changed in ENDinterface macro! */
+ modInfo_t *(*GetNxt)(modInfo_t *pThis);
+ modInfo_t *(*GetNxtType)(modInfo_t *pThis, eModType_t rqtdType);
+ uchar *(*GetName)(modInfo_t *pThis);
+ uchar *(*GetStateName)(modInfo_t *pThis);
+ void (*PrintList)(void);
+ rsRetVal (*UnloadAndDestructAll)(void);
+ rsRetVal (*UnloadAndDestructDynamic)(void);
+ rsRetVal (*doModInit)(rsRetVal (*modInit)(), uchar *name, void *pModHdlr);
+ rsRetVal (*Load)(uchar *name);
+ENDinterface(module)
+#define moduleCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+
/* prototypes */
-rsRetVal doModInit(rsRetVal (*modInit)(), uchar *name, void *pModHdlr);
-modInfo_t *modGetNxt(modInfo_t *pThis);
-modInfo_t *modGetNxtType(modInfo_t *pThis, eModType_t rqtdType);
-uchar *modGetName(modInfo_t *pThis);
-uchar *modGetStateName(modInfo_t *pThis);
-void modPrintList(void);
-rsRetVal modUnloadAndDestructAll(void);
-rsRetVal modUnloadAndDestructDynamic(void);
+PROTOTYPEObj(module);
+
+/* TODO: remove them below (means move the config init code) -- rgerhards, 2008-02-19 */
+extern uchar *pModDir; /* read-only after startup */
+
#endif /* #ifndef MODULES_H_INCLUDED */
/*
diff --git a/obj.c b/obj.c
index 0dc92b1d..9d886450 100644
--- a/obj.c
+++ b/obj.c
@@ -76,17 +76,19 @@
#include <assert.h>
/* how many objects are supported by rsyslogd? */
-#define OBJ_NUM_IDS 100 //TODO 16 were currently in use 2008-02-29
+#define OBJ_NUM_IDS 100 /* TODO change to a linked list? info: 16 were currently in use 2008-02-29 */
#include "rsyslog.h"
#include "syslogd-types.h"
#include "srUtils.h"
#include "obj.h"
#include "stream.h"
+#include "modules.h"
/* static data */
DEFobjCurrIf(obj) /* we define our own interface, as this is expected by some macros! */
DEFobjCurrIf(var)
+DEFobjCurrIf(module)
static objInfo_t *arrObjInfo[OBJ_NUM_IDS]; /* array with object information pointers */
@@ -177,9 +179,7 @@ DestructObjSelf(obj_t *pThis)
ISOBJ_assert(pThis);
if(pThis->pszName != NULL) {
-RUNLOG_VAR("%p", pThis->pszName);
free(pThis->pszName);
-RUNLOG;
}
RETiRet;
@@ -920,10 +920,8 @@ SetName(obj_t *pThis, uchar *pszName)
if(pThis->pszName == NULL)
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
-RUNLOG_VAR("%s", pThis->pszName);
finalize_it:
-RUNLOG_VAR("%d", iRet);
RETiRet;
}
@@ -954,7 +952,6 @@ GetName(obj_t *pThis)
} else {
ret = pThis->pszName;
}
-RUNLOG_VAR("%s", pThis->pszName);
} else {
ret = pThis->pszName;
}
@@ -1059,11 +1056,17 @@ UseObj(uchar *pObjName, uchar *pObjFile, interface_t *ppIf)
objInfo_t *pObjInfo;
CHKiRet(rsCStrConstructFromszStr(&pStr, pObjName));
- iRet =FindObjInfo(pStr, &pObjInfo);
+ iRet = FindObjInfo(pStr, &pObjInfo);
if(iRet == RS_RET_NOT_FOUND) {
/* in this case, we need to see if we can dynamically load the object */
- FINALIZE; /* TODO: implement */
+ if(pObjFile == NULL) {
+ FINALIZE; /* no chance, we have lost... */
+ } else {
+ CHKiRet(module.Load(pObjFile));
+ /* NOW, we must find it or we have a problem... */
+ CHKiRet(FindObjInfo(pStr, &pObjInfo));
+ }
} else if(iRet != RS_RET_OK) {
FINALIZE; /* give up */
}
@@ -1092,8 +1095,6 @@ CODESTARTobjQueryInterface(obj)
* work here (if we can support an older interface version - that,
* of course, also affects the "if" above).
*/
- //xxxpIf->oID = OBJobj;
-
pIf->UseObj = UseObj;
pIf->InfoConstruct = InfoConstruct;
pIf->DestructObjSelf = DestructObjSelf;
@@ -1154,7 +1155,9 @@ objClassInit(void)
/* init classes we use (limit to as few as possible!) */
CHKiRet(varClassInit());
+ CHKiRet(moduleClassInit());
CHKiRet(objUse(var, CORE_COMPONENT));
+ CHKiRet(objUse(module, CORE_COMPONENT));
finalize_it:
RETiRet;
diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
index c13e96e9..14d6cf3f 100644
--- a/plugins/imfile/imfile.c
+++ b/plugins/imfile/imfile.c
@@ -69,13 +69,6 @@ static int iFilPtr = 0; /* number of files to be monitored; pointer to next fre
#define MAX_INPUT_FILES 100
static fileInfo_t files[MAX_INPUT_FILES];
-/* instanceData must be defined to keep the framework happy, but it currently
- * is of no practical use. This may change in later revisions of the plugin
- * interface.
- */
-typedef struct _instanceData {
-} instanceData;
-
/* enqueue the read file line as a message
*/
@@ -349,16 +342,6 @@ ENDafterRun
* In general, they need to be present, but you do NOT need to provide
* any code here.
*/
-BEGINfreeInstance
-CODESTARTfreeInstance
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
-ENDdbgPrintInstInfo
-
-
BEGINmodExit
CODESTARTmodExit
ENDmodExit
diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c
index cd42c778..d93799f3 100644
--- a/plugins/imgssapi/imgssapi.c
+++ b/plugins/imgssapi/imgssapi.c
@@ -76,9 +76,6 @@ DEF_IMOD_STATIC_DATA
DEFobjCurrIf(tcpsrv)
DEFobjCurrIf(tcps_sess)
-typedef struct _instanceData {
-} instanceData;
-
static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */
static gss_cred_id_t gss_server_creds = GSS_C_NO_CREDENTIAL;
@@ -679,17 +676,6 @@ CODESTARTafterRun
ENDafterRun
-
-BEGINfreeInstance
-CODESTARTfreeInstance
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
-ENDdbgPrintInstInfo
-
-
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_IMOD_QUERIES
@@ -714,10 +700,9 @@ CODESTARTmodInit
CODEmodInit_QueryRegCFSLineHdlr
pOurTcpsrv = NULL;
/* request objects we use */
- CHKiRet(objUse(tcps_sess, "tcps_sess"));
+ CHKiRet(objUse(tcps_sess, "tcpsrv.so"));
CHKiRet(objUse(tcpsrv, "tcpsrv"));
- CHKiRet(objUse(tcpsrv, "tcpsrv"));
/* register config file handlers */
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputgssserverpermitplaintcp", 0, eCmdHdlrBinary,
NULL, &bPermitPlainTcp, STD_LOADABLE_MODULE_ID));
diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c
index 9b4581b2..238328ea 100644
--- a/plugins/imklog/imklog.c
+++ b/plugins/imklog/imklog.c
@@ -46,8 +46,6 @@ MODULE_TYPE_INPUT
/* Module static data */
DEF_IMOD_STATIC_DATA
-typedef struct _instanceData {
-} instanceData;
/* configuration settings TODO: move to instance data? */
int dbgPrintSymbols = 0; /* this one is extern so the helpers can access it! */
@@ -641,16 +639,6 @@ CODESTARTafterRun
ENDafterRun
-BEGINfreeInstance
-CODESTARTfreeInstance
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
-ENDdbgPrintInstInfo
-
-
BEGINmodExit
CODESTARTmodExit
ENDmodExit
diff --git a/plugins/immark/immark.c b/plugins/immark/immark.c
index 7454ef92..30118de0 100644
--- a/plugins/immark/immark.c
+++ b/plugins/immark/immark.c
@@ -50,9 +50,6 @@ MODULE_TYPE_INPUT
DEF_IMOD_STATIC_DATA
static int iMarkMessagePeriod = DEFAULT_MARK_PERIOD;
-typedef struct _instanceData {
-} instanceData;
-
/* This function is called to gather input. It must terminate only
* a) on failure (iRet set accordingly)
* b) on termination of the input module (as part of the unload process)
@@ -97,16 +94,6 @@ CODESTARTafterRun
ENDafterRun
-BEGINfreeInstance
-CODESTARTfreeInstance
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
-ENDdbgPrintInstInfo
-
-
BEGINmodExit
CODESTARTmodExit
ENDmodExit
diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
index 9ea0863c..fea79d49 100644
--- a/plugins/imtcp/imtcp.c
+++ b/plugins/imtcp/imtcp.c
@@ -53,10 +53,6 @@ DEFobjCurrIf(tcpsrv)
DEFobjCurrIf(tcps_sess)
/* Module static data */
-
-typedef struct _instanceData {
-} instanceData;
-
static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */
/* config settings */
@@ -195,15 +191,6 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
}
-BEGINfreeInstance
-CODESTARTfreeInstance
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
-ENDdbgPrintInstInfo
-
BEGINqueryEtryPt
CODESTARTqueryEtryPt
@@ -217,7 +204,7 @@ CODESTARTmodInit
CODEmodInit_QueryRegCFSLineHdlr
pOurTcpsrv = NULL;
/* request objects we use */
- CHKiRet(objUse(tcps_sess, "tcps_sess"));
+ CHKiRet(objUse(tcps_sess, "tcpsrv.so"));
CHKiRet(objUse(tcpsrv, "tcpsrv"));
/* register config file handlers */
diff --git a/plugins/imtemplate/imtemplate.c b/plugins/imtemplate/imtemplate.c
index e1e29ba6..33938045 100644
--- a/plugins/imtemplate/imtemplate.c
+++ b/plugins/imtemplate/imtemplate.c
@@ -92,13 +92,6 @@ DEF_IMOD_STATIC_DATA /* must be present, starts static data */
*/
/* static int imtemplateWhateverVar = 0; */
-/* instanceData must be defined to keep the framework happy, but it currently
- * is of no practical use. This may change in later revisions of the plugin
- * interface.
- */
-typedef struct _instanceData {
-} instanceData;
-
/* config settings */
@@ -378,16 +371,6 @@ ENDafterRun
* In general, they need to be present, but you do NOT need to provide
* any code here.
*/
-BEGINfreeInstance
-CODESTARTfreeInstance
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
-ENDdbgPrintInstInfo
-
-
BEGINmodExit
CODESTARTmodExit
ENDmodExit
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index edb8f4c1..df497632 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -53,9 +53,6 @@ static uchar *pRcvBuf = NULL; /* receive buffer (for a single packet). We use a
* termination if we can not get it. -- rgerhards, 2007-12-27
*/
-typedef struct _instanceData {
-} instanceData;
-
/* config settings */
@@ -247,16 +244,6 @@ CODESTARTafterRun
ENDafterRun
-BEGINfreeInstance
-CODESTARTfreeInstance
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
-ENDdbgPrintInstInfo
-
-
BEGINmodExit
CODESTARTmodExit
ENDmodExit
diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c
index 227cf6aa..1be2e66f 100644
--- a/plugins/imuxsock/imuxsock.c
+++ b/plugins/imuxsock/imuxsock.c
@@ -61,9 +61,6 @@ MODULE_TYPE_INPUT
/* Module static data */
DEF_IMOD_STATIC_DATA
-typedef struct _instanceData {
-} instanceData;
-
static int startIndexUxLocalSockets; /* process funix from that index on (used to
* suppress local logging. rgerhards 2005-08-01
* read-only after startup
@@ -273,16 +270,6 @@ CODESTARTafterRun
ENDafterRun
-BEGINfreeInstance
-CODESTARTfreeInstance
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
-ENDdbgPrintInstInfo
-
-
BEGINmodExit
CODESTARTmodExit
ENDmodExit
diff --git a/queue.c b/queue.c
index ccc952d8..79b6fa50 100644
--- a/queue.c
+++ b/queue.c
@@ -1557,11 +1557,15 @@ queueIsIdleDA(queue_t *pThis)
static int
queueIsIdleReg(queue_t *pThis)
{
- //return(queueGetOverallQueueSize(pThis) == 0 || (pThis->bRunsDA && queueGetOverallQueueSize(pThis) <= pThis->iLowWtrMrk));
+#if 0 /* enable for performance testing */
int ret;
ret = queueGetOverallQueueSize(pThis) == 0 || (pThis->bRunsDA && queueGetOverallQueueSize(pThis) <= pThis->iLowWtrMrk);
if(ret) fprintf(stderr, "queue is idle\n");
return ret;
+#else
+ /* regular code! */
+ return(queueGetOverallQueueSize(pThis) == 0 || (pThis->bRunsDA && queueGetOverallQueueSize(pThis) <= pThis->iLowWtrMrk));
+#endif
}
diff --git a/rsyslog.h b/rsyslog.h
index c5d352d8..52a56972 100644
--- a/rsyslog.h
+++ b/rsyslog.h
@@ -64,6 +64,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_PROVIDED_BUFFER_TOO_SMALL = -50,/**< the caller provided a buffer, but the called function sees the size of this buffer is too small - operation not carried out */
RS_RET_TRUE = -1, /**< to indicate a true state (can be used as TRUE, legacy) */
RS_RET_FALSE = -2, /**< to indicate a false state (can be used as FALSE, legacy) */
+ RS_RET_NO_IRET = -8, /**< This is a trick for the debuging system - it means no iRet is provided */
RS_RET_ERR = -3000, /**< generic failure */
RS_TRUNCAT_TOO_LARGE = -3001, /**< truncation operation where too many chars should be truncated */
RS_RET_FOUND_AT_STRING_END = -3002, /**< some value found, but at the last pos of string */
@@ -77,6 +78,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_MISSING_INTERFACE = -1001,/**< interface version mismatch, required missing */
RS_RET_INVALID_CORE_INTERFACE = -1002,/**< interface provided by host invalid, can not be used */
RS_RET_ENTRY_POINT_NOT_FOUND = -1003,/**< a requested entry point was not found */
+ RS_RET_MODULE_ENTRY_POINT_NOT_FOUND = -1004,/**< a entry point requested from a module was not present in it */
/* return states for config file processing */
RS_RET_NONE = -2000, /**< some value is not available - not necessarily an error */
RS_RET_CONFLINE_UNPROCESSED = -2001,/**< config line was not processed, pass to other module */
@@ -166,7 +168,7 @@ typedef enum rsRetVal_ rsRetVal; /**< friendly type for global return value */
/* macro below is used in conjunction with CHKiRet_Hdlr, else use ABORT_FINALIZE */
#define FINALIZE goto finalize_it;
#define DEFiRet BEGINfunc rsRetVal iRet = RS_RET_OK
-#define RETiRet do{ ENDfunc return iRet; }while(0)
+#define RETiRet do{ ENDfuncIRet return iRet; }while(0)
#define ABORT_FINALIZE(errCode) \
do { \
diff --git a/syslogd.c b/syslogd.c
index a8cbe45d..4df351aa 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -186,6 +186,7 @@ DEFobjCurrIf(obj)
DEFobjCurrIf(conf)
DEFobjCurrIf(expr)
DEFobjCurrIf(vm)
+DEFobjCurrIf(module)
/* We define our own set of syslog defintions so that we
@@ -2221,7 +2222,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions)
LockObj(pAction);
if (pAction->f_prevcount && time(NULL) >= REPEATTIME(pAction)) {
dbgprintf("flush %s: repeated %d times, %d sec.\n",
- modGetStateName(pAction->pMod), pAction->f_prevcount,
+ module.GetStateName(pAction->pMod), pAction->f_prevcount,
repeatinterval[pAction->f_repeatcount]);
actionWriteToAction(pAction);
BACKOFF(pAction);
@@ -2573,7 +2574,7 @@ die(int sig)
* init, so that modules are unloaded and reloaded on HUP to. Eventually it should go
* into freeSelectors() - but that needs to be seen. -- rgerhards, 2007-08-09
*/
- modUnloadAndDestructAll();
+ module.UnloadAndDestructAll();
/* the following line cleans up CfSysLineHandlers that were not based on loadable
* modules. As such, they are not yet cleared.
@@ -2737,7 +2738,7 @@ static void dbgPrintInitInfo(void)
if(bDebugPrintTemplateList)
tplPrintList();
if(bDebugPrintModuleList)
- modPrintList();
+ module.PrintList();
ochPrintList();
if(bDebugPrintCfSysLineHandlerList)
@@ -2790,7 +2791,7 @@ startInputModules(void)
modInfo_t *pMod;
/* loop through all modules and activate them (brr...) */
- pMod = modGetNxtType(NULL, eMOD_IN);
+ pMod = module.GetNxtType(NULL, eMOD_IN);
while(pMod != NULL) {
if((iRet = pMod->mod.im.willRun()) == RS_RET_OK) {
/* activate here */
@@ -2798,7 +2799,7 @@ startInputModules(void)
} else {
dbgprintf("module %lx will not run, iRet %d\n", (unsigned long) pMod, iRet);
}
- pMod = modGetNxtType(pMod, eMOD_IN);
+ pMod = module.GetNxtType(pMod, eMOD_IN);
}
ENDfunc
@@ -2842,7 +2843,7 @@ init(void)
/* Unload all non-static modules */
dbgprintf("Unloading non-static modules.\n");
- modUnloadAndDestructDynamic();
+ module.UnloadAndDestructDynamic();
dbgprintf("Clearing templates.\n");
tplDeleteNew();
@@ -3011,7 +3012,7 @@ addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringReques
assert(ppAction != NULL);
assert(pMod != NULL);
assert(pOMSR != NULL);
- dbgprintf("Module %s processed this config line.\n", modGetName(pMod));
+ dbgprintf("Module %s processed this config line.\n", module.GetName(pMod));
CHKiRet(actionConstruct(&pAction)); /* create action object first */
pAction->pMod = pMod;
@@ -3399,18 +3400,18 @@ static rsRetVal loadBuildInModules(void)
{
DEFiRet;
- if((iRet = doModInit(modInitFile, (uchar*) "builtin-file", NULL)) != RS_RET_OK) {
+ if((iRet = module.doModInit(modInitFile, (uchar*) "builtin-file", NULL)) != RS_RET_OK) {
RETiRet;
}
#ifdef SYSLOG_INET
- if((iRet = doModInit(modInitFwd, (uchar*) "builtin-fwd", NULL)) != RS_RET_OK) {
+ if((iRet = module.doModInit(modInitFwd, (uchar*) "builtin-fwd", NULL)) != RS_RET_OK) {
RETiRet;
}
#endif
- if((iRet = doModInit(modInitShell, (uchar*) "builtin-shell", NULL)) != RS_RET_OK) {
+ if((iRet = module.doModInit(modInitShell, (uchar*) "builtin-shell", NULL)) != RS_RET_OK) {
RETiRet;
}
- if((iRet = doModInit(modInitDiscard, (uchar*) "builtin-discard", NULL)) != RS_RET_OK) {
+ if((iRet = module.doModInit(modInitDiscard, (uchar*) "builtin-discard", NULL)) != RS_RET_OK) {
RETiRet;
}
@@ -3423,7 +3424,7 @@ static rsRetVal loadBuildInModules(void)
* User names now must begin with:
* [a-zA-Z0-9_.]
*/
- if((iRet = doModInit(modInitUsrMsg, (uchar*) "builtin-usrmsg", NULL)) != RS_RET_OK)
+ if((iRet = module.doModInit(modInitUsrMsg, (uchar*) "builtin-usrmsg", NULL)) != RS_RET_OK)
RETiRet;
/* ok, initialization of the command handler probably does not 100% belong right in
@@ -3615,17 +3616,18 @@ static rsRetVal InitGlobalClasses(void)
CHKiRet(confClassInit());
/* testing aides */
-CHKiRet(tcps_sessClassInit());
-CHKiRet(tcpsrvClassInit());
+//CHKiRet(tcps_sessClassInit());
+//CHKiRet(tcpsrvClassInit());
/* dummy "classes" */
CHKiRet(actionClassInit());
/* request objects we use */
CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */
- CHKiRet(objUse(conf, CORE_COMPONENT));
- CHKiRet(objUse(expr, CORE_COMPONENT));
- CHKiRet(objUse(vm, CORE_COMPONENT));
+ CHKiRet(objUse(conf, CORE_COMPONENT));
+ CHKiRet(objUse(expr, CORE_COMPONENT));
+ CHKiRet(objUse(vm, CORE_COMPONENT));
+ CHKiRet(objUse(module, CORE_COMPONENT));
finalize_it:
RETiRet;
diff --git a/tcps_sess.c b/tcps_sess.c
index c8ee4d67..95f287d4 100644
--- a/tcps_sess.c
+++ b/tcps_sess.c
@@ -429,6 +429,7 @@ ENDobjQueryInterface(tcps_sess)
*/
//BEGINObjClassInit(tcps_sess, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */
BEGINObjClassInit(tcps_sess, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANGE class also in END MACRO! */
+RUNLOG_STR("initializing tcps_sess class");
/* request objects we use */
//CHKiRet(objUse(expr, CORE_COMPONENT));
diff --git a/tcpsrv.c b/tcpsrv.c
index f6592cae..7341d451 100644
--- a/tcpsrv.c
+++ b/tcpsrv.c
@@ -63,6 +63,7 @@
#include "tcpsrv.h"
#include "obj.h"
+MODULE_TYPE_LIB
/* defines */
#define TCPSESS_MAX_DEFAULT 200 /* default for nbr of tcp sessions if no number is given */
@@ -801,8 +802,7 @@ ENDobjQueryInterface(tcpsrv)
* before anything else is called inside this class.
* rgerhards, 2008-02-29
*/
-//BEGINObjClassInit(tcpsrv, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */
-BEGINObjClassInit(tcpsrv, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANGE class also in END MACRO! */
+BEGINObjClassInit(tcpsrv, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */
/* request objects we use */
CHKiRet(objUse(tcps_sess, "tcps_sess"));
CHKiRet(objUse(conf, CORE_COMPONENT));
@@ -813,6 +813,30 @@ BEGINObjClassInit(tcpsrv, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANGE clas
ENDObjClassInit(tcpsrv)
+/* --------------- here now comes the plumbing that makes as a library module --------------- */
+
+
+BEGINmodExit
+CODESTARTmodExit
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_LIB_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+
+ /* Initialize all classes that are in our module - this includes ourselfs */
+ CHKiRet(tcps_sessClassInit());
+ CHKiRet(tcpsrvClassInit()); /* must be done after tcps_sess, as we use it */
+
+ /* request objects we use */
+ENDmodInit
/* vim:set ai:
*/
diff --git a/vm.c b/vm.c
index 37048a9b..3cd05622 100644
--- a/vm.c
+++ b/vm.c
@@ -504,8 +504,6 @@ CODESTARTobjQueryInterface(vm)
* work here (if we can support an older interface version - that,
* of course, also affects the "if" above).
*/
- //xxxpIf->oID = OBJvm;
-
pIf->Construct = vmConstruct;
pIf->ConstructFinalize = vmConstructFinalize;
pIf->Destruct = vmDestruct;