From 7b63cd6feda5087c43652bdcf8e694b544295d5b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 18 Sep 2008 12:44:00 +0200 Subject: minor things, mostly improved debug info --- tools/syslogd.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b6e1d826..90b38748 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1928,7 +1928,7 @@ die(int sig) /* close the inputs */ dbgprintf("Terminating input threads...\n"); - thrdTerminateAll(); /* TODO: inputs only, please */ + thrdTerminateAll(); /* and THEN send the termination log message (see long comment above) */ if (sig) { @@ -2168,8 +2168,8 @@ static void dbgPrintInitInfo(void) cCCEscapeChar); dbgprintf("Main queue size %d messages.\n", iMainMsgQueueSize); - dbgprintf("Main queue worker threads: %d, Perists every %d updates.\n", - iMainMsgQueueNumWorkers, iMainMsgQPersistUpdCnt); + dbgprintf("Main queue worker threads: %d, wThread shutdown: %d, Perists every %d updates.\n", + iMainMsgQueueNumWorkers, iMainMsgQtoWrkShutdown, iMainMsgQPersistUpdCnt); dbgprintf("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n", iMainMsgQtoQShutdown, iMainMsgQtoActShutdown, iMainMsgQtoEnq); dbgprintf("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n", @@ -2179,11 +2179,9 @@ static void dbgPrintInitInfo(void) /* TODO: add iActionRetryCount = 0; iActionRetryInterval = 30000; - static int iMainMsgQtoWrkShutdown = 60000; static int iMainMsgQtoWrkMinMsgs = 100; static int iMainMsgQbSaveOnShutdown = 1; iMainMsgQueMaxDiskSpace = 0; - setQPROP(queueSettoWrkShutdown, "$MainMsgQueueTimeoutWorkerThreadShutdown", 5000); setQPROP(queueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100); setQPROP(queueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", 1); */ -- cgit v1.2.3 From 65f74a712b111f946faaddd0583a6c7b22bd062f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 6 Oct 2008 14:25:23 +0200 Subject: added $UDPServerTimeRequery option ...which enables to work with less acurate timestamps in favor of performance. This enables querying of the time only every n-th time if imudp is running in the tight receive loop (aka receiving messsages at a high rate) --- tools/syslogd.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b576bb6d..a6e17d8f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -581,9 +581,15 @@ void untty(void) * Interface change: added new parameter "InputName", permits the input to provide * a string that identifies it. May be NULL, but must be a valid char* pointer if * non-NULL. + * + * rgerhards, 2008-10-06: + * Interface change: added new parameter "stTime", which enables the caller to provide + * a timestamp that is to be used as timegenerated instead of the current system time. + * This is meant to facilitate performance optimization. Some inputs support such modes. + * If stTime is NULL, the current system time is used. */ -rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int bParseHost, int flags, flowControl_t flowCtlType, - uchar *pszInputName) +static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int bParseHost, int flags, flowControl_t flowCtlType, + uchar *pszInputName, struct syslogTime *stTime) { DEFiRet; register uchar *p; @@ -591,7 +597,11 @@ rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int bParseHost, int msg_t *pMsg; /* Now it is time to create the message object (rgerhards) */ - CHKiRet(msgConstruct(&pMsg)); + if(stTime == NULL) { + CHKiRet(msgConstruct(&pMsg)); + } else { + CHKiRet(msgConstructWithTime(&pMsg, stTime)); + } if(pszInputName != NULL) MsgSetInputName(pMsg, (char*) pszInputName); MsgSetFlowControlType(pMsg, flowCtlType); @@ -684,10 +694,16 @@ finalize_it: * Interface change: added new parameter "InputName", permits the input to provide * a string that identifies it. May be NULL, but must be a valid char* pointer if * non-NULL. + * + * rgerhards, 2008-10-06: + * Interface change: added new parameter "stTime", which enables the caller to provide + * a timestamp that is to be used as timegenerated instead of the current system time. + * This is meant to facilitate performance optimization. Some inputs support such modes. + * If stTime is NULL, the current system time is used. */ rsRetVal parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType, - uchar *pszInputName) + uchar *pszInputName, struct syslogTime *stTime) { DEFiRet; register int iMsg; @@ -714,9 +730,6 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa * TODO: optimize buffer handling */ iMaxLine = glbl.GetMaxLine(); CHKmalloc(tmpline = malloc(sizeof(uchar) * (iMaxLine + 1))); -# ifdef USE_NETZIP - CHKmalloc(deflateBuf = malloc(sizeof(uchar) * (iMaxLine + 1))); -# endif /* we first check if we have a NUL character at the very end of the * message. This seems to be a frequent problem with a number of senders. @@ -762,6 +775,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa */ int ret; iLenDefBuf = iMaxLine; + CHKmalloc(deflateBuf = malloc(sizeof(uchar) * (iMaxLine + 1))); ret = uncompress((uchar *) deflateBuf, &iLenDefBuf, (uchar *) msg+1, len-1); dbgprintf("Compressed message uncompressed with status %d, length: new %ld, old %d.\n", ret, (long) iLenDefBuf, len-1); @@ -800,7 +814,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa */ if(iMsg == iMaxLine) { *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ - printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName); + printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName, stTime); } else { /* This case in theory never can happen. If it happens, we have * a logic error. I am checking for it, because if I would not, @@ -852,7 +866,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ /* typically, we should end up here! */ - printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName); + printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName, stTime); finalize_it: if(tmpline != NULL) @@ -1344,6 +1358,13 @@ static int parseRFCSyslogMsg(msg_t *pMsg, int flags) } else { /* we can not parse, so we get the system we * received the data from. + datetime.getCurrTime(&((*ppThis)->tRcvdAt)); + datetime.getCurrTime(&((*ppThis)->tRcvdAt)); + datetime.getCurrTime(&((*ppThis)->tRcvdAt)); + datetime.getCurrTime(&((*ppThis)->tRcvdAt)); + datetime.getCurrTime(&((*ppThis)->tRcvdAt)); + datetime.getCurrTime(&((*ppThis)->tRcvdAt)); + datetime.getCurrTime(&((*ppThis)->tRcvdAt)); */ MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); } -- cgit v1.2.3 From 8528344ef58b5d2907bba8809f63d0bca2ce8d38 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 7 Oct 2008 14:26:41 +0200 Subject: "output" timestamp now taken from mesg's time generated This enhances performance and, as some have pointed out, is probably also more consistent with what users expect how the various output-timestamp related function should work. This commit needs some more testing. --- tools/syslogd.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a6e17d8f..e794e2d1 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -589,7 +589,7 @@ void untty(void) * If stTime is NULL, the current system time is used. */ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int bParseHost, int flags, flowControl_t flowCtlType, - uchar *pszInputName, struct syslogTime *stTime) + uchar *pszInputName, struct syslogTime *stTime, time_t ttGenTime) { DEFiRet; register uchar *p; @@ -600,7 +600,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int b if(stTime == NULL) { CHKiRet(msgConstruct(&pMsg)); } else { - CHKiRet(msgConstructWithTime(&pMsg, stTime)); + CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime)); } if(pszInputName != NULL) MsgSetInputName(pMsg, (char*) pszInputName); @@ -703,7 +703,7 @@ finalize_it: */ rsRetVal parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType, - uchar *pszInputName, struct syslogTime *stTime) + uchar *pszInputName, struct syslogTime *stTime, time_t ttGenTime) { DEFiRet; register int iMsg; @@ -814,7 +814,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa */ if(iMsg == iMaxLine) { *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ - printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName, stTime); + printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName, stTime, ttGenTime); } else { /* This case in theory never can happen. If it happens, we have * a logic error. I am checking for it, because if I would not, @@ -866,7 +866,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ /* typically, we should end up here! */ - printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName, stTime); + printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName, stTime, ttGenTime); finalize_it: if(tmpline != NULL) @@ -1358,13 +1358,6 @@ static int parseRFCSyslogMsg(msg_t *pMsg, int flags) } else { /* we can not parse, so we get the system we * received the data from. - datetime.getCurrTime(&((*ppThis)->tRcvdAt)); - datetime.getCurrTime(&((*ppThis)->tRcvdAt)); - datetime.getCurrTime(&((*ppThis)->tRcvdAt)); - datetime.getCurrTime(&((*ppThis)->tRcvdAt)); - datetime.getCurrTime(&((*ppThis)->tRcvdAt)); - datetime.getCurrTime(&((*ppThis)->tRcvdAt)); - datetime.getCurrTime(&((*ppThis)->tRcvdAt)); */ MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); } -- cgit v1.2.3 From ace4f2f75202aec39449dac11b9eb1deca7428d7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 8 Oct 2008 18:55:11 +0200 Subject: reordered imudp processing. Message parsing is now done as part of main message queue worker processing (was part of the input thread) This should also improve performance, as potentially more work is done in parallel. --- tools/syslogd.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e794e2d1..1a26333d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -128,6 +128,7 @@ #include "vm.h" #include "errmsg.h" #include "datetime.h" +#include "parser.h" #include "sysvar.h" /* definitions for objects we access */ @@ -249,15 +250,15 @@ typedef struct legacyOptsLL_s { legacyOptsLL_t *pLegacyOptsLL = NULL; /* global variables for config file state */ -static int bDropTrailingLF = 1; /* drop trailing LF's on reception? */ +int bDropTrailingLF = 1; /* drop trailing LF's on reception? */ int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is the default, so if no -c option is given, we make ourselvs as compatible to sysklogd as possible. */ static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */ static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */ static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ -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 */ +uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence for control chars */ +int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */ static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ @@ -596,6 +597,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int b int pri; msg_t *pMsg; + pMsg->bIsParsed = 1; /* this is a hack until this function can be removed TODO: do it soon (rgerhards, 2008-10-09)! */ /* Now it is time to create the message object (rgerhards) */ if(stTime == NULL) { CHKiRet(msgConstruct(&pMsg)); @@ -1190,6 +1192,9 @@ msgConsumer(void __attribute__((unused)) *notNeeded, void *pUsr) assert(pMsg != NULL); + if(pMsg->bIsParsed == 0) { + parseMsg(pMsg); + } processMsg(pMsg); msgDestruct(&pMsg); @@ -1311,7 +1316,7 @@ static int parseRFCStructuredData(char **pp2parse, char *pResult) * * rger, 2005-11-24 */ -static int parseRFCSyslogMsg(msg_t *pMsg, int flags) +int parseRFCSyslogMsg(msg_t *pMsg, int flags) { char *p2parse; char *pBuf; @@ -1407,7 +1412,7 @@ static int parseRFCSyslogMsg(msg_t *pMsg, int flags) * but I thought I log it in this comment. * rgerhards, 2006-01-10 */ -static int parseLegacySyslogMsg(msg_t *pMsg, int flags) +int parseLegacySyslogMsg(msg_t *pMsg, int flags) { char *p2parse; char *pBuf; @@ -2908,6 +2913,8 @@ InitGlobalClasses(void) CHKiRet(actionClassInit()); pErrObj = "template"; CHKiRet(templateInit()); + pErrObj = "parser"; + CHKiRet(parserClassInit()); /* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ pErrObj = "net"; @@ -3526,6 +3533,5 @@ int main(int argc, char **argv) dbgClassInit(); return realMain(argc, argv); } - /* vim:set ai: */ -- cgit v1.2.3 From 5742f9cdd0da18a3ddfb0a51a981637124a6ab25 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 9 Oct 2008 07:48:22 +0200 Subject: fixing segfault caused by all inputs but imudp --- tools/syslogd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 1a26333d..a45942fa 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -597,13 +597,13 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int b int pri; msg_t *pMsg; - pMsg->bIsParsed = 1; /* this is a hack until this function can be removed TODO: do it soon (rgerhards, 2008-10-09)! */ /* Now it is time to create the message object (rgerhards) */ if(stTime == NULL) { CHKiRet(msgConstruct(&pMsg)); } else { CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime)); } + pMsg->bIsParsed = 1; /* this is a hack until this function can be removed TODO: do it soon (rgerhards, 2008-10-09)! */ if(pszInputName != NULL) MsgSetInputName(pMsg, (char*) pszInputName); MsgSetFlowControlType(pMsg, flowCtlType); @@ -1192,6 +1192,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, void *pUsr) assert(pMsg != NULL); +RUNLOG_VAR("%d", pMsg->bIsParsed); if(pMsg->bIsParsed == 0) { parseMsg(pMsg); } -- cgit v1.2.3 From 6c6e9a0f3f7d454ba9553a750b195d7f99c7299a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 9 Oct 2008 13:45:56 +0200 Subject: moved bParseHostname and bIsParsed to msgFlags This enables us to use more efficient calling conventions and also helps us keep the on-disk structure of a msg object more consistent in future releases. --- tools/syslogd.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a45942fa..13696955 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -588,8 +588,11 @@ void untty(void) * a timestamp that is to be used as timegenerated instead of the current system time. * This is meant to facilitate performance optimization. Some inputs support such modes. * If stTime is NULL, the current system time is used. + * + * rgerhards, 2008-10-09: + * interface change: bParseHostname removed, now in flags */ -static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int bParseHost, int flags, flowControl_t flowCtlType, +static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int flags, flowControl_t flowCtlType, uchar *pszInputName, struct syslogTime *stTime, time_t ttGenTime) { DEFiRet; @@ -603,13 +606,11 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int b } else { CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime)); } - pMsg->bIsParsed = 1; /* this is a hack until this function can be removed TODO: do it soon (rgerhards, 2008-10-09)! */ if(pszInputName != NULL) MsgSetInputName(pMsg, (char*) pszInputName); MsgSetFlowControlType(pMsg, flowCtlType); MsgSetRawMsg(pMsg, (char*)msg); - pMsg->bParseHOSTNAME = bParseHost; /* test for special codes */ pri = DEFUPRI; p = msg; @@ -634,7 +635,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int b * the message was received from (that, for obvious reasons, * being the local host). rgerhards 2004-11-16 */ - if(bParseHost == 0) + if((pMsg->msgFlags & PARSE_HOSTNAME) == 0) MsgSetHOSTNAME(pMsg, (char*)hname); MsgSetRcvFrom(pMsg, (char*)hname); CHKiRet(MsgSetRcvFromIP(pMsg, hnameIP)); @@ -702,9 +703,12 @@ finalize_it: * a timestamp that is to be used as timegenerated instead of the current system time. * This is meant to facilitate performance optimization. Some inputs support such modes. * If stTime is NULL, the current system time is used. + * + * rgerhards, 2008-10-09: + * interface change: bParseHostname removed, now in flags */ rsRetVal -parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType, +parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int flags, flowControl_t flowCtlType, uchar *pszInputName, struct syslogTime *stTime, time_t ttGenTime) { DEFiRet; @@ -816,7 +820,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa */ if(iMsg == iMaxLine) { *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ - printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName, stTime, ttGenTime); + printline(hname, hnameIP, tmpline, flags, flowCtlType, pszInputName, stTime, ttGenTime); } else { /* This case in theory never can happen. If it happens, we have * a logic error. I am checking for it, because if I would not, @@ -868,7 +872,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ /* typically, we should end up here! */ - printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName, stTime, ttGenTime); + printline(hname, hnameIP, tmpline, flags, flowCtlType, pszInputName, stTime, ttGenTime); finalize_it: if(tmpline != NULL) @@ -1192,8 +1196,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, void *pUsr) assert(pMsg != NULL); -RUNLOG_VAR("%d", pMsg->bIsParsed); - if(pMsg->bIsParsed == 0) { + if((pMsg->msgFlags & NEEDS_PARSING) != 0) { parseMsg(pMsg); } processMsg(pMsg); -- cgit v1.2.3 From 6334d335d89ae5df344f833c5095e9dea2abf6fb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 23 Oct 2008 14:46:47 +0200 Subject: added configuration directive "HUPisRestart" ...which enables to configure HUP to be either a full restart or "just" a leightweight way to close open files --- tools/syslogd.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 10 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 13696955..7145779d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -220,7 +220,7 @@ static char *PidFile = _PATH_LOGPID; /* read-only after startup */ static pid_t myPid; /* our pid for use in self-generated messages, e.g. on startup */ /* mypid is read-only after the initial fork() */ -static int restart = 0; /* do restart (config read) - multithread safe */ +static int bHadHUP = 0; /* did we have a HUP? */ static int bParseHOSTNAMEandTAG = 1; /* global config var: should the hostname and tag be * parsed inside message - rgerhards, 2006-03-13 */ @@ -2543,20 +2543,18 @@ static rsRetVal setMainMsgQueType(void __attribute__((unused)) *pVal, uchar *psz * The following function is resposible for handling a SIGHUP signal. Since * we are now doing mallocs/free as part of init we had better not being * doing this during a signal handler. Instead this function simply sets - * a flag variable which will tell the main loop to go through a restart. + * a flag variable which will tells the main loop to do "the right thing". */ void sighup_handler() { struct sigaction sigAct; - restart = 1; + bHadHUP = 1; memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = sighup_handler; sigaction(SIGHUP, &sigAct, NULL); - - return; } @@ -2578,6 +2576,49 @@ static void processImInternal(void) } +/* helper to doHUP(), this "HUPs" each action. The necessary locking + * is done inside the action class and nothing we need to take care of. + * rgerhards, 2008-10-22 + */ +DEFFUNC_llExecFunc(doHUPActions) +{ + BEGINfunc + actionCallHUPHdlr((action_t*) pData); + ENDfunc + return RS_RET_OK; /* we ignore errors, we can not do anything either way */ +} + + +/* This function processes a HUP after one has been detected. Note that this + * is *NOT* the sighup handler. The signal is recorded by the handler, that record + * detected inside the mainloop and then this function is called to do the + * real work. -- rgerhards, 2008-10-22 + */ +static inline void +doHUP(void) +{ + selector_t *f; + char buf[512]; + + snprintf(buf, sizeof(buf) / sizeof(char), + " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION + "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed, type '%s'.", + (int) myPid, glbl.GetHUPisRestart() ? "restart" : "lightweight"); + errno = 0; + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); + + if(glbl.GetHUPisRestart()) { + DBGPRINTF("Received SIGHUP, configured to be restart, reloading rsyslogd.\n"); + init(); /* main queue is stopped as part of init() */ + } else { + DBGPRINTF("Received SIGHUP, configured to be a non-restart type of HUP - notifying actions.\n"); + for(f = Files; f != NULL ; f = f->f_next) { + llExecFunc(&f->llActList, doHUPActions, NULL); + } + } +} + + /* This is the main processing loop. It is called after successful initialization. * When it returns, the syslogd terminates. * Its sole function is to provide some housekeeping things. The real work is done @@ -2634,11 +2675,9 @@ mainloop(void) if(bReduceRepeatMsgs == 1) doFlushRptdMsgs(); - if(restart) { - dbgprintf("\nReceived SIGHUP, reloading rsyslogd.\n"); - /* main queue is stopped as part of init() */ - init(); - restart = 0; + if(bHadHUP) { + doHUP(); + bHadHUP = 0; continue; } } -- cgit v1.2.3 From 57c9a3accee3a3e9b46d984c76c9aae7e2ec9c27 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 19 Nov 2008 13:20:31 +0100 Subject: exprimental implementaiton of $PrivDropToUser directive ... which permits to drop root privileges. This is not a completely secure way of dropping permissions, e.g. the group permissions need to be dropped, too. Also, there are several vulnerability Windows (see code comments). Finally, at least the imklog module on linux does not work when privileges are dropped. This code may still be a valuable addition, and so I have created an experimental branch so that people can check it out. --- tools/syslogd.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 7145779d..51ce1830 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -272,6 +272,7 @@ static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - * If the main queue is either not yet ready or not running in * queueing mode (mode DIRECT!), then this is set to 0. */ +static int uidDropPriv = 0; /* user-id to which priveleges should be dropped to (AFTER init()!) */ extern int errno; @@ -2063,6 +2064,30 @@ static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask) } +/* drop to specified user + * if something goes wrong, the function never returns + * Note that such an abort can cause damage to on-disk structures, so we should + * re-design the "interface" in the long term. -- rgerhards, 2008-11-19 + */ +static void doDropPrivUid(int iUid) +{ + int res; + uchar szBuf[1024]; + +dbgprintf("userid before drop: %d\n", getuid()); + res = setuid(iUid); +dbgprintf("userid after drop: %d\n", getuid()); + if(res) { + /* if we can not set the userid, this is fatal, so let's unconditionally abort */ + perror("could not set requested userid"); + exit(1); + } + DBGPRINTF("setuid(%d): %d\n", iUid, res); + snprintf((char*)szBuf, sizeof(szBuf)/sizeof(uchar), "rsyslogd's userid changed to %d", iUid); + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, szBuf, 0); +} + + /* helper to freeSelectors(), used with llExecFunc() to flush * pending output. -- rgerhards, 2007-08-02 * We do not need to lock the action object here as the processing @@ -2807,6 +2832,8 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &bErrMsgToStderr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, setMaxMsgSize, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouser", 0, eCmdHdlrUID, NULL, &uidDropPriv, NULL)); +// CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroup", 0, eCmdHdlrGID, doDropPrivGroup, NULL, NULL)); /* now add other modules handlers (we should work on that to be able to do it in ClassInit(), but so far * that is not possible). -- rgerhards, 2008-01-28 @@ -2900,8 +2927,20 @@ static rsRetVal mainThread() } /* Send a signal to the parent so it can terminate. */ - if (myPid != ppid) - kill (ppid, SIGTERM); + if(myPid != ppid) + kill(ppid, SIGTERM); + + + /* If instructed to do so, we now drop privileges. Note that this is not 100% secure, + * because inputs and outputs are already running at this time. However, we can implement + * dropping of privileges rather quickly and it will work in many cases. While it is not + * the ultimate solution, the current one is still much better than not being able to + * drop privileges at all. Doing it correctly, requires a change in architecture, which + * we should do over time. TODO -- rgerhards, 2008-11-19 + */ + if(uidDropPriv != 0) { + doDropPrivUid(uidDropPriv); + } /* END OF INTIALIZATION * ... but keep in mind that we might do a restart and thus init() might @@ -3520,11 +3559,14 @@ int realMain(int argc, char **argv) /* process compatibility mode settings */ - if(iCompatibilityMode < 3) { + if(iCompatibilityMode < 4) { errmsg.LogError(0, NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically " "generated config directives may interfer with your rsyslog.conf settings. " - "We suggest upgrading your config and adding -c3 as the first " + "We suggest upgrading your config and adding -c4 as the first " "rsyslogd option."); + } + + if(iCompatibilityMode < 3) { if(MarkInterval > 0) { legacyOptsEnq((uchar *) "ModLoad immark"); snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "MarkMessagePeriod %d", MarkInterval); -- cgit v1.2.3 From dc478db1ca80ef222f83985b539dfec1c66063e2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 26 Nov 2008 14:17:36 +0100 Subject: added ability to drop privileges Added $PrivDropToGroup, $PrivDropToUser, $PrivDropToGroupID, $PrivDropToUserID config directives to enable dropping privileges. This is an effort to provide a security enhancement. For the limits of this approach, see http://wiki.rsyslog.com/index.php/Security --- tools/syslogd.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 51ce1830..d132d139 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -82,6 +82,7 @@ #include #include #include +#include #if HAVE_SYS_TIMESPEC_H # include @@ -273,6 +274,7 @@ static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - * queueing mode (mode DIRECT!), then this is set to 0. */ static int uidDropPriv = 0; /* user-id to which priveleges should be dropped to (AFTER init()!) */ +static int gidDropPriv = 0; /* group-id to which priveleges should be dropped to (AFTER init()!) */ extern int errno; @@ -2064,6 +2066,34 @@ static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask) } +/* drop to specified group + * if something goes wrong, the function never returns + * Note that such an abort can cause damage to on-disk structures, so we should + * re-design the "interface" in the long term. -- rgerhards, 2008-11-26 + */ +static void doDropPrivGid(int iGid) +{ + int res; + uchar szBuf[1024]; + + res = setgroups(0, NULL); /* remove all supplementary group IDs */ + if(res) { + perror("could not remove supplemental group IDs"); + exit(1); + } + DBGPRINTF("setgroups(0, NULL): %d\n", res); + res = setgid(iGid); + if(res) { + /* if we can not set the userid, this is fatal, so let's unconditionally abort */ + perror("could not set requested group id"); + exit(1); + } + DBGPRINTF("setgid(%d): %d\n", iGid, res); + snprintf((char*)szBuf, sizeof(szBuf)/sizeof(uchar), "rsyslogd's groupid changed to %d", iGid); + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, szBuf, 0); +} + + /* drop to specified user * if something goes wrong, the function never returns * Note that such an abort can cause damage to on-disk structures, so we should @@ -2074,9 +2104,7 @@ static void doDropPrivUid(int iUid) int res; uchar szBuf[1024]; -dbgprintf("userid before drop: %d\n", getuid()); res = setuid(iUid); -dbgprintf("userid after drop: %d\n", getuid()); if(res) { /* if we can not set the userid, this is fatal, so let's unconditionally abort */ perror("could not set requested userid"); @@ -2833,7 +2861,9 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &bErrMsgToStderr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, setMaxMsgSize, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouser", 0, eCmdHdlrUID, NULL, &uidDropPriv, NULL)); -// CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroup", 0, eCmdHdlrGID, doDropPrivGroup, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouserid", 0, eCmdHdlrInt, NULL, &uidDropPriv, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroup", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroupid", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL)); /* now add other modules handlers (we should work on that to be able to do it in ClassInit(), but so far * that is not possible). -- rgerhards, 2008-01-28 @@ -2938,10 +2968,17 @@ static rsRetVal mainThread() * drop privileges at all. Doing it correctly, requires a change in architecture, which * we should do over time. TODO -- rgerhards, 2008-11-19 */ + if(gidDropPriv != 0) { + doDropPrivGid(gidDropPriv); + glbl.SetHUPisRestart(0); /* we can not do restart-type HUPs with dropped privs */ + } + if(uidDropPriv != 0) { doDropPrivUid(uidDropPriv); + glbl.SetHUPisRestart(0); /* we can not do restart-type HUPs with dropped privs */ } + /* END OF INTIALIZATION * ... but keep in mind that we might do a restart and thus init() might * be called again. If that happens, we must shut down the worker thread, -- cgit v1.2.3 From 31344728fe6f83d4f02ce0e5868c331b4e25d659 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 20 Dec 2008 12:56:41 +0100 Subject: bufgix: $PreserveFQDN was not properly handled for locally emitted messages --- tools/syslogd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 138bdfd8..2cac8fe4 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3288,6 +3288,7 @@ int realMain(int argc, char **argv) uchar legacyConfLine[80]; uchar *LocalHostName; uchar *LocalDomain; + uchar *LocalFQDNName; /* first, parse the command line options. We do not carry out any actual work, just * see what we should do. This relieves us from certain anomalies and we can process @@ -3392,7 +3393,9 @@ int realMain(int argc, char **argv) /* get our host and domain names - we need to do this early as we may emit * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 */ - net.getLocalHostname(&LocalHostName); + net.getLocalHostname(&LocalFQDNName); + CHKmalloc(LocalHostName = (uchar*) strdup((char*)LocalFQDNName)); + glbl.SetLocalFQDNName(LocalFQDNName); /* set the FQDN before we modify it */ if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { *p++ = '\0'; LocalDomain = p; -- cgit v1.2.3 From d9b0c77d3e719d4c08361e62f3b067228c30f6a9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 16 Apr 2008 15:27:53 +0200 Subject: some more cleanup reduced dependencies, moved non-runtime files to its own directory except for some whom's status is unclear --- tools/syslogd.c | 3441 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3441 insertions(+) create mode 100644 tools/syslogd.c (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c new file mode 100644 index 00000000..95a23e99 --- /dev/null +++ b/tools/syslogd.c @@ -0,0 +1,3441 @@ +/** + * \brief This is the main file of the rsyslogd daemon. + * + * Please visit the rsyslog project at + * + * http://www.rsyslog.com + * + * to learn more about it and discuss any questions you may have. + * + * rsyslog had initially been forked from the sysklogd project. + * I would like to express my thanks to the developers of the sysklogd + * package - without it, I would have had a much harder start... + * + * Please note that while rsyslog started from the sysklogd code base, + * it nowadays has almost nothing left in common with it. Allmost all + * parts of the code have been rewritten. + * + * This Project was intiated and is maintained by + * Rainer Gerhards . See + * AUTHORS to learn who helped make it become a reality. + * + * If you have questions about rsyslogd in general, please email + * info@adiscon.com. To learn more about rsyslogd, please visit + * http://www.rsyslog.com. + * + * \author Rainer Gerhards + * \date 2003-10-17 + * Some initial modifications on the sysklogd package to support + * liblogging. These have actually not yet been merged to the + * source you see currently (but they hopefully will) + * + * \date 2004-10-28 + * Restarted the modifications of sysklogd. This time, we + * focus on a simpler approach first. The initial goal is to + * provide MySQL database support (so that syslogd can log + * to the database). + * + * rsyslog - An Enhanced syslogd Replacement. + * Copyright 2003-2008 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see . + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" +#include "rsyslog.h" + +/* change the following setting to e.g. 32768 if you would like to + * support large message sizes for IHE (32k is the current maximum + * needed for IHE). I was initially tempted to increase it to 32k, + * but there is a large memory footprint with the current + * implementation in rsyslog. This will change as the processing + * changes, but I have re-set it to 1k, because the vast majority + * of messages is below that and the memory savings is huge, at + * least compared to the overall memory footprint. + * + * If you intend to receive Windows Event Log data (e.g. via + * EventReporter - www.eventreporter.com), you might want to + * increase this number to an even higher value, as event + * log messages can be very lengthy. + * rgerhards, 2005-07-05 + * + * during my recent testing, it showed that 4k seems to be + * the typical maximum for UDP based syslog. This is a IP stack + * restriction. Not always ... but very often. If you go beyond + * that value, be sure to test that rsyslogd actually does what + * you think it should do ;) Also, it is a good idea to check the + * doc set for anything on IHE - it most probably has information on + * message sizes. + * rgerhards, 2005-08-05 + * + * I have increased the default message size to 2048 to be in sync + * with recent IETF syslog standardization efforts. + * rgerhards, 2006-11-30 + */ +#define DEFUPRI (LOG_USER|LOG_NOTICE) +#define TIMERINTVL 30 /* interval for checking flush, mark */ + +#include +#include +#include +#include +#include +#include +#define GNU_SOURCE +#include +#include +#include +#include +#include + +#ifdef __sun +# include +#else +# include +#endif +#include +#include +#include + +#if HAVE_SYS_TIMESPEC_H +# include +#endif + +#if HAVE_SYS_STAT_H +# include +#endif + +#include + +#if HAVE_PATHS_H +#include +#endif + +#ifdef USE_NETZIP +#include +#endif + +#include + +#include "pidfile.h" +#include "srUtils.h" +#include "stringbuf.h" +#include "syslogd-types.h" +#include "template.h" +#include "outchannel.h" +#include "syslogd.h" + +#include "msg.h" +#include "modules.h" +#include "action.h" +#include "iminternal.h" +#include "cfsysline.h" +#include "omshell.h" +#include "omusrmsg.h" +#include "omfwd.h" +#include "omfile.h" +#include "omdiscard.h" +#include "threads.h" +#include "queue.h" +#include "stream.h" +#include "conf.h" +#include "vm.h" +#include "errmsg.h" +#include "datetime.h" +#include "sysvar.h" + +/* definitions for objects we access */ +DEFobjCurrIf(obj) +DEFobjCurrIf(datetime) +DEFobjCurrIf(conf) +DEFobjCurrIf(expr) +DEFobjCurrIf(vm) +DEFobjCurrIf(var) +DEFobjCurrIf(module) +DEFobjCurrIf(errmsg) +DEFobjCurrIf(net) /* TODO: make go away! */ + + +/* forward definitions */ +static rsRetVal GlobalClassExit(void); + +/* We define our own set of syslog defintions so that we + * do not need to rely on (possibly different) implementations. + * 2007-07-19 rgerhards + */ +/* missing definitions for solaris + * 2006-02-16 Rger + */ +#ifdef __sun +# define LOG_AUTHPRIV LOG_AUTH +#endif +#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */ +#define LOG_FTP (11<<3) /* ftp daemon */ + + +#ifndef UTMP_FILE +#ifdef UTMP_FILENAME +#define UTMP_FILE UTMP_FILENAME +#else +#ifdef _PATH_UTMP +#define UTMP_FILE _PATH_UTMP +#else +#define UTMP_FILE "/etc/utmp" +#endif +#endif +#endif + +#ifndef _PATH_LOGCONF +#define _PATH_LOGCONF "/etc/rsyslog.conf" +#endif + +#ifndef _PATH_MODDIR +#define _PATH_MODDIR "/lib/rsyslog/" +#endif + +#if defined(SYSLOGD_PIDNAME) +# undef _PATH_LOGPID +# if defined(FSSTND) +# ifdef OS_BSD +# define _PATH_VARRUN "/var/run/" +# endif +# if defined(__sun) || defined(__hpux) +# define _PATH_VARRUN "/var/run/" +# endif +# define _PATH_LOGPID _PATH_VARRUN SYSLOGD_PIDNAME +# else +# define _PATH_LOGPID "/etc/" SYSLOGD_PIDNAME +# endif +#else +# ifndef _PATH_LOGPID +# if defined(__sun) || defined(__hpux) +# define _PATH_VARRUN "/var/run/" +# endif +# if defined(FSSTND) +# define _PATH_LOGPID _PATH_VARRUN "rsyslogd.pid" +# else +# define _PATH_LOGPID "/etc/rsyslogd.pid" +# endif +# endif +#endif + +#ifndef _PATH_DEV +# define _PATH_DEV "/dev/" +#endif + +#ifndef _PATH_TTY +#define _PATH_TTY "/dev/tty" +#endif + +static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */ +static char *PidFile = _PATH_LOGPID; /* read-only after startup */ + +static pid_t myPid; /* our pid for use in self-generated messages, e.g. on startup */ +/* mypid is read-only after the initial fork() */ +static int restart = 0; /* do restart (config read) - multithread safe */ + +int glblHadMemShortage = 0; /* indicates if we had memory shortage some time during the run */ + + +static int bParseHOSTNAMEandTAG = 1; /* global config var: should the hostname and tag be + * parsed inside message - rgerhards, 2006-03-13 */ +static int bFinished = 0; /* used by termination signal handler, read-only except there + * is either 0 or the number of the signal that requested the + * termination. + */ + +/* Intervals at which we flush out "message repeated" messages, + * in seconds after previous message is logged. After each flush, + * we move to the next interval until we reach the largest. + * TODO: this shall go into action object! -- rgerhards, 2008-01-29 + */ +int repeatinterval[2] = { 30, 60 }; /* # of secs before flush */ + +#define LIST_DELIMITER ':' /* delimiter between two hosts */ + +struct filed *Files = NULL; /* read-only after init() (but beware of sigusr1!) */ + +static pid_t ppid; /* This is a quick and dirty hack used for spliting main/startup thread */ + +typedef struct legacyOptsLL_s { + uchar *line; + struct legacyOptsLL_s *next; +} legacyOptsLL_t; +legacyOptsLL_t *pLegacyOptsLL = NULL; + +/* global variables for config file state */ +static int bDropTrailingLF = 1; /* drop trailing LF's on reception? */ +int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is + the default, so if no -c option is given, we make ourselvs + as compatible to sysklogd as possible. */ +static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */ +static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */ +static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ +int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */ +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 */ +int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ +int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ +int iActExecOnceInterval = 0; /* execute action once every nn seconds */ +uchar *pszWorkDir = NULL;/* name of rsyslog's spool directory (without trailing slash) */ +uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */ +/* end global config file state variables */ + +uchar *LocalHostName;/* our hostname - read-only after startup */ +char *LocalDomain; /* our local domain name - read-only after startup */ +int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ +int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both), set via cmdline */ +int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ +static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */ +int DisableDNS = 0; /* don't look up IP addresses of remote messages */ +char **StripDomains = NULL;/* these domains may be stripped before writing logs - r/o after s.u., never touched by init */ +char **LocalHosts = NULL;/* these hosts are logged with their hostname - read-only after startup, never touched by init */ +static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - is available + * If the main queue is either not yet ready or not running in + * queueing mode (mode DIRECT!), then this is set to 0. + */ + +extern int errno; + +/* main message queue and its configuration parameters */ +static queue_t *pMsgQueue = NULL; /* the main message queue */ +static int iMainMsgQueueSize = 10000; /* size of the main message queue above */ +static int iMainMsgQHighWtrMark = 8000; /* high water mark for disk-assisted queues */ +static int iMainMsgQLowWtrMark = 2000; /* low water mark for disk-assisted queues */ +static int iMainMsgQDiscardMark = 9800; /* begin to discard messages */ +static int iMainMsgQDiscardSeverity = 8; /* by default, discard nothing to prevent unintentional loss */ +static int iMainMsgQueueNumWorkers = 1; /* number of worker threads for the mm queue above */ +static queueType_t MainMsgQueType = QUEUETYPE_FIXED_ARRAY; /* type of the main message queue above */ +static uchar *pszMainMsgQFName = NULL; /* prefix for the main message queue file */ +static int64 iMainMsgQueMaxFileSize = 1024*1024; +static int iMainMsgQPersistUpdCnt = 0; /* persist queue info every n updates */ +static int iMainMsgQtoQShutdown = 0; /* queue shutdown */ +static int iMainMsgQtoActShutdown = 1000; /* action shutdown (in phase 2) */ +static int iMainMsgQtoEnq = 2000; /* timeout for queue enque */ +static int iMainMsgQtoWrkShutdown = 60000; /* timeout for worker thread shutdown */ +static int iMainMsgQWrkMinMsgs = 100; /* minimum messages per worker needed to start a new one */ +static int iMainMsgQDeqSlowdown = 0; /* dequeue slowdown (simple rate limiting) */ +static int64 iMainMsgQueMaxDiskSpace = 0; /* max disk space allocated 0 ==> unlimited */ +static int bMainMsgQSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */ +static int iMainMsgQueueDeqtWinFromHr = 0; /* hour begin of time frame when queue is to be dequeued */ +static int iMainMsgQueueDeqtWinToHr = 25; /* hour begin of time frame when queue is to be dequeued */ + + +/* support for simple textual representation of FIOP names + * rgerhards, 2005-09-27 + */ +static char* getFIOPName(unsigned iFIOP) +{ + char *pRet; + switch(iFIOP) { + case FIOP_CONTAINS: + pRet = "contains"; + break; + case FIOP_ISEQUAL: + pRet = "isequal"; + break; + case FIOP_STARTSWITH: + pRet = "startswith"; + break; + case FIOP_REGEX: + pRet = "regex"; + break; + default: + pRet = "NOP"; + break; + } + return pRet; +} + + +/* Reset config variables to default values. + * rgerhards, 2007-07-17 + */ +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + cCCEscapeChar = '#'; + bActExecWhenPrevSusp = 0; + iActExecOnceInterval = 0; + bDebugPrintTemplateList = 1; + bDebugPrintCfSysLineHandlerList = 1; + bDebugPrintModuleList = 1; + bEscapeCCOnRcv = 1; /* default is to escape control characters */ + bReduceRepeatMsgs = 0; + bDropMalPTRMsgs = 0; + if(pszWorkDir != NULL) { + free(pszWorkDir); + pszWorkDir = NULL; + } + if(pszMainMsgQFName != NULL) { + free(pszMainMsgQFName); + pszMainMsgQFName = NULL; + } + iMainMsgQueueSize = 10000; + iMainMsgQHighWtrMark = 8000; + iMainMsgQLowWtrMark = 2000; + iMainMsgQDiscardMark = 9800; + iMainMsgQDiscardSeverity = 4; + iMainMsgQueMaxFileSize = 1024 * 1024; + iMainMsgQueueNumWorkers = 1; + iMainMsgQPersistUpdCnt = 0; + iMainMsgQtoQShutdown = 0; + iMainMsgQtoActShutdown = 1000; + iMainMsgQtoEnq = 2000; + iMainMsgQtoWrkShutdown = 60000; + iMainMsgQWrkMinMsgs = 100; + iMainMsgQDeqSlowdown = 0; + bMainMsgQSaveOnShutdown = 1; + MainMsgQueType = QUEUETYPE_FIXED_ARRAY; + iMainMsgQueMaxDiskSpace = 0; + glbliActionResumeRetryCount = 0; + + return RS_RET_OK; +} + + + +int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */ + + +/* hardcoded standard templates (used for defaults) */ +static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n\""; +static uchar template_TraditionalFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\""; +static uchar template_FileFormat[] = "\"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\""; +static uchar template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r\""; +static uchar template_ForwardFormat[] = "\"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg%\""; +static uchar template_TraditionalForwardFormat[] = "\"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg%\""; +static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\""; +static uchar template_StdDBFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')\",SQL"; +static uchar template_StdPgSQLFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%')\",STDSQL"; +/* end template */ + + +/* up to the next comment, prototypes that should be removed by reordering */ +/* Function prototypes. */ +static char **crunch_list(char *list); +static void reapchild(); +static void debug_switch(); +static void sighup_handler(); +static void freeSelectors(void); +static void processImInternal(void); + + +static int usage(void) +{ + fprintf(stderr, "usage: rsyslogd [-cversion] [-46AdnqQvwx] [-lhostlist] [-sdomainlist]\n" + " [-fconffile] [-ipidfile]\n" + "To run rsyslogd in native mode, use \"rsyslogd -c3 \"\n\n" + "For further information see http://www.rsyslog.com/doc\n"); + exit(1); /* "good" exit - done to terminate usage() */ +} + + +/* function to destruct a selector_t object + * rgerhards, 2007-08-01 + */ +rsRetVal +selectorDestruct(void *pVal) +{ + selector_t *pThis = (selector_t *) pVal; + + assert(pThis != NULL); + + if(pThis->pCSHostnameComp != NULL) + rsCStrDestruct(&pThis->pCSHostnameComp); + if(pThis->pCSProgNameComp != NULL) + rsCStrDestruct(&pThis->pCSProgNameComp); + + if(pThis->f_filter_type == FILTER_PROP) { + if(pThis->f_filterData.prop.pCSPropName != NULL) + rsCStrDestruct(&pThis->f_filterData.prop.pCSPropName); + if(pThis->f_filterData.prop.pCSCompValue != NULL) + rsCStrDestruct(&pThis->f_filterData.prop.pCSCompValue); + } else if(pThis->f_filter_type == FILTER_EXPR) { + if(pThis->f_filterData.f_expr != NULL) + expr.Destruct(&pThis->f_filterData.f_expr); + } + + llDestroy(&pThis->llActList); + free(pThis); + + return RS_RET_OK; +} + + +/* function to construct a selector_t object + * rgerhards, 2007-08-01 + */ +rsRetVal +selectorConstruct(selector_t **ppThis) +{ + DEFiRet; + selector_t *pThis; + + assert(ppThis != NULL); + + if((pThis = (selector_t*) calloc(1, sizeof(selector_t))) == NULL) { + glblHadMemShortage = 1; + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + CHKiRet(llInit(&pThis->llActList, actionDestruct, NULL, NULL)); + +finalize_it: + if(iRet != RS_RET_OK) { + if(pThis != NULL) { + selectorDestruct(pThis); + } + } + *ppThis = pThis; + RETiRet; +} + + +/* rgerhards, 2005-10-24: crunch_list is called only during option processing. So + * it is never called once rsyslogd is running (not even when HUPed). This code + * contains some exits, but they are considered safe because they only happen + * during startup. Anyhow, when we review the code here, we might want to + * reconsider the exit()s. + */ +static char **crunch_list(char *list) +{ + int count, i; + char *p, *q; + char **result = NULL; + + p = list; + + /* strip off trailing delimiters */ + while (p[strlen(p)-1] == LIST_DELIMITER) { + count--; + p[strlen(p)-1] = '\0'; + } + /* cut off leading delimiters */ + while (p[0] == LIST_DELIMITER) { + count--; + p++; + } + + /* count delimiters to calculate elements */ + for (count=i=0; p[i]; i++) + if (p[i] == LIST_DELIMITER) count++; + + if ((result = (char **)malloc(sizeof(char *) * (count+2))) == NULL) { + printf ("Sorry, can't get enough memory, exiting.\n"); + exit(0); /* safe exit, because only called during startup */ + } + + /* + * We now can assume that the first and last + * characters are different from any delimiters, + * so we don't have to care about this. + */ + count = 0; + while ((q=strchr(p, LIST_DELIMITER))) { + result[count] = (char *) malloc((q - p + 1) * sizeof(char)); + if (result[count] == NULL) { + printf ("Sorry, can't get enough memory, exiting.\n"); + exit(0); /* safe exit, because only called during startup */ + } + strncpy(result[count], p, q - p); + result[count][q - p] = '\0'; + p = q; p++; + count++; + } + if ((result[count] = \ + (char *)malloc(sizeof(char) * strlen(p) + 1)) == NULL) { + printf ("Sorry, can't get enough memory, exiting.\n"); + exit(0); /* safe exit, because only called during startup */ + } + strcpy(result[count],p); + result[++count] = NULL; + +#if 0 + count=0; + while (result[count]) + dbgprintf("#%d: %s\n", count, StripDomains[count++]); +#endif + return result; +} + + +void untty(void) +#ifdef HAVE_SETSID +{ + if ( !Debug ) { + setsid(); + } + return; +} +#else +{ + int i; + + if ( !Debug ) { + i = open(_PATH_TTY, O_RDWR); + if (i >= 0) { +# if !defined(__hpux) + (void) ioctl(i, (int) TIOCNOTTY, (char *)0); +# else + /* TODO: we need to implement something for HP UX! -- rgerhards, 2008-03-04 */ + /* actually, HP UX should have setsid, so the code directly above should + * trigger. So the actual question is why it doesn't do that... + */ +# endif + (void) close(i); + } + } +} +#endif + + +/* Take a raw input line, decode the message, and print the message + * on the appropriate log files. + * rgerhards 2004-11-08: Please note + * that this function does only a partial decoding. At best, it splits + * the PRI part. No further decode happens. The rest is done in + * logmsg(). + * Added the iSource parameter so that we know if we have to parse + * HOSTNAME or not. rgerhards 2004-11-16. + * changed parameter iSource to bParseHost. For details, see comment in + * printchopped(). rgerhards 2005-10-06 + * rgerhards: 2008-03-06: added "flags" to allow an input module to specify + * flags, most importantly to request ignoring the messages' timestamp. + * + * rgerhards, 2008-03-19: + * I added an additional calling parameter to permit specifying the flow + * control capability of the source. + */ +rsRetVal printline(char *hname, char *msg, int bParseHost, int flags, flowControl_t flowCtlType) +{ + DEFiRet; + register char *p; + int pri; + msg_t *pMsg; + + /* Now it is time to create the message object (rgerhards) + */ + CHKiRet(msgConstruct(&pMsg)); + MsgSetFlowControlType(pMsg, flowCtlType); + MsgSetRawMsg(pMsg, msg); + + pMsg->bParseHOSTNAME = bParseHost; + /* test for special codes */ + pri = DEFUPRI; + p = msg; + if (*p == '<') { + pri = 0; + while (isdigit((int) *++p)) + { + pri = 10 * pri + (*p - '0'); + } + if (*p == '>') + ++p; + } + if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) + pri = DEFUPRI; + pMsg->iFacility = LOG_FAC(pri); + pMsg->iSeverity = LOG_PRI(pri); + + /* Now we look at the HOSTNAME. That is a bit complicated... + * If we have a locally received message, it does NOT + * contain any hostname information in the message itself. + * As such, the HOSTNAME is the same as the system that + * the message was received from (that, for obvious reasons, + * being the local host). rgerhards 2004-11-16 + */ + if(bParseHost == 0) + MsgSetHOSTNAME(pMsg, hname); + MsgSetRcvFrom(pMsg, hname); + + /* rgerhards 2004-11-19: well, well... we've now seen that we + * have the "hostname problem" also with the traditional Unix + * message. As we like to emulate it, we need to add the hostname + * to it. + */ + if(MsgSetUxTradMsg(pMsg, p) != 0) + ABORT_FINALIZE(RS_RET_ERR); + + logmsg(pMsg, flags | SYNC_FILE); + +finalize_it: + RETiRet; +} + + +/* This takes a received message that must be decoded and submits it to + * the main message queue. The function calls the necessary parser. + * + * rgerhards, 2006-11-30: I have greatly changed this function. Formerly, + * it tried to reassemble multi-part messages, which is a legacy stock + * sysklogd concept. In essence, that was that messages not ending with + * \0 were glued together. As far as I can see, this is a sysklogd + * specific feature and, from looking at the code, seems to be used + * pretty seldom (if at all). I remove this now, not the least because it is totally + * incompatible with upcoming IETF syslog standards. If you experience + * strange behaviour with messages beeing split across multiple lines, + * this function here might be the place to look at. + * + * Some previous history worth noting: + * I added the "iSource" parameter. This is needed to distinguish between + * messages that have a hostname in them (received from the internet) and + * those that do not have (most prominently /dev/log). rgerhards 2004-11-16 + * And now I removed the "iSource" parameter and changed it to be "bParseHost", + * because all that it actually controls is whether the host is parsed or not. + * For rfc3195 support, we needed to modify the algo for host parsing, so we can + * no longer rely just on the source (rfc3195d forwarded messages arrive via + * unix domain sockets but contain the hostname). rgerhards, 2005-10-06 + * + * rgerhards, 2008-02-18: + * This function was previously called "printchopped"() and has been renamed + * as part of the effort to create a clean internal message submission interface. + * It also has been adopted to our usual calling interface, but currently does + * not provide any useful return states. But we now have the hook and things can + * improve in the future. <-- TODO! + * + * rgerhards, 2008-03-19: + * I added an additional calling parameter to permit specifying the flow + * control capability of the source. + */ +rsRetVal +parseAndSubmitMessage(char *hname, char *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType) +{ + DEFiRet; + register int iMsg; + char *pMsg; + char *pData; + char *pEnd; + char tmpline[MAXLINE + 1]; +# ifdef USE_NETZIP + char deflateBuf[MAXLINE + 1]; + uLongf iLenDefBuf; +# endif + + assert(hname != NULL); + assert(msg != NULL); + assert(len >= 0); + + /* we first check if we have a NUL character at the very end of the + * message. This seems to be a frequent problem with a number of senders. + * So I have now decided to drop these NULs. However, if they are intentional, + * that may cause us some problems, e.g. with syslog-sign. On the other hand, + * current code always has problems with intentional NULs (as it needs to escape + * them to prevent problems with the C string libraries), so that does not + * really matter. Just to be on the save side, we'll log destruction of such + * NULs in the debug log. + * rgerhards, 2007-09-14 + */ + if(*(msg + len - 1) == '\0') { + dbgprintf("dropped NUL at very end of message\n"); + len--; + } + + /* then we check if we need to drop trailing LFs, which often make + * their way into syslog messages unintentionally. In order to remain + * compatible to recent IETF developments, we allow the user to + * turn on/off this handling. rgerhards, 2007-07-23 + */ + if(bDropTrailingLF && *(msg + len - 1) == '\n') { + dbgprintf("dropped LF at very end of message (DropTrailingLF is set)\n"); + len--; + } + + iMsg = 0; /* initialize receiving buffer index */ + pMsg = tmpline; /* set receiving buffer pointer */ + pData = msg; /* set source buffer pointer */ + pEnd = msg + len; /* this is one off, which is intensional */ + +# ifdef USE_NETZIP + /* we first need to check if we have a compressed record. If so, + * we must decompress it. + */ + if(len > 0 && *msg == 'z') { /* compressed data present? (do NOT change order if conditions!) */ + /* we have compressed data, so let's deflate it. We support a maximum + * message size of MAXLINE. If it is larger, an error message is logged + * and the message is dropped. We do NOT try to decompress larger messages + * as such might be used for denial of service. It might happen to later + * builds that such functionality be added as an optional, operator-configurable + * feature. + */ + int ret; + iLenDefBuf = MAXLINE; + ret = uncompress((uchar *) deflateBuf, &iLenDefBuf, (uchar *) msg+1, len-1); + dbgprintf("Compressed message uncompressed with status %d, length: new %ld, old %d.\n", + ret, (long) iLenDefBuf, len-1); + /* Now check if the uncompression worked. If not, there is not much we can do. In + * that case, we log an error message but ignore the message itself. Storing the + * compressed text is dangerous, as it contains control characters. So we do + * not do this. If someone would like to have a copy, this code here could be + * modified to do a hex-dump of the buffer in question. We do not include + * this functionality right now. + * rgerhards, 2006-12-07 + */ + if(ret != Z_OK) { + errmsg.LogError(NO_ERRCODE, "Uncompression of a message failed with return code %d " + "- enable debug logging if you need further information. " + "Message ignored.", ret); + FINALIZE; /* unconditional exit, nothing left to do... */ + } + pData = deflateBuf; + pEnd = deflateBuf + iLenDefBuf; + } +# else /* ifdef USE_NETZIP */ + /* in this case, we still need to check if the message is compressed. If so, we must + * tell the user we can not accept it. + */ + if(len > 0 && *msg == 'z') { + errmsg.LogError(NO_ERRCODE, "Received a compressed message, but rsyslogd does not have compression " + "support enabled. The message will be ignored."); + FINALIZE; + } +# endif /* ifdef USE_NETZIP */ + + while(pData < pEnd) { + if(iMsg >= MAXLINE) { + /* emergency, we now need to flush, no matter if + * we are at end of message or not... + */ + if(iMsg == MAXLINE) { + *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ + printline(hname, tmpline, bParseHost, flags, flowCtlType); + } else { + /* This case in theory never can happen. If it happens, we have + * a logic error. I am checking for it, because if I would not, + * we would address memory invalidly with the code above. I + * do not care much about this case, just a debug log entry + * (I couldn't do any more smart things anyway...). + * rgerhards, 2007-9-20 + */ + dbgprintf("internal error: iMsg > MAXLINE in printchopped()\n"); + } + FINALIZE; /* in this case, we are done... nothing left we can do */ + } + if(*pData == '\0') { /* guard against \0 characters... */ + /* changed to the sequence (somewhat) proposed in + * draft-ietf-syslog-protocol-19. rgerhards, 2006-11-30 + */ + if(iMsg + 3 < MAXLINE) { /* do we have space? */ + *(pMsg + iMsg++) = cCCEscapeChar; + *(pMsg + iMsg++) = '0'; + *(pMsg + iMsg++) = '0'; + *(pMsg + iMsg++) = '0'; + } /* if we do not have space, we simply ignore the '\0'... */ + /* log an error? Very questionable... rgerhards, 2006-11-30 */ + /* decided: we do not log an error, it won't help... rger, 2007-06-21 */ + ++pData; + } else if(bEscapeCCOnRcv && iscntrl((int) *pData)) { + /* we are configured to escape control characters. Please note + * that this most probably break non-western character sets like + * Japanese, Korean or Chinese. rgerhards, 2007-07-17 + * Note: sysklogd logs octal values only for DEL and CCs above 127. + * For others, it logs ^n where n is the control char converted to an + * alphabet character. We like consistency and thus escape it to octal + * in all cases. If someone complains, we may change the mode. At least + * we known now what's going on. + * rgerhards, 2007-07-17 + */ + if(iMsg + 3 < MAXLINE) { /* do we have space? */ + *(pMsg + iMsg++) = cCCEscapeChar; + *(pMsg + iMsg++) = '0' + ((*pData & 0300) >> 6); + *(pMsg + iMsg++) = '0' + ((*pData & 0070) >> 3); + *(pMsg + iMsg++) = '0' + ((*pData & 0007)); + } /* again, if we do not have space, we ignore the char - see comment at '\0' */ + ++pData; + } else { + *(pMsg + iMsg++) = *pData++; + } + } + + *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ + + /* typically, we should end up here! */ + printline(hname, tmpline, bParseHost, flags, flowCtlType); + +finalize_it: + RETiRet; +} + +/* rgerhards 2004-11-09: the following is a function that can be used + * to log a message orginating from the syslogd itself. In sysklogd code, + * this is done by simply calling logmsg(). However, logmsg() is changed in + * rsyslog so that it takes a msg "object". So it can no longer be called + * directly. This method here solves the need. It provides an interface that + * allows to construct a locally-generated message. Please note that this + * function here probably is only an interim solution and that we need to + * think on the best way to do this. + */ +rsRetVal +logmsgInternal(int pri, char *msg, int flags) +{ + DEFiRet; + msg_t *pMsg; + + CHKiRet(msgConstruct(&pMsg)); + MsgSetUxTradMsg(pMsg, msg); + MsgSetRawMsg(pMsg, msg); + MsgSetHOSTNAME(pMsg, (char*)LocalHostName); + MsgSetRcvFrom(pMsg, (char*)LocalHostName); + MsgSetTAG(pMsg, "rsyslogd:"); + pMsg->iFacility = LOG_FAC(pri); + pMsg->iSeverity = LOG_PRI(pri); + pMsg->bParseHOSTNAME = 0; + datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ + flags |= INTERNAL_MSG; + + if(bHaveMainQueue == 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(pMsg, flags); + } +finalize_it: + RETiRet; +} + +/* This functions looks at the given message and checks if it matches the + * provided filter condition. If so, it returns true, else it returns + * false. This is a helper to logmsg() and meant to drive the decision + * process if a message is to be processed or not. As I expect this + * decision code to grow more complex over time AND logmsg() is already + * a very lengthy function, I thought a separate function is more appropriate. + * 2005-09-19 rgerhards + * 2008-02-25 rgerhards: changed interface, now utilizes iRet, bProcessMsg + * returns is message should be procesed. + */ +static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProcessMsg) +{ + DEFiRet; + unsigned short pbMustBeFreed; + char *pszPropVal; + int bRet = 0; + vm_t *pVM = NULL; + var_t *pResult = NULL; + + assert(f != NULL); + assert(pMsg != NULL); + + /* we first have a look at the global, BSD-style block filters (for tag + * and host). Only if they match, we evaluate the actual filter. + * rgerhards, 2005-10-18 + */ + if(f->eHostnameCmpMode == HN_NO_COMP) { + /* EMPTY BY INTENSION - we check this value first, because + * it is the one most often used, so this saves us time! + */ + } else if(f->eHostnameCmpMode == HN_COMP_MATCH) { + if(rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) { + /* not equal, so we are already done... */ + dbgprintf("hostname filter '+%s' does not match '%s'\n", + rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg)); + FINALIZE; + } + } else { /* must be -hostname */ + if(!rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) { + /* not equal, so we are already done... */ + dbgprintf("hostname filter '-%s' does not match '%s'\n", + rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg)); + FINALIZE; + } + } + + if(f->pCSProgNameComp != NULL) { + int bInv = 0, bEqv = 0, offset = 0; + if(*(rsCStrGetSzStrNoNULL(f->pCSProgNameComp)) == '-') { + if(*(rsCStrGetSzStrNoNULL(f->pCSProgNameComp) + 1) == '-') + offset = 1; + else { + bInv = 1; + offset = 1; + } + } + if(!rsCStrOffsetSzStrCmp(f->pCSProgNameComp, offset, (uchar*) getProgramName(pMsg), getProgramNameLen(pMsg))) + bEqv = 1; + + if((!bEqv && !bInv) || (bEqv && bInv)) { + /* not equal or inverted selection, so we are already done... */ + dbgprintf("programname filter '%s' does not match '%s'\n", + rsCStrGetSzStrNoNULL(f->pCSProgNameComp), getProgramName(pMsg)); + FINALIZE; + } + } + + /* done with the BSD-style block filters */ + + if(f->f_filter_type == FILTER_PRI) { + /* skip messages that are incorrect priority */ + if ( (f->f_filterData.f_pmask[pMsg->iFacility] == TABLE_NOPRI) || \ + ((f->f_filterData.f_pmask[pMsg->iFacility] & (1<iSeverity)) == 0) ) + bRet = 0; + else + bRet = 1; + } else if(f->f_filter_type == FILTER_EXPR) { + CHKiRet(vm.Construct(&pVM)); + CHKiRet(vm.ConstructFinalize(pVM)); + CHKiRet(vm.SetMsg(pVM, pMsg)); + CHKiRet(vm.ExecProg(pVM, f->f_filterData.f_expr->pVmprg)); + CHKiRet(vm.PopBoolFromStack(pVM, &pResult)); + dbgprintf("result of expression evaluation: %lld\n", pResult->val.num); + /* VM is destructed on function exit */ + bRet = (pResult->val.num) ? 1 : 0; + } else { + assert(f->f_filter_type == FILTER_PROP); /* assert() just in case... */ + pszPropVal = MsgGetProp(pMsg, NULL, f->f_filterData.prop.pCSPropName, &pbMustBeFreed); + + /* Now do the compares (short list currently ;)) */ + switch(f->f_filterData.prop.operation ) { + case FIOP_CONTAINS: + if(rsCStrLocateInSzStr(f->f_filterData.prop.pCSCompValue, (uchar*) pszPropVal) != -1) + bRet = 1; + break; + case FIOP_ISEQUAL: + if(rsCStrSzStrCmp(f->f_filterData.prop.pCSCompValue, + (uchar*) pszPropVal, strlen(pszPropVal)) == 0) + bRet = 1; /* process message! */ + break; + case FIOP_STARTSWITH: + if(rsCStrSzStrStartsWithCStr(f->f_filterData.prop.pCSCompValue, + (uchar*) pszPropVal, strlen(pszPropVal)) == 0) + bRet = 1; /* process message! */ + break; + case FIOP_REGEX: + if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue, + (unsigned char*) pszPropVal) == 0) + bRet = 1; + break; + default: + /* here, it handles NOP (for performance reasons) */ + assert(f->f_filterData.prop.operation == FIOP_NOP); + bRet = 1; /* as good as any other default ;) */ + break; + } + + /* now check if the value must be negated */ + if(f->f_filterData.prop.isNegated) + bRet = (bRet == 1) ? 0 : 1; + + if(Debug) { + dbgprintf("Filter: check for property '%s' (value '%s') ", + rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSPropName), + pszPropVal); + if(f->f_filterData.prop.isNegated) + dbgprintf("NOT "); + dbgprintf("%s '%s': %s\n", + getFIOPName(f->f_filterData.prop.operation), + rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSCompValue), + bRet ? "TRUE" : "FALSE"); + } + + /* cleanup */ + if(pbMustBeFreed) + free(pszPropVal); + } + +finalize_it: + /* destruct in any case, not just on error, but it makes error handling much easier */ + if(pVM != NULL) + vm.Destruct(&pVM); + + if(pResult != NULL) + var.Destruct(&pResult); + + *bProcessMsg = bRet; + RETiRet; +} + + +/* helper to processMsg(), used to call the configured actions. It is + * executed from within llExecFunc() of the action list. + * rgerhards, 2007-08-02 + */ +typedef struct processMsgDoActions_s { + int bPrevWasSuspended; /* was the previous action suspended? */ + msg_t *pMsg; +} processMsgDoActions_t; +DEFFUNC_llExecFunc(processMsgDoActions) +{ + DEFiRet; + rsRetVal iRetMod; /* return value of module - we do not always pass that back */ + action_t *pAction = (action_t*) pData; + processMsgDoActions_t *pDoActData = (processMsgDoActions_t*) pParam; + + assert(pAction != NULL); + + if((pAction->bExecWhenPrevSusp == 1) && (pDoActData->bPrevWasSuspended == 0)) { + dbgprintf("not calling action because the previous one is not suspended\n"); + ABORT_FINALIZE(RS_RET_OK); + } + + iRetMod = actionCallAction(pAction, pDoActData->pMsg); + if(iRetMod == RS_RET_DISCARDMSG) { + ABORT_FINALIZE(RS_RET_DISCARDMSG); + } else if(iRetMod == RS_RET_SUSPENDED) { + /* indicate suspension for next module to be called */ + pDoActData->bPrevWasSuspended = 1; + } else { + pDoActData->bPrevWasSuspended = 0; + } + +finalize_it: + RETiRet; +} + + +/* Process (consume) a received message. Calls the actions configured. + * rgerhards, 2005-10-13 + */ +static void +processMsg(msg_t *pMsg) +{ + selector_t *f; + int bContinue; + int bProcessMsg; + processMsgDoActions_t DoActData; + rsRetVal iRet; + + BEGINfunc + assert(pMsg != NULL); + + /* log the message to the particular outputs */ + + bContinue = 1; + for (f = Files; f != NULL && bContinue ; f = f->f_next) { + /* first check the filters... */ + iRet = shouldProcessThisMessage(f, pMsg, &bProcessMsg); + if(!bProcessMsg) { + continue; + } + + /* ok -- from here, we have action-specific code, nothing really selector-specific -- rger 2007-08-01 */ + DoActData.pMsg = pMsg; + DoActData.bPrevWasSuspended = 0; + if(llExecFunc(&f->llActList, processMsgDoActions, (void*)&DoActData) == RS_RET_DISCARDMSG) + bContinue = 0; + } + ENDfunc +} + + +/* The consumer of dequeued messages. This function is called by the + * queue engine on dequeueing of a message. It runs on a SEPARATE + * THREAD. + * NOTE: Having more than one worker requires guarding of some + * message object structures and potentially others - need to be checked + * before we support multiple worker threads on the message queue. + * Please note: the message object is destructed by the queue itself! + */ +static rsRetVal +msgConsumer(void __attribute__((unused)) *notNeeded, void *pUsr) +{ + DEFiRet; + msg_t *pMsg = (msg_t*) pUsr; + + assert(pMsg != NULL); + + processMsg(pMsg); + msgDestruct(&pMsg); + + RETiRet; +} + + +/* Helper to parseRFCSyslogMsg. This function parses a field up to + * (and including) the SP character after it. The field contents is + * returned in a caller-provided buffer. The parsepointer is advanced + * to after the terminating SP. The caller must ensure that the + * provided buffer is large enough to hold the to be extracted value. + * Returns 0 if everything is fine or 1 if either the field is not + * SP-terminated or any other error occurs. + * rger, 2005-11-24 + */ +static int parseRFCField(char **pp2parse, char *pResult) +{ + char *p2parse; + int iRet = 0; + + assert(pp2parse != NULL); + assert(*pp2parse != NULL); + assert(pResult != NULL); + + p2parse = *pp2parse; + + /* this is the actual parsing loop */ + while(*p2parse && *p2parse != ' ') { + *pResult++ = *p2parse++; + } + + if(*p2parse == ' ') + ++p2parse; /* eat SP, but only if not at end of string */ + else + iRet = 1; /* there MUST be an SP! */ + *pResult = '\0'; + + /* set the new parse pointer */ + *pp2parse = p2parse; + return 0; +} + + +/* Helper to parseRFCSyslogMsg. This function parses the structured + * data field of a message. It does NOT parse inside structured data, + * just gets the field as whole. Parsing the single entities is left + * to other functions. The parsepointer is advanced + * to after the terminating SP. The caller must ensure that the + * provided buffer is large enough to hold the to be extracted value. + * Returns 0 if everything is fine or 1 if either the field is not + * SP-terminated or any other error occurs. + * rger, 2005-11-24 + */ +static int parseRFCStructuredData(char **pp2parse, char *pResult) +{ + char *p2parse; + int bCont = 1; + int iRet = 0; + + assert(pp2parse != NULL); + assert(*pp2parse != NULL); + assert(pResult != NULL); + + p2parse = *pp2parse; + + /* this is the actual parsing loop + * Remeber: structured data starts with [ and includes any characters + * until the first ] followed by a SP. There may be spaces inside + * structured data. There may also be \] inside the structured data, which + * do NOT terminate an element. + */ + if(*p2parse != '[') + return 1; /* this is NOT structured data! */ + + while(bCont) { + if(*p2parse == '\0') { + iRet = 1; /* this is not valid! */ + bCont = 0; + } else if(*p2parse == '\\' && *(p2parse+1) == ']') { + /* this is escaped, need to copy both */ + *pResult++ = *p2parse++; + *pResult++ = *p2parse++; + } else if(*p2parse == ']' && *(p2parse+1) == ' ') { + /* found end, just need to copy the ] and eat the SP */ + *pResult++ = *p2parse; + p2parse += 2; + bCont = 0; + } else { + *pResult++ = *p2parse++; + } + } + + if(*p2parse == ' ') + ++p2parse; /* eat SP, but only if not at end of string */ + else + iRet = 1; /* there MUST be an SP! */ + *pResult = '\0'; + + /* set the new parse pointer */ + *pp2parse = p2parse; + return 0; +} + +/* parse a RFC-formatted syslog message. This function returns + * 0 if processing of the message shall continue and 1 if something + * went wrong and this messe should be ignored. This function has been + * implemented in the effort to support syslog-protocol. Please note that + * the name (parse *RFC*) stems from the hope that syslog-protocol will + * some time become an RFC. Do not confuse this with informational + * RFC 3164 (which is legacy syslog). + * + * currently supported format: + * + * VERSION SP TIMESTAMP SP HOSTNAME SP APP-NAME SP PROCID SP MSGID SP [SD-ID]s SP MSG + * + * is already stripped when this function is entered. VERSION already + * has been confirmed to be "1", but has NOT been stripped from the message. + * + * rger, 2005-11-24 + */ +static int parseRFCSyslogMsg(msg_t *pMsg, int flags) +{ + char *p2parse; + char *pBuf; + int bContParse = 1; + + assert(pMsg != NULL); + assert(pMsg->pszUxTradMsg != NULL); + p2parse = (char*) pMsg->pszUxTradMsg; + + /* do a sanity check on the version and eat it */ + assert(p2parse[0] == '1' && p2parse[1] == ' '); + p2parse += 2; + + /* Now get us some memory we can use as a work buffer while parsing. + * We simply allocated a buffer sufficiently large to hold all of the + * message, so we can not run into any troubles. I think this is + * more wise then to use individual buffers. + */ + if((pBuf = malloc(sizeof(char)* strlen(p2parse) + 1)) == NULL) + return 1; + + /* IMPORTANT NOTE: + * Validation is not actually done below nor are any errors handled. I have + * NOT included this for the current proof of concept. However, it is strongly + * advisable to add it when this code actually goes into production. + * rgerhards, 2005-11-24 + */ + + /* TIMESTAMP */ + if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == FALSE) { + dbgprintf("no TIMESTAMP detected!\n"); + bContParse = 0; + flags |= ADDDATE; + } + + if (flags & ADDDATE) { + datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ + } + + /* HOSTNAME */ + if(bContParse) { + parseRFCField(&p2parse, pBuf); + MsgSetHOSTNAME(pMsg, pBuf); + } else { + /* we can not parse, so we get the system we + * received the data from. + */ + MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); + } + + /* APP-NAME */ + if(bContParse) { + parseRFCField(&p2parse, pBuf); + MsgSetAPPNAME(pMsg, pBuf); + } + + /* PROCID */ + if(bContParse) { + parseRFCField(&p2parse, pBuf); + MsgSetPROCID(pMsg, pBuf); + } + + /* MSGID */ + if(bContParse) { + parseRFCField(&p2parse, pBuf); + MsgSetMSGID(pMsg, pBuf); + } + + /* STRUCTURED-DATA */ + if(bContParse) { + parseRFCStructuredData(&p2parse, pBuf); + MsgSetStructuredData(pMsg, pBuf); + } + + /* MSG */ + MsgSetMSG(pMsg, p2parse); + + free(pBuf); + return 0; /* all ok */ +} + + +/* parse a legay-formatted syslog message. This function returns + * 0 if processing of the message shall continue and 1 if something + * went wrong and this messe should be ignored. This function has been + * implemented in the effort to support syslog-protocol. + * rger, 2005-11-24 + * As of 2006-01-10, I am removing the logic to continue parsing only + * when a valid TIMESTAMP is detected. Validity of other fields already + * is ignored. This is due to the fact that the parser has grown smarter + * and is now more able to understand different dialects of the syslog + * message format. I do not expect any bad side effects of this change, + * but I thought I log it in this comment. + * rgerhards, 2006-01-10 + */ +static int parseLegacySyslogMsg(msg_t *pMsg, int flags) +{ + char *p2parse; + char *pBuf; + char *pWork; + cstr_t *pStrB; + int iCnt; + int bTAGCharDetected; + + assert(pMsg != NULL); + assert(pMsg->pszUxTradMsg != NULL); + p2parse = (char*) pMsg->pszUxTradMsg; + + /* Check to see if msg contains a timestamp. We stary trying with a + * high-precision one... + */ + if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == TRUE) { + /* we are done - parse pointer is moved by ParseTIMESTAMP3339 */; + } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), p2parse) == TRUE) { + p2parse += 16; + } else if(*p2parse == ' ') { /* try to see if it is slighly malformed - HP procurve seems to do that sometimes */ + if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), p2parse+1) == TRUE) { + /* indeed, we got it! */ + p2parse += 17; + } else { + flags |= ADDDATE; + } + } else { + flags |= ADDDATE; + } + + /* here we need to check if the timestamp is valid. If it is not, + * we can not continue to parse but must treat the rest as the + * MSG part of the message (as of RFC 3164). + * rgerhards 2004-12-03 + */ + if(flags & ADDDATE) { + datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ + } + + /* rgerhards, 2006-03-13: next, we parse the hostname and tag. But we + * do this only when the user has not forbidden this. I now introduce some + * code that allows a user to configure rsyslogd to treat the rest of the + * message as MSG part completely. In this case, the hostname will be the + * machine that we received the message from and the tag will be empty. This + * is meant to be an interim solution, but for now it is in the code. + */ + if(bParseHOSTNAMEandTAG && !(flags & INTERNAL_MSG)) { + /* parse HOSTNAME - but only if this is network-received! + * rger, 2005-11-14: we still have a problem with BSD messages. These messages + * do NOT include a host name. In most cases, this leads to the TAG to be treated + * as hostname and the first word of the message as the TAG. Clearly, this is not + * of advantage ;) I think I have now found a way to handle this situation: there + * are certain characters which are frequently used in TAG (e.g. ':'), which are + * *invalid* in host names. So while parsing the hostname, I check for these characters. + * If I find them, I set a simple flag but continue. After parsing, I check the flag. + * If it was set, then we most probably do not have a hostname but a TAG. Thus, I change + * the fields. I think this logic shall work with any type of syslog message. + */ + bTAGCharDetected = 0; + if(pMsg->bParseHOSTNAME) { + /* TODO: quick and dirty memory allocation */ + /* the memory allocated is far too much in most cases. But on the plus side, + * it is quite fast... - rgerhards, 2007-09-20 + */ + if((pBuf = malloc(sizeof(char)* (strlen(p2parse) +1))) == NULL) + return 1; + pWork = pBuf; + /* this is the actual parsing loop */ + while(*p2parse && *p2parse != ' ' && *p2parse != ':') { + if(*p2parse == '[' || *p2parse == ']' || *p2parse == '/') + bTAGCharDetected = 1; + *pWork++ = *p2parse++; + } + /* we need to handle ':' seperately, because it terminates the + * TAG - so we also need to terminate the parser here! + * rgerhards, 2007-09-10 *p2parse points to a valid address here in + * any case. We can reach this point only if we are at end of string, + * or we have a ':' or ' '. What the if below does is check if we are + * not at end of string and, if so, advance the parse pointer. If we + * are already at end of string, *p2parse is equal to '\0', neither if + * will be true and the parse pointer remain as is. This is perfectly + * well. + */ + if(*p2parse == ':') { + bTAGCharDetected = 1; + /* We will move hostname to tag, so preserve ':' (otherwise we + * will needlessly change the message format) */ + *pWork++ = *p2parse++; + } else if(*p2parse == ' ') + ++p2parse; + *pWork = '\0'; + MsgAssignHOSTNAME(pMsg, pBuf); + } + /* check if we seem to have a TAG */ + if(bTAGCharDetected) { + /* indeed, this smells like a TAG, so lets use it for this. We take + * the HOSTNAME from the sender system instead. + */ + dbgprintf("HOSTNAME contains invalid characters, assuming it to be a TAG.\n"); + moveHOSTNAMEtoTAG(pMsg); + MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); + } + + /* now parse TAG - that should be present in message from all sources. + * This code is somewhat not compliant with RFC 3164. As of 3164, + * the TAG field is ended by any non-alphanumeric character. In + * practice, however, the TAG often contains dashes and other things, + * which would end the TAG. So it is not desirable. As such, we only + * accept colon and SP to be terminators. Even there is a slight difference: + * a colon is PART of the TAG, while a SP is NOT part of the tag + * (it is CONTENT). Starting 2008-04-04, we have removed the 32 character + * size limit (from RFC3164) on the tag. This had bad effects on existing + * envrionments, as sysklogd didn't obey it either (probably another bug + * in RFC3164...). We now receive the full size, but will modify the + * outputs so that only 32 characters max are used by default. + */ + /* The following code in general is quick & dirty - I need to get + * it going for a test, rgerhards 2004-11-16 */ + /* lol.. we tried to solve it, just to remind ourselfs that 32 octets + * is the max size ;) we need to shuffle the code again... Just for + * the records: the code is currently clean, but we could optimize it! */ + if(!bTAGCharDetected) { + uchar *pszTAG; + if(rsCStrConstruct(&pStrB) != RS_RET_OK) + return 1; + rsCStrSetAllocIncrement(pStrB, 33); + pWork = pBuf; + iCnt = 0; + while(*p2parse && *p2parse != ':' && *p2parse != ' ') { + rsCStrAppendChar(pStrB, *p2parse++); + ++iCnt; + } + if(*p2parse == ':') { + ++p2parse; + rsCStrAppendChar(pStrB, ':'); + } + rsCStrFinish(pStrB); + + rsCStrConvSzStrAndDestruct(pStrB, &pszTAG, 1); + if(pszTAG == NULL) + { /* rger, 2005-11-10: no TAG found - this implies that what + * we have considered to be the HOSTNAME is most probably the + * TAG. We consider it so probable, that we now adjust it + * that way. So we pick up the previously set hostname, assign + * it to tag and use the sender system (from IP stack) as + * the hostname. This situation is the standard case with + * stock BSD syslogd. + */ + dbgprintf("No TAG in message, assuming that HOSTNAME is missing.\n"); + moveHOSTNAMEtoTAG(pMsg); + MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); + } else { /* we have a TAG, so we can happily set it ;) */ + MsgAssignTAG(pMsg, pszTAG); + } + } else { + /* we have no TAG, so we ... */ + /*DO NOTHING*/; + } + } else { + /* we enter this code area when the user has instructed rsyslog NOT + * to parse HOSTNAME and TAG - rgerhards, 2006-03-13 + */ + if(!(flags & INTERNAL_MSG)) + { + dbgprintf("HOSTNAME and TAG not parsed by user configuraton.\n"); + MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); + } + } + + /* The rest is the actual MSG */ + MsgSetMSG(pMsg, p2parse); + + return 0; /* all ok */ +} + + +/* submit a fully created message to the main message queue. The message is + * fully processed and parsed, so no parsing at all happens. This is primarily + * a hook to prevent the need for callers to know about the main message queue + * (which may change in the future as we will probably have multiple rule + * sets and thus queues...). + * rgerhards, 2008-02-13 + */ +rsRetVal +submitMsg(msg_t *pMsg) +{ + DEFiRet; + + ISOBJ_TYPE_assert(pMsg, msg); + + MsgPrepareEnqueue(pMsg); + queueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg); + + RETiRet; +} + + +/* + * Log a message to the appropriate log files, users, etc. based on + * the priority. + * rgerhards 2004-11-08: actually, this also decodes all but the PRI part. + * rgerhards 2004-11-09: ... but only, if syslogd could properly be initialized + * if not, we use emergency logging to the console and in + * this case, no further decoding happens. + * changed to no longer receive a plain message but a msg object instead. + * rgerhards-2004-11-16: OK, we are now up to another change... This method + * actually needs to PARSE the message. How exactly this needs to happen depends on + * a number of things. Most importantly, it depends on the source. For example, + * locally received messages (SOURCE_UNIXAF) do NOT have a hostname in them. So + * we need to treat them differntly form network-received messages which have. + * Well, actually not all network-received message really have a hostname. We + * can just hope they do, but we can not be sure. So this method tries to find + * whatever can be found in the message and uses that... Obviously, there is some + * potential for misinterpretation, which we simply can not solve under the + * circumstances given. + */ +void +logmsg(msg_t *pMsg, int flags) +{ + char *msg; + + BEGINfunc + assert(pMsg != NULL); + assert(pMsg->pszUxTradMsg != NULL); + msg = (char*) pMsg->pszUxTradMsg; + dbgprintf("logmsg: flags %x, from '%s', msg %s\n", flags, getRcvFrom(pMsg), msg); + + /* rger 2005-11-24 (happy thanksgiving!): we now need to check if we have + * a traditional syslog message or one formatted according to syslog-protocol. + * We need to apply different parsers depending on that. We use the + * -protocol VERSION field for the detection. + */ + if(msg[0] == '1' && msg[1] == ' ') { + dbgprintf("Message has syslog-protocol format.\n"); + setProtocolVersion(pMsg, 1); + if(parseRFCSyslogMsg(pMsg, flags) == 1) { + msgDestruct(&pMsg); + return; + } + } else { /* we have legacy syslog */ + dbgprintf("Message has legacy syslog format.\n"); + setProtocolVersion(pMsg, 0); + if(parseLegacySyslogMsg(pMsg, flags) == 1) { + msgDestruct(&pMsg); + return; + } + } + + /* ---------------------- END PARSING ---------------- */ + + /* now submit the message to the main queue - then we are done */ + pMsg->msgFlags = flags; + MsgPrepareEnqueue(pMsg); + queueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg); + ENDfunc +} + + +static void +reapchild() +{ + int saved_errno = errno; + struct sigaction sigAct; + + memset(&sigAct, 0, sizeof (sigAct)); + sigemptyset(&sigAct.sa_mask); + sigAct.sa_handler = reapchild; + sigaction(SIGCHLD, &sigAct, NULL); /* reset signal handler -ASP */ + + while(waitpid(-1, NULL, WNOHANG) > 0); + errno = saved_errno; +} + + +/* helper to doFlushRptdMsgs() to flush the individual action links via llExecFunc + * rgerhards, 2007-08-02 + */ +DEFFUNC_llExecFunc(flushRptdMsgsActions) +{ + action_t *pAction = (action_t*) pData; + + assert(pAction != NULL); + + BEGINfunc + LockObj(pAction); + if (pAction->f_prevcount && time(NULL) >= REPEATTIME(pAction)) { + dbgprintf("flush %s: repeated %d times, %d sec.\n", + module.GetStateName(pAction->pMod), pAction->f_prevcount, + repeatinterval[pAction->f_repeatcount]); + actionWriteToAction(pAction); + BACKOFF(pAction); + } + UnlockObj(pAction); + + ENDfunc + return RS_RET_OK; /* we ignore errors, we can not do anything either way */ +} + + +/* This method flushes reapeat messages. + */ +static void +doFlushRptdMsgs(void) +{ + register selector_t *f; + + /* see if we need to flush any "message repeated n times"... + * Note that this interferes with objects running on other threads. + * We are using appropriate locking inside the function to handle that. + */ + for (f = Files; f != NULL ; f = f->f_next) { + llExecFunc(&f->llActList, flushRptdMsgsActions, NULL); + } +} + + +static void debug_switch() +{ + struct sigaction sigAct; + + if(debugging_on == 0) { + debugging_on = 1; + dbgprintf("Switching debugging_on to true\n"); + } else { + dbgprintf("Switching debugging_on to false\n"); + debugging_on = 0; + } + + memset(&sigAct, 0, sizeof (sigAct)); + sigemptyset(&sigAct.sa_mask); + sigAct.sa_handler = debug_switch; + sigaction(SIGUSR1, &sigAct, NULL); +} + + +void legacyOptsEnq(uchar *line) +{ + legacyOptsLL_t *pNew; + + pNew = malloc(sizeof(legacyOptsLL_t)); + if(line == NULL) + pNew->line = NULL; + else + pNew->line = (uchar *) strdup((char *) line); + pNew->next = NULL; + + if(pLegacyOptsLL == NULL) + pLegacyOptsLL = pNew; + else { + legacyOptsLL_t *pThis = pLegacyOptsLL; + + while(pThis->next != NULL) + pThis = pThis->next; + pThis->next = pNew; + } +} + + +void legacyOptsFree(void) +{ + legacyOptsLL_t *pThis = pLegacyOptsLL, *pNext; + + while(pThis != NULL) { + if(pThis->line != NULL) + free(pThis->line); + pNext = pThis->next; + free(pThis); + pThis = pNext; + } +} + + +void legacyOptsHook(void) +{ + legacyOptsLL_t *pThis = pLegacyOptsLL; + + while(pThis != NULL) { + if(pThis->line != NULL) { + errno = 0; + errmsg.LogError(NO_ERRCODE, "Warning: backward compatibility layer added to following " + "directive to rsyslog.conf: %s", pThis->line); + conf.cfsysline(pThis->line); + } + pThis = pThis->next; + } +} + + +void legacyOptsParseTCP(char ch, char *arg) +{ + register int i; + register char *pArg = arg; + static char conflict = '\0'; + + if((conflict == 'g' && ch == 't') || (conflict == 't' && ch == 'g')) { + fprintf(stderr, "rsyslog: If you want to use both -g and -t, use directives instead, -%c ignored.\n", ch); + return; + } else + conflict = ch; + + /* extract port */ + i = 0; + while(isdigit((int) *pArg)) + i = i * 10 + *pArg++ - '0'; + + /* number of sessions */ + if(*pArg == '\0' || *pArg == ',') { + if(ch == 't') + legacyOptsEnq((uchar *) "ModLoad imtcp"); + else if(ch == 'g') + legacyOptsEnq((uchar *) "ModLoad imgssapi"); + + if(i >= 0 && i <= 65535) { + uchar line[30]; + + if(ch == 't') { + snprintf((char *) line, sizeof(line), "InputTCPServerRun %d", i); + } else if(ch == 'g') { + snprintf((char *) line, sizeof(line), "InputGSSServerRun %d", i); + } + legacyOptsEnq(line); + } else { + if(ch == 't') { + fprintf(stderr, "rsyslogd: Invalid TCP listen port %d - changed to 514.\n", i); + legacyOptsEnq((uchar *) "InputTCPServerRun 514"); + } else if(ch == 'g') { + fprintf(stderr, "rsyslogd: Invalid GSS listen port %d - changed to 514.\n", i); + legacyOptsEnq((uchar *) "InputGSSServerRun 514"); + } + } + + if(*pArg == ',') { + ++pArg; + while(isspace((int) *pArg)) + ++pArg; + i = 0; + while(isdigit((int) *pArg)) { + i = i * 10 + *pArg++ - '0'; + } + if(i > 0) { + uchar line[30]; + + snprintf((char *) line, sizeof(line), "InputTCPMaxSessions %d", i); + legacyOptsEnq(line); + } else { + if(ch == 't') { + fprintf(stderr, "rsyslogd: TCP session max configured " + "to %d [-t %s] - changing to 1.\n", i, arg); + legacyOptsEnq((uchar *) "InputTCPMaxSessions 1"); + } else if (ch == 'g') { + fprintf(stderr, "rsyslogd: GSS session max configured " + "to %d [-g %s] - changing to 1.\n", i, arg); + legacyOptsEnq((uchar *) "InputTCPMaxSessions 1"); + } + } + } + } else + fprintf(stderr, "rsyslogd: Invalid -t %s command line option.\n", arg); +} + + +/* doDie() is a signal handler. If called, it sets the bFinished variable + * to indicate the program should terminate. However, it does not terminate + * it itself, because that causes issues with multi-threading. The actual + * termination is then done on the main thread. This solution might introduce + * a minimal delay, but it is much cleaner than the approach of doing everything + * inside the signal handler. + * rgerhards, 2005-10-26 + */ +static void doDie(int sig) +{ + static int iRetries = 0; /* debug aid */ + printf("DoDie called.\n"); + if(iRetries++ == 4) { + printf("DoDie called 5 times - unconditional exit\n"); + abort(); + } + bFinished = sig; +} + + +/* This function frees all dynamically allocated memory for program termination. + * It must be called only immediately before exit(). It is primarily an aid + * for memory debuggers, which prevents cluttered outupt. + * rgerhards, 2008-03-20 + */ +static void +freeAllDynMemForTermination(void) +{ + if(pszWorkDir != NULL) + free(pszWorkDir); + if(pszMainMsgQFName != NULL) + free(pszMainMsgQFName); + if(pModDir != NULL) + free(pModDir); + if(LocalHostName != NULL) + free(LocalHostName); +} + + +/* die() is called when the program shall end. This typically only occurs + * during sigterm or during the initialization. + * As die() is intended to shutdown rsyslogd, it is + * safe to call exit() here. Just make sure that die() itself is not called + * at inapropriate places. As a general rule of thumb, it is a bad idea to add + * any calls to die() in new code! + * rgerhards, 2005-10-24 + */ +static void +die(int sig) +{ + char buf[256]; + + dbgprintf("exiting on signal %d\n", sig); + + /* IMPORTANT: we should close the inputs first, and THEN send our termination + * message. If we do it the other way around, logmsgInternal() may block on + * a full queue and the inputs still fill up that queue. Depending on the + * scheduling order, we may end up with logmsgInternal being held for a quite + * long time. When the inputs are terminated first, that should not happen + * because the queue is drained in parallel. The situation could only become + * an issue with extremely long running actions in a queue full environment. + * However, such actions are at least considered poorly written, if not + * outright wrong. So we do not care about this very remote problem. + * rgerhards, 2008-01-11 + */ + + /* close the inputs */ + dbgprintf("Terminating input threads...\n"); + thrdTerminateAll(); /* TODO: inputs only, please */ + + /* and THEN send the termination log message (see long comment above) */ + if (sig) { + (void) snprintf(buf, sizeof(buf) / sizeof(char), + " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ + "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.", + (int) myPid, sig); + errno = 0; + logmsgInternal(LOG_SYSLOG|LOG_INFO, buf, ADDDATE); + } + + /* drain queue (if configured so) and stop main queue worker thread pool */ + dbgprintf("Terminating main queue...\n"); + queueDestruct(&pMsgQueue); + pMsgQueue = NULL; + + /* Free ressources and close connections. This includes flushing any remaining + * repeated msgs. + */ + dbgprintf("Terminating outputs...\n"); + freeSelectors(); + + dbgprintf("all primary multi-thread sources have been terminated - now doing aux cleanup...\n"); + /* rger 2005-02-22 + * now clean up the in-memory structures. OK, the OS + * would also take care of that, but if we do it + * ourselfs, this makes finding memory leaks a lot + * easier. + */ + tplDeleteAll(); + + remove_pid(PidFile); + if(glblHadMemShortage) + dbgprintf("Had memory shortage at least once during the run.\n"); + + /* de-init some modules */ + modExitIminternal(); + + /*dbgPrintAllDebugInfo(); / * this is the last spot where this can be done - below output modules are unloaded! */ + + /* the following line cleans up CfSysLineHandlers that were not based on loadable + * modules. As such, they are not yet cleared. + */ + unregCfSysLineHdlrs(); + + legacyOptsFree(); + + /* terminate the remaining classes */ + GlobalClassExit(); + + /* 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 + * I have added some code now, but all that mod init/de-init should be moved to + * 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 + */ + module.UnloadAndDestructAll(eMOD_LINK_ALL); + + dbgprintf("Clean shutdown completed, bye\n"); + /* dbgClassExit MUST be the last one, because it de-inits the debug system */ + dbgClassExit(); + + /* free all remaining memory blocks - this is not absolutely necessary, but helps + * us keep memory debugger logs clean and this is in aid in developing. It doesn't + * cost much time, so we do it always. -- rgerhards, 2008-03-20 + */ + freeAllDynMemForTermination(); + /* NO CODE HERE - feeelAllDynMemForTermination() must be the last thing before exit()! */ + exit(0); /* "good" exit, this is the terminator function for rsyslog [die()] */ +} + +/* + * Signal handler to terminate the parent process. + * rgerhards, 2005-10-24: this is only called during forking of the + * detached syslogd. I consider this method to be safe. + */ +static void doexit() +{ + exit(0); /* "good" exit, only during child-creation */ +} + + +/* set the action resume interval + */ +static rsRetVal setActionResumeInterval(void __attribute__((unused)) *pVal, int iNewVal) +{ + return actionSetGlobalResumeInterval(iNewVal); +} + + +/* set the processes umask (upon configuration request) + */ +static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask) +{ + umask(iUmask); + dbgprintf("umask set to 0%3.3o.\n", iUmask); + + return RS_RET_OK; +} + + +/* helper to freeSelectors(), used with llExecFunc() to flush + * pending output. -- rgerhards, 2007-08-02 + * We do not need to lock the action object here as the processing + * queue is already empty and no other threads are running when + * we call this function. -- rgerhards, 2007-12-12 + */ +DEFFUNC_llExecFunc(freeSelectorsActions) +{ + action_t *pAction = (action_t*) pData; + + assert(pAction != NULL); + + /* flush any pending output */ + if(pAction->f_prevcount) { + actionWriteToAction(pAction); + } + + return RS_RET_OK; /* never fails ;) */ +} + + +/* Close all open log files and free selector descriptor array. + */ +static void freeSelectors(void) +{ + selector_t *f; + selector_t *fPrev; + + if(Files != NULL) { + dbgprintf("Freeing log structures.\n"); + + for(f = Files ; f != NULL ; f = f->f_next) { + llExecFunc(&f->llActList, freeSelectorsActions, NULL); + } + + /* actions flushed and ready for destruction - so do that... */ + f = Files; + while (f != NULL) { + fPrev = f; + f = f->f_next; + selectorDestruct(fPrev); + } + + /* Reflect the deletion of the selectors linked list. */ + Files = NULL; + bHaveMainQueue = 0; + } +} + + +/* helper to dbPrintInitInfo, to print out all actions via + * the llExecFunc() facility. + * rgerhards, 2007-08-02 + */ +DEFFUNC_llExecFunc(dbgPrintInitInfoAction) +{ + DEFiRet; + iRet = actionDbgPrint((action_t*) pData); + dbgprintf("\n"); + + RETiRet; +} + +/* print debug information as part of init(). This pretty much + * outputs the whole config of rsyslogd. I've moved this code + * out of init() to clean it somewhat up. + * rgerhards, 2007-07-31 + */ +static void dbgPrintInitInfo(void) +{ + register selector_t *f; + int iSelNbr = 1; + int i; + + dbgprintf("\nActive selectors:\n"); + for (f = Files; f != NULL ; f = f->f_next) { + dbgprintf("Selector %d:\n", iSelNbr++); + if(f->pCSProgNameComp != NULL) + dbgprintf("tag: '%s'\n", rsCStrGetSzStrNoNULL(f->pCSProgNameComp)); + if(f->eHostnameCmpMode != HN_NO_COMP) + dbgprintf("hostname: %s '%s'\n", + f->eHostnameCmpMode == HN_COMP_MATCH ? + "only" : "allbut", + rsCStrGetSzStrNoNULL(f->pCSHostnameComp)); + if(f->f_filter_type == FILTER_PRI) { + for (i = 0; i <= LOG_NFACILITIES; i++) + if (f->f_filterData.f_pmask[i] == TABLE_NOPRI) + dbgprintf(" X "); + else + dbgprintf("%2X ", f->f_filterData.f_pmask[i]); + } else if(f->f_filter_type == FILTER_EXPR) { + dbgprintf("EXPRESSION-BASED Filter: can currently not be displayed"); + } else { + dbgprintf("PROPERTY-BASED Filter:\n"); + dbgprintf("\tProperty.: '%s'\n", + rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSPropName)); + dbgprintf("\tOperation: "); + if(f->f_filterData.prop.isNegated) + dbgprintf("NOT "); + dbgprintf("'%s'\n", getFIOPName(f->f_filterData.prop.operation)); + dbgprintf("\tValue....: '%s'\n", + rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSCompValue)); + dbgprintf("\tAction...: "); + } + + dbgprintf("\nActions:\n"); + llExecFunc(&f->llActList, dbgPrintInitInfoAction, NULL); /* actions */ + + dbgprintf("\n"); + } + dbgprintf("\n"); + if(bDebugPrintTemplateList) + tplPrintList(); + if(bDebugPrintModuleList) + module.PrintList(); + ochPrintList(); + + if(bDebugPrintCfSysLineHandlerList) + dbgPrintCfSysLineHandlers(); + + dbgprintf("Messages with malicious PTR DNS Records are %sdropped.\n", + bDropMalPTRMsgs ? "" : "not "); + + dbgprintf("Control characters are %sreplaced upon reception.\n", + bEscapeCCOnRcv? "" : "not "); + + if(bEscapeCCOnRcv) + dbgprintf("Control character escape sequence prefix is '%c'.\n", + cCCEscapeChar); + + dbgprintf("Main queue size %d messages.\n", iMainMsgQueueSize); + dbgprintf("Main queue worker threads: %d, Perists every %d updates.\n", + iMainMsgQueueNumWorkers, iMainMsgQPersistUpdCnt); + dbgprintf("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n", + iMainMsgQtoQShutdown, iMainMsgQtoActShutdown, iMainMsgQtoEnq); + dbgprintf("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n", + iMainMsgQHighWtrMark, iMainMsgQLowWtrMark, iMainMsgQDiscardMark, iMainMsgQDiscardSeverity); + dbgprintf("Main queue save on shutdown %d, max disk space allowed %lld\n", + bMainMsgQSaveOnShutdown, iMainMsgQueMaxDiskSpace); + /* TODO: add + iActionRetryCount = 0; + iActionRetryInterval = 30000; + static int iMainMsgQtoWrkShutdown = 60000; + static int iMainMsgQtoWrkMinMsgs = 100; + static int iMainMsgQbSaveOnShutdown = 1; + iMainMsgQueMaxDiskSpace = 0; + setQPROP(queueSettoWrkShutdown, "$MainMsgQueueTimeoutWorkerThreadShutdown", 5000); + setQPROP(queueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100); + setQPROP(queueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", 1); + */ + dbgprintf("Work Directory: '%s'.\n", pszWorkDir); +} + + +/* Start the input modules. This function will probably undergo big changes + * while we implement the input module interface. For now, it does the most + * important thing to get at least my poor initial input modules up and + * running. Almost no config option is taken. + * rgerhards, 2007-12-14 + */ +static rsRetVal +startInputModules(void) +{ + DEFiRet; + modInfo_t *pMod; + + /* loop through all modules and activate them (brr...) */ + pMod = module.GetNxtType(NULL, eMOD_IN); + while(pMod != NULL) { + if((iRet = pMod->mod.im.willRun()) == RS_RET_OK) { + /* activate here */ + thrdCreate(pMod->mod.im.runInput, pMod->mod.im.afterRun); + } else { + dbgprintf("module %lx will not run, iRet %d\n", (unsigned long) pMod, iRet); + } + pMod = module.GetNxtType(pMod, eMOD_IN); + } + + ENDfunc + return RS_RET_OK; /* intentional: we do not care about module errors */ +} + + +/* INIT -- Initialize syslogd from configuration table + * init() is called at initial startup AND each time syslogd is HUPed + */ +static void +init(void) +{ + DEFiRet; + char cbuf[BUFSIZ]; + char bufStartUpMsg[512]; + struct sigaction sigAct; + + thrdTerminateAll(); /* stop all running input threads - TODO: reconsider location! */ + + /* initialize some static variables */ + pDfltHostnameCmp = NULL; + pDfltProgNameCmp = NULL; + eDfltHostnameCmpMode = HN_NO_COMP; + + dbgprintf("rsyslog %s - called init()\n", VERSION); + + /* delete the message queue, which also flushes all messages left over */ + if(pMsgQueue != NULL) { + dbgprintf("deleting main message queue\n"); + queueDestruct(&pMsgQueue); /* delete pThis here! */ + pMsgQueue = NULL; + } + + /* Close all open log files and free log descriptor array. This also frees + * all output-modules instance data. + */ + freeSelectors(); + + /* Unload all non-static modules */ + dbgprintf("Unloading non-static modules.\n"); + module.UnloadAndDestructAll(eMOD_LINK_DYNAMIC_LOADED); + + dbgprintf("Clearing templates.\n"); + tplDeleteNew(); + + /* re-setting values to defaults (where applicable) */ + /* TODO: once we have loadable modules, we must re-visit this code. The reason is + * that config variables are not re-set, because the module is not yet loaded. On + * the other hand, that doesn't matter, because the module got unloaded and is then + * re-loaded, so the variables should be re-set via that way. In any case, we should + * think about the whole situation when we implement loadable plugins. + * rgerhards, 2007-07-31 + */ + conf.cfsysline((uchar*)"ResetConfigVariables"); + + /* open the configuration file */ + if((iRet = conf.processConfFile(ConfFile)) != RS_RET_OK) { + /* rgerhards: this code is executed to set defaults when the + * config file could not be opened. We might think about + * abandoning the run in this case - but this, too, is not + * very clever... So we stick with what we have. + * We ignore any errors while doing this - we would be lost anyhow... + */ + selector_t *f = NULL; + char szTTYNameBuf[_POSIX_TTY_NAME_MAX+1]; /* +1 for NULL character */ + dbgprintf("primary config file could not be opened - using emergency definitions.\n"); + conf.cfline((uchar*)"*.ERR\t" _PATH_CONSOLE, &f); + conf.cfline((uchar*)"*.PANIC\t*", &f); + if(ttyname_r(0, szTTYNameBuf, sizeof(szTTYNameBuf)) == 0) { + snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf); + conf.cfline((uchar*)cbuf, &f); + } + selectorAddList(f); + } + + legacyOptsHook(); + + /* we are now done with reading the configuration. This is the right time to + * free some objects that were just needed for loading it. rgerhards 2005-10-19 + */ + if(pDfltHostnameCmp != NULL) { + rsCStrDestruct(&pDfltHostnameCmp); + } + + if(pDfltProgNameCmp != NULL) { + rsCStrDestruct(&pDfltProgNameCmp); + } + + /* some checks */ + if(iMainMsgQueueNumWorkers < 1) { + errmsg.LogError(NO_ERRCODE, "$MainMsgQueueNumWorkers must be at least 1! Set to 1.\n"); + iMainMsgQueueNumWorkers = 1; + } + + if(MainMsgQueType == QUEUETYPE_DISK) { + errno = 0; /* for logerror! */ + if(pszWorkDir == NULL) { + errmsg.LogError(NO_ERRCODE, "No $WorkDirectory specified - can not run main message queue in 'disk' mode. " + "Using 'FixedArray' instead.\n"); + MainMsgQueType = QUEUETYPE_FIXED_ARRAY; + } + if(pszMainMsgQFName == NULL) { + errmsg.LogError(NO_ERRCODE, "No $MainMsgQueueFileName specified - can not run main message queue in " + "'disk' mode. Using 'FixedArray' instead.\n"); + MainMsgQueType = QUEUETYPE_FIXED_ARRAY; + } + } + + /* switch the message object to threaded operation, if necessary */ + if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) { + MsgEnableThreadSafety(); + } + + /* create message queue */ + CHKiRet_Hdlr(queueConstruct(&pMsgQueue, MainMsgQueType, iMainMsgQueueNumWorkers, iMainMsgQueueSize, msgConsumer)) { + /* no queue is fatal, we need to give up in that case... */ + fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); + exit(1); + } + /* name our main queue object (it's not fatal if it fails...) */ + obj.SetName((obj_t*) pMsgQueue, (uchar*) "main queue"); + + /* ... set some properties ... */ +# define setQPROP(func, directive, data) \ + CHKiRet_Hdlr(func(pMsgQueue, data)) { \ + errmsg.LogError(NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ + } +# define setQPROPstr(func, directive, data) \ + CHKiRet_Hdlr(func(pMsgQueue, data, (data == NULL)? 0 : strlen((char*) data))) { \ + errmsg.LogError(NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ + } + + setQPROP(queueSetMaxFileSize, "$MainMsgQueueFileSize", iMainMsgQueMaxFileSize); + setQPROP(queueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", iMainMsgQueMaxDiskSpace); + setQPROPstr(queueSetFilePrefix, "$MainMsgQueueFileName", pszMainMsgQFName); + setQPROP(queueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", iMainMsgQPersistUpdCnt); + setQPROP(queueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", iMainMsgQtoQShutdown ); + setQPROP(queueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", iMainMsgQtoActShutdown); + setQPROP(queueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", iMainMsgQtoWrkShutdown); + setQPROP(queueSettoEnq, "$MainMsgQueueTimeoutEnqueue", iMainMsgQtoEnq); + setQPROP(queueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark); + setQPROP(queueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark); + setQPROP(queueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark); + setQPROP(queueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity); + setQPROP(queueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); + setQPROP(queueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); + setQPROP(queueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", iMainMsgQDeqSlowdown); + setQPROP(queueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", iMainMsgQueueDeqtWinFromHr); + setQPROP(queueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", iMainMsgQueueDeqtWinToHr); + +# undef setQPROP +# undef setQPROPstr + + /* ... and finally start the queue! */ + CHKiRet_Hdlr(queueStart(pMsgQueue)) { + /* no queue is fatal, we need to give up in that case... */ + fprintf(stderr, "fatal error %d: could not start message queue - rsyslogd can not run!\n", iRet); + exit(1); + } + + bHaveMainQueue = (MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1; + dbgprintf("Main processing queue is initialized and running\n"); + + /* the output part and the queue is now ready to run. So it is a good time + * to start the inputs. Please note that the net code above should be + * shuffled to down here once we have everything in input modules. + * rgerhards, 2007-12-14 + */ + startInputModules(); + + if(Debug) { + dbgPrintInitInfo(); + } + + /* we now generate the startup message. It now includes everything to + * identify this instance. -- rgerhards, 2005-08-17 + */ + snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char), + " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ + "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] restart", + (int) myPid); + logmsgInternal(LOG_SYSLOG|LOG_INFO, bufStartUpMsg, ADDDATE); + + memset(&sigAct, 0, sizeof (sigAct)); + sigemptyset(&sigAct.sa_mask); + sigAct.sa_handler = sighup_handler; + sigaction(SIGHUP, &sigAct, NULL); + + dbgprintf(" (re)started.\n"); + ENDfunc +} + + +/* add a completely-processed selector (after config line parsing) to + * the linked list of selectors. We now need to check + * if it has any actions associated and, if so, link it to the linked + * list. If it has nothing associated with it, we can simply discard + * it. + * We have one special case during initialization: then, the current + * selector is NULL, which means we do not need to care about it at + * all. -- rgerhards, 2007-08-01 + */ +rsRetVal +selectorAddList(selector_t *f) +{ + DEFiRet; + int iActionCnt; + + static selector_t *nextp = NULL; /* TODO: make this go away (see comment below) */ + + if(f != NULL) { + CHKiRet(llGetNumElts(&f->llActList, &iActionCnt)); + if(iActionCnt == 0) { + errmsg.LogError(NO_ERRCODE, "warning: selector line without actions will be discarded"); + selectorDestruct(f); + } else { + /* successfully created an entry */ + dbgprintf("selector line successfully processed\n"); + /* TODO: we should use the linked list class for the selector list, else we need to add globals + * ... well nextp could be added temporarily... + * Thanks to varmojfekoj for having the idea to just use "Files" to make this + * code work. I had actually forgotten to fix the code here before moving to 1.18.0. + * And, of course, I also did not migrate the selector_t structure to the linked list class. + * However, that should still be one of the very next things to happen. + * rgerhards, 2007-08-06 + */ + if(Files == NULL) { + Files = f; + } else { + nextp->f_next = f; + } + nextp = f; + } + } + +finalize_it: + RETiRet; +} + + +/* set the main message queue mode + * rgerhards, 2008-01-03 + */ +static rsRetVal setMainMsgQueType(void __attribute__((unused)) *pVal, uchar *pszType) +{ + DEFiRet; + + if (!strcasecmp((char *) pszType, "fixedarray")) { + MainMsgQueType = QUEUETYPE_FIXED_ARRAY; + dbgprintf("main message queue type set to FIXED_ARRAY\n"); + } else if (!strcasecmp((char *) pszType, "linkedlist")) { + MainMsgQueType = QUEUETYPE_LINKEDLIST; + dbgprintf("main message queue type set to LINKEDLIST\n"); + } else if (!strcasecmp((char *) pszType, "disk")) { + MainMsgQueType = QUEUETYPE_DISK; + dbgprintf("main message queue type set to DISK\n"); + } else if (!strcasecmp((char *) pszType, "direct")) { + MainMsgQueType = QUEUETYPE_DIRECT; + dbgprintf("main message queue type set to DIRECT (no queueing at all)\n"); + } else { + errmsg.LogError(NO_ERRCODE, "unknown mainmessagequeuetype parameter: %s", (char *) pszType); + iRet = RS_RET_INVALID_PARAMS; + } + free(pszType); /* no longer needed */ + + RETiRet; +} + + +/* + * The following function is resposible for handling a SIGHUP signal. Since + * we are now doing mallocs/free as part of init we had better not being + * doing this during a signal handler. Instead this function simply sets + * a flag variable which will tell the main loop to go through a restart. + */ +void sighup_handler() +{ + struct sigaction sigAct; + + restart = 1; + + memset(&sigAct, 0, sizeof (sigAct)); + sigemptyset(&sigAct.sa_mask); + sigAct.sa_handler = sighup_handler; + sigaction(SIGHUP, &sigAct, NULL); + + return; +} + + +/** + * getSubString + * + * Copy a string byte by byte until the occurrence + * of a given separator. + * + * \param ppSrc Pointer to a pointer of the source array of characters. If a + separator detected the Pointer points to the next char after the + separator. Except if the end of the string is dedected ('\n'). + Then it points to the terminator char. + * \param pDst Pointer to the destination array of characters. Here the substing + will be stored. + * \param DstSize Maximum numbers of characters to store. + * \param cSep Separator char. + * \ret int Returns 0 if no error occured. + * + * rgerhards, 2008-02-12: some notes are due... I will once again fix this function, this time + * so that it treats ' ' as a request for whitespace. But in general, the function and its callers + * should be changed over time, this is not really very good code... + */ +int getSubString(uchar **ppSrc, char *pDst, size_t DstSize, char cSep) +{ + uchar *pSrc = *ppSrc; + int iErr = 0; /* 0 = no error, >0 = error */ + while((cSep == ' ' ? !isspace(*pSrc) : *pSrc != cSep) && *pSrc != '\n' && *pSrc != '\0' && DstSize>1) { + *pDst++ = *(pSrc)++; + DstSize--; + } + /* check if the Dst buffer was to small */ + if ((cSep == ' ' ? !isspace(*pSrc) : *pSrc != cSep) && *pSrc != '\n' && *pSrc != '\0') { + dbgprintf("in getSubString, error Src buffer > Dst buffer\n"); + iErr = 1; + } + if (*pSrc == '\0' || *pSrc == '\n') + /* this line was missing, causing ppSrc to be invalid when it + * was returned in case of end-of-string. rgerhards 2005-07-29 + */ + *ppSrc = pSrc; + else + *ppSrc = pSrc+1; + *pDst = '\0'; + return iErr; +} + + +/* 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(pMsg, iFlags); + } +} + + +/* This is the main processing loop. It is called after successful initialization. + * When it returns, the syslogd terminates. + * Its sole function is to provide some housekeeping things. The real work is done + * by the other threads spawned. + */ +static void +mainloop(void) +{ + struct timeval tvSelectTimeout; + + BEGINfunc + while(!bFinished){ + /* first check if we have any internal messages queued and spit them out */ + /* TODO: do we need this any longer? I doubt it, but let's care about it + * later -- rgerhards, 2007-12-21 + */ + processImInternal(); + + /* this is now just a wait */ + tvSelectTimeout.tv_sec = TIMERINTVL; + tvSelectTimeout.tv_usec = 0; + select(1, NULL, NULL, NULL, &tvSelectTimeout); + if(bFinished) + break; /* exit as quickly as possible - see long comment below */ + + /* If we received a HUP signal, we call doFlushRptdMsgs() a bit early. This + * doesn't matter, because doFlushRptdMsgs() checks timestamps. What may happen, + * however, is that the too-early call may lead to a bit too-late output + * of "last message repeated n times" messages. But that is quite acceptable. + * rgerhards, 2007-12-21 + * ... and just to explain, we flush here because that is exactly what the mainloop + * shall do - provide a periodic interval in which not-yet-flushed messages will + * be flushed. Be careful, there is a potential race condition: doFlushRptdMsgs() + * needs to aquire a lock on the action objects. If, however, long-running consumers + * cause the main queue worker threads to lock them for a long time, we may receive + * a starvation condition, resulting in the mainloop being held on lock for an extended + * period of time. That, in turn, could lead to unresponsiveness to termination + * requests. It is especially important that the bFinished flag is checked before + * doFlushRptdMsgs() is called (I know because I ran into that situation). I am + * not yet sure if the remaining probability window of a termination-related + * problem is large enough to justify changing the code - I would consider it + * extremely unlikely that the problem ever occurs in practice. Fixing it would + * require not only a lot of effort but would cost considerable performance. So + * for the time being, I think the remaining risk can be accepted. + * rgerhards, 2008-01-10 + */ + doFlushRptdMsgs(); + + if(restart) { + dbgprintf("\nReceived SIGHUP, reloading rsyslogd.\n"); + /* main queue is stopped as part of init() */ + init(); + restart = 0; + continue; + } + } + ENDfunc +} + +/* If user is not root, prints warnings or even exits + * TODO: check all dynafiles for write permission + * ... but it is probably better to wait here until we have + * a module interface - rgerhards, 2007-07-23 + */ +static void checkPermissions() +{ +#if 0 + /* TODO: this function must either be redone or removed - now with the input modules, + * there is no such simple check we can do. What we can check, however, is if there is + * any input module active and terminate, if not. -- rgerhards, 2007-12-26 + */ + /* we are not root */ + if (geteuid() != 0) + { + fputs("WARNING: Local messages will not be logged! If you want to log them, run rsyslog as root.\n",stderr); +#ifdef SYSLOG_INET + /* udp enabled and port number less than or equal to 1024 */ + if ( AcceptRemote && (atoi(LogPort) <= 1024) ) + fprintf(stderr, "WARNING: Will not listen on UDP port %s. Use port number higher than 1024 or run rsyslog as root!\n", LogPort); + + /* tcp enabled and port number less or equal to 1024 */ + if( bEnableTCP && (atoi(TCPLstnPort) <= 1024) ) + fprintf(stderr, "WARNING: Will not listen on TCP port %s. Use port number higher than 1024 or run rsyslog as root!\n", TCPLstnPort); + + /* Neither explicit high UDP port nor explicit high TCP port. + * It is useless to run anymore */ + if( !(AcceptRemote && (atoi(LogPort) > 1024)) && !( bEnableTCP && (atoi(TCPLstnPort) > 1024)) ) + { +#endif + fprintf(stderr, "ERROR: Nothing to log, no reason to run. Please run rsyslog as root.\n"); + exit(EXIT_FAILURE); +#ifdef SYSLOG_INET + } +#endif + } +#endif +} + + +/* load build-in modules + * very first version begun on 2007-07-23 by rgerhards + */ +static rsRetVal loadBuildInModules(void) +{ + DEFiRet; + + if((iRet = module.doModInit(modInitFile, (uchar*) "builtin-file", NULL)) != RS_RET_OK) { + RETiRet; + } +#ifdef SYSLOG_INET + if((iRet = module.doModInit(modInitFwd, (uchar*) "builtin-fwd", NULL)) != RS_RET_OK) { + RETiRet; + } +#endif + if((iRet = module.doModInit(modInitShell, (uchar*) "builtin-shell", NULL)) != RS_RET_OK) { + RETiRet; + } + if((iRet = module.doModInit(modInitDiscard, (uchar*) "builtin-discard", NULL)) != RS_RET_OK) { + RETiRet; + } + + /* dirty, but this must be for the time being: the usrmsg module must always be + * loaded as last module. This is because it processes any time of action selector. + * If we load it before other modules, these others will never have a chance of + * working with the config file. We may change that implementation so that a user name + * must start with an alnum, that would definitely help (but would it break backwards + * compatibility?). * rgerhards, 2007-07-23 + * User names now must begin with: + * [a-zA-Z0-9_.] + */ + 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 + * 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 + * being, the code has found its home here. A not-just-sideeffect of this decision + * is that rsyslog will terminate if we can not register our built-in config commands. + * This, I think, is the right thing to do. -- rgerhards, 2007-07-31 + */ + CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, NULL, &pszWorkDir, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuelowwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQLowWtrMark, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardmark", 0, eCmdHdlrInt, NULL, &iMainMsgQDiscardMark, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardseverity", 0, eCmdHdlrSeverity, NULL, &iMainMsgQDiscardSeverity, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuecheckpointinterval", 0, eCmdHdlrInt, NULL, &iMainMsgQPersistUpdCnt, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetype", 0, eCmdHdlrGetWord, setMainMsgQueType, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreads", 0, eCmdHdlrInt, NULL, &iMainMsgQueueNumWorkers, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoQShutdown, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutactioncompletion", 0, eCmdHdlrInt, NULL, &iMainMsgQtoActShutdown, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutenqueue", 0, eCmdHdlrInt, NULL, &iMainMsgQtoEnq, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworketimeoutrthreadshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoWrkShutdown, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeueslowdown", 0, eCmdHdlrInt, NULL, &iMainMsgQDeqSlowdown, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreadminimummessages", 0, eCmdHdlrInt, NULL, &iMainMsgQWrkMinMsgs, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxfilesize", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxFileSize, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxdiskspace", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxDiskSpace, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesaveonshutdown", 0, eCmdHdlrBinary, NULL, &bMainMsgQSaveOnShutdown, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimebegin", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinFromHr, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinToHr, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlyonceeveryinterval", 0, eCmdHdlrInt, NULL, &iActExecOnceInterval, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL, &bDropMalPTRMsgs, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_ALLOWEDSENDER, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, conf.doModLoad, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, conf.doIncludeLine, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintTemplateList, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintModuleList, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"debugprintcfsyslinehandlerlist", 0, eCmdHdlrBinary, + NULL, &bDebugPrintCfSysLineHandlerList, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); + + /* now add other modules handlers (we should work on that to be able to do it in ClassInit(), but so far + * that is not possible). -- rgerhards, 2008-01-28 + */ + CHKiRet(actionAddCfSysLineHdrl()); + +finalize_it: + RETiRet; +} + + +/* print version and compile-time setting information. + */ +static void printVersion(void) +{ + printf("rsyslogd %s, ", VERSION); + printf("compiled with:\n"); +#ifdef FEATURE_REGEXP + printf("\tFEATURE_REGEXP:\t\t\t\tYes\n"); +#else + printf("\tFEATURE_REGEXP:\t\t\t\tNo\n"); +#endif +#ifndef NOLARGEFILE + printf("\tFEATURE_LARGEFILE:\t\t\tYes\n"); +#else + printf("\tFEATURE_LARGEFILE:\t\t\tNo\n"); +#endif +#ifdef USE_NETZIP + printf("\tFEATURE_NETZIP (message compression):\tYes\n"); +#else + printf("\tFEATURE_NETZIP (message compression):\tNo\n"); +#endif +#if defined(SYSLOG_INET) && defined(USE_GSSAPI) + printf("\tGSSAPI Kerberos 5 support:\t\tYes\n"); +#else + printf("\tGSSAPI Kerberos 5 support:\t\tNo\n"); +#endif +#ifndef NDEBUG + printf("\tFEATURE_DEBUG (debug build, slow code):\tYes\n"); +#else + printf("\tFEATURE_DEBUG (debug build, slow code):\tNo\n"); +#endif +#ifdef RTINST + printf("\tRuntime Instrumentation (slow code):\tYes\n"); +#else + printf("\tRuntime Instrumentation (slow code):\tNo\n"); +#endif + printf("\nSee http://www.rsyslog.com for more information.\n"); +} + + +/* This function is called after initial initalization. It is used to + * move code out of the too-long main() function. + * rgerhards, 2007-10-17 + */ +static void mainThread() +{ + BEGINfunc + uchar *pTmp; + + /* Note: signals MUST be processed by the thread this code is running in. The reason + * is that we need to interrupt the select() system call. -- rgerhards, 2007-10-17 + */ + + /* initialize the build-in templates */ + pTmp = template_SyslogProtocol23Format; + tplAddLine("RSYSLOG_SyslogProtocol23Format", &pTmp); + pTmp = template_FileFormat; /* new format for files with high-precision stamp */ + tplAddLine("RSYSLOG_FileFormat", &pTmp); + pTmp = template_TraditionalFileFormat; + tplAddLine("RSYSLOG_TraditionalFileFormat", &pTmp); + pTmp = template_WallFmt; + tplAddLine(" WallFmt", &pTmp); + pTmp = template_ForwardFormat; + tplAddLine("RSYSLOG_ForwardFormat", &pTmp); + pTmp = template_TraditionalForwardFormat; + tplAddLine("RSYSLOG_TraditionalForwardFormat", &pTmp); + pTmp = template_StdUsrMsgFmt; + tplAddLine(" StdUsrMsgFmt", &pTmp); + pTmp = template_StdDBFmt; + tplAddLine(" StdDBFmt", &pTmp); + pTmp = template_StdPgSQLFmt; + tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp)); + + init(); + if(Debug) { + dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); + debugging_on = 1; + } + /* Send a signal to the parent so it can terminate. + */ + if (myPid != ppid) + kill (ppid, SIGTERM); + + /* END OF INTIALIZATION + * ... but keep in mind that we might do a restart and thus init() might + * be called again. If that happens, we must shut down the worker thread, + * do the init() and then restart things. + * rgerhards, 2005-10-24 + */ + dbgprintf("initialization completed, transitioning to regular run mode\n"); + + mainloop(); + ENDfunc +} + + +/* Method to initialize all global classes and use the objects that we need. + * rgerhards, 2008-01-04 + * rgerhards, 2008-04-16: the actual initialization is now carried out by the runtime + */ +static rsRetVal +InitGlobalClasses(void) +{ + DEFiRet; + char *pErrObj; /* tells us which object failed if that happens (useful for troubleshooting!) */ + + /* Intialize the runtime system */ + pErrObj = "rsyslog runtime"; /* set in case the runtime errors before setting an object */ + CHKiRet(rsrtInit(&pErrObj, &obj)); + + /* Now tell the system which classes we need ourselfs */ + pErrObj = "errmsg"; + CHKiRet(objUse(errmsg, CORE_COMPONENT)); + pErrObj = "module"; + CHKiRet(objUse(module, CORE_COMPONENT)); + pErrObj = "var"; + CHKiRet(objUse(var, CORE_COMPONENT)); + pErrObj = "datetime"; + CHKiRet(objUse(datetime, CORE_COMPONENT)); + pErrObj = "vm"; + CHKiRet(objUse(vm, CORE_COMPONENT)); + pErrObj = "expr"; + CHKiRet(objUse(expr, CORE_COMPONENT)); + pErrObj = "conf"; + CHKiRet(objUse(conf, CORE_COMPONENT)); + + /* intialize some dummy classes that are not part of the runtime */ + pErrObj = "action"; + CHKiRet(actionClassInit()); + pErrObj = "template"; + CHKiRet(templateInit()); + + /* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ + pErrObj = "net"; + CHKiRet(objUse(net, LM_NET_FILENAME)); + +finalize_it: + if(iRet != RS_RET_OK) { + /* we know we are inside the init sequence, so we can safely emit + * messages to stderr. -- rgerhards, 2008-04-02 + */ + fprintf(stderr, "Error during class init for object '%s' - failing...\n", pErrObj); + } + + RETiRet; +} + + +/* Method to exit all global classes. We do not do any error checking here, + * because that wouldn't help us at all. So better try to deinit blindly + * as much as succeeds (which usually means everything will). We just must + * be careful to do the de-init in the opposite order of the init, because + * of the dependencies. However, its not as important this time, because + * we have reference counting. + * rgerhards, 2008-03-10 + */ +static rsRetVal +GlobalClassExit(void) +{ + DEFiRet; + + /* first, release everything we used ourself */ + objRelease(net, LM_NET_FILENAME);/* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ + objRelease(conf, CORE_COMPONENT); + objRelease(expr, CORE_COMPONENT); + objRelease(vm, CORE_COMPONENT); + objRelease(var, CORE_COMPONENT); + objRelease(datetime, CORE_COMPONENT); + + /* TODO: implement the rest of the deinit */ +#if 0 + CHKiRet(datetimeClassInit(NULL)); + CHKiRet(msgClassInit(NULL)); + CHKiRet(strmClassInit(NULL)); + CHKiRet(wtiClassInit(NULL)); + CHKiRet(wtpClassInit(NULL)); + CHKiRet(queueClassInit(NULL)); + CHKiRet(vmstkClassInit(NULL)); + CHKiRet(sysvarClassInit(NULL)); + CHKiRet(vmClassInit(NULL)); + CHKiRet(vmopClassInit(NULL)); + CHKiRet(vmprgClassInit(NULL)); + CHKiRet(ctok_tokenClassInit(NULL)); + CHKiRet(ctokClassInit(NULL)); + CHKiRet(exprClassInit(NULL)); + + /* dummy "classes" */ + CHKiRet(actionClassInit()); + CHKiRet(templateInit()); +#endif + /* dummy "classes */ + strExit(); + +#if 0 + CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ + /* the following classes were intialized by objClassInit() */ + CHKiRet(objUse(errmsg, CORE_COMPONENT)); + CHKiRet(objUse(module, CORE_COMPONENT)); +#endif + rsrtExit(&obj); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */ + + RETiRet; +} + + +/* some support for command line option parsing. Any non-trivial options must be + * buffered until the complete command line has been parsed. This is necessary to + * prevent dependencies between the options. That, in turn, means we need to have + * something that is capable of buffering options and there values. The follwing + * functions handle that. + * rgerhards, 2008-04-04 + */ +typedef struct bufOpt { + struct bufOpt *pNext; + char optchar; + char *arg; +} bufOpt_t; +static bufOpt_t *bufOptRoot = NULL; +static bufOpt_t *bufOptLast = NULL; + +/* add option buffer */ +static rsRetVal +bufOptAdd(char opt, char *arg) +{ + DEFiRet; + bufOpt_t *pBuf; + + if((pBuf = malloc(sizeof(bufOpt_t))) == NULL) + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + + pBuf->optchar = opt; + pBuf->arg = arg; + pBuf->pNext = NULL; + + if(bufOptLast == NULL) { + bufOptRoot = pBuf; /* then there is also no root! */ + } else { + bufOptLast->pNext = pBuf; + } + bufOptLast = pBuf; + +finalize_it: + RETiRet; +} + + + +/* remove option buffer from top of list, return values and destruct buffer itself. + * returns RS_RET_END_OF_LINKEDLIST when no more options are present. + * (we use int *opt instead of char *opt to keep consistent with getopt()) + */ +static rsRetVal +bufOptRemove(int *opt, char **arg) +{ + DEFiRet; + bufOpt_t *pBuf; + + if(bufOptRoot == NULL) + ABORT_FINALIZE(RS_RET_END_OF_LINKEDLIST); + pBuf = bufOptRoot; + + *opt = pBuf->optchar; + *arg = pBuf->arg; + + bufOptRoot = pBuf->pNext; + free(pBuf); + +finalize_it: + RETiRet; +} + + +/* This is the main entry point into rsyslogd. Over time, we should try to + * modularize it a bit more... + */ +int realMain(int argc, char **argv) +{ + DEFiRet; + + register int i; + register char *p; + int num_fds; + int ch; + struct hostent *hent; + extern int optind; + extern char *optarg; + struct sigaction sigAct; + int bIsFirstOption = 1; + int bEOptionWasGiven = 0; + int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */ + char *arg; /* for command line option processing */ + uchar legacyConfLine[80]; + + /* first, parse the command line options. We do not carry out any actual work, just + * see what we should do. This relieves us from certain anomalies and we can process + * the parameters down below in the correct order. For example, we must know the + * value of -M before we can do the init, but at the same time we need to have + * the base classes init before we can process most of the options. Now, with the + * split of functionality, this is no longer a problem. Thanks to varmofekoj for + * suggesting this algo. + * Note: where we just need to set some flags and can do so without knowledge + * of other options, we do this during the inital option processing. With later + * versions (if a dependency on -c option is introduced), we must move that code + * to other places, but I think it is quite appropriate and saves code to do this + * only when actually neeeded. + * rgerhards, 2008-04-04 + */ + while ((ch = getopt(argc, argv, "46aAc:def:g:hi:l:m:M:nopqQr::s:t:u:vwx")) != EOF) { + switch((char)ch) { + case '4': + case '6': + case 'A': + case 'a': + case 'f': /* configuration file */ + case 'h': + case 'i': /* pid file name */ + case 'l': + case 'm': /* mark interval */ + case 'n': /* don't fork */ + case 'o': + case 'p': + case 'q': /* add hostname if DNS resolving has failed */ + case 'Q': /* dont resolve hostnames in ACL to IPs */ + case 's': + case 'u': /* misc user settings */ + case 'w': /* disable disallowed host warnigs */ + case 'x': /* disable dns for remote messages */ + CHKiRet(bufOptAdd(ch, optarg)); + break; + case 'c': /* compatibility mode */ + if(!bIsFirstOption) { + fprintf(stderr, "-c option MUST be specified as the first option - aborting...\n"); + usage(); + exit(1); + } + iCompatibilityMode = atoi(optarg); + break; + case 'd': /* debug - must be handled now, so that debug is active during init! */ + Debug = 1; + break; + case 'e': /* log every message (no repeat message supression) */ + fprintf(stderr, "note: -e option is no longer supported, every message is now logged by default\n"); + bEOptionWasGiven = 1; + break; + case 'g': /* enable tcp gssapi logging */ +#if defined(SYSLOG_INET) && defined(USE_GSSAPI) + CHKiRet(bufOptAdd('g', optarg)); +#else + fprintf(stderr, "rsyslogd: -g not valid - not compiled with gssapi support"); +#endif + break; + case 'M': /* default module load path -- this MUST be carried out immediately! */ + glblModPath = (uchar*) optarg; + break; + case 'r': /* accept remote messages */ +#ifdef SYSLOG_INET + CHKiRet(bufOptAdd(ch, optarg)); +#else + fprintf(stderr, "rsyslogd: -r not valid - not compiled with network support\n"); +#endif + break; + case 't': /* enable tcp logging */ +#ifdef SYSLOG_INET + CHKiRet(bufOptAdd(ch, optarg)); +#else + fprintf(stderr, "rsyslogd: -t not valid - not compiled with network support\n"); +#endif + break; + case 'v': /* MUST be carried out immediately! */ + printVersion(); + exit(0); /* exit for -v option - so this is a "good one" */ + case '?': + default: + usage(); + } + bIsFirstOption = 0; /* we already saw an option character */ + } + + if ((argc -= optind)) + usage(); + + dbgprintf("rsyslogd %s startup, compatibility mode %d, module path '%s'\n", + VERSION, iCompatibilityMode, glblModPath == NULL ? "" : (char*)glblModPath); + + /* we are done with the initial option parsing and processing. Now we init the system. */ + + ppid = getpid(); + + if(chdir ("/") != 0) + fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); + + CHKiRet_Hdlr(InitGlobalClasses()) { + fprintf(stderr, "rsyslogd initializiation failed - global classes could not be initialized.\n" + "Did you do a \"make install\"?\n" + "Suggested action: run rsyslogd with -d -n options to see what exactly " + "fails.\n"); + FINALIZE; + } + + /* doing some core initializations */ + + /* get our host and domain names - we need to do this early as we may emit + * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 + */ + net.getLocalHostname(&LocalHostName); + if((p = strchr((char*)LocalHostName, '.'))) { + *p++ = '\0'; + LocalDomain = p; + } else { + LocalDomain = ""; + + /* It's not clearly defined whether gethostname() + * should return the simple hostname or the fqdn. A + * good piece of software should be aware of both and + * we want to distribute good software. Joey + * + * Good software also always checks its return values... + * If syslogd starts up before DNS is up & /etc/hosts + * doesn't have LocalHostName listed, gethostbyname will + * return NULL. + */ + /* TODO: gethostbyname() is not thread-safe, but replacing it is + * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 + */ + hent = gethostbyname((char*)LocalHostName); + if(hent) { + free(LocalHostName); + CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); + + if((p = strchr((char*)LocalHostName, '.'))) + { + *p++ = '\0'; + LocalDomain = p; + } + } + } + + /* Convert to lower case to recognize the correct domain laterly */ + for (p = (char *)LocalDomain ; *p ; p++) + *p = (char)tolower((int)*p); + + /* initialize the objects */ + 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 */ + } + + if((iRet = loadBuildInModules()) != RS_RET_OK) { + fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n", + iRet); + exit(1); /* "good" exit, leaving at init for fatal error */ + } + + /* END core initializations - we now come back to carrying out command line options*/ + + while((iRet = bufOptRemove(&ch, &arg)) == RS_RET_OK) { + dbgprintf("deque option %c, optarg '%s'\n", ch, arg); + switch((char)ch) { + case '4': + family = PF_INET; + break; + case '6': + family = PF_INET6; + break; + case 'A': + send_to_all++; + break; + case 'a': + if(iCompatibilityMode < 3) { + if(!bImUxSockLoaded) { + legacyOptsEnq((uchar *) "ModLoad imuxsock"); + bImUxSockLoaded = 1; + } + snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "addunixlistensocket %s", arg); + legacyOptsEnq(legacyConfLine); + } else { + fprintf(stderr, "error -a is no longer supported, use module imuxsock instead"); + } + break; + case 'f': /* configuration file */ + ConfFile = (uchar*) arg; + break; + case 'g': /* enable tcp gssapi logging */ + if(iCompatibilityMode < 3) { + legacyOptsParseTCP(ch, arg); + } else + fprintf(stderr, "-g option only supported in compatibility modes 0 to 2 - ignored\n"); + break; + case 'h': + if(iCompatibilityMode < 3) { + errmsg.LogError(NO_ERRCODE, "WARNING: -h option is no longer supported - ignored"); + } else { + usage(); /* for v3 and above, it simply is an error */ + } + break; + case 'i': /* pid file name */ + PidFile = arg; + break; + case 'l': + if (LocalHosts) { + fprintf (stderr, "rsyslogd: Only one -l argument allowed, the first one is taken.\n"); + } else { + LocalHosts = crunch_list(arg); + } + break; + case 'm': /* mark interval */ + if(iCompatibilityMode < 3) { + MarkInterval = atoi(arg) * 60; + } else + fprintf(stderr, + "-m option only supported in compatibility modes 0 to 2 - ignored\n"); + break; + case 'n': /* don't fork */ + NoFork = 1; + break; + case 'o': + if(iCompatibilityMode < 3) { + if(!bImUxSockLoaded) { + legacyOptsEnq((uchar *) "ModLoad imuxsock"); + bImUxSockLoaded = 1; + } + legacyOptsEnq((uchar *) "OmitLocalLogging"); + } else { + fprintf(stderr, "error -o is no longer supported, use module imuxsock instead"); + } + break; + case 'p': + if(iCompatibilityMode < 3) { + if(!bImUxSockLoaded) { + legacyOptsEnq((uchar *) "ModLoad imuxsock"); + bImUxSockLoaded = 1; + } + snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "SystemLogSocketName %s", arg); + legacyOptsEnq(legacyConfLine); + } else { + fprintf(stderr, "error -p is no longer supported, use module imuxsock instead"); + } + case 'q': /* add hostname if DNS resolving has failed */ + *net.pACLAddHostnameOnFail = 1; + break; + case 'Q': /* dont resolve hostnames in ACL to IPs */ + *net.pACLDontResolve = 1; + break; + case 'r': /* accept remote messages */ + if(iCompatibilityMode < 3) { + legacyOptsEnq((uchar *) "ModLoad imudp"); + snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "UDPServerRun %s", arg); + legacyOptsEnq(legacyConfLine); + } else + fprintf(stderr, "-r option only supported in compatibility modes 0 to 2 - ignored\n"); + break; + case 's': + if (StripDomains) { + fprintf (stderr, "rsyslogd: Only one -s argument allowed, the first one is taken.\n"); + } else { + StripDomains = crunch_list(arg); + } + break; + case 't': /* enable tcp logging */ + if(iCompatibilityMode < 3) { + legacyOptsParseTCP(ch, arg); + } else + fprintf(stderr, "-t option only supported in compatibility modes 0 to 2 - ignored\n"); + break; + case 'u': /* misc user settings */ + if(atoi(arg) == 1) + bParseHOSTNAMEandTAG = 0; + break; + case 'w': /* disable disallowed host warnigs */ + option_DisallowWarning = 0; + break; + case 'x': /* disable dns for remote messages */ + DisableDNS = 1; + break; + case '?': + default: + usage(); + } + } + + if(iRet != RS_RET_END_OF_LINKEDLIST) + FINALIZE; + + /* process compatibility mode settings */ + if(iCompatibilityMode < 3) { + errmsg.LogError(NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically " + "generated config directives may interfer with your rsyslog.conf settings. " + "We suggest upgrading your config and adding -c3 as the first " + "rsyslogd option."); + if(MarkInterval > 0) { + legacyOptsEnq((uchar *) "ModLoad immark"); + snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "MarkMessagePeriod %d", MarkInterval); + legacyOptsEnq(legacyConfLine); + } + if(!bImUxSockLoaded) { + legacyOptsEnq((uchar *) "ModLoad imuxsock"); + } + } + + if(bEOptionWasGiven && iCompatibilityMode < 3) { + errmsg.LogError(NO_ERRCODE, "WARNING: \"message repeated n times\" feature MUST be turned on in " + "rsyslog.conf - CURRENTLY EVERY MESSAGE WILL BE LOGGED. Visit " + "http://www.rsyslog.com/rptdmsgreduction to learn " + "more and cast your vote if you want us to keep this feature."); + } + + checkPermissions(); + thrdInit(); + + if( !(Debug || NoFork) ) + { + dbgprintf("Checking pidfile.\n"); + if (!check_pid(PidFile)) + { + memset(&sigAct, 0, sizeof (sigAct)); + sigemptyset(&sigAct.sa_mask); + sigAct.sa_handler = doexit; + sigaction(SIGTERM, &sigAct, NULL); + + if (fork()) { + /* + * Parent process + */ + sleep(300); + /* + * Not reached unless something major went wrong. 5 + * minutes should be a fair amount of time to wait. + * Please note that this procedure is important since + * the father must not exit before syslogd isn't + * initialized or the klogd won't be able to flush its + * logs. -Joey + */ + exit(1); /* "good" exit - after forking, not diasabling anything */ + } + num_fds = getdtablesize(); + for (i= 0; i < num_fds; i++) + (void) close(i); + untty(); + } + else + { + fputs(" Already running.\n", stderr); + exit(1); /* "good" exit, done if syslogd is already running */ + } + } + else + debugging_on = 1; + + /* tuck my process id away */ + dbgprintf("Writing pidfile %s.\n", PidFile); + if (!check_pid(PidFile)) + { + if (!write_pid(PidFile)) + { + fputs("Can't write pid.\n", stderr); + exit(1); /* exit during startup - questionable */ + } + } + else + { + fputs("Pidfile (and pid) already exist.\n", stderr); + exit(1); /* exit during startup - questionable */ + } + myPid = getpid(); /* save our pid for further testing (also used for messages) */ + + memset(&sigAct, 0, sizeof (sigAct)); + sigemptyset(&sigAct.sa_mask); + + sigAct.sa_handler = sigsegvHdlr; + sigaction(SIGSEGV, &sigAct, NULL); + sigAct.sa_handler = sigsegvHdlr; + sigaction(SIGABRT, &sigAct, NULL); + sigAct.sa_handler = doDie; + sigaction(SIGTERM, &sigAct, NULL); + sigAct.sa_handler = Debug ? doDie : SIG_IGN; + sigaction(SIGINT, &sigAct, NULL); + sigaction(SIGQUIT, &sigAct, NULL); + sigAct.sa_handler = reapchild; + sigaction(SIGCHLD, &sigAct, NULL); + sigAct.sa_handler = Debug ? debug_switch : SIG_IGN; + sigaction(SIGUSR1, &sigAct, NULL); + sigAct.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &sigAct, NULL); + sigaction(SIGXFSZ, &sigAct, NULL); /* do not abort if 2gig file limit is hit */ + + mainThread(); + + /* do any de-init's that need to be done AFTER this comment */ + + die(bFinished); + + thrdExit(); + +finalize_it: + if(iRet != RS_RET_OK) + fprintf(stderr, "rsyslogd run failed with error %d\n(see rsyslog.h " + "or http://www.rsyslog.com/errcode to learn what that number means)\n", iRet); + + ENDfunc + return 0; +} + + +/* This is the main entry point into rsyslogd. This must be a function in its own + * right in order to intialize the debug system in a portable way (otherwise we would + * need to have a statement before variable definitions. + * rgerhards, 20080-01-28 + */ +int main(int argc, char **argv) +{ + dbgClassInit(); + return realMain(argc, argv); +} + +/* vim:set ai: + */ -- cgit v1.2.3 From d071de578454754c4701285b3569e55c5cef1ee4 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 16 Apr 2008 15:45:13 +0200 Subject: removed no longer needed things ... and some more cleanup. Also moved a file that I forgot (thanks to Michael Biebl for pointing that out). --- tools/syslogd.c | 53 +---------------------------------------------------- 1 file changed, 1 insertion(+), 52 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 95a23e99..a356c338 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -248,9 +248,6 @@ static pid_t myPid; /* our pid for use in self-generated messages, e.g. on start /* mypid is read-only after the initial fork() */ static int restart = 0; /* do restart (config read) - multithread safe */ -int glblHadMemShortage = 0; /* indicates if we had memory shortage some time during the run */ - - static int bParseHOSTNAMEandTAG = 1; /* global config var: should the hostname and tag be * parsed inside message - rgerhards, 2006-03-13 */ static int bFinished = 0; /* used by termination signal handler, read-only except there @@ -488,7 +485,6 @@ selectorConstruct(selector_t **ppThis) assert(ppThis != NULL); if((pThis = (selector_t*) calloc(1, sizeof(selector_t))) == NULL) { - glblHadMemShortage = 1; ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } CHKiRet(llInit(&pThis->llActList, actionDestruct, NULL, NULL)); @@ -669,7 +665,7 @@ rsRetVal printline(char *hname, char *msg, int bParseHost, int flags, flowContro if(MsgSetUxTradMsg(pMsg, p) != 0) ABORT_FINALIZE(RS_RET_ERR); - logmsg(pMsg, flags | SYNC_FILE); + logmsg(pMsg, flags); finalize_it: RETiRet; @@ -1926,8 +1922,6 @@ die(int sig) tplDeleteAll(); remove_pid(PidFile); - if(glblHadMemShortage) - dbgprintf("Had memory shortage at least once during the run.\n"); /* de-init some modules */ modExitIminternal(); @@ -2466,51 +2460,6 @@ void sighup_handler() } -/** - * getSubString - * - * Copy a string byte by byte until the occurrence - * of a given separator. - * - * \param ppSrc Pointer to a pointer of the source array of characters. If a - separator detected the Pointer points to the next char after the - separator. Except if the end of the string is dedected ('\n'). - Then it points to the terminator char. - * \param pDst Pointer to the destination array of characters. Here the substing - will be stored. - * \param DstSize Maximum numbers of characters to store. - * \param cSep Separator char. - * \ret int Returns 0 if no error occured. - * - * rgerhards, 2008-02-12: some notes are due... I will once again fix this function, this time - * so that it treats ' ' as a request for whitespace. But in general, the function and its callers - * should be changed over time, this is not really very good code... - */ -int getSubString(uchar **ppSrc, char *pDst, size_t DstSize, char cSep) -{ - uchar *pSrc = *ppSrc; - int iErr = 0; /* 0 = no error, >0 = error */ - while((cSep == ' ' ? !isspace(*pSrc) : *pSrc != cSep) && *pSrc != '\n' && *pSrc != '\0' && DstSize>1) { - *pDst++ = *(pSrc)++; - DstSize--; - } - /* check if the Dst buffer was to small */ - if ((cSep == ' ' ? !isspace(*pSrc) : *pSrc != cSep) && *pSrc != '\n' && *pSrc != '\0') { - dbgprintf("in getSubString, error Src buffer > Dst buffer\n"); - iErr = 1; - } - if (*pSrc == '\0' || *pSrc == '\n') - /* this line was missing, causing ppSrc to be invalid when it - * was returned in case of end-of-string. rgerhards 2005-07-29 - */ - *ppSrc = pSrc; - else - *ppSrc = pSrc+1; - *pDst = '\0'; - return iErr; -} - - /* 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 -- cgit v1.2.3 From bf3e0d4f224a26e2ac9bc3edfd1e6eedcf56c9f8 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 16 Apr 2008 18:01:26 +0200 Subject: prevented segfault during runtime library init phase --- tools/syslogd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a356c338..6f252b3a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -292,7 +292,7 @@ uchar *pszWorkDir = NULL;/* name of rsyslog's spool directory (without trailing uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */ /* end global config file state variables */ -uchar *LocalHostName;/* our hostname - read-only after startup */ +uchar *LocalHostName = NULL;/* our hostname - read-only after startup */ char *LocalDomain; /* our local domain name - read-only after startup */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both), set via cmdline */ @@ -882,8 +882,8 @@ logmsgInternal(int pri, char *msg, int flags) CHKiRet(msgConstruct(&pMsg)); MsgSetUxTradMsg(pMsg, msg); MsgSetRawMsg(pMsg, msg); - MsgSetHOSTNAME(pMsg, (char*)LocalHostName); - MsgSetRcvFrom(pMsg, (char*)LocalHostName); + MsgSetHOSTNAME(pMsg, (LocalHostName == NULL) ? "[localhost]" : (char*)LocalHostName); + MsgSetRcvFrom(pMsg, (LocalHostName == NULL) ? "[localhost]" : (char*)LocalHostName); MsgSetTAG(pMsg, "rsyslogd:"); pMsg->iFacility = LOG_FAC(pri); pMsg->iSeverity = LOG_PRI(pri); -- cgit v1.2.3 From 87c936ab65b4381fed35689b38c98f130883d903 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Apr 2008 09:07:12 +0200 Subject: modularization work cleanup + created an abstract class for global data items and moved glblGetWorkDir to it --- tools/syslogd.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 6f252b3a..4fe0071a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -160,6 +160,7 @@ /* definitions for objects we access */ DEFobjCurrIf(obj) +DEFobjCurrIf(glbl) DEFobjCurrIf(datetime) DEFobjCurrIf(conf) DEFobjCurrIf(expr) @@ -288,14 +289,13 @@ static int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - n int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ int iActExecOnceInterval = 0; /* execute action once every nn seconds */ -uchar *pszWorkDir = NULL;/* name of rsyslog's spool directory (without trailing slash) */ uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */ /* end global config file state variables */ uchar *LocalHostName = NULL;/* our hostname - read-only after startup */ char *LocalDomain; /* our local domain name - read-only after startup */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ -int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both), set via cmdline */ +//int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both), set via cmdline */ int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */ int DisableDNS = 0; /* don't look up IP addresses of remote messages */ @@ -373,10 +373,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a bEscapeCCOnRcv = 1; /* default is to escape control characters */ bReduceRepeatMsgs = 0; bDropMalPTRMsgs = 0; - if(pszWorkDir != NULL) { - free(pszWorkDir); - pszWorkDir = NULL; - } if(pszMainMsgQFName != NULL) { free(pszMainMsgQFName); pszMainMsgQFName = NULL; @@ -1849,8 +1845,6 @@ static void doDie(int sig) static void freeAllDynMemForTermination(void) { - if(pszWorkDir != NULL) - free(pszWorkDir); if(pszMainMsgQFName != NULL) free(pszMainMsgQFName); if(pModDir != NULL) @@ -2143,7 +2137,7 @@ static void dbgPrintInitInfo(void) setQPROP(queueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100); setQPROP(queueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", 1); */ - dbgprintf("Work Directory: '%s'.\n", pszWorkDir); + dbgprintf("Work Directory: '%s'.\n", glbl.GetWorkDir()); } @@ -2266,7 +2260,7 @@ init(void) if(MainMsgQueType == QUEUETYPE_DISK) { errno = 0; /* for logerror! */ - if(pszWorkDir == NULL) { + if(glbl.GetWorkDir() == NULL) { errmsg.LogError(NO_ERRCODE, "No $WorkDirectory specified - can not run main message queue in 'disk' mode. " "Using 'FixedArray' instead.\n"); MainMsgQueType = QUEUETYPE_FIXED_ARRAY; @@ -2618,7 +2612,7 @@ static rsRetVal loadBuildInModules(void) * is that rsyslog will terminate if we can not register our built-in config commands. * This, I think, is the right thing to do. -- rgerhards, 2007-07-31 */ - CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, NULL, &pszWorkDir, NULL)); +// CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, NULL, &pszWorkDir, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL)); @@ -2782,6 +2776,8 @@ InitGlobalClasses(void) CHKiRet(rsrtInit(&pErrObj, &obj)); /* Now tell the system which classes we need ourselfs */ + pErrObj = "glbl"; + CHKiRet(objUse(glbl, CORE_COMPONENT)); pErrObj = "errmsg"; CHKiRet(objUse(errmsg, CORE_COMPONENT)); pErrObj = "module"; @@ -2870,7 +2866,7 @@ GlobalClassExit(void) CHKiRet(objUse(errmsg, CORE_COMPONENT)); CHKiRet(objUse(module, CORE_COMPONENT)); #endif - rsrtExit(&obj); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */ + rsrtExit(); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */ RETiRet; } -- cgit v1.2.3 From 8c65706d22cb62d724a030b5f0a9603751daac2d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Apr 2008 09:25:03 +0200 Subject: moved "family" variable to global data pool --- tools/syslogd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4fe0071a..90beba24 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -295,7 +295,6 @@ uchar *glblModPath = NULL; /* module load path - only used during initial init, uchar *LocalHostName = NULL;/* our hostname - read-only after startup */ char *LocalDomain; /* our local domain name - read-only after startup */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ -//int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both), set via cmdline */ int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */ int DisableDNS = 0; /* don't look up IP addresses of remote messages */ @@ -3127,10 +3126,10 @@ int realMain(int argc, char **argv) dbgprintf("deque option %c, optarg '%s'\n", ch, arg); switch((char)ch) { case '4': - family = PF_INET; + glbl.SetDefPFFamily(PF_INET); break; case '6': - family = PF_INET6; + glbl.SetDefPFFamily(PF_INET6); break; case 'A': send_to_all++; -- cgit v1.2.3 From e16a207726dce038835cdc12a928a95b5b915440 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Apr 2008 09:40:41 +0200 Subject: moved "bDropMalPTRMsgs" variable to global data pool --- tools/syslogd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 90beba24..5cb0cb38 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -283,7 +283,6 @@ int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sy static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */ static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */ static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ -int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */ 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 */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ @@ -371,7 +370,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a bDebugPrintModuleList = 1; bEscapeCCOnRcv = 1; /* default is to escape control characters */ bReduceRepeatMsgs = 0; - bDropMalPTRMsgs = 0; if(pszMainMsgQFName != NULL) { free(pszMainMsgQFName); pszMainMsgQFName = NULL; @@ -2107,10 +2105,10 @@ static void dbgPrintInitInfo(void) dbgPrintCfSysLineHandlers(); dbgprintf("Messages with malicious PTR DNS Records are %sdropped.\n", - bDropMalPTRMsgs ? "" : "not "); + glbl.GetDropMalPTRMsgs() ? "" : "not "); dbgprintf("Control characters are %sreplaced upon reception.\n", - bEscapeCCOnRcv? "" : "not "); + bEscapeCCOnRcv? "" : "not "); if(bEscapeCCOnRcv) dbgprintf("Control character escape sequence prefix is '%c'.\n", @@ -2639,7 +2637,6 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL, &bDropMalPTRMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL)); -- cgit v1.2.3 From 911101ed26292c766eae0b48575e5911b96d2ea7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Apr 2008 09:54:10 +0200 Subject: moved "option_DisallowWarning" variable to global data pool --- tools/syslogd.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5cb0cb38..2da9187c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -397,10 +397,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a } - -int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */ - - /* hardcoded standard templates (used for defaults) */ static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n\""; static uchar template_TraditionalFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\""; @@ -3233,7 +3229,7 @@ int realMain(int argc, char **argv) bParseHOSTNAMEandTAG = 0; break; case 'w': /* disable disallowed host warnigs */ - option_DisallowWarning = 0; + glbl.SetOption_DisallowWarning(0); break; case 'x': /* disable dns for remote messages */ DisableDNS = 1; -- cgit v1.2.3 From 4824e56aed37b5edffc883cb53c91f0b61c3df62 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Apr 2008 10:11:29 +0200 Subject: moved "DisableDNS" variable to global data pool --- tools/syslogd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 2da9187c..44607aea 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -296,7 +296,6 @@ char *LocalDomain; /* our local domain name - read-only after startup */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */ -int DisableDNS = 0; /* don't look up IP addresses of remote messages */ char **StripDomains = NULL;/* these domains may be stripped before writing logs - r/o after s.u., never touched by init */ char **LocalHosts = NULL;/* these hosts are logged with their hostname - read-only after startup, never touched by init */ static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - is available @@ -3232,7 +3231,7 @@ int realMain(int argc, char **argv) glbl.SetOption_DisallowWarning(0); break; case 'x': /* disable dns for remote messages */ - DisableDNS = 1; + glbl.SetDisableDNS(1); break; case '?': default: -- cgit v1.2.3 From e1791996b81b486e53a36ec753c3bb595f671983 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Apr 2008 10:58:30 +0200 Subject: moved host/domain-name related variables to global data pool --- tools/syslogd.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 44607aea..33a33823 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -291,13 +291,9 @@ int iActExecOnceInterval = 0; /* execute action once every nn seconds */ uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */ /* end global config file state variables */ -uchar *LocalHostName = NULL;/* our hostname - read-only after startup */ -char *LocalDomain; /* our local domain name - read-only after startup */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */ -char **StripDomains = NULL;/* these domains may be stripped before writing logs - r/o after s.u., never touched by init */ -char **LocalHosts = NULL;/* these hosts are logged with their hostname - read-only after startup, never touched by init */ static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - is available * If the main queue is either not yet ready or not running in * queueing mode (mode DIRECT!), then this is set to 0. @@ -870,8 +866,8 @@ logmsgInternal(int pri, char *msg, int flags) CHKiRet(msgConstruct(&pMsg)); MsgSetUxTradMsg(pMsg, msg); MsgSetRawMsg(pMsg, msg); - MsgSetHOSTNAME(pMsg, (LocalHostName == NULL) ? "[localhost]" : (char*)LocalHostName); - MsgSetRcvFrom(pMsg, (LocalHostName == NULL) ? "[localhost]" : (char*)LocalHostName); + MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName()); + MsgSetRcvFrom(pMsg, (char*)glbl.GetLocalHostName()); MsgSetTAG(pMsg, "rsyslogd:"); pMsg->iFacility = LOG_FAC(pri); pMsg->iSeverity = LOG_PRI(pri); @@ -1841,8 +1837,6 @@ freeAllDynMemForTermination(void) free(pszMainMsgQFName); if(pModDir != NULL) free(pModDir); - if(LocalHostName != NULL) - free(LocalHostName); } @@ -2938,7 +2932,7 @@ int realMain(int argc, char **argv) DEFiRet; register int i; - register char *p; + register uchar *p; int num_fds; int ch; struct hostent *hent; @@ -2950,6 +2944,8 @@ int realMain(int argc, char **argv) int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */ char *arg; /* for command line option processing */ uchar legacyConfLine[80]; + uchar *LocalHostName; + uchar *LocalDomain; /* first, parse the command line options. We do not carry out any actual work, just * see what we should do. This relieves us from certain anomalies and we can process @@ -3063,11 +3059,11 @@ int realMain(int argc, char **argv) * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 */ net.getLocalHostname(&LocalHostName); - if((p = strchr((char*)LocalHostName, '.'))) { + if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { *p++ = '\0'; LocalDomain = p; } else { - LocalDomain = ""; + LocalDomain = (uchar*)""; /* It's not clearly defined whether gethostname() * should return the simple hostname or the fqdn. A @@ -3087,7 +3083,7 @@ int realMain(int argc, char **argv) free(LocalHostName); CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - if((p = strchr((char*)LocalHostName, '.'))) + if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { *p++ = '\0'; LocalDomain = p; @@ -3096,8 +3092,15 @@ int realMain(int argc, char **argv) } /* Convert to lower case to recognize the correct domain laterly */ - for (p = (char *)LocalDomain ; *p ; p++) + for(p = LocalDomain ; *p ; p++) *p = (char)tolower((int)*p); + + /* we now have our hostname and can set it inside the global vars. + * TODO: think if all of this would better be a runtime function + * rgerhards, 2008-04-17 + */ + glbl.SetLocalHostName(LocalHostName); + glbl.SetLocalDomain(LocalDomain); /* initialize the objects */ if((iRet = modInitIminternal()) != RS_RET_OK) { @@ -3158,10 +3161,10 @@ int realMain(int argc, char **argv) PidFile = arg; break; case 'l': - if (LocalHosts) { + if(glbl.GetLocalHosts() != NULL) { fprintf (stderr, "rsyslogd: Only one -l argument allowed, the first one is taken.\n"); } else { - LocalHosts = crunch_list(arg); + glbl.SetLocalHosts(crunch_list(arg)); } break; case 'm': /* mark interval */ @@ -3211,10 +3214,10 @@ int realMain(int argc, char **argv) fprintf(stderr, "-r option only supported in compatibility modes 0 to 2 - ignored\n"); break; case 's': - if (StripDomains) { + if(glbl.GetStripDomains() != NULL) { fprintf (stderr, "rsyslogd: Only one -s argument allowed, the first one is taken.\n"); } else { - StripDomains = crunch_list(arg); + glbl.SetStripDomains(crunch_list(arg)); } break; case 't': /* enable tcp logging */ -- cgit v1.2.3 From e5130affc022eff12a3d9584576a385edbb13465 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Apr 2008 11:17:15 +0200 Subject: moved "glblModPath" variable inside global data pool (but still as a variable, not part of glbl object) --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 33a33823..67c7d11b 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -288,7 +288,6 @@ static int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - n int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ int iActExecOnceInterval = 0; /* execute action once every nn seconds */ -uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */ /* end global config file state variables */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ -- cgit v1.2.3 From 60309004dfc57c3243abb2f01042950201596773 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Apr 2008 12:46:57 +0200 Subject: completed better modularity of runtime - added the ability to specify an error log function for the runtime - removed dependency of core runtime on dirty.h Note that it is "better" modularity, not perfect. There is still work to do, but I think we can for the time being proceed with other things. --- tools/syslogd.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 67c7d11b..f2b18a3d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -847,6 +847,19 @@ finalize_it: RETiRet; } + +/* this is a special function used to submit an error message. This + * function is also passed to the runtime library as the generic error + * message handler. -- rgerhards, 2008-04-17 + */ +rsRetVal +submitErrMsg(uchar *msg) +{ + DEFiRet; + iRet = logmsgInternal(LOG_SYSLOG|LOG_ERR, msg, ADDDATE); + RETiRet; +} + /* rgerhards 2004-11-09: the following is a function that can be used * to log a message orginating from the syslogd itself. In sysklogd code, * this is done by simply calling logmsg(). However, logmsg() is changed in @@ -857,14 +870,14 @@ finalize_it: * think on the best way to do this. */ rsRetVal -logmsgInternal(int pri, char *msg, int flags) +logmsgInternal(int pri, uchar *msg, int flags) { DEFiRet; msg_t *pMsg; CHKiRet(msgConstruct(&pMsg)); - MsgSetUxTradMsg(pMsg, msg); - MsgSetRawMsg(pMsg, msg); + MsgSetUxTradMsg(pMsg, (char*)msg); + MsgSetRawMsg(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName()); MsgSetRcvFrom(pMsg, (char*)glbl.GetLocalHostName()); MsgSetTAG(pMsg, "rsyslogd:"); @@ -1877,7 +1890,7 @@ die(int sig) "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.", (int) myPid, sig); errno = 0; - logmsgInternal(LOG_SYSLOG|LOG_INFO, buf, ADDDATE); + logmsgInternal(LOG_SYSLOG|LOG_INFO, (uchar*)buf, ADDDATE); } /* drain queue (if configured so) and stop main queue worker thread pool */ @@ -2330,7 +2343,7 @@ init(void) " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] restart", (int) myPid); - logmsgInternal(LOG_SYSLOG|LOG_INFO, bufStartUpMsg, ADDDATE); + logmsgInternal(LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, ADDDATE); memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); -- cgit v1.2.3 From 08a4fc4ae56f29cc21c997488291f49b83fd1102 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 18 Apr 2008 14:35:27 +0200 Subject: bugfix: a recent change effectively disabled error messages --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f2b18a3d..4327ab7f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2771,6 +2771,7 @@ InitGlobalClasses(void) /* Intialize the runtime system */ pErrObj = "rsyslog runtime"; /* set in case the runtime errors before setting an object */ CHKiRet(rsrtInit(&pErrObj, &obj)); + CHKiRet(rsrtSetErrLogger(submitErrMsg)); /* set out error handler */ /* Now tell the system which classes we need ourselfs */ pErrObj = "glbl"; -- cgit v1.2.3 From 77b1cdf743a9278ec7b94f26f419966f5d4d821c Mon Sep 17 00:00:00 2001 From: varmojfekoj Date: Thu, 24 Apr 2008 14:29:11 +0200 Subject: -c option no longer must be the first option Thanks to varmjofekoj for the patch Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4327ab7f..870925a2 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2952,7 +2952,6 @@ int realMain(int argc, char **argv) extern int optind; extern char *optarg; struct sigaction sigAct; - int bIsFirstOption = 1; int bEOptionWasGiven = 0; int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */ char *arg; /* for command line option processing */ @@ -2997,11 +2996,6 @@ int realMain(int argc, char **argv) CHKiRet(bufOptAdd(ch, optarg)); break; case 'c': /* compatibility mode */ - if(!bIsFirstOption) { - fprintf(stderr, "-c option MUST be specified as the first option - aborting...\n"); - usage(); - exit(1); - } iCompatibilityMode = atoi(optarg); break; case 'd': /* debug - must be handled now, so that debug is active during init! */ @@ -3042,7 +3036,6 @@ int realMain(int argc, char **argv) default: usage(); } - bIsFirstOption = 0; /* we already saw an option character */ } if ((argc -= optind)) -- cgit v1.2.3 From 858f1efd05a2f3c8bc6a0edf8a01f40e27f02407 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 28 Apr 2008 09:21:07 +0200 Subject: preparation for bughunt including some cleanups --- tools/syslogd.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4327ab7f..634794ef 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1553,8 +1553,7 @@ submitMsg(msg_t *pMsg) } -/* - * Log a message to the appropriate log files, users, etc. based on +/* Log a message to the appropriate log files, users, etc. based on * the priority. * rgerhards 2004-11-08: actually, this also decodes all but the PRI part. * rgerhards 2004-11-09: ... but only, if syslogd could properly be initialized @@ -2208,12 +2207,12 @@ init(void) tplDeleteNew(); /* re-setting values to defaults (where applicable) */ - /* TODO: once we have loadable modules, we must re-visit this code. The reason is + /* once we have loadable modules, we must re-visit this code. The reason is * that config variables are not re-set, because the module is not yet loaded. On * the other hand, that doesn't matter, because the module got unloaded and is then - * re-loaded, so the variables should be re-set via that way. In any case, we should - * think about the whole situation when we implement loadable plugins. - * rgerhards, 2007-07-31 + * re-loaded, so the variables should be re-set via that way. And this is exactly how + * it works. Loadable module's variables are initialized on load, the rest here. + * rgerhards, 2008-04-28 */ conf.cfsysline((uchar*)"ResetConfigVariables"); -- cgit v1.2.3 From e0a2745d3f84a2f22ffce029de14e38a6433b402 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 6 May 2008 15:05:39 +0200 Subject: some cleanup (gotten rid of some more plain chars) --- tools/syslogd.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 835a020d..99179e3b 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -598,10 +598,10 @@ void untty(void) * I added an additional calling parameter to permit specifying the flow * control capability of the source. */ -rsRetVal printline(char *hname, char *msg, int bParseHost, int flags, flowControl_t flowCtlType) +rsRetVal printline(uchar *hname, uchar *msg, int bParseHost, int flags, flowControl_t flowCtlType) { DEFiRet; - register char *p; + register uchar *p; int pri; msg_t *pMsg; @@ -609,7 +609,7 @@ rsRetVal printline(char *hname, char *msg, int bParseHost, int flags, flowContro */ CHKiRet(msgConstruct(&pMsg)); MsgSetFlowControlType(pMsg, flowCtlType); - MsgSetRawMsg(pMsg, msg); + MsgSetRawMsg(pMsg, (char*)msg); pMsg->bParseHOSTNAME = bParseHost; /* test for special codes */ @@ -637,15 +637,15 @@ rsRetVal printline(char *hname, char *msg, int bParseHost, int flags, flowContro * being the local host). rgerhards 2004-11-16 */ if(bParseHost == 0) - MsgSetHOSTNAME(pMsg, hname); - MsgSetRcvFrom(pMsg, hname); + MsgSetHOSTNAME(pMsg, (char*)hname); + MsgSetRcvFrom(pMsg, (char*)hname); /* rgerhards 2004-11-19: well, well... we've now seen that we * have the "hostname problem" also with the traditional Unix * message. As we like to emulate it, we need to add the hostname * to it. */ - if(MsgSetUxTradMsg(pMsg, p) != 0) + if(MsgSetUxTradMsg(pMsg, (char*)p) != 0) ABORT_FINALIZE(RS_RET_ERR); logmsg(pMsg, flags); @@ -690,16 +690,16 @@ finalize_it: * control capability of the source. */ rsRetVal -parseAndSubmitMessage(char *hname, char *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType) +parseAndSubmitMessage(uchar *hname, uchar *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType) { DEFiRet; register int iMsg; - char *pMsg; - char *pData; - char *pEnd; - char tmpline[MAXLINE + 1]; + uchar *pMsg; + uchar *pData; + uchar *pEnd; + uchar tmpline[MAXLINE + 1]; # ifdef USE_NETZIP - char deflateBuf[MAXLINE + 1]; + uchar deflateBuf[MAXLINE + 1]; uLongf iLenDefBuf; # endif -- cgit v1.2.3 From 09afe64f29bae5af8ea1749373e8c8b6586b70d1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 16 May 2008 13:36:41 +0200 Subject: added fromhost-ip properties and some bugfixes - bugfix: TCP input modules did incorrectly set fromhost property (always blank) - bugfix: imklog did not set fromhost property - added "fromhost-ip" property - added "RSYSLOG_DebugFormat" canned template - bugfix: hostname and fromhost were swapped when a persisted message (in queued mode) was read in --- tools/syslogd.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 99179e3b..8b829771 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -392,6 +392,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a /* hardcoded standard templates (used for defaults) */ +static uchar template_DebugFormat[] = "\"Debug line with all properties:\nFROMHOST: '%FROMHOST%', fromhost-ip: '%fromhost-ip%', HOSTNAME: '%HOSTNAME%', PRI: %PRI%,\nsyslogtag '%syslogtag%', programname: '%programname%', APP-NAME: '%APP-NAME%', PROCID: '%PROCID%', MSGID: '%MSGID%',\nTIMESTAMP: '%TIMESTAMP%', STRUCTURED-DATA: '%STRUCTURED-DATA%',\nmsg: '%msg%'\nescaped msg: '%msg:::drop-cc%'\nrawmsg: '%rawmsg%'\n\n\""; static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n\""; static uchar template_TraditionalFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\""; static uchar template_FileFormat[] = "\"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\""; @@ -597,16 +598,19 @@ void untty(void) * rgerhards, 2008-03-19: * I added an additional calling parameter to permit specifying the flow * control capability of the source. + * + * rgerhards, 2008-05-16: + * I added an additional calling parameter (hnameIP) to enable specifying the IP + * of a remote host. */ -rsRetVal printline(uchar *hname, uchar *msg, int bParseHost, int flags, flowControl_t flowCtlType) +rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int bParseHost, int flags, flowControl_t flowCtlType) { DEFiRet; register uchar *p; int pri; msg_t *pMsg; - /* Now it is time to create the message object (rgerhards) - */ + /* Now it is time to create the message object (rgerhards) */ CHKiRet(msgConstruct(&pMsg)); MsgSetFlowControlType(pMsg, flowCtlType); MsgSetRawMsg(pMsg, (char*)msg); @@ -639,6 +643,7 @@ rsRetVal printline(uchar *hname, uchar *msg, int bParseHost, int flags, flowCont if(bParseHost == 0) MsgSetHOSTNAME(pMsg, (char*)hname); MsgSetRcvFrom(pMsg, (char*)hname); + CHKiRet(MsgSetRcvFromIP(pMsg, hnameIP)); /* rgerhards 2004-11-19: well, well... we've now seen that we * have the "hostname problem" also with the traditional Unix @@ -688,9 +693,13 @@ finalize_it: * rgerhards, 2008-03-19: * I added an additional calling parameter to permit specifying the flow * control capability of the source. + * + * rgerhards, 2008-05-16: + * I added an additional calling parameter (hnameIP) to enable specifying the IP + * of a remote host. */ rsRetVal -parseAndSubmitMessage(uchar *hname, uchar *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType) +parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType) { DEFiRet; register int iMsg; @@ -704,6 +713,7 @@ parseAndSubmitMessage(uchar *hname, uchar *msg, int len, int bParseHost, int fla # endif assert(hname != NULL); + assert(hnameIP != NULL); assert(msg != NULL); assert(len >= 0); @@ -789,7 +799,7 @@ parseAndSubmitMessage(uchar *hname, uchar *msg, int len, int bParseHost, int fla */ if(iMsg == MAXLINE) { *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ - printline(hname, tmpline, bParseHost, flags, flowCtlType); + printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType); } else { /* This case in theory never can happen. If it happens, we have * a logic error. I am checking for it, because if I would not, @@ -841,7 +851,7 @@ parseAndSubmitMessage(uchar *hname, uchar *msg, int len, int bParseHost, int fla *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ /* typically, we should end up here! */ - printline(hname, tmpline, bParseHost, flags, flowCtlType); + printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType); finalize_it: RETiRet; @@ -880,6 +890,7 @@ logmsgInternal(int pri, uchar *msg, int flags) MsgSetRawMsg(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName()); MsgSetRcvFrom(pMsg, (char*)glbl.GetLocalHostName()); + MsgSetRcvFromIP(pMsg, (uchar*)"127.0.0.1"); MsgSetTAG(pMsg, "rsyslogd:"); pMsg->iFacility = LOG_FAC(pri); pMsg->iSeverity = LOG_PRI(pri); @@ -2715,6 +2726,8 @@ static void mainThread() */ /* initialize the build-in templates */ + pTmp = template_DebugFormat; + tplAddLine("RSYSLOG_DebugFormat", &pTmp); pTmp = template_SyslogProtocol23Format; tplAddLine("RSYSLOG_SyslogProtocol23Format", &pTmp); pTmp = template_FileFormat; /* new format for files with high-precision stamp */ -- cgit v1.2.3 From 2658319224574a54a1c76ee02b6a7f3af5dab068 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 9 Jun 2008 16:38:53 +0200 Subject: made rsyslog tickless in the (usual and default) case that repeated message reduction is turned off. More info: http://blog.gerhards.net/2008/06/coding-to-save-environment.html --- tools/syslogd.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 8b829771..7f415f3c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2491,15 +2491,22 @@ mainloop(void) struct timeval tvSelectTimeout; BEGINfunc - while(!bFinished){ - /* first check if we have any internal messages queued and spit them out */ - /* TODO: do we need this any longer? I doubt it, but let's care about it - * later -- rgerhards, 2007-12-21 - */ - processImInternal(); + /* first check if we have any internal messages queued and spit them out. We used + * to do that on any loop iteration, but that is no longer necessry. The reason + * is that once we reach this point here, we always run on multiple threads and + * thus the main queue is properly initialized. -- rgerhards, 2008-06-09 + */ + processImInternal(); - /* this is now just a wait */ - tvSelectTimeout.tv_sec = TIMERINTVL; + while(!bFinished){ + /* this is now just a wait - please note that we do use a near-"eternal" + * timeout of 1 day if we do not have repeated message reduction turned on + * (which it is not by default). This enables us to help safe the environment + * by not unnecessarily awaking rsyslog on a regular tick (just think + * powertop, for example). In that case, we primarily wait for a signal, + * but a once-a-day wakeup should be quite acceptable. -- rgerhards, 2008-06-09 + */ + tvSelectTimeout.tv_sec = (bReduceRepeatMsgs == 1) ? TIMERINTVL : 86400 /*1 day*/; tvSelectTimeout.tv_usec = 0; select(1, NULL, NULL, NULL, &tvSelectTimeout); if(bFinished) @@ -2526,7 +2533,8 @@ mainloop(void) * for the time being, I think the remaining risk can be accepted. * rgerhards, 2008-01-10 */ - doFlushRptdMsgs(); + if(bReducedRepeatMsgs == 1) + doFlushRptdMsgs(); if(restart) { dbgprintf("\nReceived SIGHUP, reloading rsyslogd.\n"); -- cgit v1.2.3 From 8c0ac28fd9ff006154e78ffabd75a088cb8fe087 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 10 Jun 2008 08:18:10 +0200 Subject: fixed syntax error (typo in var name) and cleaup --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 7f415f3c..ab4d6784 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2533,7 +2533,7 @@ mainloop(void) * for the time being, I think the remaining risk can be accepted. * rgerhards, 2008-01-10 */ - if(bReducedRepeatMsgs == 1) + if(bReduceRepeatMsgs == 1) doFlushRptdMsgs(); if(restart) { -- cgit v1.2.3 From 3f6c73a8b7ff2c6d9c931876d823f2b4ef6bbea2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 27 Jun 2008 12:52:45 +0200 Subject: added (internal) error codes to error messages Also added redirector to web description of error codes closes bug http://bugzilla.adiscon.com/show_bug.cgi?id=20 --- tools/syslogd.c | 51 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ab4d6784..b21988ab 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -773,7 +773,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa * rgerhards, 2006-12-07 */ if(ret != Z_OK) { - errmsg.LogError(NO_ERRCODE, "Uncompression of a message failed with return code %d " + errmsg.LogError(0, NO_ERRCODE, "Uncompression of a message failed with return code %d " "- enable debug logging if you need further information. " "Message ignored.", ret); FINALIZE; /* unconditional exit, nothing left to do... */ @@ -786,7 +786,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa * tell the user we can not accept it. */ if(len > 0 && *msg == 'z') { - errmsg.LogError(NO_ERRCODE, "Received a compressed message, but rsyslogd does not have compression " + errmsg.LogError(0, NO_ERRCODE, "Received a compressed message, but rsyslogd does not have compression " "support enabled. The message will be ignored."); FINALIZE; } @@ -863,10 +863,10 @@ finalize_it: * message handler. -- rgerhards, 2008-04-17 */ rsRetVal -submitErrMsg(uchar *msg) +submitErrMsg(int iErr, uchar *msg) { DEFiRet; - iRet = logmsgInternal(LOG_SYSLOG|LOG_ERR, msg, ADDDATE); + iRet = logmsgInternal(iErr, LOG_SYSLOG|LOG_ERR, msg, ADDDATE); RETiRet; } @@ -880,10 +880,11 @@ submitErrMsg(uchar *msg) * think on the best way to do this. */ rsRetVal -logmsgInternal(int pri, uchar *msg, int flags) +logmsgInternal(int iErr, int pri, uchar *msg, int flags) { - DEFiRet; + uchar pszTag[33]; msg_t *pMsg; + DEFiRet; CHKiRet(msgConstruct(&pMsg)); MsgSetUxTradMsg(pMsg, (char*)msg); @@ -891,7 +892,17 @@ logmsgInternal(int pri, uchar *msg, int flags) MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName()); MsgSetRcvFrom(pMsg, (char*)glbl.GetLocalHostName()); MsgSetRcvFromIP(pMsg, (uchar*)"127.0.0.1"); - MsgSetTAG(pMsg, "rsyslogd:"); + /* check if we have an error code associated and, if so, + * adjust the tag. -- r5gerhards, 2008-06-27 + */ + if(iErr == NO_ERRCODE) { + MsgSetTAG(pMsg, "rsyslogd:"); + } else { +dbgprintf("iErr %d\n", iErr); + snprintf((char*)pszTag, sizeof(pszTag), "rsyslogd%d:", iErr); + pszTag[32] = '\0'; /* just to make sure... */ + MsgSetTAG(pMsg, (char*)pszTag); + } pMsg->iFacility = LOG_FAC(pri); pMsg->iSeverity = LOG_PRI(pri); pMsg->bParseHOSTNAME = 0; @@ -1745,7 +1756,7 @@ void legacyOptsHook(void) while(pThis != NULL) { if(pThis->line != NULL) { errno = 0; - errmsg.LogError(NO_ERRCODE, "Warning: backward compatibility layer added to following " + errmsg.LogError(0, NO_ERRCODE, "Warning: backward compatibility layer added to following " "directive to rsyslog.conf: %s", pThis->line); conf.cfsysline(pThis->line); } @@ -1900,7 +1911,7 @@ die(int sig) "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.", (int) myPid, sig); errno = 0; - logmsgInternal(LOG_SYSLOG|LOG_INFO, (uchar*)buf, ADDDATE); + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, ADDDATE); } /* drain queue (if configured so) and stop main queue worker thread pool */ @@ -2262,19 +2273,19 @@ init(void) /* some checks */ if(iMainMsgQueueNumWorkers < 1) { - errmsg.LogError(NO_ERRCODE, "$MainMsgQueueNumWorkers must be at least 1! Set to 1.\n"); + errmsg.LogError(0, NO_ERRCODE, "$MainMsgQueueNumWorkers must be at least 1! Set to 1.\n"); iMainMsgQueueNumWorkers = 1; } if(MainMsgQueType == QUEUETYPE_DISK) { errno = 0; /* for logerror! */ if(glbl.GetWorkDir() == NULL) { - errmsg.LogError(NO_ERRCODE, "No $WorkDirectory specified - can not run main message queue in 'disk' mode. " + errmsg.LogError(0, NO_ERRCODE, "No $WorkDirectory specified - can not run main message queue in 'disk' mode. " "Using 'FixedArray' instead.\n"); MainMsgQueType = QUEUETYPE_FIXED_ARRAY; } if(pszMainMsgQFName == NULL) { - errmsg.LogError(NO_ERRCODE, "No $MainMsgQueueFileName specified - can not run main message queue in " + errmsg.LogError(0, NO_ERRCODE, "No $MainMsgQueueFileName specified - can not run main message queue in " "'disk' mode. Using 'FixedArray' instead.\n"); MainMsgQueType = QUEUETYPE_FIXED_ARRAY; } @@ -2297,11 +2308,11 @@ init(void) /* ... set some properties ... */ # define setQPROP(func, directive, data) \ CHKiRet_Hdlr(func(pMsgQueue, data)) { \ - errmsg.LogError(NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ + errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ } # define setQPROPstr(func, directive, data) \ CHKiRet_Hdlr(func(pMsgQueue, data, (data == NULL)? 0 : strlen((char*) data))) { \ - errmsg.LogError(NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ + errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ } setQPROP(queueSetMaxFileSize, "$MainMsgQueueFileSize", iMainMsgQueMaxFileSize); @@ -2353,7 +2364,7 @@ init(void) " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] restart", (int) myPid); - logmsgInternal(LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, ADDDATE); + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, ADDDATE); memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); @@ -2385,7 +2396,7 @@ selectorAddList(selector_t *f) if(f != NULL) { CHKiRet(llGetNumElts(&f->llActList, &iActionCnt)); if(iActionCnt == 0) { - errmsg.LogError(NO_ERRCODE, "warning: selector line without actions will be discarded"); + errmsg.LogError(0, NO_ERRCODE, "warning: selector line without actions will be discarded"); selectorDestruct(f); } else { /* successfully created an entry */ @@ -2432,7 +2443,7 @@ static rsRetVal setMainMsgQueType(void __attribute__((unused)) *pVal, uchar *psz MainMsgQueType = QUEUETYPE_DIRECT; dbgprintf("main message queue type set to DIRECT (no queueing at all)\n"); } else { - errmsg.LogError(NO_ERRCODE, "unknown mainmessagequeuetype parameter: %s", (char *) pszType); + errmsg.LogError(0, RS_RET_INVALID_PARAMS, "unknown mainmessagequeuetype parameter: %s", (char *) pszType); iRet = RS_RET_INVALID_PARAMS; } free(pszType); /* no longer needed */ @@ -3178,7 +3189,7 @@ int realMain(int argc, char **argv) break; case 'h': if(iCompatibilityMode < 3) { - errmsg.LogError(NO_ERRCODE, "WARNING: -h option is no longer supported - ignored"); + errmsg.LogError(0, NO_ERRCODE, "WARNING: -h option is no longer supported - ignored"); } else { usage(); /* for v3 and above, it simply is an error */ } @@ -3273,7 +3284,7 @@ int realMain(int argc, char **argv) /* process compatibility mode settings */ if(iCompatibilityMode < 3) { - errmsg.LogError(NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically " + errmsg.LogError(0, NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically " "generated config directives may interfer with your rsyslog.conf settings. " "We suggest upgrading your config and adding -c3 as the first " "rsyslogd option."); @@ -3288,7 +3299,7 @@ int realMain(int argc, char **argv) } if(bEOptionWasGiven && iCompatibilityMode < 3) { - errmsg.LogError(NO_ERRCODE, "WARNING: \"message repeated n times\" feature MUST be turned on in " + errmsg.LogError(0, NO_ERRCODE, "WARNING: \"message repeated n times\" feature MUST be turned on in " "rsyslog.conf - CURRENTLY EVERY MESSAGE WILL BE LOGGED. Visit " "http://www.rsyslog.com/rptdmsgreduction to learn " "more and cast your vote if you want us to keep this feature."); -- cgit v1.2.3 From aeef9bbe727d80c5882cc0a883b8dfd5df461f10 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 2 Jul 2008 11:56:54 +0200 Subject: bugfix: machine certificate was required for client even in TLS anon mode Reference: http://bugzilla.adiscon.com/show_bug.cgi?id=85 The fix also slightly improves performance by not storing certificates in client sessions when there is no need to do so. --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b21988ab..dda605a8 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -898,7 +898,6 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) if(iErr == NO_ERRCODE) { MsgSetTAG(pMsg, "rsyslogd:"); } else { -dbgprintf("iErr %d\n", iErr); snprintf((char*)pszTag, sizeof(pszTag), "rsyslogd%d:", iErr); pszTag[32] = '\0'; /* just to make sure... */ MsgSetTAG(pMsg, (char*)pszTag); -- cgit v1.2.3 From 13f246c3f2e184eed47d495c5cf21af497b4dc9b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 9 Jul 2008 12:08:06 +0200 Subject: minor: enhanced debug output (PRI now included) --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index dda605a8..3f97a70f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1601,7 +1601,7 @@ logmsg(msg_t *pMsg, int flags) assert(pMsg != NULL); assert(pMsg->pszUxTradMsg != NULL); msg = (char*) pMsg->pszUxTradMsg; - dbgprintf("logmsg: flags %x, from '%s', msg %s\n", flags, getRcvFrom(pMsg), msg); + dbgprintf("logmsg: flags %x, pri %s, from '%s', msg %s\n", flags, getPRI(pMsg), getRcvFrom(pMsg), msg); /* rger 2005-11-24 (happy thanksgiving!): we now need to check if we have * a traditional syslog message or one formatted according to syslog-protocol. -- cgit v1.2.3 From 1790a23aea2d98dd855d55a990aae18c5eb0e8b3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 11 Jul 2008 18:23:04 +0200 Subject: temporary: some debug instrumentation to help find a segfault on freebsd --- tools/syslogd.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3f97a70f..b005b6d0 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -908,6 +908,8 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ flags |= INTERNAL_MSG; +RUNLOG_VAR("%d", bHaveMainQueue); +RUNLOG_VAR("%p", pMsg); if(bHaveMainQueue == 0) { /* not yet in queued mode */ iminternalAddMsg(pri, pMsg, flags); } else { @@ -1626,10 +1628,14 @@ logmsg(msg_t *pMsg, int flags) /* ---------------------- END PARSING ---------------- */ +RUNLOG; /* now submit the message to the main queue - then we are done */ pMsg->msgFlags = flags; +RUNLOG; MsgPrepareEnqueue(pMsg); +RUNLOG; queueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg); +RUNLOG; ENDfunc } -- cgit v1.2.3 From a6de2e589254dbfffd2746d8efbefc04f8ed3725 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 14 Jul 2008 11:39:58 +0200 Subject: cleanup of debugging messages (removed no longer needed ones) --- tools/syslogd.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b005b6d0..3f97a70f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -908,8 +908,6 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ flags |= INTERNAL_MSG; -RUNLOG_VAR("%d", bHaveMainQueue); -RUNLOG_VAR("%p", pMsg); if(bHaveMainQueue == 0) { /* not yet in queued mode */ iminternalAddMsg(pri, pMsg, flags); } else { @@ -1628,14 +1626,10 @@ logmsg(msg_t *pMsg, int flags) /* ---------------------- END PARSING ---------------- */ -RUNLOG; /* now submit the message to the main queue - then we are done */ pMsg->msgFlags = flags; -RUNLOG; MsgPrepareEnqueue(pMsg); -RUNLOG; queueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg); -RUNLOG; ENDfunc } -- cgit v1.2.3 From b7c91420b0814ee20088d27953582a5064c9a467 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 28 Jul 2008 07:46:35 +0200 Subject: begun implementing a diagnostic plugin (not yet completed) --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5edf92ce..1b63734b 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -870,6 +870,7 @@ submitErrMsg(int iErr, uchar *msg) RETiRet; } + /* rgerhards 2004-11-09: the following is a function that can be used * to log a message orginating from the syslogd itself. In sysklogd code, * this is done by simply calling logmsg(). However, logmsg() is changed in -- cgit v1.2.3 From d2feb7063e73938c05b76862ea2e211cc09b30fe Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 29 Jul 2008 10:07:50 +0200 Subject: enhanced configuration file error reporting and verification - enhanced config file checking - no active actions are detected - added -N rsyslogd command line option for a config validation run (which does not execute actual syslogd code and does not interfere with a running instance) - somewhat improved emergency configuration. It is now also selected if the config contains no active actions - rsyslogd error messages are now reported to stderr by default. can be turned off by the new "$ErrorMessagesToStderr off" directive Thanks to HKS for suggesting these new features. --- tools/syslogd.c | 271 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 174 insertions(+), 97 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 1b63734b..d023ec39 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -255,6 +255,7 @@ static int bFinished = 0; /* used by termination signal handler, read-only excep * is either 0 or the number of the signal that requested the * termination. */ +static int iConfigVerify = 0; /* is this just a config verify run? */ /* Intervals at which we flush out "message repeated" messages, * in seconds after previous message is logged. After each flush, @@ -285,6 +286,7 @@ static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list i static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ 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 bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ int iActExecOnceInterval = 0; /* execute action once every nn seconds */ @@ -418,7 +420,7 @@ static void processImInternal(void); static int usage(void) { fprintf(stderr, "usage: rsyslogd [-cversion] [-46AdnqQvwx] [-lhostlist] [-sdomainlist]\n" - " [-fconffile] [-ipidfile]\n" + " [-fconffile] [-ipidfile] [-Nlevel]\n" "To run rsyslogd in native mode, use \"rsyslogd -c3 \"\n\n" "For further information see http://www.rsyslog.com/doc\n"); exit(1); /* "good" exit - done to terminate usage() */ @@ -909,6 +911,18 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ flags |= INTERNAL_MSG; + /* we now check if we should print internal messages out to stderr. This was + * suggested by HKS as a way to help people troubleshoot rsyslog configuration + * (by running it interactively. This makes an awful lot of sense, so I add + * it here. -- rgerhards, 2008-07-28 + * Note that error messages can not be disable during a config verify. This + * permits us to process unmodified config files which otherwise contain a + * supressor statement. + */ + if(bErrMsgToStderr || iConfigVerify) { + fprintf(stderr, "rsyslogd: %s\n", msg); + } + if(bHaveMainQueue == 0) { /* not yet in queued mode */ iminternalAddMsg(pri, pMsg, flags); } else { @@ -1772,7 +1786,7 @@ void legacyOptsParseTCP(char ch, char *arg) static char conflict = '\0'; if((conflict == 'g' && ch == 't') || (conflict == 't' && ch == 'g')) { - fprintf(stderr, "rsyslog: If you want to use both -g and -t, use directives instead, -%c ignored.\n", ch); + fprintf(stderr, "rsyslogd: If you want to use both -g and -t, use directives instead, -%c ignored.\n", ch); return; } else conflict = ch; @@ -2191,11 +2205,15 @@ startInputModules(void) /* INIT -- Initialize syslogd from configuration table * init() is called at initial startup AND each time syslogd is HUPed + * Note that if iConfigVerify is set, only the config file is verified but nothing + * else happens. -- rgerhards, 2008-07-28 */ -static void +static rsRetVal init(void) { DEFiRet; + rsRetVal localRet; + int iNbrActions; char cbuf[BUFSIZ]; char bufStartUpMsg[512]; struct sigaction sigAct; @@ -2238,22 +2256,42 @@ init(void) */ conf.cfsysline((uchar*)"ResetConfigVariables"); + conf.ReInitConf(); + /* open the configuration file */ - if((iRet = conf.processConfFile(ConfFile)) != RS_RET_OK) { + localRet = conf.processConfFile(ConfFile); + CHKiRet(conf.GetNbrActActions(&iNbrActions)); + + if(localRet != RS_RET_OK) { + errmsg.LogError(0, localRet, "CONFIG ERROR: could not interpret master config file '%s'.", ConfFile); + } else if(iNbrActions == 0) { + errmsg.LogError(0, RS_RET_NO_ACTIONS, "CONFIG ERROR: there are no active actions configured. Inputs will " + "run, but no output whatsoever is created."); + } + + if(localRet != RS_RET_OK || iNbrActions == 0) { /* rgerhards: this code is executed to set defaults when the * config file could not be opened. We might think about * abandoning the run in this case - but this, too, is not * very clever... So we stick with what we have. * We ignore any errors while doing this - we would be lost anyhow... */ + errmsg.LogError(0, NO_ERRCODE, "EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file!"); selector_t *f = NULL; - char szTTYNameBuf[_POSIX_TTY_NAME_MAX+1]; /* +1 for NULL character */ - dbgprintf("primary config file could not be opened - using emergency definitions.\n"); + + /* note: we previously used _POSIY_TTY_NAME_MAX+1, but this turned out to be + * too low on linux... :-S -- rgerhards, 2008-07-28 + */ + char szTTYNameBuf[128]; conf.cfline((uchar*)"*.ERR\t" _PATH_CONSOLE, &f); + conf.cfline((uchar*)"syslog.*\t" _PATH_CONSOLE, &f); conf.cfline((uchar*)"*.PANIC\t*", &f); + conf.cfline((uchar*)"syslog.*\troot", &f); if(ttyname_r(0, szTTYNameBuf, sizeof(szTTYNameBuf)) == 0) { snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf); conf.cfline((uchar*)cbuf, &f); + } else { + dbgprintf("error %d obtaining controlling terminal, not using that emergency rule\n", errno); } selectorAddList(f); } @@ -2291,6 +2329,12 @@ init(void) } } + /* we are done checking the config - now validate if we should actually run or not. + * If not, terminate. -- rgerhards, 2008-07-25 + */ + if(iConfigVerify) + ABORT_FINALIZE(RS_RET_VALIDATION_RUN); + /* switch the message object to threaded operation, if necessary */ if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) { MsgEnableThreadSafety(); @@ -2372,7 +2416,9 @@ init(void) sigaction(SIGHUP, &sigAct, NULL); dbgprintf(" (re)started.\n"); - ENDfunc + +finalize_it: + RETiRet; } @@ -2680,6 +2726,7 @@ static rsRetVal loadBuildInModules(void) NULL, &bDebugPrintCfSysLineHandlerList, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &bErrMsgToStderr, NULL)); /* now add other modules handlers (we should work on that to be able to do it in ClassInit(), but so far * that is not possible). -- rgerhards, 2008-01-28 @@ -2735,9 +2782,9 @@ static void printVersion(void) * move code out of the too-long main() function. * rgerhards, 2007-10-17 */ -static void mainThread() +static rsRetVal mainThread() { - BEGINfunc + DEFiRet; uchar *pTmp; /* Note: signals MUST be processed by the thread this code is running in. The reason @@ -2766,7 +2813,8 @@ static void mainThread() pTmp = template_StdPgSQLFmt; tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp)); - init(); + CHKiRet(init()); + if(Debug) { dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); debugging_on = 1; @@ -2785,7 +2833,9 @@ static void mainThread() dbgprintf("initialization completed, transitioning to regular run mode\n"); mainloop(); - ENDfunc + +finalize_it: + RETiRet; } @@ -2968,6 +3018,98 @@ finalize_it: } +/* global initialization, to be done only once and before the mainloop is started. + * rgerhards, 2008-07-28 (extracted from realMain()) + */ +static rsRetVal +doGlblProcessInit(void) +{ + struct sigaction sigAct; + int num_fds; + int i; + DEFiRet; + + checkPermissions(); + thrdInit(); + + if( !(Debug || NoFork) ) + { + dbgprintf("Checking pidfile.\n"); + if (!check_pid(PidFile)) + { + memset(&sigAct, 0, sizeof (sigAct)); + sigemptyset(&sigAct.sa_mask); + sigAct.sa_handler = doexit; + sigaction(SIGTERM, &sigAct, NULL); + + if (fork()) { + /* Parent process + */ + sleep(300); + /* Not reached unless something major went wrong. 5 + * minutes should be a fair amount of time to wait. + * Please note that this procedure is important since + * the father must not exit before syslogd isn't + * initialized or the klogd won't be able to flush its + * logs. -Joey + */ + exit(1); /* "good" exit - after forking, not diasabling anything */ + } + num_fds = getdtablesize(); + for (i= 0; i < num_fds; i++) + (void) close(i); + untty(); + } + else + { + fputs(" Already running.\n", stderr); + exit(1); /* "good" exit, done if syslogd is already running */ + } + } + else + debugging_on = 1; + + /* tuck my process id away */ + dbgprintf("Writing pidfile %s.\n", PidFile); + if (!check_pid(PidFile)) + { + if (!write_pid(PidFile)) + { + fputs("Can't write pid.\n", stderr); + exit(1); /* exit during startup - questionable */ + } + } + else + { + fputs("Pidfile (and pid) already exist.\n", stderr); + exit(1); /* exit during startup - questionable */ + } + myPid = getpid(); /* save our pid for further testing (also used for messages) */ + + memset(&sigAct, 0, sizeof (sigAct)); + sigemptyset(&sigAct.sa_mask); + + sigAct.sa_handler = sigsegvHdlr; + sigaction(SIGSEGV, &sigAct, NULL); + sigAct.sa_handler = sigsegvHdlr; + sigaction(SIGABRT, &sigAct, NULL); + sigAct.sa_handler = doDie; + sigaction(SIGTERM, &sigAct, NULL); + sigAct.sa_handler = Debug ? doDie : SIG_IGN; + sigaction(SIGINT, &sigAct, NULL); + sigaction(SIGQUIT, &sigAct, NULL); + sigAct.sa_handler = reapchild; + sigaction(SIGCHLD, &sigAct, NULL); + sigAct.sa_handler = Debug ? debug_switch : SIG_IGN; + sigaction(SIGUSR1, &sigAct, NULL); + sigAct.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &sigAct, NULL); + sigaction(SIGXFSZ, &sigAct, NULL); /* do not abort if 2gig file limit is hit */ + + RETiRet; +} + + /* This is the main entry point into rsyslogd. Over time, we should try to * modularize it a bit more... */ @@ -2975,14 +3117,11 @@ int realMain(int argc, char **argv) { DEFiRet; - register int i; register uchar *p; - int num_fds; int ch; struct hostent *hent; extern int optind; extern char *optarg; - struct sigaction sigAct; int bEOptionWasGiven = 0; int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */ char *arg; /* for command line option processing */ @@ -3004,7 +3143,7 @@ int realMain(int argc, char **argv) * only when actually neeeded. * rgerhards, 2008-04-04 */ - while ((ch = getopt(argc, argv, "46aAc:def:g:hi:l:m:M:nopqQr::s:t:u:vwx")) != EOF) { + while ((ch = getopt(argc, argv, "46aAc:def:g:hi:l:m:M:nN:opqQr::s:t:u:vwx")) != EOF) { switch((char)ch) { case '4': case '6': @@ -3016,6 +3155,7 @@ int realMain(int argc, char **argv) case 'l': case 'm': /* mark interval */ case 'n': /* don't fork */ + case 'N': /* enable config verify mode */ case 'o': case 'p': case 'q': /* add hostname if DNS resolving has failed */ @@ -3214,6 +3354,11 @@ int realMain(int argc, char **argv) case 'n': /* don't fork */ NoFork = 1; break; + case 'N': /* enable config verify mode */ +RUNLOG; + iConfigVerify = atoi(arg); +RUNLOG; + break; case 'o': if(iCompatibilityMode < 3) { if(!bImUxSockLoaded) { @@ -3282,6 +3427,11 @@ int realMain(int argc, char **argv) if(iRet != RS_RET_END_OF_LINKEDLIST) FINALIZE; + if(iConfigVerify) { + fprintf(stderr, "rsyslogd: version %s, config validation run (level %d), master config %s\n", + VERSION, iConfigVerify, ConfFile); + } + /* process compatibility mode settings */ if(iCompatibilityMode < 3) { errmsg.LogError(0, NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically " @@ -3305,86 +3455,10 @@ int realMain(int argc, char **argv) "more and cast your vote if you want us to keep this feature."); } - checkPermissions(); - thrdInit(); - - if( !(Debug || NoFork) ) - { - dbgprintf("Checking pidfile.\n"); - if (!check_pid(PidFile)) - { - memset(&sigAct, 0, sizeof (sigAct)); - sigemptyset(&sigAct.sa_mask); - sigAct.sa_handler = doexit; - sigaction(SIGTERM, &sigAct, NULL); - - if (fork()) { - /* - * Parent process - */ - sleep(300); - /* - * Not reached unless something major went wrong. 5 - * minutes should be a fair amount of time to wait. - * Please note that this procedure is important since - * the father must not exit before syslogd isn't - * initialized or the klogd won't be able to flush its - * logs. -Joey - */ - exit(1); /* "good" exit - after forking, not diasabling anything */ - } - num_fds = getdtablesize(); - for (i= 0; i < num_fds; i++) - (void) close(i); - untty(); - } - else - { - fputs(" Already running.\n", stderr); - exit(1); /* "good" exit, done if syslogd is already running */ - } - } - else - debugging_on = 1; - - /* tuck my process id away */ - dbgprintf("Writing pidfile %s.\n", PidFile); - if (!check_pid(PidFile)) - { - if (!write_pid(PidFile)) - { - fputs("Can't write pid.\n", stderr); - exit(1); /* exit during startup - questionable */ - } - } - else - { - fputs("Pidfile (and pid) already exist.\n", stderr); - exit(1); /* exit during startup - questionable */ - } - myPid = getpid(); /* save our pid for further testing (also used for messages) */ - - memset(&sigAct, 0, sizeof (sigAct)); - sigemptyset(&sigAct.sa_mask); - - sigAct.sa_handler = sigsegvHdlr; - sigaction(SIGSEGV, &sigAct, NULL); - sigAct.sa_handler = sigsegvHdlr; - sigaction(SIGABRT, &sigAct, NULL); - sigAct.sa_handler = doDie; - sigaction(SIGTERM, &sigAct, NULL); - sigAct.sa_handler = Debug ? doDie : SIG_IGN; - sigaction(SIGINT, &sigAct, NULL); - sigaction(SIGQUIT, &sigAct, NULL); - sigAct.sa_handler = reapchild; - sigaction(SIGCHLD, &sigAct, NULL); - sigAct.sa_handler = Debug ? debug_switch : SIG_IGN; - sigaction(SIGUSR1, &sigAct, NULL); - sigAct.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &sigAct, NULL); - sigaction(SIGXFSZ, &sigAct, NULL); /* do not abort if 2gig file limit is hit */ + if(!iConfigVerify) + CHKiRet(doGlblProcessInit()); - mainThread(); + CHKiRet(mainThread()); /* do any de-init's that need to be done AFTER this comment */ @@ -3393,9 +3467,12 @@ int realMain(int argc, char **argv) thrdExit(); finalize_it: - if(iRet != RS_RET_OK) - fprintf(stderr, "rsyslogd run failed with error %d\n(see rsyslog.h " - "or http://www.rsyslog.com/errcode to learn what that number means)\n", iRet); + if(iRet == RS_RET_VALIDATION_RUN) { + fprintf(stderr, "rsyslogd: End of config validation run. Bye.\n"); + } else if(iRet != RS_RET_OK) { + fprintf(stderr, "rsyslogd run failed with error %d (see rsyslog.h " + "or try http://www.rsyslog.com/e/%d to learn what that number means)\n", iRet, iRet*-1); + } ENDfunc return 0; -- cgit v1.2.3 From c3c385c63b627d559bdd7a7a710c543e9c16a20a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 29 Jul 2008 14:55:44 +0200 Subject: added testbed for config errors and fixed a bug - bugfix: no error was reported if the target of a $IncludeConfig could not be accessed. - added testbed for common config errors --- tools/syslogd.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index d023ec39..5bdaa679 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3124,6 +3124,8 @@ int realMain(int argc, char **argv) extern char *optarg; int bEOptionWasGiven = 0; int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */ + int iHelperUOpt; + int bChDirRoot = 1; /* change the current working directory to "/"? */ char *arg; /* for command line option processing */ uchar legacyConfLine[80]; uchar *LocalHostName; @@ -3143,7 +3145,7 @@ int realMain(int argc, char **argv) * only when actually neeeded. * rgerhards, 2008-04-04 */ - while ((ch = getopt(argc, argv, "46aAc:def:g:hi:l:m:M:nN:opqQr::s:t:u:vwx")) != EOF) { + while((ch = getopt(argc, argv, "46aAc:def:g:hi:l:m:M:nN:opqQr::s:t:u:vwx")) != EOF) { switch((char)ch) { case '4': case '6': @@ -3219,9 +3221,6 @@ int realMain(int argc, char **argv) ppid = getpid(); - if(chdir ("/") != 0) - fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); - CHKiRet_Hdlr(InitGlobalClasses()) { fprintf(stderr, "rsyslogd initializiation failed - global classes could not be initialized.\n" "Did you do a \"make install\"?\n" @@ -3355,9 +3354,7 @@ int realMain(int argc, char **argv) NoFork = 1; break; case 'N': /* enable config verify mode */ -RUNLOG; iConfigVerify = atoi(arg); -RUNLOG; break; case 'o': if(iCompatibilityMode < 3) { @@ -3409,8 +3406,11 @@ RUNLOG; fprintf(stderr, "-t option only supported in compatibility modes 0 to 2 - ignored\n"); break; case 'u': /* misc user settings */ - if(atoi(arg) == 1) + iHelperUOpt = atoi(arg); + if(iHelperUOpt & 0x01) bParseHOSTNAMEandTAG = 0; + if(iHelperUOpt & 0x02) + bChDirRoot = 0; break; case 'w': /* disable disallowed host warnigs */ glbl.SetOption_DisallowWarning(0); @@ -3432,6 +3432,12 @@ RUNLOG; VERSION, iConfigVerify, ConfFile); } + if(bChDirRoot) { + if(chdir("/") != 0) + fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); + } + + /* process compatibility mode settings */ if(iCompatibilityMode < 3) { errmsg.LogError(0, NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically " -- cgit v1.2.3 From d7bc0f1f1e81ca0fa678b945962574112df949bc Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 12 Aug 2008 10:46:58 +0200 Subject: some very minor cleanup --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5bdaa679..ad28ff22 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2685,7 +2685,6 @@ static rsRetVal loadBuildInModules(void) * is that rsyslog will terminate if we can not register our built-in config commands. * This, I think, is the right thing to do. -- rgerhards, 2007-07-31 */ -// CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, NULL, &pszWorkDir, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL)); -- cgit v1.2.3 From 1a9ac0ced72dd163228438af4f31f233fab20529 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 2 Sep 2008 11:38:31 +0200 Subject: removed compile time fixed message size limit (was 2K) The limit can now be set via $MaxMessageSize global config directive (finally gotten rid of MAXLINE ;)) --- tools/syslogd.c | 79 +++++++++++++++++++++++++++------------------------------ 1 file changed, 38 insertions(+), 41 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 758d5ed1..bf42a7ef 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -58,34 +58,6 @@ #include "config.h" #include "rsyslog.h" -/* change the following setting to e.g. 32768 if you would like to - * support large message sizes for IHE (32k is the current maximum - * needed for IHE). I was initially tempted to increase it to 32k, - * but there is a large memory footprint with the current - * implementation in rsyslog. This will change as the processing - * changes, but I have re-set it to 1k, because the vast majority - * of messages is below that and the memory savings is huge, at - * least compared to the overall memory footprint. - * - * If you intend to receive Windows Event Log data (e.g. via - * EventReporter - www.eventreporter.com), you might want to - * increase this number to an even higher value, as event - * log messages can be very lengthy. - * rgerhards, 2005-07-05 - * - * during my recent testing, it showed that 4k seems to be - * the typical maximum for UDP based syslog. This is a IP stack - * restriction. Not always ... but very often. If you go beyond - * that value, be sure to test that rsyslogd actually does what - * you think it should do ;) Also, it is a good idea to check the - * doc set for anything on IHE - it most probably has information on - * message sizes. - * rgerhards, 2005-08-05 - * - * I have increased the default message size to 2048 to be in sync - * with recent IETF syslog standardization efforts. - * rgerhards, 2006-11-30 - */ #define DEFUPRI (LOG_USER|LOG_NOTICE) #define TIMERINTVL 30 /* interval for checking flush, mark */ @@ -708,9 +680,10 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa uchar *pMsg; uchar *pData; uchar *pEnd; - uchar tmpline[MAXLINE + 1]; + int iMaxLine; + uchar *tmpline = NULL; # ifdef USE_NETZIP - uchar deflateBuf[MAXLINE + 1]; + uchar *deflateBuf = NULL; uLongf iLenDefBuf; # endif @@ -719,6 +692,18 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa assert(msg != NULL); assert(len >= 0); + /* we first allocate work buffers large enough to hold the configured maximum + * size of a message. Over time, we should change this to a more optimal way, i.e. + * by calling the function with the actual length of the message to be parsed. + * rgerhards, 2008-09-02 + * + * TODO: optimize buffer handling */ + iMaxLine = glbl.GetMaxLine(); + CHKmalloc(tmpline = malloc(sizeof(uchar) * (iMaxLine + 1))); +# ifdef USE_NETZIP + CHKmalloc(deflateBuf = malloc(sizeof(uchar) * (iMaxLine + 1))); +# endif + /* we first check if we have a NUL character at the very end of the * message. This seems to be a frequent problem with a number of senders. * So I have now decided to drop these NULs. However, if they are intentional, @@ -755,14 +740,14 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa */ if(len > 0 && *msg == 'z') { /* compressed data present? (do NOT change order if conditions!) */ /* we have compressed data, so let's deflate it. We support a maximum - * message size of MAXLINE. If it is larger, an error message is logged + * message size of iMaxLine. If it is larger, an error message is logged * and the message is dropped. We do NOT try to decompress larger messages * as such might be used for denial of service. It might happen to later * builds that such functionality be added as an optional, operator-configurable * feature. */ int ret; - iLenDefBuf = MAXLINE; + iLenDefBuf = iMaxLine; ret = uncompress((uchar *) deflateBuf, &iLenDefBuf, (uchar *) msg+1, len-1); dbgprintf("Compressed message uncompressed with status %d, length: new %ld, old %d.\n", ret, (long) iLenDefBuf, len-1); @@ -795,11 +780,11 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa # endif /* ifdef USE_NETZIP */ while(pData < pEnd) { - if(iMsg >= MAXLINE) { + if(iMsg >= iMaxLine) { /* emergency, we now need to flush, no matter if * we are at end of message or not... */ - if(iMsg == MAXLINE) { + if(iMsg == iMaxLine) { *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType); } else { @@ -810,7 +795,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa * (I couldn't do any more smart things anyway...). * rgerhards, 2007-9-20 */ - dbgprintf("internal error: iMsg > MAXLINE in printchopped()\n"); + dbgprintf("internal error: iMsg > max msg size in printchopped()\n"); } FINALIZE; /* in this case, we are done... nothing left we can do */ } @@ -818,7 +803,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa /* changed to the sequence (somewhat) proposed in * draft-ietf-syslog-protocol-19. rgerhards, 2006-11-30 */ - if(iMsg + 3 < MAXLINE) { /* do we have space? */ + if(iMsg + 3 < iMaxLine) { /* do we have space? */ *(pMsg + iMsg++) = cCCEscapeChar; *(pMsg + iMsg++) = '0'; *(pMsg + iMsg++) = '0'; @@ -838,7 +823,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa * we known now what's going on. * rgerhards, 2007-07-17 */ - if(iMsg + 3 < MAXLINE) { /* do we have space? */ + if(iMsg + 3 < iMaxLine) { /* do we have space? */ *(pMsg + iMsg++) = cCCEscapeChar; *(pMsg + iMsg++) = '0' + ((*pData & 0300) >> 6); *(pMsg + iMsg++) = '0' + ((*pData & 0070) >> 3); @@ -856,6 +841,12 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType); finalize_it: + if(tmpline != NULL) + free(tmpline); +# ifdef USE_NETZIP + if(deflateBuf != NULL) + free(deflateBuf); +# endif RETiRet; } @@ -2001,16 +1992,21 @@ static void doexit() } -/* set the action resume interval - */ +/* set the maximum message size */ +static rsRetVal setMaxMsgSize(void __attribute__((unused)) *pVal, int iNewVal) +{ + return glbl.SetMaxLine(iNewVal); +} + + +/* set the action resume interval */ static rsRetVal setActionResumeInterval(void __attribute__((unused)) *pVal, int iNewVal) { return actionSetGlobalResumeInterval(iNewVal); } -/* set the processes umask (upon configuration request) - */ +/* set the processes umask (upon configuration request) */ static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask) { umask(iUmask); @@ -2726,6 +2722,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &bErrMsgToStderr, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, setMaxMsgSize, NULL, NULL)); /* now add other modules handlers (we should work on that to be able to do it in ClassInit(), but so far * that is not possible). -- rgerhards, 2008-01-28 -- cgit v1.2.3 From 262f61d869b95f63b393ae48d683b13e70322478 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 10 Sep 2008 15:59:53 +0200 Subject: added properties "inputname" and "$myhostname" - added message property "inputname", which contains the name of the input (module) that generated it. Presence is depending on suport in each input module (else it is blank). - added system property "$myhostname", which contains the name of the local host as it knows itself. --- tools/syslogd.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index bf42a7ef..96fbee05 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -576,8 +576,14 @@ void untty(void) * rgerhards, 2008-05-16: * I added an additional calling parameter (hnameIP) to enable specifying the IP * of a remote host. + * + * rgerhards, 2008-09-11: + * Interface change: added new parameter "InputName", permits the input to provide + * a string that identifies it. May be NULL, but must be a valid char* pointer if + * non-NULL. */ -rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int bParseHost, int flags, flowControl_t flowCtlType) +rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int bParseHost, int flags, flowControl_t flowCtlType, + uchar *pszInputName) { DEFiRet; register uchar *p; @@ -586,6 +592,8 @@ rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int bParseHost, int /* Now it is time to create the message object (rgerhards) */ CHKiRet(msgConstruct(&pMsg)); + if(pszInputName != NULL) + MsgSetInputName(pMsg, (char*) pszInputName); MsgSetFlowControlType(pMsg, flowCtlType); MsgSetRawMsg(pMsg, (char*)msg); @@ -671,9 +679,15 @@ finalize_it: * rgerhards, 2008-05-16: * I added an additional calling parameter (hnameIP) to enable specifying the IP * of a remote host. + * + * rgerhards, 2008-09-11: + * Interface change: added new parameter "InputName", permits the input to provide + * a string that identifies it. May be NULL, but must be a valid char* pointer if + * non-NULL. */ rsRetVal -parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType) +parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType, + uchar *pszInputName) { DEFiRet; register int iMsg; @@ -786,7 +800,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa */ if(iMsg == iMaxLine) { *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ - printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType); + printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName); } else { /* This case in theory never can happen. If it happens, we have * a logic error. I am checking for it, because if I would not, @@ -838,7 +852,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int bPa *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ /* typically, we should end up here! */ - printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType); + printline(hname, hnameIP, tmpline, bParseHost, flags, flowCtlType, pszInputName); finalize_it: if(tmpline != NULL) @@ -881,6 +895,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) DEFiRet; CHKiRet(msgConstruct(&pMsg)); + MsgSetInputName(pMsg, "rsyslogd"); MsgSetUxTradMsg(pMsg, (char*)msg); MsgSetRawMsg(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName()); -- cgit v1.2.3 From 760e5f0d3986aa93a07e207dde3206741ec3ad74 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Sep 2008 11:56:07 +0200 Subject: performance optimization: unnecessary time() calls during message parsing removed thanks to David Lang for his excellent performance analysis --- tools/syslogd.c | 52 ++++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 24 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 0f3e7dea..f9c3965d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -873,7 +873,7 @@ rsRetVal submitErrMsg(int iErr, uchar *msg) { DEFiRet; - iRet = logmsgInternal(iErr, LOG_SYSLOG|LOG_ERR, msg, ADDDATE); + iRet = logmsgInternal(iErr, LOG_SYSLOG|LOG_ERR, msg, 0); RETiRet; } @@ -1331,14 +1331,15 @@ static int parseRFCSyslogMsg(msg_t *pMsg, int flags) */ /* TIMESTAMP */ - if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == FALSE) { + datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* initialize timestamp */ + if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { + if(flags & IGNDATE) { + /* we need to ignore the msg data, so simply copy over reception date */ + datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ + } + } else { dbgprintf("no TIMESTAMP detected!\n"); bContParse = 0; - flags |= ADDDATE; - } - - if (flags & ADDDATE) { - datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ } /* HOSTNAME */ @@ -1405,21 +1406,26 @@ static int parseLegacySyslogMsg(msg_t *pMsg, int flags) cstr_t *pStrB; int iCnt; int bTAGCharDetected; + BEGINfunc assert(pMsg != NULL); assert(pMsg->pszUxTradMsg != NULL); p2parse = (char*) pMsg->pszUxTradMsg; - /* Check to see if msg contains a timestamp. We stary trying with a - * high-precision one... + /* Check to see if msg contains a timestamp. We start by assuming + * that the message timestamp is the time of reciption (which we + * generated ourselfs and then try to actually find one inside the + * message. There we go from high-to low precison and are done + * when we find a matching one. -- rgerhards, 2008-09-16 */ - if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == TRUE) { + memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); + if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { /* we are done - parse pointer is moved by ParseTIMESTAMP3339 */; - } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse) == TRUE) { + } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */; } else if(*p2parse == ' ') { /* try to see if it is slighly malformed - HP procurve seems to do that sometimes */ ++p2parse; /* move over space */ - if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse) == TRUE) { + if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { /* indeed, we got it! */ /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */; } else { @@ -1427,19 +1433,12 @@ static int parseLegacySyslogMsg(msg_t *pMsg, int flags) * for this try. */ --p2parse; - flags |= ADDDATE; } - } else { - flags |= ADDDATE; } - /* here we need to check if the timestamp is valid. If it is not, - * we can not continue to parse but must treat the rest as the - * MSG part of the message (as of RFC 3164). - * rgerhards 2004-12-03 - */ - if(flags & ADDDATE) { - datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ + if(flags & IGNDATE) { + /* we need to ignore the msg data, so simply copy over reception date */ + memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); } /* rgerhards, 2006-03-13: next, we parse the hostname and tag. But we @@ -1575,6 +1574,7 @@ static int parseLegacySyslogMsg(msg_t *pMsg, int flags) /* The rest is the actual MSG */ MsgSetMSG(pMsg, p2parse); + ENDfunc return 0; /* all ok */ } @@ -1687,6 +1687,10 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) BEGINfunc LockObj(pAction); + /* TODO: time() performance: the call below could be moved to + * the beginn of the llExec(). This makes it slightly less correct, but + * in an acceptable way. -- rgerhards, 2008-09-16 + */ if (pAction->f_prevcount && time(NULL) >= REPEATTIME(pAction)) { dbgprintf("flush %s: repeated %d times, %d sec.\n", module.GetStateName(pAction->pMod), pAction->f_prevcount, @@ -1936,7 +1940,7 @@ die(int sig) "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.", (int) myPid, sig); errno = 0; - logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, ADDDATE); + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); } /* drain queue (if configured so) and stop main queue worker thread pool */ @@ -2424,7 +2428,7 @@ init(void) " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] restart", (int) myPid); - logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, ADDDATE); + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, 0); memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); -- cgit v1.2.3 From 19ac72a36859ea267fbf4e2e640a5499c6276e07 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Sep 2008 13:12:50 +0200 Subject: fixing previous patch, time() call was accidently left in in one case, which was not on the focus of the initial testing cases. --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f9c3965d..f51947bf 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1331,11 +1331,11 @@ static int parseRFCSyslogMsg(msg_t *pMsg, int flags) */ /* TIMESTAMP */ - datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* initialize timestamp */ + memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { if(flags & IGNDATE) { /* we need to ignore the msg data, so simply copy over reception date */ - datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ + memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); } } else { dbgprintf("no TIMESTAMP detected!\n"); -- cgit v1.2.3 From bcb97650683bbcb1ecdacd0c2a6052ef836d3eda Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Sep 2008 14:57:12 +0200 Subject: consolidated time() calls in rule engine ... but did not manage to avoid doing at least one call. So this change introduced performance benefit only in a few non-common situations. Anyhow, it hopefully levels ground for better things to come. --- tools/syslogd.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f51947bf..b6e1d826 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1167,9 +1167,6 @@ processMsg(msg_t *pMsg) /* The consumer of dequeued messages. This function is called by the * queue engine on dequeueing of a message. It runs on a SEPARATE * THREAD. - * NOTE: Having more than one worker requires guarding of some - * message object structures and potentially others - need to be checked - * before we support multiple worker threads on the message queue. * Please note: the message object is destructed by the queue itself! */ static rsRetVal -- cgit v1.2.3 From 4c96ebdcfe075e80810b01257cf21ea1c9b3ec0e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 18 Sep 2008 12:19:33 +0200 Subject: bugfix: potential race condition when adding messages to queue There was a wrong order of mutex lock operations. It is hard to believe that really caused problems, but in theory it could and with threading we often see that theory becomes practice if something is only used long enough on a fast enough machine with enough CPUs ;) --- tools/syslogd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b6e1d826..3a637dd8 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2832,9 +2832,8 @@ static rsRetVal mainThread() CHKiRet(init()); - if(Debug) { + if(Debug && debugging_on) { dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); - debugging_on = 1; } /* Send a signal to the parent so it can terminate. */ @@ -3082,9 +3081,9 @@ doGlblProcessInit(void) fputs(" Already running.\n", stderr); exit(1); /* "good" exit, done if syslogd is already running */ } - } - else + } else { debugging_on = 1; + } /* tuck my process id away */ dbgprintf("Writing pidfile %s.\n", PidFile); -- cgit v1.2.3 From dc44f5a475101aa18568a0eaceacc2a4eb718391 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 26 Sep 2008 13:40:41 +0200 Subject: cleaned up internal debug system code and made it behave better in regard to multi-threading --- tools/syslogd.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3a637dd8..a39f5a5c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1871,16 +1871,22 @@ void legacyOptsParseTCP(char ch, char *arg) * a minimal delay, but it is much cleaner than the approach of doing everything * inside the signal handler. * rgerhards, 2005-10-26 + * Note: we do not call dbgprintf() as this may cause us to block in case something + * with the threading is wrong. */ static void doDie(int sig) { +# define MSG1 "DoDie called.\n" +# define MSG2 "DoDie called 5 times - unconditional exit\n" static int iRetries = 0; /* debug aid */ - printf("DoDie called.\n"); + write(1, MSG1, sizeof(MSG1)); if(iRetries++ == 4) { - printf("DoDie called 5 times - unconditional exit\n"); + write(1, MSG2, sizeof(MSG2)); abort(); } bFinished = sig; +# undef MSG1 +# undef MSG2 } -- cgit v1.2.3 From 02bb3c901d9b14e8a08b111dde151f1ed4d2d1da Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 2 Oct 2008 15:52:24 +0200 Subject: consolidated time calls during msg object creation ...this improves performance and consistency and also fixes a bug where subsecond time properties generated by imfile, imklog and internal messages could be slightly inconsistent. --- tools/syslogd.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a39f5a5c..7a99fc1d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -914,7 +914,6 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) pMsg->iFacility = LOG_FAC(pri); pMsg->iSeverity = LOG_PRI(pri); pMsg->bParseHOSTNAME = 0; - datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ flags |= INTERNAL_MSG; /* we now check if we should print internal messages out to stderr. This was @@ -1328,7 +1327,6 @@ static int parseRFCSyslogMsg(msg_t *pMsg, int flags) */ /* TIMESTAMP */ - memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { if(flags & IGNDATE) { /* we need to ignore the msg data, so simply copy over reception date */ @@ -1415,7 +1413,6 @@ static int parseLegacySyslogMsg(msg_t *pMsg, int flags) * message. There we go from high-to low precison and are done * when we find a matching one. -- rgerhards, 2008-09-16 */ - memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { /* we are done - parse pointer is moved by ParseTIMESTAMP3339 */; } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { -- cgit v1.2.3 From 44e35af7a851ce920d4db312acd9a2cdf516a81c Mon Sep 17 00:00:00 2001 From: varmojfekoj Date: Wed, 10 Dec 2008 15:24:48 +0100 Subject: some legacy options were not correctly processed Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 7a99fc1d..fd34c9f5 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -391,8 +391,9 @@ static void processImInternal(void); static int usage(void) { - fprintf(stderr, "usage: rsyslogd [-cversion] [-46AdnqQvwx] [-lhostlist] [-sdomainlist]\n" - " [-fconffile] [-ipidfile] [-Nlevel]\n" + fprintf(stderr, "usage: rsyslogd [-c] [-46AdnqQvwx] [-l] [-s]\n" + " [-f] [-i] [-N] [-M]\n" + " [-u]\n" "To run rsyslogd in native mode, use \"rsyslogd -c3 \"\n\n" "For further information see http://www.rsyslog.com/doc\n"); exit(1); /* "good" exit - done to terminate usage() */ @@ -3164,7 +3165,7 @@ int realMain(int argc, char **argv) * only when actually neeeded. * rgerhards, 2008-04-04 */ - while((ch = getopt(argc, argv, "46aAc:def:g:hi:l:m:M:nN:opqQr::s:t:u:vwx")) != EOF) { + while((ch = getopt(argc, argv, "46a:Ac:def:g:hi:l:m:M:nN:op:qQr::s:t:u:vwx")) != EOF) { switch((char)ch) { case '4': case '6': -- cgit v1.2.3 From e2ffeb19f9c2962fd711e28d50ce0d51ae3bbc45 Mon Sep 17 00:00:00 2001 From: varmojfekoj Date: Thu, 15 Jan 2009 12:59:21 +0100 Subject: bugfix: the string "Do Die" was accidently emited upon exit in non-debug mode Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index fd34c9f5..bc1f71d3 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1877,9 +1877,11 @@ static void doDie(int sig) # define MSG1 "DoDie called.\n" # define MSG2 "DoDie called 5 times - unconditional exit\n" static int iRetries = 0; /* debug aid */ - write(1, MSG1, sizeof(MSG1)); + if(Debug || NoFork) + write(1, MSG1, sizeof(MSG1) - 1); if(iRetries++ == 4) { - write(1, MSG2, sizeof(MSG2)); + if(Debug || NoFork) + write(1, MSG2, sizeof(MSG2) - 1); abort(); } bFinished = sig; -- cgit v1.2.3 From ead2c355e3261f98817ccd52bc3644103140e824 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 26 Jan 2009 22:30:55 +0100 Subject: bugfix: unitialized mutex was used in msg.c:getPRI This was subtle, because getPRI is called as part of the debugging code (always executed) in syslogd.c:logmsg. --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 2cac8fe4..f0d63932 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2431,6 +2431,7 @@ init(void) ABORT_FINALIZE(RS_RET_VALIDATION_RUN); /* switch the message object to threaded operation, if necessary */ +/* TODO:XXX: I think we must do this also if we have action queues! -- rgerhards, 2009-01-26 */ if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) { MsgEnableThreadSafety(); } -- cgit v1.2.3 From 82d7abc1f4b03f37ff94c5f184d49502b6cf489b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 30 Jan 2009 13:41:12 +0100 Subject: bugfix: invalid mutex access in msg.c --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b32ce029..2c66daac 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1607,7 +1607,7 @@ logmsg(msg_t *pMsg, int flags) assert(pMsg != NULL); assert(pMsg->pszUxTradMsg != NULL); msg = (char*) pMsg->pszUxTradMsg; - dbgprintf("logmsg: flags %x, pri %s, from '%s', msg %s\n", flags, getPRI(pMsg), getRcvFrom(pMsg), msg); + dbgprintf("logmsg: flags %x, from '%s', msg %s\n", flags, getRcvFrom(pMsg), msg); /* rger 2005-11-24 (happy thanksgiving!): we now need to check if we have * a traditional syslog message or one formatted according to syslog-protocol. -- cgit v1.2.3 From 25245cc682bd1a4854cc8b33e301bb4f0cb48fc6 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 30 Jan 2009 15:40:53 +0100 Subject: added info if atomic ops are available to rsyslogd -v output --- tools/syslogd.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 1447d868..b0d6fa25 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2792,6 +2792,11 @@ static void printVersion(void) #else printf("\tFEATURE_DEBUG (debug build, slow code):\tNo\n"); #endif +#ifdef HAVE_ATOMIC_BUILTINS + printf("\tAtomic operations supported:\t\tYes\n"); +#else + printf("\tAtomic operations supported:\t\tNo\n"); +#endif #ifdef RTINST printf("\tRuntime Instrumentation (slow code):\tYes\n"); #else -- cgit v1.2.3 From 5005bce38763051b5b12e48ac60c3ff17097a952 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 4 Mar 2009 18:22:48 +0100 Subject: added ERE support in filter conditions new comparison operation "ereregex" --- tools/syslogd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 9ced4562..6b8ce82f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1071,7 +1071,12 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce break; case FIOP_REGEX: if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue, - (unsigned char*) pszPropVal) == 0) + (unsigned char*) pszPropVal, 0) == RS_RET_OK) + bRet = 1; + break; + case FIOP_EREREGEX: + if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue, + (unsigned char*) pszPropVal, 1) == RS_RET_OK) bRet = 1; break; default: -- cgit v1.2.3 From 2e388db9ac91eae35ac836b329c8bcadd319a409 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 5 Mar 2009 11:10:43 +0100 Subject: integrated various patches for solaris Unfortunatley, I do not have the full list of contributors available. The patch set was compiled by Ben Taylor, and I made some further changes to adopt it to the news rsyslog branch. Others provided much of the base work, but I can not find the names of the original authors. If you happen to be one of them, please let me know so that I can give proper credits. --- tools/syslogd.c | 63 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 29 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 6b8ce82f..63c4b249 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -72,13 +72,18 @@ #include #include #include -#include -#ifdef __sun +#ifdef OS_SOLARIS # include +# include +# include +# include +# include #else +# include # include #endif + #include #include #include @@ -279,7 +284,7 @@ static int gidDropPriv = 0; /* group-id to which priveleges should be dropped to extern int errno; /* main message queue and its configuration parameters */ -static queue_t *pMsgQueue = NULL; /* the main message queue */ +static qqueue_t *pMsgQueue = NULL; /* the main message queue */ static int iMainMsgQueueSize = 10000; /* size of the main message queue above */ static int iMainMsgQHighWtrMark = 8000; /* high water mark for disk-assisted queues */ static int iMainMsgQLowWtrMark = 2000; /* low water mark for disk-assisted queues */ @@ -1620,7 +1625,7 @@ submitMsg(msg_t *pMsg) ISOBJ_TYPE_assert(pMsg, msg); MsgPrepareEnqueue(pMsg); - queueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg); + qqueueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg); RETiRet; } @@ -1681,7 +1686,7 @@ logmsg(msg_t *pMsg, int flags) /* now submit the message to the main queue - then we are done */ pMsg->msgFlags = flags; MsgPrepareEnqueue(pMsg); - queueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg); + qqueueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg); ENDfunc } @@ -1979,7 +1984,7 @@ die(int sig) /* drain queue (if configured so) and stop main queue worker thread pool */ dbgprintf("Terminating main queue...\n"); - queueDestruct(&pMsgQueue); + qqueueDestruct(&pMsgQueue); pMsgQueue = NULL; /* Free ressources and close connections. This includes flushing any remaining @@ -2269,8 +2274,8 @@ static void dbgPrintInitInfo(void) static int iMainMsgQtoWrkMinMsgs = 100; static int iMainMsgQbSaveOnShutdown = 1; iMainMsgQueMaxDiskSpace = 0; - setQPROP(queueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100); - setQPROP(queueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", 1); + setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100); + setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", 1); */ dbgprintf("Work Directory: '%s'.\n", glbl.GetWorkDir()); } @@ -2332,7 +2337,7 @@ init(void) /* delete the message queue, which also flushes all messages left over */ if(pMsgQueue != NULL) { dbgprintf("deleting main message queue\n"); - queueDestruct(&pMsgQueue); /* delete pThis here! */ + qqueueDestruct(&pMsgQueue); /* delete pThis here! */ pMsgQueue = NULL; } @@ -2444,7 +2449,7 @@ init(void) } /* create message queue */ - CHKiRet_Hdlr(queueConstruct(&pMsgQueue, MainMsgQueType, iMainMsgQueueNumWorkers, iMainMsgQueueSize, msgConsumer)) { + CHKiRet_Hdlr(qqueueConstruct(&pMsgQueue, MainMsgQueType, iMainMsgQueueNumWorkers, iMainMsgQueueSize, msgConsumer)) { /* no queue is fatal, we need to give up in that case... */ fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); exit(1); @@ -2462,29 +2467,29 @@ init(void) errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ } - setQPROP(queueSetMaxFileSize, "$MainMsgQueueFileSize", iMainMsgQueMaxFileSize); - setQPROP(queueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", iMainMsgQueMaxDiskSpace); - setQPROPstr(queueSetFilePrefix, "$MainMsgQueueFileName", pszMainMsgQFName); - setQPROP(queueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", iMainMsgQPersistUpdCnt); - setQPROP(queueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", iMainMsgQtoQShutdown ); - setQPROP(queueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", iMainMsgQtoActShutdown); - setQPROP(queueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", iMainMsgQtoWrkShutdown); - setQPROP(queueSettoEnq, "$MainMsgQueueTimeoutEnqueue", iMainMsgQtoEnq); - setQPROP(queueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark); - setQPROP(queueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark); - setQPROP(queueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark); - setQPROP(queueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity); - setQPROP(queueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); - setQPROP(queueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); - setQPROP(queueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", iMainMsgQDeqSlowdown); - setQPROP(queueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", iMainMsgQueueDeqtWinFromHr); - setQPROP(queueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", iMainMsgQueueDeqtWinToHr); + setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", iMainMsgQueMaxFileSize); + setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", iMainMsgQueMaxDiskSpace); + setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", pszMainMsgQFName); + setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", iMainMsgQPersistUpdCnt); + setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", iMainMsgQtoQShutdown ); + setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", iMainMsgQtoActShutdown); + setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", iMainMsgQtoWrkShutdown); + setQPROP(qqueueSettoEnq, "$MainMsgQueueTimeoutEnqueue", iMainMsgQtoEnq); + setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark); + setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark); + setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark); + setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity); + setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); + setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); + setQPROP(qqueueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", iMainMsgQDeqSlowdown); + setQPROP(qqueueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", iMainMsgQueueDeqtWinFromHr); + setQPROP(qqueueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", iMainMsgQueueDeqtWinToHr); # undef setQPROP # undef setQPROPstr /* ... and finally start the queue! */ - CHKiRet_Hdlr(queueStart(pMsgQueue)) { + CHKiRet_Hdlr(qqueueStart(pMsgQueue)) { /* no queue is fatal, we need to give up in that case... */ fprintf(stderr, "fatal error %d: could not start message queue - rsyslogd can not run!\n", iRet); exit(1); @@ -3093,7 +3098,7 @@ GlobalClassExit(void) CHKiRet(strmClassInit(NULL)); CHKiRet(wtiClassInit(NULL)); CHKiRet(wtpClassInit(NULL)); - CHKiRet(queueClassInit(NULL)); + CHKiRet(qqueueClassInit(NULL)); CHKiRet(vmstkClassInit(NULL)); CHKiRet(sysvarClassInit(NULL)); CHKiRet(vmClassInit(NULL)); -- cgit v1.2.3 From 59192611db992e7357337beb8e68ec6cee5b3fec Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 10 Mar 2009 22:36:40 +0100 Subject: bugfix: parser did not correctly parse fields in UDP-received messages --- tools/syslogd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 6b8ce82f..eb496521 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1335,6 +1335,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) char *pBuf; int bContParse = 1; + BEGINfunc assert(pMsg != NULL); assert(pMsg->pszUxTradMsg != NULL); p2parse = (char*) pMsg->pszUxTradMsg; @@ -1408,6 +1409,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) MsgSetMSG(pMsg, p2parse); free(pBuf); + ENDfunc return 0; /* all ok */ } -- cgit v1.2.3 From 8e3c5a9ca3732a41fbb8581b13c49acd699820da Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 6 Apr 2009 17:55:04 +0200 Subject: improved internal handling of RainerScript functions - building the necessary plumbing to support more functions with decent runtime performance. This is also necessary towards the long-term goal of loadable library modules. - added new RainerScript function "tolower" --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b23c12a7..c85c4371 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3091,6 +3091,7 @@ GlobalClassExit(void) objRelease(net, LM_NET_FILENAME);/* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ objRelease(conf, CORE_COMPONENT); objRelease(expr, CORE_COMPONENT); + vmClassExit(); /* this is hack, currently core_modules do not get this automatically called */ objRelease(vm, CORE_COMPONENT); objRelease(var, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); -- cgit v1.2.3 From bbfa04fbe63f1bbb47f5cdc683045cf2775b3977 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 19 Mar 2009 17:50:07 +0100 Subject: improved testing support worked on ways to provide a better test suite: - added -T rsyslogd command line option, enables to specify a directory where to chroot() into on startup. This is NOT a security feature but introduced to support testing. Thus, -T does not make sure chroot() is used in a secure way. (may be removed later) - added omstdout module for testing purposes. Spits out all messages to stdout - no config option, no other features - modified $ModLoad statement so that for modules whom's name starts with a dot, no path is prepended (this enables relative-pathes and should not break any valid current config) --- tools/syslogd.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 235bc52e..9f962899 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3324,7 +3324,7 @@ int realMain(int argc, char **argv) * only when actually neeeded. * rgerhards, 2008-04-04 */ - while((ch = getopt(argc, argv, "46a:Ac:def:g:hi:l:m:M:nN:op:qQr::s:t:u:vwx")) != EOF) { + while((ch = getopt(argc, argv, "46a:Ac:def:g:hi:l:m:M:nN:op:qQr::s:t:T:u:vwx")) != EOF) { switch((char)ch) { case '4': case '6': @@ -3342,6 +3342,7 @@ int realMain(int argc, char **argv) case 'q': /* add hostname if DNS resolving has failed */ case 'Q': /* dont resolve hostnames in ACL to IPs */ case 's': + case 'T': /* chroot on startup (primarily for testing) */ case 'u': /* misc user settings */ case 'w': /* disable disallowed host warnings */ case 'x': /* disable dns for remote messages */ @@ -3586,6 +3587,20 @@ int realMain(int argc, char **argv) } else fprintf(stderr, "-t option only supported in compatibility modes 0 to 2 - ignored\n"); break; + case 'T':/* chroot() immediately at program startup, but only for testing, NOT security yet */ +{ +char buf[1024]; +getcwd(buf, 1024); +printf("pwd: '%s'\n", buf); +printf("chroot to '%s'\n", arg); + if(chroot(arg) != 0) { + perror("chroot"); + exit(1); + } +getcwd(buf, 1024); +printf("pwd: '%s'\n", buf); +} + break; case 'u': /* misc user settings */ iHelperUOpt = atoi(arg); if(iHelperUOpt & 0x01) -- cgit v1.2.3 From 67e00c063122de13dd6c6354fa095978aa1773de Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 25 Mar 2009 17:59:35 +0100 Subject: bugfix: fixed some segaults on Solaris where vsprintf() does not check for NULL pointers --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 235bc52e..a2aead9a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3475,7 +3475,7 @@ int realMain(int argc, char **argv) /* END core initializations - we now come back to carrying out command line options*/ while((iRet = bufOptRemove(&ch, &arg)) == RS_RET_OK) { - dbgprintf("deque option %c, optarg '%s'\n", ch, arg); + dbgprintf("deque option %c, optarg '%s'\n", ch, (arg == NULL) ? "" : arg); switch((char)ch) { case '4': glbl.SetDefPFFamily(PF_INET); -- cgit v1.2.3 From eb807027af9e126a212b0630c5873dddae48963b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 2 Apr 2009 15:12:57 +0200 Subject: added O_CLOEXEC to open() calls to make sure only the minimum number of file handles is left open during a exec call. This is not a 100% solution, as there are also some fopen() calls and, more importantly, file descriptors opened by libraries. But it is better than nothing (and it was quick, at least until we run into platform hell, what we will for sure ;)). --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index c72160fb..16f255ea 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -549,7 +549,7 @@ void untty(void) int i; if ( !Debug ) { - i = open(_PATH_TTY, O_RDWR); + i = open(_PATH_TTY, O_RDWR|O_CLOEXEC); if (i >= 0) { # if !defined(__hpux) (void) ioctl(i, (int) TIOCNOTTY, (char *)0); -- cgit v1.2.3 From a86e42028afeba1daca262b590bfd49d9c393b90 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 2 Apr 2009 16:16:57 +0200 Subject: improved performance of regexp-based filters Thanks to Arnaud Cornet for providing the idea and initial patch. --- tools/syslogd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 16f255ea..c7f36b45 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -432,6 +432,8 @@ selectorDestruct(void *pVal) } else if(pThis->f_filter_type == FILTER_EXPR) { if(pThis->f_filterData.f_expr != NULL) expr.Destruct(&pThis->f_filterData.f_expr); + if(pThis->regex_cache != NULL) + rsRegexDestruct(&pThis->regex_cache); } llDestroy(&pThis->llActList); @@ -1075,8 +1077,10 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce bRet = 1; /* process message! */ break; case FIOP_REGEX: - if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue, - (unsigned char*) pszPropVal, 0) == RS_RET_OK) + //TODO REGEX: this needs to be merged with new functionality below + //rgerhards, 2009-04-02 + if(rsCStrSzStrMatchRegexCache(f->f_filterData.prop.pCSCompValue, + (unsigned char*) pszPropVal, &f->regex_cache) == 0) bRet = 1; break; case FIOP_EREREGEX: -- cgit v1.2.3 From 1d16216aa326296673cc8520a8df351c4d492dfe Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 2 Apr 2009 16:51:53 +0200 Subject: streamlined regex patch - abided to code conventions - fixed a potential segfault when regex library can not be loaded --- tools/syslogd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index c7f36b45..d5429855 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -429,11 +429,11 @@ selectorDestruct(void *pVal) rsCStrDestruct(&pThis->f_filterData.prop.pCSPropName); if(pThis->f_filterData.prop.pCSCompValue != NULL) rsCStrDestruct(&pThis->f_filterData.prop.pCSCompValue); + if(pThis->f_filterData.prop.regex_cache != NULL) + rsCStrRegexDestruct(&pThis->f_filterData.prop.regex_cache); } else if(pThis->f_filter_type == FILTER_EXPR) { if(pThis->f_filterData.f_expr != NULL) expr.Destruct(&pThis->f_filterData.f_expr); - if(pThis->regex_cache != NULL) - rsRegexDestruct(&pThis->regex_cache); } llDestroy(&pThis->llActList); @@ -1080,7 +1080,7 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce //TODO REGEX: this needs to be merged with new functionality below //rgerhards, 2009-04-02 if(rsCStrSzStrMatchRegexCache(f->f_filterData.prop.pCSCompValue, - (unsigned char*) pszPropVal, &f->regex_cache) == 0) + (unsigned char*) pszPropVal, &f->f_filterData.prop.regex_cache) == 0) bRet = 1; break; case FIOP_EREREGEX: -- cgit v1.2.3 From 4ab540e3ba25a13fd079490ac52438e55dc92672 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 2 Apr 2009 17:54:48 +0200 Subject: fully integrated regex patch Now have removed the previous method, as really nobody should call it any longer (and now nobody does ;)). Also did some other cleanup. --- tools/syslogd.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index d5429855..b23c12a7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1077,15 +1077,13 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce bRet = 1; /* process message! */ break; case FIOP_REGEX: - //TODO REGEX: this needs to be merged with new functionality below - //rgerhards, 2009-04-02 - if(rsCStrSzStrMatchRegexCache(f->f_filterData.prop.pCSCompValue, - (unsigned char*) pszPropVal, &f->f_filterData.prop.regex_cache) == 0) + if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue, + (unsigned char*) pszPropVal, 0, &f->f_filterData.prop.regex_cache) == RS_RET_OK) bRet = 1; break; case FIOP_EREREGEX: if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue, - (unsigned char*) pszPropVal, 1) == RS_RET_OK) + (unsigned char*) pszPropVal, 1, &f->f_filterData.prop.regex_cache) == RS_RET_OK) bRet = 1; break; default: -- cgit v1.2.3 From 13344f4928654fc33cc37406164a4a56d22fff93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Fernando=20Mu=C3=B1oz=20Mej=C3=ADas?= Date: Tue, 7 Apr 2009 11:15:52 +0200 Subject: Re-enable parsing host names from message. There was a subtle bug that made all messages fill their HOSTNAME from the source IP (which may be wrong in a long chain of relays) and not by reading the message. This fixes it. --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b23c12a7..a40b34dd 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1496,7 +1496,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * the fields. I think this logic shall work with any type of syslog message. */ bTAGCharDetected = 0; - if(pMsg->bParseHOSTNAME) { + if(flags & PARSE_HOSTNAME) { /* TODO: quick and dirty memory allocation */ /* the memory allocated is far too much in most cases. But on the plus side, * it is quite fast... - rgerhards, 2007-09-20 -- cgit v1.2.3 From de38f744de1ce746e6e61098fd4a05ac76ef71a0 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 8 Apr 2009 18:18:31 +0200 Subject: minor cleanup --- tools/syslogd.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 0badac19..a4f0059b 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3591,18 +3591,10 @@ int realMain(int argc, char **argv) fprintf(stderr, "-t option only supported in compatibility modes 0 to 2 - ignored\n"); break; case 'T':/* chroot() immediately at program startup, but only for testing, NOT security yet */ -{ -char buf[1024]; -getcwd(buf, 1024); -printf("pwd: '%s'\n", buf); -printf("chroot to '%s'\n", arg); if(chroot(arg) != 0) { perror("chroot"); exit(1); } -getcwd(buf, 1024); -printf("pwd: '%s'\n", buf); -} break; case 'u': /* misc user settings */ iHelperUOpt = atoi(arg); -- cgit v1.2.3 From 04272876d12488b2039b28683dc53e1c802d303d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 14 Apr 2009 13:52:07 +0200 Subject: implemented $MaxOpenFiles directive and changed testbench ... to utilize it. This work is not yet fully verified to be correct. --- tools/syslogd.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a4f0059b..8c86c12e 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -87,6 +87,7 @@ #include #include #include +#include #include #if HAVE_SYS_TIMESPEC_H @@ -2073,6 +2074,32 @@ static rsRetVal setActionResumeInterval(void __attribute__((unused)) *pVal, int } +/* set the processes max number ob files (upon configuration request) + * 2009-04-14 rgerhards + */ +static rsRetVal setMaxFiles(void __attribute__((unused)) *pVal, int iFiles) +{ + struct rlimit maxFiles; + char errStr[1024]; + DEFiRet; + + maxFiles.rlim_cur = iFiles; + maxFiles.rlim_max = iFiles; + + if(setrlimit(RLIMIT_NOFILE, &maxFiles) < 0) { + /* NOTE: under valgrind, we seem to be unable to extend the size! */ + rs_strerror_r(errno, errStr, sizeof(errStr)); + errmsg.LogError(0, RS_RET_ERR_RLIM_NOFILE, "could not set process file limit to %d: %s [kernel max %ld]", + iFiles, errStr, (long) maxFiles.rlim_max); + ABORT_FINALIZE(RS_RET_ERR_RLIM_NOFILE); + } + dbgprintf("Max number of files set to %d [kernel max %ld].\n", iFiles, (long) maxFiles.rlim_max); + +finalize_it: + RETiRet; +} + + /* set the processes umask (upon configuration request) */ static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask) { @@ -2870,6 +2897,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, conf.doModLoad, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, conf.doIncludeLine, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"maxopenfiles", 0, eCmdHdlrInt, setMaxFiles, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintTemplateList, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintModuleList, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprintcfsyslinehandlerlist", 0, eCmdHdlrBinary, -- cgit v1.2.3 From e4b3f6d287d74b34d27b4e296c33cb3f1294a58c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 22 Apr 2009 16:39:58 +0200 Subject: now batches are handed down to the actual consumer ... but the action consumer does not do anything really intelligent with them. But the DA consumer is already done, as is the main message queue consumer. --- tools/syslogd.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 8c86c12e..f48fa759 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -129,6 +129,7 @@ #include "omfile.h" #include "omdiscard.h" #include "threads.h" +#include "wti.h" #include "queue.h" #include "stream.h" #include "conf.h" @@ -1202,22 +1203,29 @@ processMsg(msg_t *pMsg) /* The consumer of dequeued messages. This function is called by the * queue engine on dequeueing of a message. It runs on a SEPARATE - * THREAD. - * Please note: the message object is destructed by the queue itself! + * THREAD. It receives an array of pointers, which it must iterate + * over. We do not do any further batching, as this is of no benefit + * for the main queue. */ static rsRetVal -msgConsumer(void __attribute__((unused)) *notNeeded, void *pUsr) +msgConsumer(void __attribute__((unused)) *notNeeded, aUsrp_t *paUsrp) { + int i; + msg_t *pMsg; DEFiRet; - msg_t *pMsg = (msg_t*) pUsr; - assert(pMsg != NULL); + assert(paUsrp != NULL); - if((pMsg->msgFlags & NEEDS_PARSING) != 0) { - parseMsg(pMsg); + for(i = 0 ; i < paUsrp->nElem ; i++) { + pMsg = (msg_t*) paUsrp->pUsrp[i]; +dbgprintf("msgConsumer..MULTIQUEUE: i: %d, pMsg: %p\n", i, pMsg); + if((pMsg->msgFlags & NEEDS_PARSING) != 0) { + parseMsg(pMsg); + } + processMsg(pMsg); + msgDestruct(&pMsg); } - processMsg(pMsg); - msgDestruct(&pMsg); +dbgprintf("DONE msgConsumer..MULTIQUEUE:\n"); RETiRet; } -- cgit v1.2.3 From 5c0aeae8ab1f344a022d586dc26c5d78203f7e0b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 23 Apr 2009 12:50:07 +0200 Subject: added $MainMsgQueueDequeueBatchSize and $ActionQueueDequeueBatchSize configuration directives --- tools/syslogd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f48fa759..5b795755 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -304,6 +304,7 @@ static int iMainMsgQtoWrkShutdown = 60000; /* timeout for worker thread shutdo static int iMainMsgQWrkMinMsgs = 100; /* minimum messages per worker needed to start a new one */ static int iMainMsgQDeqSlowdown = 0; /* dequeue slowdown (simple rate limiting) */ static int64 iMainMsgQueMaxDiskSpace = 0; /* max disk space allocated 0 ==> unlimited */ +static int iMainMsgQueDeqBatchSize = 32; /* dequeue batch size */ static int bMainMsgQSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */ static int iMainMsgQueueDeqtWinFromHr = 0; /* hour begin of time frame when queue is to be dequeued */ static int iMainMsgQueueDeqtWinToHr = 25; /* hour begin of time frame when queue is to be dequeued */ @@ -370,6 +371,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a bMainMsgQSaveOnShutdown = 1; MainMsgQueType = QUEUETYPE_FIXED_ARRAY; iMainMsgQueMaxDiskSpace = 0; + iMainMsgQueDeqBatchSize = 32; glbliActionResumeRetryCount = 0; return RS_RET_OK; @@ -2508,6 +2510,7 @@ init(void) setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", iMainMsgQueMaxFileSize); setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", iMainMsgQueMaxDiskSpace); + setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", iMainMsgQueDeqBatchSize); setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", pszMainMsgQFName); setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", iMainMsgQPersistUpdCnt); setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", iMainMsgQtoQShutdown ); @@ -2888,6 +2891,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeueslowdown", 0, eCmdHdlrInt, NULL, &iMainMsgQDeqSlowdown, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreadminimummessages", 0, eCmdHdlrInt, NULL, &iMainMsgQWrkMinMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxfilesize", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxFileSize, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuebatchsize", 0, eCmdHdlrSize, NULL, &iMainMsgQueDeqBatchSize, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxdiskspace", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxDiskSpace, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesaveonshutdown", 0, eCmdHdlrBinary, NULL, &bMainMsgQSaveOnShutdown, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimebegin", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinFromHr, NULL)); -- cgit v1.2.3 From 8e430258fdc9b0577ea8e54dae21cc5942f90104 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 11 May 2009 17:38:33 +0200 Subject: added capability to draw configuration graphs - added $GenerateConfigGraph configuration command which can be used to generate nice-looking (and very informative) rsyslog configuration graphs. - added $ActionName configuration directive (currently only used for graph generation, but may find other uses) --- tools/syslogd.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 189 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 8c86c12e..3a751a30 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -284,6 +284,7 @@ static int gidDropPriv = 0; /* group-id to which priveleges should be dropped to extern int errno; +static uchar *pszConfDAGFile = NULL; /* name of config DAG file, non-NULL means generate one */ /* main message queue and its configuration parameters */ static qqueue_t *pMsgQueue = NULL; /* the main message queue */ static int iMainMsgQueueSize = 10000; /* size of the main message queue above */ @@ -1939,10 +1940,9 @@ static void doDie(int sig) static void freeAllDynMemForTermination(void) { - if(pszMainMsgQFName != NULL) - free(pszMainMsgQFName); - if(pModDir != NULL) - free(pModDir); + free(pszMainMsgQFName); + free(pModDir); + free(pszConfDAGFile); } @@ -2210,6 +2210,184 @@ static void freeSelectors(void) } +/* helper to generateConfigDAG, to print out all actions via + * the llExecFunc() facility. + * rgerhards, 2007-08-02 + */ +struct dag_info { + FILE *fp; /* output file */ + int iActUnit; /* current action unit number */ + int iAct; /* current action in unit */ + int bDiscarded; /* message discarded (config error) */ + }; +DEFFUNC_llExecFunc(generateConfigDAGAction) +{ + action_t *pAction; + uchar *pszModName; + uchar *pszVertexName; + struct dag_info *pDagInfo; + DEFiRet; + + pDagInfo = (struct dag_info*) pParam; + pAction = (action_t*) pData; + + pszModName = module.GetStateName(pAction->pMod); + + /* vertex */ + if(pAction->pszName == NULL) { + if(!strcmp((char*)pszModName, "builtin-discard")) + pszVertexName = (uchar*)"discard"; + else + pszVertexName = pszModName; + } else { + pszVertexName = pAction->pszName; + } + + fprintf(pDagInfo->fp, "\tact%d_%d\t\t[label=\"%s\"%s%s]\n", + pDagInfo->iActUnit, pDagInfo->iAct, pszVertexName, + pDagInfo->bDiscarded ? " style=dotted color=red" : "", + (pAction->pQueue->qType == QUEUETYPE_DIRECT) ? "" : " shape=hexagon" + ); + + /* edge */ + if(pDagInfo->iAct == 0) { + } else { + fprintf(pDagInfo->fp, "\tact%d_%d -> act%d_%d[%s%s]\n", + pDagInfo->iActUnit, pDagInfo->iAct - 1, + pDagInfo->iActUnit, pDagInfo->iAct, + pDagInfo->bDiscarded ? " style=dotted color=red" : "", + pAction->bExecWhenPrevSusp ? " label=\"only if\\nsuspended\"" : "" ); + } + + /* check for discard */ + if(!strcmp((char*) pszModName, "builtin-discard")) { + fprintf(pDagInfo->fp, "\tact%d_%d\t\t[shape=box]\n", + pDagInfo->iActUnit, pDagInfo->iAct); + pDagInfo->bDiscarded = 1; + } + + + ++pDagInfo->iAct; + + RETiRet; +} + + +/* create config DAG + * This functions takes a rsyslog config and produces a .dot file for use + * with graphviz (http://www.graphviz.org). This is done in an effort to + * document, and also potentially troubleshoot, configurations. Plus, I + * consider it a nice feature to explain some concepts. Note that the + * current version only produces a graph with relatively little information. + * This is a foundation that may be later expanded (if it turns out to be + * useful enough). + * rgerhards, 2009-05-11 + */ +static rsRetVal +generateConfigDAG(uchar *pszDAGFile) +{ + selector_t *f; + FILE *fp; + int iActUnit = 1; + int bHasFilter = 0; /* filter associated with this action unit? */ + int bHadFilter; + int i; + struct dag_info dagInfo; + char *pszFilterName; + char szConnectingNode[64]; + DEFiRet; + + assert(pszDAGFile != NULL); + + if((fp = fopen((char*) pszDAGFile, "w")) == NULL) { + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*) + "configuraton graph output file could not be opened, none generated", 0); + ABORT_FINALIZE(RS_RET_FILENAME_INVALID); + } + + dagInfo.fp = fp; + + /* from here on, we assume writes go well. This here is a really + * unimportant utility function and if something goes wrong, it has + * almost no effect. So let's not overdo this... + */ + fprintf(fp, "# graph created by rsyslog " VERSION "\n\n" + "# use the dot tool from http://www.graphviz.org to visualize!\n" + "digraph rsyslogConfig {\n" + "\tinputs [shape=tripleoctagon]\n" + "\tinputs -> act0_0\n" + "\tact0_0 [label=\"main\\nqueue\" shape=hexagon]\n" + /*"\tmainq -> act1_0\n"*/ + ); + strcpy(szConnectingNode, "act0_0"); + dagInfo.bDiscarded = 0; + + for(f = Files; f != NULL ; f = f->f_next) { + /* BSD-Style filters are currently ignored */ + bHadFilter = bHasFilter; + if(f->f_filter_type == FILTER_PRI) { + bHasFilter = 0; + for (i = 0; i <= LOG_NFACILITIES; i++) + if (f->f_filterData.f_pmask[i] != 0xff) { + bHasFilter = 1; + break; + } + } else { + bHasFilter = 1; + } + + /* we know we have a filter, so it can be false */ + switch(f->f_filter_type) { + case FILTER_PRI: + pszFilterName = "pri filter"; + break; + case FILTER_PROP: + pszFilterName = "property filter"; + break; + case FILTER_EXPR: + pszFilterName = "script filter"; + break; + } + + /* write action unit node */ + if(bHasFilter) { + fprintf(fp, "\t%s -> act%d_end\t[label=\"%s:\\nfalse\"]\n", + szConnectingNode, iActUnit, pszFilterName); + fprintf(fp, "\t%s -> act%d_0\t[label=\"%s:\\ntrue\"]\n", + szConnectingNode, iActUnit, pszFilterName); + fprintf(fp, "\tact%d_end\t\t\t\t[shape=point]\n", iActUnit); + snprintf(szConnectingNode, sizeof(szConnectingNode), "act%d_end", iActUnit); + } else { + fprintf(fp, "\t%s -> act%d_0\t[label=\"no filter\"]\n", + szConnectingNode, iActUnit); + snprintf(szConnectingNode, sizeof(szConnectingNode), "act%d_0", iActUnit); + } + + /* draw individual nodes */ + dagInfo.iActUnit = iActUnit; + dagInfo.iAct = 0; + dagInfo.bDiscarded = 0; + llExecFunc(&f->llActList, generateConfigDAGAction, &dagInfo); /* actions */ + + /* finish up */ + if(bHasFilter && !dagInfo.bDiscarded) { + fprintf(fp, "\tact%d_%d -> %s\n", + iActUnit, dagInfo.iAct - 1, szConnectingNode); + } + + ++iActUnit; + } + + fprintf(fp, "\t%s -> act%d_0\n", szConnectingNode, iActUnit); + fprintf(fp, "\tact%d_0\t\t[label=discard shape=box]\n" + "}\n", iActUnit); + fclose(fp); + +finalize_it: + RETiRet; +} + + /* helper to dbPrintInitInfo, to print out all actions via * the llExecFunc() facility. * rgerhards, 2007-08-02 @@ -2223,6 +2401,7 @@ DEFFUNC_llExecFunc(dbgPrintInitInfoAction) RETiRet; } + /* print debug information as part of init(). This pretty much * outputs the whole config of rsyslogd. I've moved this code * out of init() to clean it somewhat up. @@ -2230,7 +2409,7 @@ DEFFUNC_llExecFunc(dbgPrintInitInfoAction) */ static void dbgPrintInitInfo(void) { - register selector_t *f; + selector_t *f; int iSelNbr = 1; int i; @@ -2467,6 +2646,10 @@ init(void) } } + /* check if we need to generate a config DAG and, if so, do that */ + if(pszConfDAGFile != NULL) + generateConfigDAG(pszConfDAGFile); + /* we are done checking the config - now validate if we should actually run or not. * If not, terminate. -- rgerhards, 2008-07-25 */ @@ -2903,6 +3086,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"debugprintcfsyslinehandlerlist", 0, eCmdHdlrBinary, NULL, &bDebugPrintCfSysLineHandlerList, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"generateconfiggraph", 0, eCmdHdlrGetWord, NULL, &pszConfDAGFile, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &bErrMsgToStderr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, setMaxMsgSize, NULL, NULL)); -- cgit v1.2.3 From bb79e96dc300fa5a2182e7c047afb3b15c5dc870 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 12 May 2009 15:27:40 +0200 Subject: moving to a cleaner implementation of batches ... now that we know what we need from a theoretical POV. --- tools/syslogd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 866c0173..7ee5dbd7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -138,6 +138,7 @@ #include "datetime.h" #include "parser.h" #include "sysvar.h" +#include "batch.h" /* definitions for objects we access */ DEFobjCurrIf(obj) @@ -1211,16 +1212,16 @@ processMsg(msg_t *pMsg) * for the main queue. */ static rsRetVal -msgConsumer(void __attribute__((unused)) *notNeeded, aUsrp_t *paUsrp) +msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch) { int i; msg_t *pMsg; DEFiRet; - assert(paUsrp != NULL); + assert(pBatch != NULL); - for(i = 0 ; i < paUsrp->nElem ; i++) { - pMsg = (msg_t*) paUsrp->pUsrp[i]; + for(i = 0 ; i < pBatch->nElem ; i++) { + pMsg = (msg_t*) pBatch->pElem[i].pUsrp; dbgprintf("msgConsumer..MULTIQUEUE: i: %d, pMsg: %p\n", i, pMsg); if((pMsg->msgFlags & NEEDS_PARSING) != 0) { parseMsg(pMsg); -- cgit v1.2.3 From 73b16a5d7703078a46d960bd8922d2ae3a662769 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 13 May 2009 13:22:25 +0200 Subject: added test for property replacer field functionality to testbench plus some cosmetic changes --- tools/syslogd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 7ee5dbd7..cae07811 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1155,6 +1155,7 @@ DEFFUNC_llExecFunc(processMsgDoActions) ABORT_FINALIZE(RS_RET_OK); } + /* MULTIQUEUE: look at this below! (I say: batch states!) */ iRetMod = actionCallAction(pAction, pDoActData->pMsg); if(iRetMod == RS_RET_DISCARDMSG) { ABORT_FINALIZE(RS_RET_DISCARDMSG); @@ -1170,7 +1171,9 @@ finalize_it: } -/* Process (consume) a received message. Calls the actions configured. +/* Process (consume) a received message from the main queue. Here, messages are + * filtered and those where the filter evaluates to true are passed to the action + * queue for further processing. * rgerhards, 2005-10-13 */ static void -- cgit v1.2.3 From 4a8c02870a55e19c1bebfae5cb70d1ec5aa7c203 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 13 May 2009 16:00:15 +0200 Subject: moved user object destruction to queue itself So far, the consumer was responsible for destroying objects. However, this does not work well with ultra-reliable queues. This is the first move to support them. --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index cae07811..88a588e9 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1230,7 +1230,6 @@ dbgprintf("msgConsumer..MULTIQUEUE: i: %d, pMsg: %p\n", i, pMsg); parseMsg(pMsg); } processMsg(pMsg); - msgDestruct(&pMsg); } dbgprintf("DONE msgConsumer..MULTIQUEUE:\n"); -- cgit v1.2.3 From a9c4b26d462dd3c9dbd0575a3a1acc6d8df1c3b3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 May 2009 18:47:26 +0200 Subject: some cleanup --- tools/syslogd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 88a588e9..2bd43685 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1225,13 +1225,12 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch) for(i = 0 ; i < pBatch->nElem ; i++) { pMsg = (msg_t*) pBatch->pElem[i].pUsrp; -dbgprintf("msgConsumer..MULTIQUEUE: i: %d, pMsg: %p\n", i, pMsg); + DBGPRINTF("msgConsumer processes msg %d/%d\n", i, pBatch->nElem); if((pMsg->msgFlags & NEEDS_PARSING) != 0) { parseMsg(pMsg); } processMsg(pMsg); } -dbgprintf("DONE msgConsumer..MULTIQUEUE:\n"); RETiRet; } -- cgit v1.2.3 From aba90e82484118f3568ec51c01de5ba845da589a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 22 May 2009 17:06:52 +0200 Subject: added capability to run multiple tcp listeners (on different ports) Well, actually this and a lot of related things. I improved the testbench so that the new capabilities are automatically tested and also did some general cleanup. The current multiple tcp listener solution will probably receive some further cleanup, too, but looks quite OK so far. I also reviewed the way tcpsrv et all work, in preparation of using this code for imdiag. I need to document the findings, especially as the code is rather complicated "thanks" to the combination of plain tcp and gssapi transport modes. --- tools/syslogd.c | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3a751a30..dc5b8fee 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -137,6 +137,7 @@ #include "datetime.h" #include "parser.h" #include "sysvar.h" +#include "unicode-helper.h" /* definitions for objects we access */ DEFobjCurrIf(obj) @@ -620,7 +621,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime)); } if(pszInputName != NULL) - MsgSetInputName(pMsg, (char*) pszInputName); + MsgSetInputName(pMsg, pszInputName); MsgSetFlowControlType(pMsg, flowCtlType); MsgSetRawMsg(pMsg, (char*)msg); @@ -649,8 +650,8 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f * being the local host). rgerhards 2004-11-16 */ if((pMsg->msgFlags & PARSE_HOSTNAME) == 0) - MsgSetHOSTNAME(pMsg, (char*)hname); - MsgSetRcvFrom(pMsg, (char*)hname); + MsgSetHOSTNAME(pMsg, hname); + MsgSetRcvFrom(pMsg, hname); CHKiRet(MsgSetRcvFromIP(pMsg, hnameIP)); /* rgerhards 2004-11-19: well, well... we've now seen that we @@ -928,12 +929,12 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) DEFiRet; CHKiRet(msgConstruct(&pMsg)); - MsgSetInputName(pMsg, "rsyslogd"); + MsgSetInputName(pMsg, UCHAR_CONSTANT("rsyslogd")); MsgSetUxTradMsg(pMsg, (char*)msg); MsgSetRawMsg(pMsg, (char*)msg); - MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName()); - MsgSetRcvFrom(pMsg, (char*)glbl.GetLocalHostName()); - MsgSetRcvFromIP(pMsg, (uchar*)"127.0.0.1"); + MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName()); + MsgSetRcvFrom(pMsg, glbl.GetLocalHostName()); + MsgSetRcvFromIP(pMsg, UCHAR_CONSTANT("127.0.0.1")); /* check if we have an error code associated and, if so, * adjust the tag. -- r5gerhards, 2008-06-27 */ @@ -1233,9 +1234,9 @@ msgConsumer(void __attribute__((unused)) *notNeeded, void *pUsr) * SP-terminated or any other error occurs. * rger, 2005-11-24 */ -static int parseRFCField(char **pp2parse, char *pResult) +static int parseRFCField(uchar **pp2parse, uchar *pResult) { - char *p2parse; + uchar *p2parse; int iRet = 0; assert(pp2parse != NULL); @@ -1271,9 +1272,9 @@ static int parseRFCField(char **pp2parse, char *pResult) * SP-terminated or any other error occurs. * rger, 2005-11-24 */ -static int parseRFCStructuredData(char **pp2parse, char *pResult) +static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult) { - char *p2parse; + uchar *p2parse; int bCont = 1; int iRet = 0; @@ -1340,14 +1341,14 @@ static int parseRFCStructuredData(char **pp2parse, char *pResult) */ int parseRFCSyslogMsg(msg_t *pMsg, int flags) { - char *p2parse; - char *pBuf; + uchar *p2parse; + uchar *pBuf; int bContParse = 1; BEGINfunc assert(pMsg != NULL); assert(pMsg->pszUxTradMsg != NULL); - p2parse = (char*) pMsg->pszUxTradMsg; + p2parse = pMsg->pszUxTradMsg; /* do a sanity check on the version and eat it */ assert(p2parse[0] == '1' && p2parse[1] == ' '); @@ -1358,7 +1359,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) * message, so we can not run into any troubles. I think this is * more wise then to use individual buffers. */ - if((pBuf = malloc(sizeof(char)* strlen(p2parse) + 1)) == NULL) + if((pBuf = malloc(sizeof(uchar) * ustrlen(p2parse) + 1)) == NULL) return 1; /* IMPORTANT NOTE: @@ -1393,29 +1394,29 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) /* APP-NAME */ if(bContParse) { parseRFCField(&p2parse, pBuf); - MsgSetAPPNAME(pMsg, pBuf); + MsgSetAPPNAME(pMsg, (char*)pBuf); } /* PROCID */ if(bContParse) { parseRFCField(&p2parse, pBuf); - MsgSetPROCID(pMsg, pBuf); + MsgSetPROCID(pMsg, (char*)pBuf); } /* MSGID */ if(bContParse) { parseRFCField(&p2parse, pBuf); - MsgSetMSGID(pMsg, pBuf); + MsgSetMSGID(pMsg, (char*)pBuf); } /* STRUCTURED-DATA */ if(bContParse) { parseRFCStructuredData(&p2parse, pBuf); - MsgSetStructuredData(pMsg, pBuf); + MsgSetStructuredData(pMsg, (char*)pBuf); } /* MSG */ - MsgSetMSG(pMsg, p2parse); + MsgSetMSG(pMsg, (char*)p2parse); free(pBuf); ENDfunc @@ -1438,7 +1439,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) */ int parseLegacySyslogMsg(msg_t *pMsg, int flags) { - char *p2parse; + uchar *p2parse; char *pBuf; char *pWork; cstr_t *pStrB; @@ -1448,7 +1449,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) assert(pMsg != NULL); assert(pMsg->pszUxTradMsg != NULL); - p2parse = (char*) pMsg->pszUxTradMsg; + p2parse = pMsg->pszUxTradMsg; /* Check to see if msg contains a timestamp. We start by assuming * that the message timestamp is the time of reciption (which we @@ -1503,7 +1504,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) /* the memory allocated is far too much in most cases. But on the plus side, * it is quite fast... - rgerhards, 2007-09-20 */ - if((pBuf = malloc(sizeof(char)* (strlen(p2parse) +1))) == NULL) + if((pBuf = malloc(sizeof(char)* (ustrlen(p2parse) +1))) == NULL) return 1; pWork = pBuf; /* this is the actual parsing loop */ @@ -1609,7 +1610,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) } /* The rest is the actual MSG */ - MsgSetMSG(pMsg, p2parse); + MsgSetMSG(pMsg, (char*)p2parse); ENDfunc return 0; /* all ok */ @@ -1919,10 +1920,10 @@ static void doDie(int sig) # define MSG1 "DoDie called.\n" # define MSG2 "DoDie called 5 times - unconditional exit\n" static int iRetries = 0; /* debug aid */ - if(Debug || NoFork) + if(Debug) write(1, MSG1, sizeof(MSG1) - 1); if(iRetries++ == 4) { - if(Debug || NoFork) + if(Debug) write(1, MSG2, sizeof(MSG2) - 1); abort(); } -- cgit v1.2.3 From eb1615068c6a704287eda732d287280df4cc4c44 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 25 May 2009 10:47:22 +0200 Subject: added new testing module imdiag which enables to talk to the rsyslog core at runtime. The current implementation is only a beginning, but can be expanded over time --- tools/syslogd.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index dc5b8fee..0b860448 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -350,10 +350,8 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a bDebugPrintModuleList = 1; bEscapeCCOnRcv = 1; /* default is to escape control characters */ bReduceRepeatMsgs = 0; - if(pszMainMsgQFName != NULL) { - free(pszMainMsgQFName); - pszMainMsgQFName = NULL; - } + free(pszMainMsgQFName); + pszMainMsgQFName = NULL; iMainMsgQueueSize = 10000; iMainMsgQHighWtrMark = 8000; iMainMsgQLowWtrMark = 2000; @@ -412,6 +410,26 @@ static int usage(void) } +/* ------------------------------ some support functions for imdiag ------------------------------ * + * This is a bit dirty, but the only way to do it, at least with reasonable effort. + * rgerhards, 2009-05-25 + */ + +/* return back the approximate current number of messages in the main message queue + */ +rsRetVal +diagGetMainMsgQSize(int *piSize) +{ + DEFiRet; + assert(piSize != NULL); + *piSize = pMsgQueue->iQueueSize; + RETiRet; +} + + +/* ------------------------------ end support functions for imdiag ------------------------------ */ + + /* function to destruct a selector_t object * rgerhards, 2007-08-01 */ @@ -2658,7 +2676,6 @@ init(void) ABORT_FINALIZE(RS_RET_VALIDATION_RUN); /* switch the message object to threaded operation, if necessary */ -/* TODO:XXX: I think we must do this also if we have action queues! -- rgerhards, 2009-01-26 */ if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) { MsgEnableThreadSafety(); } -- cgit v1.2.3 From 210f43137d6a077abbd8b77c1f72193dcd81cc99 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 25 May 2009 16:25:53 +0200 Subject: fixing some minor nits --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e207b5b2..31cc4a4d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1950,6 +1950,7 @@ static void doDie(int sig) # define MSG1 "DoDie called.\n" # define MSG2 "DoDie called 5 times - unconditional exit\n" static int iRetries = 0; /* debug aid */ + dbgprintf(MSG1); if(Debug) write(1, MSG1, sizeof(MSG1) - 1); if(iRetries++ == 4) { -- cgit v1.2.3 From d8ba1a0d9f1f90c250cc2405f87be151ac609968 Mon Sep 17 00:00:00 2001 From: varmojfekoj Date: Thu, 28 May 2009 16:01:34 +0200 Subject: bugfix: internal messages were emitted to whatever file had fd2 ...when rsyslogd ran in forked mode (as usual!) Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b0d6fa25..1840030b 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -925,7 +925,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) * permits us to process unmodified config files which otherwise contain a * supressor statement. */ - if(bErrMsgToStderr || iConfigVerify) { + if(((Debug || NoFork) && bErrMsgToStderr) || iConfigVerify) { fprintf(stderr, "rsyslogd: %s\n", msg); } -- cgit v1.2.3 From 23dac82b684e966490de707a44144b3ad0ce2323 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 28 May 2009 17:59:11 +0200 Subject: small enhancement: config validation run now exits with code 1 if an error is detected. This change is considered important but small enough to apply it directly to the stable version. [But it is a border case, the change requires more code than I had hoped. Thus I have NOT tried to actually catch all cases, this is left for the current devel releases, if necessary] --- tools/syslogd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 1840030b..01d3af71 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2237,6 +2237,7 @@ init(void) DEFiRet; rsRetVal localRet; int iNbrActions; + int bHadConfigErr = 0; char cbuf[BUFSIZ]; char bufStartUpMsg[512]; struct sigaction sigAct; @@ -2287,9 +2288,11 @@ init(void) if(localRet != RS_RET_OK) { errmsg.LogError(0, localRet, "CONFIG ERROR: could not interpret master config file '%s'.", ConfFile); + bHadConfigErr = 1; } else if(iNbrActions == 0) { errmsg.LogError(0, RS_RET_NO_ACTIONS, "CONFIG ERROR: there are no active actions configured. Inputs will " "run, but no output whatsoever is created."); + bHadConfigErr = 1; } if(localRet != RS_RET_OK || iNbrActions == 0) { @@ -2355,8 +2358,13 @@ init(void) /* we are done checking the config - now validate if we should actually run or not. * If not, terminate. -- rgerhards, 2008-07-25 */ - if(iConfigVerify) + if(iConfigVerify) { + if(bHadConfigErr) { + /* a bit dirty, but useful... */ + exit(1); + } ABORT_FINALIZE(RS_RET_VALIDATION_RUN); + } /* switch the message object to threaded operation, if necessary */ if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) { -- cgit v1.2.3 From 43c45bfebcc672d6fbec2d4d659609d1ea48eda6 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 29 May 2009 13:40:04 +0200 Subject: fixed problem in syslog-protocol (now RFC5424) parser ... as well as some other minor issues. --- tools/syslogd.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 01d3af71..f8149613 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1252,21 +1252,26 @@ static int parseRFCStructuredData(char **pp2parse, char *pResult) if(*p2parse != '[') return 1; /* this is NOT structured data! */ - while(bCont) { - if(*p2parse == '\0') { - iRet = 1; /* this is not valid! */ - bCont = 0; - } else if(*p2parse == '\\' && *(p2parse+1) == ']') { - /* this is escaped, need to copy both */ - *pResult++ = *p2parse++; - *pResult++ = *p2parse++; - } else if(*p2parse == ']' && *(p2parse+1) == ' ') { - /* found end, just need to copy the ] and eat the SP */ - *pResult++ = *p2parse; - p2parse += 2; - bCont = 0; - } else { - *pResult++ = *p2parse++; + if(*p2parse != '-') { /* empty structured data? */ + *pResult++ = '-'; + ++p2parse; + } else { + while(bCont) { + if(*p2parse == '\0') { + iRet = 1; /* this is not valid! */ + bCont = 0; + } else if(*p2parse == '\\' && *(p2parse+1) == ']') { + /* this is escaped, need to copy both */ + *pResult++ = *p2parse++; + *pResult++ = *p2parse++; + } else if(*p2parse == ']' && *(p2parse+1) == ' ') { + /* found end, just need to copy the ] and eat the SP */ + *pResult++ = *p2parse; + p2parse += 2; + bCont = 0; + } else { + *pResult++ = *p2parse++; + } } } -- cgit v1.2.3 From 6ddb3249e6bac6c573a5ab45eba65fba91c1d9e9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 29 May 2009 13:54:53 +0200 Subject: fixed copy&paste error in previous commit (testcase was only present in v4, so I did not spot the issue immediately) --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f8149613..13eaede2 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1252,7 +1252,7 @@ static int parseRFCStructuredData(char **pp2parse, char *pResult) if(*p2parse != '[') return 1; /* this is NOT structured data! */ - if(*p2parse != '-') { /* empty structured data? */ + if(*p2parse == '-') { /* empty structured data? */ *pResult++ = '-'; ++p2parse; } else { -- cgit v1.2.3 From 2cf3b2fa3c5c5b6cbf104294c7fc8860bb49bac0 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 29 May 2009 17:39:32 +0200 Subject: fixed a regression of yesterday's patch ... I know I should not have done this to a stable branch... Thankfully nothing was yet released. --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 13eaede2..357f6699 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2300,7 +2300,7 @@ init(void) bHadConfigErr = 1; } - if(localRet != RS_RET_OK || iNbrActions == 0) { + if((localRet != RS_RET_OK && localRet != RS_RET_NONFATAL_CONFIG_ERR) || iNbrActions == 0) { /* rgerhards: this code is executed to set defaults when the * config file could not be opened. We might think about * abandoning the run in this case - but this, too, is not -- cgit v1.2.3 From 9e434f19a9baa4a6f411808b5cb6bc22d6a32781 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 4 Jun 2009 12:15:59 +0200 Subject: cleaned up stream class ... ... and also made it callable via an rsyslog interface rather then relying on the OS loader (important if we go for using it inside loadbale modules, which we soon possible will) --- tools/syslogd.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b43b7a37..22cb6879 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -136,7 +136,6 @@ #include "errmsg.h" #include "datetime.h" #include "parser.h" -#include "sysvar.h" #include "unicode-helper.h" /* definitions for objects we access */ @@ -3340,26 +3339,6 @@ GlobalClassExit(void) objRelease(datetime, CORE_COMPONENT); /* TODO: implement the rest of the deinit */ -#if 0 - CHKiRet(datetimeClassInit(NULL)); - CHKiRet(msgClassInit(NULL)); - CHKiRet(strmClassInit(NULL)); - CHKiRet(wtiClassInit(NULL)); - CHKiRet(wtpClassInit(NULL)); - CHKiRet(qqueueClassInit(NULL)); - CHKiRet(vmstkClassInit(NULL)); - CHKiRet(sysvarClassInit(NULL)); - CHKiRet(vmClassInit(NULL)); - CHKiRet(vmopClassInit(NULL)); - CHKiRet(vmprgClassInit(NULL)); - CHKiRet(ctok_tokenClassInit(NULL)); - CHKiRet(ctokClassInit(NULL)); - CHKiRet(exprClassInit(NULL)); - - /* dummy "classes" */ - CHKiRet(actionClassInit()); - CHKiRet(templateInit()); -#endif /* dummy "classes */ strExit(); -- cgit v1.2.3 From 76da7f9f4e3dc900046a1956153d10532f2b1ae0 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 4 Jun 2009 15:59:37 +0200 Subject: added $OMFileIOBufferSize config directive and plumbing --- tools/syslogd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 22cb6879..206b79e8 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3042,18 +3042,18 @@ static rsRetVal loadBuildInModules(void) { DEFiRet; - if((iRet = module.doModInit(modInitFile, (uchar*) "builtin-file", NULL)) != RS_RET_OK) { + if((iRet = module.doModInit(modInitFile, UCHAR_CONSTANT("builtin-file"), NULL)) != RS_RET_OK) { RETiRet; } #ifdef SYSLOG_INET - if((iRet = module.doModInit(modInitFwd, (uchar*) "builtin-fwd", NULL)) != RS_RET_OK) { + if((iRet = module.doModInit(modInitFwd, UCHAR_CONSTANT("builtin-fwd"), NULL)) != RS_RET_OK) { RETiRet; } #endif - if((iRet = module.doModInit(modInitShell, (uchar*) "builtin-shell", NULL)) != RS_RET_OK) { + if((iRet = module.doModInit(modInitShell, UCHAR_CONSTANT("builtin-shell"), NULL)) != RS_RET_OK) { RETiRet; } - if((iRet = module.doModInit(modInitDiscard, (uchar*) "builtin-discard", NULL)) != RS_RET_OK) { + if((iRet = module.doModInit(modInitDiscard, UCHAR_CONSTANT("builtin-discard"), NULL)) != RS_RET_OK) { RETiRet; } -- cgit v1.2.3 From 9704f129f72ec9ece11aeccea4bbf0cbccb116cb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 9 Jun 2009 19:00:18 +0200 Subject: added capability to fsync() queue disk files for enhanced reliability also adds speed, because you do no longer need to run the whole file system in sync mode. New testbench and new config directives: - $MainMsgQueueSyncQueueFiles - $ActionQueueSyncQueueFiles --- tools/syslogd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 206b79e8..19ece349 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -297,6 +297,7 @@ static queueType_t MainMsgQueType = QUEUETYPE_FIXED_ARRAY; /* type of the main m static uchar *pszMainMsgQFName = NULL; /* prefix for the main message queue file */ static int64 iMainMsgQueMaxFileSize = 1024*1024; static int iMainMsgQPersistUpdCnt = 0; /* persist queue info every n updates */ +static int bMainMsgQSyncQeueFiles = 0; /* sync queue files on every write? */ static int iMainMsgQtoQShutdown = 0; /* queue shutdown */ static int iMainMsgQtoActShutdown = 1000; /* action shutdown (in phase 2) */ static int iMainMsgQtoEnq = 2000; /* timeout for queue enque */ @@ -359,6 +360,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a iMainMsgQueMaxFileSize = 1024 * 1024; iMainMsgQueueNumWorkers = 1; iMainMsgQPersistUpdCnt = 0; + bMainMsgQSyncQeueFiles = 0; iMainMsgQtoQShutdown = 0; iMainMsgQtoActShutdown = 1000; iMainMsgQtoEnq = 2000; @@ -2715,6 +2717,7 @@ init(void) setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", iMainMsgQueMaxDiskSpace); setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", pszMainMsgQFName); setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", iMainMsgQPersistUpdCnt); + setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", bMainMsgQSyncQeueFiles); setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", iMainMsgQtoQShutdown ); setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", iMainMsgQtoActShutdown); setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", iMainMsgQtoWrkShutdown); @@ -3084,6 +3087,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardmark", 0, eCmdHdlrInt, NULL, &iMainMsgQDiscardMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardseverity", 0, eCmdHdlrSeverity, NULL, &iMainMsgQDiscardSeverity, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuecheckpointinterval", 0, eCmdHdlrInt, NULL, &iMainMsgQPersistUpdCnt, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesyncqueuefiles", 0, eCmdHdlrBinary, NULL, &bMainMsgQSyncQeueFiles, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetype", 0, eCmdHdlrGetWord, setMainMsgQueType, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreads", 0, eCmdHdlrInt, NULL, &iMainMsgQueueNumWorkers, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoQShutdown, NULL)); -- cgit v1.2.3 From 6f4e3c4e4c85acdcf58969970484a54639ecc8f9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 10 Jun 2009 16:49:14 +0200 Subject: restructered code in perparation for multiple rule set support ... this was long overdue, and I finlly tackeld it. It turned out to be more complex than I initially thought. The next step now probably is to actually implement multiple rule sets and the beauty that comes with them. --- tools/syslogd.c | 537 ++++++-------------------------------------------------- 1 file changed, 54 insertions(+), 483 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 19ece349..183c7760 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -132,11 +132,13 @@ #include "queue.h" #include "stream.h" #include "conf.h" -#include "vm.h" #include "errmsg.h" #include "datetime.h" #include "parser.h" #include "unicode-helper.h" +#include "ruleset.h" +#include "rule.h" +#include "vm.h" /* definitions for objects we access */ DEFobjCurrIf(obj) @@ -144,10 +146,10 @@ DEFobjCurrIf(glbl) DEFobjCurrIf(datetime) DEFobjCurrIf(conf) DEFobjCurrIf(expr) -DEFobjCurrIf(vm) -DEFobjCurrIf(var) DEFobjCurrIf(module) DEFobjCurrIf(errmsg) +DEFobjCurrIf(rule) +DEFobjCurrIf(ruleset) DEFobjCurrIf(net) /* TODO: make go away! */ @@ -246,7 +248,7 @@ int repeatinterval[2] = { 30, 60 }; /* # of secs before flush */ #define LIST_DELIMITER ':' /* delimiter between two hosts */ -struct filed *Files = NULL; /* read-only after init() (but beware of sigusr1!) */ +ruleset_t *pCurrRuleset; /* ruleset that is currently being processed */ static pid_t ppid; /* This is a quick and dirty hack used for spliting main/startup thread */ @@ -313,7 +315,8 @@ static int iMainMsgQueueDeqtWinToHr = 25; /* hour begin of time frame when que /* support for simple textual representation of FIOP names * rgerhards, 2005-09-27 */ -static char* getFIOPName(unsigned iFIOP) +char* +getFIOPName(unsigned iFIOP) { char *pRet; switch(iFIOP) { @@ -396,7 +399,6 @@ static char **crunch_list(char *list); static void reapchild(); static void debug_switch(); static void sighup_handler(); -static void freeSelectors(void); static void processImInternal(void); @@ -431,67 +433,6 @@ diagGetMainMsgQSize(int *piSize) /* ------------------------------ end support functions for imdiag ------------------------------ */ -/* function to destruct a selector_t object - * rgerhards, 2007-08-01 - */ -rsRetVal -selectorDestruct(void *pVal) -{ - selector_t *pThis = (selector_t *) pVal; - - assert(pThis != NULL); - - if(pThis->pCSHostnameComp != NULL) - rsCStrDestruct(&pThis->pCSHostnameComp); - if(pThis->pCSProgNameComp != NULL) - rsCStrDestruct(&pThis->pCSProgNameComp); - - if(pThis->f_filter_type == FILTER_PROP) { - if(pThis->f_filterData.prop.pCSPropName != NULL) - rsCStrDestruct(&pThis->f_filterData.prop.pCSPropName); - if(pThis->f_filterData.prop.pCSCompValue != NULL) - rsCStrDestruct(&pThis->f_filterData.prop.pCSCompValue); - if(pThis->f_filterData.prop.regex_cache != NULL) - rsCStrRegexDestruct(&pThis->f_filterData.prop.regex_cache); - } else if(pThis->f_filter_type == FILTER_EXPR) { - if(pThis->f_filterData.f_expr != NULL) - expr.Destruct(&pThis->f_filterData.f_expr); - } - - llDestroy(&pThis->llActList); - free(pThis); - - return RS_RET_OK; -} - - -/* function to construct a selector_t object - * rgerhards, 2007-08-01 - */ -rsRetVal -selectorConstruct(selector_t **ppThis) -{ - DEFiRet; - selector_t *pThis; - - assert(ppThis != NULL); - - if((pThis = (selector_t*) calloc(1, sizeof(selector_t))) == NULL) { - ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); - } - CHKiRet(llInit(&pThis->llActList, actionDestruct, NULL, NULL)); - -finalize_it: - if(iRet != RS_RET_OK) { - if(pThis != NULL) { - selectorDestruct(pThis); - } - } - *ppThis = pThis; - RETiRet; -} - - /* rgerhards, 2005-10-24: crunch_list is called only during option processing. So * it is never called once rsyslogd is running (not even when HUPed). This code * contains some exits, but they are considered safe because they only happen @@ -993,233 +934,6 @@ finalize_it: RETiRet; } -/* This functions looks at the given message and checks if it matches the - * provided filter condition. If so, it returns true, else it returns - * false. This is a helper to logmsg() and meant to drive the decision - * process if a message is to be processed or not. As I expect this - * decision code to grow more complex over time AND logmsg() is already - * a very lengthy function, I thought a separate function is more appropriate. - * 2005-09-19 rgerhards - * 2008-02-25 rgerhards: changed interface, now utilizes iRet, bProcessMsg - * returns is message should be procesed. - */ -static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProcessMsg) -{ - DEFiRet; - unsigned short pbMustBeFreed; - char *pszPropVal; - int bRet = 0; - vm_t *pVM = NULL; - var_t *pResult = NULL; - - assert(f != NULL); - assert(pMsg != NULL); - - /* we first have a look at the global, BSD-style block filters (for tag - * and host). Only if they match, we evaluate the actual filter. - * rgerhards, 2005-10-18 - */ - if(f->eHostnameCmpMode == HN_NO_COMP) { - /* EMPTY BY INTENSION - we check this value first, because - * it is the one most often used, so this saves us time! - */ - } else if(f->eHostnameCmpMode == HN_COMP_MATCH) { - if(rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) { - /* not equal, so we are already done... */ - dbgprintf("hostname filter '+%s' does not match '%s'\n", - rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg)); - FINALIZE; - } - } else { /* must be -hostname */ - if(!rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) { - /* not equal, so we are already done... */ - dbgprintf("hostname filter '-%s' does not match '%s'\n", - rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg)); - FINALIZE; - } - } - - if(f->pCSProgNameComp != NULL) { - int bInv = 0, bEqv = 0, offset = 0; - if(*(rsCStrGetSzStrNoNULL(f->pCSProgNameComp)) == '-') { - if(*(rsCStrGetSzStrNoNULL(f->pCSProgNameComp) + 1) == '-') - offset = 1; - else { - bInv = 1; - offset = 1; - } - } - if(!rsCStrOffsetSzStrCmp(f->pCSProgNameComp, offset, (uchar*) getProgramName(pMsg), getProgramNameLen(pMsg))) - bEqv = 1; - - if((!bEqv && !bInv) || (bEqv && bInv)) { - /* not equal or inverted selection, so we are already done... */ - dbgprintf("programname filter '%s' does not match '%s'\n", - rsCStrGetSzStrNoNULL(f->pCSProgNameComp), getProgramName(pMsg)); - FINALIZE; - } - } - - /* done with the BSD-style block filters */ - - if(f->f_filter_type == FILTER_PRI) { - /* skip messages that are incorrect priority */ - if ( (f->f_filterData.f_pmask[pMsg->iFacility] == TABLE_NOPRI) || \ - ((f->f_filterData.f_pmask[pMsg->iFacility] & (1<iSeverity)) == 0) ) - bRet = 0; - else - bRet = 1; - } else if(f->f_filter_type == FILTER_EXPR) { - CHKiRet(vm.Construct(&pVM)); - CHKiRet(vm.ConstructFinalize(pVM)); - CHKiRet(vm.SetMsg(pVM, pMsg)); - CHKiRet(vm.ExecProg(pVM, f->f_filterData.f_expr->pVmprg)); - CHKiRet(vm.PopBoolFromStack(pVM, &pResult)); - dbgprintf("result of expression evaluation: %lld\n", pResult->val.num); - /* VM is destructed on function exit */ - bRet = (pResult->val.num) ? 1 : 0; - } else { - assert(f->f_filter_type == FILTER_PROP); /* assert() just in case... */ - pszPropVal = MsgGetProp(pMsg, NULL, f->f_filterData.prop.pCSPropName, &pbMustBeFreed); - - /* Now do the compares (short list currently ;)) */ - switch(f->f_filterData.prop.operation ) { - case FIOP_CONTAINS: - if(rsCStrLocateInSzStr(f->f_filterData.prop.pCSCompValue, (uchar*) pszPropVal) != -1) - bRet = 1; - break; - case FIOP_ISEQUAL: - if(rsCStrSzStrCmp(f->f_filterData.prop.pCSCompValue, - (uchar*) pszPropVal, strlen(pszPropVal)) == 0) - bRet = 1; /* process message! */ - break; - case FIOP_STARTSWITH: - if(rsCStrSzStrStartsWithCStr(f->f_filterData.prop.pCSCompValue, - (uchar*) pszPropVal, strlen(pszPropVal)) == 0) - bRet = 1; /* process message! */ - break; - case FIOP_REGEX: - if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue, - (unsigned char*) pszPropVal, 0, &f->f_filterData.prop.regex_cache) == RS_RET_OK) - bRet = 1; - break; - case FIOP_EREREGEX: - if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue, - (unsigned char*) pszPropVal, 1, &f->f_filterData.prop.regex_cache) == RS_RET_OK) - bRet = 1; - break; - default: - /* here, it handles NOP (for performance reasons) */ - assert(f->f_filterData.prop.operation == FIOP_NOP); - bRet = 1; /* as good as any other default ;) */ - break; - } - - /* now check if the value must be negated */ - if(f->f_filterData.prop.isNegated) - bRet = (bRet == 1) ? 0 : 1; - - if(Debug) { - dbgprintf("Filter: check for property '%s' (value '%s') ", - rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSPropName), - pszPropVal); - if(f->f_filterData.prop.isNegated) - dbgprintf("NOT "); - dbgprintf("%s '%s': %s\n", - getFIOPName(f->f_filterData.prop.operation), - rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSCompValue), - bRet ? "TRUE" : "FALSE"); - } - - /* cleanup */ - if(pbMustBeFreed) - free(pszPropVal); - } - -finalize_it: - /* destruct in any case, not just on error, but it makes error handling much easier */ - if(pVM != NULL) - vm.Destruct(&pVM); - - if(pResult != NULL) - var.Destruct(&pResult); - - *bProcessMsg = bRet; - RETiRet; -} - - -/* helper to processMsg(), used to call the configured actions. It is - * executed from within llExecFunc() of the action list. - * rgerhards, 2007-08-02 - */ -typedef struct processMsgDoActions_s { - int bPrevWasSuspended; /* was the previous action suspended? */ - msg_t *pMsg; -} processMsgDoActions_t; -DEFFUNC_llExecFunc(processMsgDoActions) -{ - DEFiRet; - rsRetVal iRetMod; /* return value of module - we do not always pass that back */ - action_t *pAction = (action_t*) pData; - processMsgDoActions_t *pDoActData = (processMsgDoActions_t*) pParam; - - assert(pAction != NULL); - - if((pAction->bExecWhenPrevSusp == 1) && (pDoActData->bPrevWasSuspended == 0)) { - dbgprintf("not calling action because the previous one is not suspended\n"); - ABORT_FINALIZE(RS_RET_OK); - } - - iRetMod = actionCallAction(pAction, pDoActData->pMsg); - if(iRetMod == RS_RET_DISCARDMSG) { - ABORT_FINALIZE(RS_RET_DISCARDMSG); - } else if(iRetMod == RS_RET_SUSPENDED) { - /* indicate suspension for next module to be called */ - pDoActData->bPrevWasSuspended = 1; - } else { - pDoActData->bPrevWasSuspended = 0; - } - -finalize_it: - RETiRet; -} - - -/* Process (consume) a received message. Calls the actions configured. - * rgerhards, 2005-10-13 - */ -static void -processMsg(msg_t *pMsg) -{ - selector_t *f; - int bContinue; - int bProcessMsg; - processMsgDoActions_t DoActData; - rsRetVal iRet; - - BEGINfunc - assert(pMsg != NULL); - - /* log the message to the particular outputs */ - - bContinue = 1; - for (f = Files; f != NULL && bContinue ; f = f->f_next) { - /* first check the filters... */ - iRet = shouldProcessThisMessage(f, pMsg, &bProcessMsg); - if(!bProcessMsg) { - continue; - } - - /* ok -- from here, we have action-specific code, nothing really selector-specific -- rger 2007-08-01 */ - DoActData.pMsg = pMsg; - DoActData.bPrevWasSuspended = 0; - if(llExecFunc(&f->llActList, processMsgDoActions, (void*)&DoActData) == RS_RET_DISCARDMSG) - bContinue = 0; - } - ENDfunc -} - /* The consumer of dequeued messages. This function is called by the * queue engine on dequeueing of a message. It runs on a SEPARATE @@ -1237,7 +951,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, void *pUsr) if((pMsg->msgFlags & NEEDS_PARSING) != 0) { parseMsg(pMsg); } - processMsg(pMsg); + ruleset.ProcessMsg(pCurrRuleset, pMsg); msgDestruct(&pMsg); RETiRet; @@ -1744,7 +1458,6 @@ reapchild() DEFFUNC_llExecFunc(flushRptdMsgsActions) { action_t *pAction = (action_t*) pData; - assert(pAction != NULL); BEGINfunc @@ -1767,20 +1480,12 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) } -/* This method flushes reapeat messages. +/* This method flushes repeat messages. */ static void doFlushRptdMsgs(void) { - register selector_t *f; - - /* see if we need to flush any "message repeated n times"... - * Note that this interferes with objects running on other threads. - * We are using appropriate locking inside the function to handle that. - */ - for (f = Files; f != NULL ; f = f->f_next) { - llExecFunc(&f->llActList, flushRptdMsgsActions, NULL); - } + ruleset.IterateAllActions(flushRptdMsgsActions, NULL); } @@ -1971,6 +1676,16 @@ freeAllDynMemForTermination(void) } +/* Finalize and destruct all actions. + */ +static inline void +destructAllActions(void) +{ + ruleset.DestructAllActions(); + bHaveMainQueue = 0; // flag that internal messages need to be temporarily stored +} + + /* die() is called when the program shall end. This typically only occurs * during sigterm or during the initialization. * As die() is intended to shutdown rsyslogd, it is @@ -2021,7 +1736,7 @@ die(int sig) * repeated msgs. */ dbgprintf("Terminating outputs...\n"); - freeSelectors(); + destructAllActions(); dbgprintf("all primary multi-thread sources have been terminated - now doing aux cleanup...\n"); /* rger 2005-02-22 @@ -2057,7 +1772,7 @@ die(int sig) * rgerhards, 2007-08-03 * I have added some code now, but all that mod init/de-init should be moved to * 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 + * into destructAllActions() - but that needs to be seen. -- rgerhards, 2007-08-09 */ module.UnloadAndDestructAll(eMOD_LINK_ALL); @@ -2185,56 +1900,6 @@ static void doDropPrivUid(int iUid) } -/* helper to freeSelectors(), used with llExecFunc() to flush - * pending output. -- rgerhards, 2007-08-02 - * We do not need to lock the action object here as the processing - * queue is already empty and no other threads are running when - * we call this function. -- rgerhards, 2007-12-12 - */ -DEFFUNC_llExecFunc(freeSelectorsActions) -{ - action_t *pAction = (action_t*) pData; - - assert(pAction != NULL); - - /* flush any pending output */ - if(pAction->f_prevcount) { - actionWriteToAction(pAction); - } - - return RS_RET_OK; /* never fails ;) */ -} - - -/* Close all open log files and free selector descriptor array. - */ -static void freeSelectors(void) -{ - selector_t *f; - selector_t *fPrev; - - if(Files != NULL) { - dbgprintf("Freeing log structures.\n"); - - for(f = Files ; f != NULL ; f = f->f_next) { - llExecFunc(&f->llActList, freeSelectorsActions, NULL); - } - - /* actions flushed and ready for destruction - so do that... */ - f = Files; - while (f != NULL) { - fPrev = f; - f = f->f_next; - selectorDestruct(fPrev); - } - - /* Reflect the deletion of the selectors linked list. */ - Files = NULL; - bHaveMainQueue = 0; - } -} - - /* helper to generateConfigDAG, to print out all actions via * the llExecFunc() facility. * rgerhards, 2007-08-02 @@ -2311,14 +1976,14 @@ DEFFUNC_llExecFunc(generateConfigDAGAction) static rsRetVal generateConfigDAG(uchar *pszDAGFile) { - selector_t *f; + //rule_t *f; FILE *fp; int iActUnit = 1; - int bHasFilter = 0; /* filter associated with this action unit? */ - int bHadFilter; - int i; + //int bHasFilter = 0; /* filter associated with this action unit? */ + //int bHadFilter; + //int i; struct dag_info dagInfo; - char *pszFilterName; + //char *pszFilterName; char szConnectingNode[64]; DEFiRet; @@ -2347,6 +2012,8 @@ generateConfigDAG(uchar *pszDAGFile) strcpy(szConnectingNode, "act0_0"); dagInfo.bDiscarded = 0; +/* TODO: re-enable! */ +#if 0 for(f = Files; f != NULL ; f = f->f_next) { /* BSD-Style filters are currently ignored */ bHadFilter = bHasFilter; @@ -2402,6 +2069,7 @@ generateConfigDAG(uchar *pszDAGFile) ++iActUnit; } +#endif fprintf(fp, "\t%s -> act%d_0\n", szConnectingNode, iActUnit); fprintf(fp, "\tact%d_0\t\t[label=discard shape=box]\n" @@ -2413,20 +2081,6 @@ finalize_it: } -/* helper to dbPrintInitInfo, to print out all actions via - * the llExecFunc() facility. - * rgerhards, 2007-08-02 - */ -DEFFUNC_llExecFunc(dbgPrintInitInfoAction) -{ - DEFiRet; - iRet = actionDbgPrint((action_t*) pData); - dbgprintf("\n"); - - RETiRet; -} - - /* print debug information as part of init(). This pretty much * outputs the whole config of rsyslogd. I've moved this code * out of init() to clean it somewhat up. @@ -2434,46 +2088,7 @@ DEFFUNC_llExecFunc(dbgPrintInitInfoAction) */ static void dbgPrintInitInfo(void) { - selector_t *f; - int iSelNbr = 1; - int i; - - dbgprintf("\nActive selectors:\n"); - for (f = Files; f != NULL ; f = f->f_next) { - dbgprintf("Selector %d:\n", iSelNbr++); - if(f->pCSProgNameComp != NULL) - dbgprintf("tag: '%s'\n", rsCStrGetSzStrNoNULL(f->pCSProgNameComp)); - if(f->eHostnameCmpMode != HN_NO_COMP) - dbgprintf("hostname: %s '%s'\n", - f->eHostnameCmpMode == HN_COMP_MATCH ? - "only" : "allbut", - rsCStrGetSzStrNoNULL(f->pCSHostnameComp)); - if(f->f_filter_type == FILTER_PRI) { - for (i = 0; i <= LOG_NFACILITIES; i++) - if (f->f_filterData.f_pmask[i] == TABLE_NOPRI) - dbgprintf(" X "); - else - dbgprintf("%2X ", f->f_filterData.f_pmask[i]); - } else if(f->f_filter_type == FILTER_EXPR) { - dbgprintf("EXPRESSION-BASED Filter: can currently not be displayed"); - } else { - dbgprintf("PROPERTY-BASED Filter:\n"); - dbgprintf("\tProperty.: '%s'\n", - rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSPropName)); - dbgprintf("\tOperation: "); - if(f->f_filterData.prop.isNegated) - dbgprintf("NOT "); - dbgprintf("'%s'\n", getFIOPName(f->f_filterData.prop.operation)); - dbgprintf("\tValue....: '%s'\n", - rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSCompValue)); - dbgprintf("\tAction...: "); - } - - dbgprintf("\nActions:\n"); - llExecFunc(&f->llActList, dbgPrintInitInfoAction, NULL); /* actions */ - - dbgprintf("\n"); - } + ruleset.DebugPrintAll(); dbgprintf("\n"); if(bDebugPrintTemplateList) tplPrintList(); @@ -2553,13 +2168,13 @@ startInputModules(void) static rsRetVal init(void) { - DEFiRet; rsRetVal localRet; int iNbrActions; int bHadConfigErr = 0; char cbuf[BUFSIZ]; char bufStartUpMsg[512]; struct sigaction sigAct; + DEFiRet; thrdTerminateAll(); /* stop all running input threads - TODO: reconsider location! */ @@ -2580,7 +2195,7 @@ init(void) /* Close all open log files and free log descriptor array. This also frees * all output-modules instance data. */ - freeSelectors(); + destructAllActions(); /* Unload all non-static modules */ dbgprintf("Unloading non-static modules.\n"); @@ -2601,6 +2216,11 @@ init(void) conf.ReInitConf(); + // TODO: move to the right place + ruleset.Construct(&pCurrRuleset); + ruleset.SetName(pCurrRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset")); + ruleset.ConstructFinalize(pCurrRuleset); + /* open the configuration file */ localRet = conf.processConfFile(ConfFile); CHKiRet(conf.GetNbrActActions(&iNbrActions)); @@ -2622,23 +2242,24 @@ init(void) * We ignore any errors while doing this - we would be lost anyhow... */ errmsg.LogError(0, NO_ERRCODE, "EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file!"); - selector_t *f = NULL; /* note: we previously used _POSIY_TTY_NAME_MAX+1, but this turned out to be * too low on linux... :-S -- rgerhards, 2008-07-28 */ char szTTYNameBuf[128]; - conf.cfline((uchar*)"*.ERR\t" _PATH_CONSOLE, &f); - conf.cfline((uchar*)"syslog.*\t" _PATH_CONSOLE, &f); - conf.cfline((uchar*)"*.PANIC\t*", &f); - conf.cfline((uchar*)"syslog.*\troot", &f); + rule_t *pRule; + CHKiRet(rule.Construct(&pRule)); + conf.cfline((uchar*)"*.ERR\t" _PATH_CONSOLE, &pRule); + conf.cfline((uchar*)"syslog.*\t" _PATH_CONSOLE, &pRule); + conf.cfline((uchar*)"*.PANIC\t*", &pRule); + conf.cfline((uchar*)"syslog.*\troot", &pRule); if(ttyname_r(0, szTTYNameBuf, sizeof(szTTYNameBuf)) == 0) { snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf); - conf.cfline((uchar*)cbuf, &f); + conf.cfline((uchar*)cbuf, &pRule); } else { dbgprintf("error %d obtaining controlling terminal, not using that emergency rule\n", errno); } - selectorAddList(f); + ruleset.AddRule(pCurrRuleset, &pRule); } legacyOptsHook(); @@ -2777,53 +2398,6 @@ finalize_it: } -/* add a completely-processed selector (after config line parsing) to - * the linked list of selectors. We now need to check - * if it has any actions associated and, if so, link it to the linked - * list. If it has nothing associated with it, we can simply discard - * it. - * We have one special case during initialization: then, the current - * selector is NULL, which means we do not need to care about it at - * all. -- rgerhards, 2007-08-01 - */ -rsRetVal -selectorAddList(selector_t *f) -{ - DEFiRet; - int iActionCnt; - - static selector_t *nextp = NULL; /* TODO: make this go away (see comment below) */ - - if(f != NULL) { - CHKiRet(llGetNumElts(&f->llActList, &iActionCnt)); - if(iActionCnt == 0) { - errmsg.LogError(0, NO_ERRCODE, "warning: selector line without actions will be discarded"); - selectorDestruct(f); - } else { - /* successfully created an entry */ - dbgprintf("selector line successfully processed\n"); - /* TODO: we should use the linked list class for the selector list, else we need to add globals - * ... well nextp could be added temporarily... - * Thanks to varmojfekoj for having the idea to just use "Files" to make this - * code work. I had actually forgotten to fix the code here before moving to 1.18.0. - * And, of course, I also did not migrate the selector_t structure to the linked list class. - * However, that should still be one of the very next things to happen. - * rgerhards, 2007-08-06 - */ - if(Files == NULL) { - Files = f; - } else { - nextp->f_next = f; - } - nextp = f; - } - } - -finalize_it: - RETiRet; -} - - /* set the main message queue mode * rgerhards, 2008-01-03 */ @@ -2911,7 +2485,6 @@ DEFFUNC_llExecFunc(doHUPActions) static inline void doHUP(void) { - selector_t *f; char buf[512]; snprintf(buf, sizeof(buf) / sizeof(char), @@ -2926,9 +2499,7 @@ doHUP(void) init(); /* main queue is stopped as part of init() */ } else { DBGPRINTF("Received SIGHUP, configured to be a non-restart type of HUP - notifying actions.\n"); - for(f = Files; f != NULL ; f = f->f_next) { - llExecFunc(&f->llActList, doHUPActions, NULL); - } + ruleset.IterateAllActions(doHUPActions, NULL); } } @@ -3285,14 +2856,14 @@ InitGlobalClasses(void) CHKiRet(objUse(errmsg, CORE_COMPONENT)); pErrObj = "module"; CHKiRet(objUse(module, CORE_COMPONENT)); - pErrObj = "var"; - CHKiRet(objUse(var, CORE_COMPONENT)); pErrObj = "datetime"; CHKiRet(objUse(datetime, CORE_COMPONENT)); - pErrObj = "vm"; - CHKiRet(objUse(vm, CORE_COMPONENT)); pErrObj = "expr"; CHKiRet(objUse(expr, CORE_COMPONENT)); + pErrObj = "rule"; + CHKiRet(objUse(rule, CORE_COMPONENT)); + pErrObj = "ruleset"; + CHKiRet(objUse(ruleset, CORE_COMPONENT)); pErrObj = "conf"; CHKiRet(objUse(conf, CORE_COMPONENT)); @@ -3336,10 +2907,10 @@ GlobalClassExit(void) /* first, release everything we used ourself */ objRelease(net, LM_NET_FILENAME);/* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ objRelease(conf, CORE_COMPONENT); + objRelease(ruleset, CORE_COMPONENT); + objRelease(rule, CORE_COMPONENT); objRelease(expr, CORE_COMPONENT); vmClassExit(); /* this is hack, currently core_modules do not get this automatically called */ - objRelease(vm, CORE_COMPONENT); - objRelease(var, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); /* TODO: implement the rest of the deinit */ -- cgit v1.2.3 From 1c8fe77b78a64d69138b30ec28b430677b197601 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 10 Jun 2009 19:03:38 +0200 Subject: added $Ruleset config command so we now can define multiple rule sets, we just can not use them ;) That means we have the foundation to bind listeners to different rule sets. --- tools/syslogd.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 183c7760..f4b59970 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2398,6 +2398,32 @@ finalize_it: } +/* Begin a new rule set. The new rule set is created, and all rules that now + * follow go into that rule set. + * TODO: we may later add the capability to switch back to an already existing + * rule set. + * NOTE: pCurrRuleset is NOT desructed and must not be! The ruleset class keeps + * a list of all known rule sets, and can destruct them at the end of execution. + * pCurrRuleset is just a shortcut so that "everyone" knows which ruleset to + * extend. + * TODO: A problem with this function is the way config lines are processed. The rule + * is actually only written when the next rule is completely read. That way, this + * (past) rule goes into the wrong (new) ruleset. I need to see how to fix this best... + * rgerhards, 2009-06-10 + */ +static rsRetVal beginNewRuleset(void __attribute__((unused)) *pVal, uchar *pszName) +{ + DEFiRet; + CHKiRet(ruleset.Construct(&pCurrRuleset)); + CHKiRet(ruleset.SetName(pCurrRuleset, pszName)); + CHKiRet(ruleset.ConstructFinalize(pCurrRuleset)); + +finalize_it: + free(pszName); /* no longer needed */ + RETiRet; +} + + /* set the main message queue mode * rgerhards, 2008-01-03 */ @@ -2651,6 +2677,7 @@ static rsRetVal loadBuildInModules(void) * This, I think, is the right thing to do. -- rgerhards, 2007-07-31 */ CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, beginNewRuleset, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL)); -- cgit v1.2.3 From 1af948107e6e520788e374adccf4986bf07e92f5 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 12 Jun 2009 10:14:45 +0200 Subject: fixed abort when emergency configuration was activated this regression was introduced last friday, so this is *NOT* present in any released version. --- tools/syslogd.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f4b59970..96f3cb34 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2247,12 +2247,11 @@ init(void) * too low on linux... :-S -- rgerhards, 2008-07-28 */ char szTTYNameBuf[128]; - rule_t *pRule; - CHKiRet(rule.Construct(&pRule)); - conf.cfline((uchar*)"*.ERR\t" _PATH_CONSOLE, &pRule); - conf.cfline((uchar*)"syslog.*\t" _PATH_CONSOLE, &pRule); - conf.cfline((uchar*)"*.PANIC\t*", &pRule); - conf.cfline((uchar*)"syslog.*\troot", &pRule); + rule_t *pRule = NULL; /* initialization to NULL is *vitally* important! */ + conf.cfline(UCHAR_CONSTANT("*.ERR\t" _PATH_CONSOLE), &pRule); + conf.cfline(UCHAR_CONSTANT("syslog.*\t" _PATH_CONSOLE), &pRule); + conf.cfline(UCHAR_CONSTANT("*.PANIC\t*"), &pRule); + conf.cfline(UCHAR_CONSTANT("syslog.*\troot"), &pRule); if(ttyname_r(0, szTTYNameBuf, sizeof(szTTYNameBuf)) == 0) { snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf); conf.cfline((uchar*)cbuf, &pRule); -- cgit v1.2.3 From e3d9843c85b1dfddabc937ac6ccb4057d626bf03 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 12 Jun 2009 11:47:00 +0200 Subject: re-enabled pipe, tty and console in omfile ... by moving code to stream.c. Thanks to the new design, new cases are not really needed, resulting in cleaner code. I also did a cleanup of header file usage as a side-activity. --- tools/syslogd.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 96f3cb34..05c61059 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -138,6 +138,7 @@ #include "unicode-helper.h" #include "ruleset.h" #include "rule.h" +#include "net.h" #include "vm.h" /* definitions for objects we access */ @@ -221,7 +222,7 @@ static rsRetVal GlobalClassExit(void); #endif #ifndef _PATH_TTY -#define _PATH_TTY "/dev/tty" +# define _PATH_TTY "/dev/tty" #endif static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */ @@ -504,7 +505,7 @@ static char **crunch_list(char *list) void untty(void) #ifdef HAVE_SETSID { - if ( !Debug ) { + if(!Debug) { setsid(); } return; @@ -513,18 +514,18 @@ void untty(void) { int i; - if ( !Debug ) { + if(!Debug) { i = open(_PATH_TTY, O_RDWR|O_CLOEXEC); if (i >= 0) { # if !defined(__hpux) - (void) ioctl(i, (int) TIOCNOTTY, (char *)0); + (void) ioctl(i, (int) TIOCNOTTY, NULL); # else /* TODO: we need to implement something for HP UX! -- rgerhards, 2008-03-04 */ /* actually, HP UX should have setsid, so the code directly above should * trigger. So the actual question is why it doesn't do that... */ # endif - (void) close(i); + close(i); } } } -- cgit v1.2.3 From ca0ddc30a3edce02a440904a01f0b866c0f82b5a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 12 Jun 2009 15:31:08 +0200 Subject: completed multi-ruleset core support ... as well as added multi-ruleset support for imtcp --- tools/syslogd.c | 75 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 28 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 05c61059..99bf281d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -249,8 +249,6 @@ int repeatinterval[2] = { 30, 60 }; /* # of secs before flush */ #define LIST_DELIMITER ':' /* delimiter between two hosts */ -ruleset_t *pCurrRuleset; /* ruleset that is currently being processed */ - static pid_t ppid; /* This is a quick and dirty hack used for spliting main/startup thread */ typedef struct legacyOptsLL_s { @@ -952,7 +950,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, void *pUsr) if((pMsg->msgFlags & NEEDS_PARSING) != 0) { parseMsg(pMsg); } - ruleset.ProcessMsg(pCurrRuleset, pMsg); + ruleset.ProcessMsg(pMsg); msgDestruct(&pMsg); RETiRet; @@ -2172,6 +2170,7 @@ init(void) rsRetVal localRet; int iNbrActions; int bHadConfigErr = 0; + ruleset_t *pRuleset; char cbuf[BUFSIZ]; char bufStartUpMsg[512]; struct sigaction sigAct; @@ -2217,10 +2216,10 @@ init(void) conf.ReInitConf(); - // TODO: move to the right place - ruleset.Construct(&pCurrRuleset); - ruleset.SetName(pCurrRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset")); - ruleset.ConstructFinalize(pCurrRuleset); + /* construct the default ruleset */ + ruleset.Construct(&pRuleset); + ruleset.SetName(pRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset")); + ruleset.ConstructFinalize(pRuleset); /* open the configuration file */ localRet = conf.processConfFile(ConfFile); @@ -2259,7 +2258,7 @@ init(void) } else { dbgprintf("error %d obtaining controlling terminal, not using that emergency rule\n", errno); } - ruleset.AddRule(pCurrRuleset, &pRule); + ruleset.AddRule(ruleset.GetCurrent(), &pRule); } legacyOptsHook(); @@ -2398,25 +2397,45 @@ finalize_it: } -/* Begin a new rule set. The new rule set is created, and all rules that now - * follow go into that rule set. - * TODO: we may later add the capability to switch back to an already existing - * rule set. - * NOTE: pCurrRuleset is NOT desructed and must not be! The ruleset class keeps - * a list of all known rule sets, and can destruct them at the end of execution. - * pCurrRuleset is just a shortcut so that "everyone" knows which ruleset to - * extend. - * TODO: A problem with this function is the way config lines are processed. The rule - * is actually only written when the next rule is completely read. That way, this - * (past) rule goes into the wrong (new) ruleset. I need to see how to fix this best... - * rgerhards, 2009-06-10 +/* Switch the default ruleset (that, what servcies bind to if nothing specific + * is specified). + * rgerhards, 2009-06-12 + */ +static rsRetVal +setDefaultRuleset(void __attribute__((unused)) *pVal, uchar *pszName) +{ + DEFiRet; + + CHKiRet(ruleset.SetDefaultRuleset(pszName)); + +finalize_it: + free(pszName); /* no longer needed */ + RETiRet; +} + + +/* Switch to either an already existing rule set or start a new one. The + * named rule set becomes the new "current" rule set (what means that new + * actions are added to it). + * rgerhards, 2009-06-12 */ -static rsRetVal beginNewRuleset(void __attribute__((unused)) *pVal, uchar *pszName) +static rsRetVal +setCurrRuleset(void __attribute__((unused)) *pVal, uchar *pszName) { + ruleset_t *pRuleset; + rsRetVal localRet; DEFiRet; - CHKiRet(ruleset.Construct(&pCurrRuleset)); - CHKiRet(ruleset.SetName(pCurrRuleset, pszName)); - CHKiRet(ruleset.ConstructFinalize(pCurrRuleset)); + + localRet = ruleset.SetCurrRuleset(pszName); + + if(localRet == RS_RET_NOT_FOUND) { + DBGPRINTF("begin new current rule set '%s'\n", pszName); + CHKiRet(ruleset.Construct(&pRuleset)); + CHKiRet(ruleset.SetName(pRuleset, pszName)); + CHKiRet(ruleset.ConstructFinalize(pRuleset)); + } else { + ABORT_FINALIZE(localRet); + } finalize_it: free(pszName); /* no longer needed */ @@ -2658,7 +2677,7 @@ static rsRetVal loadBuildInModules(void) } /* dirty, but this must be for the time being: the usrmsg module must always be - * loaded as last module. This is because it processes any time of action selector. + * loaded as last module. This is because it processes any type of action selector. * If we load it before other modules, these others will never have a chance of * working with the config file. We may change that implementation so that a user name * must start with an alnum, that would definitely help (but would it break backwards @@ -2666,8 +2685,7 @@ static rsRetVal loadBuildInModules(void) * User names now must begin with: * [a-zA-Z0-9_.] */ - if((iRet = module.doModInit(modInitUsrMsg, (uchar*) "builtin-usrmsg", NULL)) != RS_RET_OK) - RETiRet; + CHKiRet(module.doModInit(modInitUsrMsg, (uchar*) "builtin-usrmsg", 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 @@ -2677,7 +2695,8 @@ static rsRetVal loadBuildInModules(void) * This, I think, is the right thing to do. -- rgerhards, 2007-07-31 */ CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, beginNewRuleset, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"defaultruleset", 0, eCmdHdlrGetWord, setDefaultRuleset, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, setCurrRuleset, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL)); -- cgit v1.2.3 From ff6232d2bee06fbbc25ad83a1cf3bb798884679a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 15 Jun 2009 08:12:14 +0200 Subject: bugfix: error messages were not emitted to stderr in forked mode stderr and stdo are now kept open across fork() --- tools/syslogd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 357f6699..0f63f1bc 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -925,7 +925,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) * permits us to process unmodified config files which otherwise contain a * supressor statement. */ - if(((Debug || NoFork) && bErrMsgToStderr) || iConfigVerify) { + if(bErrMsgToStderr || iConfigVerify) { fprintf(stderr, "rsyslogd: %s\n", msg); } @@ -3096,7 +3096,9 @@ doGlblProcessInit(void) exit(1); /* "good" exit - after forking, not diasabling anything */ } num_fds = getdtablesize(); - for (i= 0; i < num_fds; i++) + close(0); + /* we keep stdout and stderr open in case we have to emit something */ + for (i = 3; i < num_fds; i++) (void) close(i); untty(); } @@ -3532,6 +3534,7 @@ finalize_it: */ int main(int argc, char **argv) { + fprintf(stderr, "rsyslogd startup\n"); dbgClassInit(); return realMain(argc, argv); } -- cgit v1.2.3 From 7f78b2ef65634d4320325cca4793caa3d50ef777 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 15 Jun 2009 08:13:41 +0200 Subject: removed forgotten debug message --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 0f63f1bc..1bbf1904 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3534,7 +3534,6 @@ finalize_it: */ int main(int argc, char **argv) { - fprintf(stderr, "rsyslogd startup\n"); dbgClassInit(); return realMain(argc, argv); } -- cgit v1.2.3 From 16ecb90c3ac88bb2261c31c990d88f97f1a1b32f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 15 Jun 2009 13:44:51 +0200 Subject: omfile buffers are now synchronized after inactivity This is the first shot at this functionality. Currently, we run off a fixed counter in the rsyslogd mainloop, which needs to be restructured. But this code works, so it is a good time for a commit. --- tools/syslogd.c | 44 +++----------------------------------------- 1 file changed, 3 insertions(+), 41 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 99bf281d..2b29cd7c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2575,7 +2575,8 @@ mainloop(void) * powertop, for example). In that case, we primarily wait for a signal, * but a once-a-day wakeup should be quite acceptable. -- rgerhards, 2008-06-09 */ - tvSelectTimeout.tv_sec = (bReduceRepeatMsgs == 1) ? TIMERINTVL : 86400 /*1 day*/; + //tvSelectTimeout.tv_sec = (bReduceRepeatMsgs == 1) ? TIMERINTVL : 86400 /*1 day*/; +tvSelectTimeout.tv_sec = 5; // TESTING ONLY!!! TODO: change back!!! tvSelectTimeout.tv_usec = 0; select(1, NULL, NULL, NULL, &tvSelectTimeout); if(bFinished) @@ -2610,49 +2611,11 @@ mainloop(void) bHadHUP = 0; continue; } + execScheduled(); /* handle Apc calls (if any) */ } ENDfunc } -/* If user is not root, prints warnings or even exits - * TODO: check all dynafiles for write permission - * ... but it is probably better to wait here until we have - * a module interface - rgerhards, 2007-07-23 - */ -static void checkPermissions() -{ -#if 0 - /* TODO: this function must either be redone or removed - now with the input modules, - * there is no such simple check we can do. What we can check, however, is if there is - * any input module active and terminate, if not. -- rgerhards, 2007-12-26 - */ - /* we are not root */ - if (geteuid() != 0) - { - fputs("WARNING: Local messages will not be logged! If you want to log them, run rsyslog as root.\n",stderr); -#ifdef SYSLOG_INET - /* udp enabled and port number less than or equal to 1024 */ - if ( AcceptRemote && (atoi(LogPort) <= 1024) ) - fprintf(stderr, "WARNING: Will not listen on UDP port %s. Use port number higher than 1024 or run rsyslog as root!\n", LogPort); - - /* tcp enabled and port number less or equal to 1024 */ - if( bEnableTCP && (atoi(TCPLstnPort) <= 1024) ) - fprintf(stderr, "WARNING: Will not listen on TCP port %s. Use port number higher than 1024 or run rsyslog as root!\n", TCPLstnPort); - - /* Neither explicit high UDP port nor explicit high TCP port. - * It is useless to run anymore */ - if( !(AcceptRemote && (atoi(LogPort) > 1024)) && !( bEnableTCP && (atoi(TCPLstnPort) > 1024)) ) - { -#endif - fprintf(stderr, "ERROR: Nothing to log, no reason to run. Please run rsyslog as root.\n"); - exit(EXIT_FAILURE); -#ifdef SYSLOG_INET - } -#endif - } -#endif -} - /* load build-in modules * very first version begun on 2007-07-23 by rgerhards @@ -3053,7 +3016,6 @@ doGlblProcessInit(void) int i; DEFiRet; - checkPermissions(); thrdInit(); if( !(Debug || NoFork) ) -- cgit v1.2.3 From 015d17ca70e81ad998e32cdfeed3cd925fd7dedc Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Jun 2009 08:46:45 +0200 Subject: some performance optimizations - saved gettimeofday() calls in imtcp (and increased reception buffer) - somewhat optimized stringbuf.c - some other optimizations --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b43b7a37..a9f1dbdb 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -639,7 +639,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime)); } if(pszInputName != NULL) - MsgSetInputName(pMsg, pszInputName); + MsgSetInputName(pMsg, pszInputName, ustrlen(pszInputName)); MsgSetFlowControlType(pMsg, flowCtlType); MsgSetRawMsg(pMsg, (char*)msg); @@ -947,7 +947,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) DEFiRet; CHKiRet(msgConstruct(&pMsg)); - MsgSetInputName(pMsg, UCHAR_CONSTANT("rsyslogd")); + MsgSetInputName(pMsg, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd")-1); MsgSetUxTradMsg(pMsg, (char*)msg); MsgSetRawMsg(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName()); -- cgit v1.2.3 From f7579e68a67364c8040966be57c2eae4c9550ee5 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Jun 2009 11:36:05 +0200 Subject: done various optimizations to the stringbuf and its users --- tools/syslogd.c | 170 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 85 insertions(+), 85 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a9f1dbdb..c224087d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -553,7 +553,7 @@ static char **crunch_list(char *list) #if 0 count=0; while (result[count]) - dbgprintf("#%d: %s\n", count, StripDomains[count++]); + DBGPRINTF("#%d: %s\n", count, StripDomains[count++]); #endif return result; } @@ -780,7 +780,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla * rgerhards, 2007-09-14 */ if(*(msg + len - 1) == '\0') { - dbgprintf("dropped NUL at very end of message\n"); + DBGPRINTF("dropped NUL at very end of message\n"); len--; } @@ -790,7 +790,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla * turn on/off this handling. rgerhards, 2007-07-23 */ if(bDropTrailingLF && *(msg + len - 1) == '\n') { - dbgprintf("dropped LF at very end of message (DropTrailingLF is set)\n"); + DBGPRINTF("dropped LF at very end of message (DropTrailingLF is set)\n"); len--; } @@ -815,7 +815,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla iLenDefBuf = iMaxLine; CHKmalloc(deflateBuf = malloc(sizeof(uchar) * (iMaxLine + 1))); ret = uncompress((uchar *) deflateBuf, &iLenDefBuf, (uchar *) msg+1, len-1); - dbgprintf("Compressed message uncompressed with status %d, length: new %ld, old %d.\n", + DBGPRINTF("Compressed message uncompressed with status %d, length: new %ld, old %d.\n", ret, (long) iLenDefBuf, len-1); /* Now check if the uncompression worked. If not, there is not much we can do. In * that case, we log an error message but ignore the message itself. Storing the @@ -861,7 +861,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla * (I couldn't do any more smart things anyway...). * rgerhards, 2007-9-20 */ - dbgprintf("internal error: iMsg > max msg size in printchopped()\n"); + DBGPRINTF("internal error: iMsg > max msg size in printchopped()\n"); } FINALIZE; /* in this case, we are done... nothing left we can do */ } @@ -1025,14 +1025,14 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce } else if(f->eHostnameCmpMode == HN_COMP_MATCH) { if(rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) { /* not equal, so we are already done... */ - dbgprintf("hostname filter '+%s' does not match '%s'\n", + DBGPRINTF("hostname filter '+%s' does not match '%s'\n", rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg)); FINALIZE; } } else { /* must be -hostname */ if(!rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) { /* not equal, so we are already done... */ - dbgprintf("hostname filter '-%s' does not match '%s'\n", + DBGPRINTF("hostname filter '-%s' does not match '%s'\n", rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg)); FINALIZE; } @@ -1053,7 +1053,7 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce if((!bEqv && !bInv) || (bEqv && bInv)) { /* not equal or inverted selection, so we are already done... */ - dbgprintf("programname filter '%s' does not match '%s'\n", + DBGPRINTF("programname filter '%s' does not match '%s'\n", rsCStrGetSzStrNoNULL(f->pCSProgNameComp), getProgramName(pMsg)); FINALIZE; } @@ -1063,7 +1063,7 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce if(f->f_filter_type == FILTER_PRI) { /* skip messages that are incorrect priority */ - if ( (f->f_filterData.f_pmask[pMsg->iFacility] == TABLE_NOPRI) || \ + if ( (f->f_filterData.f_pmask[pMsg->iFacility] == TABLE_NOPRI) || ((f->f_filterData.f_pmask[pMsg->iFacility] & (1<iSeverity)) == 0) ) bRet = 0; else @@ -1074,7 +1074,7 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce CHKiRet(vm.SetMsg(pVM, pMsg)); CHKiRet(vm.ExecProg(pVM, f->f_filterData.f_expr->pVmprg)); CHKiRet(vm.PopBoolFromStack(pVM, &pResult)); - dbgprintf("result of expression evaluation: %lld\n", pResult->val.num); + DBGPRINTF("result of expression evaluation: %lld\n", pResult->val.num); /* VM is destructed on function exit */ bRet = (pResult->val.num) ? 1 : 0; } else { @@ -1166,7 +1166,7 @@ DEFFUNC_llExecFunc(processMsgDoActions) assert(pAction != NULL); if((pAction->bExecWhenPrevSusp == 1) && (pDoActData->bPrevWasSuspended == 0)) { - dbgprintf("not calling action because the previous one is not suspended\n"); + DBGPRINTF("not calling action because the previous one is not suspended\n"); ABORT_FINALIZE(RS_RET_OK); } @@ -1399,7 +1399,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); } } else { - dbgprintf("no TIMESTAMP detected!\n"); + DBGPRINTF("no TIMESTAMP detected!\n"); bContParse = 0; } @@ -1561,7 +1561,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) /* indeed, this smells like a TAG, so lets use it for this. We take * the HOSTNAME from the sender system instead. */ - dbgprintf("HOSTNAME contains invalid characters, assuming it to be a TAG.\n"); + DBGPRINTF("HOSTNAME contains invalid characters, assuming it to be a TAG.\n"); moveHOSTNAMEtoTAG(pMsg); MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); } @@ -1586,22 +1586,21 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * the records: the code is currently clean, but we could optimize it! */ if(!bTAGCharDetected) { uchar *pszTAG; - if(rsCStrConstruct(&pStrB) != RS_RET_OK) + if(cstrConstruct(&pStrB) != RS_RET_OK) return 1; rsCStrSetAllocIncrement(pStrB, 33); pWork = pBuf; iCnt = 0; while(*p2parse && *p2parse != ':' && *p2parse != ' ') { - rsCStrAppendChar(pStrB, *p2parse++); + cstrAppendChar(pStrB, *p2parse++); ++iCnt; } if(*p2parse == ':') { ++p2parse; - rsCStrAppendChar(pStrB, ':'); + cstrAppendChar(pStrB, ':'); } - rsCStrFinish(pStrB); - - rsCStrConvSzStrAndDestruct(pStrB, &pszTAG, 1); + cstrFinalize(pStrB); + cstrConvSzStrAndDestruct(pStrB, &pszTAG, 1); if(pszTAG == NULL) { /* rger, 2005-11-10: no TAG found - this implies that what * we have considered to be the HOSTNAME is most probably the @@ -1611,7 +1610,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * the hostname. This situation is the standard case with * stock BSD syslogd. */ - dbgprintf("No TAG in message, assuming that HOSTNAME is missing.\n"); + DBGPRINTF("No TAG in message, assuming that HOSTNAME is missing.\n"); moveHOSTNAMEtoTAG(pMsg); MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); } else { /* we have a TAG, so we can happily set it ;) */ @@ -1627,7 +1626,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) */ if(!(flags & INTERNAL_MSG)) { - dbgprintf("HOSTNAME and TAG not parsed by user configuraton.\n"); + DBGPRINTF("HOSTNAME and TAG not parsed by user configuraton.\n"); MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); } } @@ -1688,7 +1687,7 @@ logmsg(msg_t *pMsg, int flags) assert(pMsg != NULL); assert(pMsg->pszUxTradMsg != NULL); msg = (char*) pMsg->pszUxTradMsg; - dbgprintf("logmsg: flags %x, from '%s', msg %s\n", flags, getRcvFrom(pMsg), msg); + DBGPRINTF("logmsg: flags %x, from '%s', msg %s\n", flags, getRcvFrom(pMsg), msg); /* rger 2005-11-24 (happy thanksgiving!): we now need to check if we have * a traditional syslog message or one formatted according to syslog-protocol. @@ -1696,14 +1695,14 @@ logmsg(msg_t *pMsg, int flags) * -protocol VERSION field for the detection. */ if(msg[0] == '1' && msg[1] == ' ') { - dbgprintf("Message has syslog-protocol format.\n"); + DBGPRINTF("Message has syslog-protocol format.\n"); setProtocolVersion(pMsg, 1); if(parseRFCSyslogMsg(pMsg, flags) == 1) { msgDestruct(&pMsg); return; } } else { /* we have legacy syslog */ - dbgprintf("Message has legacy syslog format.\n"); + DBGPRINTF("Message has legacy syslog format.\n"); setProtocolVersion(pMsg, 0); if(parseLegacySyslogMsg(pMsg, flags) == 1) { msgDestruct(&pMsg); @@ -1753,7 +1752,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) * in an acceptable way. -- rgerhards, 2008-09-16 */ if (pAction->f_prevcount && time(NULL) >= REPEATTIME(pAction)) { - dbgprintf("flush %s: repeated %d times, %d sec.\n", + DBGPRINTF("flush %s: repeated %d times, %d sec.\n", module.GetStateName(pAction->pMod), pAction->f_prevcount, repeatinterval[pAction->f_repeatcount]); actionWriteToAction(pAction); @@ -1789,9 +1788,9 @@ static void debug_switch() if(debugging_on == 0) { debugging_on = 1; - dbgprintf("Switching debugging_on to true\n"); + DBGPRINTF("Switching debugging_on to true\n"); } else { - dbgprintf("Switching debugging_on to false\n"); + DBGPRINTF("Switching debugging_on to false\n"); debugging_on = 0; } @@ -1935,7 +1934,7 @@ void legacyOptsParseTCP(char ch, char *arg) * a minimal delay, but it is much cleaner than the approach of doing everything * inside the signal handler. * rgerhards, 2005-10-26 - * Note: we do not call dbgprintf() as this may cause us to block in case something + * Note: we do not call DBGPRINTF() as this may cause us to block in case something * with the threading is wrong. */ static void doDie(int sig) @@ -1983,7 +1982,7 @@ die(int sig) { char buf[256]; - dbgprintf("exiting on signal %d\n", sig); + DBGPRINTF("exiting on signal %d\n", sig); /* IMPORTANT: we should close the inputs first, and THEN send our termination * message. If we do it the other way around, logmsgInternal() may block on @@ -1998,7 +1997,7 @@ die(int sig) */ /* close the inputs */ - dbgprintf("Terminating input threads...\n"); + DBGPRINTF("Terminating input threads...\n"); thrdTerminateAll(); /* and THEN send the termination log message (see long comment above) */ @@ -2012,17 +2011,17 @@ die(int sig) } /* drain queue (if configured so) and stop main queue worker thread pool */ - dbgprintf("Terminating main queue...\n"); + DBGPRINTF("Terminating main queue...\n"); qqueueDestruct(&pMsgQueue); pMsgQueue = NULL; /* Free ressources and close connections. This includes flushing any remaining * repeated msgs. */ - dbgprintf("Terminating outputs...\n"); + DBGPRINTF("Terminating outputs...\n"); freeSelectors(); - dbgprintf("all primary multi-thread sources have been terminated - now doing aux cleanup...\n"); + DBGPRINTF("all primary multi-thread sources have been terminated - now doing aux cleanup...\n"); /* rger 2005-02-22 * now clean up the in-memory structures. OK, the OS * would also take care of that, but if we do it @@ -2060,7 +2059,7 @@ die(int sig) */ module.UnloadAndDestructAll(eMOD_LINK_ALL); - dbgprintf("Clean shutdown completed, bye\n"); + DBGPRINTF("Clean shutdown completed, bye\n"); /* dbgClassExit MUST be the last one, because it de-inits the debug system */ dbgClassExit(); @@ -2117,7 +2116,7 @@ static rsRetVal setMaxFiles(void __attribute__((unused)) *pVal, int iFiles) iFiles, errStr, (long) maxFiles.rlim_max); ABORT_FINALIZE(RS_RET_ERR_RLIM_NOFILE); } - dbgprintf("Max number of files set to %d [kernel max %ld].\n", iFiles, (long) maxFiles.rlim_max); + DBGPRINTF("Max number of files set to %d [kernel max %ld].\n", iFiles, (long) maxFiles.rlim_max); finalize_it: RETiRet; @@ -2128,7 +2127,7 @@ finalize_it: static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask) { umask(iUmask); - dbgprintf("umask set to 0%3.3o.\n", iUmask); + DBGPRINTF("umask set to 0%3.3o.\n", iUmask); return RS_RET_OK; } @@ -2213,7 +2212,7 @@ static void freeSelectors(void) selector_t *fPrev; if(Files != NULL) { - dbgprintf("Freeing log structures.\n"); + DBGPRINTF("Freeing log structures.\n"); for(f = Files ; f != NULL ; f = f->f_next) { llExecFunc(&f->llActList, freeSelectorsActions, NULL); @@ -2420,7 +2419,7 @@ DEFFUNC_llExecFunc(dbgPrintInitInfoAction) { DEFiRet; iRet = actionDbgPrint((action_t*) pData); - dbgprintf("\n"); + DBGPRINTF("\n"); RETiRet; } @@ -2437,43 +2436,44 @@ static void dbgPrintInitInfo(void) int iSelNbr = 1; int i; - dbgprintf("\nActive selectors:\n"); + DBGPRINTF("\nActive selectors:\n"); for (f = Files; f != NULL ; f = f->f_next) { - dbgprintf("Selector %d:\n", iSelNbr++); + DBGPRINTF("Selector %d:\n", iSelNbr++); if(f->pCSProgNameComp != NULL) - dbgprintf("tag: '%s'\n", rsCStrGetSzStrNoNULL(f->pCSProgNameComp)); + DBGPRINTF("tag: '%s'\n", rsCStrGetSzStrNoNULL(f->pCSProgNameComp)); if(f->eHostnameCmpMode != HN_NO_COMP) - dbgprintf("hostname: %s '%s'\n", + DBGPRINTF("hostname: %s '%s'\n", f->eHostnameCmpMode == HN_COMP_MATCH ? "only" : "allbut", rsCStrGetSzStrNoNULL(f->pCSHostnameComp)); if(f->f_filter_type == FILTER_PRI) { for (i = 0; i <= LOG_NFACILITIES; i++) - if (f->f_filterData.f_pmask[i] == TABLE_NOPRI) - dbgprintf(" X "); - else - dbgprintf("%2X ", f->f_filterData.f_pmask[i]); + if (f->f_filterData.f_pmask[i] == TABLE_NOPRI) { + DBGPRINTF(" X "); + } else { + DBGPRINTF("%2X ", f->f_filterData.f_pmask[i]); + } } else if(f->f_filter_type == FILTER_EXPR) { - dbgprintf("EXPRESSION-BASED Filter: can currently not be displayed"); + DBGPRINTF("EXPRESSION-BASED Filter: can currently not be displayed"); } else { - dbgprintf("PROPERTY-BASED Filter:\n"); - dbgprintf("\tProperty.: '%s'\n", + DBGPRINTF("PROPERTY-BASED Filter:\n"); + DBGPRINTF("\tProperty.: '%s'\n", rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSPropName)); - dbgprintf("\tOperation: "); + DBGPRINTF("\tOperation: "); if(f->f_filterData.prop.isNegated) - dbgprintf("NOT "); - dbgprintf("'%s'\n", getFIOPName(f->f_filterData.prop.operation)); - dbgprintf("\tValue....: '%s'\n", + DBGPRINTF("NOT "); + DBGPRINTF("'%s'\n", getFIOPName(f->f_filterData.prop.operation)); + DBGPRINTF("\tValue....: '%s'\n", rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSCompValue)); - dbgprintf("\tAction...: "); + DBGPRINTF("\tAction...: "); } - dbgprintf("\nActions:\n"); + DBGPRINTF("\nActions:\n"); llExecFunc(&f->llActList, dbgPrintInitInfoAction, NULL); /* actions */ - dbgprintf("\n"); + DBGPRINTF("\n"); } - dbgprintf("\n"); + DBGPRINTF("\n"); if(bDebugPrintTemplateList) tplPrintList(); if(bDebugPrintModuleList) @@ -2483,24 +2483,24 @@ static void dbgPrintInitInfo(void) if(bDebugPrintCfSysLineHandlerList) dbgPrintCfSysLineHandlers(); - dbgprintf("Messages with malicious PTR DNS Records are %sdropped.\n", + DBGPRINTF("Messages with malicious PTR DNS Records are %sdropped.\n", glbl.GetDropMalPTRMsgs() ? "" : "not "); - dbgprintf("Control characters are %sreplaced upon reception.\n", + DBGPRINTF("Control characters are %sreplaced upon reception.\n", bEscapeCCOnRcv? "" : "not "); if(bEscapeCCOnRcv) - dbgprintf("Control character escape sequence prefix is '%c'.\n", + DBGPRINTF("Control character escape sequence prefix is '%c'.\n", cCCEscapeChar); - dbgprintf("Main queue size %d messages.\n", iMainMsgQueueSize); - dbgprintf("Main queue worker threads: %d, wThread shutdown: %d, Perists every %d updates.\n", + DBGPRINTF("Main queue size %d messages.\n", iMainMsgQueueSize); + DBGPRINTF("Main queue worker threads: %d, wThread shutdown: %d, Perists every %d updates.\n", iMainMsgQueueNumWorkers, iMainMsgQtoWrkShutdown, iMainMsgQPersistUpdCnt); - dbgprintf("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n", + DBGPRINTF("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n", iMainMsgQtoQShutdown, iMainMsgQtoActShutdown, iMainMsgQtoEnq); - dbgprintf("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n", + DBGPRINTF("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n", iMainMsgQHighWtrMark, iMainMsgQLowWtrMark, iMainMsgQDiscardMark, iMainMsgQDiscardSeverity); - dbgprintf("Main queue save on shutdown %d, max disk space allowed %lld\n", + DBGPRINTF("Main queue save on shutdown %d, max disk space allowed %lld\n", bMainMsgQSaveOnShutdown, iMainMsgQueMaxDiskSpace); /* TODO: add iActionRetryCount = 0; @@ -2511,7 +2511,7 @@ static void dbgPrintInitInfo(void) setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100); setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", 1); */ - dbgprintf("Work Directory: '%s'.\n", glbl.GetWorkDir()); + DBGPRINTF("Work Directory: '%s'.\n", glbl.GetWorkDir()); } @@ -2534,7 +2534,7 @@ startInputModules(void) /* activate here */ thrdCreate(pMod->mod.im.runInput, pMod->mod.im.afterRun); } else { - dbgprintf("module %lx will not run, iRet %d\n", (unsigned long) pMod, iRet); + DBGPRINTF("module %lx will not run, iRet %d\n", (unsigned long) pMod, iRet); } pMod = module.GetNxtType(pMod, eMOD_IN); } @@ -2567,11 +2567,11 @@ init(void) pDfltProgNameCmp = NULL; eDfltHostnameCmpMode = HN_NO_COMP; - dbgprintf("rsyslog %s - called init()\n", VERSION); + DBGPRINTF("rsyslog %s - called init()\n", VERSION); /* delete the message queue, which also flushes all messages left over */ if(pMsgQueue != NULL) { - dbgprintf("deleting main message queue\n"); + DBGPRINTF("deleting main message queue\n"); qqueueDestruct(&pMsgQueue); /* delete pThis here! */ pMsgQueue = NULL; } @@ -2582,10 +2582,10 @@ init(void) freeSelectors(); /* Unload all non-static modules */ - dbgprintf("Unloading non-static modules.\n"); + DBGPRINTF("Unloading non-static modules.\n"); module.UnloadAndDestructAll(eMOD_LINK_DYNAMIC_LOADED); - dbgprintf("Clearing templates.\n"); + DBGPRINTF("Clearing templates.\n"); tplDeleteNew(); /* re-setting values to defaults (where applicable) */ @@ -2635,7 +2635,7 @@ init(void) snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf); conf.cfline((uchar*)cbuf, &f); } else { - dbgprintf("error %d obtaining controlling terminal, not using that emergency rule\n", errno); + DBGPRINTF("error %d obtaining controlling terminal, not using that emergency rule\n", errno); } selectorAddList(f); } @@ -2741,7 +2741,7 @@ init(void) } bHaveMainQueue = (MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1; - dbgprintf("Main processing queue is initialized and running\n"); + DBGPRINTF("Main processing queue is initialized and running\n"); /* the output part and the queue is now ready to run. So it is a good time * to start the inputs. Please note that the net code above should be @@ -2768,7 +2768,7 @@ init(void) sigAct.sa_handler = sighup_handler; sigaction(SIGHUP, &sigAct, NULL); - dbgprintf(" (re)started.\n"); + DBGPRINTF(" (re)started.\n"); finalize_it: RETiRet; @@ -2799,7 +2799,7 @@ selectorAddList(selector_t *f) selectorDestruct(f); } else { /* successfully created an entry */ - dbgprintf("selector line successfully processed\n"); + DBGPRINTF("selector line successfully processed\n"); /* TODO: we should use the linked list class for the selector list, else we need to add globals * ... well nextp could be added temporarily... * Thanks to varmojfekoj for having the idea to just use "Files" to make this @@ -2831,16 +2831,16 @@ static rsRetVal setMainMsgQueType(void __attribute__((unused)) *pVal, uchar *psz if (!strcasecmp((char *) pszType, "fixedarray")) { MainMsgQueType = QUEUETYPE_FIXED_ARRAY; - dbgprintf("main message queue type set to FIXED_ARRAY\n"); + DBGPRINTF("main message queue type set to FIXED_ARRAY\n"); } else if (!strcasecmp((char *) pszType, "linkedlist")) { MainMsgQueType = QUEUETYPE_LINKEDLIST; - dbgprintf("main message queue type set to LINKEDLIST\n"); + DBGPRINTF("main message queue type set to LINKEDLIST\n"); } else if (!strcasecmp((char *) pszType, "disk")) { MainMsgQueType = QUEUETYPE_DISK; - dbgprintf("main message queue type set to DISK\n"); + DBGPRINTF("main message queue type set to DISK\n"); } else if (!strcasecmp((char *) pszType, "direct")) { MainMsgQueType = QUEUETYPE_DIRECT; - dbgprintf("main message queue type set to DIRECT (no queueing at all)\n"); + DBGPRINTF("main message queue type set to DIRECT (no queueing at all)\n"); } else { errmsg.LogError(0, RS_RET_INVALID_PARAMS, "unknown mainmessagequeuetype parameter: %s", (char *) pszType); iRet = RS_RET_INVALID_PARAMS; @@ -3219,7 +3219,7 @@ static rsRetVal mainThread() CHKiRet(init()); if(Debug && debugging_on) { - dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); + DBGPRINTF("Debugging enabled, SIGUSR1 to turn off debugging.\n"); } /* Send a signal to the parent so it can terminate. */ @@ -3251,7 +3251,7 @@ static rsRetVal mainThread() * do the init() and then restart things. * rgerhards, 2005-10-24 */ - dbgprintf("initialization completed, transitioning to regular run mode\n"); + DBGPRINTF("initialization completed, transitioning to regular run mode\n"); mainloop(); @@ -3458,7 +3458,7 @@ doGlblProcessInit(void) if( !(Debug || NoFork) ) { - dbgprintf("Checking pidfile.\n"); + DBGPRINTF("Checking pidfile.\n"); if (!check_pid(PidFile)) { memset(&sigAct, 0, sizeof (sigAct)); @@ -3494,7 +3494,7 @@ doGlblProcessInit(void) } /* tuck my process id away */ - dbgprintf("Writing pidfile %s.\n", PidFile); + DBGPRINTF("Writing pidfile %s.\n", PidFile); if (!check_pid(PidFile)) { if (!write_pid(PidFile)) @@ -3640,7 +3640,7 @@ int realMain(int argc, char **argv) if ((argc -= optind)) usage(); - dbgprintf("rsyslogd %s startup, compatibility mode %d, module path '%s'\n", + DBGPRINTF("rsyslogd %s startup, compatibility mode %d, module path '%s'\n", VERSION, iCompatibilityMode, glblModPath == NULL ? "" : (char*)glblModPath); /* we are done with the initial option parsing and processing. Now we init the system. */ @@ -3722,7 +3722,7 @@ int realMain(int argc, char **argv) /* END core initializations - we now come back to carrying out command line options*/ while((iRet = bufOptRemove(&ch, &arg)) == RS_RET_OK) { - dbgprintf("deque option %c, optarg '%s'\n", ch, (arg == NULL) ? "" : arg); + DBGPRINTF("deque option %c, optarg '%s'\n", ch, (arg == NULL) ? "" : arg); switch((char)ch) { case '4': glbl.SetDefPFFamily(PF_INET); -- cgit v1.2.3 From 74b2b24f508be90d20961304d5e3cce648f3eb7c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Jun 2009 12:31:27 +0200 Subject: removed long-obsoleted property UxTradMsg ... as well as some cleanup (some commented-out code is left to support UxTradMsg again is someone really complains ;)). --- tools/syslogd.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index c224087d..2f06d273 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -670,16 +670,9 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f if((pMsg->msgFlags & PARSE_HOSTNAME) == 0) MsgSetHOSTNAME(pMsg, hname); MsgSetRcvFrom(pMsg, hname); + MsgSetAfterPRIOffs(pMsg, p - msg); CHKiRet(MsgSetRcvFromIP(pMsg, hnameIP)); - /* rgerhards 2004-11-19: well, well... we've now seen that we - * have the "hostname problem" also with the traditional Unix - * message. As we like to emulate it, we need to add the hostname - * to it. - */ - if(MsgSetUxTradMsg(pMsg, (char*)p) != 0) - ABORT_FINALIZE(RS_RET_ERR); - logmsg(pMsg, flags); finalize_it: @@ -948,7 +941,6 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) CHKiRet(msgConstruct(&pMsg)); MsgSetInputName(pMsg, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd")-1); - MsgSetUxTradMsg(pMsg, (char*)msg); MsgSetRawMsg(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName()); MsgSetRcvFrom(pMsg, glbl.GetLocalHostName()); @@ -1370,8 +1362,8 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) BEGINfunc assert(pMsg != NULL); - assert(pMsg->pszUxTradMsg != NULL); - p2parse = pMsg->pszUxTradMsg; + assert(pMsg->pszRawMsg != NULL); + p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ /* do a sanity check on the version and eat it */ assert(p2parse[0] == '1' && p2parse[1] == ' '); @@ -1471,8 +1463,8 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) BEGINfunc assert(pMsg != NULL); - assert(pMsg->pszUxTradMsg != NULL); - p2parse = pMsg->pszUxTradMsg; + assert(pMsg->pszRawMsg != NULL); + p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ /* Check to see if msg contains a timestamp. We start by assuming * that the message timestamp is the time of reciption (which we @@ -1685,8 +1677,9 @@ logmsg(msg_t *pMsg, int flags) BEGINfunc assert(pMsg != NULL); - assert(pMsg->pszUxTradMsg != NULL); - msg = (char*) pMsg->pszUxTradMsg; + assert(pMsg->pszRawMsg != NULL); + + msg = (char*) pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ DBGPRINTF("logmsg: flags %x, from '%s', msg %s\n", flags, getRcvFrom(pMsg), msg); /* rger 2005-11-24 (happy thanksgiving!): we now need to check if we have -- cgit v1.2.3 From aef1a38fe8c7472362904b2f90c67113b21034ab Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Jun 2009 13:28:18 +0200 Subject: fixing problems that occurred during the last merge --- tools/syslogd.c | 291 -------------------------------------------------------- 1 file changed, 291 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index fd4bc937..ea8eff7a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -925,233 +925,6 @@ finalize_it: RETiRet; } -/* This functions looks at the given message and checks if it matches the - * provided filter condition. If so, it returns true, else it returns - * false. This is a helper to logmsg() and meant to drive the decision - * process if a message is to be processed or not. As I expect this - * decision code to grow more complex over time AND logmsg() is already - * a very lengthy function, I thought a separate function is more appropriate. - * 2005-09-19 rgerhards - * 2008-02-25 rgerhards: changed interface, now utilizes iRet, bProcessMsg - * returns is message should be procesed. - */ -static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProcessMsg) -{ - DEFiRet; - unsigned short pbMustBeFreed; - char *pszPropVal; - int bRet = 0; - vm_t *pVM = NULL; - var_t *pResult = NULL; - - assert(f != NULL); - assert(pMsg != NULL); - - /* we first have a look at the global, BSD-style block filters (for tag - * and host). Only if they match, we evaluate the actual filter. - * rgerhards, 2005-10-18 - */ - if(f->eHostnameCmpMode == HN_NO_COMP) { - /* EMPTY BY INTENSION - we check this value first, because - * it is the one most often used, so this saves us time! - */ - } else if(f->eHostnameCmpMode == HN_COMP_MATCH) { - if(rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) { - /* not equal, so we are already done... */ - DBGPRINTF("hostname filter '+%s' does not match '%s'\n", - rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg)); - FINALIZE; - } - } else { /* must be -hostname */ - if(!rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) { - /* not equal, so we are already done... */ - DBGPRINTF("hostname filter '-%s' does not match '%s'\n", - rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg)); - FINALIZE; - } - } - - if(f->pCSProgNameComp != NULL) { - int bInv = 0, bEqv = 0, offset = 0; - if(*(rsCStrGetSzStrNoNULL(f->pCSProgNameComp)) == '-') { - if(*(rsCStrGetSzStrNoNULL(f->pCSProgNameComp) + 1) == '-') - offset = 1; - else { - bInv = 1; - offset = 1; - } - } - if(!rsCStrOffsetSzStrCmp(f->pCSProgNameComp, offset, (uchar*) getProgramName(pMsg), getProgramNameLen(pMsg))) - bEqv = 1; - - if((!bEqv && !bInv) || (bEqv && bInv)) { - /* not equal or inverted selection, so we are already done... */ - DBGPRINTF("programname filter '%s' does not match '%s'\n", - rsCStrGetSzStrNoNULL(f->pCSProgNameComp), getProgramName(pMsg)); - FINALIZE; - } - } - - /* done with the BSD-style block filters */ - - if(f->f_filter_type == FILTER_PRI) { - /* skip messages that are incorrect priority */ - if ( (f->f_filterData.f_pmask[pMsg->iFacility] == TABLE_NOPRI) || - ((f->f_filterData.f_pmask[pMsg->iFacility] & (1<iSeverity)) == 0) ) - bRet = 0; - else - bRet = 1; - } else if(f->f_filter_type == FILTER_EXPR) { - CHKiRet(vm.Construct(&pVM)); - CHKiRet(vm.ConstructFinalize(pVM)); - CHKiRet(vm.SetMsg(pVM, pMsg)); - CHKiRet(vm.ExecProg(pVM, f->f_filterData.f_expr->pVmprg)); - CHKiRet(vm.PopBoolFromStack(pVM, &pResult)); - DBGPRINTF("result of expression evaluation: %lld\n", pResult->val.num); - /* VM is destructed on function exit */ - bRet = (pResult->val.num) ? 1 : 0; - } else { - assert(f->f_filter_type == FILTER_PROP); /* assert() just in case... */ - pszPropVal = MsgGetProp(pMsg, NULL, f->f_filterData.prop.pCSPropName, &pbMustBeFreed); - - /* Now do the compares (short list currently ;)) */ - switch(f->f_filterData.prop.operation ) { - case FIOP_CONTAINS: - if(rsCStrLocateInSzStr(f->f_filterData.prop.pCSCompValue, (uchar*) pszPropVal) != -1) - bRet = 1; - break; - case FIOP_ISEQUAL: - if(rsCStrSzStrCmp(f->f_filterData.prop.pCSCompValue, - (uchar*) pszPropVal, strlen(pszPropVal)) == 0) - bRet = 1; /* process message! */ - break; - case FIOP_STARTSWITH: - if(rsCStrSzStrStartsWithCStr(f->f_filterData.prop.pCSCompValue, - (uchar*) pszPropVal, strlen(pszPropVal)) == 0) - bRet = 1; /* process message! */ - break; - case FIOP_REGEX: - if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue, - (unsigned char*) pszPropVal, 0, &f->f_filterData.prop.regex_cache) == RS_RET_OK) - bRet = 1; - break; - case FIOP_EREREGEX: - if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue, - (unsigned char*) pszPropVal, 1, &f->f_filterData.prop.regex_cache) == RS_RET_OK) - bRet = 1; - break; - default: - /* here, it handles NOP (for performance reasons) */ - assert(f->f_filterData.prop.operation == FIOP_NOP); - bRet = 1; /* as good as any other default ;) */ - break; - } - - /* now check if the value must be negated */ - if(f->f_filterData.prop.isNegated) - bRet = (bRet == 1) ? 0 : 1; - - if(Debug) { - dbgprintf("Filter: check for property '%s' (value '%s') ", - rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSPropName), - pszPropVal); - if(f->f_filterData.prop.isNegated) - dbgprintf("NOT "); - dbgprintf("%s '%s': %s\n", - getFIOPName(f->f_filterData.prop.operation), - rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSCompValue), - bRet ? "TRUE" : "FALSE"); - } - - /* cleanup */ - if(pbMustBeFreed) - free(pszPropVal); - } - -finalize_it: - /* destruct in any case, not just on error, but it makes error handling much easier */ - if(pVM != NULL) - vm.Destruct(&pVM); - - if(pResult != NULL) - var.Destruct(&pResult); - - *bProcessMsg = bRet; - RETiRet; -} - - -/* helper to processMsg(), used to call the configured actions. It is - * executed from within llExecFunc() of the action list. - * rgerhards, 2007-08-02 - */ -typedef struct processMsgDoActions_s { - int bPrevWasSuspended; /* was the previous action suspended? */ - msg_t *pMsg; -} processMsgDoActions_t; -DEFFUNC_llExecFunc(processMsgDoActions) -{ - DEFiRet; - rsRetVal iRetMod; /* return value of module - we do not always pass that back */ - action_t *pAction = (action_t*) pData; - processMsgDoActions_t *pDoActData = (processMsgDoActions_t*) pParam; - - assert(pAction != NULL); - - if((pAction->bExecWhenPrevSusp == 1) && (pDoActData->bPrevWasSuspended == 0)) { - DBGPRINTF("not calling action because the previous one is not suspended\n"); - ABORT_FINALIZE(RS_RET_OK); - } - - iRetMod = actionCallAction(pAction, pDoActData->pMsg); - if(iRetMod == RS_RET_DISCARDMSG) { - ABORT_FINALIZE(RS_RET_DISCARDMSG); - } else if(iRetMod == RS_RET_SUSPENDED) { - /* indicate suspension for next module to be called */ - pDoActData->bPrevWasSuspended = 1; - } else { - pDoActData->bPrevWasSuspended = 0; - } - -finalize_it: - RETiRet; -} - - -/* Process (consume) a received message. Calls the actions configured. - * rgerhards, 2005-10-13 - */ -static void -processMsg(msg_t *pMsg) -{ - selector_t *f; - int bContinue; - int bProcessMsg; - processMsgDoActions_t DoActData; - rsRetVal iRet; - - BEGINfunc - assert(pMsg != NULL); - - /* log the message to the particular outputs */ - - bContinue = 1; - for (f = Files; f != NULL && bContinue ; f = f->f_next) { - /* first check the filters... */ - iRet = shouldProcessThisMessage(f, pMsg, &bProcessMsg); - if(!bProcessMsg) { - continue; - } - - /* ok -- from here, we have action-specific code, nothing really selector-specific -- rger 2007-08-01 */ - DoActData.pMsg = pMsg; - DoActData.bPrevWasSuspended = 0; - if(llExecFunc(&f->llActList, processMsgDoActions, (void*)&DoActData) == RS_RET_DISCARDMSG) - bContinue = 0; - } - ENDfunc -} - /* The consumer of dequeued messages. This function is called by the * queue engine on dequeueing of a message. It runs on a SEPARATE @@ -2118,56 +1891,6 @@ static void doDropPrivUid(int iUid) } -/* helper to freeSelectors(), used with llExecFunc() to flush - * pending output. -- rgerhards, 2007-08-02 - * We do not need to lock the action object here as the processing - * queue is already empty and no other threads are running when - * we call this function. -- rgerhards, 2007-12-12 - */ -DEFFUNC_llExecFunc(freeSelectorsActions) -{ - action_t *pAction = (action_t*) pData; - - assert(pAction != NULL); - - /* flush any pending output */ - if(pAction->f_prevcount) { - actionWriteToAction(pAction); - } - - return RS_RET_OK; /* never fails ;) */ -} - - -/* Close all open log files and free selector descriptor array. - */ -static void freeSelectors(void) -{ - selector_t *f; - selector_t *fPrev; - - if(Files != NULL) { - DBGPRINTF("Freeing log structures.\n"); - - for(f = Files ; f != NULL ; f = f->f_next) { - llExecFunc(&f->llActList, freeSelectorsActions, NULL); - } - - /* actions flushed and ready for destruction - so do that... */ - f = Files; - while (f != NULL) { - fPrev = f; - f = f->f_next; - selectorDestruct(fPrev); - } - - /* Reflect the deletion of the selectors linked list. */ - Files = NULL; - bHaveMainQueue = 0; - } -} - - /* helper to generateConfigDAG, to print out all actions via * the llExecFunc() facility. * rgerhards, 2007-08-02 @@ -2349,20 +2072,6 @@ finalize_it: } -/* helper to dbPrintInitInfo, to print out all actions via - * the llExecFunc() facility. - * rgerhards, 2007-08-02 - */ -DEFFUNC_llExecFunc(dbgPrintInitInfoAction) -{ - DEFiRet; - iRet = actionDbgPrint((action_t*) pData); - DBGPRINTF("\n"); - - RETiRet; -} - - /* print debug information as part of init(). This pretty much * outputs the whole config of rsyslogd. I've moved this code * out of init() to clean it somewhat up. -- cgit v1.2.3 From 6f0db63e9b962edf6305860b608500e8c650b71b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Jun 2009 15:13:47 +0200 Subject: milestone: input-side multiSubmit capability ... commit before I try to touch the queue side ;) --- tools/syslogd.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ea8eff7a..4d2839a1 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1345,8 +1345,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) } -/* submit a fully created message to the main message queue. The message is - * fully processed and parsed, so no parsing at all happens. This is primarily +/* submit a message to the main message queue. This is primarily * a hook to prevent the need for callers to know about the main message queue * (which may change in the future as we will probably have multiple rule * sets and thus queues...). @@ -1366,6 +1365,29 @@ submitMsg(msg_t *pMsg) } +/* submit multiple messages at once, very similar to submitMsg, just + * for multi_submit_t. + * rgerhards, 2009-06-16 + */ +rsRetVal +multiSubmitMsg(multi_submit_t *pMultiSub) +{ + int i; + DEFiRet; + assert(pMultiSub != NULL); + + for(i = 0 ; i < pMultiSub->nElem ; ++i) { +dbgprintf("multiSubmitMsg, index %d\n", i); + MsgPrepareEnqueue(pMultiSub->ppMsgs[i]); + qqueueEnqObj(pMsgQueue, pMultiSub->ppMsgs[i]->flowCtlType, (void*) pMultiSub->ppMsgs[i]); + } + + pMultiSub->nElem = 0; + + RETiRet; +} + + /* Log a message to the appropriate log files, users, etc. based on * the priority. * rgerhards 2004-11-08: actually, this also decodes all but the PRI part. -- cgit v1.2.3 From c4e18c5bab66537ee9c8fb482edce62c7c39c247 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Jun 2009 15:43:22 +0200 Subject: implemented first version of multi-enqueue support, queue side --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4d2839a1..e3cd54f7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1379,9 +1379,9 @@ multiSubmitMsg(multi_submit_t *pMultiSub) for(i = 0 ; i < pMultiSub->nElem ; ++i) { dbgprintf("multiSubmitMsg, index %d\n", i); MsgPrepareEnqueue(pMultiSub->ppMsgs[i]); - qqueueEnqObj(pMsgQueue, pMultiSub->ppMsgs[i]->flowCtlType, (void*) pMultiSub->ppMsgs[i]); } + iRet = qqueueMultiEnqObj(pMsgQueue, pMultiSub); pMultiSub->nElem = 0; RETiRet; -- cgit v1.2.3 From 56e462610db0dc71cfc2e4af17d1eb27bd67fae7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 17 Jun 2009 12:56:58 +0200 Subject: further optimized message object pri, facility and severity string generation simplified --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e3cd54f7..9f70ff26 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1377,7 +1377,6 @@ multiSubmitMsg(multi_submit_t *pMultiSub) assert(pMultiSub != NULL); for(i = 0 ; i < pMultiSub->nElem ; ++i) { -dbgprintf("multiSubmitMsg, index %d\n", i); MsgPrepareEnqueue(pMultiSub->ppMsgs[i]); } -- cgit v1.2.3 From d2d54013aebb756169182ed8716b142d27134a70 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 17 Jun 2009 15:22:13 +0200 Subject: going forward in moving string-handling functions to new interface... --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 9f70ff26..cfecfd83 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1051,7 +1051,7 @@ static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult) return 0; } -/* parse a RFC-formatted syslog message. This function returns +/* parse a RFC5424-formatted syslog message. This function returns * 0 if processing of the message shall continue and 1 if something * went wrong and this messe should be ignored. This function has been * implemented in the effort to support syslog-protocol. Please note that -- cgit v1.2.3 From bca66bc1399d1b9bcc370c64b5a8befb2244695d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 18 Jun 2009 11:10:28 +0200 Subject: some minor bugfixes - bugfix: invalid error message issued if $inlcudeConfig was on an empty set of files (e.g. *.conf, where none such files existed) thanks to Michael Biebl for reporting this bug - bugfix: when run in foreground (but not in debug mode), a debug message ("DoDie called") was emitted at shutdown. Removed. thanks to Michael Biebl for reporting this bug - bugfix: some garbagge was emitted to stderr on shutdown. This garbage consisted of file names, which were written during startup (key point: not a pointer error) thanks to Michael Biebl for reporting this bug - bugfix: startup and shutdown message were emitted to stdout thanks to Michael Biebl for reporting this bug --- tools/syslogd.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 1bbf1904..6f32b262 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -903,7 +903,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) MsgSetRcvFrom(pMsg, (char*)glbl.GetLocalHostName()); MsgSetRcvFromIP(pMsg, (uchar*)"127.0.0.1"); /* check if we have an error code associated and, if so, - * adjust the tag. -- r5gerhards, 2008-06-27 + * adjust the tag. -- rgerhards, 2008-06-27 */ if(iErr == NO_ERRCODE) { MsgSetTAG(pMsg, "rsyslogd:"); @@ -925,8 +925,9 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) * permits us to process unmodified config files which otherwise contain a * supressor statement. */ - if(bErrMsgToStderr || iConfigVerify) { - fprintf(stderr, "rsyslogd: %s\n", msg); + if(((Debug || NoFork) && bErrMsgToStderr) || iConfigVerify) { + if(LOG_PRI(pri) == LOG_ERR) + fprintf(stderr, "rsyslogd: %s\n", msg); } if(bHaveMainQueue == 0) { /* not yet in queued mode */ @@ -1882,10 +1883,10 @@ static void doDie(int sig) # define MSG1 "DoDie called.\n" # define MSG2 "DoDie called 5 times - unconditional exit\n" static int iRetries = 0; /* debug aid */ - if(Debug || NoFork) + if(Debug) write(1, MSG1, sizeof(MSG1) - 1); if(iRetries++ == 4) { - if(Debug || NoFork) + if(Debug) write(1, MSG2, sizeof(MSG2) - 1); abort(); } @@ -2442,7 +2443,7 @@ init(void) */ snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ - "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] restart", + "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] (re)start", (int) myPid); logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, 0); -- cgit v1.2.3 From 8628312396b1535c41124e499d292f4d1e77d955 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 18 Jun 2009 13:22:21 +0200 Subject: cleaned up/optimized raw message handling in msg object --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 034111f5..91918d96 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -582,7 +582,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f if(pszInputName != NULL) MsgSetInputName(pMsg, pszInputName, ustrlen(pszInputName)); MsgSetFlowControlType(pMsg, flowCtlType); - MsgSetRawMsg(pMsg, (char*)msg); + MsgSetRawMsgWOSize(pMsg, (char*)msg); /* test for special codes */ pri = DEFUPRI; @@ -882,7 +882,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) CHKiRet(msgConstruct(&pMsg)); MsgSetInputName(pMsg, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd")-1); - MsgSetRawMsg(pMsg, (char*)msg); + MsgSetRawMsgWOSize(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName()); MsgSetRcvFrom(pMsg, glbl.GetLocalHostName()); MsgSetRcvFromIP(pMsg, UCHAR_CONSTANT("127.0.0.1")); -- cgit v1.2.3 From 2f86678c577ee469852ffae35123c4a90b12d214 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 18 Jun 2009 14:30:21 +0200 Subject: optimized TAG handling in msg object --- tools/syslogd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 91918d96..8e804d8f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -890,11 +890,11 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) * adjust the tag. -- rgerhards, 2008-06-27 */ if(iErr == NO_ERRCODE) { - MsgSetTAG(pMsg, "rsyslogd:"); + MsgSetTAG(pMsg, UCHAR_CONSTANT("rsyslogd:"), sizeof("rsyslogd:") - 1); } else { - snprintf((char*)pszTag, sizeof(pszTag), "rsyslogd%d:", iErr); + size_t len = snprintf((char*)pszTag, sizeof(pszTag), "rsyslogd%d:", iErr); pszTag[32] = '\0'; /* just to make sure... */ - MsgSetTAG(pMsg, (char*)pszTag); + MsgSetTAG(pMsg, pszTag, len); } pMsg->iFacility = LOG_FAC(pri); pMsg->iSeverity = LOG_PRI(pri); -- cgit v1.2.3 From 2de4964affabc1ccf61bc72426a468fc871a54d0 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 18 Jun 2009 16:51:40 +0200 Subject: optimized handling of MSG part in msg object WARNING: currently, message repeation processing is disabled, must be reenabled (but prefer to do some other tests first) --- tools/syslogd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 8e804d8f..11f4ebd9 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1146,7 +1146,8 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) } /* MSG */ - MsgSetMSG(pMsg, (char*)p2parse); + MsgSetMSGoffs(pMsg, p2parse - pMsg->pszRawMsg); + //MsgSetMSG(pMsg, (char*)p2parse); free(pBuf); ENDfunc @@ -1339,7 +1340,9 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) } /* The rest is the actual MSG */ - MsgSetMSG(pMsg, (char*)p2parse); +dbgprintf("XXX: msg set msg offset %d, str: '%s', prev '%s'\n", p2parse - pMsg->pszRawMsg, pMsg->pszRawMsg + (p2parse - pMsg->pszRawMsg), p2parse); +// MsgSetMSG(pMsg, (char*)p2parse); + MsgSetMSGoffs(pMsg, p2parse - pMsg->pszRawMsg); ENDfunc return 0; /* all ok */ -- cgit v1.2.3 From 7a695d171436fe249770e8256ae48cd4ed86fd30 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 19 Jun 2009 12:03:56 +0200 Subject: removed uniprocessor optimization ... as it was not even optimal on uniprocessors any longer ;) I keep the config directive in, maybe we can utilize it again at some later point in time (questionable). --- tools/syslogd.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 11f4ebd9..16f08c21 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1340,8 +1340,6 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) } /* The rest is the actual MSG */ -dbgprintf("XXX: msg set msg offset %d, str: '%s', prev '%s'\n", p2parse - pMsg->pszRawMsg, pMsg->pszRawMsg + (p2parse - pMsg->pszRawMsg), p2parse); -// MsgSetMSG(pMsg, (char*)p2parse); MsgSetMSGoffs(pMsg, p2parse - pMsg->pszRawMsg); ENDfunc -- cgit v1.2.3 From ce5869f7c41c8db943d8cbe804b69af40d43e2e6 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 22 Jun 2009 18:52:30 +0200 Subject: optimized processing of TAG message field --- tools/syslogd.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 16f08c21..ed826fc1 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1173,9 +1173,9 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) uchar *p2parse; char *pBuf; char *pWork; - cstr_t *pStrB; - int iCnt; int bTAGCharDetected; + int i; /* general index for parsing */ + uchar bufParseTAG[CONF_TAG_MAXSIZE]; BEGINfunc assert(pMsg != NULL); @@ -1293,23 +1293,16 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * is the max size ;) we need to shuffle the code again... Just for * the records: the code is currently clean, but we could optimize it! */ if(!bTAGCharDetected) { - uchar *pszTAG; - if(cstrConstruct(&pStrB) != RS_RET_OK) - return 1; - rsCStrSetAllocIncrement(pStrB, 33); - pWork = pBuf; - iCnt = 0; - while(*p2parse && *p2parse != ':' && *p2parse != ' ') { - cstrAppendChar(pStrB, *p2parse++); - ++iCnt; + i = 0; + while(*p2parse && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE) { + bufParseTAG[i++] = *p2parse++; } if(*p2parse == ':') { ++p2parse; - cstrAppendChar(pStrB, ':'); + bufParseTAG[i++] = ':'; } - cstrFinalize(pStrB); - cstrConvSzStrAndDestruct(pStrB, &pszTAG, 1); - if(pszTAG == NULL) + + if(i == 0) { /* rger, 2005-11-10: no TAG found - this implies that what * we have considered to be the HOSTNAME is most probably the * TAG. We consider it so probable, that we now adjust it @@ -1322,7 +1315,8 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) moveHOSTNAMEtoTAG(pMsg); MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); } else { /* we have a TAG, so we can happily set it ;) */ - MsgAssignTAG(pMsg, pszTAG); + bufParseTAG[i] = '\0'; /* terminate string */ + MsgSetTAG(pMsg, bufParseTAG, i); } } else { /* we have no TAG, so we ... */ -- cgit v1.2.3 From b50d13a6a97c0b6fa14807775ae0edf52ef015fb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 23 Jun 2009 14:50:03 +0200 Subject: restored repeated message reduction processing --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ed826fc1..178ad455 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1469,6 +1469,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) assert(pAction != NULL); BEGINfunc +RUNLOG_VAR("%p", pAction); LockObj(pAction); /* TODO: time() performance: the call below could be moved to * the beginn of the llExec(). This makes it slightly less correct, but -- cgit v1.2.3 From b1f2e53921b7ab19c363a63de47a0e7a35866052 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 23 Jun 2009 15:17:55 +0200 Subject: prevented unneccessary apc calls --- tools/syslogd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 178ad455..385fef1c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1469,7 +1469,6 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) assert(pAction != NULL); BEGINfunc -RUNLOG_VAR("%p", pAction); LockObj(pAction); /* TODO: time() performance: the call below could be moved to * the beginn of the llExec(). This makes it slightly less correct, but @@ -2586,7 +2585,7 @@ mainloop(void) * but a once-a-day wakeup should be quite acceptable. -- rgerhards, 2008-06-09 */ //tvSelectTimeout.tv_sec = (bReduceRepeatMsgs == 1) ? TIMERINTVL : 86400 /*1 day*/; -tvSelectTimeout.tv_sec = 5; // TESTING ONLY!!! TODO: change back!!! + tvSelectTimeout.tv_sec = TIMERINTVL; /* TODO: change this back to the above code when we have a better solution for apc */ tvSelectTimeout.tv_usec = 0; select(1, NULL, NULL, NULL, &tvSelectTimeout); if(bFinished) -- cgit v1.2.3 From 86e37f70fe0e9de0e00362990c73536843c8fef3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 23 Jun 2009 16:14:19 +0200 Subject: more strict parsing of the hostname in rfc3164 mode ... hopefully removes false positives (but may cause some trouble with hostname parsing). For details, see this bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=126 This patch is not optimal for v4 - another one will follow. The spirit of this commit is to enable easier backporting if someone is interested in doing so. --- tools/syslogd.c | 114 ++++++++++++++++++++------------------------------------ 1 file changed, 41 insertions(+), 73 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 385fef1c..2f28cde0 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1176,6 +1176,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) int bTAGCharDetected; int i; /* general index for parsing */ uchar bufParseTAG[CONF_TAG_MAXSIZE]; + uchar bufParseHOSTNAME[CONF_TAG_HOSTNAME]; BEGINfunc assert(pMsg != NULL); @@ -1228,50 +1229,27 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * If I find them, I set a simple flag but continue. After parsing, I check the flag. * If it was set, then we most probably do not have a hostname but a TAG. Thus, I change * the fields. I think this logic shall work with any type of syslog message. + * rgerhards, 2009-06-23: and I now have extended this logic to every character + * that is not a valid hostname. */ bTAGCharDetected = 0; if(flags & PARSE_HOSTNAME) { - /* TODO: quick and dirty memory allocation */ - /* the memory allocated is far too much in most cases. But on the plus side, - * it is quite fast... - rgerhards, 2007-09-20 - */ - if((pBuf = malloc(sizeof(char)* (ustrlen(p2parse) +1))) == NULL) - return 1; - pWork = pBuf; - /* this is the actual parsing loop */ - while(*p2parse && *p2parse != ' ' && *p2parse != ':') { - if(*p2parse == '[' || *p2parse == ']' || *p2parse == '/') - bTAGCharDetected = 1; - *pWork++ = *p2parse++; + i = 0; + while((isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.' + || p2parse[i] == '_') && i < CONF_TAG_MAXSIZE) { + bufParseHOSTNAME[i] = p2parse[i]; + ++i; + } + + if(i > 0 && p2parse[i] == ' ' && isalnum(p2parse[i-1])) { + /* we got a hostname! */ + p2parse += i + 1; /* "eat" it (including SP delimiter) */ + bufParseHOSTNAME[i] = '\0'; + MsgSetHOSTNAME(pMsg, bufParseHOSTNAME); + //MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i); + } else { + MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); } - /* we need to handle ':' seperately, because it terminates the - * TAG - so we also need to terminate the parser here! - * rgerhards, 2007-09-10 *p2parse points to a valid address here in - * any case. We can reach this point only if we are at end of string, - * or we have a ':' or ' '. What the if below does is check if we are - * not at end of string and, if so, advance the parse pointer. If we - * are already at end of string, *p2parse is equal to '\0', neither if - * will be true and the parse pointer remain as is. This is perfectly - * well. - */ - if(*p2parse == ':') { - bTAGCharDetected = 1; - /* We will move hostname to tag, so preserve ':' (otherwise we - * will needlessly change the message format) */ - *pWork++ = *p2parse++; - } else if(*p2parse == ' ') - ++p2parse; - *pWork = '\0'; - MsgAssignHOSTNAME(pMsg, pBuf); - } - /* check if we seem to have a TAG */ - if(bTAGCharDetected) { - /* indeed, this smells like a TAG, so lets use it for this. We take - * the HOSTNAME from the sender system instead. - */ - DBGPRINTF("HOSTNAME contains invalid characters, assuming it to be a TAG.\n"); - moveHOSTNAMEtoTAG(pMsg); - MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); } /* now parse TAG - that should be present in message from all sources. @@ -1287,40 +1265,30 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * in RFC3164...). We now receive the full size, but will modify the * outputs so that only 32 characters max are used by default. */ - /* The following code in general is quick & dirty - I need to get - * it going for a test, rgerhards 2004-11-16 */ - /* lol.. we tried to solve it, just to remind ourselfs that 32 octets - * is the max size ;) we need to shuffle the code again... Just for - * the records: the code is currently clean, but we could optimize it! */ - if(!bTAGCharDetected) { - i = 0; - while(*p2parse && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE) { - bufParseTAG[i++] = *p2parse++; - } - if(*p2parse == ':') { - ++p2parse; - bufParseTAG[i++] = ':'; - } + i = 0; + while(*p2parse && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE) { + bufParseTAG[i++] = *p2parse++; + } + if(*p2parse == ':') { + ++p2parse; + bufParseTAG[i++] = ':'; + } - if(i == 0) - { /* rger, 2005-11-10: no TAG found - this implies that what - * we have considered to be the HOSTNAME is most probably the - * TAG. We consider it so probable, that we now adjust it - * that way. So we pick up the previously set hostname, assign - * it to tag and use the sender system (from IP stack) as - * the hostname. This situation is the standard case with - * stock BSD syslogd. - */ - DBGPRINTF("No TAG in message, assuming that HOSTNAME is missing.\n"); - moveHOSTNAMEtoTAG(pMsg); - MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); - } else { /* we have a TAG, so we can happily set it ;) */ - bufParseTAG[i] = '\0'; /* terminate string */ - MsgSetTAG(pMsg, bufParseTAG, i); - } - } else { - /* we have no TAG, so we ... */ - /*DO NOTHING*/; + if(i == 0) + { /* rger, 2005-11-10: no TAG found - this implies that what + * we have considered to be the HOSTNAME is most probably the + * TAG. We consider it so probable, that we now adjust it + * that way. So we pick up the previously set hostname, assign + * it to tag and use the sender system (from IP stack) as + * the hostname. This situation is the standard case with + * stock BSD syslogd. + */ + DBGPRINTF("No TAG in message, assuming that HOSTNAME is missing.\n"); + moveHOSTNAMEtoTAG(pMsg); + MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); + } else { /* we have a TAG, so we can happily set it ;) */ + bufParseTAG[i] = '\0'; /* terminate string */ + MsgSetTAG(pMsg, bufParseTAG, i); } } else { /* we enter this code area when the user has instructed rsyslog NOT -- cgit v1.2.3 From 662ad3e4bf8dbd317d18aa1afcbf3e8b9e424506 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 23 Jun 2009 16:32:29 +0200 Subject: optimized hostname processing --- tools/syslogd.c | 47 +++++++++++------------------------------------ 1 file changed, 11 insertions(+), 36 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 2f28cde0..faa793fb 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -609,7 +609,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f * being the local host). rgerhards 2004-11-16 */ if((pMsg->msgFlags & PARSE_HOSTNAME) == 0) - MsgSetHOSTNAME(pMsg, hname); + MsgSetHOSTNAME(pMsg, hname, strlen(hname)); MsgSetRcvFrom(pMsg, hname); MsgSetAfterPRIOffs(pMsg, p - msg); CHKiRet(MsgSetRcvFromIP(pMsg, hnameIP)); @@ -883,7 +883,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) CHKiRet(msgConstruct(&pMsg)); MsgSetInputName(pMsg, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd")-1); MsgSetRawMsgWOSize(pMsg, (char*)msg); - MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName()); + MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostName()); MsgSetRcvFromIP(pMsg, UCHAR_CONSTANT("127.0.0.1")); /* check if we have an error code associated and, if so, @@ -1113,12 +1113,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) /* HOSTNAME */ if(bContParse) { parseRFCField(&p2parse, pBuf); - MsgSetHOSTNAME(pMsg, pBuf); - } else { - /* we can not parse, so we get the system we - * received the data from. - */ - MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); + MsgSetHOSTNAME(pMsg, pBuf, strlen(pBuf)); } /* APP-NAME */ @@ -1147,7 +1142,6 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) /* MSG */ MsgSetMSGoffs(pMsg, p2parse - pMsg->pszRawMsg); - //MsgSetMSG(pMsg, (char*)p2parse); free(pBuf); ENDfunc @@ -1171,8 +1165,6 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) int parseLegacySyslogMsg(msg_t *pMsg, int flags) { uchar *p2parse; - char *pBuf; - char *pWork; int bTAGCharDetected; int i; /* general index for parsing */ uchar bufParseTAG[CONF_TAG_MAXSIZE]; @@ -1198,8 +1190,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { /* indeed, we got it! */ /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */; - } else { - /* parse pointer needs to be restored, as we moved it off-by-one + } else {/* parse pointer needs to be restored, as we moved it off-by-one * for this try. */ --p2parse; @@ -1245,10 +1236,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) /* we got a hostname! */ p2parse += i + 1; /* "eat" it (including SP delimiter) */ bufParseHOSTNAME[i] = '\0'; - MsgSetHOSTNAME(pMsg, bufParseHOSTNAME); - //MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i); - } else { - MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); + MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i); } } @@ -1274,30 +1262,17 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) bufParseTAG[i++] = ':'; } - if(i == 0) - { /* rger, 2005-11-10: no TAG found - this implies that what - * we have considered to be the HOSTNAME is most probably the - * TAG. We consider it so probable, that we now adjust it - * that way. So we pick up the previously set hostname, assign - * it to tag and use the sender system (from IP stack) as - * the hostname. This situation is the standard case with - * stock BSD syslogd. - */ - DBGPRINTF("No TAG in message, assuming that HOSTNAME is missing.\n"); - moveHOSTNAMEtoTAG(pMsg); - MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); - } else { /* we have a TAG, so we can happily set it ;) */ - bufParseTAG[i] = '\0'; /* terminate string */ - MsgSetTAG(pMsg, bufParseTAG, i); - } + /* no TAG can only be detected if the message immediatly ends, in which case an empty TAG + * is considered OK. So we do not need to check for empty TAG. -- rgerhards, 2009-06-23 + */ + bufParseTAG[i] = '\0'; /* terminate string */ + MsgSetTAG(pMsg, bufParseTAG, i); } else { /* we enter this code area when the user has instructed rsyslog NOT * to parse HOSTNAME and TAG - rgerhards, 2006-03-13 */ - if(!(flags & INTERNAL_MSG)) - { + if(!(flags & INTERNAL_MSG)) { DBGPRINTF("HOSTNAME and TAG not parsed by user configuraton.\n"); - MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); } } -- cgit v1.2.3 From b2fa740b9ab5fb9e85309b3307f3fca21f625ab1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 23 Jun 2009 17:14:42 +0200 Subject: optimized TAG handling --- tools/syslogd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index faa793fb..6f264e5e 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -609,7 +609,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f * being the local host). rgerhards 2004-11-16 */ if((pMsg->msgFlags & PARSE_HOSTNAME) == 0) - MsgSetHOSTNAME(pMsg, hname, strlen(hname)); + MsgSetHOSTNAME(pMsg, hname, ustrlen(hname)); MsgSetRcvFrom(pMsg, hname); MsgSetAfterPRIOffs(pMsg, p - msg); CHKiRet(MsgSetRcvFromIP(pMsg, hnameIP)); @@ -1113,7 +1113,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) /* HOSTNAME */ if(bContParse) { parseRFCField(&p2parse, pBuf); - MsgSetHOSTNAME(pMsg, pBuf, strlen(pBuf)); + MsgSetHOSTNAME(pMsg, pBuf, ustrlen(pBuf)); } /* APP-NAME */ @@ -1267,8 +1267,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) */ bufParseTAG[i] = '\0'; /* terminate string */ MsgSetTAG(pMsg, bufParseTAG, i); - } else { - /* we enter this code area when the user has instructed rsyslog NOT + } else {/* we enter this code area when the user has instructed rsyslog NOT * to parse HOSTNAME and TAG - rgerhards, 2006-03-13 */ if(!(flags & INTERNAL_MSG)) { -- cgit v1.2.3 From d116f30a877c65b4f23dbb92601251402b0f957e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 25 Jun 2009 12:53:00 +0200 Subject: improvements/fixes in queue termination timeout handling - bugfix: subtle (and usually irrelevant) issue in timout processing timeout could be one second too early if nanoseconds wrapped - set a more sensible timeout for shutdow, now 1.5 seconds to complete processing (this also removes those cases where the shutdown message was not written because the termination happened before it) --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ace08e58..6a3fa6c9 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -302,7 +302,7 @@ static uchar *pszMainMsgQFName = NULL; /* prefix for the main message queue f static int64 iMainMsgQueMaxFileSize = 1024*1024; static int iMainMsgQPersistUpdCnt = 0; /* persist queue info every n updates */ static int bMainMsgQSyncQeueFiles = 0; /* sync queue files on every write? */ -static int iMainMsgQtoQShutdown = 0; /* queue shutdown */ +static int iMainMsgQtoQShutdown = 1500; /* queue shutdown (ms) */ static int iMainMsgQtoActShutdown = 1000; /* action shutdown (in phase 2) */ static int iMainMsgQtoEnq = 2000; /* timeout for queue enque */ static int iMainMsgQtoWrkShutdown = 60000; /* timeout for worker thread shutdown */ @@ -367,7 +367,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a iMainMsgQueueNumWorkers = 1; iMainMsgQPersistUpdCnt = 0; bMainMsgQSyncQeueFiles = 0; - iMainMsgQtoQShutdown = 0; + iMainMsgQtoQShutdown = 1500; iMainMsgQtoActShutdown = 1000; iMainMsgQtoEnq = 2000; iMainMsgQtoWrkShutdown = 60000; -- cgit v1.2.3 From 5af5b1e42868d00dfbc5fa47028768d0a03f8e32 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 25 Jun 2009 12:59:13 +0200 Subject: improvements/fixes in queue termination timeout handling - bugfix: subtle (and usually irrelevant) issue in timout processing timeout could be one second too early if nanoseconds wrapped - set a more sensible timeout for shutdow, now 1.5 seconds to complete processing (this also removes those cases where the shutdown message was not written because the termination happened before it) --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 6f264e5e..0fdaf5ba 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -299,7 +299,7 @@ static uchar *pszMainMsgQFName = NULL; /* prefix for the main message queue f static int64 iMainMsgQueMaxFileSize = 1024*1024; static int iMainMsgQPersistUpdCnt = 0; /* persist queue info every n updates */ static int bMainMsgQSyncQeueFiles = 0; /* sync queue files on every write? */ -static int iMainMsgQtoQShutdown = 0; /* queue shutdown */ +static int iMainMsgQtoQShutdown = 1500; /* queue shutdown (ms) */ static int iMainMsgQtoActShutdown = 1000; /* action shutdown (in phase 2) */ static int iMainMsgQtoEnq = 2000; /* timeout for queue enque */ static int iMainMsgQtoWrkShutdown = 60000; /* timeout for worker thread shutdown */ @@ -363,7 +363,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a iMainMsgQueueNumWorkers = 1; iMainMsgQPersistUpdCnt = 0; bMainMsgQSyncQeueFiles = 0; - iMainMsgQtoQShutdown = 0; + iMainMsgQtoQShutdown = 1500; iMainMsgQtoActShutdown = 1000; iMainMsgQtoEnq = 2000; iMainMsgQtoWrkShutdown = 60000; -- cgit v1.2.3 From 1f79c785975261e4158c9b85f6451d5bd00b2495 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 25 Jun 2009 16:03:28 +0200 Subject: named queue worker threads ... but I don't see the name anywhere...? --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 0fdaf5ba..8bc4939f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2272,7 +2272,7 @@ init(void) exit(1); } /* name our main queue object (it's not fatal if it fails...) */ - obj.SetName((obj_t*) pMsgQueue, (uchar*) "main queue"); + obj.SetName((obj_t*) pMsgQueue, (uchar*) "main Q"); /* ... set some properties ... */ # define setQPROP(func, directive, data) \ -- cgit v1.2.3 From ba4806a70439dd24dc98bd707893b1319dd5e3ef Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Thu, 18 Jun 2009 13:51:17 -0400 Subject: add support for KLogPath --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 8bc4939f..f6f4b469 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2750,8 +2750,6 @@ static rsRetVal mainThread() pTmp = template_StdPgSQLFmt; tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp)); - CHKiRet(init()); - if(Debug && debugging_on) { DBGPRINTF("Debugging enabled, SIGUSR1 to turn off debugging.\n"); } @@ -2779,6 +2777,8 @@ static rsRetVal mainThread() } + CHKiRet(init()); + /* END OF INTIALIZATION * ... but keep in mind that we might do a restart and thus init() might * be called again. If that happens, we must shut down the worker thread, -- cgit v1.2.3 From e747478051f4f81a872c791710933881c9564d64 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Mon, 29 Jun 2009 11:18:55 +0200 Subject: separate willRun and runInput calls for input modules Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f6f4b469..6ccacf5f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2081,6 +2081,29 @@ static void dbgPrintInitInfo(void) } +/* Actually run the input modules. This happens after privileges are dropped, + * if that is requested. + */ +static rsRetVal +runInputModules(void) +{ + modInfo_t *pMod; + + /* loop through all modules and activate them (brr...) */ + pMod = module.GetNxtType(NULL, eMOD_IN); + while(pMod != NULL) { + if(pMod->mod.im.bCanRun) { + /* activate here */ + thrdCreate(pMod->mod.im.runInput, pMod->mod.im.afterRun); + } + pMod = module.GetNxtType(pMod, eMOD_IN); + } + + ENDfunc + return RS_RET_OK; /* intentional: we do not care about module errors */ +} + + /* Start the input modules. This function will probably undergo big changes * while we implement the input module interface. For now, it does the most * important thing to get at least my poor initial input modules up and @@ -2088,7 +2111,7 @@ static void dbgPrintInitInfo(void) * rgerhards, 2007-12-14 */ static rsRetVal -startInputModules(void) +startInputModules(int bRunInputModules) { DEFiRet; modInfo_t *pMod; @@ -2096,15 +2119,18 @@ startInputModules(void) /* loop through all modules and activate them (brr...) */ pMod = module.GetNxtType(NULL, eMOD_IN); while(pMod != NULL) { - if((iRet = pMod->mod.im.willRun()) == RS_RET_OK) { - /* activate here */ - thrdCreate(pMod->mod.im.runInput, pMod->mod.im.afterRun); - } else { + iRet = pMod->mod.im.willRun(); + pMod->mod.im.bCanRun = (iRet == RS_RET_OK); + if(!pMod->mod.im.bCanRun) { DBGPRINTF("module %lx will not run, iRet %d\n", (unsigned long) pMod, iRet); } pMod = module.GetNxtType(pMod, eMOD_IN); } + if (bRunInputModules) { + runInputModules(); + } + ENDfunc return RS_RET_OK; /* intentional: we do not care about module errors */ } @@ -2116,7 +2142,7 @@ startInputModules(void) * else happens. -- rgerhards, 2008-07-28 */ static rsRetVal -init(void) +init(int bRunInputModules) { rsRetVal localRet; int iNbrActions; @@ -2321,7 +2347,7 @@ init(void) * shuffled to down here once we have everything in input modules. * rgerhards, 2007-12-14 */ - startInputModules(); + startInputModules(bRunInputModules); if(Debug) { dbgPrintInitInfo(); @@ -2492,7 +2518,7 @@ doHUP(void) if(glbl.GetHUPisRestart()) { DBGPRINTF("Received SIGHUP, configured to be restart, reloading rsyslogd.\n"); - init(); /* main queue is stopped as part of init() */ + init(1); /* main queue is stopped as part of init() */ } else { DBGPRINTF("Received SIGHUP, configured to be a non-restart type of HUP - notifying actions.\n"); ruleset.IterateAllActions(doHUPActions, NULL); @@ -2750,6 +2776,8 @@ static rsRetVal mainThread() pTmp = template_StdPgSQLFmt; tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp)); + CHKiRet(init(0)); + if(Debug && debugging_on) { DBGPRINTF("Debugging enabled, SIGUSR1 to turn off debugging.\n"); } @@ -2777,7 +2805,7 @@ static rsRetVal mainThread() } - CHKiRet(init()); + runInputModules(); /* END OF INTIALIZATION * ... but keep in mind that we might do a restart and thus init() might -- cgit v1.2.3 From 6a29afc83f16c57d243b39b8e8d47f2ed909bae0 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 29 Jun 2009 11:26:18 +0200 Subject: some cleanup --- tools/syslogd.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 6ccacf5f..10d07c95 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2111,7 +2111,7 @@ runInputModules(void) * rgerhards, 2007-12-14 */ static rsRetVal -startInputModules(int bRunInputModules) +startInputModules(void) { DEFiRet; modInfo_t *pMod; @@ -2127,10 +2127,6 @@ startInputModules(int bRunInputModules) pMod = module.GetNxtType(pMod, eMOD_IN); } - if (bRunInputModules) { - runInputModules(); - } - ENDfunc return RS_RET_OK; /* intentional: we do not care about module errors */ } @@ -2142,7 +2138,7 @@ startInputModules(int bRunInputModules) * else happens. -- rgerhards, 2008-07-28 */ static rsRetVal -init(int bRunInputModules) +init() { rsRetVal localRet; int iNbrActions; @@ -2343,11 +2339,14 @@ init(int bRunInputModules) DBGPRINTF("Main processing queue is initialized and running\n"); /* the output part and the queue is now ready to run. So it is a good time - * to start the inputs. Please note that the net code above should be + * to initialize the inputs. Please note that the net code above should be * shuffled to down here once we have everything in input modules. * rgerhards, 2007-12-14 + * NOTE: as of 2009-06-29, the input modules are initialized, but not yet run. + * Keep in mind. though, that the outputs already run if the queue was + * persisted to disk. -- rgerhards */ - startInputModules(bRunInputModules); + startInputModules(); if(Debug) { dbgPrintInitInfo(); @@ -2518,7 +2517,8 @@ doHUP(void) if(glbl.GetHUPisRestart()) { DBGPRINTF("Received SIGHUP, configured to be restart, reloading rsyslogd.\n"); - init(1); /* main queue is stopped as part of init() */ + init(); /* main queue is stopped as part of init() */ + runInputModules(); } else { DBGPRINTF("Received SIGHUP, configured to be a non-restart type of HUP - notifying actions.\n"); ruleset.IterateAllActions(doHUPActions, NULL); @@ -2776,11 +2776,12 @@ static rsRetVal mainThread() pTmp = template_StdPgSQLFmt; tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp)); - CHKiRet(init(0)); + CHKiRet(init()); if(Debug && debugging_on) { DBGPRINTF("Debugging enabled, SIGUSR1 to turn off debugging.\n"); } + /* Send a signal to the parent so it can terminate. */ if(myPid != ppid) @@ -2788,7 +2789,7 @@ static rsRetVal mainThread() /* If instructed to do so, we now drop privileges. Note that this is not 100% secure, - * because inputs and outputs are already running at this time. However, we can implement + * because outputs are already running at this time. However, we can implement * dropping of privileges rather quickly and it will work in many cases. While it is not * the ultimate solution, the current one is still much better than not being able to * drop privileges at all. Doing it correctly, requires a change in architecture, which @@ -2805,13 +2806,12 @@ static rsRetVal mainThread() } + /* finally let the inputs run... */ runInputModules(); /* END OF INTIALIZATION * ... but keep in mind that we might do a restart and thus init() might - * be called again. If that happens, we must shut down the worker thread, - * do the init() and then restart things. - * rgerhards, 2005-10-24 + * be called again. -- rgerhards, 2005-10-24 */ DBGPRINTF("initialization completed, transitioning to regular run mode\n"); -- cgit v1.2.3 From 6511278082a7e1e9602385cd24cdb5e363cb702f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 29 Jun 2009 12:40:41 +0200 Subject: bugfix: ssh session hangs after rsyslgod is started from it stderr/stdout were not closed to be able to emit error messages, but this caused ssh sessions to hang. Now we close them after the initial initialization. See forum thread: http://kb.monitorware.com/controlling-terminal-issues-t9875.html --- tools/syslogd.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 77273bec..45c55664 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3015,7 +3015,6 @@ static rsRetVal mainThread() glbl.SetHUPisRestart(0); /* we can not do restart-type HUPs with dropped privs */ } - /* END OF INTIALIZATION * ... but keep in mind that we might do a restart and thus init() might * be called again. If that happens, we must shut down the worker thread, @@ -3024,6 +3023,19 @@ static rsRetVal mainThread() */ dbgprintf("initialization completed, transitioning to regular run mode\n"); + /* close stderr and stdout if they are kept open during a fork. Note that this + * may introduce subtle security issues: if we are in a jail, one may break out of + * it via these descriptors. But if I close them earlier, error messages will (once + * again) not be emitted to the user that starts the daemon. As root jail support + * is still in its infancy (and not really done), we currently accept this issue. + * rgerhards, 2009-06-29 + */ + if(!(Debug || NoFork)) { + close(1); + close(2); + bErrMsgToStderr = 0; + } + mainloop(); finalize_it: -- cgit v1.2.3 From de84a12f8a5f140c0f7b8e00f4cac92ef13cd866 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 29 Jun 2009 16:53:26 +0200 Subject: introduced the idea of detached properties some things inside the message can be used over a large number of messages and need to to be allocated and re-written every time. I now begin to implement this as a "prop_t" object, first use for the inputName. Some input modules are already converted, some others to go. Will do a little performance check on the new method before I go further. Also, this commit has some cleanup and a few bug fixes that prevented compiliation in debug mode (I overlooked this as I did not compile for debug, what I normally do, and the automatted test also does not do that) --- tools/syslogd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3204d94e..2fe949ac 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -580,7 +580,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime)); } if(pszInputName != NULL) - MsgSetInputName(pMsg, pszInputName, ustrlen(pszInputName)); + MsgSetInputNameStr(pMsg, pszInputName, ustrlen(pszInputName)); MsgSetFlowControlType(pMsg, flowCtlType); MsgSetRawMsgWOSize(pMsg, (char*)msg); @@ -881,7 +881,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) DEFiRet; CHKiRet(msgConstruct(&pMsg)); - MsgSetInputName(pMsg, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd")-1); + MsgSetInputNameStr(pMsg, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd")-1); MsgSetRawMsgWOSize(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostName()); @@ -2089,6 +2089,7 @@ runInputModules(void) { modInfo_t *pMod; + BEGINfunc /* loop through all modules and activate them (brr...) */ pMod = module.GetNxtType(NULL, eMOD_IN); while(pMod != NULL) { -- cgit v1.2.3 From e397c34d2a6c7c1e4c116fd2363cb173e32eb2a2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 30 Jun 2009 15:21:15 +0200 Subject: finished transition to using inputName property ... plus some celanup and adding minor missing functionality (the rule debug info again tell the property name, not just number). --- tools/syslogd.c | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 2fe949ac..f1c43602 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -140,6 +140,7 @@ #include "rule.h" #include "net.h" #include "vm.h" +#include "prop.h" /* definitions for objects we access */ DEFobjCurrIf(obj) @@ -151,25 +152,13 @@ DEFobjCurrIf(module) DEFobjCurrIf(errmsg) DEFobjCurrIf(rule) DEFobjCurrIf(ruleset) +DEFobjCurrIf(prop) DEFobjCurrIf(net) /* TODO: make go away! */ /* forward definitions */ static rsRetVal GlobalClassExit(void); -/* We define our own set of syslog defintions so that we - * do not need to rely on (possibly different) implementations. - * 2007-07-19 rgerhards - */ -/* missing definitions for solaris - * 2006-02-16 Rger - */ -#ifdef __sun -# define LOG_AUTHPRIV LOG_AUTH -#endif -#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */ -#define LOG_FTP (11<<3) /* ftp daemon */ - #ifndef UTMP_FILE #ifdef UTMP_FILENAME @@ -217,14 +206,11 @@ static rsRetVal GlobalClassExit(void); # endif #endif -#ifndef _PATH_DEV -# define _PATH_DEV "/dev/" -#endif - #ifndef _PATH_TTY # define _PATH_TTY "/dev/tty" #endif +static prop_t *pInternalInputName = NULL; /* there is only one global inputName for all internally-generated messages */ static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */ static char *PidFile = _PATH_LOGPID; /* read-only after startup */ @@ -566,7 +552,7 @@ void untty(void) * interface change: bParseHostname removed, now in flags */ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int flags, flowControl_t flowCtlType, - uchar *pszInputName, struct syslogTime *stTime, time_t ttGenTime) + prop_t *pInputName, struct syslogTime *stTime, time_t ttGenTime) { DEFiRet; register uchar *p; @@ -579,8 +565,8 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f } else { CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime)); } - if(pszInputName != NULL) - MsgSetInputNameStr(pMsg, pszInputName, ustrlen(pszInputName)); + if(pInputName != NULL) + MsgSetInputName(pMsg, pInputName); MsgSetFlowControlType(pMsg, flowCtlType); MsgSetRawMsgWOSize(pMsg, (char*)msg); @@ -675,7 +661,7 @@ finalize_it: */ rsRetVal parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int flags, flowControl_t flowCtlType, - uchar *pszInputName, struct syslogTime *stTime, time_t ttGenTime) + prop_t *pInputName, struct syslogTime *stTime, time_t ttGenTime) { DEFiRet; register int iMsg; @@ -786,7 +772,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla */ if(iMsg == iMaxLine) { *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ - printline(hname, hnameIP, tmpline, flags, flowCtlType, pszInputName, stTime, ttGenTime); + printline(hname, hnameIP, tmpline, flags, flowCtlType, pInputName, stTime, ttGenTime); } else { /* This case in theory never can happen. If it happens, we have * a logic error. I am checking for it, because if I would not, @@ -838,7 +824,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ /* typically, we should end up here! */ - printline(hname, hnameIP, tmpline, flags, flowCtlType, pszInputName, stTime, ttGenTime); + printline(hname, hnameIP, tmpline, flags, flowCtlType, pInputName, stTime, ttGenTime); finalize_it: if(tmpline != NULL) @@ -881,7 +867,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) DEFiRet; CHKiRet(msgConstruct(&pMsg)); - MsgSetInputNameStr(pMsg, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd")-1); + MsgSetInputName(pMsg, pInternalInputName); MsgSetRawMsgWOSize(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostName()); @@ -1711,6 +1697,10 @@ die(int sig) legacyOptsFree(); + /* destruct our input name */ + if(pInternalInputName != NULL) + prop.Destruct(&pInternalInputName); + /* terminate the remaining classes */ GlobalClassExit(); @@ -2867,6 +2857,8 @@ InitGlobalClasses(void) CHKiRet(objUse(ruleset, CORE_COMPONENT)); pErrObj = "conf"; CHKiRet(objUse(conf, CORE_COMPONENT)); + pErrObj = "prop"; + CHKiRet(objUse(prop, CORE_COMPONENT)); /* intialize some dummy classes that are not part of the runtime */ pErrObj = "action"; @@ -2907,6 +2899,7 @@ GlobalClassExit(void) /* first, release everything we used ourself */ objRelease(net, LM_NET_FILENAME);/* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ + objRelease(prop, CORE_COMPONENT); objRelease(conf, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); objRelease(rule, CORE_COMPONENT); @@ -3213,6 +3206,11 @@ int realMain(int argc, char **argv) /* doing some core initializations */ + /* we need to create the inputName property (only once during our lifetime) */ + CHKiRet(prop.Construct(&pInternalInputName)); + CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslgod"), sizeof("rsyslgod") - 1)); + CHKiRet(prop.ConstructFinalize(pInternalInputName)); + /* get our host and domain names - we need to do this early as we may emit * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 */ -- cgit v1.2.3 From aaffc4281e0b26f419a3fc341461f2fc479080b8 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 30 Jun 2009 18:45:41 +0200 Subject: introduced a new way of handling the RcvFrom property ... plus a fix for a long-time bug in obj-types.h. That lead to the object pointer only then to become NULL when the object was actually destructed, I discovered this issue during introduction of the pRcvFrom property in msg_t, but it potentially had other effects, too. I am not sure if some experienced instability resulted from this bug OR if its fix will cause harm to so-far "correctly" running code. The later may very well be. Thus I will change it only for the current branch and also the beta, but not in all old builds. Let's see how things evolve. --- tools/syslogd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f1c43602..3694c70a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -596,7 +596,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f */ if((pMsg->msgFlags & PARSE_HOSTNAME) == 0) MsgSetHOSTNAME(pMsg, hname, ustrlen(hname)); - MsgSetRcvFrom(pMsg, hname); + MsgSetRcvFromStr(pMsg, hname, ustrlen(hname)); MsgSetAfterPRIOffs(pMsg, p - msg); CHKiRet(MsgSetRcvFromIP(pMsg, hnameIP)); @@ -870,7 +870,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) MsgSetInputName(pMsg, pInternalInputName); MsgSetRawMsgWOSize(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); - MsgSetRcvFrom(pMsg, glbl.GetLocalHostName()); + MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); MsgSetRcvFromIP(pMsg, UCHAR_CONSTANT("127.0.0.1")); /* check if we have an error code associated and, if so, * adjust the tag. -- rgerhards, 2008-06-27 @@ -3259,6 +3259,7 @@ int realMain(int argc, char **argv) */ glbl.SetLocalHostName(LocalHostName); glbl.SetLocalDomain(LocalDomain); + glbl.GenerateLocalHostNameProperty(); /* must be redone after conf processing, FQDN setting may have changed */ /* initialize the objects */ if((iRet = modInitIminternal()) != RS_RET_OK) { @@ -3455,6 +3456,9 @@ int realMain(int argc, char **argv) if(!iConfigVerify) CHKiRet(doGlblProcessInit()); + /* re-generate local host name property, as the config may have changed our FQDN settings */ + glbl.GenerateLocalHostNameProperty(); + CHKiRet(mainThread()); /* do any de-init's that need to be done AFTER this comment */ -- cgit v1.2.3 From d6faee67b413d1f257c96a14e46f15ec1868a365 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 1 Jul 2009 13:28:17 +0200 Subject: RcvFromIP now also a property This sets stage to enable use of the property-interface to speed up things (mildly), the next step to be done. I have also fixed one regression of yesterday's changes. --- tools/syslogd.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3694c70a..be5b5aad 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -211,6 +211,7 @@ static rsRetVal GlobalClassExit(void); #endif static prop_t *pInternalInputName = NULL; /* there is only one global inputName for all internally-generated messages */ +static prop_t *pLocalHostIP = NULL; /* there is only one global IP for all internally-generated messages */ static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */ static char *PidFile = _PATH_LOGPID; /* read-only after startup */ @@ -598,7 +599,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f MsgSetHOSTNAME(pMsg, hname, ustrlen(hname)); MsgSetRcvFromStr(pMsg, hname, ustrlen(hname)); MsgSetAfterPRIOffs(pMsg, p - msg); - CHKiRet(MsgSetRcvFromIP(pMsg, hnameIP)); + CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hname))); logmsg(pMsg, flags); @@ -871,7 +872,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) MsgSetRawMsgWOSize(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); - MsgSetRcvFromIP(pMsg, UCHAR_CONSTANT("127.0.0.1")); + MsgSetRcvFromIP(pMsg, pLocalHostIP); /* check if we have an error code associated and, if so, * adjust the tag. -- rgerhards, 2008-06-27 */ @@ -1697,9 +1698,11 @@ die(int sig) legacyOptsFree(); - /* destruct our input name */ + /* destruct our global properties */ if(pInternalInputName != NULL) prop.Destruct(&pInternalInputName); + if(pLocalHostIP != NULL) + prop.Destruct(&pLocalHostIP); /* terminate the remaining classes */ GlobalClassExit(); @@ -3208,9 +3211,13 @@ int realMain(int argc, char **argv) /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInternalInputName)); - CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslgod"), sizeof("rsyslgod") - 1)); + CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslgod") - 1)); CHKiRet(prop.ConstructFinalize(pInternalInputName)); + CHKiRet(prop.Construct(&pLocalHostIP)); + CHKiRet(prop.SetString(pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1)); + CHKiRet(prop.ConstructFinalize(pLocalHostIP)); + /* get our host and domain names - we need to do this early as we may emit * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 */ -- cgit v1.2.3 From 7bfa03bdc0b73647ffdbe4b73e5c1649af665fbf Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 1 Jul 2009 14:33:19 +0200 Subject: now put the new property-based methods to good use ... hopefully reducing the number of allocs/frees as well as overall memory usage in a busy system (plus that these shared properties hopefully remain in cache longer than its single-instance counterparts...) --- tools/syslogd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index be5b5aad..f7253a8e 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -559,6 +559,8 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f register uchar *p; int pri; msg_t *pMsg; + prop_t *propFromHost = NULL; + prop_t *propFromHostIP = NULL; /* Now it is time to create the message object (rgerhards) */ if(stTime == NULL) { @@ -597,9 +599,9 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f */ if((pMsg->msgFlags & PARSE_HOSTNAME) == 0) MsgSetHOSTNAME(pMsg, hname, ustrlen(hname)); - MsgSetRcvFromStr(pMsg, hname, ustrlen(hname)); + MsgSetRcvFromStr(pMsg, hname, ustrlen(hname), &propFromHost); + CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hname), &propFromHostIP)); MsgSetAfterPRIOffs(pMsg, p - msg); - CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hname))); logmsg(pMsg, flags); -- cgit v1.2.3 From e3040285dbf0854443bc2443e0de5ac59f6f839e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 6 Jul 2009 16:38:09 +0200 Subject: first shot at asynchronous stream writer with timeout capability ... seems to work on quick testing, but needs a far more testing and improvement. Good milestone commit. --- tools/syslogd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f7253a8e..f79410d7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2548,8 +2548,8 @@ mainloop(void) * powertop, for example). In that case, we primarily wait for a signal, * but a once-a-day wakeup should be quite acceptable. -- rgerhards, 2008-06-09 */ - //tvSelectTimeout.tv_sec = (bReduceRepeatMsgs == 1) ? TIMERINTVL : 86400 /*1 day*/; - tvSelectTimeout.tv_sec = TIMERINTVL; /* TODO: change this back to the above code when we have a better solution for apc */ + tvSelectTimeout.tv_sec = (bReduceRepeatMsgs == 1) ? TIMERINTVL : 86400 /*1 day*/; + //tvSelectTimeout.tv_sec = TIMERINTVL; /* TODO: change this back to the above code when we have a better solution for apc */ tvSelectTimeout.tv_usec = 0; select(1, NULL, NULL, NULL, &tvSelectTimeout); if(bFinished) @@ -2584,7 +2584,7 @@ mainloop(void) bHadHUP = 0; continue; } - execScheduled(); /* handle Apc calls (if any) */ + // TODO: remove execScheduled(); /* handle Apc calls (if any) */ } ENDfunc } -- cgit v1.2.3 From 7eadb67d19da21d7521640d224a2c47ca1b782b5 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 14 Jul 2009 15:27:00 +0200 Subject: bugfix: fromhost-ip was sometimes truncated --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f7253a8e..ade6f1c7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -600,7 +600,7 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f if((pMsg->msgFlags & PARSE_HOSTNAME) == 0) MsgSetHOSTNAME(pMsg, hname, ustrlen(hname)); MsgSetRcvFromStr(pMsg, hname, ustrlen(hname), &propFromHost); - CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hname), &propFromHostIP)); + CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hnameIP), &propFromHostIP)); MsgSetAfterPRIOffs(pMsg, p - msg); logmsg(pMsg, flags); -- cgit v1.2.3 From c68fb88446d2b996269c0ff459628164f9948848 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 15 Jul 2009 12:34:59 +0200 Subject: cleaned up AUTHORS file and references ... was not well maintained at all, now refering to git --- tools/syslogd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4c27a662..5809355d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -16,12 +16,9 @@ * parts of the code have been rewritten. * * This Project was intiated and is maintained by - * Rainer Gerhards . See - * AUTHORS to learn who helped make it become a reality. + * Rainer Gerhards . * - * If you have questions about rsyslogd in general, please email - * info@adiscon.com. To learn more about rsyslogd, please visit - * http://www.rsyslog.com. + * For further information, please see http://www.rsyslog.com * * \author Rainer Gerhards * \date 2003-10-17 -- cgit v1.2.3 From 60a7a0d4d0d592ef6e372edc919ef62e13ee062e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 15 Jul 2009 12:59:28 +0200 Subject: $HUPisRestart removed ... but the rest of the code is not yet cleaned-up. Will do that slowly over time... (huge potential, but must be done carefully) --- tools/syslogd.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5809355d..f9b8adef 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2362,7 +2362,7 @@ init() */ snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ - "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] (re)start", + "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] start", (int) myPid); logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, 0); @@ -2371,7 +2371,7 @@ init() sigAct.sa_handler = sighup_handler; sigaction(SIGHUP, &sigAct, NULL); - DBGPRINTF(" (re)started.\n"); + DBGPRINTF(" started.\n"); finalize_it: RETiRet; @@ -2515,19 +2515,11 @@ doHUP(void) snprintf(buf, sizeof(buf) / sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION - "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed, type '%s'.", - (int) myPid, glbl.GetHUPisRestart() ? "restart" : "lightweight"); + "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed", + (int) myPid); errno = 0; - logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); - if(glbl.GetHUPisRestart()) { - DBGPRINTF("Received SIGHUP, configured to be restart, reloading rsyslogd.\n"); - init(); /* main queue is stopped as part of init() */ - runInputModules(); - } else { - DBGPRINTF("Received SIGHUP, configured to be a non-restart type of HUP - notifying actions.\n"); - ruleset.IterateAllActions(doHUPActions, NULL); - } + ruleset.IterateAllActions(doHUPActions, NULL); } @@ -2803,12 +2795,10 @@ static rsRetVal mainThread() */ if(gidDropPriv != 0) { doDropPrivGid(gidDropPriv); - glbl.SetHUPisRestart(0); /* we can not do restart-type HUPs with dropped privs */ } if(uidDropPriv != 0) { doDropPrivUid(uidDropPriv); - glbl.SetHUPisRestart(0); /* we can not do restart-type HUPs with dropped privs */ } /* finally let the inputs run... */ -- cgit v1.2.3 From 766e3e93d86d0284b135ee37f57d5af9dd25e298 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 15 Jul 2009 13:58:10 +0200 Subject: some mild restart-type HUP cleanup ... only those things that were obvious (and puzzled people looking at the code without konwing the subtle issues of HUP ;)). --- tools/syslogd.c | 54 +++++++++--------------------------------------------- 1 file changed, 9 insertions(+), 45 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f9b8adef..804259d1 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2136,13 +2136,12 @@ startInputModules(void) } -/* INIT -- Initialize syslogd from configuration table - * init() is called at initial startup AND each time syslogd is HUPed +/* INIT -- Initialize syslogd * Note that if iConfigVerify is set, only the config file is verified but nothing * else happens. -- rgerhards, 2008-07-28 */ static rsRetVal -init() +init(void) { rsRetVal localRet; int iNbrActions; @@ -2153,8 +2152,6 @@ init() struct sigaction sigAct; DEFiRet; - thrdTerminateAll(); /* stop all running input threads - TODO: reconsider location! */ - /* initialize some static variables */ pDfltHostnameCmp = NULL; pDfltProgNameCmp = NULL; @@ -2162,37 +2159,6 @@ init() DBGPRINTF("rsyslog %s - called init()\n", VERSION); - /* delete the message queue, which also flushes all messages left over */ - if(pMsgQueue != NULL) { - DBGPRINTF("deleting main message queue\n"); - qqueueDestruct(&pMsgQueue); /* delete pThis here! */ - pMsgQueue = NULL; - } - - /* Close all open log files and free log descriptor array. This also frees - * all output-modules instance data. - */ - destructAllActions(); - - /* Unload all non-static modules */ - DBGPRINTF("Unloading non-static modules.\n"); - module.UnloadAndDestructAll(eMOD_LINK_DYNAMIC_LOADED); - - DBGPRINTF("Clearing templates.\n"); - tplDeleteNew(); - - /* re-setting values to defaults (where applicable) */ - /* once we have loadable modules, we must re-visit this code. The reason is - * that config variables are not re-set, because the module is not yet loaded. On - * the other hand, that doesn't matter, because the module got unloaded and is then - * re-loaded, so the variables should be re-set via that way. And this is exactly how - * it works. Loadable module's variables are initialized on load, the rest here. - * rgerhards, 2008-04-28 - */ - conf.cfsysline((uchar*)"ResetConfigVariables"); - - conf.ReInitConf(); - /* construct the default ruleset */ ruleset.Construct(&pRuleset); ruleset.SetName(pRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset")); @@ -2357,6 +2323,13 @@ init() dbgPrintInitInfo(); } + memset(&sigAct, 0, sizeof (sigAct)); + sigemptyset(&sigAct.sa_mask); + sigAct.sa_handler = sighup_handler; + sigaction(SIGHUP, &sigAct, NULL); + + DBGPRINTF(" started.\n"); + /* we now generate the startup message. It now includes everything to * identify this instance. -- rgerhards, 2005-08-17 */ @@ -2366,13 +2339,6 @@ init() (int) myPid); logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, 0); - memset(&sigAct, 0, sizeof (sigAct)); - sigemptyset(&sigAct.sa_mask); - sigAct.sa_handler = sighup_handler; - sigaction(SIGHUP, &sigAct, NULL); - - DBGPRINTF(" started.\n"); - finalize_it: RETiRet; } @@ -2805,8 +2771,6 @@ static rsRetVal mainThread() runInputModules(); /* END OF INTIALIZATION - * ... but keep in mind that we might do a restart and thus init() might - * be called again. -- rgerhards, 2005-10-24 */ DBGPRINTF("initialization completed, transitioning to regular run mode\n"); -- cgit v1.2.3 From cc8ef1a1546548c5d77b06f0726bf16bba5ad77e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 15 Jul 2009 14:05:39 +0200 Subject: bugfix: memory leak with some input modules --- tools/syslogd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ade6f1c7..e52a524a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -602,6 +602,8 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f MsgSetRcvFromStr(pMsg, hname, ustrlen(hname), &propFromHost); CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hnameIP), &propFromHostIP)); MsgSetAfterPRIOffs(pMsg, p - msg); + prop.Destruct(&propFromHost); + prop.Destruct(&propFromHostIP); logmsg(pMsg, flags); -- cgit v1.2.3 From 05cd77cd4d8f4c5a8dc0a8662c4dfe288230257d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 15 Jul 2009 14:28:33 +0200 Subject: some more (very mild) cleanup --- tools/syslogd.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 70fbeb81..ada3288e 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -422,7 +422,7 @@ diagGetMainMsgQSize(int *piSize) /* rgerhards, 2005-10-24: crunch_list is called only during option processing. So - * it is never called once rsyslogd is running (not even when HUPed). This code + * it is never called once rsyslogd is running. This code * contains some exits, but they are considered safe because they only happen * during startup. Anyhow, when we review the code here, we might want to * reconsider the exit()s. @@ -1719,16 +1719,6 @@ die(int sig) /* terminate the remaining classes */ GlobalClassExit(); - /* 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 - * I have added some code now, but all that mod init/de-init should be moved to - * init, so that modules are unloaded and reloaded on HUP to. Eventually it should go - * into destructAllActions() - but that needs to be seen. -- rgerhards, 2007-08-09 - */ module.UnloadAndDestructAll(eMOD_LINK_ALL); DBGPRINTF("Clean shutdown completed, bye\n"); -- cgit v1.2.3 From 7d92de155c832e0a4af2cb3b65f7cef909b19f8d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 20 Jul 2009 18:36:30 +0200 Subject: internal: added ability to terminate input modules not via pthread_cancel... ... but an alternate approach via pthread_kill. This is somewhat safer as we do not need to think about the cancel-safeness of all libraries we use. However, not all inputs can easily supported, so this now is a feature that can be requested by the input module (the most important ones request it). --- tools/syslogd.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ada3288e..40e9e92c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1664,6 +1664,7 @@ die(int sig) /* close the inputs */ DBGPRINTF("Terminating input threads...\n"); + glbl.SetGlobalInputTermination(); thrdTerminateAll(); /* and THEN send the termination log message (see long comment above) */ @@ -2083,6 +2084,7 @@ static rsRetVal runInputModules(void) { modInfo_t *pMod; + int bNeedsCancel; BEGINfunc /* loop through all modules and activate them (brr...) */ @@ -2090,7 +2092,9 @@ runInputModules(void) while(pMod != NULL) { if(pMod->mod.im.bCanRun) { /* activate here */ - thrdCreate(pMod->mod.im.runInput, pMod->mod.im.afterRun); + bNeedsCancel = (pMod->isCompatibleWithFeature(sFEATURENonCancelInputTermination) == RS_RET_OK) ? + 0 : 1; + thrdCreate(pMod->mod.im.runInput, pMod->mod.im.afterRun, bNeedsCancel); } pMod = module.GetNxtType(pMod, eMOD_IN); } @@ -2429,6 +2433,9 @@ void sighup_handler() sigaction(SIGHUP, &sigAct, NULL); } +void sigttin_handler() +{ +} /* this function pulls all internal messages from the buffer * and puts them into the processing engine. @@ -3036,6 +3043,8 @@ doGlblProcessInit(void) sigaction(SIGCHLD, &sigAct, NULL); sigAct.sa_handler = Debug ? debug_switch : SIG_IGN; sigaction(SIGUSR1, &sigAct, NULL); + sigAct.sa_handler = sigttin_handler; + sigaction(SIGTTIN, &sigAct, NULL); /* (ab)used to interrupt input threads */ sigAct.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sigAct, NULL); sigaction(SIGXFSZ, &sigAct, NULL); /* do not abort if 2gig file limit is hit */ -- cgit v1.2.3 From 73b73fe5c31bcaf9052d9bbb13f38ff3a13fd22d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 20 Aug 2009 14:18:41 +0200 Subject: bugfix: hostnames with dashes in them were incorrectly treated as malformed ... thus causing them to be treated as TAG (this was a regression introduced from the "rfc3164 strict" change in 4.5.0). Testbench has been updated to include a smaple message with a hostname containing a dash. --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 40e9e92c..ff671138 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1225,7 +1225,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) if(flags & PARSE_HOSTNAME) { i = 0; while((isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.' - || p2parse[i] == '_') && i < CONF_TAG_MAXSIZE) { + || p2parse[i] == '_' || p2parse[i] == '-') && i < CONF_TAG_MAXSIZE) { bufParseHOSTNAME[i] = p2parse[i]; ++i; } -- cgit v1.2.3 From daa76ad94428599336ddafdd6854dc0b71356180 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 20 Aug 2009 14:22:33 +0200 Subject: bugfix: hostnames with dashes in them were incorrectly treated as malformed ... thus causing them to be treated as TAG (this was a regression introduced from the "rfc3164 strict" change in 4.5.0). --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3846e6a9..88588621 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1218,7 +1218,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) if(flags & PARSE_HOSTNAME) { i = 0; while((isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.' - || p2parse[i] == '_') && i < CONF_TAG_MAXSIZE) { + || p2parse[i] == '_' || p2parse[i] == '-') && i < CONF_TAG_MAXSIZE) { bufParseHOSTNAME[i] = p2parse[i]; ++i; } -- cgit v1.2.3 From 071c9b511a711725537eff386f82a3af3ca930a8 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 4 Sep 2009 14:53:44 +0200 Subject: added $LogRSyslogStatusMessages configuration directive ...permitting to turn off rsyslog start/stop/HUP messages. See Debian ticket http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=463793 --- tools/syslogd.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 88588621..500b5b1f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -249,6 +249,8 @@ int bDropTrailingLF = 1; /* drop trailing LF's on reception? */ int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is the default, so if no -c option is given, we make ourselvs as compatible to sysklogd as possible. */ +#define DFLT_bLogStatusMsgs 1 +static int bLogStatusMsgs = DFLT_bLogStatusMsgs; /* log rsyslog start/stop/HUP messages? */ static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */ static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */ static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ @@ -332,6 +334,7 @@ getFIOPName(unsigned iFIOP) static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { cCCEscapeChar = '#'; + bLogStatusMsgs = DFLT_bLogStatusMsgs; bActExecWhenPrevSusp = 0; iActExecOnceInterval = 0; bDebugPrintTemplateList = 1; @@ -1659,7 +1662,7 @@ die(int sig) thrdTerminateAll(); /* and THEN send the termination log message (see long comment above) */ - if (sig) { + if(sig && bLogStatusMsgs) { (void) snprintf(buf, sizeof(buf) / sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.", @@ -2353,11 +2356,13 @@ init() /* we now generate the startup message. It now includes everything to * identify this instance. -- rgerhards, 2005-08-17 */ - snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char), - " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ - "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] (re)start", - (int) myPid); - logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, 0); + if(bLogStatusMsgs) { + snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char), + " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ + "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] (re)start", + (int) myPid); + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, 0); + } memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); @@ -2506,12 +2511,14 @@ doHUP(void) { char buf[512]; - snprintf(buf, sizeof(buf) / sizeof(char), - " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION - "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed, type '%s'.", - (int) myPid, glbl.GetHUPisRestart() ? "restart" : "lightweight"); - errno = 0; - logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); + if(bLogStatusMsgs) { + snprintf(buf, sizeof(buf) / sizeof(char), + " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION + "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed, type '%s'.", + (int) myPid, glbl.GetHUPisRestart() ? "restart" : "lightweight"); + errno = 0; + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); + } if(glbl.GetHUPisRestart()) { DBGPRINTF("Received SIGHUP, configured to be restart, reloading rsyslogd.\n"); @@ -2632,6 +2639,7 @@ static rsRetVal loadBuildInModules(void) * is that rsyslog will terminate if we can not register our built-in config commands. * This, I think, is the right thing to do. -- rgerhards, 2007-07-31 */ + CHKiRet(regCfSysLineHdlr((uchar *)"logrsyslogstatusmessages", 0, eCmdHdlrBinary, NULL, &bLogStatusMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultruleset", 0, eCmdHdlrGetWord, setDefaultRuleset, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, setCurrRuleset, NULL, NULL)); -- cgit v1.2.3 From 8bea0d1d5762a3f0af74a5b9e9c0b15518774bec Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Sep 2009 12:30:00 +0200 Subject: added $AbortOnUncleanConfig directive permits to prevent startup when there are problems with the configuration file. See it's doc for details. --- tools/syslogd.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 26281005..912cca69 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -258,6 +258,7 @@ uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence f int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */ static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ +int bAbortOnUncleanConfig = 0; /* abort run (rather than starting with partial config) if there was any issue in conf */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ int iActExecOnceInterval = 0; /* execute action once every nn seconds */ /* end global config file state variables */ @@ -343,6 +344,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a bDebugPrintModuleList = 1; bEscapeCCOnRcv = 1; /* default is to escape control characters */ bReduceRepeatMsgs = 0; + bAbortOnUncleanConfig = 0; free(pszMainMsgQFName); pszMainMsgQFName = NULL; iMainMsgQueueSize = 10000; @@ -2251,6 +2253,14 @@ init(void) ABORT_FINALIZE(RS_RET_VALIDATION_RUN); } + if(bAbortOnUncleanConfig && bHadConfigErr) { + fprintf(stderr, "rsyslogd: $AbortOnUncleanConfig is set, and config is not clean.\n" + "Check error log for details, fix errors and restart. As a last\n" + "resort, you may want to remove $AbortOnUncleanConfig to permit a\n" + "startup with a dirty config.\n"); + exit(2); + } + /* switch the message object to threaded operation, if necessary */ if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) { MsgEnableThreadSafety(); @@ -2630,6 +2640,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesaveonshutdown", 0, eCmdHdlrBinary, NULL, &bMainMsgQSaveOnShutdown, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimebegin", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinFromHr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinToHr, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"abortonuncleanconfig", 0, eCmdHdlrBinary, NULL, &bAbortOnUncleanConfig, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlyonceeveryinterval", 0, eCmdHdlrInt, NULL, &iActExecOnceInterval, NULL)); -- cgit v1.2.3 From 37ba1df6e37b2d020001f390ccb2462ae04fc9c1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 24 Sep 2009 09:48:38 +0200 Subject: bugfix: random data could be appended to message, possibly causing segfaults --- tools/syslogd.c | 108 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 38 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ff6369c3..5671dcde 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1242,10 +1242,12 @@ msgConsumer(void __attribute__((unused)) *notNeeded, void *pUsr) * to after the terminating SP. The caller must ensure that the * provided buffer is large enough to hold the to be extracted value. * Returns 0 if everything is fine or 1 if either the field is not - * SP-terminated or any other error occurs. - * rger, 2005-11-24 + * SP-terminated or any other error occurs. -- rger, 2005-11-24 + * The function now receives the size of the string and makes sure + * that it does not process more than that. The *pLenStr counter is + * updated on exit. -- rgerhards, 2009-09-23 */ -static int parseRFCField(uchar **pp2parse, uchar *pResult) +static int parseRFCField(uchar **pp2parse, uchar *pResult, int *pLenStr) { uchar *p2parse; int iRet = 0; @@ -1257,14 +1259,17 @@ static int parseRFCField(uchar **pp2parse, uchar *pResult) p2parse = *pp2parse; /* this is the actual parsing loop */ - while(*p2parse && *p2parse != ' ') { + while(*pLenStr > 0 && *p2parse != ' ') { *pResult++ = *p2parse++; + --(*pLenStr); } - if(*p2parse == ' ') + if(*pLenStr > 0 && *p2parse == ' ') { ++p2parse; /* eat SP, but only if not at end of string */ - else + --(*pLenStr); + } else { iRet = 1; /* there MUST be an SP! */ + } *pResult = '\0'; /* set the new parse pointer */ @@ -1280,20 +1285,24 @@ static int parseRFCField(uchar **pp2parse, uchar *pResult) * to after the terminating SP. The caller must ensure that the * provided buffer is large enough to hold the to be extracted value. * Returns 0 if everything is fine or 1 if either the field is not - * SP-terminated or any other error occurs. - * rger, 2005-11-24 + * SP-terminated or any other error occurs. -- rger, 2005-11-24 + * The function now receives the size of the string and makes sure + * that it does not process more than that. The *pLenStr counter is + * updated on exit. -- rgerhards, 2009-09-23 */ -static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult) +static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult, int *pLenStr) { uchar *p2parse; int bCont = 1; int iRet = 0; + int lenStr; assert(pp2parse != NULL); assert(*pp2parse != NULL); assert(pResult != NULL); p2parse = *pp2parse; + lenStr = *pLenStr; /* this is the actual parsing loop * Remeber: structured data starts with [ and includes any characters @@ -1301,40 +1310,47 @@ static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult) * structured data. There may also be \] inside the structured data, which * do NOT terminate an element. */ - if(*p2parse != '[') + if(lenStr == 0 || *p2parse != '[') return 1; /* this is NOT structured data! */ if(*p2parse == '-') { /* empty structured data? */ *pResult++ = '-'; ++p2parse; + --lenStr; } else { while(bCont) { - if(*p2parse == '\0') { + if(lenStr < 2) { iRet = 1; /* this is not valid! */ bCont = 0; } else if(*p2parse == '\\' && *(p2parse+1) == ']') { /* this is escaped, need to copy both */ *pResult++ = *p2parse++; *pResult++ = *p2parse++; + lenStr -= 2; } else if(*p2parse == ']' && *(p2parse+1) == ' ') { /* found end, just need to copy the ] and eat the SP */ *pResult++ = *p2parse; p2parse += 2; + lenStr -= 2; bCont = 0; } else { *pResult++ = *p2parse++; + --lenStr; } } } - if(*p2parse == ' ') + if(lenStr > 0 && *p2parse == ' ') { ++p2parse; /* eat SP, but only if not at end of string */ - else + --lenStr; + } else { iRet = 1; /* there MUST be an SP! */ + } *pResult = '\0'; /* set the new parse pointer */ *pp2parse = p2parse; + *pLenStr = lenStr; return 0; } @@ -1359,23 +1375,26 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) { uchar *p2parse; uchar *pBuf; + int lenMsg; int bContParse = 1; BEGINfunc assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ + lenMsg = pMsg->iLenRawMsg - (pMsg->offAfterPRI + 1); - /* do a sanity check on the version and eat it */ + /* do a sanity check on the version and eat it (the caller checked this already) */ assert(p2parse[0] == '1' && p2parse[1] == ' '); p2parse += 2; + lenMsg -= 2; /* Now get us some memory we can use as a work buffer while parsing. * We simply allocated a buffer sufficiently large to hold all of the * message, so we can not run into any troubles. I think this is * more wise then to use individual buffers. */ - if((pBuf = malloc(sizeof(uchar) * ustrlen(p2parse) + 1)) == NULL) + if((pBuf = malloc(sizeof(uchar) * (lenMsg + 1))) == NULL) return 1; /* IMPORTANT NOTE: @@ -1386,7 +1405,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) */ /* TIMESTAMP */ - if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { + if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) { if(flags & IGNDATE) { /* we need to ignore the msg data, so simply copy over reception date */ memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); @@ -1398,7 +1417,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) /* HOSTNAME */ if(bContParse) { - parseRFCField(&p2parse, pBuf); + parseRFCField(&p2parse, pBuf, &lenMsg); MsgSetHOSTNAME(pMsg, pBuf); } else { /* we can not parse, so we get the system we @@ -1409,30 +1428,30 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) /* APP-NAME */ if(bContParse) { - parseRFCField(&p2parse, pBuf); + parseRFCField(&p2parse, pBuf, &lenMsg); MsgSetAPPNAME(pMsg, (char*)pBuf); } /* PROCID */ if(bContParse) { - parseRFCField(&p2parse, pBuf); + parseRFCField(&p2parse, pBuf, &lenMsg); MsgSetPROCID(pMsg, (char*)pBuf); } /* MSGID */ if(bContParse) { - parseRFCField(&p2parse, pBuf); + parseRFCField(&p2parse, pBuf, &lenMsg); MsgSetMSGID(pMsg, (char*)pBuf); } /* STRUCTURED-DATA */ if(bContParse) { - parseRFCStructuredData(&p2parse, pBuf); + parseRFCStructuredData(&p2parse, pBuf, &lenMsg); MsgSetStructuredData(pMsg, (char*)pBuf); } /* MSG */ - MsgSetMSG(pMsg, (char*)p2parse); + MsgSetMSG(pMsg, (lenMsg == 0) ? "" : (char*)p2parse); free(pBuf); ENDfunc @@ -1460,11 +1479,15 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) char *pWork; cstr_t *pStrB; int iCnt; + int lenMsg; int bTAGCharDetected; BEGINfunc assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); + lenMsg = pMsg->iLenRawMsg - (pMsg->offAfterPRI + 1); +RUNLOG_VAR("%d", pMsg->offAfterPRI); +RUNLOG_VAR("%d", lenMsg); p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ /* Check to see if msg contains a timestamp. We start by assuming @@ -1473,13 +1496,14 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * message. There we go from high-to low precison and are done * when we find a matching one. -- rgerhards, 2008-09-16 */ - if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { + if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) { /* we are done - parse pointer is moved by ParseTIMESTAMP3339 */; - } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { + } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) { /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */; - } else if(*p2parse == ' ') { /* try to see if it is slighly malformed - HP procurve seems to do that sometimes */ + } else if(*p2parse == ' ' && lenMsg > 1) { /* try to see if it is slighly malformed - HP procurve seems to do that sometimes */ ++p2parse; /* move over space */ - if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) { + --lenMsg; + if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) { /* indeed, we got it! */ /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */; } else { @@ -1487,6 +1511,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * for this try. */ --p2parse; + ++lenMsg; } } @@ -1520,14 +1545,15 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) /* the memory allocated is far too much in most cases. But on the plus side, * it is quite fast... - rgerhards, 2007-09-20 */ - if((pBuf = malloc(sizeof(char)* (ustrlen(p2parse) +1))) == NULL) + if((pBuf = malloc(sizeof(char) * (lenMsg + 1))) == NULL) return 1; pWork = pBuf; /* this is the actual parsing loop */ - while(*p2parse && *p2parse != ' ' && *p2parse != ':') { + while(lenMsg > 0 && *p2parse != ' ' && *p2parse != ':') { if(*p2parse == '[' || *p2parse == ']' || *p2parse == '/') bTAGCharDetected = 1; *pWork++ = *p2parse++; + --lenMsg; } /* we need to handle ':' seperately, because it terminates the * TAG - so we also need to terminate the parser here! @@ -1539,13 +1565,17 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * will be true and the parse pointer remain as is. This is perfectly * well. */ - if(*p2parse == ':') { - bTAGCharDetected = 1; - /* We will move hostname to tag, so preserve ':' (otherwise we - * will needlessly change the message format) */ - *pWork++ = *p2parse++; - } else if(*p2parse == ' ') - ++p2parse; + if(lenMsg > 0) { + if(*p2parse == ':') { + bTAGCharDetected = 1; + /* We will move hostname to tag, so preserve ':' (otherwise we + * will needlessly change the message format) */ + *pWork++ = *p2parse++; + } else if(*p2parse == ' ') { + ++p2parse; + } + --lenMsg; + } *pWork = '\0'; MsgAssignHOSTNAME(pMsg, pBuf); } @@ -1584,12 +1614,14 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) rsCStrSetAllocIncrement(pStrB, 33); pWork = pBuf; iCnt = 0; - while(*p2parse && *p2parse != ':' && *p2parse != ' ') { + while(lenMsg > 0 && *p2parse != ':' && *p2parse != ' ') { cstrAppendChar(pStrB, *p2parse++); ++iCnt; + --lenMsg; } - if(*p2parse == ':') { + if(lenMsg > 0 && *p2parse == ':') { ++p2parse; + --lenMsg; cstrAppendChar(pStrB, ':'); } cstrFinalize(pStrB); @@ -1625,7 +1657,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) } /* The rest is the actual MSG */ - MsgSetMSG(pMsg, (char*)p2parse); + MsgSetMSG(pMsg, (lenMsg == 0) ? "" : (char*)p2parse); ENDfunc return 0; /* all ok */ -- cgit v1.2.3 From cb9761627630dc8aeafbbfcfe091f87b66b5a92a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 1 Oct 2009 16:54:34 +0200 Subject: RFC5424 formatted messages with only structured data and no MSG part were improperly handled. This was a regression of one of the last bugfixes, so no previously released version contained this bug (thus it does not show up in the ChangeLog). --- tools/syslogd.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5671dcde..5f6b480f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1320,9 +1320,17 @@ static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult, int *pLenStr } else { while(bCont) { if(lenStr < 2) { - iRet = 1; /* this is not valid! */ - bCont = 0; - } else if(*p2parse == '\\' && *(p2parse+1) == ']') { + /* we now need to check if we have only structured data */ + if(lenStr > 0 && *p2parse == ']') { + *pResult++ = *p2parse; + p2parse++; + lenStr--; + bCont = 0; + } else { + iRet = 1; /* this is not valid! */ + bCont = 0; + } + } else if(*p2parse == '\\' && *(p2parse+1) == ']') { /* this is escaped, need to copy both */ *pResult++ = *p2parse++; *pResult++ = *p2parse++; @@ -1382,7 +1390,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ - lenMsg = pMsg->iLenRawMsg - (pMsg->offAfterPRI + 1); + lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; /* do a sanity check on the version and eat it (the caller checked this already) */ assert(p2parse[0] == '1' && p2parse[1] == ' '); -- cgit v1.2.3 From 0d7521d59167e47dd5c085d34edf3cd06e45cfc1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 5 Oct 2009 12:38:40 +0200 Subject: bugfix: invalid storage class selected for some size config parameters. This resulted in wrong values. The most prominent victim was the directory creation mode, which was set to zero in some cases. For details, see related blog post: http://blog.gerhards.net/2009/10/another-note-on-hard-to-find-bugs.html This replaces the improper bugfix from two commits ago with a proper one. --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 88588621..60e162f8 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1748,7 +1748,7 @@ static void doexit() /* set the maximum message size */ -static rsRetVal setMaxMsgSize(void __attribute__((unused)) *pVal, int iNewVal) +static rsRetVal setMaxMsgSize(void __attribute__((unused)) *pVal, long iNewVal) { return glbl.SetMaxLine(iNewVal); } -- cgit v1.2.3 From 92ec206279e29d12d3d44e51280485d641579e41 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 7 Oct 2009 10:53:05 +0200 Subject: bugfix and testbench improvement made shutdown more reliable by makeing sure that the main queue DA worker is only cancelled if this is actually unavoidable. Also moved down the deletion of rsyslogd's pid file to immediately before termination, so that absence of the file is a proper indication that rsyslogd has finished (in the past, e.g. the testbench accidently ran two intances as the pid file was deleted too early). Also some improvments to the testbench, namely to handle aborts more intelligently (but still not perfect). --- tools/syslogd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index bd2d107f..3350804d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1733,8 +1733,6 @@ die(int sig) */ tplDeleteAll(); - remove_pid(PidFile); - /* de-init some modules */ modExitIminternal(); @@ -1768,6 +1766,9 @@ die(int sig) */ freeAllDynMemForTermination(); /* NO CODE HERE - feeelAllDynMemForTermination() must be the last thing before exit()! */ + + remove_pid(PidFile); + exit(0); /* "good" exit, this is the terminator function for rsyslog [die()] */ } -- cgit v1.2.3 From 98d1ed504ec001728955a5bcd7916f64cd85f39f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 9 Oct 2009 15:37:34 +0200 Subject: bugfix: potential segfault on messages with empty MSG part. This was a recently introduced regression. --- tools/syslogd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3350804d..895ac5d6 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1200,8 +1200,6 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); lenMsg = pMsg->iLenRawMsg - (pMsg->offAfterPRI + 1); -RUNLOG_VAR("%d", pMsg->offAfterPRI); -RUNLOG_VAR("%d", lenMsg); p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ /* Check to see if msg contains a timestamp. We start by assuming @@ -1257,16 +1255,16 @@ RUNLOG_VAR("%d", lenMsg); bTAGCharDetected = 0; if(lenMsg > 0 && flags & PARSE_HOSTNAME) { i = 0; - while(lenMsg > 0 && (isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.' + while(i < lenMsg && (isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.' || p2parse[i] == '_' || p2parse[i] == '-') && i < CONF_TAG_MAXSIZE) { bufParseHOSTNAME[i] = p2parse[i]; ++i; - --lenMsg; } if(i > 0 && p2parse[i] == ' ' && isalnum(p2parse[i-1])) { /* we got a hostname! */ p2parse += i + 1; /* "eat" it (including SP delimiter) */ + lenMsg -= i + 1; bufParseHOSTNAME[i] = '\0'; MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i); } -- cgit v1.2.3 From 8e60b2daa653b33ac244c8cb1ae4219df9ef414c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 12 Oct 2009 15:53:07 +0200 Subject: changed submitAndParseMsg() interface to be a wrapper around the new interface ... for message creation/submission. This enables older plugins to be used together with the new interface. The removal also enables us to drop a lot of duplicate code, reducing complexity and increasing maintainibility. --- tools/syslogd.c | 334 +++----------------------------------------------------- 1 file changed, 17 insertions(+), 317 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 8c4c8e94..5dd03fcb 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -160,18 +160,6 @@ DEFobjCurrIf(net) /* TODO: make go away! */ static rsRetVal GlobalClassExit(void); -#ifndef UTMP_FILE -#ifdef UTMP_FILENAME -#define UTMP_FILE UTMP_FILENAME -#else -#ifdef _PATH_UTMP -#define UTMP_FILE _PATH_UTMP -#else -#define UTMP_FILE "/etc/utmp" -#endif -#endif -#endif - #ifndef _PATH_LOGCONF #define _PATH_LOGCONF "/etc/rsyslog.conf" #endif @@ -524,52 +512,21 @@ void untty(void) #endif -/* Take a raw input line, decode the message, and print the message - * on the appropriate log files. - * rgerhards 2004-11-08: Please note - * that this function does only a partial decoding. At best, it splits - * the PRI part. No further decode happens. The rest is done in - * logmsg(). - * Added the iSource parameter so that we know if we have to parse - * HOSTNAME or not. rgerhards 2004-11-16. - * changed parameter iSource to bParseHost. For details, see comment in - * printchopped(). rgerhards 2005-10-06 - * rgerhards: 2008-03-06: added "flags" to allow an input module to specify - * flags, most importantly to request ignoring the messages' timestamp. - * - * rgerhards, 2008-03-19: - * I added an additional calling parameter to permit specifying the flow - * control capability of the source. - * - * rgerhards, 2008-05-16: - * I added an additional calling parameter (hnameIP) to enable specifying the IP - * of a remote host. - * - * rgerhards, 2008-09-11: - * Interface change: added new parameter "InputName", permits the input to provide - * a string that identifies it. May be NULL, but must be a valid char* pointer if - * non-NULL. - * - * rgerhards, 2008-10-06: - * Interface change: added new parameter "stTime", which enables the caller to provide - * a timestamp that is to be used as timegenerated instead of the current system time. - * This is meant to facilitate performance optimization. Some inputs support such modes. - * If stTime is NULL, the current system time is used. - * - * rgerhards, 2008-10-09: - * interface change: bParseHostname removed, now in flags +/* This takes a received message that must be decoded and submits it to + * the main message queue. This is a legacy function which is being provided + * to aid older input plugins that do not support message creation via + * the new interfaces themselves. It is not recommended to use this + * function for new plugins. -- rgerhards, 2009-10-12 */ -static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int flags, flowControl_t flowCtlType, +rsRetVal +parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int flags, flowControl_t flowCtlType, prop_t *pInputName, struct syslogTime *stTime, time_t ttGenTime) { - DEFiRet; - register uchar *p; - int pri; + prop_t *pProp = NULL; msg_t *pMsg; - prop_t *propFromHost = NULL; - prop_t *propFromHostIP = NULL; + DEFiRet; - /* Now it is time to create the message object (rgerhards) */ + /* we now create our own message object and submit it to the queue */ if(stTime == NULL) { CHKiRet(msgConstruct(&pMsg)); } else { @@ -577,278 +534,21 @@ static inline rsRetVal printline(uchar *hname, uchar *hnameIP, uchar *msg, int f } if(pInputName != NULL) MsgSetInputName(pMsg, pInputName); + MsgSetRawMsg(pMsg, (char*)msg, len); MsgSetFlowControlType(pMsg, flowCtlType); - MsgSetRawMsgWOSize(pMsg, (char*)msg); - - /* test for special codes */ - pri = DEFUPRI; - p = msg; - if (*p == '<') { - pri = 0; - while (isdigit((int) *++p)) - { - pri = 10 * pri + (*p - '0'); - } - if (*p == '>') - ++p; - } - if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) - pri = DEFUPRI; - pMsg->iFacility = LOG_FAC(pri); - pMsg->iSeverity = LOG_PRI(pri); - - /* Now we look at the HOSTNAME. That is a bit complicated... - * If we have a locally received message, it does NOT - * contain any hostname information in the message itself. - * As such, the HOSTNAME is the same as the system that - * the message was received from (that, for obvious reasons, - * being the local host). rgerhards 2004-11-16 - */ - if((pMsg->msgFlags & PARSE_HOSTNAME) == 0) - MsgSetHOSTNAME(pMsg, hname, ustrlen(hname)); - MsgSetRcvFromStr(pMsg, hname, ustrlen(hname), &propFromHost); - CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hnameIP), &propFromHostIP)); - MsgSetAfterPRIOffs(pMsg, p - msg); - prop.Destruct(&propFromHost); - prop.Destruct(&propFromHostIP); + pMsg->msgFlags = flags | NEEDS_PARSING; - logmsg(pMsg, flags); + MsgSetRcvFromStr(pMsg, hname, ustrlen(hname), &pProp); + CHKiRet(prop.Destruct(&pProp)); + CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hnameIP), &pProp)); + CHKiRet(prop.Destruct(&pProp)); + CHKiRet(submitMsg(pMsg)); finalize_it: RETiRet; } -/* This takes a received message that must be decoded and submits it to - * the main message queue. The function calls the necessary parser. - * - * rgerhards, 2006-11-30: I have greatly changed this function. Formerly, - * it tried to reassemble multi-part messages, which is a legacy stock - * sysklogd concept. In essence, that was that messages not ending with - * \0 were glued together. As far as I can see, this is a sysklogd - * specific feature and, from looking at the code, seems to be used - * pretty seldom (if at all). I remove this now, not the least because it is totally - * incompatible with upcoming IETF syslog standards. If you experience - * strange behaviour with messages beeing split across multiple lines, - * this function here might be the place to look at. - * - * Some previous history worth noting: - * I added the "iSource" parameter. This is needed to distinguish between - * messages that have a hostname in them (received from the internet) and - * those that do not have (most prominently /dev/log). rgerhards 2004-11-16 - * And now I removed the "iSource" parameter and changed it to be "bParseHost", - * because all that it actually controls is whether the host is parsed or not. - * For rfc3195 support, we needed to modify the algo for host parsing, so we can - * no longer rely just on the source (rfc3195d forwarded messages arrive via - * unix domain sockets but contain the hostname). rgerhards, 2005-10-06 - * - * rgerhards, 2008-02-18: - * This function was previously called "printchopped"() and has been renamed - * as part of the effort to create a clean internal message submission interface. - * It also has been adopted to our usual calling interface, but currently does - * not provide any useful return states. But we now have the hook and things can - * improve in the future. <-- TODO! - * - * rgerhards, 2008-03-19: - * I added an additional calling parameter to permit specifying the flow - * control capability of the source. - * - * rgerhards, 2008-05-16: - * I added an additional calling parameter (hnameIP) to enable specifying the IP - * of a remote host. - * - * rgerhards, 2008-09-11: - * Interface change: added new parameter "InputName", permits the input to provide - * a string that identifies it. May be NULL, but must be a valid char* pointer if - * non-NULL. - * - * rgerhards, 2008-10-06: - * Interface change: added new parameter "stTime", which enables the caller to provide - * a timestamp that is to be used as timegenerated instead of the current system time. - * This is meant to facilitate performance optimization. Some inputs support such modes. - * If stTime is NULL, the current system time is used. - * - * rgerhards, 2008-10-09: - * interface change: bParseHostname removed, now in flags - */ -rsRetVal -parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int flags, flowControl_t flowCtlType, - prop_t *pInputName, struct syslogTime *stTime, time_t ttGenTime) -{ - DEFiRet; - register int iMsg; - uchar *pMsg; - uchar *pData; - uchar *pEnd; - int iMaxLine; - uchar *tmpline = NULL; -# ifdef USE_NETZIP - uchar *deflateBuf = NULL; - uLongf iLenDefBuf; -# endif - - assert(hname != NULL); - assert(hnameIP != NULL); - assert(msg != NULL); - assert(len >= 0); - - /* we first allocate work buffers large enough to hold the configured maximum - * size of a message. Over time, we should change this to a more optimal way, i.e. - * by calling the function with the actual length of the message to be parsed. - * rgerhards, 2008-09-02 - * - * TODO: optimize buffer handling */ - iMaxLine = glbl.GetMaxLine(); - CHKmalloc(tmpline = malloc(sizeof(uchar) * (iMaxLine + 1))); - - /* we first check if we have a NUL character at the very end of the - * message. This seems to be a frequent problem with a number of senders. - * So I have now decided to drop these NULs. However, if they are intentional, - * that may cause us some problems, e.g. with syslog-sign. On the other hand, - * current code always has problems with intentional NULs (as it needs to escape - * them to prevent problems with the C string libraries), so that does not - * really matter. Just to be on the save side, we'll log destruction of such - * NULs in the debug log. - * rgerhards, 2007-09-14 - */ - if(*(msg + len - 1) == '\0') { - DBGPRINTF("dropped NUL at very end of message\n"); - len--; - } - - /* then we check if we need to drop trailing LFs, which often make - * their way into syslog messages unintentionally. In order to remain - * compatible to recent IETF developments, we allow the user to - * turn on/off this handling. rgerhards, 2007-07-23 - */ - if(bDropTrailingLF && *(msg + len - 1) == '\n') { - DBGPRINTF("dropped LF at very end of message (DropTrailingLF is set)\n"); - len--; - } - - iMsg = 0; /* initialize receiving buffer index */ - pMsg = tmpline; /* set receiving buffer pointer */ - pData = msg; /* set source buffer pointer */ - pEnd = msg + len; /* this is one off, which is intensional */ - -# ifdef USE_NETZIP - /* we first need to check if we have a compressed record. If so, - * we must decompress it. - */ - if(len > 0 && *msg == 'z') { /* compressed data present? (do NOT change order if conditions!) */ - /* we have compressed data, so let's deflate it. We support a maximum - * message size of iMaxLine. If it is larger, an error message is logged - * and the message is dropped. We do NOT try to decompress larger messages - * as such might be used for denial of service. It might happen to later - * builds that such functionality be added as an optional, operator-configurable - * feature. - */ - int ret; - iLenDefBuf = iMaxLine; - CHKmalloc(deflateBuf = malloc(sizeof(uchar) * (iMaxLine + 1))); - ret = uncompress((uchar *) deflateBuf, &iLenDefBuf, (uchar *) msg+1, len-1); - DBGPRINTF("Compressed message uncompressed with status %d, length: new %ld, old %d.\n", - ret, (long) iLenDefBuf, len-1); - /* Now check if the uncompression worked. If not, there is not much we can do. In - * that case, we log an error message but ignore the message itself. Storing the - * compressed text is dangerous, as it contains control characters. So we do - * not do this. If someone would like to have a copy, this code here could be - * modified to do a hex-dump of the buffer in question. We do not include - * this functionality right now. - * rgerhards, 2006-12-07 - */ - if(ret != Z_OK) { - errmsg.LogError(0, NO_ERRCODE, "Uncompression of a message failed with return code %d " - "- enable debug logging if you need further information. " - "Message ignored.", ret); - FINALIZE; /* unconditional exit, nothing left to do... */ - } - pData = deflateBuf; - pEnd = deflateBuf + iLenDefBuf; - } -# else /* ifdef USE_NETZIP */ - /* in this case, we still need to check if the message is compressed. If so, we must - * tell the user we can not accept it. - */ - if(len > 0 && *msg == 'z') { - errmsg.LogError(0, NO_ERRCODE, "Received a compressed message, but rsyslogd does not have compression " - "support enabled. The message will be ignored."); - FINALIZE; - } -# endif /* ifdef USE_NETZIP */ - - while(pData < pEnd) { - if(iMsg >= iMaxLine) { - /* emergency, we now need to flush, no matter if - * we are at end of message or not... - */ - if(iMsg == iMaxLine) { - *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ - printline(hname, hnameIP, tmpline, flags, flowCtlType, pInputName, stTime, ttGenTime); - } else { - /* This case in theory never can happen. If it happens, we have - * a logic error. I am checking for it, because if I would not, - * we would address memory invalidly with the code above. I - * do not care much about this case, just a debug log entry - * (I couldn't do any more smart things anyway...). - * rgerhards, 2007-9-20 - */ - DBGPRINTF("internal error: iMsg > max msg size in printchopped()\n"); - } - FINALIZE; /* in this case, we are done... nothing left we can do */ - } - if(*pData == '\0') { /* guard against \0 characters... */ - /* changed to the sequence (somewhat) proposed in - * draft-ietf-syslog-protocol-19. rgerhards, 2006-11-30 - */ - if(iMsg + 3 < iMaxLine) { /* do we have space? */ - *(pMsg + iMsg++) = cCCEscapeChar; - *(pMsg + iMsg++) = '0'; - *(pMsg + iMsg++) = '0'; - *(pMsg + iMsg++) = '0'; - } /* if we do not have space, we simply ignore the '\0'... */ - /* log an error? Very questionable... rgerhards, 2006-11-30 */ - /* decided: we do not log an error, it won't help... rger, 2007-06-21 */ - ++pData; - } else if(bEscapeCCOnRcv && iscntrl((int) *pData)) { - /* we are configured to escape control characters. Please note - * that this most probably break non-western character sets like - * Japanese, Korean or Chinese. rgerhards, 2007-07-17 - * Note: sysklogd logs octal values only for DEL and CCs above 127. - * For others, it logs ^n where n is the control char converted to an - * alphabet character. We like consistency and thus escape it to octal - * in all cases. If someone complains, we may change the mode. At least - * we known now what's going on. - * rgerhards, 2007-07-17 - */ - if(iMsg + 3 < iMaxLine) { /* do we have space? */ - *(pMsg + iMsg++) = cCCEscapeChar; - *(pMsg + iMsg++) = '0' + ((*pData & 0300) >> 6); - *(pMsg + iMsg++) = '0' + ((*pData & 0070) >> 3); - *(pMsg + iMsg++) = '0' + ((*pData & 0007)); - } /* again, if we do not have space, we ignore the char - see comment at '\0' */ - ++pData; - } else { - *(pMsg + iMsg++) = *pData++; - } - } - - *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ - - /* typically, we should end up here! */ - printline(hname, hnameIP, tmpline, flags, flowCtlType, pInputName, stTime, ttGenTime); - -finalize_it: - if(tmpline != NULL) - free(tmpline); -# ifdef USE_NETZIP - if(deflateBuf != NULL) - free(deflateBuf); -# endif - RETiRet; -} - - /* this is a special function used to submit an error message. This * function is also passed to the runtime library as the generic error * message handler. -- rgerhards, 2008-04-17 -- cgit v1.2.3 From 05b0c4322bbd7621762dc4b9b3a2e1baeabdaa1f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 13 Oct 2009 07:29:11 +0200 Subject: removed no longer needed msg_t property "bParseHOSTNAME" --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5dd03fcb..58046558 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -596,7 +596,6 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) } pMsg->iFacility = LOG_FAC(pri); pMsg->iSeverity = LOG_PRI(pri); - pMsg->bParseHOSTNAME = 0; flags |= INTERNAL_MSG; /* we now check if we should print internal messages out to stderr. This was -- cgit v1.2.3 From 4d70c9b3e5e480d6dfa1c94506270f1f78e8ef32 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 13 Oct 2009 14:38:45 +0200 Subject: added some debug settings plus improved shutdown sequence ... non-working version! --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 58046558..36a46175 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -631,7 +631,7 @@ finalize_it: * for the main queue. */ static rsRetVal -msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch) +msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShutdownImmediate) { int i; msg_t *pMsg; @@ -639,7 +639,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch) assert(pBatch != NULL); - for(i = 0 ; i < pBatch->nElem ; i++) { + for(i = 0 ; i < pBatch->nElem && !*pbShutdownImmediate ; i++) { pMsg = (msg_t*) pBatch->pElem[i].pUsrp; DBGPRINTF("msgConsumer processes msg %d/%d\n", i, pBatch->nElem); if((pMsg->msgFlags & NEEDS_PARSING) != 0) { -- cgit v1.2.3 From c5408da3d8f17691fb91282d031757ed041fec55 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 14 Oct 2009 11:01:21 +0200 Subject: new queue engine - initial commit (probably not 100% working!) simplified and thus speeded up the queue engine, also fixed some potential race conditions (in very unusual shutdown conditions) along the way. The threading model has seriously changes, so there may be some regressions. NOTE: the code passed basic tests, but there is still more work and testing to be done. This commit should be treated with care. --- tools/syslogd.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 36a46175..89b90dec 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -158,6 +158,7 @@ DEFobjCurrIf(net) /* TODO: make go away! */ /* forward definitions */ static rsRetVal GlobalClassExit(void); +static void logmsg(msg_t *pMsg, int flags); #ifndef _PATH_LOGCONF @@ -400,13 +401,16 @@ static int usage(void) */ /* return back the approximate current number of messages in the main message queue + * This number includes the messages that reside in an associated DA queue (if + * it exists) -- rgerhards, 2009-10-14 */ rsRetVal diagGetMainMsgQSize(int *piSize) { DEFiRet; assert(piSize != NULL); - *piSize = pMsgQueue->iQueueSize; + *piSize = (pMsgQueue->bIsDA) ? pMsgQueue->pqDA->iQueueSize : 0; + *piSize += pMsgQueue->iQueueSize; RETiRet; } @@ -584,6 +588,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); MsgSetRcvFromIP(pMsg, pLocalHostIP); + MsgSetMSGoffs(pMsg, 0); /* check if we have an error code associated and, if so, * adjust the tag. -- rgerhards, 2008-06-27 */ @@ -1079,7 +1084,7 @@ multiSubmitMsg(multi_submit_t *pMultiSub) * potential for misinterpretation, which we simply can not solve under the * circumstances given. */ -void +static void logmsg(msg_t *pMsg, int flags) { char *msg; -- cgit v1.2.3 From e6b2cba8038061ab7f1f324110eeabbc8dfe2c30 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 14 Oct 2009 11:16:43 +0200 Subject: bugfix(minor): diag function returned wrong queue memeber count ...for the main queue if an active DA queue existed. This had no relevance to real deployments (assuming they are not running the debug/diagnostic module...), but sometimes caused grief and false alerts in the testbench. --- tools/syslogd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 45c30baa..fb3294d5 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -411,7 +411,8 @@ diagGetMainMsgQSize(int *piSize) { DEFiRet; assert(piSize != NULL); - *piSize = pMsgQueue->iQueueSize; + *piSize = (pMsgQueue->pqDA != NULL) ? pMsgQueue->pqDA->iQueueSize : 0; + *piSize += pMsgQueue->iQueueSize; RETiRet; } -- cgit v1.2.3 From 90e8475260cf8ac54519b3d964d879489af879f6 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 19 Oct 2009 09:41:45 +0200 Subject: bugfix: message processing states were not set correctly in all cases however, this had no negative effect, as the message processing state was not evaluated when a batch was deleted, and that was the only case where the state could be wrong. --- tools/syslogd.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 1c494dea..f8a78343 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -641,6 +641,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu int i; msg_t *pMsg; DEFiRet; + rsRetVal localRet; assert(pBatch != NULL); @@ -650,7 +651,11 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu if((pMsg->msgFlags & NEEDS_PARSING) != 0) { parseMsg(pMsg); } + localRet = ruleset.ProcessMsg(pMsg); +dbgprintf("msgConsumer got iRet %d from ProcessMsg\n", localRet); + /* if we reach this point, the message is considered committed (by definition!) */ + pBatch->pElem[i].state = BATCH_STATE_COMM; } RETiRet; -- cgit v1.2.3 From 4ccf24c096073e9ef1681faf8c459474d6e584c2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 19 Oct 2009 10:17:24 +0200 Subject: cleanup: finally moved some config variables just to conf.c --- tools/syslogd.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 99ccd1f1..7945ec55 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1888,11 +1888,6 @@ init(void) struct sigaction sigAct; DEFiRet; - /* initialize some static variables */ - pDfltHostnameCmp = NULL; - pDfltProgNameCmp = NULL; - eDfltHostnameCmpMode = HN_NO_COMP; - DBGPRINTF("rsyslog %s - called init()\n", VERSION); /* construct the default ruleset */ @@ -1942,17 +1937,6 @@ init(void) legacyOptsHook(); - /* we are now done with reading the configuration. This is the right time to - * free some objects that were just needed for loading it. rgerhards 2005-10-19 - */ - if(pDfltHostnameCmp != NULL) { - rsCStrDestruct(&pDfltHostnameCmp); - } - - if(pDfltProgNameCmp != NULL) { - rsCStrDestruct(&pDfltProgNameCmp); - } - /* some checks */ if(iMainMsgQueueNumWorkers < 1) { errmsg.LogError(0, NO_ERRCODE, "$MainMsgQueueNumWorkers must be at least 1! Set to 1.\n"); -- cgit v1.2.3 From e04e1b50025f5fa9c26abd946190dce8f797d08f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 22 Oct 2009 11:33:38 +0200 Subject: enhanced test environment (including testbench) support for enhancing probability of memory addressing failure by using non-NULL default value for malloced memory (optional, only if requested by configure option). This helps to track down some otherwise undetected issues within the testbench and is expected to be very useful in the future. --- tools/syslogd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 07829e46..cf37e1f0 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -447,7 +447,7 @@ static char **crunch_list(char *list) for (count=i=0; p[i]; i++) if (p[i] == LIST_DELIMITER) count++; - if ((result = (char **)malloc(sizeof(char *) * (count+2))) == NULL) { + if ((result = (char **)MALLOC(sizeof(char *) * (count+2))) == NULL) { printf ("Sorry, can't get enough memory, exiting.\n"); exit(0); /* safe exit, because only called during startup */ } @@ -459,7 +459,7 @@ static char **crunch_list(char *list) */ count = 0; while ((q=strchr(p, LIST_DELIMITER))) { - result[count] = (char *) malloc((q - p + 1) * sizeof(char)); + result[count] = (char *) MALLOC((q - p + 1) * sizeof(char)); if (result[count] == NULL) { printf ("Sorry, can't get enough memory, exiting.\n"); exit(0); /* safe exit, because only called during startup */ @@ -470,7 +470,7 @@ static char **crunch_list(char *list) count++; } if ((result[count] = \ - (char *)malloc(sizeof(char) * strlen(p) + 1)) == NULL) { + (char *)MALLOC(sizeof(char) * strlen(p) + 1)) == NULL) { printf ("Sorry, can't get enough memory, exiting.\n"); exit(0); /* safe exit, because only called during startup */ } @@ -828,7 +828,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags) * message, so we can not run into any troubles. I think this is * more wise then to use individual buffers. */ - if((pBuf = malloc(sizeof(uchar) * (lenMsg + 1))) == NULL) + if((pBuf = MALLOC(sizeof(uchar) * (lenMsg + 1))) == NULL) return 1; /* IMPORTANT NOTE: @@ -1208,7 +1208,7 @@ void legacyOptsEnq(uchar *line) { legacyOptsLL_t *pNew; - pNew = malloc(sizeof(legacyOptsLL_t)); + pNew = MALLOC(sizeof(legacyOptsLL_t)); if(line == NULL) pNew->line = NULL; else @@ -2661,7 +2661,7 @@ bufOptAdd(char opt, char *arg) DEFiRet; bufOpt_t *pBuf; - if((pBuf = malloc(sizeof(bufOpt_t))) == NULL) + if((pBuf = MALLOC(sizeof(bufOpt_t))) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); pBuf->optchar = opt; -- cgit v1.2.3 From f3134f89211ea6a65e72bca1dd2f91bf0a0ae894 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 27 Oct 2009 15:16:10 +0100 Subject: some more cleanup - action config line handlers are now defined in action.c As an artifact of early development, they were registered in syslogd.c --- tools/syslogd.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index cf37e1f0..10df10d1 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -133,7 +133,6 @@ #include "errmsg.h" #include "datetime.h" #include "parser.h" -//#include "sysvar.h" #include "batch.h" #include "unicode-helper.h" #include "ruleset.h" @@ -2397,11 +2396,6 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroup", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroupid", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL)); - /* now add other modules handlers (we should work on that to be able to do it in ClassInit(), but so far - * that is not possible). -- rgerhards, 2008-01-28 - */ - CHKiRet(actionAddCfSysLineHdrl()); - finalize_it: RETiRet; } -- cgit v1.2.3 From 1ada506e2d90377c2475e103340d8986bf8847f9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 27 Oct 2009 17:31:27 +0100 Subject: added the capability to have ruleset-specific main message queues This offers considerable additional flexibility AND superior performance (in cases where multiple inputs now can avoid lock contention) --- tools/syslogd.c | 125 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 53 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 10df10d1..62d33677 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -265,7 +265,7 @@ extern int errno; static uchar *pszConfDAGFile = NULL; /* name of config DAG file, non-NULL means generate one */ /* main message queue and its configuration parameters */ -static qqueue_t *pMsgQueue = NULL; /* the main message queue */ +qqueue_t *pMsgQueue = NULL; /* the main message queue */ static int iMainMsgQueueSize = 10000; /* size of the main message queue above */ static int iMainMsgQHighWtrMark = 8000; /* high water mark for disk-assisted queues */ static int iMainMsgQLowWtrMark = 2000; /* low water mark for disk-assisted queues */ @@ -640,7 +640,6 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu int i; msg_t *pMsg; DEFiRet; - rsRetVal localRet; assert(pBatch != NULL); @@ -650,9 +649,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu if((pMsg->msgFlags & NEEDS_PARSING) != 0) { parseMsg(pMsg); } - localRet = ruleset.ProcessMsg(pMsg); -dbgprintf("msgConsumer got iRet %d from ProcessMsg\n", localRet); /* if we reach this point, the message is considered committed (by definition!) */ pBatch->pElem[i].state = BATCH_STATE_COMM; } @@ -1037,12 +1034,17 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) rsRetVal submitMsg(msg_t *pMsg) { + qqueue_t *pQueue; + ruleset_t *pRuleset; DEFiRet; ISOBJ_TYPE_assert(pMsg, msg); + pRuleset = MsgGetRuleset(pMsg); + + pQueue = (pRuleset == NULL) ? pMsgQueue : ruleset.GetRulesetQueue(pRuleset); MsgPrepareEnqueue(pMsg); - qqueueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg); + qqueueEnqObj(pQueue, pMsg->flowCtlType, (void*) pMsg); RETiRet; } @@ -1880,6 +1882,70 @@ startInputModules(void) } +/* create a main message queue, now also used for ruleset queues. This function + * needs to be moved to some other module, but it is considered acceptable for + * the time being (remember that we want to restructure config processing at large!). + * rgerhards, 2009-10-27 + */ +rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) +{ + DEFiRet; + + /* switch the message object to threaded operation, if necessary */ + if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) { + MsgEnableThreadSafety(); + } + + /* create message queue */ + CHKiRet_Hdlr(qqueueConstruct(ppQueue, MainMsgQueType, iMainMsgQueueNumWorkers, iMainMsgQueueSize, msgConsumer)) { + /* no queue is fatal, we need to give up in that case... */ + errmsg.LogError(0, iRet, "could not create (ruleset) main message queue"); \ + } + /* name our main queue object (it's not fatal if it fails...) */ + obj.SetName((obj_t*) (*ppQueue), pszQueueName); + + /* ... set some properties ... */ +# define setQPROP(func, directive, data) \ + CHKiRet_Hdlr(func(*ppQueue, data)) { \ + errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ + } +# define setQPROPstr(func, directive, data) \ + CHKiRet_Hdlr(func(*ppQueue, data, (data == NULL)? 0 : strlen((char*) data))) { \ + errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ + } + + setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", iMainMsgQueMaxFileSize); + setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", iMainMsgQueMaxDiskSpace); + setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", iMainMsgQueDeqBatchSize); + setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", pszMainMsgQFName); + setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", iMainMsgQPersistUpdCnt); + setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", bMainMsgQSyncQeueFiles); + setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", iMainMsgQtoQShutdown ); + setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", iMainMsgQtoActShutdown); + setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", iMainMsgQtoWrkShutdown); + setQPROP(qqueueSettoEnq, "$MainMsgQueueTimeoutEnqueue", iMainMsgQtoEnq); + setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark); + setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark); + setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark); + setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity); + setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); + setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); + setQPROP(qqueueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", iMainMsgQDeqSlowdown); + setQPROP(qqueueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", iMainMsgQueueDeqtWinFromHr); + setQPROP(qqueueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", iMainMsgQueueDeqtWinToHr); + +# undef setQPROP +# undef setQPROPstr + + /* ... and finally start the queue! */ + CHKiRet_Hdlr(qqueueStart(*ppQueue)) { + /* no queue is fatal, we need to give up in that case... */ + errmsg.LogError(0, iRet, "could not start (ruleset) main message queue"); \ + } + RETiRet; +} + + /* INIT -- Initialize syslogd * Note that if iConfigVerify is set, only the config file is verified but nothing * else happens. -- rgerhards, 2008-07-28 @@ -1988,59 +2054,12 @@ init(void) exit(2); } - /* switch the message object to threaded operation, if necessary */ - if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) { - MsgEnableThreadSafety(); - } - /* create message queue */ - CHKiRet_Hdlr(qqueueConstruct(&pMsgQueue, MainMsgQueType, iMainMsgQueueNumWorkers, iMainMsgQueueSize, msgConsumer)) { + CHKiRet_Hdlr(createMainQueue(&pMsgQueue, UCHAR_CONSTANT("main Q"))) { /* no queue is fatal, we need to give up in that case... */ fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); exit(1); } - /* name our main queue object (it's not fatal if it fails...) */ - obj.SetName((obj_t*) pMsgQueue, (uchar*) "main Q"); - - /* ... set some properties ... */ -# define setQPROP(func, directive, data) \ - CHKiRet_Hdlr(func(pMsgQueue, data)) { \ - errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ - } -# define setQPROPstr(func, directive, data) \ - CHKiRet_Hdlr(func(pMsgQueue, data, (data == NULL)? 0 : strlen((char*) data))) { \ - errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ - } - - setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", iMainMsgQueMaxFileSize); - setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", iMainMsgQueMaxDiskSpace); - setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", iMainMsgQueDeqBatchSize); - setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", pszMainMsgQFName); - setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", iMainMsgQPersistUpdCnt); - setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", bMainMsgQSyncQeueFiles); - setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", iMainMsgQtoQShutdown ); - setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", iMainMsgQtoActShutdown); - setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", iMainMsgQtoWrkShutdown); - setQPROP(qqueueSettoEnq, "$MainMsgQueueTimeoutEnqueue", iMainMsgQtoEnq); - setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark); - setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark); - setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark); - setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity); - setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); - setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); - setQPROP(qqueueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", iMainMsgQDeqSlowdown); - setQPROP(qqueueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", iMainMsgQueueDeqtWinFromHr); - setQPROP(qqueueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", iMainMsgQueueDeqtWinToHr); - -# undef setQPROP -# undef setQPROPstr - - /* ... and finally start the queue! */ - CHKiRet_Hdlr(qqueueStart(pMsgQueue)) { - /* no queue is fatal, we need to give up in that case... */ - fprintf(stderr, "fatal error %d: could not start message queue - rsyslogd can not run!\n", iRet); - exit(1); - } bHaveMainQueue = (MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1; DBGPRINTF("Main processing queue is initialized and running\n"); -- cgit v1.2.3 From caad1340d64a345fa9d1bfc3f902e898d6ee2f76 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 30 Oct 2009 16:51:22 +0100 Subject: bugfix: correct default for escape ('#') character restored This was accidently changed to '\\', thanks to David Lang for reporting the bug. --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 62d33677..270bf843 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -242,7 +242,7 @@ static int bLogStatusMsgs = DFLT_bLogStatusMsgs; /* log rsyslog start/stop/HUP m static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */ static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */ static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ -uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence for control chars */ +uchar cCCEscapeChar = '#';/* character to be used to start an escape sequence for control chars */ int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */ static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ -- cgit v1.2.3 From f291d5c570052f163004cbf31f24bb0884dc6681 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 3 Nov 2009 10:08:17 +0100 Subject: ruleset queue setting was not honored during multi-submit --- tools/syslogd.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 270bf843..41d819a6 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1027,8 +1027,6 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) /* submit a message to the main message queue. This is primarily * a hook to prevent the need for callers to know about the main message queue - * (which may change in the future as we will probably have multiple rule - * sets and thus queues...). * rgerhards, 2008-02-13 */ rsRetVal @@ -1051,23 +1049,31 @@ submitMsg(msg_t *pMsg) /* submit multiple messages at once, very similar to submitMsg, just - * for multi_submit_t. + * for multi_submit_t. All messages need to go into the SAME queue! * rgerhards, 2009-06-16 */ rsRetVal multiSubmitMsg(multi_submit_t *pMultiSub) { int i; + qqueue_t *pQueue; + ruleset_t *pRuleset; DEFiRet; assert(pMultiSub != NULL); + if(pMultiSub->nElem == 0) + FINALIZE; + for(i = 0 ; i < pMultiSub->nElem ; ++i) { MsgPrepareEnqueue(pMultiSub->ppMsgs[i]); } - iRet = qqueueMultiEnqObj(pMsgQueue, pMultiSub); + pRuleset = MsgGetRuleset(pMultiSub->ppMsgs[0]); + pQueue = (pRuleset == NULL) ? pMsgQueue : ruleset.GetRulesetQueue(pRuleset); + iRet = qqueueMultiEnqObj(pQueue, pMultiSub); pMultiSub->nElem = 0; +finalize_it: RETiRet; } -- cgit v1.2.3 From 7d78b3bdfd357dd921797ce983eb96532c56a7f6 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 3 Nov 2009 10:41:47 +0100 Subject: restructured parser part of rsyslog now cleaner and hopefully usuable as a basis for loadable parser modules. I also cleaned up/consolidated some of the internal message generation functionality in rsyslogd. --- tools/syslogd.c | 447 +------------------------------------------------------- 1 file changed, 7 insertions(+), 440 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 41d819a6..998d6512 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -157,7 +157,6 @@ DEFobjCurrIf(net) /* TODO: make go away! */ /* forward definitions */ static rsRetVal GlobalClassExit(void); -static void logmsg(msg_t *pMsg, int flags); #ifndef _PATH_LOGCONF @@ -207,7 +206,7 @@ static pid_t myPid; /* our pid for use in self-generated messages, e.g. on start /* mypid is read-only after the initial fork() */ static int bHadHUP = 0; /* did we have a HUP? */ -static int bParseHOSTNAMEandTAG = 1; /* global config var: should the hostname and tag be +int bParseHOSTNAMEandTAG = 1; /* global config var: should the hostname and tag be * parsed inside message - rgerhards, 2006-03-13 */ static int bFinished = 0; /* used by termination signal handler, read-only except there * is either 0 or the number of the signal that requested the @@ -566,13 +565,7 @@ submitErrMsg(int iErr, uchar *msg) /* rgerhards 2004-11-09: the following is a function that can be used - * to log a message orginating from the syslogd itself. In sysklogd code, - * this is done by simply calling logmsg(). However, logmsg() is changed in - * rsyslog so that it takes a msg "object". So it can no longer be called - * directly. This method here solves the need. It provides an interface that - * allows to construct a locally-generated message. Please note that this - * function here probably is only an interim solution and that we need to - * think on the best way to do this. + * to log a message orginating from the syslogd itself. */ rsRetVal logmsgInternal(int iErr, int pri, uchar *msg, int flags) @@ -601,6 +594,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) pMsg->iFacility = LOG_FAC(pri); pMsg->iSeverity = LOG_PRI(pri); flags |= INTERNAL_MSG; + pMsg->msgFlags = flags; /* we now check if we should print internal messages out to stderr. This was * suggested by HKS as a way to help people troubleshoot rsyslog configuration @@ -616,12 +610,12 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) } if(bHaveMainQueue == 0) { /* not yet in queued mode */ - iminternalAddMsg(pri, pMsg, flags); + iminternalAddMsg(pri, pMsg); } else { /* we have the queue, so we can simply provide the * message to the queue engine. */ - logmsg(pMsg, flags); + submitMsg(pMsg); } finalize_it: RETiRet; @@ -658,373 +652,6 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu } -/* Helper to parseRFCSyslogMsg. This function parses a field up to - * (and including) the SP character after it. The field contents is - * returned in a caller-provided buffer. The parsepointer is advanced - * to after the terminating SP. The caller must ensure that the - * provided buffer is large enough to hold the to be extracted value. - * Returns 0 if everything is fine or 1 if either the field is not - * SP-terminated or any other error occurs. -- rger, 2005-11-24 - * The function now receives the size of the string and makes sure - * that it does not process more than that. The *pLenStr counter is - * updated on exit. -- rgerhards, 2009-09-23 - */ -static int parseRFCField(uchar **pp2parse, uchar *pResult, int *pLenStr) -{ - uchar *p2parse; - int iRet = 0; - - assert(pp2parse != NULL); - assert(*pp2parse != NULL); - assert(pResult != NULL); - - p2parse = *pp2parse; - - /* this is the actual parsing loop */ - while(*pLenStr > 0 && *p2parse != ' ') { - *pResult++ = *p2parse++; - --(*pLenStr); - } - - if(*pLenStr > 0 && *p2parse == ' ') { - ++p2parse; /* eat SP, but only if not at end of string */ - --(*pLenStr); - } else { - iRet = 1; /* there MUST be an SP! */ - } - *pResult = '\0'; - - /* set the new parse pointer */ - *pp2parse = p2parse; - return 0; -} - - -/* Helper to parseRFCSyslogMsg. This function parses the structured - * data field of a message. It does NOT parse inside structured data, - * just gets the field as whole. Parsing the single entities is left - * to other functions. The parsepointer is advanced - * to after the terminating SP. The caller must ensure that the - * provided buffer is large enough to hold the to be extracted value. - * Returns 0 if everything is fine or 1 if either the field is not - * SP-terminated or any other error occurs. -- rger, 2005-11-24 - * The function now receives the size of the string and makes sure - * that it does not process more than that. The *pLenStr counter is - * updated on exit. -- rgerhards, 2009-09-23 - */ -static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult, int *pLenStr) -{ - uchar *p2parse; - int bCont = 1; - int iRet = 0; - int lenStr; - - assert(pp2parse != NULL); - assert(*pp2parse != NULL); - assert(pResult != NULL); - - p2parse = *pp2parse; - lenStr = *pLenStr; - - /* this is the actual parsing loop - * Remeber: structured data starts with [ and includes any characters - * until the first ] followed by a SP. There may be spaces inside - * structured data. There may also be \] inside the structured data, which - * do NOT terminate an element. - */ - if(lenStr == 0 || *p2parse != '[') - return 1; /* this is NOT structured data! */ - - if(*p2parse == '-') { /* empty structured data? */ - *pResult++ = '-'; - ++p2parse; - --lenStr; - } else { - while(bCont) { - if(lenStr < 2) { - /* we now need to check if we have only structured data */ - if(lenStr > 0 && *p2parse == ']') { - *pResult++ = *p2parse; - p2parse++; - lenStr--; - bCont = 0; - } else { - iRet = 1; /* this is not valid! */ - bCont = 0; - } - } else if(*p2parse == '\\' && *(p2parse+1) == ']') { - /* this is escaped, need to copy both */ - *pResult++ = *p2parse++; - *pResult++ = *p2parse++; - lenStr -= 2; - } else if(*p2parse == ']' && *(p2parse+1) == ' ') { - /* found end, just need to copy the ] and eat the SP */ - *pResult++ = *p2parse; - p2parse += 2; - lenStr -= 2; - bCont = 0; - } else { - *pResult++ = *p2parse++; - --lenStr; - } - } - } - - if(lenStr > 0 && *p2parse == ' ') { - ++p2parse; /* eat SP, but only if not at end of string */ - --lenStr; - } else { - iRet = 1; /* there MUST be an SP! */ - } - *pResult = '\0'; - - /* set the new parse pointer */ - *pp2parse = p2parse; - *pLenStr = lenStr; - return 0; -} - -/* parse a RFC5424-formatted syslog message. This function returns - * 0 if processing of the message shall continue and 1 if something - * went wrong and this messe should be ignored. This function has been - * implemented in the effort to support syslog-protocol. Please note that - * the name (parse *RFC*) stems from the hope that syslog-protocol will - * some time become an RFC. Do not confuse this with informational - * RFC 3164 (which is legacy syslog). - * - * currently supported format: - * - * VERSION SP TIMESTAMP SP HOSTNAME SP APP-NAME SP PROCID SP MSGID SP [SD-ID]s SP MSG - * - * is already stripped when this function is entered. VERSION already - * has been confirmed to be "1", but has NOT been stripped from the message. - * - * rger, 2005-11-24 - */ -int parseRFCSyslogMsg(msg_t *pMsg, int flags) -{ - uchar *p2parse; - uchar *pBuf; - int lenMsg; - int bContParse = 1; - - BEGINfunc - assert(pMsg != NULL); - assert(pMsg->pszRawMsg != NULL); - p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ - lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; - - /* do a sanity check on the version and eat it (the caller checked this already) */ - assert(p2parse[0] == '1' && p2parse[1] == ' '); - p2parse += 2; - lenMsg -= 2; - - /* Now get us some memory we can use as a work buffer while parsing. - * We simply allocated a buffer sufficiently large to hold all of the - * message, so we can not run into any troubles. I think this is - * more wise then to use individual buffers. - */ - if((pBuf = MALLOC(sizeof(uchar) * (lenMsg + 1))) == NULL) - return 1; - - /* IMPORTANT NOTE: - * Validation is not actually done below nor are any errors handled. I have - * NOT included this for the current proof of concept. However, it is strongly - * advisable to add it when this code actually goes into production. - * rgerhards, 2005-11-24 - */ - - /* TIMESTAMP */ - if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) { - if(flags & IGNDATE) { - /* we need to ignore the msg data, so simply copy over reception date */ - memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); - } - } else { - DBGPRINTF("no TIMESTAMP detected!\n"); - bContParse = 0; - } - - /* HOSTNAME */ - if(bContParse) { - parseRFCField(&p2parse, pBuf, &lenMsg); - MsgSetHOSTNAME(pMsg, pBuf, ustrlen(pBuf)); - } - - /* APP-NAME */ - if(bContParse) { - parseRFCField(&p2parse, pBuf, &lenMsg); - MsgSetAPPNAME(pMsg, (char*)pBuf); - } - - /* PROCID */ - if(bContParse) { - parseRFCField(&p2parse, pBuf, &lenMsg); - MsgSetPROCID(pMsg, (char*)pBuf); - } - - /* MSGID */ - if(bContParse) { - parseRFCField(&p2parse, pBuf, &lenMsg); - MsgSetMSGID(pMsg, (char*)pBuf); - } - - /* STRUCTURED-DATA */ - if(bContParse) { - parseRFCStructuredData(&p2parse, pBuf, &lenMsg); - MsgSetStructuredData(pMsg, (char*)pBuf); - } - - /* MSG */ - MsgSetMSGoffs(pMsg, p2parse - pMsg->pszRawMsg); - - free(pBuf); - ENDfunc - return 0; /* all ok */ -} - - -/* parse a legay-formatted syslog message. This function returns - * 0 if processing of the message shall continue and 1 if something - * went wrong and this messe should be ignored. This function has been - * implemented in the effort to support syslog-protocol. - * rger, 2005-11-24 - * As of 2006-01-10, I am removing the logic to continue parsing only - * when a valid TIMESTAMP is detected. Validity of other fields already - * is ignored. This is due to the fact that the parser has grown smarter - * and is now more able to understand different dialects of the syslog - * message format. I do not expect any bad side effects of this change, - * but I thought I log it in this comment. - * rgerhards, 2006-01-10 - */ -int parseLegacySyslogMsg(msg_t *pMsg, int flags) -{ - uchar *p2parse; - int lenMsg; - int bTAGCharDetected; - int i; /* general index for parsing */ - uchar bufParseTAG[CONF_TAG_MAXSIZE]; - uchar bufParseHOSTNAME[CONF_TAG_HOSTNAME]; - BEGINfunc - - assert(pMsg != NULL); - assert(pMsg->pszRawMsg != NULL); - lenMsg = pMsg->iLenRawMsg - (pMsg->offAfterPRI + 1); - p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ - - /* Check to see if msg contains a timestamp. We start by assuming - * that the message timestamp is the time of reception (which we - * generated ourselfs and then try to actually find one inside the - * message. There we go from high-to low precison and are done - * when we find a matching one. -- rgerhards, 2008-09-16 - */ - if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) { - /* we are done - parse pointer is moved by ParseTIMESTAMP3339 */; - } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) { - /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */; - } else if(*p2parse == ' ' && lenMsg > 1) { /* try to see if it is slighly malformed - HP procurve seems to do that sometimes */ - ++p2parse; /* move over space */ - --lenMsg; - if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) { - /* indeed, we got it! */ - /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */; - } else {/* parse pointer needs to be restored, as we moved it off-by-one - * for this try. - */ - --p2parse; - ++lenMsg; - } - } - - if(flags & IGNDATE) { - /* we need to ignore the msg data, so simply copy over reception date */ - memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); - } - - /* rgerhards, 2006-03-13: next, we parse the hostname and tag. But we - * do this only when the user has not forbidden this. I now introduce some - * code that allows a user to configure rsyslogd to treat the rest of the - * message as MSG part completely. In this case, the hostname will be the - * machine that we received the message from and the tag will be empty. This - * is meant to be an interim solution, but for now it is in the code. - */ - if(bParseHOSTNAMEandTAG && !(flags & INTERNAL_MSG)) { - /* parse HOSTNAME - but only if this is network-received! - * rger, 2005-11-14: we still have a problem with BSD messages. These messages - * do NOT include a host name. In most cases, this leads to the TAG to be treated - * as hostname and the first word of the message as the TAG. Clearly, this is not - * of advantage ;) I think I have now found a way to handle this situation: there - * are certain characters which are frequently used in TAG (e.g. ':'), which are - * *invalid* in host names. So while parsing the hostname, I check for these characters. - * If I find them, I set a simple flag but continue. After parsing, I check the flag. - * If it was set, then we most probably do not have a hostname but a TAG. Thus, I change - * the fields. I think this logic shall work with any type of syslog message. - * rgerhards, 2009-06-23: and I now have extended this logic to every character - * that is not a valid hostname. - */ - bTAGCharDetected = 0; - if(lenMsg > 0 && flags & PARSE_HOSTNAME) { - i = 0; - while(i < lenMsg && (isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.' - || p2parse[i] == '_' || p2parse[i] == '-') && i < CONF_TAG_MAXSIZE) { - bufParseHOSTNAME[i] = p2parse[i]; - ++i; - } - - if(i > 0 && p2parse[i] == ' ' && isalnum(p2parse[i-1])) { - /* we got a hostname! */ - p2parse += i + 1; /* "eat" it (including SP delimiter) */ - lenMsg -= i + 1; - bufParseHOSTNAME[i] = '\0'; - MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i); - } - } - - /* now parse TAG - that should be present in message from all sources. - * This code is somewhat not compliant with RFC 3164. As of 3164, - * the TAG field is ended by any non-alphanumeric character. In - * practice, however, the TAG often contains dashes and other things, - * which would end the TAG. So it is not desirable. As such, we only - * accept colon and SP to be terminators. Even there is a slight difference: - * a colon is PART of the TAG, while a SP is NOT part of the tag - * (it is CONTENT). Starting 2008-04-04, we have removed the 32 character - * size limit (from RFC3164) on the tag. This had bad effects on existing - * envrionments, as sysklogd didn't obey it either (probably another bug - * in RFC3164...). We now receive the full size, but will modify the - * outputs so that only 32 characters max are used by default. - */ - i = 0; - while(lenMsg > 0 && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE) { - bufParseTAG[i++] = *p2parse++; - --lenMsg; - } - if(lenMsg > 0 && *p2parse == ':') { - ++p2parse; - --lenMsg; - bufParseTAG[i++] = ':'; - } - - /* no TAG can only be detected if the message immediatly ends, in which case an empty TAG - * is considered OK. So we do not need to check for empty TAG. -- rgerhards, 2009-06-23 - */ - bufParseTAG[i] = '\0'; /* terminate string */ - MsgSetTAG(pMsg, bufParseTAG, i); - } else {/* we enter this code area when the user has instructed rsyslog NOT - * to parse HOSTNAME and TAG - rgerhards, 2006-03-13 - */ - if(!(flags & INTERNAL_MSG)) { - DBGPRINTF("HOSTNAME and TAG not parsed by user configuraton.\n"); - } - } - - /* The rest is the actual MSG */ - MsgSetMSGoffs(pMsg, p2parse - pMsg->pszRawMsg); - - ENDfunc - return 0; /* all ok */ -} - - /* submit a message to the main message queue. This is primarily * a hook to prevent the need for callers to know about the main message queue * rgerhards, 2008-02-13 @@ -1078,65 +705,6 @@ finalize_it: } -/* Log a message to the appropriate log files, users, etc. based on - * the priority. - * rgerhards 2004-11-08: actually, this also decodes all but the PRI part. - * rgerhards 2004-11-09: ... but only, if syslogd could properly be initialized - * if not, we use emergency logging to the console and in - * this case, no further decoding happens. - * changed to no longer receive a plain message but a msg object instead. - * rgerhards-2004-11-16: OK, we are now up to another change... This method - * actually needs to PARSE the message. How exactly this needs to happen depends on - * a number of things. Most importantly, it depends on the source. For example, - * locally received messages (SOURCE_UNIXAF) do NOT have a hostname in them. So - * we need to treat them differntly form network-received messages which have. - * Well, actually not all network-received message really have a hostname. We - * can just hope they do, but we can not be sure. So this method tries to find - * whatever can be found in the message and uses that... Obviously, there is some - * potential for misinterpretation, which we simply can not solve under the - * circumstances given. - */ -static void -logmsg(msg_t *pMsg, int flags) -{ - char *msg; - - BEGINfunc - assert(pMsg != NULL); - assert(pMsg->pszRawMsg != NULL); - - msg = (char*) pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ - DBGPRINTF("logmsg: flags %x, from '%s', msg %s\n", flags, getRcvFrom(pMsg), msg); - - /* rger 2005-11-24 (happy thanksgiving!): we now need to check if we have - * a traditional syslog message or one formatted according to syslog-protocol. - * We need to apply different parsers depending on that. We use the - * -protocol VERSION field for the detection. - */ - if(msg[0] == '1' && msg[1] == ' ') { - DBGPRINTF("Message has syslog-protocol format.\n"); - setProtocolVersion(pMsg, 1); - if(parseRFCSyslogMsg(pMsg, flags) == 1) { - msgDestruct(&pMsg); - return; - } - } else { /* we have legacy syslog */ - DBGPRINTF("Message has legacy syslog format.\n"); - setProtocolVersion(pMsg, 0); - if(parseLegacySyslogMsg(pMsg, flags) == 1) { - msgDestruct(&pMsg); - return; - } - } - - /* ---------------------- END PARSING ---------------- */ - - /* now submit the message to the main queue - then we are done */ - pMsg->msgFlags = flags; - MsgPrepareEnqueue(pMsg); - qqueueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg); - ENDfunc -} static void @@ -2213,11 +1781,10 @@ void sigttin_handler() static void processImInternal(void) { int iPri; - int iFlags; msg_t *pMsg; - while(iminternalRemoveMsg(&iPri, &pMsg, &iFlags) == RS_RET_OK) { - logmsg(pMsg, iFlags); + while(iminternalRemoveMsg(&iPri, &pMsg) == RS_RET_OK) { + submitMsg(pMsg); } } -- cgit v1.2.3 From 6f511cecfae3592f271627ebcb41e6a8c4f831e9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 3 Nov 2009 12:39:48 +0100 Subject: more cleanup and working towards a parser module calling interface I cleaned up a lot of config variable access along the way. This version compiles and runs, but does not yet offer any enhanced functionality. pmrfc5424 is just a dummy that is not yet being used. --- tools/syslogd.c | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 998d6512..c1277d3e 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -144,7 +144,7 @@ /* definitions for objects we access */ DEFobjCurrIf(obj) DEFobjCurrIf(glbl) -DEFobjCurrIf(datetime) +DEFobjCurrIf(datetime) /* TODO: make go away! */ DEFobjCurrIf(conf) DEFobjCurrIf(expr) DEFobjCurrIf(module) @@ -152,6 +152,7 @@ DEFobjCurrIf(errmsg) DEFobjCurrIf(rule) DEFobjCurrIf(ruleset) DEFobjCurrIf(prop) +DEFobjCurrIf(parser) DEFobjCurrIf(net) /* TODO: make go away! */ @@ -206,8 +207,6 @@ static pid_t myPid; /* our pid for use in self-generated messages, e.g. on start /* mypid is read-only after the initial fork() */ static int bHadHUP = 0; /* did we have a HUP? */ -int bParseHOSTNAMEandTAG = 1; /* global config var: should the hostname and tag be - * parsed inside message - rgerhards, 2006-03-13 */ static int bFinished = 0; /* used by termination signal handler, read-only except there * is either 0 or the number of the signal that requested the * termination. @@ -232,7 +231,6 @@ typedef struct legacyOptsLL_s { legacyOptsLL_t *pLegacyOptsLL = NULL; /* global variables for config file state */ -int bDropTrailingLF = 1; /* drop trailing LF's on reception? */ int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is the default, so if no -c option is given, we make ourselvs as compatible to sysklogd as possible. */ @@ -241,8 +239,6 @@ static int bLogStatusMsgs = DFLT_bLogStatusMsgs; /* log rsyslog start/stop/HUP m static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */ static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */ static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ -uchar cCCEscapeChar = '#';/* character to be used to start an escape sequence for control chars */ -int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */ static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bAbortOnUncleanConfig = 0; /* abort run (rather than starting with partial config) if there was any issue in conf */ @@ -322,14 +318,12 @@ getFIOPName(unsigned iFIOP) */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { - cCCEscapeChar = '#'; bLogStatusMsgs = DFLT_bLogStatusMsgs; bActExecWhenPrevSusp = 0; iActExecOnceInterval = 0; bDebugPrintTemplateList = 1; bDebugPrintCfSysLineHandlerList = 1; bDebugPrintModuleList = 1; - bEscapeCCOnRcv = 1; /* default is to escape control characters */ bReduceRepeatMsgs = 0; bAbortOnUncleanConfig = 0; free(pszMainMsgQFName); @@ -641,7 +635,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu pMsg = (msg_t*) pBatch->pElem[i].pUsrp; DBGPRINTF("msgConsumer processes msg %d/%d\n", i, pBatch->nElem); if((pMsg->msgFlags & NEEDS_PARSING) != 0) { - parseMsg(pMsg); + parser.ParseMsg(pMsg); } ruleset.ProcessMsg(pMsg); /* if we reach this point, the message is considered committed (by definition!) */ @@ -1372,13 +1366,6 @@ static void dbgPrintInitInfo(void) DBGPRINTF("Messages with malicious PTR DNS Records are %sdropped.\n", glbl.GetDropMalPTRMsgs() ? "" : "not "); - DBGPRINTF("Control characters are %sreplaced upon reception.\n", - bEscapeCCOnRcv? "" : "not "); - - if(bEscapeCCOnRcv) - DBGPRINTF("Control character escape sequence prefix is '%c'.\n", - cCCEscapeChar); - DBGPRINTF("Main queue size %d messages.\n", iMainMsgQueueSize); DBGPRINTF("Main queue worker threads: %d, wThread shutdown: %d, Perists every %d updates.\n", iMainMsgQueueNumWorkers, iMainMsgQtoWrkShutdown, iMainMsgQPersistUpdCnt); @@ -1964,9 +1951,6 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlyonceeveryinterval", 0, eCmdHdlrInt, NULL, &iActExecOnceInterval, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_ALLOWEDSENDER, NULL)); @@ -2161,14 +2145,14 @@ InitGlobalClasses(void) CHKiRet(objUse(conf, CORE_COMPONENT)); pErrObj = "prop"; CHKiRet(objUse(prop, CORE_COMPONENT)); + pErrObj = "parser"; + CHKiRet(objUse(parser, CORE_COMPONENT)); /* intialize some dummy classes that are not part of the runtime */ pErrObj = "action"; CHKiRet(actionClassInit()); pErrObj = "template"; CHKiRet(templateInit()); - pErrObj = "parser"; - CHKiRet(parserClassInit()); /* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ pErrObj = "net"; @@ -2705,7 +2689,7 @@ int realMain(int argc, char **argv) case 'u': /* misc user settings */ iHelperUOpt = atoi(arg); if(iHelperUOpt & 0x01) - bParseHOSTNAMEandTAG = 0; + glbl.SetParseHOSTNAMEandTAG(0); if(iHelperUOpt & 0x02) bChDirRoot = 0; break; -- cgit v1.2.3 From b1db196953713dd09c499a3edf81347bd903c19e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 3 Nov 2009 18:44:02 +0100 Subject: one step closer to dynamically loadable parsers This is a milestone commit, which adds new code that breaks nothing, but also does not add any visible change. Just prep work... --- tools/syslogd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index c1277d3e..3fb54467 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -125,6 +125,7 @@ #include "omfwd.h" #include "omfile.h" #include "omdiscard.h" +#include "pmrfc5424.h" #include "threads.h" #include "wti.h" #include "queue.h" @@ -1913,6 +1914,9 @@ static rsRetVal loadBuildInModules(void) */ CHKiRet(module.doModInit(modInitUsrMsg, (uchar*) "builtin-usrmsg", NULL)); + /* load build-in parser modules */ + CHKiRet(module.doModInit(modInitpmrfc5424, UCHAR_CONSTANT("builtin-pmrfc5424"), NULL)); + /* ok, initialization of the command handler probably does not 100% belong right in * this space here. However, with the current design, this is actually quite a good * place to put it. We might decide to shuffle it around later, but for the time -- cgit v1.2.3 From b41e0d51f54a89f489bbf1c1bf5f85d576ae4049 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 3 Nov 2009 18:48:40 +0100 Subject: some more cleanup along the way ... getting the module structure a bit cleaner ;) --- tools/syslogd.c | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3fb54467..aeab292c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -286,34 +286,6 @@ static int iMainMsgQueueDeqtWinFromHr = 0; /* hour begin of time frame when qu static int iMainMsgQueueDeqtWinToHr = 25; /* hour begin of time frame when queue is to be dequeued */ -/* support for simple textual representation of FIOP names - * rgerhards, 2005-09-27 - */ -char* -getFIOPName(unsigned iFIOP) -{ - char *pRet; - switch(iFIOP) { - case FIOP_CONTAINS: - pRet = "contains"; - break; - case FIOP_ISEQUAL: - pRet = "isequal"; - break; - case FIOP_STARTSWITH: - pRet = "startswith"; - break; - case FIOP_REGEX: - pRet = "regex"; - break; - default: - pRet = "NOP"; - break; - } - return pRet; -} - - /* Reset config variables to default values. * rgerhards, 2007-07-17 */ @@ -382,7 +354,7 @@ static int usage(void) fprintf(stderr, "usage: rsyslogd [-c] [-46AdnqQvwx] [-l] [-s]\n" " [-f] [-i] [-N] [-M]\n" " [-u]\n" - "To run rsyslogd in native mode, use \"rsyslogd -c3 \"\n\n" + "To run rsyslogd in native mode, use \"rsyslogd -c5 \"\n\n" "For further information see http://www.rsyslog.com/doc\n"); exit(1); /* "good" exit - done to terminate usage() */ } -- cgit v1.2.3 From 1b7f5c54684db29c096e09238648a45dce78ebee Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 4 Nov 2009 10:40:27 +0100 Subject: moved rfc3164/5424 code to new parser modules another milestone commit: the program works, the new interface is used, some more cleanup is needed and the per-ruleset config options are still missing. But we are getting closer... --- tools/syslogd.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index aeab292c..5b7f1e65 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -33,7 +33,7 @@ * to the database). * * rsyslog - An Enhanced syslogd Replacement. - * Copyright 2003-2008 Rainer Gerhards and Adiscon GmbH. + * Copyright 2003-2009 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * @@ -126,6 +126,7 @@ #include "omfile.h" #include "omdiscard.h" #include "pmrfc5424.h" +#include "pmrfc3164.h" #include "threads.h" #include "wti.h" #include "queue.h" @@ -346,7 +347,6 @@ static char **crunch_list(char *list); static void reapchild(); static void debug_switch(); static void sighup_handler(); -static void processImInternal(void); static int usage(void) @@ -600,6 +600,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu { int i; msg_t *pMsg; + rsRetVal localRet; DEFiRet; assert(pBatch != NULL); @@ -608,9 +609,12 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu pMsg = (msg_t*) pBatch->pElem[i].pUsrp; DBGPRINTF("msgConsumer processes msg %d/%d\n", i, pBatch->nElem); if((pMsg->msgFlags & NEEDS_PARSING) != 0) { - parser.ParseMsg(pMsg); + localRet = parser.ParseMsg(pMsg); + if(localRet == RS_RET_OK) + ruleset.ProcessMsg(pMsg); + } else { + ruleset.ProcessMsg(pMsg); } - ruleset.ProcessMsg(pMsg); /* if we reach this point, the message is considered committed (by definition!) */ pBatch->pElem[i].state = BATCH_STATE_COMM; } @@ -1738,7 +1742,7 @@ void sigttin_handler() * really help us. TODO: add error messages? * rgerhards, 2007-08-03 */ -static void processImInternal(void) +static inline void processImInternal(void) { int iPri; msg_t *pMsg; @@ -1888,6 +1892,11 @@ static rsRetVal loadBuildInModules(void) /* load build-in parser modules */ CHKiRet(module.doModInit(modInitpmrfc5424, UCHAR_CONSTANT("builtin-pmrfc5424"), NULL)); + CHKiRet(module.doModInit(modInitpmrfc3164, UCHAR_CONSTANT("builtin-pmrfc3164"), NULL)); + + /* and set default parser modules (order is *very* important, legacy (3164) parse needs to go last! */ + CHKiRet(parser.AddDfltParser(UCHAR_CONSTANT("rsyslog.rfc5424"))); + CHKiRet(parser.AddDfltParser(UCHAR_CONSTANT("rsyslog.rfc3164"))); /* 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 -- cgit v1.2.3 From aa2e8ea15b2001f131ebd196c180cc82aceb57b4 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 4 Nov 2009 15:34:31 +0100 Subject: first complete implementation of loadable parser system I have now done the necessary cleanup. Looks like everything is in place. Unfortunately, I do not yet have any actual parser that is not built-in, but I think we can postpone working on that when the first one appears. I don't expect troubles in that case, but you never know ;) --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5b7f1e65..eef3bb82 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2176,6 +2176,7 @@ GlobalClassExit(void) objRelease(rule, CORE_COMPONENT); objRelease(expr, CORE_COMPONENT); vmClassExit(); /* this is hack, currently core_modules do not get this automatically called */ + parserClassExit(); /* this is hack, currently core_modules do not get this automatically called */ objRelease(datetime, CORE_COMPONENT); /* TODO: implement the rest of the deinit */ -- cgit v1.2.3 From 2b5e15d549940c7ace9017eaf40d523e3741c9a2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 10 Nov 2009 12:50:48 +0100 Subject: added a so-called "On Demand Debug" mode in which debug output can be generated only after the process has started, but not right from the beginning. This is assumed to be useful for hard-to-find bugs. Also improved the doc on the debug system. --- tools/syslogd.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index fb3294d5..7649d054 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1469,13 +1469,27 @@ doFlushRptdMsgs(void) static void debug_switch() { + time_t tTime; + struct tm tp; struct sigaction sigAct; + time(&tTime); + localtime_r(&tTime, &tp); if(debugging_on == 0) { debugging_on = 1; - DBGPRINTF("Switching debugging_on to true\n"); + dbgprintf("\n"); + dbgprintf("\n"); + dbgprintf("********************************************************************************\n"); + dbgprintf("Switching debugging_on to true at %2.2d:%2.2d:%2.2d\n", + tp.tm_hour, tp.tm_min, tp.tm_sec); + dbgprintf("********************************************************************************\n"); } else { - DBGPRINTF("Switching debugging_on to false\n"); + dbgprintf("********************************************************************************\n"); + dbgprintf("Switching debugging_on to false at %2.2d:%2.2d:%2.2d\n", + tp.tm_hour, tp.tm_min, tp.tm_sec); + dbgprintf("********************************************************************************\n"); + dbgprintf("\n"); + dbgprintf("\n"); debugging_on = 0; } @@ -3082,8 +3096,6 @@ doGlblProcessInit(void) fputs(" Already running.\n", stderr); exit(1); /* "good" exit, done if syslogd is already running */ } - } else { - debugging_on = 1; } /* tuck my process id away */ -- cgit v1.2.3 From 2dafb35077f013a22f0ce9d59306d8f59d709a51 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 12 Nov 2009 12:03:27 +0100 Subject: some module cleanup --- tools/syslogd.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index eeeb4aeb..df04609c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -245,7 +245,6 @@ static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition t int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bAbortOnUncleanConfig = 0; /* abort run (rather than starting with partial config) if there was any issue in conf */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ -int iActExecOnceInterval = 0; /* execute action once every nn seconds */ /* end global config file state variables */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ @@ -294,7 +293,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a { bLogStatusMsgs = DFLT_bLogStatusMsgs; bActExecWhenPrevSusp = 0; - iActExecOnceInterval = 0; bDebugPrintTemplateList = 1; bDebugPrintCfSysLineHandlerList = 1; bDebugPrintModuleList = 1; @@ -1948,7 +1946,6 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"abortonuncleanconfig", 0, eCmdHdlrBinary, NULL, &bAbortOnUncleanConfig, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlyonceeveryinterval", 0, eCmdHdlrInt, NULL, &iActExecOnceInterval, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL)); -- cgit v1.2.3 From e4542eb926c9fd757dc8f40f4fe6cb843b8b2650 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 12 Nov 2009 14:07:12 +0100 Subject: bugfix: segfault on startup when -q or -Q option was given bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=157 Thanks to Jonas Nogueira for reporting this bug. --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 6f32b262..9dbea061 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3422,10 +3422,10 @@ int realMain(int argc, char **argv) fprintf(stderr, "error -p is no longer supported, use module imuxsock instead"); } case 'q': /* add hostname if DNS resolving has failed */ - *net.pACLAddHostnameOnFail = 1; + net.pACLAddHostnameOnFail = 1; break; case 'Q': /* dont resolve hostnames in ACL to IPs */ - *net.pACLDontResolve = 1; + net.pACLDontResolve = 1; break; case 'r': /* accept remote messages */ if(iCompatibilityMode < 3) { -- cgit v1.2.3 From f6dfcc7c3d326c54e1d5e301e1a2c032e4131e02 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 12 Nov 2009 14:21:53 +0100 Subject: correcting -q/-Q patch - was invalid This is the correct patch. The previous one solved the segfault, but disabled the -q/Q options. --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 9dbea061..75d5ff82 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3422,10 +3422,10 @@ int realMain(int argc, char **argv) fprintf(stderr, "error -p is no longer supported, use module imuxsock instead"); } case 'q': /* add hostname if DNS resolving has failed */ - net.pACLAddHostnameOnFail = 1; + *(net.pACLAddHostnameOnFail) = 1; break; case 'Q': /* dont resolve hostnames in ACL to IPs */ - net.pACLDontResolve = 1; + *(net.pACLDontResolve) = 1; break; case 'r': /* accept remote messages */ if(iCompatibilityMode < 3) { -- cgit v1.2.3 From 8b246de2a587454f9260ff91192d27a2e168ea2d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 12 Nov 2009 17:12:10 +0100 Subject: some light performance enhancement ...by replacing time() call with much faster (at least under linux) gettimeofday() calls. --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a8cba185..820cf273 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -706,7 +706,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) * the beginn of the llExec(). This makes it slightly less correct, but * in an acceptable way. -- rgerhards, 2008-09-16 */ - if (pAction->f_prevcount && time(NULL) >= REPEATTIME(pAction)) { + if (pAction->f_prevcount && datetime.GetTime(NULL) >= REPEATTIME(pAction)) { DBGPRINTF("flush %s: repeated %d times, %d sec.\n", module.GetStateName(pAction->pMod), pAction->f_prevcount, repeatinterval[pAction->f_repeatcount]); @@ -735,7 +735,7 @@ static void debug_switch() struct tm tp; struct sigaction sigAct; - time(&tTime); + datetime.GetTime(&tTime); localtime_r(&tTime, &tp); if(debugging_on == 0) { debugging_on = 1; -- cgit v1.2.3 From 8c29f2843591376f8a1abca5f09a9740927f1000 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 17 Nov 2009 08:11:31 +0100 Subject: moved DNS resolution code out of imudp and into the backend processing Most importantly, DNS resolution now never happens if the resolved name is not required. Note that this applies to imudp - for the other inputs, DNS resolution almost comes for free, so we do not do it there. However, the new method has been implemented in a generic way and as such may also be used by other modules in the future. --- tools/syslogd.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 11 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 820cf273..3fc3da0d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -586,6 +586,82 @@ finalize_it: RETiRet; } +/* check message against ACL set + * rgerhards, 2009-11-16 + */ +#if 0 +static inline rsRetVal +chkMsgAgainstACL() { + /* if we reach this point, we had a good receive and can process the packet received */ + /* check if we have a different sender than before, if so, we need to query some new values */ + if(net.CmpHost(&frominet, frominetPrev, socklen) != 0) { + CHKiRet(net.cvthname(&frominet, fromHost, fromHostFQDN, fromHostIP)); + memcpy(frominetPrev, &frominet, socklen); /* update cache indicator */ + /* Here we check if a host is permitted to send us + * syslog messages. If it isn't, we do not further + * process the message but log a warning (if we are + * configured to do this). + * rgerhards, 2005-09-26 + */ + *pbIsPermitted = net.isAllowedSender((uchar*)"UDP", + (struct sockaddr *)&frominet, (char*)fromHostFQDN); + + if(!*pbIsPermitted) { + DBGPRINTF("%s is not an allowed sender\n", (char*)fromHostFQDN); + if(glbl.GetOption_DisallowWarning) { + time_t tt; + + datetime.GetTime(&tt); + if(tt > ttLastDiscard + 60) { + ttLastDiscard = tt; + errmsg.LogError(0, NO_ERRCODE, + "UDP message from disallowed sender %s discarded", + (char*)fromHost); + } + } + } + } +} +#endif + + +/* consumes a single messages - this function is primarily used to shuffle + * out some code from msgConsumer(). After this function, the message is + * (by definition!) considered committed. + * rgerhards, 2009-11-16 + */ +static inline rsRetVal +msgConsumeOne(msg_t *pMsg, prop_t **propFromHost, prop_t **propFromHostIP) { + uchar fromHost[NI_MAXHOST]; + uchar fromHostIP[NI_MAXHOST]; + uchar fromHostFQDN[NI_MAXHOST]; + int bIsPermitted; + DEFiRet; + + if((pMsg->msgFlags & NEEDS_ACLCHK_U) != 0) { + dbgprintf("msgConsumer: UDP ACL must be checked for message (hostname-based)\n"); + CHKiRet(net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, fromHostIP)); + bIsPermitted = net.isAllowedSender2((uchar*)"UDP", + (struct sockaddr *)pMsg->rcvFrom.pfrominet, (char*)fromHostFQDN, 1); + if(!bIsPermitted) { + DBGPRINTF("Message from '%s' discarded, not a permitted sender host\n", + fromHostFQDN); + ABORT_FINALIZE(RS_RET_ERR); + /* save some of the info we obtained */ + MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), propFromHost); + CHKiRet(MsgSetRcvFromIPStr(pMsg, fromHostIP, ustrlen(fromHostIP), propFromHostIP)); + pMsg->msgFlags &= ~NEEDS_ACLCHK_U; + } + } + + if((pMsg->msgFlags & NEEDS_PARSING) != 0) + CHKiRet(parser.ParseMsg(pMsg)); + + ruleset.ProcessMsg(pMsg); +finalize_it: + RETiRet; +} + /* The consumer of dequeued messages. This function is called by the * queue engine on dequeueing of a message. It runs on a SEPARATE @@ -597,26 +673,22 @@ static rsRetVal msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShutdownImmediate) { int i; - msg_t *pMsg; - rsRetVal localRet; + prop_t *propFromHost = NULL; + prop_t *propFromHostIP = NULL; DEFiRet; assert(pBatch != NULL); for(i = 0 ; i < pBatch->nElem && !*pbShutdownImmediate ; i++) { - pMsg = (msg_t*) pBatch->pElem[i].pUsrp; DBGPRINTF("msgConsumer processes msg %d/%d\n", i, pBatch->nElem); - if((pMsg->msgFlags & NEEDS_PARSING) != 0) { - localRet = parser.ParseMsg(pMsg); - if(localRet == RS_RET_OK) - ruleset.ProcessMsg(pMsg); - } else { - ruleset.ProcessMsg(pMsg); - } - /* if we reach this point, the message is considered committed (by definition!) */ + msgConsumeOne((msg_t*) pBatch->pElem[i].pUsrp, &propFromHost, &propFromHostIP); pBatch->pElem[i].state = BATCH_STATE_COMM; } + if(propFromHost != NULL) + prop.Destruct(&propFromHost); + if(propFromHostIP != NULL) + prop.Destruct(&propFromHostIP); RETiRet; } -- cgit v1.2.3 From 30c2e42ec305bb97bd04172e5c02b89eeea53e35 Mon Sep 17 00:00:00 2001 From: varmojfekoj Date: Tue, 17 Nov 2009 09:00:01 +0100 Subject: added option to use unlimited-size select() calls Thanks to varmjofekoj for the patch Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5f6b480f..687f2217 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2150,6 +2150,9 @@ static rsRetVal setMaxFiles(void __attribute__((unused)) *pVal, int iFiles) iFiles, errStr, (long) maxFiles.rlim_max); ABORT_FINALIZE(RS_RET_ERR_RLIM_NOFILE); } +#ifdef USE_UNLIMITED_SELECT + glbl.SetFdSetSize(howmany(iFiles, __NFDBITS) * sizeof (fd_mask)); +#endif DBGPRINTF("Max number of files set to %d [kernel max %ld].\n", iFiles, (long) maxFiles.rlim_max); finalize_it: -- cgit v1.2.3 From 5b55ab75e27861241981ae447ed3d1b8ad968deb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 20 Nov 2009 18:41:04 +0100 Subject: debugondemand mode caused backgrounding to fail This is close to a bug, but I'd consider the ability to background in this mode a new feature... --- tools/syslogd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e03bf4d8..f11808f3 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -904,7 +904,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) * permits us to process unmodified config files which otherwise contain a * supressor statement. */ - if(((Debug || NoFork) && bErrMsgToStderr) || iConfigVerify) { + if(((Debug == DEBUG_FULL || NoFork) && bErrMsgToStderr) || iConfigVerify) { if(LOG_PRI(pri) == LOG_ERR) fprintf(stderr, "rsyslogd: %s\n", msg); } @@ -1644,10 +1644,10 @@ static void doDie(int sig) # define MSG1 "DoDie called.\n" # define MSG2 "DoDie called 5 times - unconditional exit\n" static int iRetries = 0; /* debug aid */ - if(Debug) + if(Debug == DEBUG_FULL) write(1, MSG1, sizeof(MSG1) - 1); if(iRetries++ == 4) { - if(Debug) + if(Debug == DEBUG_FULL) write(1, MSG2, sizeof(MSG2) - 1); abort(); } @@ -2881,7 +2881,7 @@ static rsRetVal mainThread() * is still in its infancy (and not really done), we currently accept this issue. * rgerhards, 2009-06-29 */ - if(!(Debug || NoFork)) { + if(!(Debug == DEBUG_FULL || NoFork)) { close(1); close(2); bErrMsgToStderr = 0; @@ -3072,7 +3072,7 @@ doGlblProcessInit(void) thrdInit(); - if( !(Debug || NoFork) ) + if( !(Debug == DEBUG_FULL || NoFork) ) { DBGPRINTF("Checking pidfile.\n"); if (!check_pid(PidFile)) -- cgit v1.2.3 From 549ed00c4aeb5c4d73e91f2b64c619b562ddcbf2 Mon Sep 17 00:00:00 2001 From: Jonathan Bond-Caron Date: Fri, 27 Nov 2009 10:30:47 +0100 Subject: added $EscapeControlCharacterTab config directive --- tools/syslogd.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f11808f3..2806921c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -254,8 +254,9 @@ static int bLogStatusMsgs = DFLT_bLogStatusMsgs; /* log rsyslog start/stop/HUP m static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */ static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */ static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ -uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence for control chars */ +uchar cCCEscapeChar = '#';/* character to be used to start an escape sequence for control chars */ int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */ +int bEscapeTab = 1; /* treat tab as escape control character: 0 - no, 1 - yes */ static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ @@ -341,6 +342,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a bDebugPrintCfSysLineHandlerList = 1; bDebugPrintModuleList = 1; bEscapeCCOnRcv = 1; /* default is to escape control characters */ + bEscapeTab = 1; bReduceRepeatMsgs = 0; free(pszMainMsgQFName); pszMainMsgQFName = NULL; @@ -807,7 +809,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla /* log an error? Very questionable... rgerhards, 2006-11-30 */ /* decided: we do not log an error, it won't help... rger, 2007-06-21 */ ++pData; - } else if(bEscapeCCOnRcv && iscntrl((int) *pData)) { + } else if(bEscapeCCOnRcv && iscntrl((int) *pData) && (*pData != '\t' || bEscapeTab)) { /* we are configured to escape control characters. Please note * that this most probably break non-western character sets like * Japanese, Korean or Chinese. rgerhards, 2007-07-17 @@ -1197,8 +1199,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); lenMsg = pMsg->iLenRawMsg - (pMsg->offAfterPRI + 1); -RUNLOG_VAR("%d", pMsg->offAfterPRI); -RUNLOG_VAR("%d", lenMsg); + p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ /* Check to see if msg contains a timestamp. We start by assuming @@ -2724,6 +2725,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactertab", 0, eCmdHdlrBinary, NULL, &bEscapeTab, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL)); -- cgit v1.2.3 From 8021912232ed1cc14b9175e7efaa7d8961940c3e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 4 Dec 2009 13:11:50 +0100 Subject: bugfix: potential segfault when -p command line option was used thanks to varmojfekoj for pointing me at this bug --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 75d5ff82..10283568 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3421,6 +3421,7 @@ int realMain(int argc, char **argv) } else { fprintf(stderr, "error -p is no longer supported, use module imuxsock instead"); } + break; case 'q': /* add hostname if DNS resolving has failed */ *(net.pACLAddHostnameOnFail) = 1; break; -- cgit v1.2.3 From bd03b86c6322c82fc9f667122f4365e339f28ccc Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 Jan 2010 15:49:26 +0100 Subject: bugfix: -d did not enable display of debug messages regression from introduction of "debug on demand" mode Thanks to Michael Biebl for reporting this bug --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3dd51adf..ab8f015d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3203,6 +3203,7 @@ int realMain(int argc, char **argv) iCompatibilityMode = atoi(optarg); break; case 'd': /* debug - must be handled now, so that debug is active during init! */ + debugging_on = 1; Debug = 1; break; case 'e': /* log every message (no repeat message supression) */ -- cgit v1.2.3 From eac8ef081b6058e6d21943683d19519709fab55c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 26 Jan 2010 15:23:57 +0100 Subject: fixed small misalignment --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 967401d2..e9e7f08c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -280,7 +280,7 @@ static int iMainMsgQtoWrkShutdown = 60000; /* timeout for worker thread shutdo static int iMainMsgQWrkMinMsgs = 100; /* minimum messages per worker needed to start a new one */ static int iMainMsgQDeqSlowdown = 0; /* dequeue slowdown (simple rate limiting) */ static int64 iMainMsgQueMaxDiskSpace = 0; /* max disk space allocated 0 ==> unlimited */ -static int iMainMsgQueDeqBatchSize = 32; /* dequeue batch size */ +static int64 iMainMsgQueDeqBatchSize = 32; /* dequeue batch size */ static int bMainMsgQSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */ static int iMainMsgQueueDeqtWinFromHr = 0; /* hour begin of time frame when queue is to be dequeued */ static int iMainMsgQueueDeqtWinToHr = 25; /* hour begin of time frame when queue is to be dequeued */ -- cgit v1.2.3 From 074ec9495e9f07f7ff441a60f756b0d15931a8d7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 27 Jan 2010 09:52:15 +0100 Subject: backporting bugfixes from 5.2.2 - bugfix: queues in direct mode could case a segfault, especially if an action failed for action queues. The issue was an invalid increment of a stack-based pointer which lead to destruction of the stack frame and thus a segfault on function return. Thanks to Michael Biebl for alerting us on this problem. [backport from 5.5.2] - bugfix: wrong memory assignment for a config variable (probably without causing any harm) [backport from 5.2.2] --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 21df6d6c..0f7325fc 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -280,7 +280,7 @@ static int iMainMsgQtoWrkShutdown = 60000; /* timeout for worker thread shutdo static int iMainMsgQWrkMinMsgs = 100; /* minimum messages per worker needed to start a new one */ static int iMainMsgQDeqSlowdown = 0; /* dequeue slowdown (simple rate limiting) */ static int64 iMainMsgQueMaxDiskSpace = 0; /* max disk space allocated 0 ==> unlimited */ -static int iMainMsgQueDeqBatchSize = 32; /* dequeue batch size */ +static int64 iMainMsgQueDeqBatchSize = 32; /* dequeue batch size */ static int bMainMsgQSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */ static int iMainMsgQueueDeqtWinFromHr = 0; /* hour begin of time frame when queue is to be dequeued */ static int iMainMsgQueueDeqtWinToHr = 25; /* hour begin of time frame when queue is to be dequeued */ -- cgit v1.2.3 From 66d129c9ca24f6f3001fad9cc854c54a360df49e Mon Sep 17 00:00:00 2001 From: Cristiano Date: Wed, 3 Feb 2010 15:42:14 +0100 Subject: (slightly) enhanced support for FreeBSD by setting _PATH_MODDIR to the correct value on FreeBSD. Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ab8f015d..db1e9428 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -177,7 +177,11 @@ static rsRetVal GlobalClassExit(void); #endif #ifndef _PATH_MODDIR -#define _PATH_MODDIR "/lib/rsyslog/" +# if defined(__FreeBSD__) +# define _PATH_MODDIR "/usr/local/lib/rsyslog/" +# else +# define _PATH_MODDIR "/lib/rsyslog/" +# endif #endif #if defined(SYSLOGD_PIDNAME) -- cgit v1.2.3 From c577e9c64cec0eebf6b7c3bd964354ab90c045ae Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 22 Feb 2010 09:31:10 +0100 Subject: bugfix: message without MSG part could case a segfault [backported from v5 commit 98d1ed504ec001728955a5bcd7916f64cd85f39f] This actually was a "recent" regression, but I did not realize that it was introduced by the performance optimization in v4-devel. Shame on me for having two devel versions at the same time... --- tools/syslogd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index db1e9428..3e6d51d3 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1198,8 +1198,6 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); lenMsg = pMsg->iLenRawMsg - (pMsg->offAfterPRI + 1); -RUNLOG_VAR("%d", pMsg->offAfterPRI); -RUNLOG_VAR("%d", lenMsg); p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ /* Check to see if msg contains a timestamp. We start by assuming @@ -1255,16 +1253,16 @@ RUNLOG_VAR("%d", lenMsg); bTAGCharDetected = 0; if(lenMsg > 0 && flags & PARSE_HOSTNAME) { i = 0; - while(lenMsg > 0 && (isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.' + while(i < lenMsg && (isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.' || p2parse[i] == '_' || p2parse[i] == '-') && i < CONF_TAG_MAXSIZE) { bufParseHOSTNAME[i] = p2parse[i]; ++i; - --lenMsg; } if(i > 0 && p2parse[i] == ' ' && isalnum(p2parse[i-1])) { /* we got a hostname! */ p2parse += i + 1; /* "eat" it (including SP delimiter) */ + lenMsg -= i + 1; bufParseHOSTNAME[i] = '\0'; MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i); } -- cgit v1.2.3 From af5fb078d48b364b20adf7e56e9869664e7424f9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 22 Feb 2010 14:25:56 +0100 Subject: message parser fixes and testbench enhancements - improved testbench to contain samples for totally malformed messages which miss parts of the message content - bugfix: some malformed messages could lead to a missing LF inside files or some other missing parts of the template content. - bugfix: if a message ended immediately with a hostname, the hostname was mistakenly interpreted as TAG, and localhost be used as hostname --- tools/syslogd.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3e6d51d3..caab1691 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1192,12 +1192,12 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) int bTAGCharDetected; int i; /* general index for parsing */ uchar bufParseTAG[CONF_TAG_MAXSIZE]; - uchar bufParseHOSTNAME[CONF_TAG_HOSTNAME]; + uchar bufParseHOSTNAME[CONF_HOSTNAME_MAXSIZE]; BEGINfunc assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); - lenMsg = pMsg->iLenRawMsg - (pMsg->offAfterPRI + 1); + lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; /* note: offAfterPRI is already the number of PRI chars (do not add one!) */ p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ /* Check to see if msg contains a timestamp. We start by assuming @@ -1254,12 +1254,20 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) if(lenMsg > 0 && flags & PARSE_HOSTNAME) { i = 0; while(i < lenMsg && (isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.' - || p2parse[i] == '_' || p2parse[i] == '-') && i < CONF_TAG_MAXSIZE) { + || p2parse[i] == '_' || p2parse[i] == '-') && i < (CONF_HOSTNAME_MAXSIZE - 1)) { bufParseHOSTNAME[i] = p2parse[i]; ++i; } - if(i > 0 && p2parse[i] == ' ' && isalnum(p2parse[i-1])) { + if(i == lenMsg) { + /* we have a message that is empty immediately after the hostname, + * but the hostname thus is valid! -- rgerhards, 2010-02-22 + */ + p2parse += i; + lenMsg -= i; + bufParseHOSTNAME[i] = '\0'; + MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i); + } else if(i > 0 && p2parse[i] == ' ' && isalnum(p2parse[i-1])) { /* we got a hostname! */ p2parse += i + 1; /* "eat" it (including SP delimiter) */ lenMsg -= i + 1; -- cgit v1.2.3 From 50636ba267bb1930bce7c3baecdab8a245d52b05 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sun, 28 Feb 2010 17:18:04 +0100 Subject: moved pipe code to its own module ... based on old omfile. Michael Biebl reported that xconsole seems to have some issues with the new pipe code, so it was best to use the old code for pipes. The optimizations were done to speed up file access, so it doesn't really matter pipes do not receive them. --- tools/syslogd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index caab1691..ba1dbb18 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -127,6 +127,7 @@ #include "omusrmsg.h" #include "omfwd.h" #include "omfile.h" +#include "ompipe.h" #include "omdiscard.h" #include "threads.h" #include "queue.h" @@ -2663,6 +2664,9 @@ static rsRetVal loadBuildInModules(void) if((iRet = module.doModInit(modInitFile, UCHAR_CONSTANT("builtin-file"), NULL)) != RS_RET_OK) { RETiRet; } + if((iRet = module.doModInit(modInitPipe, UCHAR_CONSTANT("builtin-pipe"), NULL)) != RS_RET_OK) { + RETiRet; + } #ifdef SYSLOG_INET if((iRet = module.doModInit(modInitFwd, UCHAR_CONSTANT("builtin-fwd"), NULL)) != RS_RET_OK) { RETiRet; -- cgit v1.2.3 From 71ffb32ab8a1847f746a298ad20f7dd8b40570a0 Mon Sep 17 00:00:00 2001 From: Yann Droneaud Date: Wed, 3 Mar 2010 18:59:22 +0100 Subject: Fix Large File Support (LFS) support (bug #182) - _FILE_OFFSET_BITS must be defined before including any other system headers otherwise it does nothing. - Don't define it in rsyslog.h, let it be defined in config.h, and let ./configure script enable LFS since Autoconf provides a portable macro to enable LFS support : AC_SYS_LARGEFILE --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ba1dbb18..64b23566 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2770,7 +2770,7 @@ static void printVersion(void) #else printf("\tFEATURE_REGEXP:\t\t\t\tNo\n"); #endif -#ifndef NOLARGEFILE +#if defined(_LARGE_FILES) || (defined (_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS >= 64) printf("\tFEATURE_LARGEFILE:\t\t\tYes\n"); #else printf("\tFEATURE_LARGEFILE:\t\t\tNo\n"); -- cgit v1.2.3 From e0afe5c8258d4b70ade84f1176c44ae6d593f2df Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 23 Mar 2010 08:03:21 +0100 Subject: added some diagnostics info to startup --- tools/syslogd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 64b23566..a61d1e5d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3174,6 +3174,7 @@ int realMain(int argc, char **argv) uchar *LocalHostName; uchar *LocalDomain; uchar *LocalFQDNName; + char cwdbuf[128]; /* buffer to obtain/display current working directory */ /* first, parse the command line options. We do not carry out any actual work, just * see what we should do. This relieves us from certain anomalies and we can process @@ -3260,8 +3261,9 @@ int realMain(int argc, char **argv) if ((argc -= optind)) usage(); - DBGPRINTF("rsyslogd %s startup, compatibility mode %d, module path '%s'\n", - VERSION, iCompatibilityMode, glblModPath == NULL ? "" : (char*)glblModPath); + DBGPRINTF("rsyslogd %s startup, compatibility mode %d, module path '%s', cwd:%s\n", + VERSION, iCompatibilityMode, glblModPath == NULL ? "" : (char*)glblModPath, + getcwd(cwdbuf, sizeof(cwdbuf))); /* we are done with the initial option parsing and processing. Now we init the system. */ -- cgit v1.2.3 From 302ad02e7781892856c1cacaf98a87f90db9571c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 31 Mar 2010 16:21:58 +0200 Subject: temporary bugfix replaced by permanent one for... ...message-induced off-by-one error (potential segfault) (see 4.6.2) The analysis has been completed and a better fix been crafted and integrated. --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 64b23566..a03dcf0e 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -792,7 +792,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla * (I couldn't do any more smart things anyway...). * rgerhards, 2007-9-20 */ - DBGPRINTF("internal error: iMsg > max msg size in printchopped()\n"); + DBGPRINTF("internal error: iMsg > max msg size in parseAndSubmitMessage()\n"); } FINALIZE; /* in this case, we are done... nothing left we can do */ } -- cgit v1.2.3 From 2cd132eebb84dbcffcf0c20b9354c14f797c29cd Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 7 Apr 2010 12:42:41 +0200 Subject: enhanced nettester tool so that it re-uses it's callers environment this enables us to work with the "usual" environment tweaks (for debugging and other purposes), without the need for any special handling in nettester itself --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a61d1e5d..a93b588f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -792,7 +792,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla * (I couldn't do any more smart things anyway...). * rgerhards, 2007-9-20 */ - DBGPRINTF("internal error: iMsg > max msg size in printchopped()\n"); + DBGPRINTF("internal error: iMsg > max msg size in parseAndSubmitMessage()\n"); } FINALIZE; /* in this case, we are done... nothing left we can do */ } -- cgit v1.2.3 From d19806431653e6575a002ab48206c16d3041e465 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 26 Apr 2010 12:08:00 +0200 Subject: added new $Sleep directive to hold processing for a couple of seconds during startup --- tools/syslogd.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e318fd8e..98bfd3b2 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2460,6 +2460,25 @@ finalize_it: } + +/* Put the rsyslog main thread to sleep for n seconds. This was introduced as + * a quick and dirty workaround for a privilege drop race in regard to listener + * startup, which itself was a result of the not-yet-done proper coding of + * privilege drop code (quite some effort). It may be useful for other occasions, too. + * is specified). + * rgerhards, 2009-06-12 + */ +static rsRetVal +putToSleep(void __attribute__((unused)) *pVal, int iNewVal) +{ + DEFiRet; + DBGPRINTF("rsyslog main thread put to sleep via $sleep %d directive...\n", iNewVal); + srSleep(iNewVal, 0); + DBGPRINTF("rsyslog main thread continues after $sleep %d\n", iNewVal); + RETiRet; +} + + /* Switch to either an already existing rule set or start a new one. The * named rule set becomes the new "current" rule set (what means that new * actions are added to it). @@ -2713,6 +2732,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultruleset", 0, eCmdHdlrGetWord, setDefaultRuleset, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, setCurrRuleset, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"sleep", 0, eCmdHdlrInt, putToSleep, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL)); -- cgit v1.2.3 From 74f8bf146546275e296a3d5af17cc4c6d0397778 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 10 May 2010 15:37:44 +0200 Subject: some more cleanup and a nasty little bug i doDie() --- tools/syslogd.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 2432a28d..d5df8b91 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -20,18 +20,6 @@ * * For further information, please see http://www.rsyslog.com * - * \author Rainer Gerhards - * \date 2003-10-17 - * Some initial modifications on the sysklogd package to support - * liblogging. These have actually not yet been merged to the - * source you see currently (but they hopefully will) - * - * \date 2004-10-28 - * Restarted the modifications of sysklogd. This time, we - * focus on a simpler approach first. The initial goal is to - * provide MySQL database support (so that syslogd can log - * to the database). - * * rsyslog - An Enhanced syslogd Replacement. * Copyright 2003-2009 Rainer Gerhards and Adiscon GmbH. * @@ -981,7 +969,6 @@ static void doDie(int sig) # define MSG2 "DoDie called 5 times - unconditional exit\n" static int iRetries = 0; /* debug aid */ dbgprintf(MSG1); - if(Debug) if(Debug == DEBUG_FULL) write(1, MSG1, sizeof(MSG1) - 1); if(iRetries++ == 4) { -- cgit v1.2.3 From 527bfcea5c9ca5c8414620a022f097d4e53af784 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 1 Jun 2010 18:51:55 +0200 Subject: first implementation of strgen interface and a first built-in strgen module. Some tweaks and more default strgens are needed, but the code doesn't look too bad ;) --- tools/syslogd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index d5df8b91..49f7ed52 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -116,6 +116,7 @@ #include "omdiscard.h" #include "pmrfc5424.h" #include "pmrfc3164.h" +#include "smtradfile.h" #include "threads.h" #include "wti.h" #include "queue.h" @@ -2000,6 +2001,9 @@ static rsRetVal loadBuildInModules(void) CHKiRet(parser.AddDfltParser(UCHAR_CONSTANT("rsyslog.rfc5424"))); CHKiRet(parser.AddDfltParser(UCHAR_CONSTANT("rsyslog.rfc3164"))); + /* load build-in strgen modules */ + CHKiRet(module.doModInit(modInitsmtradfile, UCHAR_CONSTANT("builtin-smtradfile"), NULL)); + /* ok, initialization of the command handler probably does not 100% belong right in * this space here. However, with the current design, this is actually quite a good * place to put it. We might decide to shuffle it around later, but for the time -- cgit v1.2.3 From d9e64c16e52357bae1eb00fc8403c4e63d6365ca Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 4 Jun 2010 12:45:31 +0200 Subject: finshed implementation of strgen modules and also provided four build-in modules for the most common use cases, hopefully resulting in a speedup of around 5% for typical rsyslog processing. --- tools/syslogd.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 49f7ed52..dfbd184b 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -116,7 +116,10 @@ #include "omdiscard.h" #include "pmrfc5424.h" #include "pmrfc3164.h" +#include "smfile.h" #include "smtradfile.h" +#include "smfwd.h" +#include "smtradfwd.h" #include "threads.h" #include "wti.h" #include "queue.h" @@ -322,15 +325,15 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a /* hardcoded standard templates (used for defaults) */ static uchar template_DebugFormat[] = "\"Debug line with all properties:\nFROMHOST: '%FROMHOST%', fromhost-ip: '%fromhost-ip%', HOSTNAME: '%HOSTNAME%', PRI: %PRI%,\nsyslogtag '%syslogtag%', programname: '%programname%', APP-NAME: '%APP-NAME%', PROCID: '%PROCID%', MSGID: '%MSGID%',\nTIMESTAMP: '%TIMESTAMP%', STRUCTURED-DATA: '%STRUCTURED-DATA%',\nmsg: '%msg%'\nescaped msg: '%msg:::drop-cc%'\nrawmsg: '%rawmsg%'\n\n\""; static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n\""; -static uchar template_TraditionalFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n\""; -static uchar template_FileFormat[] = "\"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n\""; +static uchar template_TraditionalFileFormat[] = "=RSYSLOG_TraditionalFileFormat"; +static uchar template_FileFormat[] = "=RSYSLOG_FileFormat"; +static uchar template_ForwardFormat[] = "=RSYSLOG_ForwardFormat"; +static uchar template_TraditionalForwardFormat[] = "=RSYSLOG_TraditionalForwardFormat"; static uchar template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r\""; -static uchar template_ForwardFormat[] = "\"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%\""; -static uchar template_TraditionalForwardFormat[] = "\"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%\""; static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\""; static uchar template_StdDBFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')\",SQL"; static uchar template_StdPgSQLFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%')\",STDSQL"; -/* end template */ +/* end templates */ /* up to the next comment, prototypes that should be removed by reordering */ @@ -2002,7 +2005,10 @@ static rsRetVal loadBuildInModules(void) CHKiRet(parser.AddDfltParser(UCHAR_CONSTANT("rsyslog.rfc3164"))); /* load build-in strgen modules */ + CHKiRet(module.doModInit(modInitsmfile, UCHAR_CONSTANT("builtin-smfile"), NULL)); CHKiRet(module.doModInit(modInitsmtradfile, UCHAR_CONSTANT("builtin-smtradfile"), NULL)); + CHKiRet(module.doModInit(modInitsmfwd, UCHAR_CONSTANT("builtin-smfwd"), NULL)); + CHKiRet(module.doModInit(modInitsmtradfwd, UCHAR_CONSTANT("builtin-smtradfwd"), 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 @@ -2122,10 +2128,6 @@ static rsRetVal mainThread() DEFiRet; uchar *pTmp; - /* Note: signals MUST be processed by the thread this code is running in. The reason - * is that we need to interrupt the select() system call. -- rgerhards, 2007-10-17 - */ - /* initialize the build-in templates */ pTmp = template_DebugFormat; tplAddLine("RSYSLOG_DebugFormat", &pTmp); -- cgit v1.2.3 From 395660f462c62029f76b99f73bd9a424a8cf73a2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 9 Jun 2010 14:34:35 +0200 Subject: somewhat improved direct mode queue performance ... but only for batch enqueues. This will not help much with the current code, but will play well with upcoming changes. --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index dfbd184b..94e8346d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -735,7 +735,7 @@ multiSubmitMsg(multi_submit_t *pMultiSub) pRuleset = MsgGetRuleset(pMultiSub->ppMsgs[0]); pQueue = (pRuleset == NULL) ? pMsgQueue : ruleset.GetRulesetQueue(pRuleset); - iRet = qqueueMultiEnqObj(pQueue, pMultiSub); + iRet = pQueue->MultiEnq(pQueue, pMultiSub); pMultiSub->nElem = 0; finalize_it: -- cgit v1.2.3 From 8fbcea483710faae468ecf0ba706adc7e60ed41d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 9 Jun 2010 15:37:00 +0200 Subject: main msg q consumer now preprocesses messages before doing rule processing things like ACL check and message parsing. This leads to a greater level of concurrent processing. Beware, though, that this commit duplicates some messages. May be a regression from this or an earlier commit. I will soon sort out. --- tools/syslogd.c | 72 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 25 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 94e8346d..2c36e6c2 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -627,39 +627,66 @@ chkMsgAgainstACL() { * (by definition!) considered committed. * rgerhards, 2009-11-16 */ +///static inline rsRetVal +///msgConsumeOne(msg_t *pMsg, prop_t **propFromHost, prop_t **propFromHostIP) { + ///DEFiRet; + //////RETiRet; +///} + +/* preprocess a batch of messages, that is ready them for actual processing. This is done + * as a first stage and totally in parallel to any other worker active in the system. So + * it helps us keep up the overall concurrency level. + * rgerhards, 2010-06-09 + */ static inline rsRetVal -msgConsumeOne(msg_t *pMsg, prop_t **propFromHost, prop_t **propFromHostIP) { +preprocessBatch(batch_t *pBatch, int *pbShutdownImmediate) { uchar fromHost[NI_MAXHOST]; uchar fromHostIP[NI_MAXHOST]; uchar fromHostFQDN[NI_MAXHOST]; + prop_t *propFromHost = NULL; + prop_t *propFromHostIP = NULL; int bIsPermitted; + msg_t *pMsg; + int i; + rsRetVal localRet; DEFiRet; - if((pMsg->msgFlags & NEEDS_ACLCHK_U) != 0) { - dbgprintf("msgConsumer: UDP ACL must be checked for message (hostname-based)\n"); - CHKiRet(net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, fromHostIP)); - bIsPermitted = net.isAllowedSender2((uchar*)"UDP", - (struct sockaddr *)pMsg->rcvFrom.pfrominet, (char*)fromHostFQDN, 1); - if(!bIsPermitted) { - DBGPRINTF("Message from '%s' discarded, not a permitted sender host\n", - fromHostFQDN); - ABORT_FINALIZE(RS_RET_ERR); - /* save some of the info we obtained */ - MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), propFromHost); - CHKiRet(MsgSetRcvFromIPStr(pMsg, fromHostIP, ustrlen(fromHostIP), propFromHostIP)); - pMsg->msgFlags &= ~NEEDS_ACLCHK_U; + for(i = 0 ; i < pBatch->nElem && !*pbShutdownImmediate ; i++) { + pMsg = (msg_t*) pBatch->pElem[i].pUsrp; + if((pMsg->msgFlags & NEEDS_ACLCHK_U) != 0) { + DBGPRINTF("msgConsumer: UDP ACL must be checked for message (hostname-based)\n"); + if(net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, fromHostIP) != RS_RET_OK) + continue; + bIsPermitted = net.isAllowedSender2((uchar*)"UDP", + (struct sockaddr *)pMsg->rcvFrom.pfrominet, (char*)fromHostFQDN, 1); + if(!bIsPermitted) { + DBGPRINTF("Message from '%s' discarded, not a permitted sender host\n", + fromHostFQDN); + pBatch->pElem[i].state = BATCH_STATE_DISC; + } else { + /* save some of the info we obtained */ + MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), &propFromHost); + CHKiRet(MsgSetRcvFromIPStr(pMsg, fromHostIP, ustrlen(fromHostIP), &propFromHostIP)); + pMsg->msgFlags &= ~NEEDS_ACLCHK_U; + } + } + if((pMsg->msgFlags & NEEDS_PARSING) != 0) { + if((localRet = parser.ParseMsg(pMsg)) != RS_RET_OK) { + DBGPRINTF("Message discarded, parsing error %d\n", localRet); + pBatch->pElem[i].state = BATCH_STATE_DISC; + } } } - if((pMsg->msgFlags & NEEDS_PARSING) != 0) - CHKiRet(parser.ParseMsg(pMsg)); - ruleset.ProcessMsg(pMsg); finalize_it: + if(propFromHost != NULL) + prop.Destruct(&propFromHost); + if(propFromHostIP != NULL) + prop.Destruct(&propFromHostIP); RETiRet; } - /* The consumer of dequeued messages. This function is called by the * queue engine on dequeueing of a message. It runs on a SEPARATE * THREAD. It receives an array of pointers, which it must iterate @@ -670,22 +697,17 @@ static rsRetVal msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShutdownImmediate) { int i; - prop_t *propFromHost = NULL; - prop_t *propFromHostIP = NULL; DEFiRet; assert(pBatch != NULL); + preprocessBatch(pBatch, pbShutdownImmediate); for(i = 0 ; i < pBatch->nElem && !*pbShutdownImmediate ; i++) { DBGPRINTF("msgConsumer processes msg %d/%d\n", i, pBatch->nElem); - msgConsumeOne((msg_t*) pBatch->pElem[i].pUsrp, &propFromHost, &propFromHostIP); + ruleset.ProcessMsg((msg_t*) pBatch->pElem[i].pUsrp); pBatch->pElem[i].state = BATCH_STATE_COMM; } - if(propFromHost != NULL) - prop.Destruct(&propFromHost); - if(propFromHostIP != NULL) - prop.Destruct(&propFromHostIP); RETiRet; } -- cgit v1.2.3 From fe8d317c1b40fe162891d5ddec1cb7df702bb7fe Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 10 Jun 2010 14:36:49 +0200 Subject: milestone commit(BUGGY): batch is now handed down to rule processing Now, the full batch is passed down to the rule, which then enqueues the elements as single messages. Note that this code has some known defects and needs more changes until it is correct again. This is primarily a commit to be able to return to a known-(somewhat)-good state. --- tools/syslogd.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 2c36e6c2..46587a27 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -639,19 +639,24 @@ chkMsgAgainstACL() { * rgerhards, 2010-06-09 */ static inline rsRetVal -preprocessBatch(batch_t *pBatch, int *pbShutdownImmediate) { +preprocessBatch(batch_t *pBatch) { uchar fromHost[NI_MAXHOST]; uchar fromHostIP[NI_MAXHOST]; uchar fromHostFQDN[NI_MAXHOST]; prop_t *propFromHost = NULL; prop_t *propFromHostIP = NULL; + int bSingleRuleset; + ruleset_t *batchRuleset; /* the ruleset used for all message inside the batch, if there is a single one */ int bIsPermitted; msg_t *pMsg; int i; rsRetVal localRet; DEFiRet; - for(i = 0 ; i < pBatch->nElem && !*pbShutdownImmediate ; i++) { + bSingleRuleset = 1; + batchRuleset = (pBatch->nElem > 0) ? ((msg_t*) pBatch->pElem[0].pUsrp)->pRuleset : NULL; + + for(i = 0 ; i < pBatch->nElem && !*(pBatch->pbShutdownImmediate) ; i++) { pMsg = (msg_t*) pBatch->pElem[i].pUsrp; if((pMsg->msgFlags & NEEDS_ACLCHK_U) != 0) { DBGPRINTF("msgConsumer: UDP ACL must be checked for message (hostname-based)\n"); @@ -676,8 +681,11 @@ preprocessBatch(batch_t *pBatch, int *pbShutdownImmediate) { pBatch->pElem[i].state = BATCH_STATE_DISC; } } + if(pMsg->pRuleset != batchRuleset) + bSingleRuleset = 0; } + batchSetSingleRuleset(pBatch, bSingleRuleset); finalize_it: if(propFromHost != NULL) @@ -696,18 +704,18 @@ finalize_it: static rsRetVal msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShutdownImmediate) { - int i; DEFiRet; - assert(pBatch != NULL); - - preprocessBatch(pBatch, pbShutdownImmediate); + pBatch->pbShutdownImmediate = pbShutdownImmediate; /* TODO: move this to batch creation! */ + preprocessBatch(pBatch); + ruleset.ProcessBatch(pBatch); +dbgprintf("ZZZ: back in msgConsumer\n"); +//TODO: the BATCH_STATE_COMM must be set somewhere down the road, but we +//do not have this yet and so we emulate -- 2010-06-10 +int i; for(i = 0 ; i < pBatch->nElem && !*pbShutdownImmediate ; i++) { - DBGPRINTF("msgConsumer processes msg %d/%d\n", i, pBatch->nElem); - ruleset.ProcessMsg((msg_t*) pBatch->pElem[i].pUsrp); pBatch->pElem[i].state = BATCH_STATE_COMM; } - RETiRet; } -- cgit v1.2.3 From 802f6d8a8f39e5ba578e0183e4500bef8e3a198c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 15 Jun 2010 14:02:34 +0200 Subject: milestone(BUGGY): batch now pushed down to action at least in important cases (not for non-direct action queues and some other minor things). This version is definitely buggy, but may be tried with success on a non-production system. I will continue to work on the correctness, but needed to commit now to get a baseline. --- tools/syslogd.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 46587a27..9b7b77ab 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -622,17 +622,6 @@ chkMsgAgainstACL() { #endif -/* consumes a single messages - this function is primarily used to shuffle - * out some code from msgConsumer(). After this function, the message is - * (by definition!) considered committed. - * rgerhards, 2009-11-16 - */ -///static inline rsRetVal -///msgConsumeOne(msg_t *pMsg, prop_t **propFromHost, prop_t **propFromHostIP) { - ///DEFiRet; - //////RETiRet; -///} - /* preprocess a batch of messages, that is ready them for actual processing. This is done * as a first stage and totally in parallel to any other worker active in the system. So * it helps us keep up the overall concurrency level. @@ -708,8 +697,8 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu assert(pBatch != NULL); pBatch->pbShutdownImmediate = pbShutdownImmediate; /* TODO: move this to batch creation! */ preprocessBatch(pBatch); +//pBatch->bSingleRuleset = 0; // TODO: testing aid, remove!!!! ruleset.ProcessBatch(pBatch); -dbgprintf("ZZZ: back in msgConsumer\n"); //TODO: the BATCH_STATE_COMM must be set somewhere down the road, but we //do not have this yet and so we emulate -- 2010-06-10 int i; -- cgit v1.2.3 From e64cd212432c2cf76245888499461e9c8bf73243 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 21 Jul 2010 18:08:19 +0200 Subject: moving towards scoping inside rsyslog.conf first step: adding object-type specifier to config statement table --- tools/syslogd.c | 100 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 9b7b77ab..67d2fced 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2036,57 +2036,57 @@ static rsRetVal loadBuildInModules(void) * is that rsyslog will terminate if we can not register our built-in config commands. * This, I think, is the right thing to do. -- rgerhards, 2007-07-31 */ - CHKiRet(regCfSysLineHdlr((uchar *)"logrsyslogstatusmessages", 0, eCmdHdlrBinary, NULL, &bLogStatusMsgs, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"defaultruleset", 0, eCmdHdlrGetWord, setDefaultRuleset, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, setCurrRuleset, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"sleep", 0, eCmdHdlrInt, putToSleep, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuelowwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQLowWtrMark, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardmark", 0, eCmdHdlrInt, NULL, &iMainMsgQDiscardMark, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardseverity", 0, eCmdHdlrSeverity, NULL, &iMainMsgQDiscardSeverity, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuecheckpointinterval", 0, eCmdHdlrInt, NULL, &iMainMsgQPersistUpdCnt, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesyncqueuefiles", 0, eCmdHdlrBinary, NULL, &bMainMsgQSyncQeueFiles, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetype", 0, eCmdHdlrGetWord, setMainMsgQueType, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreads", 0, eCmdHdlrInt, NULL, &iMainMsgQueueNumWorkers, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoQShutdown, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutactioncompletion", 0, eCmdHdlrInt, NULL, &iMainMsgQtoActShutdown, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutenqueue", 0, eCmdHdlrInt, NULL, &iMainMsgQtoEnq, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkertimeoutthreadshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoWrkShutdown, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeueslowdown", 0, eCmdHdlrInt, NULL, &iMainMsgQDeqSlowdown, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreadminimummessages", 0, eCmdHdlrInt, NULL, &iMainMsgQWrkMinMsgs, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxfilesize", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxFileSize, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuebatchsize", 0, eCmdHdlrSize, NULL, &iMainMsgQueDeqBatchSize, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxdiskspace", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxDiskSpace, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesaveonshutdown", 0, eCmdHdlrBinary, NULL, &bMainMsgQSaveOnShutdown, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimebegin", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinFromHr, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinToHr, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"abortonuncleanconfig", 0, eCmdHdlrBinary, NULL, &bAbortOnUncleanConfig, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_ALLOWEDSENDER, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, conf.doModLoad, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, conf.doIncludeLine, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"maxopenfiles", 0, eCmdHdlrInt, setMaxFiles, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintTemplateList, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintModuleList, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"logrsyslogstatusmessages", 0, eCmdHdlrBinary, NULL, &bLogStatusMsgs, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"defaultruleset", 0, eCmdHdlrGetWord, setDefaultRuleset, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, setCurrRuleset, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"sleep", 0, eCmdHdlrInt, putToSleep, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuelowwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQLowWtrMark, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardmark", 0, eCmdHdlrInt, NULL, &iMainMsgQDiscardMark, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardseverity", 0, eCmdHdlrSeverity, NULL, &iMainMsgQDiscardSeverity, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuecheckpointinterval", 0, eCmdHdlrInt, NULL, &iMainMsgQPersistUpdCnt, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesyncqueuefiles", 0, eCmdHdlrBinary, NULL, &bMainMsgQSyncQeueFiles, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetype", 0, eCmdHdlrGetWord, setMainMsgQueType, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreads", 0, eCmdHdlrInt, NULL, &iMainMsgQueueNumWorkers, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoQShutdown, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutactioncompletion", 0, eCmdHdlrInt, NULL, &iMainMsgQtoActShutdown, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutenqueue", 0, eCmdHdlrInt, NULL, &iMainMsgQtoEnq, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkertimeoutthreadshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoWrkShutdown, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeueslowdown", 0, eCmdHdlrInt, NULL, &iMainMsgQDeqSlowdown, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreadminimummessages", 0, eCmdHdlrInt, NULL, &iMainMsgQWrkMinMsgs, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxfilesize", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxFileSize, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuebatchsize", 0, eCmdHdlrSize, NULL, &iMainMsgQueDeqBatchSize, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxdiskspace", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxDiskSpace, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesaveonshutdown", 0, eCmdHdlrBinary, NULL, &bMainMsgQSaveOnShutdown, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimebegin", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinFromHr, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinToHr, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"abortonuncleanconfig", 0, eCmdHdlrBinary, NULL, &bAbortOnUncleanConfig, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_ALLOWEDSENDER, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, conf.doModLoad, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, conf.doIncludeLine, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"maxopenfiles", 0, eCmdHdlrInt, setMaxFiles, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintTemplateList, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintModuleList, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprintcfsyslinehandlerlist", 0, eCmdHdlrBinary, - NULL, &bDebugPrintCfSysLineHandlerList, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"generateconfiggraph", 0, eCmdHdlrGetWord, NULL, &pszConfDAGFile, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &bErrMsgToStderr, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, setMaxMsgSize, NULL, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouser", 0, eCmdHdlrUID, NULL, &uidDropPriv, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouserid", 0, eCmdHdlrInt, NULL, &uidDropPriv, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroup", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroupid", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL)); + NULL, &bDebugPrintCfSysLineHandlerList, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"generateconfiggraph", 0, eCmdHdlrGetWord, NULL, &pszConfDAGFile, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &bErrMsgToStderr, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, setMaxMsgSize, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouser", 0, eCmdHdlrUID, NULL, &uidDropPriv, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouserid", 0, eCmdHdlrInt, NULL, &uidDropPriv, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroup", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroupid", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL, eConfObjGlobal)); finalize_it: RETiRet; -- cgit v1.2.3 From c97b1d3c72ef1504a430f65ae017112d834a3127 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 23 Jul 2010 17:33:08 +0200 Subject: added support to save/restore rsyslog core action settings... ... but not those of plugins (which are at least as important as the core ones). So this is an interim commit. --- tools/syslogd.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 67d2fced..d059757e 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -241,7 +241,6 @@ static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bAbortOnUncleanConfig = 0; /* abort run (rather than starting with partial config) if there was any issue in conf */ -int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ /* end global config file state variables */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ @@ -289,7 +288,6 @@ static int iMainMsgQueueDeqtWinToHr = 25; /* hour begin of time frame when que static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { bLogStatusMsgs = DFLT_bLogStatusMsgs; - bActExecWhenPrevSusp = 0; bDebugPrintTemplateList = 1; bDebugPrintCfSysLineHandlerList = 1; bDebugPrintModuleList = 1; @@ -316,7 +314,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a MainMsgQueType = QUEUETYPE_FIXED_ARRAY; iMainMsgQueMaxDiskSpace = 0; iMainMsgQueDeqBatchSize = 32; - glbliActionResumeRetryCount = 0; return RS_RET_OK; } @@ -2037,7 +2034,6 @@ static rsRetVal loadBuildInModules(void) * This, I think, is the right thing to do. -- rgerhards, 2007-07-31 */ CHKiRet(regCfSysLineHdlr((uchar *)"logrsyslogstatusmessages", 0, eCmdHdlrBinary, NULL, &bLogStatusMsgs, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultruleset", 0, eCmdHdlrGetWord, setDefaultRuleset, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, setCurrRuleset, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"sleep", 0, eCmdHdlrInt, putToSleep, NULL, NULL, eConfObjGlobal)); @@ -2065,7 +2061,6 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinToHr, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"abortonuncleanconfig", 0, eCmdHdlrBinary, NULL, &bAbortOnUncleanConfig, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL, eConfObjGlobal)); -- cgit v1.2.3 From e4c926bfbca3aab3fe34fc9cfedb7343423de016 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 5 Aug 2010 15:44:01 +0200 Subject: changed omudpspoof default spoof address to simplify typical use case --- tools/syslogd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 9b7b77ab..2c8c3e17 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -333,6 +333,7 @@ static uchar template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %t static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\""; static uchar template_StdDBFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')\",SQL"; static uchar template_StdPgSQLFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%')\",STDSQL"; +static uchar template_spoofadr[] = "\"%fromhost-ip%\""; /* end templates */ @@ -2168,6 +2169,8 @@ static rsRetVal mainThread() tplAddLine(" StdDBFmt", &pTmp); pTmp = template_StdPgSQLFmt; tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp)); + pTmp = template_spoofadr; + tplLastStaticInit(tplAddLine("RSYSLOG_omudpspoofDfltSourceTpl", &pTmp)); CHKiRet(init()); -- cgit v1.2.3 From 55256ac96815d6e13fc9df7206d50ef7dcaca4fe Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 10 Aug 2010 14:51:43 +0200 Subject: added imptcp imptcp is a simplified, Linux-specific and potentielly fast syslog plain tcp input plugin (NOT supporting TLS!) --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a03dcf0e..18e0c98f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -371,7 +371,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a /* hardcoded standard templates (used for defaults) */ -static uchar template_DebugFormat[] = "\"Debug line with all properties:\nFROMHOST: '%FROMHOST%', fromhost-ip: '%fromhost-ip%', HOSTNAME: '%HOSTNAME%', PRI: %PRI%,\nsyslogtag '%syslogtag%', programname: '%programname%', APP-NAME: '%APP-NAME%', PROCID: '%PROCID%', MSGID: '%MSGID%',\nTIMESTAMP: '%TIMESTAMP%', STRUCTURED-DATA: '%STRUCTURED-DATA%',\nmsg: '%msg%'\nescaped msg: '%msg:::drop-cc%'\nrawmsg: '%rawmsg%'\n\n\""; +static uchar template_DebugFormat[] = "\"Debug line with all properties:\nFROMHOST: '%FROMHOST%', fromhost-ip: '%fromhost-ip%', HOSTNAME: '%HOSTNAME%', PRI: %PRI%,\nsyslogtag '%syslogtag%', programname: '%programname%', APP-NAME: '%APP-NAME%', PROCID: '%PROCID%', MSGID: '%MSGID%',\nTIMESTAMP: '%TIMESTAMP%', STRUCTURED-DATA: '%STRUCTURED-DATA%',\nmsg: '%msg%'\nescaped msg: '%msg:::drop-cc%'\ninputname: %inputname% rawmsg: '%rawmsg%'\n\n\""; static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n\""; static uchar template_TraditionalFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n\""; static uchar template_FileFormat[] = "\"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n\""; -- cgit v1.2.3 From 41327992680cfb8dd602ea92d6902448dd66413d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 7 Sep 2010 13:06:04 +0200 Subject: acquire /dev/log socket optionally from systemd --- tools/syslogd.c | 61 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 9b7b77ab..a7f76313 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -135,6 +135,7 @@ #include "net.h" #include "vm.h" #include "prop.h" +#include "sd-daemon.h" /* definitions for objects we access */ DEFobjCurrIf(obj) @@ -391,7 +392,7 @@ static char **crunch_list(char *list) char **result = NULL; p = list; - + /* strip off trailing delimiters */ while (p[strlen(p)-1] == LIST_DELIMITER) { count--; @@ -400,18 +401,18 @@ static char **crunch_list(char *list) /* cut off leading delimiters */ while (p[0] == LIST_DELIMITER) { count--; - p++; + p++; } - + /* count delimiters to calculate elements */ for (count=i=0; p[i]; i++) if (p[i] == LIST_DELIMITER) count++; - + if ((result = (char **)MALLOC(sizeof(char *) * (count+2))) == NULL) { printf ("Sorry, can't get enough memory, exiting.\n"); exit(0); /* safe exit, because only called during startup */ } - + /* * We now can assume that the first and last * characters are different from any delimiters, @@ -574,7 +575,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) if(bHaveMainQueue == 0) { /* not yet in queued mode */ iminternalAddMsg(pri, pMsg); } else { - /* we have the queue, so we can simply provide the + /* we have the queue, so we can simply provide the * message to the queue engine. */ submitMsg(pMsg); @@ -721,7 +722,7 @@ submitMsg(msg_t *pMsg) DEFiRet; ISOBJ_TYPE_assert(pMsg, msg); - + pRuleset = MsgGetRuleset(pMsg); pQueue = (pRuleset == NULL) ? pMsgQueue : ruleset.GetRulesetQueue(pRuleset); @@ -787,7 +788,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) { action_t *pAction = (action_t*) pData; assert(pAction != NULL); - + BEGINfunc LockObj(pAction); /* TODO: time() performance: the call below could be moved to @@ -842,7 +843,7 @@ static void debug_switch() dbgprintf("\n"); debugging_on = 0; } - + memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = debug_switch; @@ -1030,7 +1031,7 @@ destructAllActions(void) /* die() is called when the program shall end. This typically only occurs - * during sigterm or during the initialization. + * during sigterm or during the initialization. * As die() is intended to shutdown rsyslogd, it is * safe to call exit() here. Just make sure that die() itself is not called * at inapropriate places. As a general rule of thumb, it is a bad idea to add @@ -1070,7 +1071,7 @@ die(int sig) errno = 0; logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); } - + /* drain queue (if configured so) and stop main queue worker thread pool */ DBGPRINTF("Terminating main queue...\n"); qqueueDestruct(&pMsgQueue); @@ -1194,7 +1195,7 @@ static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask) } -/* drop to specified group +/* drop to specified group * if something goes wrong, the function never returns * Note that such an abort can cause damage to on-disk structures, so we should * re-design the "interface" in the long term. -- rgerhards, 2008-11-26 @@ -1222,7 +1223,7 @@ static void doDropPrivGid(int iGid) } -/* drop to specified user +/* drop to specified user * if something goes wrong, the function never returns * Note that such an abort can cause damage to on-disk structures, so we should * re-design the "interface" in the long term. -- rgerhards, 2008-11-19 @@ -1332,7 +1333,7 @@ generateConfigDAG(uchar *pszDAGFile) DEFiRet; assert(pszDAGFile != NULL); - + if((fp = fopen((char*) pszDAGFile, "w")) == NULL) { logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*) "configuraton graph output file could not be opened, none generated", 0); @@ -1458,7 +1459,7 @@ static void dbgPrintInitInfo(void) /* TODO: add iActionRetryCount = 0; iActionRetryInterval = 30000; - static int iMainMsgQtoWrkMinMsgs = 100; + static int iMainMsgQtoWrkMinMsgs = 100; static int iMainMsgQbSaveOnShutdown = 1; iMainMsgQueMaxDiskSpace = 0; setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100); @@ -1730,7 +1731,7 @@ init(void) * identify this instance. -- rgerhards, 2005-08-17 */ if(bLogStatusMsgs) { - snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char), + snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] start", (int) myPid); @@ -1760,7 +1761,7 @@ finalize_it: -/* Put the rsyslog main thread to sleep for n seconds. This was introduced as +/* Put the rsyslog main thread to sleep for n seconds. This was introduced as * a quick and dirty workaround for a privilege drop race in regard to listener * startup, which itself was a result of the not-yet-done proper coding of * privilege drop code (quite some effort). It may be useful for other occasions, too. @@ -1845,7 +1846,7 @@ static rsRetVal setMainMsgQueType(void __attribute__((unused)) *pVal, uchar *psz void sighup_handler() { struct sigaction sigAct; - + bHadHUP = 1; memset(&sigAct, 0, sizeof (sigAct)); @@ -2428,8 +2429,10 @@ doGlblProcessInit(void) num_fds = getdtablesize(); close(0); /* we keep stdout and stderr open in case we have to emit something */ - for (i = 3; i < num_fds; i++) - (void) close(i); + + if (sd_listen_fds(0) <= 0) + for (i = 3; i < num_fds; i++) + (void) close(i); untty(); } else @@ -2486,7 +2489,7 @@ doGlblProcessInit(void) * modularize it a bit more... */ int realMain(int argc, char **argv) -{ +{ DEFiRet; register uchar *p; @@ -2516,7 +2519,7 @@ int realMain(int argc, char **argv) * of other options, we do this during the inital option processing. With later * versions (if a dependency on -c option is introduced), we must move that code * to other places, but I think it is quite appropriate and saves code to do this - * only when actually neeeded. + * only when actually neeeded. * rgerhards, 2008-04-04 */ while((ch = getopt(argc, argv, "46a:Ac:def:g:hi:l:m:M:nN:op:qQr::s:t:T:u:vwx")) != EOF) { @@ -2581,7 +2584,7 @@ int realMain(int argc, char **argv) case 'v': /* MUST be carried out immediately! */ printVersion(); exit(0); /* exit for -v option - so this is a "good one" */ - case '?': + case '?': default: usage(); } @@ -2637,7 +2640,7 @@ int realMain(int argc, char **argv) * Good software also always checks its return values... * If syslogd starts up before DNS is up & /etc/hosts * doesn't have LocalHostName listed, gethostbyname will - * return NULL. + * return NULL. */ /* TODO: gethostbyname() is not thread-safe, but replacing it is * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 @@ -2646,7 +2649,7 @@ int realMain(int argc, char **argv) if(hent) { free(LocalHostName); CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - + if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { *p++ = '\0'; @@ -2658,7 +2661,7 @@ int realMain(int argc, char **argv) /* Convert to lower case to recognize the correct domain laterly */ for(p = LocalDomain ; *p ; p++) *p = (char)tolower((int)*p); - + /* we now have our hostname and can set it inside the global vars. * TODO: think if all of this would better be a runtime function * rgerhards, 2008-04-17 @@ -2814,7 +2817,7 @@ int realMain(int argc, char **argv) case 'x': /* disable dns for remote messages */ glbl.SetDisableDNS(1); break; - case '?': + case '?': default: usage(); } @@ -2871,7 +2874,7 @@ int realMain(int argc, char **argv) /* do any de-init's that need to be done AFTER this comment */ die(bFinished); - + thrdExit(); finalize_it: @@ -2893,7 +2896,7 @@ finalize_it: * rgerhards, 20080-01-28 */ int main(int argc, char **argv) -{ +{ dbgClassInit(); return realMain(argc, argv); } -- cgit v1.2.3 From 735be1e247563d422c18d955530eb8360e706361 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 17 Sep 2010 10:15:20 +0200 Subject: minor: improved error message when already running --- tools/syslogd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 56000e08..4964f8fc 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2437,10 +2437,9 @@ doGlblProcessInit(void) for (i = 3; i < num_fds; i++) (void) close(i); untty(); - } - else - { - fputs(" Already running.\n", stderr); + } else { + fputs(" Already running. If you want to run multiple instances, you need " + "to specify different pid files (use -i option)\n", stderr); exit(1); /* "good" exit, done if syslogd is already running */ } } -- cgit v1.2.3 From 1bfb97e576d779a709e1e2979eef4697b9b0cd16 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 2 Dec 2010 07:28:04 +0100 Subject: bugfix: one type of 64bit atomics was enabled when 32bit atomics were supported also cleaned up some minor things --- tools/syslogd.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4964f8fc..70d4cf2e 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2111,11 +2111,6 @@ static void printVersion(void) #else printf("\tFEATURE_LARGEFILE:\t\t\tNo\n"); #endif -#ifdef USE_NETZIP - printf("\tFEATURE_NETZIP (message compression):\tYes\n"); -#else - printf("\tFEATURE_NETZIP (message compression):\tNo\n"); -#endif #if defined(SYSLOG_INET) && defined(USE_GSSAPI) printf("\tGSSAPI Kerberos 5 support:\t\tYes\n"); #else @@ -2127,9 +2122,14 @@ static void printVersion(void) printf("\tFEATURE_DEBUG (debug build, slow code):\tNo\n"); #endif #ifdef HAVE_ATOMIC_BUILTINS - printf("\tAtomic operations supported:\t\tYes\n"); + printf("\t32bit Atomic operations supported:\tYes\n"); +#else + printf("\t32bit Atomic operations supported:\tNo\n"); +#endif +#ifdef HAVE_ATOMIC_BUILTINS64 + printf("\t64bit Atomic operations supported:\tYes\n"); #else - printf("\tAtomic operations supported:\t\tNo\n"); + printf("\t64bit Atomic operations supported:\tNo\n"); #endif #ifdef RTINST printf("\tRuntime Instrumentation (slow code):\tYes\n"); -- cgit v1.2.3 From 371a8eec29fa25bbf58f4b1f0d7e3bf4c3ad6329 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 16 Dec 2010 12:57:55 +0100 Subject: some cleanup based on clang static analyzer results --- tools/syslogd.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a03dcf0e..12d94e9a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1190,7 +1190,6 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) { uchar *p2parse; int lenMsg; - int bTAGCharDetected; int i; /* general index for parsing */ uchar bufParseTAG[CONF_TAG_MAXSIZE]; uchar bufParseHOSTNAME[CONF_HOSTNAME_MAXSIZE]; @@ -1251,7 +1250,6 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * rgerhards, 2009-06-23: and I now have extended this logic to every character * that is not a valid hostname. */ - bTAGCharDetected = 0; if(lenMsg > 0 && flags & PARSE_HOSTNAME) { i = 0; while(i < lenMsg && (isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.' -- cgit v1.2.3 From 06bad730521dc476a7eabbbedf624a4cfbf65b18 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 16 Dec 2010 13:40:23 +0100 Subject: cleanup of cosmetic nit (result of clang static code analyser run) --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index fb1c6e0e..5f8d45a8 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3290,7 +3290,7 @@ int realMain(int argc, char **argv) } } - if ((argc -= optind)) + if(argc - optind) usage(); DBGPRINTF("rsyslogd %s startup, compatibility mode %d, module path '%s', cwd:%s\n", -- cgit v1.2.3 From c5611012f9d82155d6017435b5cf52c0b4e31149 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 16 Dec 2010 13:41:18 +0100 Subject: fixed cosmetic nit (as a result of clang static code analyzer run) --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 2e4ea5d5..ffcaa27f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2590,7 +2590,7 @@ int realMain(int argc, char **argv) } } - if ((argc -= optind)) + if(argc - optind) usage(); DBGPRINTF("rsyslogd %s startup, compatibility mode %d, module path '%s', cwd:%s\n", -- cgit v1.2.3 From 699d0d933ab64941d40df17c69b2c377231924cf Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 16 Dec 2010 15:29:20 +0100 Subject: added $LocalHostName config directive & some bugfixing - added $LocalHostName config directive - bugfix: local hostname was pulled too-early, so that some config directives (namely FQDN settings) did not have any effect --- tools/syslogd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5f8d45a8..058d75d8 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2302,6 +2302,9 @@ init() legacyOptsHook(); + /* re-generate local host name property, as the config may have changed our FQDN settings */ + glbl.GenerateLocalHostNameProperty(); + /* we are now done with reading the configuration. This is the right time to * free some objects that were just needed for loading it. rgerhards 2005-10-19 */ @@ -3566,9 +3569,6 @@ int realMain(int argc, char **argv) if(!iConfigVerify) CHKiRet(doGlblProcessInit()); - /* re-generate local host name property, as the config may have changed our FQDN settings */ - glbl.GenerateLocalHostNameProperty(); - CHKiRet(mainThread()); /* do any de-init's that need to be done AFTER this comment */ -- cgit v1.2.3 From 1b84d5998926df6ef1b2bbfc9fe5a59a80c5564c Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Fri, 11 Feb 2011 09:24:45 +0100 Subject: Improved systemd socket activation support Support for multiple unix sockets and activation in forking mode Signed-off-by: Marius Tomaschewski --- tools/syslogd.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 19a5900c..52c0be5f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2429,13 +2429,46 @@ doGlblProcessInit(void) */ exit(1); /* "good" exit - after forking, not diasabling anything */ } + num_fds = getdtablesize(); close(0); /* we keep stdout and stderr open in case we have to emit something */ + i = 3; + + /* if (sd_booted()) */ { + const char *e; + char buf[24] = { '\0' }; + char *p = NULL; + unsigned long l; + int fds; + + /* fork & systemd socket activation: + * fetch listen pid and update to ours, + * when it is set to pid of our parent. + */ + if ( (e = getenv("LISTEN_PID"))) { + errno = 0; + l = strtoul(e, &p, 10); + if (errno == 0 && l > 0 && (!p || !*p)) { + if (getppid() == (pid_t)l) { + snprintf(buf, sizeof(buf), "%d", + getpid()); + setenv("LISTEN_PID", buf, 1); + } + } + } + + /* + * close only all further fds, except + * of the fds provided by systemd. + */ + sd_fds = sd_listen_fds(0); + if (sd_fds > 0) + i = SD_LISTEN_FDS_START + sd_fds; + } + for ( ; i < num_fds; i++) + (void) close(i); - if (sd_listen_fds(0) <= 0) - for (i = 3; i < num_fds; i++) - (void) close(i); untty(); } else { fputs(" Already running. If you want to run multiple instances, you need " -- cgit v1.2.3 From c90079aaf07ed574b11ade34af899cb4980ac9f5 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 11 Feb 2011 11:25:06 +0100 Subject: fixed some compile issues in recent systemd patch --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 52c0be5f..cdb31ef6 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2440,7 +2440,7 @@ doGlblProcessInit(void) char buf[24] = { '\0' }; char *p = NULL; unsigned long l; - int fds; + int sd_fds; /* fork & systemd socket activation: * fetch listen pid and update to ours, -- cgit v1.2.3 From 772e0ae8460478e43caac55dfa3182dd4b58b52a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 16 Feb 2011 11:46:56 +0100 Subject: cleanup: no longer parameter in iminternal system removed --- tools/syslogd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index cdb31ef6..c4a3b270 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -574,7 +574,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) } if(bHaveMainQueue == 0) { /* not yet in queued mode */ - iminternalAddMsg(pri, pMsg); + iminternalAddMsg(pMsg); } else { /* we have the queue, so we can simply provide the * message to the queue engine. @@ -1868,10 +1868,9 @@ void sigttin_handler() */ static inline void processImInternal(void) { - int iPri; msg_t *pMsg; - while(iminternalRemoveMsg(&iPri, &pMsg) == RS_RET_OK) { + while(iminternalRemoveMsg(&pMsg) == RS_RET_OK) { submitMsg(pMsg); } } -- cgit v1.2.3 From de898fd5893b1b4811cc513a52af5dabcedc5291 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 22 Feb 2011 17:33:40 +0100 Subject: bugfix (minor): warning message suggested invalid compatibility mode --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index c4a3b270..574c2efa 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2875,7 +2875,7 @@ int realMain(int argc, char **argv) if(iCompatibilityMode < 4) { errmsg.LogError(0, NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically " "generated config directives may interfer with your rsyslog.conf settings. " - "We suggest upgrading your config and adding -c4 as the first " + "We suggest upgrading your config and adding -c5 as the first " "rsyslogd option."); } -- cgit v1.2.3 From f46fa5ca003b55702107e170a2868ed0120246c7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 25 Feb 2011 12:37:03 +0100 Subject: cosmetic: removing commented-out testing aid --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 574c2efa..f7d71d06 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -699,7 +699,6 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu assert(pBatch != NULL); pBatch->pbShutdownImmediate = pbShutdownImmediate; /* TODO: move this to batch creation! */ preprocessBatch(pBatch); -//pBatch->bSingleRuleset = 0; // TODO: testing aid, remove!!!! ruleset.ProcessBatch(pBatch); //TODO: the BATCH_STATE_COMM must be set somewhere down the road, but we //do not have this yet and so we emulate -- 2010-06-10 -- cgit v1.2.3 From 3866bd51bf7e622594ff4831664c28d80f711cb3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 8 Mar 2011 18:29:33 +0100 Subject: bugfix(kind of): tell users that config graph can currently not be generated closes: http://bugzilla.adiscon.com/show_bug.cgi?id=232 --- tools/syslogd.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ffcaa27f..dd9729ef 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1334,6 +1334,11 @@ generateConfigDAG(uchar *pszDAGFile) assert(pszDAGFile != NULL); + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*) + "Configuration graph generation is unfortunately disabled " + "in the current code base.", 0); + ABORT_FINALIZE(RS_RET_FILENAME_INVALID); + if((fp = fopen((char*) pszDAGFile, "w")) == NULL) { logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*) "configuraton graph output file could not be opened, none generated", 0); -- cgit v1.2.3 From 9e18ecc9bd14093b78199fd36c315cfce4d26a26 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 16 Mar 2011 15:04:43 +0100 Subject: fixed a regression of last patch and some cleanup --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index dd9729ef..1148108c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -799,7 +799,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) DBGPRINTF("flush %s: repeated %d times, %d sec.\n", module.GetStateName(pAction->pMod), pAction->f_prevcount, repeatinterval[pAction->f_repeatcount]); - actionWriteToAction(pAction); + actionWriteToAction(pAction, NULL, 0); BACKOFF(pAction); } UnlockObj(pAction); -- cgit v1.2.3 From e1c34e174139ad030ca1108ff9782b294909013c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 Apr 2011 07:53:23 +0200 Subject: renamed conf.c to legacyconf.c to make room for new config system --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 44c88624..a6127305 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -124,7 +124,7 @@ #include "wti.h" #include "queue.h" #include "stream.h" -#include "conf.h" +#include "legacyconf.h" #include "errmsg.h" #include "datetime.h" #include "parser.h" -- cgit v1.2.3 From bbe1f2688c4bd5cb1b66bb48af1ce5428d69c3b9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 Apr 2011 08:24:25 +0200 Subject: renaming conf.* wasn't a good idea -- undoing too many dependencies, things get cluttered (and merging probably gets problematic). Now new config will be "conf2". --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a6127305..44c88624 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -124,7 +124,7 @@ #include "wti.h" #include "queue.h" #include "stream.h" -#include "legacyconf.h" +#include "conf.h" #include "errmsg.h" #include "datetime.h" #include "parser.h" -- cgit v1.2.3 From 7420dd6c2f68fc1abcce9fb2076d3aadc92cbffc Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 Apr 2011 09:05:41 +0200 Subject: bugfix(minor): improper template function call in syslogd.c --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index c9734d14..487ab364 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2172,7 +2172,7 @@ static rsRetVal mainThread() pTmp = template_StdDBFmt; tplAddLine(" StdDBFmt", &pTmp); pTmp = template_StdPgSQLFmt; - tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp)); + tplAddLine(" StdPgSQLFmt", &pTmp); pTmp = template_spoofadr; tplLastStaticInit(tplAddLine("RSYSLOG_omudpspoofDfltSourceTpl", &pTmp)); -- cgit v1.2.3 From f72bde2f701b1a1ff42273e8f9b07de47b480ce9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 Apr 2011 09:43:36 +0200 Subject: milestone: templates are now in config object --- tools/syslogd.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 44c88624..d0a6df40 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -21,7 +21,7 @@ * For further information, please see http://www.rsyslog.com * * rsyslog - An Enhanced syslogd Replacement. - * Copyright 2003-2009 Rainer Gerhards and Adiscon GmbH. + * Copyright 2003-2011 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * @@ -135,6 +135,7 @@ #include "net.h" #include "vm.h" #include "prop.h" +#include "rsconf.h" #include "sd-daemon.h" /* definitions for objects we access */ @@ -149,6 +150,7 @@ DEFobjCurrIf(rule) DEFobjCurrIf(ruleset) DEFobjCurrIf(prop) DEFobjCurrIf(parser) +DEFobjCurrIf(rsconf) DEFobjCurrIf(net) /* TODO: make go away! */ @@ -198,6 +200,8 @@ static rsRetVal GlobalClassExit(void); # define _PATH_TTY "/dev/tty" #endif +rsconf_t *ourConf; /* our config object */ + static prop_t *pInternalInputName = NULL; /* there is only one global inputName for all internally-generated messages */ static prop_t *pLocalHostIP = NULL; /* there is only one global IP for all internally-generated messages */ static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */ @@ -1087,7 +1091,7 @@ die(int sig) * ourselfs, this makes finding memory leaks a lot * easier. */ - tplDeleteAll(); + tplDeleteAll(ourConf); /* de-init some modules */ modExitIminternal(); @@ -1438,7 +1442,7 @@ static void dbgPrintInitInfo(void) ruleset.DebugPrintAll(); DBGPRINTF("\n"); if(bDebugPrintTemplateList) - tplPrintList(); + tplPrintList(ourConf); if(bDebugPrintModuleList) module.PrintList(); ochPrintList(); @@ -2147,29 +2151,32 @@ static rsRetVal mainThread() DEFiRet; uchar *pTmp; + /* we need to init the config object first! */ + CHKiRet(rsconf.Construct(&ourConf)); + /* initialize the build-in templates */ pTmp = template_DebugFormat; - tplAddLine("RSYSLOG_DebugFormat", &pTmp); + tplAddLine(ourConf, "RSYSLOG_DebugFormat", &pTmp); pTmp = template_SyslogProtocol23Format; - tplAddLine("RSYSLOG_SyslogProtocol23Format", &pTmp); + tplAddLine(ourConf, "RSYSLOG_SyslogProtocol23Format", &pTmp); pTmp = template_FileFormat; /* new format for files with high-precision stamp */ - tplAddLine("RSYSLOG_FileFormat", &pTmp); + tplAddLine(ourConf, "RSYSLOG_FileFormat", &pTmp); pTmp = template_TraditionalFileFormat; - tplAddLine("RSYSLOG_TraditionalFileFormat", &pTmp); + tplAddLine(ourConf, "RSYSLOG_TraditionalFileFormat", &pTmp); pTmp = template_WallFmt; - tplAddLine(" WallFmt", &pTmp); + tplAddLine(ourConf, " WallFmt", &pTmp); pTmp = template_ForwardFormat; - tplAddLine("RSYSLOG_ForwardFormat", &pTmp); + tplAddLine(ourConf, "RSYSLOG_ForwardFormat", &pTmp); pTmp = template_TraditionalForwardFormat; - tplAddLine("RSYSLOG_TraditionalForwardFormat", &pTmp); + tplAddLine(ourConf, "RSYSLOG_TraditionalForwardFormat", &pTmp); pTmp = template_StdUsrMsgFmt; - tplAddLine(" StdUsrMsgFmt", &pTmp); + tplAddLine(ourConf, " StdUsrMsgFmt", &pTmp); pTmp = template_StdDBFmt; - tplAddLine(" StdDBFmt", &pTmp); + tplAddLine(ourConf, " StdDBFmt", &pTmp); pTmp = template_StdPgSQLFmt; - tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp)); + tplAddLine(ourConf, " StdPgSQLFmt", &pTmp); pTmp = template_spoofadr; - tplLastStaticInit(tplAddLine("RSYSLOG_omudpspoofDfltSourceTpl", &pTmp)); + tplLastStaticInit(ourConf, tplAddLine(ourConf, "RSYSLOG_omudpspoofDfltSourceTpl", &pTmp)); CHKiRet(init()); @@ -2261,6 +2268,8 @@ InitGlobalClasses(void) CHKiRet(objUse(prop, CORE_COMPONENT)); pErrObj = "parser"; CHKiRet(objUse(parser, CORE_COMPONENT)); + pErrObj = "rsconf"; + CHKiRet(objUse(rsconf, CORE_COMPONENT)); /* intialize some dummy classes that are not part of the runtime */ pErrObj = "action"; @@ -2306,6 +2315,7 @@ GlobalClassExit(void) objRelease(expr, CORE_COMPONENT); vmClassExit(); /* this is hack, currently core_modules do not get this automatically called */ parserClassExit(); /* this is hack, currently core_modules do not get this automatically called */ + rsconfClassExit(); /* this is hack, currently core_modules do not get this automatically called */ objRelease(datetime, CORE_COMPONENT); /* TODO: implement the rest of the deinit */ -- cgit v1.2.3 From d348558a51402d08310d95cfd6e8a2d6b9fce1b2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 Apr 2011 11:26:37 +0200 Subject: milestone: conf obj interface now utilzes rsconf_t --- tools/syslogd.c | 64 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 13 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index d0a6df40..c01fd6ad 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -898,7 +898,7 @@ void legacyOptsHook(void) errno = 0; errmsg.LogError(0, NO_ERRCODE, "Warning: backward compatibility layer added to following " "directive to rsyslog.conf: %s", pThis->line); - conf.cfsysline(pThis->line); + conf.cfsysline(ourConf, pThis->line); } pThis = pThis->next; } @@ -1618,8 +1618,8 @@ init(void) ruleset.ConstructFinalize(pRuleset); /* open the configuration file */ - localRet = conf.processConfFile(ConfFile); - CHKiRet(conf.GetNbrActActions(&iNbrActions)); + localRet = conf.processConfFile(ourConf, ConfFile); + CHKiRet(conf.GetNbrActActions(ourConf, &iNbrActions)); if(localRet != RS_RET_OK) { errmsg.LogError(0, localRet, "CONFIG ERROR: could not interpret master config file '%s'.", ConfFile); @@ -1644,13 +1644,13 @@ init(void) */ char szTTYNameBuf[128]; rule_t *pRule = NULL; /* initialization to NULL is *vitally* important! */ - conf.cfline(UCHAR_CONSTANT("*.ERR\t" _PATH_CONSOLE), &pRule); - conf.cfline(UCHAR_CONSTANT("syslog.*\t" _PATH_CONSOLE), &pRule); - conf.cfline(UCHAR_CONSTANT("*.PANIC\t*"), &pRule); - conf.cfline(UCHAR_CONSTANT("syslog.*\troot"), &pRule); + conf.cfline(ourConf, UCHAR_CONSTANT("*.ERR\t" _PATH_CONSOLE), &pRule); + conf.cfline(ourConf, UCHAR_CONSTANT("syslog.*\t" _PATH_CONSOLE), &pRule); + conf.cfline(ourConf, UCHAR_CONSTANT("*.PANIC\t*"), &pRule); + conf.cfline(ourConf, UCHAR_CONSTANT("syslog.*\troot"), &pRule); if(ttyname_r(0, szTTYNameBuf, sizeof(szTTYNameBuf)) == 0) { snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf); - conf.cfline((uchar*)cbuf, &pRule); + conf.cfline(ourConf, (uchar*)cbuf, &pRule); } else { DBGPRINTF("error %d obtaining controlling terminal, not using that emergency rule\n", errno); } @@ -1985,6 +1985,44 @@ mainloop(void) } +/* this method is needed to shuffle the current conf object down to the + * IncludeConfig handler. + */ +static rsRetVal +doNameLine(void *pVal, uchar *pNewVal) +{ + DEFiRet; + iRet = conf.doNameLine(ourConf, pVal, pNewVal); + free(pNewVal); + RETiRet; +} + + +/* this method is needed to shuffle the current conf object down to the + * IncludeConfig handler. + */ +static rsRetVal +doModLoad(void *pVal, uchar *pNewVal) +{ + DEFiRet; + iRet = conf.doModLoad(ourConf, pVal, pNewVal); + free(pNewVal); + RETiRet; +} + + +/* this method is needed to shuffle the current conf object down to the + * IncludeConfig handler. + */ +static rsRetVal +doIncludeLine(void *pVal, uchar *pNewVal) +{ + DEFiRet; + iRet = conf.doIncludeLine(ourConf, pVal, pNewVal); + free(pNewVal); + RETiRet; +} + /* load build-in modules * very first version begun on 2007-07-23 by rgerhards */ @@ -2071,11 +2109,11 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"abortonuncleanconfig", 0, eCmdHdlrBinary, NULL, &bAbortOnUncleanConfig, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_ALLOWEDSENDER, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, conf.doModLoad, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, conf.doIncludeLine, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_TEMPLATE, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_OUTCHANNEL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_ALLOWEDSENDER, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, doModLoad, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, doIncludeLine, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"maxopenfiles", 0, eCmdHdlrInt, setMaxFiles, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintTemplateList, NULL, eConfObjGlobal)); -- cgit v1.2.3 From b722cd3fe608a0bbf4a6df962f9d5c5e547fdc09 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 Apr 2011 12:18:26 +0200 Subject: milestone: ruleset now supports rsconf_t --- tools/syslogd.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index c01fd6ad..dbc5ec64 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -815,7 +815,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) static void doFlushRptdMsgs(void) { - ruleset.IterateAllActions(flushRptdMsgsActions, NULL); + ruleset.IterateAllActions(ourConf, flushRptdMsgsActions, NULL); } @@ -1026,7 +1026,7 @@ freeAllDynMemForTermination(void) static inline void destructAllActions(void) { - ruleset.DestructAllActions(); + ruleset.DestructAllActions(ourConf); bHaveMainQueue = 0; // flag that internal messages need to be temporarily stored } @@ -1439,7 +1439,7 @@ finalize_it: */ static void dbgPrintInitInfo(void) { - ruleset.DebugPrintAll(); + ruleset.DebugPrintAll(ourConf); DBGPRINTF("\n"); if(bDebugPrintTemplateList) tplPrintList(ourConf); @@ -1614,8 +1614,8 @@ init(void) /* construct the default ruleset */ ruleset.Construct(&pRuleset); - ruleset.SetName(pRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset")); - ruleset.ConstructFinalize(pRuleset); + ruleset.SetName(ourConf, pRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset")); + ruleset.ConstructFinalize(ourConf, pRuleset); /* open the configuration file */ localRet = conf.processConfFile(ourConf, ConfFile); @@ -1654,7 +1654,7 @@ init(void) } else { DBGPRINTF("error %d obtaining controlling terminal, not using that emergency rule\n", errno); } - ruleset.AddRule(ruleset.GetCurrent(), &pRule); + ruleset.AddRule(ourConf, ruleset.GetCurrent(), &pRule); } legacyOptsHook(); @@ -1758,7 +1758,7 @@ setDefaultRuleset(void __attribute__((unused)) *pVal, uchar *pszName) { DEFiRet; - CHKiRet(ruleset.SetDefaultRuleset(pszName)); + CHKiRet(ruleset.SetDefaultRuleset(ourConf, pszName)); finalize_it: free(pszName); /* no longer needed */ @@ -1797,13 +1797,13 @@ setCurrRuleset(void __attribute__((unused)) *pVal, uchar *pszName) rsRetVal localRet; DEFiRet; - localRet = ruleset.SetCurrRuleset(pszName); + localRet = ruleset.SetCurrRuleset(ourConf, pszName); if(localRet == RS_RET_NOT_FOUND) { DBGPRINTF("begin new current rule set '%s'\n", pszName); CHKiRet(ruleset.Construct(&pRuleset)); - CHKiRet(ruleset.SetName(pRuleset, pszName)); - CHKiRet(ruleset.ConstructFinalize(pRuleset)); + CHKiRet(ruleset.SetName(ourConf, pRuleset, pszName)); + CHKiRet(ruleset.ConstructFinalize(ourConf, pRuleset)); } else { ABORT_FINALIZE(localRet); } @@ -1913,7 +1913,7 @@ doHUP(void) logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); } - ruleset.IterateAllActions(doHUPActions, NULL); + ruleset.IterateAllActions(ourConf, doHUPActions, NULL); } -- cgit v1.2.3 From 542fd3300671a2480ff009e060b32f08fed44b4d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 Apr 2011 12:37:39 +0200 Subject: some more work was required on the ruleset modification --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index dbc5ec64..72fb04d5 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1654,7 +1654,7 @@ init(void) } else { DBGPRINTF("error %d obtaining controlling terminal, not using that emergency rule\n", errno); } - ruleset.AddRule(ourConf, ruleset.GetCurrent(), &pRule); + ruleset.AddRule(ourConf, ruleset.GetCurrent(ourConf), &pRule); } legacyOptsHook(); -- cgit v1.2.3 From 28e750eebd8ccb5655bdc18693b3b7c9d9ad826b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 Apr 2011 14:58:31 +0200 Subject: step: slowly migrating config settings... ;) --- tools/syslogd.c | 79 ++++++++++++++++++--------------------------------------- 1 file changed, 25 insertions(+), 54 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 72fb04d5..e0e5868b 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -238,12 +238,6 @@ legacyOptsLL_t *pLegacyOptsLL = NULL; int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is the default, so if no -c option is given, we make ourselvs as compatible to sysklogd as possible. */ -#define DFLT_bLogStatusMsgs 1 -static int bLogStatusMsgs = DFLT_bLogStatusMsgs; /* log rsyslog start/stop/HUP messages? */ -static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */ -static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */ -static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ -static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bAbortOnUncleanConfig = 0; /* abort run (rather than starting with partial config) if there was any issue in conf */ /* end global config file state variables */ @@ -292,10 +286,10 @@ static int iMainMsgQueueDeqtWinToHr = 25; /* hour begin of time frame when que */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { - bLogStatusMsgs = DFLT_bLogStatusMsgs; - bDebugPrintTemplateList = 1; - bDebugPrintCfSysLineHandlerList = 1; - bDebugPrintModuleList = 1; + ourConf->globals.bLogStatusMsgs = DFLT_bLogStatusMsgs; + ourConf->globals.bDebugPrintTemplateList = 1; + ourConf->globals.bDebugPrintCfSysLineHandlerList = 1; + ourConf->globals.bDebugPrintModuleList = 1; bReduceRepeatMsgs = 0; bAbortOnUncleanConfig = 0; free(pszMainMsgQFName); @@ -569,7 +563,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) * permits us to process unmodified config files which otherwise contain a * supressor statement. */ - if(((Debug == DEBUG_FULL || NoFork) && bErrMsgToStderr) || iConfigVerify) { + if(((Debug == DEBUG_FULL || NoFork) && ourConf->globals.bErrMsgToStderr) || iConfigVerify) { if(LOG_PRI(pri) == LOG_ERR) fprintf(stderr, "rsyslogd: %s\n", msg); } @@ -1064,7 +1058,7 @@ die(int sig) thrdTerminateAll(); /* and THEN send the termination log message (see long comment above) */ - if(sig && bLogStatusMsgs) { + if(sig && ourConf->globals.bLogStatusMsgs) { (void) snprintf(buf, sizeof(buf) / sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.", @@ -1439,17 +1433,10 @@ finalize_it: */ static void dbgPrintInitInfo(void) { - ruleset.DebugPrintAll(ourConf); - DBGPRINTF("\n"); - if(bDebugPrintTemplateList) - tplPrintList(ourConf); - if(bDebugPrintModuleList) - module.PrintList(); + dbgprintf("The following is the old-style, to-be-replaced, current config dump at the end " + " of the config load process ;)\n"); ochPrintList(); - if(bDebugPrintCfSysLineHandlerList) - dbgPrintCfSysLineHandlers(); - DBGPRINTF("Messages with malicious PTR DNS Records are %sdropped.\n", glbl.GetDropMalPTRMsgs() ? "" : "not "); @@ -1621,6 +1608,9 @@ init(void) localRet = conf.processConfFile(ourConf, ConfFile); CHKiRet(conf.GetNbrActActions(ourConf, &iNbrActions)); + dbgprintf("rsyslog finished loading initial config %p\n", ourConf); + rsconf.DebugPrint(ourConf); + if(localRet != RS_RET_OK) { errmsg.LogError(0, localRet, "CONFIG ERROR: could not interpret master config file '%s'.", ConfFile); bHadConfigErr = 1; @@ -1736,7 +1726,7 @@ init(void) /* we now generate the startup message. It now includes everything to * identify this instance. -- rgerhards, 2005-08-17 */ - if(bLogStatusMsgs) { + if(ourConf->globals.bLogStatusMsgs) { snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] start", @@ -1766,25 +1756,6 @@ finalize_it: } - -/* Put the rsyslog main thread to sleep for n seconds. This was introduced as - * a quick and dirty workaround for a privilege drop race in regard to listener - * startup, which itself was a result of the not-yet-done proper coding of - * privilege drop code (quite some effort). It may be useful for other occasions, too. - * is specified). - * rgerhards, 2009-06-12 - */ -static rsRetVal -putToSleep(void __attribute__((unused)) *pVal, int iNewVal) -{ - DEFiRet; - DBGPRINTF("rsyslog main thread put to sleep via $sleep %d directive...\n", iNewVal); - srSleep(iNewVal, 0); - DBGPRINTF("rsyslog main thread continues after $sleep %d\n", iNewVal); - RETiRet; -} - - /* Switch to either an already existing rule set or start a new one. The * named rule set becomes the new "current" rule set (what means that new * actions are added to it). @@ -1904,7 +1875,7 @@ doHUP(void) { char buf[512]; - if(bLogStatusMsgs) { + if(ourConf->globals.bLogStatusMsgs) { snprintf(buf, sizeof(buf) / sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed", @@ -2026,7 +1997,7 @@ doIncludeLine(void *pVal, uchar *pNewVal) /* load build-in modules * very first version begun on 2007-07-23 by rgerhards */ -static rsRetVal loadBuildInModules(void) +static rsRetVal loadBuildInModules(rsconf_t *config) { DEFiRet; @@ -2080,10 +2051,10 @@ static rsRetVal loadBuildInModules(void) * is that rsyslog will terminate if we can not register our built-in config commands. * This, I think, is the right thing to do. -- rgerhards, 2007-07-31 */ - CHKiRet(regCfSysLineHdlr((uchar *)"logrsyslogstatusmessages", 0, eCmdHdlrBinary, NULL, &bLogStatusMsgs, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"logrsyslogstatusmessages", 0, eCmdHdlrBinary, NULL, &ourConf->globals.bLogStatusMsgs, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultruleset", 0, eCmdHdlrGetWord, setDefaultRuleset, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, setCurrRuleset, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"sleep", 0, eCmdHdlrInt, putToSleep, NULL, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"sleep", 0, eCmdHdlrGoneAway, NULL, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL, eConfObjGlobal)); @@ -2116,14 +2087,14 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, doIncludeLine, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"maxopenfiles", 0, eCmdHdlrInt, setMaxFiles, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintTemplateList, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintModuleList, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &(config->globals.bDebugPrintTemplateList), NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &(config->globals.bDebugPrintModuleList), NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprintcfsyslinehandlerlist", 0, eCmdHdlrBinary, - NULL, &bDebugPrintCfSysLineHandlerList, NULL, eConfObjGlobal)); + NULL, &(config->globals.bDebugPrintCfSysLineHandlerList), NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"generateconfiggraph", 0, eCmdHdlrGetWord, NULL, &pszConfDAGFile, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &bErrMsgToStderr, NULL, eConfObjGlobal)); + CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &ourConf->globals.bErrMsgToStderr, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, setMaxMsgSize, NULL, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouser", 0, eCmdHdlrUID, NULL, &uidDropPriv, NULL, eConfObjGlobal)); CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouserid", 0, eCmdHdlrInt, NULL, &uidDropPriv, NULL, eConfObjGlobal)); @@ -2189,9 +2160,6 @@ static rsRetVal mainThread() DEFiRet; uchar *pTmp; - /* we need to init the config object first! */ - CHKiRet(rsconf.Construct(&ourConf)); - /* initialize the build-in templates */ pTmp = template_DebugFormat; tplAddLine(ourConf, "RSYSLOG_DebugFormat", &pTmp); @@ -2260,7 +2228,7 @@ static rsRetVal mainThread() if(!(Debug == DEBUG_FULL || NoFork)) { close(1); close(2); - bErrMsgToStderr = 0; + ourConf->globals.bErrMsgToStderr = 0; } mainloop(); @@ -2743,6 +2711,9 @@ int realMain(int argc, char **argv) for(p = LocalDomain ; *p ; p++) *p = (char)tolower((int)*p); + /* we need to init the config object first! */ + CHKiRet(rsconf.Construct(&ourConf)); + /* we now have our hostname and can set it inside the global vars. * TODO: think if all of this would better be a runtime function * rgerhards, 2008-04-17 @@ -2758,7 +2729,7 @@ int realMain(int argc, char **argv) exit(1); /* "good" exit, leaving at init for fatal error */ } - if((iRet = loadBuildInModules()) != RS_RET_OK) { + if((iRet = loadBuildInModules(ourConf)) != RS_RET_OK) { fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n", iRet); exit(1); /* "good" exit, leaving at init for fatal error */ -- cgit v1.2.3 From 82fa17ae5621849790eb39ed046d58333ede347c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 21 Apr 2011 11:37:26 +0200 Subject: step: begun to create a "load" interface in rsconf --- tools/syslogd.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e0e5868b..1cf0b894 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -563,7 +563,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) * permits us to process unmodified config files which otherwise contain a * supressor statement. */ - if(((Debug == DEBUG_FULL || NoFork) && ourConf->globals.bErrMsgToStderr) || iConfigVerify) { + if(((Debug == DEBUG_FULL || NoFork) && runConf->globals.bErrMsgToStderr) || iConfigVerify) { if(LOG_PRI(pri) == LOG_ERR) fprintf(stderr, "rsyslogd: %s\n", msg); } @@ -809,7 +809,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) static void doFlushRptdMsgs(void) { - ruleset.IterateAllActions(ourConf, flushRptdMsgsActions, NULL); + ruleset.IterateAllActions(runConf, flushRptdMsgsActions, NULL); } @@ -1020,7 +1020,7 @@ freeAllDynMemForTermination(void) static inline void destructAllActions(void) { - ruleset.DestructAllActions(ourConf); + ruleset.DestructAllActions(runConf); bHaveMainQueue = 0; // flag that internal messages need to be temporarily stored } @@ -1058,7 +1058,8 @@ die(int sig) thrdTerminateAll(); /* and THEN send the termination log message (see long comment above) */ - if(sig && ourConf->globals.bLogStatusMsgs) { +dbgprintf("XXXX: runConf %p\n", runConf); + if(sig && runConf->globals.bLogStatusMsgs) { (void) snprintf(buf, sizeof(buf) / sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.", @@ -1085,7 +1086,7 @@ die(int sig) * ourselfs, this makes finding memory leaks a lot * easier. */ - tplDeleteAll(ourConf); + tplDeleteAll(runConf); /* de-init some modules */ modExitIminternal(); @@ -1598,11 +1599,7 @@ init(void) DEFiRet; DBGPRINTF("rsyslog %s - called init()\n", VERSION); - - /* construct the default ruleset */ - ruleset.Construct(&pRuleset); - ruleset.SetName(ourConf, pRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset")); - ruleset.ConstructFinalize(ourConf, pRuleset); +#if 1 /* open the configuration file */ localRet = conf.processConfFile(ourConf, ConfFile); @@ -1646,6 +1643,7 @@ init(void) } ruleset.AddRule(ourConf, ruleset.GetCurrent(ourConf), &pRule); } +#endif legacyOptsHook(); @@ -1721,6 +1719,7 @@ init(void) sigAct.sa_handler = sighup_handler; sigaction(SIGHUP, &sigAct, NULL); + CHKiRet(rsconf.Activate(ourConf)); DBGPRINTF(" started.\n"); /* we now generate the startup message. It now includes everything to @@ -2187,7 +2186,7 @@ static rsRetVal mainThread() CHKiRet(init()); if(Debug && debugging_on) { - DBGPRINTF("Debugging enabled, SIGUSR1 to turn off debugging.\n"); + dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); } /* Send a signal to the parent so it can terminate. @@ -2711,9 +2710,6 @@ int realMain(int argc, char **argv) for(p = LocalDomain ; *p ; p++) *p = (char)tolower((int)*p); - /* we need to init the config object first! */ - CHKiRet(rsconf.Construct(&ourConf)); - /* we now have our hostname and can set it inside the global vars. * TODO: think if all of this would better be a runtime function * rgerhards, 2008-04-17 @@ -2729,11 +2725,6 @@ int realMain(int argc, char **argv) exit(1); /* "good" exit, leaving at init for fatal error */ } - if((iRet = loadBuildInModules(ourConf)) != RS_RET_OK) { - fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n", - iRet); - exit(1); /* "good" exit, leaving at init for fatal error */ - } /* END core initializations - we now come back to carrying out command line options*/ @@ -2878,11 +2869,24 @@ int realMain(int argc, char **argv) if(iRet != RS_RET_END_OF_LINKEDLIST) FINALIZE; + CHKiRet(rsconf.Load(&ourConf, ConfFile)); + + + + /* begin config load */ + if((iRet = loadBuildInModules(ourConf)) != RS_RET_OK) { + fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n", + iRet); + exit(1); /* "good" exit, leaving at init for fatal error */ + } if(iConfigVerify) { fprintf(stderr, "rsyslogd: version %s, config validation run (level %d), master config %s\n", VERSION, iConfigVerify, ConfFile); } + + + if(bChDirRoot) { if(chdir("/") != 0) fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); -- cgit v1.2.3 From 13ecf8a6ef5a5b69819865a2b9b524d4c561f5de Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 21 Apr 2011 14:27:41 +0200 Subject: step: config handler setting from syslogd.c moved to rsconf.c --- tools/syslogd.c | 392 ++++++-------------------------------------------------- 1 file changed, 41 insertions(+), 351 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 1cf0b894..409bb4f9 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -238,8 +238,6 @@ legacyOptsLL_t *pLegacyOptsLL = NULL; int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is the default, so if no -c option is given, we make ourselvs as compatible to sysklogd as possible. */ -int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ -int bAbortOnUncleanConfig = 0; /* abort run (rather than starting with partial config) if there was any issue in conf */ /* end global config file state variables */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ @@ -249,73 +247,11 @@ static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - * If the main queue is either not yet ready or not running in * queueing mode (mode DIRECT!), then this is set to 0. */ -static int uidDropPriv = 0; /* user-id to which priveleges should be dropped to (AFTER init()!) */ -static int gidDropPriv = 0; /* group-id to which priveleges should be dropped to (AFTER init()!) */ extern int errno; -static uchar *pszConfDAGFile = NULL; /* name of config DAG file, non-NULL means generate one */ /* main message queue and its configuration parameters */ qqueue_t *pMsgQueue = NULL; /* the main message queue */ -static int iMainMsgQueueSize = 10000; /* size of the main message queue above */ -static int iMainMsgQHighWtrMark = 8000; /* high water mark for disk-assisted queues */ -static int iMainMsgQLowWtrMark = 2000; /* low water mark for disk-assisted queues */ -static int iMainMsgQDiscardMark = 9800; /* begin to discard messages */ -static int iMainMsgQDiscardSeverity = 8; /* by default, discard nothing to prevent unintentional loss */ -static int iMainMsgQueueNumWorkers = 1; /* number of worker threads for the mm queue above */ -static queueType_t MainMsgQueType = QUEUETYPE_FIXED_ARRAY; /* type of the main message queue above */ -static uchar *pszMainMsgQFName = NULL; /* prefix for the main message queue file */ -static int64 iMainMsgQueMaxFileSize = 1024*1024; -static int iMainMsgQPersistUpdCnt = 0; /* persist queue info every n updates */ -static int bMainMsgQSyncQeueFiles = 0; /* sync queue files on every write? */ -static int iMainMsgQtoQShutdown = 1500; /* queue shutdown (ms) */ -static int iMainMsgQtoActShutdown = 1000; /* action shutdown (in phase 2) */ -static int iMainMsgQtoEnq = 2000; /* timeout for queue enque */ -static int iMainMsgQtoWrkShutdown = 60000; /* timeout for worker thread shutdown */ -static int iMainMsgQWrkMinMsgs = 100; /* minimum messages per worker needed to start a new one */ -static int iMainMsgQDeqSlowdown = 0; /* dequeue slowdown (simple rate limiting) */ -static int64 iMainMsgQueMaxDiskSpace = 0; /* max disk space allocated 0 ==> unlimited */ -static int64 iMainMsgQueDeqBatchSize = 32; /* dequeue batch size */ -static int bMainMsgQSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */ -static int iMainMsgQueueDeqtWinFromHr = 0; /* hour begin of time frame when queue is to be dequeued */ -static int iMainMsgQueueDeqtWinToHr = 25; /* hour begin of time frame when queue is to be dequeued */ - - -/* Reset config variables to default values. - * rgerhards, 2007-07-17 - */ -static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) -{ - ourConf->globals.bLogStatusMsgs = DFLT_bLogStatusMsgs; - ourConf->globals.bDebugPrintTemplateList = 1; - ourConf->globals.bDebugPrintCfSysLineHandlerList = 1; - ourConf->globals.bDebugPrintModuleList = 1; - bReduceRepeatMsgs = 0; - bAbortOnUncleanConfig = 0; - free(pszMainMsgQFName); - pszMainMsgQFName = NULL; - iMainMsgQueueSize = 10000; - iMainMsgQHighWtrMark = 8000; - iMainMsgQLowWtrMark = 2000; - iMainMsgQDiscardMark = 9800; - iMainMsgQDiscardSeverity = 8; - iMainMsgQueMaxFileSize = 1024 * 1024; - iMainMsgQueueNumWorkers = 1; - iMainMsgQPersistUpdCnt = 0; - bMainMsgQSyncQeueFiles = 0; - iMainMsgQtoQShutdown = 1500; - iMainMsgQtoActShutdown = 1000; - iMainMsgQtoEnq = 2000; - iMainMsgQtoWrkShutdown = 60000; - iMainMsgQWrkMinMsgs = 100; - iMainMsgQDeqSlowdown = 0; - bMainMsgQSaveOnShutdown = 1; - MainMsgQueType = QUEUETYPE_FIXED_ARRAY; - iMainMsgQueMaxDiskSpace = 0; - iMainMsgQueDeqBatchSize = 32; - - return RS_RET_OK; -} /* hardcoded standard templates (used for defaults) */ @@ -1009,9 +945,7 @@ static void doDie(int sig) static void freeAllDynMemForTermination(void) { - free(pszMainMsgQFName); - free(pModDir); - free(pszConfDAGFile); + free(ourConf->globals.pszConfDAGFile); } @@ -1058,7 +992,6 @@ die(int sig) thrdTerminateAll(); /* and THEN send the termination log message (see long comment above) */ -dbgprintf("XXXX: runConf %p\n", runConf); if(sig && runConf->globals.bLogStatusMsgs) { (void) snprintf(buf, sizeof(buf) / sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ @@ -1138,59 +1071,6 @@ static void doexit() } -/* set the maximum message size */ -static rsRetVal setMaxMsgSize(void __attribute__((unused)) *pVal, long iNewVal) -{ - return glbl.SetMaxLine(iNewVal); -} - - -/* set the action resume interval */ -static rsRetVal setActionResumeInterval(void __attribute__((unused)) *pVal, int iNewVal) -{ - return actionSetGlobalResumeInterval(iNewVal); -} - - -/* set the processes max number ob files (upon configuration request) - * 2009-04-14 rgerhards - */ -static rsRetVal setMaxFiles(void __attribute__((unused)) *pVal, int iFiles) -{ - struct rlimit maxFiles; - char errStr[1024]; - DEFiRet; - - maxFiles.rlim_cur = iFiles; - maxFiles.rlim_max = iFiles; - - if(setrlimit(RLIMIT_NOFILE, &maxFiles) < 0) { - /* NOTE: under valgrind, we seem to be unable to extend the size! */ - rs_strerror_r(errno, errStr, sizeof(errStr)); - errmsg.LogError(0, RS_RET_ERR_RLIM_NOFILE, "could not set process file limit to %d: %s [kernel max %ld]", - iFiles, errStr, (long) maxFiles.rlim_max); - ABORT_FINALIZE(RS_RET_ERR_RLIM_NOFILE); - } -#ifdef USE_UNLIMITED_SELECT - glbl.SetFdSetSize(howmany(iFiles, __NFDBITS) * sizeof (fd_mask)); -#endif - DBGPRINTF("Max number of files set to %d [kernel max %ld].\n", iFiles, (long) maxFiles.rlim_max); - -finalize_it: - RETiRet; -} - - -/* set the processes umask (upon configuration request) */ -static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask) -{ - umask(iUmask); - DBGPRINTF("umask set to 0%3.3o.\n", iUmask); - - return RS_RET_OK; -} - - /* drop to specified group * if something goes wrong, the function never returns * Note that such an abort can cause damage to on-disk structures, so we should @@ -1441,25 +1321,6 @@ static void dbgPrintInitInfo(void) DBGPRINTF("Messages with malicious PTR DNS Records are %sdropped.\n", glbl.GetDropMalPTRMsgs() ? "" : "not "); - DBGPRINTF("Main queue size %d messages.\n", iMainMsgQueueSize); - DBGPRINTF("Main queue worker threads: %d, wThread shutdown: %d, Perists every %d updates.\n", - iMainMsgQueueNumWorkers, iMainMsgQtoWrkShutdown, iMainMsgQPersistUpdCnt); - DBGPRINTF("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n", - iMainMsgQtoQShutdown, iMainMsgQtoActShutdown, iMainMsgQtoEnq); - DBGPRINTF("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n", - iMainMsgQHighWtrMark, iMainMsgQLowWtrMark, iMainMsgQDiscardMark, iMainMsgQDiscardSeverity); - DBGPRINTF("Main queue save on shutdown %d, max disk space allowed %lld\n", - bMainMsgQSaveOnShutdown, iMainMsgQueMaxDiskSpace); - /* TODO: add - iActionRetryCount = 0; - iActionRetryInterval = 30000; - static int iMainMsgQtoWrkMinMsgs = 100; - static int iMainMsgQbSaveOnShutdown = 1; - iMainMsgQueMaxDiskSpace = 0; - setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100); - setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", 1); - */ - DBGPRINTF("Work Directory: '%s'.\n", glbl.GetWorkDir()); } @@ -1528,12 +1389,12 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) DEFiRet; /* switch the message object to threaded operation, if necessary */ - if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) { + if(ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT || ourConf->globals.mainQ.iMainMsgQueueNumWorkers > 1) { MsgEnableThreadSafety(); } /* create message queue */ - CHKiRet_Hdlr(qqueueConstruct(ppQueue, MainMsgQueType, iMainMsgQueueNumWorkers, iMainMsgQueueSize, msgConsumer)) { + CHKiRet_Hdlr(qqueueConstruct(ppQueue, ourConf->globals.mainQ.MainMsgQueType, ourConf->globals.mainQ.iMainMsgQueueNumWorkers, ourConf->globals.mainQ.iMainMsgQueueSize, msgConsumer)) { /* no queue is fatal, we need to give up in that case... */ errmsg.LogError(0, iRet, "could not create (ruleset) main message queue"); \ } @@ -1550,25 +1411,25 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ } - setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", iMainMsgQueMaxFileSize); - setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", iMainMsgQueMaxDiskSpace); - setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", iMainMsgQueDeqBatchSize); - setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", pszMainMsgQFName); - setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", iMainMsgQPersistUpdCnt); - setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", bMainMsgQSyncQeueFiles); - setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", iMainMsgQtoQShutdown ); - setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", iMainMsgQtoActShutdown); - setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", iMainMsgQtoWrkShutdown); - setQPROP(qqueueSettoEnq, "$MainMsgQueueTimeoutEnqueue", iMainMsgQtoEnq); - setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark); - setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark); - setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark); - setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity); - setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); - setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); - setQPROP(qqueueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", iMainMsgQDeqSlowdown); - setQPROP(qqueueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", iMainMsgQueueDeqtWinFromHr); - setQPROP(qqueueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", iMainMsgQueueDeqtWinToHr); + setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", ourConf->globals.mainQ.iMainMsgQueMaxFileSize); + setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", ourConf->globals.mainQ.iMainMsgQueMaxDiskSpace); + setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", ourConf->globals.mainQ.iMainMsgQueDeqBatchSize); + setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", ourConf->globals.mainQ.pszMainMsgQFName); + setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", ourConf->globals.mainQ.iMainMsgQPersistUpdCnt); + setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", ourConf->globals.mainQ.bMainMsgQSyncQeueFiles); + setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", ourConf->globals.mainQ.iMainMsgQtoQShutdown ); + setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", ourConf->globals.mainQ.iMainMsgQtoActShutdown); + setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", ourConf->globals.mainQ.iMainMsgQtoWrkShutdown); + setQPROP(qqueueSettoEnq, "$MainMsgQueueTimeoutEnqueue", ourConf->globals.mainQ.iMainMsgQtoEnq); + setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", ourConf->globals.mainQ.iMainMsgQHighWtrMark); + setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", ourConf->globals.mainQ.iMainMsgQLowWtrMark); + setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", ourConf->globals.mainQ.iMainMsgQDiscardMark); + setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", ourConf->globals.mainQ.iMainMsgQDiscardSeverity); + setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", ourConf->globals.mainQ.iMainMsgQWrkMinMsgs); + setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", ourConf->globals.mainQ.bMainMsgQSaveOnShutdown); + setQPROP(qqueueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", ourConf->globals.mainQ.iMainMsgQDeqSlowdown); + setQPROP(qqueueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", ourConf->globals.mainQ.iMainMsgQueueDeqtWinFromHr); + setQPROP(qqueueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", ourConf->globals.mainQ.iMainMsgQueueDeqtWinToHr); # undef setQPROP # undef setQPROPstr @@ -1592,7 +1453,6 @@ init(void) rsRetVal localRet; int iNbrActions; int bHadConfigErr = 0; - ruleset_t *pRuleset; char cbuf[BUFSIZ]; char bufStartUpMsg[512]; struct sigaction sigAct; @@ -1648,28 +1508,28 @@ init(void) legacyOptsHook(); /* some checks */ - if(iMainMsgQueueNumWorkers < 1) { + if(ourConf->globals.mainQ.iMainMsgQueueNumWorkers < 1) { errmsg.LogError(0, NO_ERRCODE, "$MainMsgQueueNumWorkers must be at least 1! Set to 1.\n"); - iMainMsgQueueNumWorkers = 1; + ourConf->globals.mainQ.iMainMsgQueueNumWorkers = 1; } - if(MainMsgQueType == QUEUETYPE_DISK) { + if(ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DISK) { errno = 0; /* for logerror! */ if(glbl.GetWorkDir() == NULL) { errmsg.LogError(0, NO_ERRCODE, "No $WorkDirectory specified - can not run main message queue in 'disk' mode. " "Using 'FixedArray' instead.\n"); - MainMsgQueType = QUEUETYPE_FIXED_ARRAY; + ourConf->globals.mainQ.MainMsgQueType = QUEUETYPE_FIXED_ARRAY; } - if(pszMainMsgQFName == NULL) { + if(ourConf->globals.mainQ.pszMainMsgQFName == NULL) { errmsg.LogError(0, NO_ERRCODE, "No $MainMsgQueueFileName specified - can not run main message queue in " "'disk' mode. Using 'FixedArray' instead.\n"); - MainMsgQueType = QUEUETYPE_FIXED_ARRAY; + ourConf->globals.mainQ.MainMsgQueType = QUEUETYPE_FIXED_ARRAY; } } /* check if we need to generate a config DAG and, if so, do that */ - if(pszConfDAGFile != NULL) - generateConfigDAG(pszConfDAGFile); + if(ourConf->globals.pszConfDAGFile != NULL) + generateConfigDAG(ourConf->globals.pszConfDAGFile); /* we are done checking the config - now validate if we should actually run or not. * If not, terminate. -- rgerhards, 2008-07-25 @@ -1682,7 +1542,8 @@ init(void) ABORT_FINALIZE(RS_RET_VALIDATION_RUN); } - if(bAbortOnUncleanConfig && bHadConfigErr) { +#warning restructure following if to use return value of loadConf + if(loadConf->globals.bAbortOnUncleanConfig && bHadConfigErr) { fprintf(stderr, "rsyslogd: $AbortOnUncleanConfig is set, and config is not clean.\n" "Check error log for details, fix errors and restart. As a last\n" "resort, you may want to remove $AbortOnUncleanConfig to permit a\n" @@ -1697,7 +1558,7 @@ init(void) exit(1); } - bHaveMainQueue = (MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1; + bHaveMainQueue = (ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1; DBGPRINTF("Main processing queue is initialized and running\n"); /* the output part and the queue is now ready to run. So it is a good time @@ -1738,81 +1599,6 @@ finalize_it: } -/* Switch the default ruleset (that, what servcies bind to if nothing specific - * is specified). - * rgerhards, 2009-06-12 - */ -static rsRetVal -setDefaultRuleset(void __attribute__((unused)) *pVal, uchar *pszName) -{ - DEFiRet; - - CHKiRet(ruleset.SetDefaultRuleset(ourConf, pszName)); - -finalize_it: - free(pszName); /* no longer needed */ - RETiRet; -} - - -/* Switch to either an already existing rule set or start a new one. The - * named rule set becomes the new "current" rule set (what means that new - * actions are added to it). - * rgerhards, 2009-06-12 - */ -static rsRetVal -setCurrRuleset(void __attribute__((unused)) *pVal, uchar *pszName) -{ - ruleset_t *pRuleset; - rsRetVal localRet; - DEFiRet; - - localRet = ruleset.SetCurrRuleset(ourConf, pszName); - - if(localRet == RS_RET_NOT_FOUND) { - DBGPRINTF("begin new current rule set '%s'\n", pszName); - CHKiRet(ruleset.Construct(&pRuleset)); - CHKiRet(ruleset.SetName(ourConf, pRuleset, pszName)); - CHKiRet(ruleset.ConstructFinalize(ourConf, pRuleset)); - } else { - ABORT_FINALIZE(localRet); - } - -finalize_it: - free(pszName); /* no longer needed */ - RETiRet; -} - - -/* set the main message queue mode - * rgerhards, 2008-01-03 - */ -static rsRetVal setMainMsgQueType(void __attribute__((unused)) *pVal, uchar *pszType) -{ - DEFiRet; - - if (!strcasecmp((char *) pszType, "fixedarray")) { - MainMsgQueType = QUEUETYPE_FIXED_ARRAY; - DBGPRINTF("main message queue type set to FIXED_ARRAY\n"); - } else if (!strcasecmp((char *) pszType, "linkedlist")) { - MainMsgQueType = QUEUETYPE_LINKEDLIST; - DBGPRINTF("main message queue type set to LINKEDLIST\n"); - } else if (!strcasecmp((char *) pszType, "disk")) { - MainMsgQueType = QUEUETYPE_DISK; - DBGPRINTF("main message queue type set to DISK\n"); - } else if (!strcasecmp((char *) pszType, "direct")) { - MainMsgQueType = QUEUETYPE_DIRECT; - DBGPRINTF("main message queue type set to DIRECT (no queueing at all)\n"); - } else { - errmsg.LogError(0, RS_RET_INVALID_PARAMS, "unknown mainmessagequeuetype parameter: %s", (char *) pszType); - iRet = RS_RET_INVALID_PARAMS; - } - free(pszType); /* no longer needed */ - - RETiRet; -} - - /* * The following function is resposible for handling a SIGHUP signal. Since * we are now doing mallocs/free as part of init we had better not being @@ -1913,7 +1699,7 @@ mainloop(void) * powertop, for example). In that case, we primarily wait for a signal, * but a once-a-day wakeup should be quite acceptable. -- rgerhards, 2008-06-09 */ - tvSelectTimeout.tv_sec = (bReduceRepeatMsgs == 1) ? TIMERINTVL : 86400 /*1 day*/; + tvSelectTimeout.tv_sec = (runConf->globals.bReduceRepeatMsgs == 1) ? TIMERINTVL : 86400 /*1 day*/; //tvSelectTimeout.tv_sec = TIMERINTVL; /* TODO: change this back to the above code when we have a better solution for apc */ tvSelectTimeout.tv_usec = 0; select(1, NULL, NULL, NULL, &tvSelectTimeout); @@ -1941,7 +1727,7 @@ mainloop(void) * for the time being, I think the remaining risk can be accepted. * rgerhards, 2008-01-10 */ - if(bReduceRepeatMsgs == 1) + if(runConf->globals.bReduceRepeatMsgs == 1) doFlushRptdMsgs(); if(bHadHUP) { @@ -1954,49 +1740,10 @@ mainloop(void) ENDfunc } - -/* this method is needed to shuffle the current conf object down to the - * IncludeConfig handler. - */ -static rsRetVal -doNameLine(void *pVal, uchar *pNewVal) -{ - DEFiRet; - iRet = conf.doNameLine(ourConf, pVal, pNewVal); - free(pNewVal); - RETiRet; -} - - -/* this method is needed to shuffle the current conf object down to the - * IncludeConfig handler. - */ -static rsRetVal -doModLoad(void *pVal, uchar *pNewVal) -{ - DEFiRet; - iRet = conf.doModLoad(ourConf, pVal, pNewVal); - free(pNewVal); - RETiRet; -} - - -/* this method is needed to shuffle the current conf object down to the - * IncludeConfig handler. - */ -static rsRetVal -doIncludeLine(void *pVal, uchar *pNewVal) -{ - DEFiRet; - iRet = conf.doIncludeLine(ourConf, pVal, pNewVal); - free(pNewVal); - RETiRet; -} - /* load build-in modules * very first version begun on 2007-07-23 by rgerhards */ -static rsRetVal loadBuildInModules(rsconf_t *config) +static rsRetVal loadBuildInModules() { DEFiRet; @@ -2043,63 +1790,6 @@ static rsRetVal loadBuildInModules(rsconf_t *config) CHKiRet(module.doModInit(modInitsmfwd, UCHAR_CONSTANT("builtin-smfwd"), NULL)); CHKiRet(module.doModInit(modInitsmtradfwd, UCHAR_CONSTANT("builtin-smtradfwd"), 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 - * being, the code has found its home here. A not-just-sideeffect of this decision - * is that rsyslog will terminate if we can not register our built-in config commands. - * This, I think, is the right thing to do. -- rgerhards, 2007-07-31 - */ - CHKiRet(regCfSysLineHdlr((uchar *)"logrsyslogstatusmessages", 0, eCmdHdlrBinary, NULL, &ourConf->globals.bLogStatusMsgs, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"defaultruleset", 0, eCmdHdlrGetWord, setDefaultRuleset, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, setCurrRuleset, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"sleep", 0, eCmdHdlrGoneAway, NULL, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuelowwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQLowWtrMark, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardmark", 0, eCmdHdlrInt, NULL, &iMainMsgQDiscardMark, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardseverity", 0, eCmdHdlrSeverity, NULL, &iMainMsgQDiscardSeverity, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuecheckpointinterval", 0, eCmdHdlrInt, NULL, &iMainMsgQPersistUpdCnt, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesyncqueuefiles", 0, eCmdHdlrBinary, NULL, &bMainMsgQSyncQeueFiles, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetype", 0, eCmdHdlrGetWord, setMainMsgQueType, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreads", 0, eCmdHdlrInt, NULL, &iMainMsgQueueNumWorkers, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoQShutdown, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutactioncompletion", 0, eCmdHdlrInt, NULL, &iMainMsgQtoActShutdown, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutenqueue", 0, eCmdHdlrInt, NULL, &iMainMsgQtoEnq, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkertimeoutthreadshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoWrkShutdown, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeueslowdown", 0, eCmdHdlrInt, NULL, &iMainMsgQDeqSlowdown, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreadminimummessages", 0, eCmdHdlrInt, NULL, &iMainMsgQWrkMinMsgs, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxfilesize", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxFileSize, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuebatchsize", 0, eCmdHdlrSize, NULL, &iMainMsgQueDeqBatchSize, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxdiskspace", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxDiskSpace, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesaveonshutdown", 0, eCmdHdlrBinary, NULL, &bMainMsgQSaveOnShutdown, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimebegin", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinFromHr, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinToHr, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"abortonuncleanconfig", 0, eCmdHdlrBinary, NULL, &bAbortOnUncleanConfig, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_TEMPLATE, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_OUTCHANNEL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_ALLOWEDSENDER, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, doModLoad, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, doIncludeLine, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"maxopenfiles", 0, eCmdHdlrInt, setMaxFiles, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &(config->globals.bDebugPrintTemplateList), NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &(config->globals.bDebugPrintModuleList), NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"debugprintcfsyslinehandlerlist", 0, eCmdHdlrBinary, - NULL, &(config->globals.bDebugPrintCfSysLineHandlerList), NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"generateconfiggraph", 0, eCmdHdlrGetWord, NULL, &pszConfDAGFile, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &ourConf->globals.bErrMsgToStderr, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, setMaxMsgSize, NULL, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouser", 0, eCmdHdlrUID, NULL, &uidDropPriv, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouserid", 0, eCmdHdlrInt, NULL, &uidDropPriv, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroup", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL, eConfObjGlobal)); - CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroupid", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL, eConfObjGlobal)); - finalize_it: RETiRet; } @@ -2202,12 +1892,12 @@ static rsRetVal mainThread() * drop privileges at all. Doing it correctly, requires a change in architecture, which * we should do over time. TODO -- rgerhards, 2008-11-19 */ - if(gidDropPriv != 0) { - doDropPrivGid(gidDropPriv); + if(ourConf->globals.gidDropPriv != 0) { + doDropPrivGid(ourConf->globals.gidDropPriv); } - if(uidDropPriv != 0) { - doDropPrivUid(uidDropPriv); + if(ourConf->globals.uidDropPriv != 0) { + doDropPrivUid(ourConf->globals.uidDropPriv); } /* finally let the inputs run... */ @@ -2874,7 +2564,7 @@ int realMain(int argc, char **argv) /* begin config load */ - if((iRet = loadBuildInModules(ourConf)) != RS_RET_OK) { + if((iRet = loadBuildInModules()) != RS_RET_OK) { fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n", iRet); exit(1); /* "good" exit, leaving at init for fatal error */ -- cgit v1.2.3 From 115b15a568c050950517b8bedf067c89b3b7ac30 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 26 Apr 2011 17:10:36 +0200 Subject: shuffled even more config code from syslgod to config handler --- tools/syslogd.c | 167 +------------------------------------------------------- 1 file changed, 1 insertion(+), 166 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 409bb4f9..0dbb3c06 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -108,18 +108,6 @@ #include "action.h" #include "iminternal.h" #include "cfsysline.h" -#include "omshell.h" -#include "omusrmsg.h" -#include "omfwd.h" -#include "omfile.h" -#include "ompipe.h" -#include "omdiscard.h" -#include "pmrfc5424.h" -#include "pmrfc3164.h" -#include "smfile.h" -#include "smtradfile.h" -#include "smfwd.h" -#include "smtradfwd.h" #include "threads.h" #include "wti.h" #include "queue.h" @@ -254,21 +242,6 @@ extern int errno; qqueue_t *pMsgQueue = NULL; /* the main message queue */ -/* hardcoded standard templates (used for defaults) */ -static uchar template_DebugFormat[] = "\"Debug line with all properties:\nFROMHOST: '%FROMHOST%', fromhost-ip: '%fromhost-ip%', HOSTNAME: '%HOSTNAME%', PRI: %PRI%,\nsyslogtag '%syslogtag%', programname: '%programname%', APP-NAME: '%APP-NAME%', PROCID: '%PROCID%', MSGID: '%MSGID%',\nTIMESTAMP: '%TIMESTAMP%', STRUCTURED-DATA: '%STRUCTURED-DATA%',\nmsg: '%msg%'\nescaped msg: '%msg:::drop-cc%'\ninputname: %inputname% rawmsg: '%rawmsg%'\n\n\""; -static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n\""; -static uchar template_TraditionalFileFormat[] = "=RSYSLOG_TraditionalFileFormat"; -static uchar template_FileFormat[] = "=RSYSLOG_FileFormat"; -static uchar template_ForwardFormat[] = "=RSYSLOG_ForwardFormat"; -static uchar template_TraditionalForwardFormat[] = "=RSYSLOG_TraditionalForwardFormat"; -static uchar template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r\""; -static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\""; -static uchar template_StdDBFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')\",SQL"; -static uchar template_StdPgSQLFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%')\",STDSQL"; -static uchar template_spoofadr[] = "\"%fromhost-ip%\""; -/* end templates */ - - /* up to the next comment, prototypes that should be removed by reordering */ /* Function prototypes. */ static char **crunch_list(char *list); @@ -499,7 +472,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) * permits us to process unmodified config files which otherwise contain a * supressor statement. */ - if(((Debug == DEBUG_FULL || NoFork) && runConf->globals.bErrMsgToStderr) || iConfigVerify) { + if(((Debug == DEBUG_FULL || NoFork) && ourConf->globals.bErrMsgToStderr) || iConfigVerify) { if(LOG_PRI(pri) == LOG_ERR) fprintf(stderr, "rsyslogd: %s\n", msg); } @@ -1458,53 +1431,6 @@ init(void) struct sigaction sigAct; DEFiRet; - DBGPRINTF("rsyslog %s - called init()\n", VERSION); -#if 1 - - /* open the configuration file */ - localRet = conf.processConfFile(ourConf, ConfFile); - CHKiRet(conf.GetNbrActActions(ourConf, &iNbrActions)); - - dbgprintf("rsyslog finished loading initial config %p\n", ourConf); - rsconf.DebugPrint(ourConf); - - if(localRet != RS_RET_OK) { - errmsg.LogError(0, localRet, "CONFIG ERROR: could not interpret master config file '%s'.", ConfFile); - bHadConfigErr = 1; - } else if(iNbrActions == 0) { - errmsg.LogError(0, RS_RET_NO_ACTIONS, "CONFIG ERROR: there are no active actions configured. Inputs will " - "run, but no output whatsoever is created."); - bHadConfigErr = 1; - } - - if((localRet != RS_RET_OK && localRet != RS_RET_NONFATAL_CONFIG_ERR) || iNbrActions == 0) { - /* rgerhards: this code is executed to set defaults when the - * config file could not be opened. We might think about - * abandoning the run in this case - but this, too, is not - * very clever... So we stick with what we have. - * We ignore any errors while doing this - we would be lost anyhow... - */ - errmsg.LogError(0, NO_ERRCODE, "EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file!"); - - /* note: we previously used _POSIY_TTY_NAME_MAX+1, but this turned out to be - * too low on linux... :-S -- rgerhards, 2008-07-28 - */ - char szTTYNameBuf[128]; - rule_t *pRule = NULL; /* initialization to NULL is *vitally* important! */ - conf.cfline(ourConf, UCHAR_CONSTANT("*.ERR\t" _PATH_CONSOLE), &pRule); - conf.cfline(ourConf, UCHAR_CONSTANT("syslog.*\t" _PATH_CONSOLE), &pRule); - conf.cfline(ourConf, UCHAR_CONSTANT("*.PANIC\t*"), &pRule); - conf.cfline(ourConf, UCHAR_CONSTANT("syslog.*\troot"), &pRule); - if(ttyname_r(0, szTTYNameBuf, sizeof(szTTYNameBuf)) == 0) { - snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf); - conf.cfline(ourConf, (uchar*)cbuf, &pRule); - } else { - DBGPRINTF("error %d obtaining controlling terminal, not using that emergency rule\n", errno); - } - ruleset.AddRule(ourConf, ruleset.GetCurrent(ourConf), &pRule); - } -#endif - legacyOptsHook(); /* some checks */ @@ -1740,61 +1666,6 @@ mainloop(void) ENDfunc } -/* load build-in modules - * very first version begun on 2007-07-23 by rgerhards - */ -static rsRetVal loadBuildInModules() -{ - DEFiRet; - - if((iRet = module.doModInit(modInitFile, UCHAR_CONSTANT("builtin-file"), NULL)) != RS_RET_OK) { - RETiRet; - } - if((iRet = module.doModInit(modInitPipe, UCHAR_CONSTANT("builtin-pipe"), NULL)) != RS_RET_OK) { - RETiRet; - } -#ifdef SYSLOG_INET - if((iRet = module.doModInit(modInitFwd, UCHAR_CONSTANT("builtin-fwd"), NULL)) != RS_RET_OK) { - RETiRet; - } -#endif - if((iRet = module.doModInit(modInitShell, UCHAR_CONSTANT("builtin-shell"), NULL)) != RS_RET_OK) { - RETiRet; - } - if((iRet = module.doModInit(modInitDiscard, UCHAR_CONSTANT("builtin-discard"), NULL)) != RS_RET_OK) { - RETiRet; - } - - /* dirty, but this must be for the time being: the usrmsg module must always be - * loaded as last module. This is because it processes any type of action selector. - * If we load it before other modules, these others will never have a chance of - * working with the config file. We may change that implementation so that a user name - * must start with an alnum, that would definitely help (but would it break backwards - * compatibility?). * rgerhards, 2007-07-23 - * User names now must begin with: - * [a-zA-Z0-9_.] - */ - CHKiRet(module.doModInit(modInitUsrMsg, (uchar*) "builtin-usrmsg", NULL)); - - /* load build-in parser modules */ - CHKiRet(module.doModInit(modInitpmrfc5424, UCHAR_CONSTANT("builtin-pmrfc5424"), NULL)); - CHKiRet(module.doModInit(modInitpmrfc3164, UCHAR_CONSTANT("builtin-pmrfc3164"), NULL)); - - /* and set default parser modules (order is *very* important, legacy (3164) parse needs to go last! */ - CHKiRet(parser.AddDfltParser(UCHAR_CONSTANT("rsyslog.rfc5424"))); - CHKiRet(parser.AddDfltParser(UCHAR_CONSTANT("rsyslog.rfc3164"))); - - /* load build-in strgen modules */ - CHKiRet(module.doModInit(modInitsmfile, UCHAR_CONSTANT("builtin-smfile"), NULL)); - CHKiRet(module.doModInit(modInitsmtradfile, UCHAR_CONSTANT("builtin-smtradfile"), NULL)); - CHKiRet(module.doModInit(modInitsmfwd, UCHAR_CONSTANT("builtin-smfwd"), NULL)); - CHKiRet(module.doModInit(modInitsmtradfwd, UCHAR_CONSTANT("builtin-smtradfwd"), NULL)); - -finalize_it: - RETiRet; -} - - /* print version and compile-time setting information. */ static void printVersion(void) @@ -1847,31 +1718,6 @@ static void printVersion(void) static rsRetVal mainThread() { DEFiRet; - uchar *pTmp; - - /* initialize the build-in templates */ - pTmp = template_DebugFormat; - tplAddLine(ourConf, "RSYSLOG_DebugFormat", &pTmp); - pTmp = template_SyslogProtocol23Format; - tplAddLine(ourConf, "RSYSLOG_SyslogProtocol23Format", &pTmp); - pTmp = template_FileFormat; /* new format for files with high-precision stamp */ - tplAddLine(ourConf, "RSYSLOG_FileFormat", &pTmp); - pTmp = template_TraditionalFileFormat; - tplAddLine(ourConf, "RSYSLOG_TraditionalFileFormat", &pTmp); - pTmp = template_WallFmt; - tplAddLine(ourConf, " WallFmt", &pTmp); - pTmp = template_ForwardFormat; - tplAddLine(ourConf, "RSYSLOG_ForwardFormat", &pTmp); - pTmp = template_TraditionalForwardFormat; - tplAddLine(ourConf, "RSYSLOG_TraditionalForwardFormat", &pTmp); - pTmp = template_StdUsrMsgFmt; - tplAddLine(ourConf, " StdUsrMsgFmt", &pTmp); - pTmp = template_StdDBFmt; - tplAddLine(ourConf, " StdDBFmt", &pTmp); - pTmp = template_StdPgSQLFmt; - tplAddLine(ourConf, " StdPgSQLFmt", &pTmp); - pTmp = template_spoofadr; - tplLastStaticInit(ourConf, tplAddLine(ourConf, "RSYSLOG_omudpspoofDfltSourceTpl", &pTmp)); CHKiRet(init()); @@ -2561,22 +2407,11 @@ int realMain(int argc, char **argv) CHKiRet(rsconf.Load(&ourConf, ConfFile)); - - - /* begin config load */ - if((iRet = loadBuildInModules()) != RS_RET_OK) { - fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n", - iRet); - exit(1); /* "good" exit, leaving at init for fatal error */ - } if(iConfigVerify) { fprintf(stderr, "rsyslogd: version %s, config validation run (level %d), master config %s\n", VERSION, iConfigVerify, ConfFile); } - - - if(bChDirRoot) { if(chdir("/") != 0) fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); -- cgit v1.2.3 From 8fb8c0d37b68d633e562bbc96f9971917620d181 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 26 Apr 2011 17:21:44 +0200 Subject: step: moved config validation code --- tools/syslogd.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 0dbb3c06..63eb55b9 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1433,26 +1433,6 @@ init(void) legacyOptsHook(); - /* some checks */ - if(ourConf->globals.mainQ.iMainMsgQueueNumWorkers < 1) { - errmsg.LogError(0, NO_ERRCODE, "$MainMsgQueueNumWorkers must be at least 1! Set to 1.\n"); - ourConf->globals.mainQ.iMainMsgQueueNumWorkers = 1; - } - - if(ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DISK) { - errno = 0; /* for logerror! */ - if(glbl.GetWorkDir() == NULL) { - errmsg.LogError(0, NO_ERRCODE, "No $WorkDirectory specified - can not run main message queue in 'disk' mode. " - "Using 'FixedArray' instead.\n"); - ourConf->globals.mainQ.MainMsgQueType = QUEUETYPE_FIXED_ARRAY; - } - if(ourConf->globals.mainQ.pszMainMsgQFName == NULL) { - errmsg.LogError(0, NO_ERRCODE, "No $MainMsgQueueFileName specified - can not run main message queue in " - "'disk' mode. Using 'FixedArray' instead.\n"); - ourConf->globals.mainQ.MainMsgQueType = QUEUETYPE_FIXED_ARRAY; - } - } - /* check if we need to generate a config DAG and, if so, do that */ if(ourConf->globals.pszConfDAGFile != NULL) generateConfigDAG(ourConf->globals.pszConfDAGFile); -- cgit v1.2.3 From 19c8bed08dbeb9ce0313ec92d7de85c9c51c4f48 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 26 Apr 2011 17:30:59 +0200 Subject: step: outchannel list integrated into main config object --- tools/syslogd.c | 61 +++++++++++++++++++-------------------------------------- 1 file changed, 20 insertions(+), 41 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 63eb55b9..318031a1 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1280,23 +1280,6 @@ finalize_it: } -/* print debug information as part of init(). This pretty much - * outputs the whole config of rsyslogd. I've moved this code - * out of init() to clean it somewhat up. - * rgerhards, 2007-07-31 - */ -static void dbgPrintInitInfo(void) -{ - dbgprintf("The following is the old-style, to-be-replaced, current config dump at the end " - " of the config load process ;)\n"); - ochPrintList(); - - DBGPRINTF("Messages with malicious PTR DNS Records are %sdropped.\n", - glbl.GetDropMalPTRMsgs() ? "" : "not "); - -} - - /* Actually run the input modules. This happens after privileges are dropped, * if that is requested. */ @@ -1441,31 +1424,31 @@ init(void) * If not, terminate. -- rgerhards, 2008-07-25 */ if(iConfigVerify) { - if(bHadConfigErr) { - /* a bit dirty, but useful... */ - exit(1); - } - ABORT_FINALIZE(RS_RET_VALIDATION_RUN); + if(bHadConfigErr) { + /* a bit dirty, but useful... */ + exit(1); } + ABORT_FINALIZE(RS_RET_VALIDATION_RUN); +} #warning restructure following if to use return value of loadConf - if(loadConf->globals.bAbortOnUncleanConfig && bHadConfigErr) { - fprintf(stderr, "rsyslogd: $AbortOnUncleanConfig is set, and config is not clean.\n" - "Check error log for details, fix errors and restart. As a last\n" - "resort, you may want to remove $AbortOnUncleanConfig to permit a\n" - "startup with a dirty config.\n"); - exit(2); - } +if(loadConf->globals.bAbortOnUncleanConfig && bHadConfigErr) { + fprintf(stderr, "rsyslogd: $AbortOnUncleanConfig is set, and config is not clean.\n" + "Check error log for details, fix errors and restart. As a last\n" + "resort, you may want to remove $AbortOnUncleanConfig to permit a\n" + "startup with a dirty config.\n"); + exit(2); +} - /* create message queue */ - CHKiRet_Hdlr(createMainQueue(&pMsgQueue, UCHAR_CONSTANT("main Q"))) { - /* no queue is fatal, we need to give up in that case... */ - fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); - exit(1); - } +/* create message queue */ +CHKiRet_Hdlr(createMainQueue(&pMsgQueue, UCHAR_CONSTANT("main Q"))) { + /* no queue is fatal, we need to give up in that case... */ + fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); + exit(1); +} - bHaveMainQueue = (ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1; - DBGPRINTF("Main processing queue is initialized and running\n"); +bHaveMainQueue = (ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1; +DBGPRINTF("Main processing queue is initialized and running\n"); /* the output part and the queue is now ready to run. So it is a good time * to initialize the inputs. Please note that the net code above should be @@ -1477,10 +1460,6 @@ init(void) */ startInputModules(); - if(Debug) { - dbgPrintInitInfo(); - } - memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = sighup_handler; -- cgit v1.2.3 From 706121052d2c2c0bca42b3f8f1e785dd96369772 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 27 Apr 2011 13:33:06 +0200 Subject: step: shuffled module-related code from syslogd.c to rsconf.c ... plus some minor cleanup/code shuffle --- tools/syslogd.c | 269 +++++++++++--------------------------------------------- 1 file changed, 52 insertions(+), 217 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 318031a1..fc23f058 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -203,7 +203,7 @@ static int bFinished = 0; /* used by termination signal handler, read-only excep * is either 0 or the number of the signal that requested the * termination. */ -static int iConfigVerify = 0; /* is this just a config verify run? */ +int iConfigVerify = 0; /* is this just a config verify run? */ /* Intervals at which we flush out "message repeated" messages, * in seconds after previous message is logged. After each flush, @@ -1043,57 +1043,7 @@ static void doexit() exit(0); /* "good" exit, only during child-creation */ } - -/* drop to specified group - * if something goes wrong, the function never returns - * Note that such an abort can cause damage to on-disk structures, so we should - * re-design the "interface" in the long term. -- rgerhards, 2008-11-26 - */ -static void doDropPrivGid(int iGid) -{ - int res; - uchar szBuf[1024]; - - res = setgroups(0, NULL); /* remove all supplementary group IDs */ - if(res) { - perror("could not remove supplemental group IDs"); - exit(1); - } - DBGPRINTF("setgroups(0, NULL): %d\n", res); - res = setgid(iGid); - if(res) { - /* if we can not set the userid, this is fatal, so let's unconditionally abort */ - perror("could not set requested group id"); - exit(1); - } - DBGPRINTF("setgid(%d): %d\n", iGid, res); - snprintf((char*)szBuf, sizeof(szBuf)/sizeof(uchar), "rsyslogd's groupid changed to %d", iGid); - logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, szBuf, 0); -} - - -/* drop to specified user - * if something goes wrong, the function never returns - * Note that such an abort can cause damage to on-disk structures, so we should - * re-design the "interface" in the long term. -- rgerhards, 2008-11-19 - */ -static void doDropPrivUid(int iUid) -{ - int res; - uchar szBuf[1024]; - - res = setuid(iUid); - if(res) { - /* if we can not set the userid, this is fatal, so let's unconditionally abort */ - perror("could not set requested userid"); - exit(1); - } - DBGPRINTF("setuid(%d): %d\n", iUid, res); - snprintf((char*)szBuf, sizeof(szBuf)/sizeof(uchar), "rsyslogd's userid changed to %d", iUid); - logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, szBuf, 0); -} - - +#if 0 /* TODO: re-enable, currently not used */ /* helper to generateConfigDAG, to print out all actions via * the llExecFunc() facility. * rgerhards, 2007-08-02 @@ -1278,61 +1228,7 @@ generateConfigDAG(uchar *pszDAGFile) finalize_it: RETiRet; } - - -/* Actually run the input modules. This happens after privileges are dropped, - * if that is requested. - */ -static rsRetVal -runInputModules(void) -{ - modInfo_t *pMod; - int bNeedsCancel; - - BEGINfunc - /* loop through all modules and activate them (brr...) */ - pMod = module.GetNxtType(NULL, eMOD_IN); - while(pMod != NULL) { - if(pMod->mod.im.bCanRun) { - /* activate here */ - bNeedsCancel = (pMod->isCompatibleWithFeature(sFEATURENonCancelInputTermination) == RS_RET_OK) ? - 0 : 1; - thrdCreate(pMod->mod.im.runInput, pMod->mod.im.afterRun, bNeedsCancel); - } - pMod = module.GetNxtType(pMod, eMOD_IN); - } - - ENDfunc - return RS_RET_OK; /* intentional: we do not care about module errors */ -} - - -/* Start the input modules. This function will probably undergo big changes - * while we implement the input module interface. For now, it does the most - * important thing to get at least my poor initial input modules up and - * running. Almost no config option is taken. - * rgerhards, 2007-12-14 - */ -static rsRetVal -startInputModules(void) -{ - DEFiRet; - modInfo_t *pMod; - - /* loop through all modules and activate them (brr...) */ - pMod = module.GetNxtType(NULL, eMOD_IN); - while(pMod != NULL) { - iRet = pMod->mod.im.willRun(); - pMod->mod.im.bCanRun = (iRet == RS_RET_OK); - if(!pMod->mod.im.bCanRun) { - DBGPRINTF("module %lx will not run, iRet %d\n", (unsigned long) pMod, iRet); - } - pMod = module.GetNxtType(pMod, eMOD_IN); - } - - ENDfunc - return RS_RET_OK; /* intentional: we do not care about module errors */ -} +#endif /* create a main message queue, now also used for ruleset queues. This function @@ -1406,59 +1302,22 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) static rsRetVal init(void) { - rsRetVal localRet; - int iNbrActions; - int bHadConfigErr = 0; - char cbuf[BUFSIZ]; char bufStartUpMsg[512]; struct sigaction sigAct; DEFiRet; legacyOptsHook(); - /* check if we need to generate a config DAG and, if so, do that */ - if(ourConf->globals.pszConfDAGFile != NULL) - generateConfigDAG(ourConf->globals.pszConfDAGFile); - /* we are done checking the config - now validate if we should actually run or not. - * If not, terminate. -- rgerhards, 2008-07-25 - */ - if(iConfigVerify) { - if(bHadConfigErr) { - /* a bit dirty, but useful... */ + /* create message queue */ + CHKiRet_Hdlr(createMainQueue(&pMsgQueue, UCHAR_CONSTANT("main Q"))) { + /* no queue is fatal, we need to give up in that case... */ + fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); exit(1); } - ABORT_FINALIZE(RS_RET_VALIDATION_RUN); -} -#warning restructure following if to use return value of loadConf -if(loadConf->globals.bAbortOnUncleanConfig && bHadConfigErr) { - fprintf(stderr, "rsyslogd: $AbortOnUncleanConfig is set, and config is not clean.\n" - "Check error log for details, fix errors and restart. As a last\n" - "resort, you may want to remove $AbortOnUncleanConfig to permit a\n" - "startup with a dirty config.\n"); - exit(2); -} - -/* create message queue */ -CHKiRet_Hdlr(createMainQueue(&pMsgQueue, UCHAR_CONSTANT("main Q"))) { - /* no queue is fatal, we need to give up in that case... */ - fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); - exit(1); -} - -bHaveMainQueue = (ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1; -DBGPRINTF("Main processing queue is initialized and running\n"); - - /* the output part and the queue is now ready to run. So it is a good time - * to initialize the inputs. Please note that the net code above should be - * shuffled to down here once we have everything in input modules. - * rgerhards, 2007-12-14 - * NOTE: as of 2009-06-29, the input modules are initialized, but not yet run. - * Keep in mind. though, that the outputs already run if the queue was - * persisted to disk. -- rgerhards - */ - startInputModules(); + bHaveMainQueue = (ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1; + DBGPRINTF("Main processing queue is initialized and running\n"); memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); @@ -1670,67 +1529,6 @@ static void printVersion(void) } -/* This function is called after initial initalization. It is used to - * move code out of the too-long main() function. - * rgerhards, 2007-10-17 - */ -static rsRetVal mainThread() -{ - DEFiRet; - - CHKiRet(init()); - - if(Debug && debugging_on) { - dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); - } - - /* Send a signal to the parent so it can terminate. - */ - if(myPid != ppid) - kill(ppid, SIGTERM); - - - /* If instructed to do so, we now drop privileges. Note that this is not 100% secure, - * because outputs are already running at this time. However, we can implement - * dropping of privileges rather quickly and it will work in many cases. While it is not - * the ultimate solution, the current one is still much better than not being able to - * drop privileges at all. Doing it correctly, requires a change in architecture, which - * we should do over time. TODO -- rgerhards, 2008-11-19 - */ - if(ourConf->globals.gidDropPriv != 0) { - doDropPrivGid(ourConf->globals.gidDropPriv); - } - - if(ourConf->globals.uidDropPriv != 0) { - doDropPrivUid(ourConf->globals.uidDropPriv); - } - - /* finally let the inputs run... */ - runInputModules(); - - /* END OF INTIALIZATION - */ - DBGPRINTF("initialization completed, transitioning to regular run mode\n"); - - /* close stderr and stdout if they are kept open during a fork. Note that this - * may introduce subtle security issues: if we are in a jail, one may break out of - * it via these descriptors. But if I close them earlier, error messages will (once - * again) not be emitted to the user that starts the daemon. As root jail support - * is still in its infancy (and not really done), we currently accept this issue. - * rgerhards, 2009-06-29 - */ - if(!(Debug == DEBUG_FULL || NoFork)) { - close(1); - close(2); - ourConf->globals.bErrMsgToStderr = 0; - } - - mainloop(); - -finalize_it: - RETiRet; -} - /* Method to initialize all global classes and use the objects that we need. * rgerhards, 2008-01-04 @@ -2033,8 +1831,7 @@ doGlblProcessInit(void) */ int realMain(int argc, char **argv) { - DEFiRet; - + rsRetVal localRet; register uchar *p; int ch; struct hostent *hent; @@ -2050,6 +1847,7 @@ int realMain(int argc, char **argv) uchar *LocalDomain; uchar *LocalFQDNName; char cwdbuf[128]; /* buffer to obtain/display current working directory */ + DEFiRet; /* first, parse the command line options. We do not carry out any actual work, just * see what we should do. This relieves us from certain anomalies and we can process @@ -2364,19 +2162,29 @@ int realMain(int argc, char **argv) if(iRet != RS_RET_END_OF_LINKEDLIST) FINALIZE; - CHKiRet(rsconf.Load(&ourConf, ConfFile)); - if(iConfigVerify) { fprintf(stderr, "rsyslogd: version %s, config validation run (level %d), master config %s\n", VERSION, iConfigVerify, ConfFile); } + localRet = rsconf.Load(&ourConf, ConfFile); + if(localRet == RS_RET_NONFATAL_CONFIG_ERR) { + if(loadConf->globals.bAbortOnUncleanConfig) { + fprintf(stderr, "rsyslogd: $AbortOnUncleanConfig is set, and config is not clean.\n" + "Check error log for details, fix errors and restart. As a last\n" + "resort, you may want to remove $AbortOnUncleanConfig to permit a\n" + "startup with a dirty config.\n"); + exit(2); + } + iRet = RS_RET_OK; + } + CHKiRet(localRet); + if(bChDirRoot) { if(chdir("/") != 0) fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); } - /* process compatibility mode settings */ if(iCompatibilityMode < 4) { errmsg.LogError(0, NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically " @@ -2406,7 +2214,34 @@ int realMain(int argc, char **argv) if(!iConfigVerify) CHKiRet(doGlblProcessInit()); - CHKiRet(mainThread()); + CHKiRet(init()); + + if(Debug && debugging_on) { + dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); + } + + /* Send a signal to the parent so it can terminate. */ + if(myPid != ppid) + kill(ppid, SIGTERM); + + + /* END OF INTIALIZATION */ + DBGPRINTF("initialization completed, transitioning to regular run mode\n"); + + /* close stderr and stdout if they are kept open during a fork. Note that this + * may introduce subtle security issues: if we are in a jail, one may break out of + * it via these descriptors. But if I close them earlier, error messages will (once + * again) not be emitted to the user that starts the daemon. As root jail support + * is still in its infancy (and not really done), we currently accept this issue. + * rgerhards, 2009-06-29 + */ + if(!(Debug == DEBUG_FULL || NoFork)) { + close(1); + close(2); + ourConf->globals.bErrMsgToStderr = 0; + } + + mainloop(); /* do any de-init's that need to be done AFTER this comment */ -- cgit v1.2.3 From 5cd3cdf3c82ef49506124ace13d20c52afd5d44a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 27 Apr 2011 17:11:41 +0200 Subject: step: config-specific module list used during config processing --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index fc23f058..dcce4d77 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2176,7 +2176,7 @@ int realMain(int argc, char **argv) "startup with a dirty config.\n"); exit(2); } - iRet = RS_RET_OK; + localRet = RS_RET_OK; } CHKiRet(localRet); -- cgit v1.2.3 From 6093f3110306e0575d10d09807da1e6895af4eba Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 27 Apr 2011 17:57:47 +0200 Subject: step: moved main message queue activation to after priv drop --- tools/syslogd.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index dcce4d77..4fe6fa26 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -231,7 +231,7 @@ int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sy int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */ -static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - is available +int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - is available * If the main queue is either not yet ready or not running in * queueing mode (mode DIRECT!), then this is set to 0. */ @@ -1308,17 +1308,6 @@ init(void) legacyOptsHook(); - - /* create message queue */ - CHKiRet_Hdlr(createMainQueue(&pMsgQueue, UCHAR_CONSTANT("main Q"))) { - /* no queue is fatal, we need to give up in that case... */ - fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); - exit(1); - } - - bHaveMainQueue = (ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1; - DBGPRINTF("Main processing queue is initialized and running\n"); - memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = sighup_handler; -- cgit v1.2.3 From 7c12000d865b0885c2d5125f14742a54e41a270c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 30 May 2011 08:37:35 +0200 Subject: regression fix: config validation code affected by recent changes did not return with proper return value --- tools/syslogd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4fe6fa26..4c512ac2 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2165,6 +2165,10 @@ int realMain(int argc, char **argv) "startup with a dirty config.\n"); exit(2); } + if(iConfigVerify) { + /* a bit dirty, but useful... */ + exit(1); + } localRet = RS_RET_OK; } CHKiRet(localRet); -- cgit v1.2.3 From 2b9e5ac193ea91817ff17851a4a16a42a5b87fdb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 6 Jun 2011 16:41:55 +0200 Subject: added a first implementation of a DNS name cache this still has a couple of weaknesses, like no size limit, no expiration of entries, suboptimal algorithms -- but it should perform better than what we had previously. Implementation will be improved based on feedback during the next couple of releases --- tools/syslogd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4c512ac2..bbace3de 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -124,6 +124,7 @@ #include "vm.h" #include "prop.h" #include "rsconf.h" +#include "dnscache.h" #include "sd-daemon.h" /* definitions for objects we access */ @@ -1567,6 +1568,7 @@ InitGlobalClasses(void) /* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ pErrObj = "net"; CHKiRet(objUse(net, LM_NET_FILENAME)); + dnscacheInit(); finalize_it: if(iRet != RS_RET_OK) { @@ -1615,6 +1617,7 @@ GlobalClassExit(void) CHKiRet(objUse(errmsg, CORE_COMPONENT)); CHKiRet(objUse(module, CORE_COMPONENT)); #endif + dnscacheDeinit(); rsrtExit(); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */ RETiRet; -- cgit v1.2.3 From 90f8c7300495da9b61e4706be652c612fccc084f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 16 Jun 2011 15:17:48 +0200 Subject: bugfix: problems in failover action handling closes: http://bugzilla.adiscon.com/show_bug.cgi?id=270 (not yet confirmed!) --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 487ab364..096f9309 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -799,7 +799,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) DBGPRINTF("flush %s: repeated %d times, %d sec.\n", module.GetStateName(pAction->pMod), pAction->f_prevcount, repeatinterval[pAction->f_repeatcount]); - actionWriteToAction(pAction, NULL, 0); + actionWriteToAction(pAction); BACKOFF(pAction); } UnlockObj(pAction); -- cgit v1.2.3 From 30f2b5b094d282af6f601aa4e8fa88c1baf187f4 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 6 Jul 2011 12:26:52 +0200 Subject: milestone:/[PARTWORK]: config is processed using new parser, except... ... for "if" filters (more work to come, probably lots of more work... ;)) --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 6dbd4be5..79bf0c8a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -802,7 +802,7 @@ void legacyOptsHook(void) errno = 0; errmsg.LogError(0, NO_ERRCODE, "Warning: backward compatibility layer added to following " "directive to rsyslog.conf: %s", pThis->line); - conf.cfsysline(ourConf, pThis->line); + conf.cfsysline(pThis->line); } pThis = pThis->next; } -- cgit v1.2.3 From d9ea755214ab75afa039a4df89f828d4b8b30ef0 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 8 Jul 2011 09:13:39 +0200 Subject: milestone/[PARTWORK]: implemented comparison operations --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 79bf0c8a..f623b398 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1602,7 +1602,6 @@ GlobalClassExit(void) objRelease(ruleset, CORE_COMPONENT); objRelease(rule, CORE_COMPONENT); objRelease(expr, CORE_COMPONENT); - vmClassExit(); /* this is hack, currently core_modules do not get this automatically called */ parserClassExit(); /* this is hack, currently core_modules do not get this automatically called */ rsconfClassExit(); /* this is hack, currently core_modules do not get this automatically called */ objRelease(datetime, CORE_COMPONENT); -- cgit v1.2.3 From 84f217e87d6cd912a81564acc341d00515571f96 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 11 Jul 2011 15:07:56 +0200 Subject: cleanup, removing now unused code --- tools/syslogd.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f623b398..45abf1a7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -121,7 +121,6 @@ #include "ruleset.h" #include "rule.h" #include "net.h" -#include "vm.h" #include "prop.h" #include "rsconf.h" #include "dnscache.h" @@ -132,7 +131,6 @@ DEFobjCurrIf(obj) DEFobjCurrIf(glbl) DEFobjCurrIf(datetime) /* TODO: make go away! */ DEFobjCurrIf(conf) -DEFobjCurrIf(expr) DEFobjCurrIf(module) DEFobjCurrIf(errmsg) DEFobjCurrIf(rule) @@ -1544,8 +1542,6 @@ InitGlobalClasses(void) CHKiRet(objUse(module, CORE_COMPONENT)); pErrObj = "datetime"; CHKiRet(objUse(datetime, CORE_COMPONENT)); - pErrObj = "expr"; - CHKiRet(objUse(expr, CORE_COMPONENT)); pErrObj = "rule"; CHKiRet(objUse(rule, CORE_COMPONENT)); pErrObj = "ruleset"; @@ -1601,7 +1597,6 @@ GlobalClassExit(void) objRelease(conf, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); objRelease(rule, CORE_COMPONENT); - objRelease(expr, CORE_COMPONENT); parserClassExit(); /* this is hack, currently core_modules do not get this automatically called */ rsconfClassExit(); /* this is hack, currently core_modules do not get this automatically called */ objRelease(datetime, CORE_COMPONENT); -- cgit v1.2.3 From a5bc2a8b4bdf8b7834326ae6410c3bc7285fa1e8 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 12 Jul 2011 12:14:47 +0200 Subject: removed emergency config, do error reporting on fatal config file error --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 45abf1a7..72c0bdb3 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2243,7 +2243,7 @@ finalize_it: if(iRet == RS_RET_VALIDATION_RUN) { fprintf(stderr, "rsyslogd: End of config validation run. Bye.\n"); } else if(iRet != RS_RET_OK) { - fprintf(stderr, "rsyslogd run failed with error %d (see rsyslog.h " + fprintf(stderr, "rsyslogd: run failed with error %d (see rsyslog.h " "or try http://www.rsyslog.com/e/%d to learn what that number means)\n", iRet, iRet*-1); } -- cgit v1.2.3 From 20607ba1695b99838db7bdf809b22cf52bbdf5ce Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 12 Jul 2011 12:29:55 +0200 Subject: removed compatibility mode as we expect people have adjusted their confs by now --- tools/syslogd.c | 247 +++----------------------------------------------------- 1 file changed, 13 insertions(+), 234 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 72c0bdb3..91df6469 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -215,12 +215,6 @@ int repeatinterval[2] = { 30, 60 }; /* # of secs before flush */ static pid_t ppid; /* This is a quick and dirty hack used for spliting main/startup thread */ -typedef struct legacyOptsLL_s { - uchar *line; - struct legacyOptsLL_s *next; -} legacyOptsLL_t; -legacyOptsLL_t *pLegacyOptsLL = NULL; - /* global variables for config file state */ int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is the default, so if no -c option is given, we make ourselvs @@ -754,132 +748,6 @@ static void debug_switch() } -void legacyOptsEnq(uchar *line) -{ - legacyOptsLL_t *pNew; - - pNew = MALLOC(sizeof(legacyOptsLL_t)); - if(line == NULL) - pNew->line = NULL; - else - pNew->line = (uchar *) strdup((char *) line); - pNew->next = NULL; - - if(pLegacyOptsLL == NULL) - pLegacyOptsLL = pNew; - else { - legacyOptsLL_t *pThis = pLegacyOptsLL; - - while(pThis->next != NULL) - pThis = pThis->next; - pThis->next = pNew; - } -} - - -void legacyOptsFree(void) -{ - legacyOptsLL_t *pThis = pLegacyOptsLL, *pNext; - - while(pThis != NULL) { - if(pThis->line != NULL) - free(pThis->line); - pNext = pThis->next; - free(pThis); - pThis = pNext; - } -} - - -void legacyOptsHook(void) -{ - legacyOptsLL_t *pThis = pLegacyOptsLL; - - while(pThis != NULL) { - if(pThis->line != NULL) { - errno = 0; - errmsg.LogError(0, NO_ERRCODE, "Warning: backward compatibility layer added to following " - "directive to rsyslog.conf: %s", pThis->line); - conf.cfsysline(pThis->line); - } - pThis = pThis->next; - } -} - - -void legacyOptsParseTCP(char ch, char *arg) -{ - register int i; - register char *pArg = arg; - static char conflict = '\0'; - - if((conflict == 'g' && ch == 't') || (conflict == 't' && ch == 'g')) { - fprintf(stderr, "rsyslogd: If you want to use both -g and -t, use directives instead, -%c ignored.\n", ch); - return; - } else - conflict = ch; - - /* extract port */ - i = 0; - while(isdigit((int) *pArg)) - i = i * 10 + *pArg++ - '0'; - - /* number of sessions */ - if(*pArg == '\0' || *pArg == ',') { - if(ch == 't') - legacyOptsEnq((uchar *) "ModLoad imtcp"); - else if(ch == 'g') - legacyOptsEnq((uchar *) "ModLoad imgssapi"); - - if(i >= 0 && i <= 65535) { - uchar line[30]; - - if(ch == 't') { - snprintf((char *) line, sizeof(line), "InputTCPServerRun %d", i); - } else if(ch == 'g') { - snprintf((char *) line, sizeof(line), "InputGSSServerRun %d", i); - } - legacyOptsEnq(line); - } else { - if(ch == 't') { - fprintf(stderr, "rsyslogd: Invalid TCP listen port %d - changed to 514.\n", i); - legacyOptsEnq((uchar *) "InputTCPServerRun 514"); - } else if(ch == 'g') { - fprintf(stderr, "rsyslogd: Invalid GSS listen port %d - changed to 514.\n", i); - legacyOptsEnq((uchar *) "InputGSSServerRun 514"); - } - } - - if(*pArg == ',') { - ++pArg; - while(isspace((int) *pArg)) - ++pArg; - i = 0; - while(isdigit((int) *pArg)) { - i = i * 10 + *pArg++ - '0'; - } - if(i > 0) { - uchar line[30]; - - snprintf((char *) line, sizeof(line), "InputTCPMaxSessions %d", i); - legacyOptsEnq(line); - } else { - if(ch == 't') { - fprintf(stderr, "rsyslogd: TCP session max configured " - "to %d [-t %s] - changing to 1.\n", i, arg); - legacyOptsEnq((uchar *) "InputTCPMaxSessions 1"); - } else if (ch == 'g') { - fprintf(stderr, "rsyslogd: GSS session max configured " - "to %d [-g %s] - changing to 1.\n", i, arg); - legacyOptsEnq((uchar *) "InputTCPMaxSessions 1"); - } - } - } - } else - fprintf(stderr, "rsyslogd: Invalid -t %s command line option.\n", arg); -} - - /* doDie() is a signal handler. If called, it sets the bFinished variable * to indicate the program should terminate. However, it does not terminate * it itself, because that causes issues with multi-threading. The actual @@ -1003,8 +871,6 @@ die(int sig) */ unregCfSysLineHdlrs(); - legacyOptsFree(); - /* destruct our global properties */ if(pInternalInputName != NULL) prop.Destruct(&pInternalInputName); @@ -1305,8 +1171,6 @@ init(void) struct sigaction sigAct; DEFiRet; - legacyOptsHook(); - memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = sighup_handler; @@ -1824,11 +1688,9 @@ int realMain(int argc, char **argv) extern int optind; extern char *optarg; int bEOptionWasGiven = 0; - int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */ int iHelperUOpt; int bChDirRoot = 1; /* change the current working directory to "/"? */ char *arg; /* for command line option processing */ - uchar legacyConfLine[80]; uchar *LocalHostName; uchar *LocalDomain; uchar *LocalFQDNName; @@ -1871,6 +1733,9 @@ int realMain(int argc, char **argv) case 'u': /* misc user settings */ case 'w': /* disable disallowed host warnings */ case 'x': /* disable dns for remote messages */ + case 'g': /* enable tcp gssapi logging */ + case 'r': /* accept remote messages */ + case 't': /* enable tcp logging */ CHKiRet(bufOptAdd(ch, optarg)); break; case 'c': /* compatibility mode */ @@ -1881,37 +1746,15 @@ int realMain(int argc, char **argv) Debug = 1; break; case 'e': /* log every message (no repeat message supression) */ - fprintf(stderr, "note: -e option is no longer supported, every message is now logged by default\n"); bEOptionWasGiven = 1; break; - case 'g': /* enable tcp gssapi logging */ -#if defined(SYSLOG_INET) && defined(USE_GSSAPI) - CHKiRet(bufOptAdd('g', optarg)); -#else - fprintf(stderr, "rsyslogd: -g not valid - not compiled with gssapi support"); -#endif - break; case 'M': /* default module load path -- this MUST be carried out immediately! */ glblModPath = (uchar*) optarg; break; - case 'r': /* accept remote messages */ -#ifdef SYSLOG_INET - CHKiRet(bufOptAdd(ch, optarg)); -#else - fprintf(stderr, "rsyslogd: -r not valid - not compiled with network support\n"); -#endif - break; - case 't': /* enable tcp logging */ -#ifdef SYSLOG_INET - CHKiRet(bufOptAdd(ch, optarg)); -#else - fprintf(stderr, "rsyslogd: -t not valid - not compiled with network support\n"); -#endif - break; case 'v': /* MUST be carried out immediately! */ printVersion(); exit(0); /* exit for -v option - so this is a "good one" */ - case '?': + case '?': default: usage(); } @@ -2020,32 +1863,15 @@ int realMain(int argc, char **argv) send_to_all++; break; case 'a': - if(iCompatibilityMode < 3) { - if(!bImUxSockLoaded) { - legacyOptsEnq((uchar *) "ModLoad imuxsock"); - bImUxSockLoaded = 1; - } - snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "addunixlistensocket %s", arg); - legacyOptsEnq(legacyConfLine); - } else { - fprintf(stderr, "error -a is no longer supported, use module imuxsock instead"); - } + fprintf(stderr, "rsyslogd: error -a is no longer supported, use module imuxsock instead"); break; case 'f': /* configuration file */ ConfFile = (uchar*) arg; break; case 'g': /* enable tcp gssapi logging */ - if(iCompatibilityMode < 3) { - legacyOptsParseTCP(ch, arg); - } else - fprintf(stderr, "-g option only supported in compatibility modes 0 to 2 - ignored\n"); - break; + fprintf(stderr, "rsyslogd: -g option no longer supported - ignored\n"); case 'h': - if(iCompatibilityMode < 3) { - errmsg.LogError(0, NO_ERRCODE, "WARNING: -h option is no longer supported - ignored"); - } else { - usage(); /* for v3 and above, it simply is an error */ - } + fprintf(stderr, "rsyslogd: error -h is no longer supported - ignored"); break; case 'i': /* pid file name */ PidFile = arg; @@ -2058,11 +1884,7 @@ int realMain(int argc, char **argv) } break; case 'm': /* mark interval */ - if(iCompatibilityMode < 3) { - MarkInterval = atoi(arg) * 60; - } else - fprintf(stderr, - "-m option only supported in compatibility modes 0 to 2 - ignored\n"); + fprintf(stderr, "rsyslogd: error -m is no longer supported - use immark instead"); break; case 'n': /* don't fork */ NoFork = 1; @@ -2071,27 +1893,10 @@ int realMain(int argc, char **argv) iConfigVerify = atoi(arg); break; case 'o': - if(iCompatibilityMode < 3) { - if(!bImUxSockLoaded) { - legacyOptsEnq((uchar *) "ModLoad imuxsock"); - bImUxSockLoaded = 1; - } - legacyOptsEnq((uchar *) "OmitLocalLogging"); - } else { - fprintf(stderr, "error -o is no longer supported, use module imuxsock instead"); - } + fprintf(stderr, "error -o is no longer supported, use module imuxsock instead"); break; case 'p': - if(iCompatibilityMode < 3) { - if(!bImUxSockLoaded) { - legacyOptsEnq((uchar *) "ModLoad imuxsock"); - bImUxSockLoaded = 1; - } - snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "SystemLogSocketName %s", arg); - legacyOptsEnq(legacyConfLine); - } else { - fprintf(stderr, "error -p is no longer supported, use module imuxsock instead"); - } + fprintf(stderr, "error -p is no longer supported, use module imuxsock instead"); break; case 'q': /* add hostname if DNS resolving has failed */ *(net.pACLAddHostnameOnFail) = 1; @@ -2100,12 +1905,7 @@ int realMain(int argc, char **argv) *(net.pACLDontResolve) = 1; break; case 'r': /* accept remote messages */ - if(iCompatibilityMode < 3) { - legacyOptsEnq((uchar *) "ModLoad imudp"); - snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "UDPServerRun %s", arg); - legacyOptsEnq(legacyConfLine); - } else - fprintf(stderr, "-r option only supported in compatibility modes 0 to 2 - ignored\n"); + fprintf(stderr, "rsyslogd: error option -r is no longer supported - ignored"); break; case 's': if(glbl.GetStripDomains() != NULL) { @@ -2115,10 +1915,7 @@ int realMain(int argc, char **argv) } break; case 't': /* enable tcp logging */ - if(iCompatibilityMode < 3) { - legacyOptsParseTCP(ch, arg); - } else - fprintf(stderr, "-t option only supported in compatibility modes 0 to 2 - ignored\n"); + fprintf(stderr, "rsyslogd: error option -t is no longer supported - ignored"); break; case 'T':/* chroot() immediately at program startup, but only for testing, NOT security yet */ if(chroot(arg) != 0) { @@ -2176,25 +1973,7 @@ int realMain(int argc, char **argv) } /* process compatibility mode settings */ - if(iCompatibilityMode < 4) { - errmsg.LogError(0, NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically " - "generated config directives may interfer with your rsyslog.conf settings. " - "We suggest upgrading your config and adding -c5 as the first " - "rsyslogd option."); - } - - if(iCompatibilityMode < 3) { - if(MarkInterval > 0) { - legacyOptsEnq((uchar *) "ModLoad immark"); - snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "MarkMessagePeriod %d", MarkInterval); - legacyOptsEnq(legacyConfLine); - } - if(!bImUxSockLoaded) { - legacyOptsEnq((uchar *) "ModLoad imuxsock"); - } - } - - if(bEOptionWasGiven && iCompatibilityMode < 3) { + if(bEOptionWasGiven) { errmsg.LogError(0, NO_ERRCODE, "WARNING: \"message repeated n times\" feature MUST be turned on in " "rsyslog.conf - CURRENTLY EVERY MESSAGE WILL BE LOGGED. Visit " "http://www.rsyslog.com/rptdmsgreduction to learn " -- cgit v1.2.3 From 1ca6cc236d1dabf1633238b873fb1c057e52f95e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 10 Aug 2011 11:41:03 +0200 Subject: bugfix: off-by-one(two) bug in legacy syslog parser --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 12d94e9a..ba27d08a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1289,7 +1289,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags) * outputs so that only 32 characters max are used by default. */ i = 0; - while(lenMsg > 0 && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE) { + while(lenMsg > 0 && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE - 2) { bufParseTAG[i++] = *p2parse++; --lenMsg; } -- cgit v1.2.3 From fb7fab511e0de2566c0de47468b443ef5bb508d3 Mon Sep 17 00:00:00 2001 From: mono_matsuko Date: Mon, 5 Sep 2011 12:18:11 +0200 Subject: bugfix: rsyslogd -v always said 64 atomics were not present Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 096f9309..6bed6a1a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2129,7 +2129,7 @@ static void printVersion(void) #else printf("\t32bit Atomic operations supported:\tNo\n"); #endif -#ifdef HAVE_ATOMIC_BUILTINS64 +#ifdef HAVE_ATOMIC_BUILTINS_64BIT printf("\t64bit Atomic operations supported:\tYes\n"); #else printf("\t64bit Atomic operations supported:\tNo\n"); -- cgit v1.2.3 From c55997638f8833daec34d7f51b9ff6694620f6f8 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 8 Sep 2011 15:05:04 +0200 Subject: added $InputRELPServerBindRuleset directive to specify rulesets for RELP --- tools/syslogd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 91df6469..6d794260 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -383,7 +383,7 @@ void untty(void) */ rsRetVal parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int flags, flowControl_t flowCtlType, - prop_t *pInputName, struct syslogTime *stTime, time_t ttGenTime) + prop_t *pInputName, struct syslogTime *stTime, time_t ttGenTime, ruleset_t *pRuleset) { prop_t *pProp = NULL; msg_t *pMsg; @@ -399,6 +399,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla MsgSetInputName(pMsg, pInputName); MsgSetRawMsg(pMsg, (char*)msg, len); MsgSetFlowControlType(pMsg, flowCtlType); + MsgSetRuleset(pMsg, pRuleset); pMsg->msgFlags = flags | NEEDS_PARSING; MsgSetRcvFromStr(pMsg, hname, ustrlen(hname), &pProp); -- cgit v1.2.3 From e25dc05e9127537cf2ddbae30b15300f601fbff0 Mon Sep 17 00:00:00 2001 From: Tomas Heinrich Date: Tue, 10 Jan 2012 17:07:55 +0100 Subject: added canned template for ultra-exact sysklogd file format the point is that LF will be translated to SP Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 64b23566..4a5cbf60 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -381,6 +381,7 @@ static uchar template_TraditionalForwardFormat[] = "\"<%PRI%>%TIMESTAMP% %HOSTNA static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\""; static uchar template_StdDBFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')\",SQL"; static uchar template_StdPgSQLFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%')\",STDSQL"; +static uchar template_SysklogdFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%\n\""; /* end template */ @@ -2836,6 +2837,8 @@ static rsRetVal mainThread() tplAddLine(" StdUsrMsgFmt", &pTmp); pTmp = template_StdDBFmt; tplAddLine(" StdDBFmt", &pTmp); + pTmp = template_SysklogdFileFormat; + tplAddLine("RSYSLOG_SysklogdFileFormat", &pTmp); pTmp = template_StdPgSQLFmt; tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp)); -- cgit v1.2.3 From a2e69cffff21ad433e61b45f91a2be4d5ebc5c72 Mon Sep 17 00:00:00 2001 From: Tomas Heinrich Date: Tue, 10 Jan 2012 17:14:16 +0100 Subject: added $SpaceLFOnReceive config directive Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4a5cbf60..b696c55f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -259,6 +259,7 @@ static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list i static int bDebugPrintModuleList = 1;/* output module list in debug mode? */ uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence for control chars */ int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */ +int bSpaceLFOnRcv = 0; /* replace newlines with spaces on reception: 0 - no, 1 - yes */ static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ @@ -343,6 +344,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a bDebugPrintCfSysLineHandlerList = 1; bDebugPrintModuleList = 1; bEscapeCCOnRcv = 1; /* default is to escape control characters */ + bSpaceLFOnRcv = 0; bReduceRepeatMsgs = 0; free(pszMainMsgQFName); pszMainMsgQFName = NULL; @@ -810,6 +812,9 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla /* log an error? Very questionable... rgerhards, 2006-11-30 */ /* decided: we do not log an error, it won't help... rger, 2007-06-21 */ ++pData; + } else if (bSpaceLFOnRcv && *pData == '\n') { + *(pMsg + iMsg++) = ' '; + ++pData; } else if(bEscapeCCOnRcv && iscntrl((int) *pData)) { /* we are configured to escape control characters. Please note * that this most probably break non-western character sets like @@ -2115,6 +2120,9 @@ static void dbgPrintInitInfo(void) DBGPRINTF("Control characters are %sreplaced upon reception.\n", bEscapeCCOnRcv? "" : "not "); + DBGPRINTF("Newlines are %sreplaced upon reception.\n", + bSpaceLFOnRcv? "" : "not "); + if(bEscapeCCOnRcv) DBGPRINTF("Control character escape sequence prefix is '%c'.\n", cCCEscapeChar); @@ -2728,6 +2736,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"spacelfonreceive", 0, eCmdHdlrBinary, NULL, &bSpaceLFOnRcv, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL)); -- cgit v1.2.3 From 209a6d8e15afb83c0bf146dd95fc203bb9983242 Mon Sep 17 00:00:00 2001 From: Tomas Heinrich Date: Mon, 16 Jan 2012 16:53:18 +0100 Subject: FQDN hostname for multihomed host was not always set to the correct name ..if multiple aliases existed. Thanks to Tomas Heinreich for the patch. Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f66cbee3..7254385e 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -3350,9 +3350,29 @@ int realMain(int argc, char **argv) */ hent = gethostbyname((char*)LocalHostName); if(hent) { + int i = 0; + + if(hent->h_aliases) { + size_t hnlen; + + hnlen = strlen((char *) LocalHostName); + + for (i = 0; hent->h_aliases[i]; i++) { + if (!strncmp(hent->h_aliases[i], (char *) LocalHostName, hnlen) + && hent->h_aliases[i][hnlen] == '.') { + /* found a matching hostname */ + break; + } + } + } + free(LocalHostName); - CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - + if(hent->h_aliases && hent->h_aliases[i]) { + CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); + } else { + CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); + } + if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { *p++ = '\0'; -- cgit v1.2.3 From 167192666ba8905b83210ab7c5f00cc6be9f7147 Mon Sep 17 00:00:00 2001 From: Peng Haitao Date: Fri, 6 Jan 2012 14:48:18 +0800 Subject: fix error of not define HAVE_SETSID [add list to the CC list] When HAVE_SETSID is not defined, rsyslogd will use ioctl() make itself to daemon, but this can not make rsyslogd process become the process group leader of a new process group. In RHEL6.1, the status is as follows: # uname -a Linux RHEL6U1GA-Intel64-199 2.6.32-131.0.15.el6.x86_64 #1 SMP Tue May 10 15:42:40 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux # /etc/init.d/rsyslog restart Shutting down system logger: [ OK ] Starting system logger: [ OK ] # ps axo pgrp,ppid,pid,comm | grep rsyslog 6290 1 6301 rsyslogd When we send SIGTERM signal to 6290, rsyslogd will die:( So I think we should call setpgid() before ioctl(). Signed-off-by: Peng Haitao --- tools/syslogd.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 6879bafa..65770404 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -460,8 +460,15 @@ void untty(void) #else { int i; + pid_t pid; if(!Debug) { + pid = getpid(); + if (setpgid(pid, pid) < 0) { + perror("setpgid"); + exit(1); + } + i = open(_PATH_TTY, O_RDWR|O_CLOEXEC); if (i >= 0) { # if !defined(__hpux) -- cgit v1.2.3 From f8019d52f83884acb5e8f8755fe976d1592b4ccb Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Mon, 15 Aug 2011 22:22:13 +1000 Subject: add elasticsearch output module Add support for sending events to elasticsearch - a distributed, RESTful, search engine built on Lucene (www.elasticsearch.org). The output module is enabled via a configure option, and uses libcurl to send the messages from rsyslog to elasticsearch. This patch makes use of the earlier JSON quoting patch to ensure valid JSON strings are sent to the server. Signed-off-by: Nathan Scott --- tools/syslogd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 0b7bbc96..bec2f9a7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -334,6 +334,7 @@ static uchar template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %t static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\""; static uchar template_StdDBFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')\",SQL"; static uchar template_StdPgSQLFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%')\",STDSQL"; +static uchar template_StdJSONFmt[] = "\"{\\\"message\\\":\\\"%msg%\\\",\\\"fromhost\\\":\\\"%HOSTNAME%\\\",\\\"facility\\\":\\\"%syslogfacility-text%\\\",\\\"priority\\\":\\\"%syslogpriority-text%\\\",\\\"timereported\\\":\\\"%timereported:::date-rfc3339%\\\",\\\"timegenerated\\\":\\\"%timegenerated:::date-rfc3339%\\\"}\",JSON"; static uchar template_spoofadr[] = "\"%fromhost-ip%\""; /* end templates */ @@ -2173,6 +2174,8 @@ static rsRetVal mainThread() tplAddLine(" StdDBFmt", &pTmp); pTmp = template_StdPgSQLFmt; tplAddLine(" StdPgSQLFmt", &pTmp); + pTmp = template_StdJSONFmt; + tplAddLine(" StdJSONFmt", &pTmp); pTmp = template_spoofadr; tplLastStaticInit(tplAddLine("RSYSLOG_omudpspoofDfltSourceTpl", &pTmp)); -- cgit v1.2.3 From 3fe63651667d3b74c2f9c97824cb9ed65913a99e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 19 Jan 2012 15:24:16 +0100 Subject: refactor: remove very old sync.[ch] system for "abstracting" mutex access This was a bad idea that never was used much. --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4cfbd377..2e7a1e23 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -695,7 +695,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) assert(pAction != NULL); BEGINfunc - LockObj(pAction); + d_pthread_mutex_lock(&pAction->mutAction); /* TODO: time() performance: the call below could be moved to * the beginn of the llExec(). This makes it slightly less correct, but * in an acceptable way. -- rgerhards, 2008-09-16 @@ -707,7 +707,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) actionWriteToAction(pAction); BACKOFF(pAction); } - UnlockObj(pAction); + d_pthread_mutex_unlock(&pAction->mutAction); ENDfunc return RS_RET_OK; /* we ignore errors, we can not do anything either way */ -- cgit v1.2.3 From f9b6b94b802c653e6c588f42af0997682e75f267 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 21 Feb 2012 16:52:36 +0100 Subject: added configuration directives to customize queue light delay marks $MainMsgQueueLightDelayMark, $ActionQueueLightDelayMark; both specify number of messages starting at which a delay happens. --- tools/syslogd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 0b7bbc96..4c537570 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -262,6 +262,7 @@ static uchar *pszConfDAGFile = NULL; /* name of config DAG file, non-NULL mea qqueue_t *pMsgQueue = NULL; /* the main message queue */ static int iMainMsgQueueSize = 10000; /* size of the main message queue above */ static int iMainMsgQHighWtrMark = 8000; /* high water mark for disk-assisted queues */ +static int iMainMsgQLightDlyMark = 7000; /* light delay mark for disk-assisted queues */ static int iMainMsgQLowWtrMark = 2000; /* low water mark for disk-assisted queues */ static int iMainMsgQDiscardMark = 9800; /* begin to discard messages */ static int iMainMsgQDiscardSeverity = 8; /* by default, discard nothing to prevent unintentional loss */ @@ -300,6 +301,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a pszMainMsgQFName = NULL; iMainMsgQueueSize = 10000; iMainMsgQHighWtrMark = 8000; + iMainMsgQLightDlyMark = 7000; iMainMsgQLowWtrMark = 2000; iMainMsgQDiscardMark = 9800; iMainMsgQDiscardSeverity = 8; @@ -1457,8 +1459,8 @@ static void dbgPrintInitInfo(void) iMainMsgQueueNumWorkers, iMainMsgQtoWrkShutdown, iMainMsgQPersistUpdCnt); DBGPRINTF("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n", iMainMsgQtoQShutdown, iMainMsgQtoActShutdown, iMainMsgQtoEnq); - DBGPRINTF("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n", - iMainMsgQHighWtrMark, iMainMsgQLowWtrMark, iMainMsgQDiscardMark, iMainMsgQDiscardSeverity); + DBGPRINTF("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d, light-delay %d\n", + iMainMsgQHighWtrMark, iMainMsgQLowWtrMark, iMainMsgQDiscardMark, iMainMsgQDiscardSeverity, iMainMsgQLightDlyMark); DBGPRINTF("Main queue save on shutdown %d, max disk space allowed %lld\n", bMainMsgQSaveOnShutdown, iMainMsgQueMaxDiskSpace); /* TODO: add @@ -1574,6 +1576,7 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark); setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark); setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark); + setQPROP(qqueueSetiLightDlyMrk, "$MainMsgQueueLightDelayMark", iMainMsgQLightDlyMark); setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity); setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); @@ -2051,6 +2054,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuelowwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQLowWtrMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardmark", 0, eCmdHdlrInt, NULL, &iMainMsgQDiscardMark, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuelightdelaymark", 0, eCmdHdlrInt, NULL, &iMainMsgQLightDlyMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardseverity", 0, eCmdHdlrSeverity, NULL, &iMainMsgQDiscardSeverity, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuecheckpointinterval", 0, eCmdHdlrInt, NULL, &iMainMsgQPersistUpdCnt, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesyncqueuefiles", 0, eCmdHdlrBinary, NULL, &bMainMsgQSyncQeueFiles, NULL)); -- cgit v1.2.3 From 5c09faee34befd6c2fa117055928c810ccf86f91 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 22 Feb 2012 09:43:25 +0100 Subject: queue: lightdelay config: keep default of 70% until mark is explicitely set --- tools/syslogd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4c537570..c0e663d2 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -262,7 +262,7 @@ static uchar *pszConfDAGFile = NULL; /* name of config DAG file, non-NULL mea qqueue_t *pMsgQueue = NULL; /* the main message queue */ static int iMainMsgQueueSize = 10000; /* size of the main message queue above */ static int iMainMsgQHighWtrMark = 8000; /* high water mark for disk-assisted queues */ -static int iMainMsgQLightDlyMark = 7000; /* light delay mark for disk-assisted queues */ +static int iMainMsgQLightDlyMark = -1; /* light delay mark for disk-assisted queues */ static int iMainMsgQLowWtrMark = 2000; /* low water mark for disk-assisted queues */ static int iMainMsgQDiscardMark = 9800; /* begin to discard messages */ static int iMainMsgQDiscardSeverity = 8; /* by default, discard nothing to prevent unintentional loss */ @@ -301,7 +301,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a pszMainMsgQFName = NULL; iMainMsgQueueSize = 10000; iMainMsgQHighWtrMark = 8000; - iMainMsgQLightDlyMark = 7000; + iMainMsgQLightDlyMark = -1; iMainMsgQLowWtrMark = 2000; iMainMsgQDiscardMark = 9800; iMainMsgQDiscardSeverity = 8; @@ -1576,7 +1576,9 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark); setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark); setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark); - setQPROP(qqueueSetiLightDlyMrk, "$MainMsgQueueLightDelayMark", iMainMsgQLightDlyMark); + if(iMainMsgQLightDlyMark > 0) { + setQPROP(qqueueSetiLightDlyMrk, "$MainMsgQueueLightDelayMark", iMainMsgQLightDlyMark); + } setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity); setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); -- cgit v1.2.3 From 9601b181cf5d2166e2c813973e82a4b48002e83f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 6 Mar 2012 17:26:04 +0100 Subject: added capability to use a local interface IP address as fromhost-ip for imuxsock new config directives: $IMUXSockLocalIPIF --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index c0e663d2..02a0dad6 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2712,6 +2712,7 @@ int realMain(int argc, char **argv) CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); } else { CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); + int i; } if((p = (uchar*)strchr((char*)LocalHostName, '.'))) -- cgit v1.2.3 From 2c7604f45b1c416180794f2c4f29ba25504f8d47 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 12 Mar 2012 17:01:44 +0100 Subject: cosmetic: removed stray definition --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 92c539c7..33330a95 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2725,7 +2725,6 @@ int realMain(int argc, char **argv) CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); } else { CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - int i; } if((p = (uchar*)strchr((char*)LocalHostName, '.'))) -- cgit v1.2.3 From 49ec54d36984b9e91da7bd41e56e65dac22ce830 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 21 Mar 2012 11:43:45 +0100 Subject: milestone: added capability to use a local interface IP address as fromhost-ip ... for locally originating messages. New directive $LocalHostIPIF. Note that not all modules yet support this new directive - next step... --- tools/syslogd.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 02a0dad6..9cd3c9ca 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -199,7 +199,6 @@ static rsRetVal GlobalClassExit(void); #endif static prop_t *pInternalInputName = NULL; /* there is only one global inputName for all internally-generated messages */ -static prop_t *pLocalHostIP = NULL; /* there is only one global IP for all internally-generated messages */ static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */ static char *PidFile = _PATH_LOGPID; /* read-only after startup */ @@ -545,7 +544,8 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) MsgSetRawMsgWOSize(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); - MsgSetRcvFromIP(pMsg, pLocalHostIP); +dbgprintf("ZZZZ: pLocalHostIPIF used!\n"); + MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP()); MsgSetMSGoffs(pMsg, 0); /* check if we have an error code associated and, if so, * adjust the tag. -- rgerhards, 2008-06-27 @@ -1109,8 +1109,6 @@ die(int sig) /* destruct our global properties */ if(pInternalInputName != NULL) prop.Destruct(&pInternalInputName); - if(pLocalHostIP != NULL) - prop.Destruct(&pLocalHostIP); /* terminate the remaining classes */ GlobalClassExit(); @@ -2660,10 +2658,6 @@ int realMain(int argc, char **argv) CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslgod") - 1)); CHKiRet(prop.ConstructFinalize(pInternalInputName)); - CHKiRet(prop.Construct(&pLocalHostIP)); - CHKiRet(prop.SetString(pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1)); - CHKiRet(prop.ConstructFinalize(pLocalHostIP)); - /* get our host and domain names - we need to do this early as we may emit * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 */ @@ -2712,7 +2706,6 @@ int realMain(int argc, char **argv) CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); } else { CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - int i; } if((p = (uchar*)strchr((char*)LocalHostName, '.'))) -- cgit v1.2.3 From d0a73d3449511392b115ca078517ff659aafe23d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 11 Apr 2012 11:18:41 +0200 Subject: bugfix: hostname was not requeried on HUP Thanks to Marius Tomaschewski for reporting this bug. --- tools/syslogd.c | 165 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 93 insertions(+), 72 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 0b7bbc96..183decb1 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -154,6 +154,7 @@ DEFobjCurrIf(net) /* TODO: make go away! */ /* forward definitions */ static rsRetVal GlobalClassExit(void); +static rsRetVal queryLocalHostname(void); #ifndef _PATH_LOGCONF @@ -1897,6 +1898,11 @@ DEFFUNC_llExecFunc(doHUPActions) * is *NOT* the sighup handler. The signal is recorded by the handler, that record * detected inside the mainloop and then this function is called to do the * real work. -- rgerhards, 2008-10-22 + * Note: there is a VERY slim chance of a data race when the hostname is reset. + * We prefer to take this risk rather than sync all accesses, because to the best + * of my analysis it can not really hurt (the actual property is reference-counted) + * but the sync would require some extra CPU for *each* message processed. + * rgerhards, 2012-04-11 */ static inline void doHUP(void) @@ -1912,6 +1918,7 @@ doHUP(void) logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); } + queryLocalHostname(); /* re-read our name */ ruleset.IterateAllActions(doHUPActions, NULL); } @@ -2329,6 +2336,90 @@ GlobalClassExit(void) } +/* query our host and domain names - we need to do this early as we may emit + * rgerhards, 2012-04-11 + */ +static rsRetVal +queryLocalHostname(void) +{ + uchar *LocalHostName; + uchar *LocalDomain; + uchar *LocalFQDNName; + uchar *p; + struct hostent *hent; + DEFiRet; + + net.getLocalHostname(&LocalFQDNName); + CHKmalloc(LocalHostName = (uchar*) strdup((char*)LocalFQDNName)); + glbl.SetLocalFQDNName(LocalFQDNName); /* set the FQDN before we modify it */ + if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { + *p++ = '\0'; + LocalDomain = p; + } else { + LocalDomain = (uchar*)""; + + /* It's not clearly defined whether gethostname() + * should return the simple hostname or the fqdn. A + * good piece of software should be aware of both and + * we want to distribute good software. Joey + * + * Good software also always checks its return values... + * If syslogd starts up before DNS is up & /etc/hosts + * doesn't have LocalHostName listed, gethostbyname will + * return NULL. + */ + /* TODO: gethostbyname() is not thread-safe, but replacing it is + * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 + */ + hent = gethostbyname((char*)LocalHostName); + if(hent) { + int i = 0; + + if(hent->h_aliases) { + size_t hnlen; + + hnlen = strlen((char *) LocalHostName); + + for (i = 0; hent->h_aliases[i]; i++) { + if (!strncmp(hent->h_aliases[i], (char *) LocalHostName, hnlen) + && hent->h_aliases[i][hnlen] == '.') { + /* found a matching hostname */ + break; + } + } + } + + free(LocalHostName); + if(hent->h_aliases && hent->h_aliases[i]) { + CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); + } else { + CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); + } + + if((p = (uchar*)strchr((char*)LocalHostName, '.'))) + { + *p++ = '\0'; + LocalDomain = p; + } + } + } + + /* Convert to lower case to recognize the correct domain laterly */ + for(p = LocalDomain ; *p ; p++) + *p = (char)tolower((int)*p); + + /* we now have our hostname and can set it inside the global vars. + * TODO: think if all of this would better be a runtime function + * rgerhards, 2008-04-17 + */ + glbl.SetLocalHostName(LocalHostName); + glbl.SetLocalDomain(LocalDomain); + glbl.GenerateLocalHostNameProperty(); /* must be redone after conf processing, FQDN setting may have changed */ +finalize_it: + RETiRet; +} + + /* some support for command line option parsing. Any non-trivial options must be * buffered until the complete command line has been parsed. This is necessary to * prevent dependencies between the options. That, in turn, means we need to have @@ -2530,9 +2621,7 @@ int realMain(int argc, char **argv) { DEFiRet; - register uchar *p; int ch; - struct hostent *hent; extern int optind; extern char *optarg; int bEOptionWasGiven = 0; @@ -2541,9 +2630,6 @@ int realMain(int argc, char **argv) int bChDirRoot = 1; /* change the current working directory to "/"? */ char *arg; /* for command line option processing */ uchar legacyConfLine[80]; - uchar *LocalHostName; - uchar *LocalDomain; - uchar *LocalFQDNName; char cwdbuf[128]; /* buffer to obtain/display current working directory */ /* first, parse the command line options. We do not carry out any actual work, just @@ -2651,7 +2737,7 @@ int realMain(int argc, char **argv) /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInternalInputName)); - CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslgod") - 1)); + CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd") - 1)); CHKiRet(prop.ConstructFinalize(pInternalInputName)); CHKiRet(prop.Construct(&pLocalHostIP)); @@ -2661,72 +2747,7 @@ int realMain(int argc, char **argv) /* get our host and domain names - we need to do this early as we may emit * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 */ - net.getLocalHostname(&LocalFQDNName); - CHKmalloc(LocalHostName = (uchar*) strdup((char*)LocalFQDNName)); - glbl.SetLocalFQDNName(LocalFQDNName); /* set the FQDN before we modify it */ - if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { - *p++ = '\0'; - LocalDomain = p; - } else { - LocalDomain = (uchar*)""; - - /* It's not clearly defined whether gethostname() - * should return the simple hostname or the fqdn. A - * good piece of software should be aware of both and - * we want to distribute good software. Joey - * - * Good software also always checks its return values... - * If syslogd starts up before DNS is up & /etc/hosts - * doesn't have LocalHostName listed, gethostbyname will - * return NULL. - */ - /* TODO: gethostbyname() is not thread-safe, but replacing it is - * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 - */ - hent = gethostbyname((char*)LocalHostName); - if(hent) { - int i = 0; - - if(hent->h_aliases) { - size_t hnlen; - - hnlen = strlen((char *) LocalHostName); - - for (i = 0; hent->h_aliases[i]; i++) { - if (!strncmp(hent->h_aliases[i], (char *) LocalHostName, hnlen) - && hent->h_aliases[i][hnlen] == '.') { - /* found a matching hostname */ - break; - } - } - } - - free(LocalHostName); - if(hent->h_aliases && hent->h_aliases[i]) { - CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); - } else { - CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - } - - if((p = (uchar*)strchr((char*)LocalHostName, '.'))) - { - *p++ = '\0'; - LocalDomain = p; - } - } - } - - /* Convert to lower case to recognize the correct domain laterly */ - for(p = LocalDomain ; *p ; p++) - *p = (char)tolower((int)*p); - - /* we now have our hostname and can set it inside the global vars. - * TODO: think if all of this would better be a runtime function - * rgerhards, 2008-04-17 - */ - glbl.SetLocalHostName(LocalHostName); - glbl.SetLocalDomain(LocalDomain); - glbl.GenerateLocalHostNameProperty(); /* must be redone after conf processing, FQDN setting may have changed */ + queryLocalHostname(); /* initialize the objects */ if((iRet = modInitIminternal()) != RS_RET_OK) { -- cgit v1.2.3 From a3a0acadb4aa9d09bde3a6951557939b0a0eeda6 Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Wed, 11 Apr 2012 14:39:42 +0200 Subject: Allocate LocalDomain as new string LocalDomain points to "" or the domain in LocalHostName, allocate as new string before passing to SetLocalDomain or free will fail later. Signed-off-by: Marius Tomaschewski --- tools/syslogd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 183decb1..5e94beab 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2404,6 +2404,9 @@ queryLocalHostname(void) } } + /* LocalDomain is "" or part of LocalHostName, allocate a new string */ + CHKmalloc(LocalDomain = (uchar*)strdup(LocalDomain)); + /* Convert to lower case to recognize the correct domain laterly */ for(p = LocalDomain ; *p ; p++) *p = (char)tolower((int)*p); -- cgit v1.2.3 From d749dadcc30e35448894a152fb0ddf77d60b8300 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 12 Apr 2012 10:14:32 +0200 Subject: imuxsock: do not cache hostname --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5e94beab..af63b111 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -21,7 +21,7 @@ * For further information, please see http://www.rsyslog.com * * rsyslog - An Enhanced syslogd Replacement. - * Copyright 2003-2009 Rainer Gerhards and Adiscon GmbH. + * Copyright 2003-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * -- cgit v1.2.3 From 8597affe159dfd44e75bcc72a1ce42eff61da96e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 3 May 2012 08:49:05 +0200 Subject: debug: slightly improved debug info for input module startup --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index af63b111..93f37e4a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1489,6 +1489,7 @@ runInputModules(void) pMod = module.GetNxtType(NULL, eMOD_IN); while(pMod != NULL) { if(pMod->mod.im.bCanRun) { + DBGPRINTF("trying to start input module '%s'\n", pMod->pszName); /* activate here */ bNeedsCancel = (pMod->isCompatibleWithFeature(sFEATURENonCancelInputTermination) == RS_RET_OK) ? 0 : 1; -- cgit v1.2.3 From 8ce2e3917705186cc708faa68d6b3faeebd0fa32 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 3 May 2012 18:40:31 +0200 Subject: cleanup no longer used variable --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 04379dfb..06fd4cd4 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1781,7 +1781,6 @@ doGlblProcessInit(void) int realMain(int argc, char **argv) { rsRetVal localRet; - register uchar *p; int ch; extern int optind; extern char *optarg; -- cgit v1.2.3 From af968e6ef9f146987a858743df3d9f64d3bb0661 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 4 May 2012 09:30:47 +0200 Subject: cleanup: removing no longer needed macros --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 93f37e4a..98f06627 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2406,7 +2406,7 @@ queryLocalHostname(void) } /* LocalDomain is "" or part of LocalHostName, allocate a new string */ - CHKmalloc(LocalDomain = (uchar*)strdup(LocalDomain)); + CHKmalloc(LocalDomain = (uchar*)strdup((char*)LocalDomain)); /* Convert to lower case to recognize the correct domain laterly */ for(p = LocalDomain ; *p ; p++) -- cgit v1.2.3 From a4980cbde24b48c5540435d27d01651d5ca46d03 Mon Sep 17 00:00:00 2001 From: Tomas Heinrich Date: Tue, 29 May 2012 11:21:50 +0200 Subject: bugfix: if debug message could end up in log file when forking if rsyslog was set to auto-background (thus fork, the default) and debug mode to stdout was enabled, debug messages ended up in the first log file opened. Currently, stdout logging is completely disabled in forking mode (but writing to the debug log file is still possible). This is a change in behaviour, which is under review. If it causes problems to you, please let us know. Signed-off-by: Rainer Gerhards --- tools/syslogd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 98f06627..f3f27598 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2514,6 +2514,9 @@ doGlblProcessInit(void) sigAct.sa_handler = doexit; sigaction(SIGTERM, &sigAct, NULL); + /* stop writing debug messages to stdout (if debugging is on) */ + stddbg = -1; + if (fork()) { /* Parent process */ -- cgit v1.2.3 From 04399f5ebe22d4f0c228fceb6766f33a49892e38 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 29 May 2012 12:01:07 +0200 Subject: added --enable-debugless configure option for very high demanding environments This actually at compile time disables a lot of debug code, resulting in some speedup (but serious loss of debugging capabilities) --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 7d995cc2..930920b7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -448,7 +448,6 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) MsgSetRawMsgWOSize(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); -dbgprintf("ZZZZ: pLocalHostIPIF used!\n"); MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP()); MsgSetMSGoffs(pMsg, 0); /* check if we have an error code associated and, if so, -- cgit v1.2.3 From 21fc2ac97775bf223f9b4882cb4b35898bce8984 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 31 May 2012 13:01:07 +0200 Subject: cosmetic: slightly improved debug output --- tools/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index f3f27598..7872cb5f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2506,7 +2506,7 @@ doGlblProcessInit(void) if( !(Debug == DEBUG_FULL || NoFork) ) { - DBGPRINTF("Checking pidfile.\n"); + DBGPRINTF("Checking pidfile '%s'.\n", PidFile); if (!check_pid(PidFile)) { memset(&sigAct, 0, sizeof (sigAct)); @@ -2579,7 +2579,7 @@ doGlblProcessInit(void) } /* tuck my process id away */ - DBGPRINTF("Writing pidfile %s.\n", PidFile); + DBGPRINTF("Writing pidfile '%s'.\n", PidFile); if (!check_pid(PidFile)) { if (!write_pid(PidFile)) -- cgit v1.2.3 From 55659b96a38d926445c9ae4123df4b1d29e18c32 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 4 Jun 2012 12:01:24 +0200 Subject: add small delay (50ms) after sending shutdown message There seem to be cases where the shutdown message is otherwise not processed, not even on an idle system. Thanks to Marcin for bringing this problem up. --- tools/syslogd.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 7872cb5f..0988d462 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1072,6 +1072,11 @@ die(int sig) errno = 0; logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); } + /* we sleep for 50ms to give the queue a chance to pick up the exit message; + * otherwise we have seen cases where the message did not make it to log + * files, even on idle systems. + */ + srSleep(0, 50); /* drain queue (if configured so) and stop main queue worker thread pool */ DBGPRINTF("Terminating main queue...\n"); -- cgit v1.2.3 From dec9bcfe2a869b0f70b5f2a18e08a0322ebf5517 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 12 Jun 2012 13:58:13 +0200 Subject: bugfix "$PreserveFQDN on" was not honored in some modules Thanks to bodik for reporting this bug. --------------------------------------------- --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 0988d462..cbbb66bc 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2200,6 +2200,7 @@ static rsRetVal mainThread() if(myPid != ppid) kill(ppid, SIGTERM); + glbl.GenerateLocalHostNameProperty(); /* regenerate, FQDN setting may have changed */ /* If instructed to do so, we now drop privileges. Note that this is not 100% secure, * because outputs are already running at this time. However, we can implement -- cgit v1.2.3 From c8324b3460a85d57ca1bcfa481168d566069a0d1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 12 Jun 2012 18:52:32 +0200 Subject: milestone: regex is compiled from script based filter --- tools/syslogd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 82ad79b9..b84aae22 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -125,6 +125,7 @@ #include "rsconf.h" #include "dnscache.h" #include "sd-daemon.h" +#include "rainerscript.h" /* definitions for objects we access */ DEFobjCurrIf(obj) @@ -1445,6 +1446,7 @@ InitGlobalClasses(void) pErrObj = "net"; CHKiRet(objUse(net, LM_NET_FILENAME)); dnscacheInit(); + initRainerscript(); finalize_it: if(iRet != RS_RET_OK) { -- cgit v1.2.3 From bf85d81790a26945e404c6fdfdddad5eadbaa371 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 25 Jun 2012 12:35:46 +0200 Subject: implemented freeCnf() module interface & fixed some mem leaks The interface was actually not present in older versions, even though some modules already used it. The implementation was now done, and not in 6.3/6.4 because the resulting memory leak was ultra-slim and the new interface handling has some potential to seriously break things. Not the kind of thing you want to add in late beta state, if avoidable. --- tools/syslogd.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index b84aae22..20a4aa12 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -786,18 +786,6 @@ static void doDie(int sig) } -/* This function frees all dynamically allocated memory for program termination. - * It must be called only immediately before exit(). It is primarily an aid - * for memory debuggers, which prevents cluttered outupt. - * rgerhards, 2008-03-20 - */ -static void -freeAllDynMemForTermination(void) -{ - free(ourConf->globals.pszConfDAGFile); -} - - /* Finalize and destruct all actions. */ static inline void @@ -867,14 +855,16 @@ die(int sig) destructAllActions(); DBGPRINTF("all primary multi-thread sources have been terminated - now doing aux cleanup...\n"); + + DBGPRINTF("destructing current config...\n"); + rsconf.Destruct(&runConf); + /* rger 2005-02-22 * now clean up the in-memory structures. OK, the OS * would also take care of that, but if we do it * ourselfs, this makes finding memory leaks a lot * easier. */ - tplDeleteAll(runConf); - /* de-init some modules */ modExitIminternal(); @@ -898,15 +888,8 @@ die(int sig) /* dbgClassExit MUST be the last one, because it de-inits the debug system */ dbgClassExit(); - /* free all remaining memory blocks - this is not absolutely necessary, but helps - * us keep memory debugger logs clean and this is in aid in developing. It doesn't - * cost much time, so we do it always. -- rgerhards, 2008-03-20 - */ - freeAllDynMemForTermination(); - /* NO CODE HERE - feeelAllDynMemForTermination() must be the last thing before exit()! */ - + /* NO CODE HERE - dbgClassExit() must be the last thing before exit()! */ remove_pid(PidFile); - exit(0); /* "good" exit, this is the terminator function for rsyslog [die()] */ } -- cgit v1.2.3 From 4d01df57c2f378ceda3bcc400a9df5e50a0c007b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 1 Aug 2012 10:14:37 +0200 Subject: bugfix: potential abort if output plugin logged message during shutdown note that none of the rsyslog-provided plugins does this Thanks to bodik and Rohit Prasad for alerting us on this bug and analyzing it. fixes: http://bugzilla.adiscon.com/show_bug.cgi?id=347 --- tools/syslogd.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index cbbb66bc..8fc1d1e1 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -725,11 +725,19 @@ submitMsg(msg_t *pMsg) ISOBJ_TYPE_assert(pMsg, msg); pRuleset = MsgGetRuleset(pMsg); - pQueue = (pRuleset == NULL) ? pMsgQueue : ruleset.GetRulesetQueue(pRuleset); + + /* if a plugin logs a message during shutdown, the queue may no longer exist */ + if(pQueue == NULL) { + DBGPRINTF("submitMsg() could not submit message - " + "queue does (no longer?) exist - ignored\n"); + FINALIZE; + } + MsgPrepareEnqueue(pMsg); qqueueEnqObj(pQueue, pMsg->flowCtlType, (void*) pMsg); +finalize_it: RETiRet; } @@ -750,12 +758,20 @@ multiSubmitMsg(multi_submit_t *pMultiSub) if(pMultiSub->nElem == 0) FINALIZE; + pRuleset = MsgGetRuleset(pMultiSub->ppMsgs[0]); + pQueue = (pRuleset == NULL) ? pMsgQueue : ruleset.GetRulesetQueue(pRuleset); + + /* if a plugin logs a message during shutdown, the queue may no longer exist */ + if(pQueue == NULL) { + DBGPRINTF("multiSubmitMsg() could not submit message - " + "queue does (no longer?) exist - ignored\n"); + FINALIZE; + } + for(i = 0 ; i < pMultiSub->nElem ; ++i) { MsgPrepareEnqueue(pMultiSub->ppMsgs[i]); } - pRuleset = MsgGetRuleset(pMultiSub->ppMsgs[0]); - pQueue = (pRuleset == NULL) ? pMsgQueue : ruleset.GetRulesetQueue(pRuleset); iRet = pQueue->MultiEnq(pQueue, pMultiSub); pMultiSub->nElem = 0; -- cgit v1.2.3 From d92ad440da788fea9f17bfa4b0185f12644bf714 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 22 Aug 2012 14:30:12 +0200 Subject: bugfix: multiple main queues with same queue file name were not detected This lead to queue file corruption. While the root cause is a config error, it is a bug that this important and hard to find config error was not detected by rsyslog. --- tools/syslogd.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 8fc1d1e1..d8e50327 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -231,6 +231,11 @@ typedef struct legacyOptsLL_s { } legacyOptsLL_t; legacyOptsLL_t *pLegacyOptsLL = NULL; +struct queuefilenames_s { + struct queuefilenames_s *next; + uchar *name; +} *queuefilenames = NULL; + /* global variables for config file state */ int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is the default, so if no -c option is given, we make ourselvs @@ -1031,6 +1036,14 @@ static void doDie(int sig) static void freeAllDynMemForTermination(void) { + struct queuefilenames_s *qfn, *qfnDel; + + for(qfn = queuefilenames ; qfn != NULL ; ) { + qfnDel = qfn; + qfn = qfn->next; + free(qfnDel->name); + free(qfnDel); + } free(pszMainMsgQFName); free(pModDir); free(pszConfDAGFile); @@ -1559,6 +1572,10 @@ startInputModules(void) */ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) { + struct queuefilenames_s *qfn; + uchar *qfname = NULL; + static int qfn_renamenum = 0; + uchar qfrenamebuf[1024]; DEFiRet; /* switch the message object to threaded operation, if necessary */ @@ -1584,10 +1601,32 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ } + if(pszMainMsgQFName != NULL) { + /* check if the queue file name is unique, else emit an error */ + for(qfn = queuefilenames ; qfn != NULL ; qfn = qfn->next) { + dbgprintf("check queue file name '%s' vs '%s'\n", qfn->name, pszMainMsgQFName); + if(!ustrcmp(qfn->name, pszMainMsgQFName)) { + snprintf((char*)qfrenamebuf, sizeof(qfrenamebuf), "%d-%s-%s", + ++qfn_renamenum, pszMainMsgQFName, + (pszQueueName == NULL) ? "NONAME" : (char*)pszQueueName); + qfname = ustrdup(qfrenamebuf); + errmsg.LogError(0, NO_ERRCODE, "Error: queue file name '%s' already in use " + " - using '%s' instead", pszMainMsgQFName, qfname); + break; + } + } + if(qfname == NULL) + qfname = ustrdup(pszMainMsgQFName); + qfn = malloc(sizeof(struct queuefilenames_s)); + qfn->name = qfname; + qfn->next = queuefilenames; + queuefilenames = qfn; + } + setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", iMainMsgQueMaxFileSize); setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", iMainMsgQueMaxDiskSpace); setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", iMainMsgQueDeqBatchSize); - setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", pszMainMsgQFName); + setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", qfname); setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", iMainMsgQPersistUpdCnt); setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", bMainMsgQSyncQeueFiles); setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", iMainMsgQtoQShutdown ); -- cgit v1.2.3 From 2f7586bbe415318c35b9ec6d4680c81d443a6660 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 25 Aug 2012 12:35:09 +0200 Subject: cleanup: remove left-over commented-out code --- tools/syslogd.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 90f78d25..81150677 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -215,16 +215,6 @@ int repeatinterval[2] = { 30, 60 }; /* # of secs before flush */ static pid_t ppid; /* This is a quick and dirty hack used for spliting main/startup thread */ -#if 0 -#warning need this? -//======= -typedef struct legacyOptsLL_s { - uchar *line; - struct legacyOptsLL_s *next; -} legacyOptsLL_t; -legacyOptsLL_t *pLegacyOptsLL = NULL; -#endif - struct queuefilenames_s { struct queuefilenames_s *next; uchar *name; -- cgit v1.2.3 From 200e08ac4252a0a0eca31a441e63688179baebb1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 6 Sep 2012 11:09:16 +0200 Subject: new ruleengine: some cleanup --- tools/syslogd.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 219b41ab..a30fb464 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -119,7 +119,6 @@ #include "batch.h" #include "unicode-helper.h" #include "ruleset.h" -#include "rule.h" #include "net.h" #include "prop.h" #include "rsconf.h" @@ -134,7 +133,6 @@ DEFobjCurrIf(datetime) /* TODO: make go away! */ DEFobjCurrIf(conf) DEFobjCurrIf(module) DEFobjCurrIf(errmsg) -DEFobjCurrIf(rule) DEFobjCurrIf(ruleset) DEFobjCurrIf(prop) DEFobjCurrIf(parser) @@ -1453,8 +1451,6 @@ InitGlobalClasses(void) CHKiRet(objUse(module, CORE_COMPONENT)); pErrObj = "datetime"; CHKiRet(objUse(datetime, CORE_COMPONENT)); - pErrObj = "rule"; - CHKiRet(objUse(rule, CORE_COMPONENT)); pErrObj = "ruleset"; CHKiRet(objUse(ruleset, CORE_COMPONENT)); pErrObj = "conf"; @@ -1508,7 +1504,6 @@ GlobalClassExit(void) objRelease(prop, CORE_COMPONENT); objRelease(conf, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); - objRelease(rule, CORE_COMPONENT); parserClassExit(); /* this is hack, currently core_modules do not get this automatically called */ rsconfClassExit(); /* this is hack, currently core_modules do not get this automatically called */ objRelease(datetime, CORE_COMPONENT); -- cgit v1.2.3 From c0e35e864aebef9de367f736e8b73a3f3753c7f9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 20 Sep 2012 08:31:03 +0200 Subject: bugfix: config validation run did not always return correct return state --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 219b41ab..152c27ae 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2108,6 +2108,7 @@ finalize_it: } else if(iRet != RS_RET_OK) { fprintf(stderr, "rsyslogd: run failed with error %d (see rsyslog.h " "or try http://www.rsyslog.com/e/%d to learn what that number means)\n", iRet, iRet*-1); + exit(1); } ENDfunc -- cgit v1.2.3 From 762c1a81d5ee669091c7b5b20453f4968acd21c2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 20 Sep 2012 08:41:32 +0200 Subject: bugfix: config validation run did not always return correct return state --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 81150677..5064511d 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2132,6 +2132,7 @@ finalize_it: } else if(iRet != RS_RET_OK) { fprintf(stderr, "rsyslogd: run failed with error %d (see rsyslog.h " "or try http://www.rsyslog.com/e/%d to learn what that number means)\n", iRet, iRet*-1); + exit(1); } ENDfunc -- cgit v1.2.3 From 4269e4578118f089021bc15cdd82bb0182a97aaf Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 9 Oct 2012 18:54:25 +0200 Subject: new ratelimit: interface plumbing added no actual implementation yet done --- tools/syslogd.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 8ba8edd3..bfdb5081 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -125,6 +125,7 @@ #include "dnscache.h" #include "sd-daemon.h" #include "rainerscript.h" +#include "ratelimit.h" /* definitions for objects we access */ DEFobjCurrIf(obj) @@ -417,7 +418,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla CHKiRet(prop.Destruct(&pProp)); CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hnameIP), &pProp)); CHKiRet(prop.Destruct(&pProp)); - CHKiRet(submitMsg(pMsg)); + CHKiRet(submitMsg2(pMsg, NULL)); finalize_it: RETiRet; @@ -488,7 +489,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) /* we have the queue, so we can simply provide the * message to the queue engine. */ - submitMsg(pMsg); + submitMsg2(pMsg, NULL); } finalize_it: RETiRet; @@ -624,7 +625,7 @@ int i; * rgerhards, 2008-02-13 */ rsRetVal -submitMsg(msg_t *pMsg) +submitMsg2(msg_t *pMsg, ratelimit_t *ratelimit) { qqueue_t *pQueue; ruleset_t *pRuleset; @@ -648,6 +649,11 @@ submitMsg(msg_t *pMsg) finalize_it: RETiRet; } +rsRetVal +submitMsg(msg_t *pMsg) /* backward compat. level */ +{ + return submitMsg2(pMsg, NULL); +} /* submit multiple messages at once, very similar to submitMsg, just @@ -655,7 +661,7 @@ finalize_it: * rgerhards, 2009-06-16 */ rsRetVal -multiSubmitMsg(multi_submit_t *pMultiSub) +multiSubmitMsg2(multi_submit_t *pMultiSub, ratelimit_t *ratelimit) { int i; qqueue_t *pQueue; @@ -686,6 +692,11 @@ multiSubmitMsg(multi_submit_t *pMultiSub) finalize_it: RETiRet; } +rsRetVal +multiSubmitMsg(multi_submit_t *pMultiSub) /* backward compat. level */ +{ + return multiSubmitMsg2(pMultiSub, NULL); +} @@ -1268,7 +1279,7 @@ static inline void processImInternal(void) msg_t *pMsg; while(iminternalRemoveMsg(&pMsg) == RS_RET_OK) { - submitMsg(pMsg); + submitMsg2(pMsg, NULL); } } @@ -1473,6 +1484,7 @@ InitGlobalClasses(void) CHKiRet(objUse(net, LM_NET_FILENAME)); dnscacheInit(); initRainerscript(); + ratelimitModInit(); finalize_it: if(iRet != RS_RET_OK) { @@ -1511,6 +1523,7 @@ GlobalClassExit(void) /* TODO: implement the rest of the deinit */ /* dummy "classes */ strExit(); + ratelimitModExit(); #if 0 CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ -- cgit v1.2.3 From 49fb431e0ce15da6a1e72cb541eadea3a3096ab6 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 15 Oct 2012 08:41:04 +0200 Subject: milestone: ratelimiter used in imptcp --- tools/syslogd.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index bfdb5081..e8957e13 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -699,6 +699,49 @@ multiSubmitMsg(multi_submit_t *pMultiSub) /* backward compat. level */ } +/* add a message to a multisubmit structure. This handles ratelimiting. IF + * pMultiSub == NULL, a single-message enqueue happens. */ +rsRetVal +multiSubmitAddMsg(multi_submit_t *pMultiSub, msg_t *pMsg, ratelimit_t *ratelimit) +{ + rsRetVal localRet; + DEFiRet; + + if(pMultiSub == NULL) { +dbgprintf("DDDD: multiSubmitAddMsg, not checking ratelimiter for single submit!\n"); + CHKiRet(submitMsg(pMsg)); + } else { +dbgprintf("DDDD: have multisub!\n"); + localRet = ratelimitMsg(pMsg, ratelimit); + if(localRet == RS_RET_OK_HAVE_REPMSG) { +dbgprintf("DDDD: doing repeat submit!\n"); + pMultiSub->ppMsgs[pMultiSub->nElem++] = ratelimitGetRepeatMsg(ratelimit); + if(pMultiSub->nElem == pMultiSub->maxElem) + CHKiRet(multiSubmitMsg2(pMultiSub, NULL)); + localRet = RS_RET_OK; + } + if(localRet == RS_RET_OK) { + pMultiSub->ppMsgs[pMultiSub->nElem++] = pMsg; + if(pMultiSub->nElem == pMultiSub->maxElem) + CHKiRet(multiSubmitMsg2(pMultiSub, NULL)); + } + } + +finalize_it: + RETiRet; +} + +/* flush multiSubmit, e.g. at end of read records */ +rsRetVal +multiSubmitFlush(multi_submit_t *pMultiSub) +{ + DEFiRet; +dbgprintf("DDDD: multiSubmitFlish, nElem %d\n", pMultiSub->nElem); + if(pMultiSub->nElem > 0) { + iRet = multiSubmitMsg(pMultiSub); + } + RETiRet; +} static void -- cgit v1.2.3 From 2a6ff7d53d1c30f0d7efd022cf321736870c5629 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 15 Oct 2012 08:55:12 +0200 Subject: interface cleanup (probably not final) --- tools/syslogd.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e8957e13..1eac6ccb 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -418,7 +418,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla CHKiRet(prop.Destruct(&pProp)); CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hnameIP), &pProp)); CHKiRet(prop.Destruct(&pProp)); - CHKiRet(submitMsg2(pMsg, NULL)); + CHKiRet(submitMsg2(pMsg)); finalize_it: RETiRet; @@ -489,7 +489,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) /* we have the queue, so we can simply provide the * message to the queue engine. */ - submitMsg2(pMsg, NULL); + submitMsg2(pMsg); } finalize_it: RETiRet; @@ -625,7 +625,7 @@ int i; * rgerhards, 2008-02-13 */ rsRetVal -submitMsg2(msg_t *pMsg, ratelimit_t *ratelimit) +submitMsg2(msg_t *pMsg) { qqueue_t *pQueue; ruleset_t *pRuleset; @@ -649,10 +649,11 @@ submitMsg2(msg_t *pMsg, ratelimit_t *ratelimit) finalize_it: RETiRet; } + rsRetVal -submitMsg(msg_t *pMsg) /* backward compat. level */ +submitMsg(msg_t *pMsg) { - return submitMsg2(pMsg, NULL); + return submitMsg2(pMsg); } @@ -661,7 +662,7 @@ submitMsg(msg_t *pMsg) /* backward compat. level */ * rgerhards, 2009-06-16 */ rsRetVal -multiSubmitMsg2(multi_submit_t *pMultiSub, ratelimit_t *ratelimit) +multiSubmitMsg2(multi_submit_t *pMultiSub) { int i; qqueue_t *pQueue; @@ -695,7 +696,7 @@ finalize_it: rsRetVal multiSubmitMsg(multi_submit_t *pMultiSub) /* backward compat. level */ { - return multiSubmitMsg2(pMultiSub, NULL); + return multiSubmitMsg2(pMultiSub); } @@ -717,13 +718,13 @@ dbgprintf("DDDD: have multisub!\n"); dbgprintf("DDDD: doing repeat submit!\n"); pMultiSub->ppMsgs[pMultiSub->nElem++] = ratelimitGetRepeatMsg(ratelimit); if(pMultiSub->nElem == pMultiSub->maxElem) - CHKiRet(multiSubmitMsg2(pMultiSub, NULL)); + CHKiRet(multiSubmitMsg2(pMultiSub)); localRet = RS_RET_OK; } if(localRet == RS_RET_OK) { pMultiSub->ppMsgs[pMultiSub->nElem++] = pMsg; if(pMultiSub->nElem == pMultiSub->maxElem) - CHKiRet(multiSubmitMsg2(pMultiSub, NULL)); + CHKiRet(multiSubmitMsg2(pMultiSub)); } } @@ -738,7 +739,7 @@ multiSubmitFlush(multi_submit_t *pMultiSub) DEFiRet; dbgprintf("DDDD: multiSubmitFlish, nElem %d\n", pMultiSub->nElem); if(pMultiSub->nElem > 0) { - iRet = multiSubmitMsg(pMultiSub); + iRet = multiSubmitMsg2(pMultiSub); } RETiRet; } @@ -1322,7 +1323,7 @@ static inline void processImInternal(void) msg_t *pMsg; while(iminternalRemoveMsg(&pMsg) == RS_RET_OK) { - submitMsg2(pMsg, NULL); + submitMsg(pMsg); } } -- cgit v1.2.3 From 3806643baa9fe0d50fb36080e4ab3a078b8a5952 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 15 Oct 2012 11:19:22 +0200 Subject: ratelimiter: enable thread-safe mode & (related) API changes --- tools/syslogd.c | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 1eac6ccb..a56cea94 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -700,38 +700,6 @@ multiSubmitMsg(multi_submit_t *pMultiSub) /* backward compat. level */ } -/* add a message to a multisubmit structure. This handles ratelimiting. IF - * pMultiSub == NULL, a single-message enqueue happens. */ -rsRetVal -multiSubmitAddMsg(multi_submit_t *pMultiSub, msg_t *pMsg, ratelimit_t *ratelimit) -{ - rsRetVal localRet; - DEFiRet; - - if(pMultiSub == NULL) { -dbgprintf("DDDD: multiSubmitAddMsg, not checking ratelimiter for single submit!\n"); - CHKiRet(submitMsg(pMsg)); - } else { -dbgprintf("DDDD: have multisub!\n"); - localRet = ratelimitMsg(pMsg, ratelimit); - if(localRet == RS_RET_OK_HAVE_REPMSG) { -dbgprintf("DDDD: doing repeat submit!\n"); - pMultiSub->ppMsgs[pMultiSub->nElem++] = ratelimitGetRepeatMsg(ratelimit); - if(pMultiSub->nElem == pMultiSub->maxElem) - CHKiRet(multiSubmitMsg2(pMultiSub)); - localRet = RS_RET_OK; - } - if(localRet == RS_RET_OK) { - pMultiSub->ppMsgs[pMultiSub->nElem++] = pMsg; - if(pMultiSub->nElem == pMultiSub->maxElem) - CHKiRet(multiSubmitMsg2(pMultiSub)); - } - } - -finalize_it: - RETiRet; -} - /* flush multiSubmit, e.g. at end of read records */ rsRetVal multiSubmitFlush(multi_submit_t *pMultiSub) -- cgit v1.2.3 From 34a88a7e9a9501593b6fe9f79cc96963c4da7cde Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 15 Oct 2012 16:39:36 +0200 Subject: ratelimit: added linux-like ratelimiter type --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a56cea94..f76fe8cb 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -705,7 +705,6 @@ rsRetVal multiSubmitFlush(multi_submit_t *pMultiSub) { DEFiRet; -dbgprintf("DDDD: multiSubmitFlish, nElem %d\n", pMultiSub->nElem); if(pMultiSub->nElem > 0) { iRet = multiSubmitMsg2(pMultiSub); } -- cgit v1.2.3 From bdc609639eae599d2c63bc0ba26a8c70ce718551 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 16 Oct 2012 18:58:11 +0200 Subject: cleanup: removed remains of -c option (compatibility mode) both from code & doc and emitted warning message if still used closes: http://bugzilla.adiscon.com/show_bug.cgi?id=361 Thanks to Michael Biebl for reporting & suggestions --- tools/syslogd.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5064511d..b158feb3 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -220,11 +220,6 @@ struct queuefilenames_s { uchar *name; } *queuefilenames = NULL; -/* global variables for config file state */ -int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is - the default, so if no -c option is given, we make ourselvs - as compatible to sysklogd as possible. */ -/* end global config file state variables */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ @@ -250,10 +245,9 @@ static void sighup_handler(); static int usage(void) { - fprintf(stderr, "usage: rsyslogd [-c] [-46AdnqQvwx] [-l] [-s]\n" + fprintf(stderr, "usage: rsyslogd [-46AdnqQvwx] [-l] [-s]\n" " [-f] [-i] [-N] [-M]\n" " [-u]\n" - "To run rsyslogd in native mode, use \"rsyslogd -c5 \"\n\n" "For further information see http://www.rsyslog.com/doc\n"); exit(1); /* "good" exit - done to terminate usage() */ } @@ -1862,10 +1856,7 @@ int realMain(int argc, char **argv) * split of functionality, this is no longer a problem. Thanks to varmofekoj for * suggesting this algo. * Note: where we just need to set some flags and can do so without knowledge - * of other options, we do this during the inital option processing. With later - * versions (if a dependency on -c option is introduced), we must move that code - * to other places, but I think it is quite appropriate and saves code to do this - * only when actually neeeded. + * of other options, we do this during the inital option processing. * rgerhards, 2008-04-04 */ while((ch = getopt(argc, argv, "46a:Ac:def:g:hi:l:m:M:nN:op:qQr::s:t:T:u:vwx")) != EOF) { @@ -1896,7 +1887,7 @@ int realMain(int argc, char **argv) CHKiRet(bufOptAdd(ch, optarg)); break; case 'c': /* compatibility mode */ - iCompatibilityMode = atoi(optarg); + fprintf(stderr, "rsyslogd: error: option -c is no longer supported - ignored"); break; case 'd': /* debug - must be handled now, so that debug is active during init! */ debugging_on = 1; @@ -1920,8 +1911,8 @@ int realMain(int argc, char **argv) if(argc - optind) usage(); - DBGPRINTF("rsyslogd %s startup, compatibility mode %d, module path '%s', cwd:%s\n", - VERSION, iCompatibilityMode, glblModPath == NULL ? "" : (char*)glblModPath, + DBGPRINTF("rsyslogd %s startup, module path '%s', cwd:%s\n", + VERSION, glblModPath == NULL ? "" : (char*)glblModPath, getcwd(cwdbuf, sizeof(cwdbuf))); /* we are done with the initial option parsing and processing. Now we init the system. */ -- cgit v1.2.3 From fb53a0420f84400628fea810306a9936933ec875 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 19 Oct 2012 10:04:59 +0200 Subject: cleanup --- tools/syslogd.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 2e5d08cd..a8c5d887 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -489,44 +489,6 @@ finalize_it: RETiRet; } -/* check message against ACL set - * rgerhards, 2009-11-16 - */ -#if 0 -static inline rsRetVal -chkMsgAgainstACL() { - /* if we reach this point, we had a good receive and can process the packet received */ - /* check if we have a different sender than before, if so, we need to query some new values */ - if(net.CmpHost(&frominet, frominetPrev, socklen) != 0) { - CHKiRet(net.cvthname(&frominet, fromHost, fromHostFQDN, fromHostIP)); - memcpy(frominetPrev, &frominet, socklen); /* update cache indicator */ - /* Here we check if a host is permitted to send us - * syslog messages. If it isn't, we do not further - * process the message but log a warning (if we are - * configured to do this). - * rgerhards, 2005-09-26 - */ - *pbIsPermitted = net.isAllowedSender((uchar*)"UDP", - (struct sockaddr *)&frominet, (char*)fromHostFQDN); - - if(!*pbIsPermitted) { - DBGPRINTF("%s is not an allowed sender\n", (char*)fromHostFQDN); - if(glbl.GetOption_DisallowWarning) { - time_t tt; - - datetime.GetTime(&tt); - if(tt > ttLastDiscard + 60) { - ttLastDiscard = tt; - errmsg.LogError(0, NO_ERRCODE, - "UDP message from disallowed sender %s discarded", - (char*)fromHost); - } - } - } - } -} -#endif - /* preprocess a batch of messages, that is ready them for actual processing. This is done * as a first stage and totally in parallel to any other worker active in the system. So -- cgit v1.2.3 From 9516e8f99f0385eb7948df9b6af87b51d3462ccb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 19 Oct 2012 11:01:37 +0200 Subject: ratelimit: add default ratelimiter --- tools/syslogd.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a8c5d887..cb6a47cd 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -221,6 +221,7 @@ struct queuefilenames_s { } *queuefilenames = NULL; +static ratelimit_t *dflt_ratelimiter = NULL; /* ratelimiter for submits without explicit one */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */ @@ -432,6 +433,12 @@ submitErrMsg(int iErr, uchar *msg) } +static inline rsRetVal +submitMsgWithDfltRatelimiter(msg_t *pMsg) +{ + return ratelimitAddMsg(dflt_ratelimiter, NULL, pMsg); +} + /* rgerhards 2004-11-09: the following is a function that can be used * to log a message orginating from the syslogd itself. */ @@ -483,7 +490,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) /* we have the queue, so we can simply provide the * message to the queue engine. */ - submitMsg2(pMsg); + submitMsgWithDfltRatelimiter(pMsg); } finalize_it: RETiRet; @@ -594,7 +601,7 @@ submitMsg2(msg_t *pMsg) /* if a plugin logs a message during shutdown, the queue may no longer exist */ if(pQueue == NULL) { - DBGPRINTF("submitMsg() could not submit message - " + DBGPRINTF("submitMsg2() could not submit message - " "queue does (no longer?) exist - ignored\n"); FINALIZE; } @@ -609,7 +616,7 @@ finalize_it: rsRetVal submitMsg(msg_t *pMsg) { - return submitMsg2(pMsg); + return submitMsgWithDfltRatelimiter(pMsg); } @@ -1246,7 +1253,7 @@ static inline void processImInternal(void) msg_t *pMsg; while(iminternalRemoveMsg(&pMsg) == RS_RET_OK) { - submitMsg(pMsg); + submitMsgWithDfltRatelimiter(pMsg); } } @@ -2023,6 +2030,9 @@ int realMain(int argc, char **argv) } CHKiRet(localRet); + CHKiRet(ratelimitNew(&dflt_ratelimiter, "rsyslogd", NULL)); + /* TODO: add linux-type limiting capability */ + if(bChDirRoot) { if(chdir("/") != 0) fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); -- cgit v1.2.3 From 95fefbc12a71c26e02bb1de8628b3f70a6856b08 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 22 Oct 2012 11:20:07 +0200 Subject: prepare for 7.20 stable release & minor things The most important real code chane is the initialization of the epoll control set. This should just be cosmetic (valgrind warnings), as all data we actually use already was properly initialized. --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index edb546a1..c5801555 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1858,7 +1858,7 @@ int realMain(int argc, char **argv) CHKiRet(bufOptAdd(ch, optarg)); break; case 'c': /* compatibility mode */ - fprintf(stderr, "rsyslogd: error: option -c is no longer supported - ignored"); + fprintf(stderr, "rsyslogd: error: option -c is no longer supported - ignored\n"); break; case 'd': /* debug - must be handled now, so that debug is active during init! */ debugging_on = 1; -- cgit v1.2.3 From 3d41da36b8e7e3980579d67600cf42128e5c3aee Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 23 Oct 2012 11:22:56 +0200 Subject: remove "last message repeated n times" from rsyslog output part --- tools/syslogd.c | 78 +++------------------------------------------------------ 1 file changed, 3 insertions(+), 75 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index cb6a47cd..3e85108f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -44,7 +44,6 @@ #include "rsyslog.h" #define DEFUPRI (LOG_USER|LOG_NOTICE) -#define TIMERINTVL 30 /* interval for checking flush, mark */ #include #include @@ -204,13 +203,6 @@ static int bFinished = 0; /* used by termination signal handler, read-only excep */ int iConfigVerify = 0; /* is this just a config verify run? */ -/* Intervals at which we flush out "message repeated" messages, - * in seconds after previous message is logged. After each flush, - * we move to the next interval until we reach the largest. - * TODO: this shall go into action object! -- rgerhards, 2008-01-29 - */ -int repeatinterval[2] = { 30, 60 }; /* # of secs before flush */ - #define LIST_DELIMITER ':' /* delimiter between two hosts */ static pid_t ppid; /* This is a quick and dirty hack used for spliting main/startup thread */ @@ -691,43 +683,6 @@ reapchild() } -/* helper to doFlushRptdMsgs() to flush the individual action links via llExecFunc - * rgerhards, 2007-08-02 - */ -DEFFUNC_llExecFunc(flushRptdMsgsActions) -{ - action_t *pAction = (action_t*) pData; - assert(pAction != NULL); - - BEGINfunc - d_pthread_mutex_lock(&pAction->mutAction); - /* TODO: time() performance: the call below could be moved to - * the beginn of the llExec(). This makes it slightly less correct, but - * in an acceptable way. -- rgerhards, 2008-09-16 - */ - if (pAction->f_prevcount && datetime.GetTime(NULL) >= REPEATTIME(pAction)) { - DBGPRINTF("flush %s: repeated %d times, %d sec.\n", - module.GetStateName(pAction->pMod), pAction->f_prevcount, - repeatinterval[pAction->f_repeatcount]); - actionWriteToAction(pAction); - BACKOFF(pAction); - } - d_pthread_mutex_unlock(&pAction->mutAction); - - ENDfunc - return RS_RET_OK; /* we ignore errors, we can not do anything either way */ -} - - -/* This method flushes repeat messages. - */ -static void -doFlushRptdMsgs(void) -{ - ruleset.IterateAllActions(runConf, flushRptdMsgsActions, NULL); -} - - static void debug_switch() { time_t tTime; @@ -1320,49 +1275,22 @@ mainloop(void) while(!bFinished){ /* this is now just a wait - please note that we do use a near-"eternal" - * timeout of 1 day if we do not have repeated message reduction turned on - * (which it is not by default). This enables us to help safe the environment + * timeout of 1 day. This enables us to help safe the environment * by not unnecessarily awaking rsyslog on a regular tick (just think * powertop, for example). In that case, we primarily wait for a signal, * but a once-a-day wakeup should be quite acceptable. -- rgerhards, 2008-06-09 */ - tvSelectTimeout.tv_sec = (runConf->globals.bReduceRepeatMsgs == 1) ? TIMERINTVL : 86400 /*1 day*/; - //tvSelectTimeout.tv_sec = TIMERINTVL; /* TODO: change this back to the above code when we have a better solution for apc */ + tvSelectTimeout.tv_sec = 86400 /*1 day*/; tvSelectTimeout.tv_usec = 0; select(1, NULL, NULL, NULL, &tvSelectTimeout); if(bFinished) - break; /* exit as quickly as possible - see long comment below */ - - /* If we received a HUP signal, we call doFlushRptdMsgs() a bit early. This - * doesn't matter, because doFlushRptdMsgs() checks timestamps. What may happen, - * however, is that the too-early call may lead to a bit too-late output - * of "last message repeated n times" messages. But that is quite acceptable. - * rgerhards, 2007-12-21 - * ... and just to explain, we flush here because that is exactly what the mainloop - * shall do - provide a periodic interval in which not-yet-flushed messages will - * be flushed. Be careful, there is a potential race condition: doFlushRptdMsgs() - * needs to aquire a lock on the action objects. If, however, long-running consumers - * cause the main queue worker threads to lock them for a long time, we may receive - * a starvation condition, resulting in the mainloop being held on lock for an extended - * period of time. That, in turn, could lead to unresponsiveness to termination - * requests. It is especially important that the bFinished flag is checked before - * doFlushRptdMsgs() is called (I know because I ran into that situation). I am - * not yet sure if the remaining probability window of a termination-related - * problem is large enough to justify changing the code - I would consider it - * extremely unlikely that the problem ever occurs in practice. Fixing it would - * require not only a lot of effort but would cost considerable performance. So - * for the time being, I think the remaining risk can be accepted. - * rgerhards, 2008-01-10 - */ - if(runConf->globals.bReduceRepeatMsgs == 1) - doFlushRptdMsgs(); + break; /* exit as quickly as possible */ if(bHadHUP) { doHUP(); bHadHUP = 0; continue; } - // TODO: remove execScheduled(); /* handle Apc calls (if any) */ } ENDfunc } -- cgit v1.2.3 From 99d6dc01d22b1283e992cec481e4f2a03ee74340 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 23 Oct 2012 17:12:09 +0200 Subject: rate-limit rsyslog internal messages a special ratelimiter is used; it's linux-type ratelimit settings are currently hardcoded --- tools/syslogd.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 2195e51c..d66bfb81 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -214,6 +214,7 @@ struct queuefilenames_s { static ratelimit_t *dflt_ratelimiter = NULL; /* ratelimiter for submits without explicit one */ +static ratelimit_t *internalMsg_ratelimiter = NULL; /* ratelimiter for rsyslog-own messages */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */ @@ -482,7 +483,8 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) /* we have the queue, so we can simply provide the * message to the queue engine. */ - submitMsgWithDfltRatelimiter(pMsg); + ratelimitAddMsg(internalMsg_ratelimiter, NULL, pMsg); + //submitMsgWithDfltRatelimiter(pMsg); } finalize_it: RETiRet; @@ -1958,8 +1960,11 @@ int realMain(int argc, char **argv) } CHKiRet(localRet); - CHKiRet(ratelimitNew(&dflt_ratelimiter, "rsyslogd", NULL)); + CHKiRet(ratelimitNew(&dflt_ratelimiter, "rsyslogd", "dflt")); /* TODO: add linux-type limiting capability */ + CHKiRet(ratelimitNew(&internalMsg_ratelimiter, "rsyslogd", "internal_messages")); + ratelimitSetLinuxLike(internalMsg_ratelimiter, 5, 500); + /* TODO: make internalMsg ratelimit settings configurable */ if(bChDirRoot) { if(chdir("/") != 0) -- cgit v1.2.3 From 0d762b750988d47cfec96ee6e3bdca9ea15ecc96 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 27 Oct 2012 14:41:56 +0200 Subject: add -D rsyslogd option to enable config parser debug mode --- tools/syslogd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index c5801555..05cbfc13 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -93,6 +93,8 @@ #include #endif +extern int yydebug; /* interface to flex */ + #include #include "pidfile.h" @@ -1830,7 +1832,7 @@ int realMain(int argc, char **argv) * of other options, we do this during the inital option processing. * rgerhards, 2008-04-04 */ - while((ch = getopt(argc, argv, "46a:Ac:def:g:hi:l:m:M:nN:op:qQr::s:t:T:u:vwx")) != EOF) { + while((ch = getopt(argc, argv, "46a:Ac:dDef:g:hi:l:m:M:nN:op:qQr::s:t:T:u:vwx")) != EOF) { switch((char)ch) { case '4': case '6': @@ -1863,6 +1865,10 @@ int realMain(int argc, char **argv) case 'd': /* debug - must be handled now, so that debug is active during init! */ debugging_on = 1; Debug = 1; + yydebug = 1; + break; + case 'D': /* BISON debug */ + yydebug = 1; break; case 'e': /* log every message (no repeat message supression) */ bEOptionWasGiven = 1; -- cgit v1.2.3 From c55e0a5a06e69106bc346057dd61dcb98688a4aa Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 3 Nov 2012 12:32:50 +0100 Subject: queue: change generic msg ptr (pUsr) to be of msg_t type --- tools/syslogd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e347794b..a2ce6469 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -514,10 +514,10 @@ preprocessBatch(batch_t *pBatch) { DEFiRet; bSingleRuleset = 1; - batchRuleset = (pBatch->nElem > 0) ? ((msg_t*) pBatch->pElem[0].pUsrp)->pRuleset : NULL; + batchRuleset = (pBatch->nElem > 0) ? pBatch->pElem[0].pMsg->pRuleset : NULL; for(i = 0 ; i < pBatch->nElem && !*(pBatch->pbShutdownImmediate) ; i++) { - pMsg = (msg_t*) pBatch->pElem[i].pUsrp; + pMsg = pBatch->pElem[i].pMsg; if((pMsg->msgFlags & NEEDS_ACLCHK_U) != 0) { DBGPRINTF("msgConsumer: UDP ACL must be checked for message (hostname-based)\n"); if(net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, fromHostIP) != RS_RET_OK) @@ -603,7 +603,7 @@ submitMsg2(msg_t *pMsg) } MsgPrepareEnqueue(pMsg); - qqueueEnqObj(pQueue, pMsg->flowCtlType, (void*) pMsg); + qqueueEnqMsg(pQueue, pMsg->flowCtlType, pMsg); finalize_it: RETiRet; -- cgit v1.2.3 From 8b5f57a2c6b99944d2de885a1f7a303bdee0af48 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 9 Nov 2012 08:52:27 +0100 Subject: enabled to build without libuuid, at loss of uuid functionality this enables smoother builds on older systems that do not support libuuid. Loss of functionality should usually not matter too much as uuid support has only recently been added and is very seldom used. --- tools/syslogd.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 05cbfc13..a3cbc799 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1418,6 +1418,11 @@ static void printVersion(void) printf("\tRuntime Instrumentation (slow code):\tYes\n"); #else printf("\tRuntime Instrumentation (slow code):\tNo\n"); +#endif +#ifdef USE_LIBUUID + printf("\tuuid support:\t\t\t\tYes\n"); +#else + printf("\tuuid support:\t\t\t\tNo\n"); #endif printf("\nSee http://www.rsyslog.com for more information.\n"); } -- cgit v1.2.3 From e95584a204016c87daec0f5bee0f3f794bbba38c Mon Sep 17 00:00:00 2001 From: oxpa Date: Thu, 22 Nov 2012 12:21:07 +0100 Subject: bugfix: hostname set in rsyslog.conf was not picked up until HUP which could also mean "never" or "not for a very long time". --- tools/syslogd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 3bd0f018..5cc1b319 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2026,6 +2026,8 @@ int realMain(int argc, char **argv) } localRet = rsconf.Load(&ourConf, ConfFile); + queryLocalHostname(); /* need to re-query to pick up a changed hostname due to config */ + if(localRet == RS_RET_NONFATAL_CONFIG_ERR) { if(loadConf->globals.bAbortOnUncleanConfig) { fprintf(stderr, "rsyslogd: $AbortOnUncleanConfig is set, and config is not clean.\n" -- cgit v1.2.3 From 7182c6def360378038c9dc824b7cdf8f3d73a73f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 30 Nov 2012 12:57:26 +0100 Subject: silence compiler warnings the changes do not affect actual code execution, just keep the compile log clean. --- tools/syslogd.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5882b570..8ffafa6a 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -779,8 +779,11 @@ static void debug_switch() * a minimal delay, but it is much cleaner than the approach of doing everything * inside the signal handler. * rgerhards, 2005-10-26 - * Note: we do not call DBGPRINTF() as this may cause us to block in case something - * with the threading is wrong. + * Note: + * - we do not call DBGPRINTF() as this may cause us to block in case something + * with the threading is wrong. + * - we do not really care about the return state of write(), but we need this + * strange check we do to silence compiler warnings (thanks, Ubuntu!) */ static void doDie(int sig) { @@ -788,11 +791,13 @@ static void doDie(int sig) # define MSG2 "DoDie called 5 times - unconditional exit\n" static int iRetries = 0; /* debug aid */ dbgprintf(MSG1); - if(Debug == DEBUG_FULL) - write(1, MSG1, sizeof(MSG1) - 1); + if(Debug == DEBUG_FULL) { + if(write(1, MSG1, sizeof(MSG1) - 1)) {} + } if(iRetries++ == 4) { - if(Debug == DEBUG_FULL) - write(1, MSG2, sizeof(MSG2) - 1); + if(Debug == DEBUG_FULL) { + if(write(1, MSG2, sizeof(MSG2) - 1)) {} + } abort(); } bFinished = sig; -- cgit v1.2.3 From 62f6a7d7b4b3c9fee0fffea961a201d24a059b2c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 30 Nov 2012 17:09:28 +0100 Subject: fix missing functionality: ruleset(){} could not specify ruleset queue The "queue.xxx" parameter set was not supported, and legacy ruleset config statements did not work (by intention). The fix introduces the "queue.xxx" parameter set. It has some regression potential, but only for the new functionality. Note that using that interface it is possible to specify duplicate queue file names, which will cause trouble. This will be solved in v7.3, because there is a too-large regression potential for the v7.2 stable branch. --- tools/syslogd.c | 109 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 52 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 8ffafa6a..ae821f60 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1116,7 +1116,7 @@ finalize_it: * the time being (remember that we want to restructure config processing at large!). * rgerhards, 2009-10-27 */ -rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) +rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfparamvals *queueParams) { struct queuefilenames_s *qfn; uchar *qfname = NULL; @@ -1125,7 +1125,7 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) DEFiRet; /* switch the message object to threaded operation, if necessary */ - if(ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT || ourConf->globals.mainQ.iMainMsgQueueNumWorkers > 1) { + if(queueParams != NULL || ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT || ourConf->globals.mainQ.iMainMsgQueueNumWorkers > 1) { MsgEnableThreadSafety(); } @@ -1137,60 +1137,65 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) /* name our main queue object (it's not fatal if it fails...) */ obj.SetName((obj_t*) (*ppQueue), pszQueueName); - /* ... set some properties ... */ -# define setQPROP(func, directive, data) \ - CHKiRet_Hdlr(func(*ppQueue, data)) { \ - errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ - } -# define setQPROPstr(func, directive, data) \ - CHKiRet_Hdlr(func(*ppQueue, data, (data == NULL)? 0 : strlen((char*) data))) { \ - errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ - } + if(queueParams == NULL) { /* use legacy parameters? */ + /* ... set some properties ... */ + # define setQPROP(func, directive, data) \ + CHKiRet_Hdlr(func(*ppQueue, data)) { \ + errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ + } + # define setQPROPstr(func, directive, data) \ + CHKiRet_Hdlr(func(*ppQueue, data, (data == NULL)? 0 : strlen((char*) data))) { \ + errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ + } - if(ourConf->globals.mainQ.pszMainMsgQFName != NULL) { - /* check if the queue file name is unique, else emit an error */ - for(qfn = queuefilenames ; qfn != NULL ; qfn = qfn->next) { - dbgprintf("check queue file name '%s' vs '%s'\n", qfn->name, ourConf->globals.mainQ.pszMainMsgQFName ); - if(!ustrcmp(qfn->name, ourConf->globals.mainQ.pszMainMsgQFName)) { - snprintf((char*)qfrenamebuf, sizeof(qfrenamebuf), "%d-%s-%s", - ++qfn_renamenum, ourConf->globals.mainQ.pszMainMsgQFName, - (pszQueueName == NULL) ? "NONAME" : (char*)pszQueueName); - qfname = ustrdup(qfrenamebuf); - errmsg.LogError(0, NO_ERRCODE, "Error: queue file name '%s' already in use " - " - using '%s' instead", ourConf->globals.mainQ.pszMainMsgQFName, qfname); - break; + if(ourConf->globals.mainQ.pszMainMsgQFName != NULL) { + /* check if the queue file name is unique, else emit an error */ + for(qfn = queuefilenames ; qfn != NULL ; qfn = qfn->next) { + dbgprintf("check queue file name '%s' vs '%s'\n", qfn->name, ourConf->globals.mainQ.pszMainMsgQFName ); + if(!ustrcmp(qfn->name, ourConf->globals.mainQ.pszMainMsgQFName)) { + snprintf((char*)qfrenamebuf, sizeof(qfrenamebuf), "%d-%s-%s", + ++qfn_renamenum, ourConf->globals.mainQ.pszMainMsgQFName, + (pszQueueName == NULL) ? "NONAME" : (char*)pszQueueName); + qfname = ustrdup(qfrenamebuf); + errmsg.LogError(0, NO_ERRCODE, "Error: queue file name '%s' already in use " + " - using '%s' instead", ourConf->globals.mainQ.pszMainMsgQFName, qfname); + break; + } } + if(qfname == NULL) + qfname = ustrdup(ourConf->globals.mainQ.pszMainMsgQFName); + qfn = malloc(sizeof(struct queuefilenames_s)); + qfn->name = qfname; + qfn->next = queuefilenames; + queuefilenames = qfn; } - if(qfname == NULL) - qfname = ustrdup(ourConf->globals.mainQ.pszMainMsgQFName); - qfn = malloc(sizeof(struct queuefilenames_s)); - qfn->name = qfname; - qfn->next = queuefilenames; - queuefilenames = qfn; - } - setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", ourConf->globals.mainQ.iMainMsgQueMaxFileSize); - setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", ourConf->globals.mainQ.iMainMsgQueMaxDiskSpace); - setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", ourConf->globals.mainQ.iMainMsgQueDeqBatchSize); - setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", qfname); - setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", ourConf->globals.mainQ.iMainMsgQPersistUpdCnt); - setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", ourConf->globals.mainQ.bMainMsgQSyncQeueFiles); - setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", ourConf->globals.mainQ.iMainMsgQtoQShutdown ); - setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", ourConf->globals.mainQ.iMainMsgQtoActShutdown); - setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", ourConf->globals.mainQ.iMainMsgQtoWrkShutdown); - setQPROP(qqueueSettoEnq, "$MainMsgQueueTimeoutEnqueue", ourConf->globals.mainQ.iMainMsgQtoEnq); - setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", ourConf->globals.mainQ.iMainMsgQHighWtrMark); - setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", ourConf->globals.mainQ.iMainMsgQLowWtrMark); - setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", ourConf->globals.mainQ.iMainMsgQDiscardMark); - setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", ourConf->globals.mainQ.iMainMsgQDiscardSeverity); - setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", ourConf->globals.mainQ.iMainMsgQWrkMinMsgs); - setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", ourConf->globals.mainQ.bMainMsgQSaveOnShutdown); - setQPROP(qqueueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", ourConf->globals.mainQ.iMainMsgQDeqSlowdown); - setQPROP(qqueueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", ourConf->globals.mainQ.iMainMsgQueueDeqtWinFromHr); - setQPROP(qqueueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", ourConf->globals.mainQ.iMainMsgQueueDeqtWinToHr); - -# undef setQPROP -# undef setQPROPstr + setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", ourConf->globals.mainQ.iMainMsgQueMaxFileSize); + setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", ourConf->globals.mainQ.iMainMsgQueMaxDiskSpace); + setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", ourConf->globals.mainQ.iMainMsgQueDeqBatchSize); + setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", qfname); + setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", ourConf->globals.mainQ.iMainMsgQPersistUpdCnt); + setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", ourConf->globals.mainQ.bMainMsgQSyncQeueFiles); + setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", ourConf->globals.mainQ.iMainMsgQtoQShutdown ); + setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", ourConf->globals.mainQ.iMainMsgQtoActShutdown); + setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", ourConf->globals.mainQ.iMainMsgQtoWrkShutdown); + setQPROP(qqueueSettoEnq, "$MainMsgQueueTimeoutEnqueue", ourConf->globals.mainQ.iMainMsgQtoEnq); + setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", ourConf->globals.mainQ.iMainMsgQHighWtrMark); + setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", ourConf->globals.mainQ.iMainMsgQLowWtrMark); + setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", ourConf->globals.mainQ.iMainMsgQDiscardMark); + setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", ourConf->globals.mainQ.iMainMsgQDiscardSeverity); + setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", ourConf->globals.mainQ.iMainMsgQWrkMinMsgs); + setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", ourConf->globals.mainQ.bMainMsgQSaveOnShutdown); + setQPROP(qqueueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", ourConf->globals.mainQ.iMainMsgQDeqSlowdown); + setQPROP(qqueueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", ourConf->globals.mainQ.iMainMsgQueueDeqtWinFromHr); + setQPROP(qqueueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", ourConf->globals.mainQ.iMainMsgQueueDeqtWinToHr); + + # undef setQPROP + # undef setQPROPstr + } else { /* use new style config! */ + qqueueSetDefaultsRulesetQueue(*ppQueue); + qqueueApplyCnfParam(*ppQueue, queueParams); + } /* ... and finally start the queue! */ CHKiRet_Hdlr(qqueueStart(*ppQueue)) { -- cgit v1.2.3 From 3495720a2f6bc69ccba4c0d978ee815812cc9b75 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 6 Dec 2012 15:40:15 +0100 Subject: bugfix: some message properties could be garbled due to race condition This happened only on very high volume systems, if the same message was being processed by two different actions. This was a regression caused by the new config processor, which did no longer properly enable msg locking in multithreaded cases. The bugfix is actually a refactoring of the msg locking code - we no longer do unlocked operations, as the use case for it has mostly gone away. It is potentially possible only at very low-end systems, and there the small additional overhead of doing the locking does not really hurt. Instead, the removal of that capability can actually slightly improve performance in common cases, as the code path is smaller and requires slightly less memory writes. That probably outperforms the extra locking overhead (which in the low-end case always happens in user space, without need for kernel support as we can always directly aquire the lock - there is no contention at all). --- tools/syslogd.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 5cc1b319..a89c7e57 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -638,7 +638,6 @@ submitMsg(msg_t *pMsg) FINALIZE; } - MsgPrepareEnqueue(pMsg); qqueueEnqObj(pQueue, pMsg->flowCtlType, (void*) pMsg); finalize_it: @@ -672,10 +671,6 @@ multiSubmitMsg(multi_submit_t *pMultiSub) FINALIZE; } - for(i = 0 ; i < pMultiSub->nElem ; ++i) { - MsgPrepareEnqueue(pMultiSub->ppMsgs[i]); - } - iRet = pQueue->MultiEnq(pQueue, pMultiSub); pMultiSub->nElem = 0; @@ -1119,11 +1114,6 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) uchar qfrenamebuf[1024]; DEFiRet; - /* switch the message object to threaded operation, if necessary */ - if(ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT || ourConf->globals.mainQ.iMainMsgQueueNumWorkers > 1) { - MsgEnableThreadSafety(); - } - /* create message queue */ CHKiRet_Hdlr(qqueueConstruct(ppQueue, ourConf->globals.mainQ.MainMsgQueType, ourConf->globals.mainQ.iMainMsgQueueNumWorkers, ourConf->globals.mainQ.iMainMsgQueueSize, msgConsumer)) { /* no queue is fatal, we need to give up in that case... */ -- cgit v1.2.3 From 3352d2c605567c29840cc93a358d60881c865cb7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 14 Dec 2012 09:20:51 +0100 Subject: minor cleanup --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4be8536d..bd5b52ca 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -622,7 +622,6 @@ submitMsg(msg_t *pMsg) rsRetVal multiSubmitMsg2(multi_submit_t *pMultiSub) { - int i; qqueue_t *pQueue; ruleset_t *pRuleset; DEFiRet; -- cgit v1.2.3 From 9273b4bb4dcb6683cf6825fedd3cb5cd0f59805a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 15 Jan 2013 15:01:16 +0100 Subject: optimize memory layout for much better cache hits Moave element status out of batch_obj_t because we get a *much* better cache hit ratio this way. Note that this is really a HUGE saving, even if it doesn't look so (both profiler data as well as practical tests indicate that!). --- tools/syslogd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index bd5b52ca..a4b53d1f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -527,7 +527,7 @@ preprocessBatch(batch_t *pBatch) { if(!bIsPermitted) { DBGPRINTF("Message from '%s' discarded, not a permitted sender host\n", fromHostFQDN); - pBatch->pElem[i].state = BATCH_STATE_DISC; + pBatch->eltState[i] = BATCH_STATE_DISC; } else { /* save some of the info we obtained */ MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), &propFromHost); @@ -538,7 +538,7 @@ preprocessBatch(batch_t *pBatch) { if((pMsg->msgFlags & NEEDS_PARSING) != 0) { if((localRet = parser.ParseMsg(pMsg)) != RS_RET_OK) { DBGPRINTF("Message discarded, parsing error %d\n", localRet); - pBatch->pElem[i].state = BATCH_STATE_DISC; + pBatch->eltState[i] = BATCH_STATE_DISC; } } if(pMsg->pRuleset != batchRuleset) @@ -573,7 +573,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu //do not have this yet and so we emulate -- 2010-06-10 int i; for(i = 0 ; i < pBatch->nElem && !*pbShutdownImmediate ; i++) { - pBatch->pElem[i].state = BATCH_STATE_COMM; + pBatch->eltState[i] = BATCH_STATE_COMM; } RETiRet; } -- cgit v1.2.3 From eb5c7a04199028703a328d199c36ac6f5b631ccd Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 18 Jan 2013 14:40:41 +0100 Subject: optimize: reduce nbr of strcpy() in FROMHOST processing --- tools/syslogd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index a4b53d1f..4f3bad67 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -501,8 +501,9 @@ finalize_it: static inline rsRetVal preprocessBatch(batch_t *pBatch) { uchar fromHost[NI_MAXHOST]; - uchar fromHostIP[NI_MAXHOST]; uchar fromHostFQDN[NI_MAXHOST]; + uchar *fromHostIP; + rs_size_t lenIP; prop_t *propFromHost = NULL; prop_t *propFromHostIP = NULL; int bSingleRuleset; @@ -520,7 +521,7 @@ preprocessBatch(batch_t *pBatch) { pMsg = pBatch->pElem[i].pMsg; if((pMsg->msgFlags & NEEDS_ACLCHK_U) != 0) { DBGPRINTF("msgConsumer: UDP ACL must be checked for message (hostname-based)\n"); - if(net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, fromHostIP) != RS_RET_OK) + if(net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, &fromHostIP, &lenIP) != RS_RET_OK) continue; bIsPermitted = net.isAllowedSender2((uchar*)"UDP", (struct sockaddr *)pMsg->rcvFrom.pfrominet, (char*)fromHostFQDN, 1); @@ -531,7 +532,7 @@ preprocessBatch(batch_t *pBatch) { } else { /* save some of the info we obtained */ MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), &propFromHost); - CHKiRet(MsgSetRcvFromIPStr(pMsg, fromHostIP, ustrlen(fromHostIP), &propFromHostIP)); + CHKiRet(MsgSetRcvFromIPStr(pMsg, fromHostIP, lenIP, &propFromHostIP)); pMsg->msgFlags &= ~NEEDS_ACLCHK_U; } } -- cgit v1.2.3 From 0d71694fb3cbff71d504769e0e70a58ebe5f9a0d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 24 Jan 2013 06:19:13 +0100 Subject: optimize: have dns cache pre-create rsyslog prop_t's --- tools/syslogd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 4f3bad67..e33c2f4b 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -502,8 +502,7 @@ static inline rsRetVal preprocessBatch(batch_t *pBatch) { uchar fromHost[NI_MAXHOST]; uchar fromHostFQDN[NI_MAXHOST]; - uchar *fromHostIP; - rs_size_t lenIP; + prop_t *ip; prop_t *propFromHost = NULL; prop_t *propFromHostIP = NULL; int bSingleRuleset; @@ -521,7 +520,7 @@ preprocessBatch(batch_t *pBatch) { pMsg = pBatch->pElem[i].pMsg; if((pMsg->msgFlags & NEEDS_ACLCHK_U) != 0) { DBGPRINTF("msgConsumer: UDP ACL must be checked for message (hostname-based)\n"); - if(net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, &fromHostIP, &lenIP) != RS_RET_OK) + if(net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, &ip) != RS_RET_OK) continue; bIsPermitted = net.isAllowedSender2((uchar*)"UDP", (struct sockaddr *)pMsg->rcvFrom.pfrominet, (char*)fromHostFQDN, 1); @@ -532,7 +531,7 @@ preprocessBatch(batch_t *pBatch) { } else { /* save some of the info we obtained */ MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), &propFromHost); - CHKiRet(MsgSetRcvFromIPStr(pMsg, fromHostIP, lenIP, &propFromHostIP)); + CHKiRet(MsgSetRcvFromIP(pMsg, ip)); pMsg->msgFlags &= ~NEEDS_ACLCHK_U; } } -- cgit v1.2.3 From 35bec820b601bfcf9eff314fbfc718bb8949bda1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 22 Jan 2013 16:55:21 +0100 Subject: optimze: reduce memory operations during dns resolution/hostname setting previously, hostname and ip strings were shuffled to the msg object, which created a property out of them. Now the cache holds the property, and it is resused (almost) everywhere, what saves a lot of memory operations. The only exception is imtcp session setup, where different handling of the hostname is done, which we need to sort out (but that's another story). --- tools/syslogd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e33c2f4b..ae1b3de5 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -500,9 +500,9 @@ finalize_it: */ static inline rsRetVal preprocessBatch(batch_t *pBatch) { - uchar fromHost[NI_MAXHOST]; - uchar fromHostFQDN[NI_MAXHOST]; prop_t *ip; + prop_t *fqdn; + prop_t *localName; prop_t *propFromHost = NULL; prop_t *propFromHostIP = NULL; int bSingleRuleset; @@ -520,17 +520,17 @@ preprocessBatch(batch_t *pBatch) { pMsg = pBatch->pElem[i].pMsg; if((pMsg->msgFlags & NEEDS_ACLCHK_U) != 0) { DBGPRINTF("msgConsumer: UDP ACL must be checked for message (hostname-based)\n"); - if(net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, &ip) != RS_RET_OK) + if(net.cvthname(pMsg->rcvFrom.pfrominet, &localName, &fqdn, &ip) != RS_RET_OK) continue; bIsPermitted = net.isAllowedSender2((uchar*)"UDP", - (struct sockaddr *)pMsg->rcvFrom.pfrominet, (char*)fromHostFQDN, 1); + (struct sockaddr *)pMsg->rcvFrom.pfrominet, (char*)propGetSzStr(fqdn), 1); if(!bIsPermitted) { DBGPRINTF("Message from '%s' discarded, not a permitted sender host\n", - fromHostFQDN); + propGetSzStr(fqdn)); pBatch->eltState[i] = BATCH_STATE_DISC; } else { /* save some of the info we obtained */ - MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), &propFromHost); + MsgSetRcvFrom(pMsg, localName); CHKiRet(MsgSetRcvFromIP(pMsg, ip)); pMsg->msgFlags &= ~NEEDS_ACLCHK_U; } -- cgit v1.2.3 From 8aad93c582fcf9628a4d81da515f5fca31efca24 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 26 Feb 2013 09:58:17 +0100 Subject: imuxsock: add capability to ignore messages from ourselfes This helps prevent message routing loops, and is vital to have if omjournal is used together with traditional syslog. --- tools/syslogd.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index ae1b3de5..c2928a8f 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -195,7 +195,6 @@ static prop_t *pInternalInputName = NULL; /* there is only one global inputName static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */ static char *PidFile = _PATH_LOGPID; /* read-only after startup */ -static pid_t myPid; /* our pid for use in self-generated messages, e.g. on startup */ /* mypid is read-only after the initial fork() */ static int bHadHUP = 0; /* did we have a HUP? */ @@ -795,7 +794,7 @@ die(int sig) (void) snprintf(buf, sizeof(buf) / sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.", - (int) myPid, sig); + (int) glblGetOurPid(), sig); errno = 0; logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); } @@ -1169,7 +1168,7 @@ init(void) snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] start", - (int) myPid); + (int) glblGetOurPid()); logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, 0); } @@ -1248,7 +1247,7 @@ doHUP(void) snprintf(buf, sizeof(buf) / sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed", - (int) myPid); + (int) glblGetOurPid()); errno = 0; logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); } @@ -1704,7 +1703,7 @@ doGlblProcessInit(void) fputs("Pidfile (and pid) already exist.\n", stderr); exit(1); /* exit during startup - questionable */ } - myPid = getpid(); /* save our pid for further testing (also used for messages) */ + glblSetOurPid(getpid()); memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); @@ -2001,7 +2000,7 @@ int realMain(int argc, char **argv) } /* Send a signal to the parent so it can terminate. */ - if(myPid != ppid) + if(glblGetOurPid() != ppid) kill(ppid, SIGTERM); -- cgit v1.2.3 From 0114b531b38b16db98b04b680017d6c758987fd9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 15 Mar 2013 14:33:23 +0100 Subject: debug system improvement & bug fix for init system status (see below) - rsyslogd startup information is now properly conveyed back to init when privileges are beging dropped Actually, we have moved termination of the parent in front of the priv drop. So it shall work now in all cases. See code comments in commit for more details. - If forking, the parent now waits for a maximum of 60 seconds for termination by the child - improved debugging support in forked (auto-backgrounding) mode The rsyslog debug log file is now continued to be written across the fork. --- tools/syslogd.c | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 62c18e72..0d7aac6c 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -224,7 +224,7 @@ struct queuefilenames_s { int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ -static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */ +static int doFork = 1; /* fork - run in daemon mode - read-only after startup */ int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - is available * If the main queue is either not yet ready or not running in * queueing mode (mode DIRECT!), then this is set to 0. @@ -473,7 +473,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) * permits us to process unmodified config files which otherwise contain a * supressor statement. */ - if(((Debug == DEBUG_FULL || NoFork) && ourConf->globals.bErrMsgToStderr) || iConfigVerify) { + if(((Debug == DEBUG_FULL || !doFork) && ourConf->globals.bErrMsgToStderr) || iConfigVerify) { if(LOG_PRI(pri) == LOG_ERR) fprintf(stderr, "rsyslogd: %s\n", msg); } @@ -652,7 +652,6 @@ finalize_it: rsRetVal multiSubmitMsg(multi_submit_t *pMultiSub) { - int i; qqueue_t *pQueue; ruleset_t *pRuleset; DEFiRet; @@ -1693,8 +1692,7 @@ doGlblProcessInit(void) thrdInit(); - if( !(Debug == DEBUG_FULL || NoFork) ) - { + if(doFork) { DBGPRINTF("Checking pidfile '%s'.\n", PidFile); if (!check_pid(PidFile)) { @@ -1706,16 +1704,23 @@ doGlblProcessInit(void) /* stop writing debug messages to stdout (if debugging is on) */ stddbg = -1; + dbgprintf("ready for forking\n"); if (fork()) { /* Parent process */ - sleep(300); - /* Not reached unless something major went wrong. 5 - * minutes should be a fair amount of time to wait. - * Please note that this procedure is important since - * the father must not exit before syslogd isn't - * initialized or the klogd won't be able to flush its - * logs. -Joey + dbgprintf("parent process going to sleep for 60 secs\n"); + sleep(60); + /* Not reached unless something major went wrong. 1 + * minute should be a fair amount of time to wait. + * The parent should not exit before rsyslogd is + * properly initilized (at least almost) or the init + * system may get a wrong impression of our readyness. + * Note that we exit before being completely initialized, + * but at this point it is very, very unlikely that something + * bad can happen. We do this here, because otherwise we would + * need to have much more code to handle priv drop (which we + * don't consider worth for the init system, especially as it + * is going away on the majority of distros). */ exit(1); /* "good" exit - after forking, not diasabling anything */ } @@ -1724,6 +1729,7 @@ doGlblProcessInit(void) close(0); /* we keep stdout and stderr open in case we have to emit something */ i = 3; + dbgprintf("in child, finalizing initialization\n"); /* if (sd_booted()) */ { const char *e; @@ -1757,7 +1763,8 @@ doGlblProcessInit(void) i = SD_LISTEN_FDS_START + sd_fds; } for ( ; i < num_fds; i++) - (void) close(i); + if(i != dbgGetDbglogFd()) + close(i); untty(); } else { @@ -1968,7 +1975,7 @@ int realMain(int argc, char **argv) fprintf(stderr, "rsyslogd: error -m is no longer supported - use immark instead"); break; case 'n': /* don't fork */ - NoFork = 1; + doFork = 0; break; case 'N': /* enable config verify mode */ iConfigVerify = atoi(arg); @@ -2066,17 +2073,18 @@ int realMain(int argc, char **argv) if(!iConfigVerify) CHKiRet(doGlblProcessInit()); + /* Send a signal to the parent so it can terminate. */ + if(myPid != ppid) { + dbgprintf("signaling parent to terminate\n"); + kill(ppid, SIGTERM); + } + CHKiRet(init()); if(Debug && debugging_on) { dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); } - /* Send a signal to the parent so it can terminate. */ - if(myPid != ppid) - kill(ppid, SIGTERM); - - /* END OF INTIALIZATION */ DBGPRINTF("initialization completed, transitioning to regular run mode\n"); @@ -2087,7 +2095,7 @@ int realMain(int argc, char **argv) * is still in its infancy (and not really done), we currently accept this issue. * rgerhards, 2009-06-29 */ - if(!(Debug == DEBUG_FULL || NoFork)) { + if(!doFork) { close(1); close(2); ourConf->globals.bErrMsgToStderr = 0; -- cgit v1.2.3 From 0dab9aa0c4f50403436f318e92a65903a956c195 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 18 Mar 2013 13:57:42 +0100 Subject: fix merge problem --- tools/syslogd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 66adde48..d4fc1c36 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2001,16 +2001,16 @@ int realMain(int argc, char **argv) if(!iConfigVerify) CHKiRet(doGlblProcessInit()); + /* Send a signal to the parent so it can terminate. */ + if(glblGetOurPid() != ppid) + kill(ppid, SIGTERM); + CHKiRet(init()); if(Debug && debugging_on) { dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); } - /* Send a signal to the parent so it can terminate. */ - if(glblGetOurPid() != ppid) - kill(ppid, SIGTERM); - /* END OF INTIALIZATION */ DBGPRINTF("initialization completed, transitioning to regular run mode\n"); -- cgit v1.2.3 From cbe737ed06667b5bcb15f332061ebcde8d50bc8b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 20 Mar 2013 12:49:35 +0100 Subject: bugfix: stdout/stderr were not closed on forking but were closed when running in the forground - this was just reversed of what it should be. This is a regression of a recent change. --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index d4fc1c36..e291ba47 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2021,7 +2021,7 @@ int realMain(int argc, char **argv) * is still in its infancy (and not really done), we currently accept this issue. * rgerhards, 2009-06-29 */ - if(!doFork) { + if(doFork) { close(1); close(2); ourConf->globals.bErrMsgToStderr = 0; -- cgit v1.2.3 From b78a7ba0af45014b1b50a6842dfaad82806d8bf2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 20 Mar 2013 12:49:35 +0100 Subject: bugfix: stdout/stderr were not closed on forking but were closed when running in the forground - this was just reversed of what it should be. This is a regression of a recent change. Conflicts: ChangeLog --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 0d7aac6c..e2776c11 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2095,7 +2095,7 @@ int realMain(int argc, char **argv) * is still in its infancy (and not really done), we currently accept this issue. * rgerhards, 2009-06-29 */ - if(!doFork) { + if(doFork) { close(1); close(2); ourConf->globals.bErrMsgToStderr = 0; -- cgit v1.2.3 From 86e34c6985da29c62f13ab83e44548f1fd21849d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 9 Apr 2013 10:54:04 +0200 Subject: make imrelp properly terminate on system shutdown it didn't do so if it was inside a retry loop --- tools/syslogd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e2776c11..a0c01bf7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -604,6 +604,7 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu assert(pBatch != NULL); pBatch->pbShutdownImmediate = pbShutdownImmediate; /* TODO: move this to batch creation! */ preprocessBatch(pBatch); +dbgprintf("DDDD: batches ShutdownImmediate is %p\n", pBatch->pbShutdownImmediate); ruleset.ProcessBatch(pBatch); //TODO: the BATCH_STATE_COMM must be set somewhere down the road, but we //do not have this yet and so we emulate -- 2010-06-10 -- cgit v1.2.3 From 89ace1e401dc179a20ec283c2f7c2f80becf4700 Mon Sep 17 00:00:00 2001 From: Louis Bouchard Date: Wed, 17 Apr 2013 08:52:17 +0200 Subject: bugfix: $PreserveFQDN is not properly working closes: http://bugzilla.adiscon.com/show_bug.cgi?id=426 --- tools/syslogd.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index e291ba47..fe1205dd 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1528,6 +1528,13 @@ queryLocalHostname(void) */ glbl.SetLocalHostName(LocalHostName); glbl.SetLocalDomain(LocalDomain); + + if ( strlen((char*)LocalDomain) ) { + CHKmalloc(LocalFQDNName = (uchar*)malloc(strlen((char*)LocalDomain)+strlen((char*)LocalHostName)+1)); + if ( sprintf((char*)LocalFQDNName,"%s.%s",(char*)LocalHostName,(char*)LocalDomain) ) + glbl.SetLocalFQDNName(LocalFQDNName); + } + glbl.GenerateLocalHostNameProperty(); /* must be redone after conf processing, FQDN setting may have changed */ finalize_it: RETiRet; -- cgit v1.2.3 From d0cefac7a766d0f02ca76fcaeb6cfbace695b925 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 24 Apr 2013 11:09:37 +0200 Subject: cleanup --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 77adb2cb..fe1205dd 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -567,7 +567,6 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch, int *pbShu assert(pBatch != NULL); pBatch->pbShutdownImmediate = pbShutdownImmediate; /* TODO: move this to batch creation! */ preprocessBatch(pBatch); -dbgprintf("DDDD: batches ShutdownImmediate is %p\n", pBatch->pbShutdownImmediate); ruleset.ProcessBatch(pBatch); //TODO: the BATCH_STATE_COMM must be set somewhere down the road, but we //do not have this yet and so we emulate -- 2010-06-10 -- cgit v1.2.3 From 9c54bf41d02ba236137859ea5f12d6f048647349 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 24 Apr 2013 11:15:24 +0200 Subject: bugfix: off-by-one error in handling local FQDN name (regression) A remporary buffer was allocated one byte too small. Did only affect startup, not actual operations. Came up during routine tests, and can have no effect once the engine runs. Bug was introduced in 7.3.11. --- tools/syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index fe1205dd..1b38bf92 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1530,7 +1530,7 @@ queryLocalHostname(void) glbl.SetLocalDomain(LocalDomain); if ( strlen((char*)LocalDomain) ) { - CHKmalloc(LocalFQDNName = (uchar*)malloc(strlen((char*)LocalDomain)+strlen((char*)LocalHostName)+1)); + CHKmalloc(LocalFQDNName = (uchar*)malloc(strlen((char*)LocalDomain)+strlen((char*)LocalHostName)+2));/* one for dot, one for NUL! */ if ( sprintf((char*)LocalFQDNName,"%s.%s",(char*)LocalHostName,(char*)LocalDomain) ) glbl.SetLocalFQDNName(LocalFQDNName); } -- cgit v1.2.3 From 7369904b578322f7fb22897def3cd63b27eacf46 Mon Sep 17 00:00:00 2001 From: Axel Rau Date: Wed, 1 May 2013 18:45:31 +0200 Subject: Add configurable local client IP --- tools/syslogd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 1b38bf92..47a21585 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1773,7 +1773,7 @@ int realMain(int argc, char **argv) * of other options, we do this during the inital option processing. * rgerhards, 2008-04-04 */ - while((ch = getopt(argc, argv, "46a:Ac:dDef:g:hi:l:m:M:nN:op:qQr::s:t:T:u:vwx")) != EOF) { + while((ch = getopt(argc, argv, "46a:Ac:dDef:g:hi:l:m:M:nN:op:qQr::s:S:t:T:u:vwx")) != EOF) { switch((char)ch) { case '4': case '6': @@ -1791,6 +1791,7 @@ int realMain(int argc, char **argv) case 'q': /* add hostname if DNS resolving has failed */ case 'Q': /* dont resolve hostnames in ACL to IPs */ case 's': + case 'S': /* Source IP for local client to be used on multihomed host */ case 'T': /* chroot on startup (primarily for testing) */ case 'u': /* misc user settings */ case 'w': /* disable disallowed host warnings */ @@ -1882,6 +1883,13 @@ int realMain(int argc, char **argv) case 'a': fprintf(stderr, "rsyslogd: error -a is no longer supported, use module imuxsock instead"); break; + case 'S': /* Source IP for local client to be used on multihomed host */ + if(glbl.GetSourceIPofLocalClient() != NULL) { + fprintf (stderr, "rsyslogd: Only one -S argument allowed, the first one is taken.\n"); + } else { + glbl.SetSourceIPofLocalClient(arg); + } + break; case 'f': /* configuration file */ ConfFile = (uchar*) arg; break; -- cgit v1.2.3 From 415b26d5a19d8b1fd50d8e0b7b29cc8527537316 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 10 May 2013 15:39:42 +0200 Subject: enable shuffling of crypto parameters down through queue definition --- tools/syslogd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 47a21585..d2f249cf 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1057,7 +1057,7 @@ finalize_it: * the time being (remember that we want to restructure config processing at large!). * rgerhards, 2009-10-27 */ -rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfparamvals *queueParams) +rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct nvlst *lst) { struct queuefilenames_s *qfn; uchar *qfname = NULL; @@ -1073,7 +1073,7 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfpara /* name our main queue object (it's not fatal if it fails...) */ obj.SetName((obj_t*) (*ppQueue), pszQueueName); - if(queueParams == NULL) { /* use legacy parameters? */ + if(lst == NULL) { /* use legacy parameters? */ /* ... set some properties ... */ # define setQPROP(func, directive, data) \ CHKiRet_Hdlr(func(*ppQueue, data)) { \ @@ -1130,7 +1130,7 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfpara # undef setQPROPstr } else { /* use new style config! */ qqueueSetDefaultsRulesetQueue(*ppQueue); - qqueueApplyCnfParam(*ppQueue, queueParams); + qqueueApplyCnfParam(*ppQueue, lst); } /* ... and finally start the queue! */ @@ -1887,7 +1887,7 @@ int realMain(int argc, char **argv) if(glbl.GetSourceIPofLocalClient() != NULL) { fprintf (stderr, "rsyslogd: Only one -S argument allowed, the first one is taken.\n"); } else { - glbl.SetSourceIPofLocalClient(arg); + glbl.SetSourceIPofLocalClient((uchar*)arg); } break; case 'f': /* configuration file */ -- cgit v1.2.3 From faeaaf2d6c5992b0a6cea53011f4caca935da3dd Mon Sep 17 00:00:00 2001 From: Tomas Heinrich Date: Wed, 15 May 2013 14:27:03 +0200 Subject: Drop unneeded macro definition The macro itself was a malformed version of "_GNU_SOURCE" and thus had no effect. It is not needed as this macro is already defined via AC_GNU_SOURCE. --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 1b38bf92..7a8e21c2 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -51,7 +51,6 @@ #include #include #include -#define GNU_SOURCE #include #include #include -- cgit v1.2.3 From b31838624119708b3d265dd34d6bc6cda25944c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Fri, 14 Jun 2013 00:40:48 -0400 Subject: systemd: use service type notify There is a time window, between rsyslog reporting syntax errors and the daemon returning with failure, this may cause systemctl restart rsyslog to not report any error inmediately but later in the logs which is confusing to users. The appropiate steps to correct this annoyance is to notify systemd with a simple sd_notify(0, "READY=1"); just before entering the main loop. Tested in openSUSE 12.3/13.1 x86_64 --- tools/syslogd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/syslogd.c') diff --git a/tools/syslogd.c b/tools/syslogd.c index 7a8e21c2..a8a733d6 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2033,6 +2033,8 @@ int realMain(int argc, char **argv) ourConf->globals.bErrMsgToStderr = 0; } + sd_notify(0, "READY=1"); + mainloop(); /* do any de-init's that need to be done AFTER this comment */ -- cgit v1.2.3