summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac4
-rw-r--r--iminternal.c189
-rw-r--r--iminternal.h48
-rw-r--r--linkedlist.c59
-rw-r--r--linkedlist.h1
-rw-r--r--module-template.h1
-rw-r--r--msg.h1
-rw-r--r--ommysql.c21
-rw-r--r--rsyslog.h1
-rw-r--r--syslogd.c90
-rw-r--r--template.h2
12 files changed, 386 insertions, 33 deletions
diff --git a/Makefile.am b/Makefile.am
index 95aac156..a51173bf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,7 +7,7 @@ rfc3195d_SOURCES=rfc3195d.c rsyslog.h
man_MANS = rfc3195d.8 rklogd.8 rsyslogd.8 rsyslog.conf.5
-rsyslogd_SOURCES=syslogd.c pidfile.c template.c outchannel.c stringbuf.c srUtils.c parse.c syslogd-types.h template.h outchannel.h syslogd.h stringbuf.h parse.h srUtils.h liblogging-stub.h net.c net.h msg.c msg.h omshell.c omshell.h omusrmsg.c omusrmsg.h ommysql.c ommysql.h omfwd.c omfwd.h tcpsyslog.c tcpsyslog.h omfile.h omfile.c omdiscard.c omdiscard.h modules.c modules.h module-template.h objomsr.c objomsr.h cfsysline.c cfsysline.h linkedlist.c linkedlist.h
+rsyslogd_SOURCES=syslogd.c pidfile.c template.c outchannel.c stringbuf.c srUtils.c parse.c syslogd-types.h template.h outchannel.h syslogd.h stringbuf.h parse.h srUtils.h liblogging-stub.h net.c net.h msg.c msg.h omshell.c omshell.h omusrmsg.c omusrmsg.h ommysql.c ommysql.h omfwd.c omfwd.h tcpsyslog.c tcpsyslog.h omfile.h omfile.c omdiscard.c omdiscard.h modules.c modules.h module-template.h objomsr.c objomsr.h cfsysline.c cfsysline.h linkedlist.c linkedlist.h iminternal.c iminternal.h
rsyslogd_CPPFLAGS=$(mysql_includes)
rsyslogd_LDADD=$(mysql_libs) $(zlib_libs) $(pthreads_libs)
diff --git a/configure.ac b/configure.ac
index 34104d32..a8c46b67 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
-AC_INIT(rsyslog, 1.17.7, rsyslog@lists.adiscon.com.)
-AM_INIT_AUTOMAKE(rsyslog, 1.17.7)
+AC_INIT(rsyslog, 1.18.0, rsyslog@lists.adiscon.com.)
+AM_INIT_AUTOMAKE(rsyslog, 1.18.0)
AC_CONFIG_SRCDIR([syslogd.c])
AC_CONFIG_HEADER([config.h])
diff --git a/iminternal.c b/iminternal.c
new file mode 100644
index 00000000..2f898e46
--- /dev/null
+++ b/iminternal.c
@@ -0,0 +1,189 @@
+/* iminternal.c
+ * This file set implements the internal messages input module for rsyslog.
+ * Note: we currently do not have an input module spec, but
+ * we will have one in the future. This module needs then to be
+ * adapted.
+ *
+ * File begun on 2007-08-03 by RGerhards
+ *
+ * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "rsyslog.h"
+#include "syslogd.h"
+#include "linkedlist.h"
+#include "iminternal.h"
+
+static linkedList_t llMsgs;
+
+
+/* destructs an iminternal object
+ */
+static rsRetVal iminternalDestruct(iminternal_t *pThis)
+{
+ DEFiRet;
+
+ assert(pThis != NULL);
+
+ if(pThis->pMsg != NULL)
+ MsgDestruct(pThis->pMsg);
+
+ free(pThis);
+
+ return iRet;
+}
+
+
+/* Construct an iminternal object
+ */
+static rsRetVal iminternalConstruct(iminternal_t **ppThis)
+{
+ DEFiRet;
+ iminternal_t *pThis;
+
+ assert(ppThis != NULL);
+
+ if((pThis = (iminternal_t*) calloc(1, sizeof(iminternal_t))) == NULL) {
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ }
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pThis != NULL)
+ iminternalDestruct(pThis);
+ }
+
+ *ppThis = pThis;
+
+ return iRet;
+};
+
+
+/* add a message to the linked list
+ * Note: the pMsg reference counter is not incremented. Consequently,
+ * the caller must NOT decrement it. The caller actually hands over
+ * full ownership of the pMsg object.
+ * The interface of this function is modelled after syslogd/logmsg(),
+ * for which it is an "replacement".
+ */
+rsRetVal iminternalAddMsg(int pri, msg_t *pMsg, int flags)
+{
+ DEFiRet;
+ iminternal_t *pThis;
+
+ assert(pMsg != NULL);
+
+ CHKiRet(iminternalConstruct(&pThis));
+
+ pThis->pri = pri;
+ pThis->pMsg = pMsg;
+ pThis->flags = flags;
+
+ CHKiRet(llAppend(&llMsgs, NULL, (void*) pThis));
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ dprintf("iminternalAddMsg() error %d - can not otherwise report this error, message lost\n", iRet);
+ if(pThis != NULL)
+ iminternalDestruct(pThis);
+ }
+
+ return iRet;
+}
+
+
+/* pull the first error message from the linked list, remove it
+ * from the list and return it to the caller. The caller is
+ * responsible for freeing the message!
+ */
+rsRetVal iminternalRemoveMsg(int *pPri, msg_t **ppMsg, int *pFlags)
+{
+ DEFiRet;
+ iminternal_t *pThis;
+ linkedListCookie_t llCookie = NULL;
+
+ assert(pPri != NULL);
+ assert(ppMsg != NULL);
+ assert(pFlags != NULL);
+
+ CHKiRet(llGetNextElt(&llMsgs, &llCookie, (void**) &pThis));
+ *pPri = pThis->pri;
+ *pFlags = pThis->flags;
+ *ppMsg = pThis->pMsg;
+ pThis->pMsg = NULL; /* we do no longer own it - important for destructor */
+
+ if(llDestroyRootElt(&llMsgs) != RS_RET_OK) {
+ dprintf("Root element of iminternal linked list could not be destroyed - there is "
+ "nothing we can do against it, we ignore it for now. Things may go wild "
+ "from here on. This is most probably a program logic error.\n");
+ }
+
+finalize_it:
+ return iRet;
+}
+
+/* tell the caller if we have any messages ready for processing.
+ * 0 means we have none, everything else means there is at least
+ * one message ready.
+ */
+rsRetVal iminternalHaveMsgReady(int* pbHaveOne)
+{
+ assert(pbHaveOne != NULL);
+
+ return llGetNumElts(&llMsgs, pbHaveOne);
+}
+
+
+/* initialize the iminternal subsystem
+ * must be called once at the start of the program
+ */
+rsRetVal modInitIminternal(void)
+{
+ DEFiRet;
+
+ iRet = llInit(&llMsgs, iminternalDestruct, NULL, NULL);
+
+ return iRet;
+}
+
+
+/* de-initialize the iminternal subsystem
+ * must be called once at the end of the program
+ * Note: the error list must have been pulled first. We do
+ * NOT care if there are any errors left - we simply destroy
+ * them.
+ */
+rsRetVal modExitIminternal(void)
+{
+ DEFiRet;
+
+ iRet = llDestroy(&llMsgs);
+
+ return iRet;
+}
+
+/*
+ * vi:set ai:
+ */
diff --git a/iminternal.h b/iminternal.h
new file mode 100644
index 00000000..0677f814
--- /dev/null
+++ b/iminternal.h
@@ -0,0 +1,48 @@
+/* Definition of the internal messages input module.
+ *
+ * Note: we currently do not have an input module spec, but
+ * we will have one in the future. This module needs then to be
+ * adapted.
+ *
+ * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+
+#ifndef IMINTERNAL_H_INCLUDED
+#define IMINTERNAL_H_INCLUDED
+#include "template.h"
+
+/* this is a single entry for a parse routine. It describes exactly
+ * one entry point/handler.
+ * The short name is cslch (Configfile SysLine CommandHandler)
+ */
+struct iminternal_s { /* config file sysline parse entry */
+ int pri;
+ msg_t *pMsg; /* the message (in all its glory) */
+ int flags;
+};
+typedef struct iminternal_s iminternal_t;
+
+/* prototypes */
+rsRetVal modInitIminternal(void);
+rsRetVal modExitIminternal(void);
+rsRetVal iminternalAddMsg(int pri, msg_t *pMsg, int flags);
+rsRetVal iminternalHaveMsgReady(int* pbHaveOne);
+rsRetVal iminternalRemoveMsg(int *pPri, msg_t **ppMsg, int *pFlags);
+
+#endif /* #ifndef IMINTERNAL_H_INCLUDED */
diff --git a/linkedlist.c b/linkedlist.c
index 4037193b..7ebadf5a 100644
--- a/linkedlist.c
+++ b/linkedlist.c
@@ -59,6 +59,31 @@ rsRetVal llInit(linkedList_t *pThis, rsRetVal (*pEltDestructor)(), rsRetVal (*pK
};
+/* llDestroyEltData - destroys a list element
+ * It is a separate function as the
+ * functionality is needed in multiple code-pathes.
+ */
+static rsRetVal llDestroyElt(linkedList_t *pList, llElt_t *pElt)
+{
+ DEFiRet;
+
+ assert(pList != NULL);
+ assert(pElt != NULL);
+
+ /* we ignore errors during destruction, as we need to try
+ * free the element in any case.
+ */
+ if(pElt->pData != NULL)
+ pList->pEltDestruct(pElt->pData);
+ if(pElt->pKey != NULL)
+ pList->pKeyDestruct(pElt->pKey);
+ free(pElt);
+ pList->iNumElts--; /* one less */
+
+ return iRet;
+}
+
+
/* llDestroy - destroys a COMPLETE linkedList
*/
rsRetVal llDestroy(linkedList_t *pThis)
@@ -76,13 +101,37 @@ rsRetVal llDestroy(linkedList_t *pThis)
/* we ignore errors during destruction, as we need to try
* finish the linked list in any case.
*/
- if(pEltPrev->pData != NULL)
- pThis->pEltDestruct(pEltPrev->pData);
- if(pEltPrev->pKey != NULL)
- pThis->pKeyDestruct(pEltPrev->pKey);
- free(pEltPrev);
+ llDestroyElt(pThis, pEltPrev);
+ }
+
+ return iRet;
+}
+
+/* llDestroyRootElt - destroy the root element but otherwise
+ * keeps this list intact. -- rgerhards, 2007-08-03
+ */
+rsRetVal llDestroyRootElt(linkedList_t *pThis)
+{
+ DEFiRet;
+ llElt_t *pPrev;
+
+ if(pThis->pRoot == NULL) {
+ ABORT_FINALIZE(RS_RET_EMPTY_LIST);
+ }
+
+ pPrev = pThis->pRoot;
+ if(pPrev->pNext == NULL) {
+ /* it was the only list element */
+ pThis->pLast = NULL;
+ pThis->pRoot = NULL;
+ } else {
+ /* there are other list elements */
+ pThis->pRoot = pPrev->pNext;
}
+ CHKiRet(llDestroyElt(pThis, pPrev));
+
+finalize_it:
return iRet;
}
diff --git a/linkedlist.h b/linkedlist.h
index ac67a01b..0b5b36e9 100644
--- a/linkedlist.h
+++ b/linkedlist.h
@@ -54,6 +54,7 @@ typedef llElt_t* linkedListCookie_t; /* this type avoids exposing internals and
/* prototypes */
rsRetVal llInit(linkedList_t *pThis, rsRetVal (*pEltDestructor)(), rsRetVal (*pKeyDestructor)(void*), int (*pCmpOp)());
rsRetVal llDestroy(linkedList_t *pThis);
+rsRetVal llDestroyRootElt(linkedList_t *pThis);
rsRetVal llGetNextElt(linkedList_t *pThis, linkedListCookie_t *ppElt, void **ppUsr);
rsRetVal llAppend(linkedList_t *pThis, void *pKey, void *pData);
rsRetVal llFind(linkedList_t *pThis, void *pKey, void **ppData);
diff --git a/module-template.h b/module-template.h
index 54f18cfa..ce13bce6 100644
--- a/module-template.h
+++ b/module-template.h
@@ -333,6 +333,7 @@ finalize_it:\
return iRet;\
}
+
/* definitions for host API queries */
#define CODEmodInit_QueryRegCFSLineHdlr \
CHKiRet(pHostQueryEtryPt((uchar*)"regCfSysLineHdlr", &omsdRegCFSLineHdlr));
diff --git a/msg.h b/msg.h
index bf5ba07b..794fb953 100644
--- a/msg.h
+++ b/msg.h
@@ -24,6 +24,7 @@
#ifndef MSG_H_INCLUDED
#define MSG_H_INCLUDED 1
+#include "syslogd-types.h"
#include "template.h"
/* rgerhards 2004-11-08: The following structure represents a
diff --git a/ommysql.c b/ommysql.c
index 573e72ec..801bf5ac 100644
--- a/ommysql.c
+++ b/ommysql.c
@@ -1,4 +1,4 @@
-/* omusrmsg.c
+/* ommysql.c
* This is the implementation of the build-in output module for MySQL.
*
* NOTE: read comments in module-template.h to understand how this file
@@ -115,7 +115,7 @@ ENDgetWriteFDForSelect
* We check if we have a valid MySQL handle. If not, we simply
* report an error, but can not be specific. RGerhards, 2007-01-30
*/
-static void reportDBError(instanceData *pData)
+static void reportDBError(instanceData *pData, int bSilent)
{
char errMsg[512];
@@ -128,7 +128,10 @@ static void reportDBError(instanceData *pData)
} else { /* we can ask mysql for the error description... */
snprintf(errMsg, sizeof(errMsg)/sizeof(char), "db error (%d): %s\n", mysql_errno(pData->f_hmysql),
mysql_error(pData->f_hmysql));
- logerror(errMsg);
+ if(bSilent)
+ dprintf("mysql, DBError(silent): %s\n", errMsg);
+ else
+ logerror(errMsg);
}
return;
@@ -139,7 +142,7 @@ static void reportDBError(instanceData *pData)
* MySQL connection.
* Initially added 2004-10-28 mmeckelein
*/
-static rsRetVal initMySQL(instanceData *pData)
+static rsRetVal initMySQL(instanceData *pData, int bSilent)
{
DEFiRet;
@@ -154,7 +157,7 @@ static rsRetVal initMySQL(instanceData *pData)
/* Connect to database */
if(mysql_real_connect(pData->f_hmysql, pData->f_dbsrv, pData->f_dbuid,
pData->f_dbpwd, pData->f_dbname, 0, NULL, 0) == NULL) {
- reportDBError(pData);
+ reportDBError(pData, bSilent);
closeMySQL(pData); /* ignore any error we may get */
iRet = RS_RET_SUSPENDED;
}
@@ -179,10 +182,10 @@ rsRetVal writeMySQL(uchar *psz, instanceData *pData)
if(mysql_query(pData->f_hmysql, (char*)psz)) {
/* error occured, try to re-init connection and retry */
closeMySQL(pData); /* close the current handle */
- CHKiRet(initMySQL(pData)); /* try to re-open */
+ CHKiRet(initMySQL(pData, 0)); /* try to re-open */
if(mysql_query(pData->f_hmysql, (char*)psz)) { /* re-try insert */
/* we failed, giving up for now */
- reportDBError(pData);
+ reportDBError(pData, 0);
closeMySQL(pData); /* free ressources */
ABORT_FINALIZE(RS_RET_SUSPENDED);
}
@@ -196,7 +199,7 @@ finalize_it:
BEGINtryResume
CODESTARTtryResume
if(pData->f_hmysql == NULL) {
- iRet = initMySQL(pData);
+ iRet = initMySQL(pData, 1);
}
ENDtryResume
@@ -273,7 +276,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
logerror("Trouble with MySQL connection properties. -MySQL logging disabled");
ABORT_FINALIZE(RS_RET_INVALID_PARAMS);
} else {
- CHKiRet(initMySQL(pData));
+ CHKiRet(initMySQL(pData, 0));
}
#endif /* #ifdef WITH_DB */
diff --git a/rsyslog.h b/rsyslog.h
index e0e8d1ea..e202b8e8 100644
--- a/rsyslog.h
+++ b/rsyslog.h
@@ -68,6 +68,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_END_OF_LINKEDLIST = -2014, /**< end of linked list, not an error, but a status */
RS_RET_CHAIN_NOT_PERMITTED = -2015, /**< chaining (e.g. of config command handlers) not permitted */
RS_RET_INVALID_PARAMS = -2016,/**< supplied parameters are invalid */
+ RS_RET_EMPTY_LIST = -2017, /**< linked list is empty */
RS_RET_OK = 0 /**< operation successful */
};
typedef enum rsRetVal_ rsRetVal; /**< friendly type for global return value */
diff --git a/syslogd.c b/syslogd.c
index 7ec50134..928f0e3c 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -211,6 +211,7 @@
#include "msg.h"
#include "modules.h"
#include "tcpsyslog.h"
+#include "iminternal.h"
#include "cfsysline.h"
#include "omshell.h"
#include "omusrmsg.h"
@@ -715,6 +716,7 @@ static void freeSelectors(void);
static rsRetVal processConfFile(uchar *pConfFile);
static rsRetVal actionDestruct(action_t *pThis);
static rsRetVal selectorAddList(selector_t *f);
+static void processImInternal(void);
/* Access functions for the selector_t. These functions are primarily
* necessary to make things thread-safe. Consequently, they are slim
@@ -2377,7 +2379,7 @@ time_t now;
* function here probably is only an interim solution and that we need to
* think on the best way to do this.
*/
-static void logmsgInternal(int pri, char * msg, int flags)
+static void logmsgInternal(int pri, char *msg, int flags)
{
msg_t *pMsg;
@@ -2407,9 +2409,17 @@ static void logmsgInternal(int pri, char * msg, int flags)
pMsg->iSeverity = LOG_PRI(pri);
pMsg->bParseHOSTNAME = 0;
getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */
+ flags |= INTERNAL_MSG;
- logmsg(pri, pMsg, flags | INTERNAL_MSG);
- MsgDestruct(pMsg);
+ if(bRunningMultithreaded == 0) { /* not yet in queued mode */
+ iminternalAddMsg(pri, pMsg, flags);
+ } else {
+ /* we have the queue, so we can simply provide the
+ * message to the queue engine.
+ */
+ logmsg(pri, pMsg, flags);
+ MsgDestruct(pMsg);
+ }
}
/*
@@ -2539,9 +2549,12 @@ int shouldProcessThisMessage(selector_t *f, msg_t *pMsg)
/* doEmergencyLoggin()
* ... does exactly do that. It logs messages when the subsystem has not yet
* been initialized. This almost always happens during initial startup or
- * during HUPing.
- * rgerhards, 2007-07-25
- * TODO: add logging to system console
+ * during HUPing. -- rgerhards, 2007-07-25
+ * rgerhards, 2007-08-03: as of now, this can normally no longer happen. All
+ * startup messages are now buffered until the system is ready to run. I leave
+ * this minimal implementation here in in the very remote case that it might
+ * be needed in the future or due to a program bug. Do *not* excpect this
+ * code to be called.
*/
static void doEmergencyLogging(msg_t *pMsg)
{
@@ -2651,6 +2664,8 @@ DEFFUNC_llExecFunc(processMsgDoActions)
} else if(iRetMod == RS_RET_SUSPENDED) {
/* indicate suspension for next module to be called */
pDoActData->bPrevWasSuspended = 1;
+ } else {
+ pDoActData->bPrevWasSuspended = 0;
}
finalize_it:
@@ -3651,7 +3666,7 @@ static void die(int sig)
errno = 0;
logmsgInternal(LOG_SYSLOG|LOG_INFO, buf, ADDDATE);
}
-
+
/* Free ressources and close connections */
freeSelectors();
@@ -4057,6 +4072,12 @@ static void freeSelectors(void)
if(Files != NULL) {
dprintf("Freeing log structures.\n");
+ /* just in case, we flush the emergency log. If error messages occur after
+ * this stage, we loose them, but that's ok. With multi-threading, this can
+ * never happen. -- rgerhards, 2007-08-03
+ */
+ processImInternal();
+
/* we need first to flush, then wait for all messages to be processed
* (stopWoker() does that), then we can free the structures.
*/
@@ -5012,9 +5033,7 @@ finalize_it:
/* do not overwrite error state! */
OMSRdestruct(pOMSR);
if(pAction != NULL)
- actionDestruct(pAction); /* this line should take care of the TODO's below */
- /* TODO: free pMod instance data, potential mem leak */
- /* TODO: better said - where is the selector_t AND its elements destroyed? */
+ actionDestruct(pAction);
}
return iRet;
@@ -5428,6 +5447,25 @@ static void debugListenInfo(int fd, char *type)
}
+/* this function pulls all internal messages from the buffer
+ * and puts them into the processing engine.
+ * We can only do limited error handling, as this would not
+ * really help us. TODO: add error messages?
+ * rgerhards, 2007-08-03
+ */
+static void processImInternal(void)
+{
+ int iPri;
+ int iFlags;
+ msg_t *pMsg;
+
+ while(iminternalRemoveMsg(&iPri, &pMsg, &iFlags) == RS_RET_OK) {
+ logmsg(iPri, pMsg, iFlags);
+ MsgDestruct(pMsg);
+ }
+}
+
+
/* helper function for mainloop(). This is used to add all module
* writeFDsfor Select via llExecFunc().
* rgerhards, 2007-08-02
@@ -5490,6 +5528,10 @@ static void mainloop(void)
int fd;
char line[MAXLINE +1];
int maxfds;
+ int nfds;
+ errno = 0;
+ FD_ZERO(&readfds);
+ maxfds = 0;
#ifdef SYSLOG_INET
mainloopWriteFDSInfo_t writeFDSInfo;
fd_set writefds;
@@ -5507,13 +5549,10 @@ static void mainloop(void)
#endif
#endif
-
- /* --------------------- Main loop begins here. ----------------------------------------- */
while(!bFinished){
- int nfds;
- errno = 0;
- FD_ZERO(&readfds);
- maxfds = 0;
+ /* first check if we have any internal messages queued and spit them out */
+ processImInternal();
+
#ifdef SYSLOG_UNIXAF
/* Add the Unix Domain Sockets to the list of read
* descriptors.
@@ -5926,6 +5965,11 @@ int main(int argc, char **argv)
}
/* doing some core initializations */
+ if((iRet = modInitIminternal()) != RS_RET_OK) {
+ fprintf(stderr, "fatal error: could not initialize errbuf object (error code %d).\n",
+ iRet);
+ exit(1); /* "good" exit, leaving at init for fatal error */
+ }
#ifdef USE_PTHREADS
/* create message queue */
@@ -6208,6 +6252,20 @@ int main(int argc, char **argv)
*/
mainloop();
+
+ /* de-init some modules */
+ modExitIminternal();
+
+ /* TODO: this would also be the right place to de-init the builtin output modules. We
+ * do not currently do that, because the module interface does not allow for
+ * it. This will come some time later (it's essential with loadable modules).
+ * For the time being, this is a memory leak on exit, but as the process is
+ * terminated, we do not really bother about it.
+ * rgerhards, 2007-08-03
+ */
+
+ /* end de-init's */
+
die(bFinished);
return 0;
}
diff --git a/template.h b/template.h
index d749595a..95ffb221 100644
--- a/template.h
+++ b/template.h
@@ -8,6 +8,8 @@
#define TEMPLATE_H_INCLUDED 1
+#include "stringbuf.h"
+
#ifdef FEATURE_REGEXP
/* Include regular expressions */
#include <regex.h>