summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2007-08-03 14:58:24 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2007-08-03 14:58:24 +0000
commit51971302280a9789b794e6c0c534a6e02767a39e (patch)
tree39234fe7dab5a0ac5ff51f0d55b5e1a19e159c43
parentadbf55ece666c71e882c370a74efa0bbf3239226 (diff)
downloadrsyslog-51971302280a9789b794e6c0c534a6e02767a39e.tar.gz
rsyslog-51971302280a9789b794e6c0c534a6e02767a39e.tar.xz
rsyslog-51971302280a9789b794e6c0c534a6e02767a39e.zip
- I found out that we finally have problems with the (somewhat recursive)
call to logerror() that many of the modules do. I have not tried it, but I think things will become wild when we compile without pthread support. Threading prevents full recursion, so we have not seen any bad effects so far. However, the problems that I experienced in ommysl (that caused me to re-structure startWorker()) are actually rooted in this issue. I first thought to fix it via a module interace, but I now came to the conclusion that it is not more effort and much cleaner to do an internal error buffering class. This is implemented in errbuf.c/h. - I just noticed that this is not actually an error buf, but the core of an input module for all internal messages. As such, I implement it now as iminternal.c/h. Of course, there is no input module interface yet designed, but that doesn't matter. Worst-case, I need to re-write the im, best case I can use the im (at least partly) to define the interface. - added a few functions to the linkedlist class - error messages during startup are now buffered - so we do no longer need to think about how emergency logging might work. Actually, these are logged to whatever is instatiated in the log file. This enhances the chance that we will be able to drop the error message somewhere it is seen.
-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>