diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2009-07-09 17:45:21 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2009-07-09 17:45:21 +0200 |
commit | 809f0a16e75bf7679a4919c642699a7bb3039ae3 (patch) | |
tree | 5669c84e04fe8e6a605d11b9d50634ff8ce9c266 | |
parent | cafb951020817cca6b89b5cc6b91f3a8ab86f29a (diff) | |
parent | 4130ca8670b37d0fe92a1abb47a2840c62604ded (diff) | |
download | rsyslog-809f0a16e75bf7679a4919c642699a7bb3039ae3.tar.gz rsyslog-809f0a16e75bf7679a4919c642699a7bb3039ae3.tar.xz rsyslog-809f0a16e75bf7679a4919c642699a7bb3039ae3.zip |
Merge branch 'master' into udpspoof & cleanup & slight optimization
Conflicts:
runtime/msg.c
I messed up and did some changes during the merge commit ;) But these are
not large, just a little bit of cleanup and some very slight optimizations
inside the msg object.
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | action.c | 3 | ||||
-rw-r--r-- | plugins/omstdout/omstdout.c | 13 | ||||
-rw-r--r-- | runtime/msg.c | 347 | ||||
-rw-r--r-- | runtime/msg.h | 6 | ||||
-rw-r--r-- | runtime/rule.c | 7 | ||||
-rw-r--r-- | tests/Makefile.am | 6 | ||||
-rwxr-xr-x | tests/diag.sh | 1 | ||||
-rw-r--r-- | tests/nettester.c | 20 | ||||
-rwxr-xr-x | tests/parsertest.sh | 18 | ||||
-rwxr-xr-x | tests/proprepltest.sh | 7 | ||||
-rw-r--r-- | tests/testsuites/master.nolimittag | 11 | ||||
-rw-r--r-- | tests/testsuites/master.rfctag | 11 | ||||
-rw-r--r-- | tests/testsuites/nolimittag.conf | 8 | ||||
-rw-r--r-- | tests/testsuites/rfctag.conf | 9 | ||||
-rw-r--r-- | tools/syslogd.c | 233 |
16 files changed, 283 insertions, 421 deletions
@@ -67,6 +67,10 @@ Version 4.5.1 [DEVEL] (rgerhards), 2009-07-?? was on. Happend e.g. with imuxsock. - added $klogConsoleLogLevel directive which permits to set a new console log level while rsyslog is active +- bugfix: message could be truncated after TAG, often when forwarding + This was a result of an internal processing error if maximum field + sizes had been specified in the property replacer. +- testbench improvements --------------------------------------------------------------------------- Version 4.5.0 [DEVEL] (rgerhards), 2009-07-02 - activation order of inputs changed, they are now activated only after @@ -45,6 +45,7 @@ #include "batch.h" #include "wti.h" #include "datetime.h" +#include "unicode-helper.h" #define NO_TIME_PROVIDED 0 /* indicate we do not provide any cached time */ @@ -1180,7 +1181,7 @@ doActionCallAction(action_t *pAction, msg_t *pMsg) /* suppress duplicate messages */ if ((pAction->f_ReduceRepeated == 1) && pAction->f_pMsg != NULL && (pMsg->msgFlags & MARK) == 0 && getMSGLen(pMsg) == getMSGLen(pAction->f_pMsg) && - !strcmp(getMSG(pMsg), getMSG(pAction->f_pMsg)) && + !ustrcmp(getMSG(pMsg), getMSG(pAction->f_pMsg)) && !strcmp(getHOSTNAME(pMsg), getHOSTNAME(pAction->f_pMsg)) && !strcmp(getPROCID(pMsg, LOCK_MUTEX), getPROCID(pAction->f_pMsg, LOCK_MUTEX)) && !strcmp(getAPPNAME(pMsg, LOCK_MUTEX), getAPPNAME(pAction->f_pMsg, LOCK_MUTEX))) { diff --git a/plugins/omstdout/omstdout.c b/plugins/omstdout/omstdout.c index b9125f19..584ae458 100644 --- a/plugins/omstdout/omstdout.c +++ b/plugins/omstdout/omstdout.c @@ -50,11 +50,13 @@ MODULE_TYPE_OUTPUT DEF_OMOD_STATIC_DATA /* config variables */ -static int bUseArrayInterface; /* shall action use array instead of string template interface? */ +static int bUseArrayInterface = 0; /* shall action use array instead of string template interface? */ +static int bEnsureLFEnding = 1; /* shall action use array instead of string template interface? */ typedef struct _instanceData { int bUseArrayInterface; /* uses action use array instead of string template interface? */ + int bEnsureLFEnding; /* ensure that a linefeed is written at the end of EACH record (test aid for nettester) */ } instanceData; BEGINcreateInstance @@ -90,6 +92,7 @@ BEGINdoAction int iParam; int iBuf; char szBuf[65564]; + size_t len; CODESTARTdoAction if(pData->bUseArrayInterface) { /* if we use array passing, we need to put together a string @@ -120,7 +123,11 @@ CODESTARTdoAction } else { toWrite = (char*) ppString[0]; } + len = strlen(toWrite); write(1, toWrite, strlen(toWrite)); /* 1 is stdout! */ + if(pData->bEnsureLFEnding && toWrite[len-1] != '\n') { + write(1, "\n", 1); /* write missing LF */ + } ENDdoAction @@ -143,6 +150,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) iTplOpts = (bUseArrayInterface == 0) ? 0 : OMSR_TPL_AS_ARRAY; CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, iTplOpts, (uchar*) "RSYSLOG_FileFormat")); pData->bUseArrayInterface = bUseArrayInterface; + pData->bEnsureLFEnding = bEnsureLFEnding; CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct @@ -165,6 +173,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a { DEFiRet; bUseArrayInterface = 0; + bEnsureLFEnding = 1; RETiRet; } @@ -195,6 +204,8 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomstdoutarrayinterface", 0, eCmdHdlrBinary, NULL, &bUseArrayInterface, STD_LOADABLE_MODULE_ID)); } + CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomstdoutensurelfending", 0, eCmdHdlrBinary, NULL, + &bEnsureLFEnding, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit diff --git a/runtime/msg.c b/runtime/msg.c index 4d48c895..8a72a6d6 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -1130,15 +1130,21 @@ char *getProtocolVersionString(msg_t *pM) } -static char *getRawMsg(msg_t *pM) +static inline void +getRawMsg(msg_t *pM, uchar **pBuf, int *piLen) { - if(pM == NULL) - return ""; - else - if(pM->pszRawMsg == NULL) - return ""; - else - return (char*)pM->pszRawMsg; + if(pM == NULL) { + *pBuf= UCHAR_CONSTANT(""); + *piLen = 0; + } else { + if(pM->pszRawMsg == NULL) { + *pBuf= UCHAR_CONSTANT(""); + *piLen = 0; + } else { + *pBuf = pM->pszRawMsg; + *piLen = pM->iLenRawMsg; + } + } } @@ -1159,16 +1165,16 @@ int getMSGLen(msg_t *pM) return((pM == NULL) ? 0 : pM->iLenMSG); } -char *getMSG(msg_t *pM) +uchar *getMSG(msg_t *pM) { - char *ret; + uchar *ret; if(pM == NULL) - ret = ""; + ret = UCHAR_CONSTANT(""); else { if(pM->offMSG == -1) - ret = ""; + ret = UCHAR_CONSTANT(""); else - ret = (char*)(pM->pszRawMsg + pM->offMSG); + ret = pM->pszRawMsg + pM->offMSG; } return ret; } @@ -1613,21 +1619,23 @@ static inline void tryEmulateTAG(msg_t *pM, bool bLockMutex) } -static inline char *getTAG(msg_t *pM) +static inline void +getTAG(msg_t *pM, uchar **ppBuf, int *piLen) { - char *ret; - - if(pM == NULL) - ret = ""; - else { + if(pM == NULL) { + *ppBuf = UCHAR_CONSTANT(""); + *piLen = 0; + } else { if(pM->iLenTAG == 0) tryEmulateTAG(pM, LOCK_MUTEX); - if(pM->iLenTAG == 0) - ret = ""; - else - ret = (char*) ((pM->iLenTAG < CONF_TAG_BUFSIZE) ? pM->TAG.szBuf : pM->TAG.pszTAG); + if(pM->iLenTAG == 0) { + *ppBuf = UCHAR_CONSTANT(""); + *piLen = 0; + } else { + *ppBuf = (pM->iLenTAG < CONF_TAG_BUFSIZE) ? pM->TAG.szBuf : pM->TAG.pszTAG; + *piLen = pM->iLenTAG; + } } - return(ret); } @@ -1754,10 +1762,10 @@ int getProgramNameLen(msg_t *pM, bool bLockMutex) /* get the "programname" as sz string * rgerhards, 2005-10-19 */ -char *getProgramName(msg_t *pM, bool bLockMutex) +uchar *getProgramName(msg_t *pM, bool bLockMutex) { prepareProgramName(pM, bLockMutex); - return (pM->pCSProgName == NULL) ? "" : (char*) rsCStrGetSzStrNoNULL(pM->pCSProgName); + return (pM->pCSProgName == NULL) ? UCHAR_CONSTANT("") : rsCStrGetSzStrNoNULL(pM->pCSProgName); } @@ -1774,7 +1782,7 @@ static void tryEmulateAPPNAME(msg_t *pM) if(getProtocolVersion(pM) == 0) { /* only then it makes sense to emulate */ - MsgSetAPPNAME(pM, getProgramName(pM, MUTEX_ALREADY_LOCKED)); + MsgSetAPPNAME(pM, (char*)getProgramName(pM, MUTEX_ALREADY_LOCKED)); } } @@ -2130,14 +2138,14 @@ static uchar *getNOW(eNOWType eNow) * be used in selector line processing. * rgerhards 2005-09-15 */ -char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, +uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, propid_t propID, size_t *pPropLen, unsigned short *pbMustBeFreed) { - char *pRes; /* result pointer */ + uchar *pRes; /* result pointer */ int bufLen = -1; /* length of string or -1, if not known */ - char *pBufStart; - char *pBuf; + uchar *pBufStart; + uchar *pBuf; int iLen; short iOffs; @@ -2159,16 +2167,17 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, bufLen = getMSGLen(pMsg); break; case PROP_TIMESTAMP: - pRes = getTimeReported(pMsg, pTpe->data.field.eDateFormat); + pRes = (uchar*)getTimeReported(pMsg, pTpe->data.field.eDateFormat); break; case PROP_HOSTNAME: - pRes = getHOSTNAME(pMsg); + pRes = (uchar*)getHOSTNAME(pMsg); + bufLen = getHOSTNAMELen(pMsg); break; case PROP_SYSLOGTAG: - pRes = getTAG(pMsg); + getTAG(pMsg, &pRes, &bufLen); break; case PROP_RAWMSG: - pRes = getRawMsg(pMsg); + getRawMsg(pMsg, &pRes, &bufLen); break; /* enable this, if someone actually uses UxTradMsg, delete after some time has * passed and nobody complained -- rgerhards, 2009-06-16 @@ -2177,120 +2186,121 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, break; */ case PROP_INPUTNAME: - getInputName(pMsg, ((uchar**) &pRes), &bufLen); + getInputName(pMsg, &pRes, &bufLen); break; case PROP_FROMHOST: - pRes = (char*) getRcvFrom(pMsg); + pRes = getRcvFrom(pMsg); break; case PROP_FROMHOST_IP: - pRes = (char*) getRcvFromIP(pMsg); + pRes = getRcvFromIP(pMsg); break; case PROP_PRI: - pRes = getPRI(pMsg); + pRes = (uchar*)getPRI(pMsg); break; case PROP_PRI_TEXT: - pBuf = malloc(20 * sizeof(char)); + pBuf = malloc(20 * sizeof(uchar)); if(pBuf == NULL) { *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } else { *pbMustBeFreed = 1; - pRes = textpri(pBuf, 20, getPRIi(pMsg)); + pRes = (uchar*)textpri((char*)pBuf, 20, getPRIi(pMsg)); } break; case PROP_IUT: - pRes = "1"; /* always 1 for syslog messages (a MonitorWare thing;)) */ + pRes = UCHAR_CONSTANT("1"); /* always 1 for syslog messages (a MonitorWare thing;)) */ + bufLen = 1; break; case PROP_SYSLOGFACILITY: - pRes = getFacility(pMsg); + pRes = (uchar*)getFacility(pMsg); break; case PROP_SYSLOGFACILITY_TEXT: - pRes = getFacilityStr(pMsg); + pRes = (uchar*)getFacilityStr(pMsg); break; case PROP_SYSLOGSEVERITY: - pRes = getSeverity(pMsg); + pRes = (uchar*)getSeverity(pMsg); break; case PROP_SYSLOGSEVERITY_TEXT: - pRes = getSeverityStr(pMsg); + pRes = (uchar*)getSeverityStr(pMsg); break; case PROP_TIMEGENERATED: - pRes = getTimeGenerated(pMsg, pTpe->data.field.eDateFormat); + pRes = (uchar*)getTimeGenerated(pMsg, pTpe->data.field.eDateFormat); break; case PROP_PROGRAMNAME: pRes = getProgramName(pMsg, LOCK_MUTEX); break; case PROP_PROTOCOL_VERSION: - pRes = getProtocolVersionString(pMsg); + pRes = (uchar*)getProtocolVersionString(pMsg); break; case PROP_STRUCTURED_DATA: - pRes = getStructuredData(pMsg); + pRes = (uchar*)getStructuredData(pMsg); break; case PROP_APP_NAME: - pRes = getAPPNAME(pMsg, LOCK_MUTEX); + pRes = (uchar*)getAPPNAME(pMsg, LOCK_MUTEX); break; case PROP_PROCID: - pRes = getPROCID(pMsg, LOCK_MUTEX); + pRes = (uchar*)getPROCID(pMsg, LOCK_MUTEX); break; case PROP_MSGID: - pRes = getMSGID(pMsg); + pRes = (uchar*)getMSGID(pMsg); break; case PROP_SYS_NOW: - if((pRes = (char*) getNOW(NOW_NOW)) == NULL) { - return "***OUT OF MEMORY***"; + if((pRes = getNOW(NOW_NOW)) == NULL) { + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ break; case PROP_SYS_YEAR: - if((pRes = (char*) getNOW(NOW_YEAR)) == NULL) { - return "***OUT OF MEMORY***"; + if((pRes = getNOW(NOW_YEAR)) == NULL) { + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ break; case PROP_SYS_MONTH: - if((pRes = (char*) getNOW(NOW_MONTH)) == NULL) { - return "***OUT OF MEMORY***"; + if((pRes = getNOW(NOW_MONTH)) == NULL) { + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ break; case PROP_SYS_DAY: - if((pRes = (char*) getNOW(NOW_DAY)) == NULL) { - return "***OUT OF MEMORY***"; + if((pRes = getNOW(NOW_DAY)) == NULL) { + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ break; case PROP_SYS_HOUR: - if((pRes = (char*) getNOW(NOW_HOUR)) == NULL) { - return "***OUT OF MEMORY***"; + if((pRes = getNOW(NOW_HOUR)) == NULL) { + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ break; case PROP_SYS_HHOUR: - if((pRes = (char*) getNOW(NOW_HHOUR)) == NULL) { - return "***OUT OF MEMORY***"; + if((pRes = getNOW(NOW_HHOUR)) == NULL) { + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ break; case PROP_SYS_QHOUR: - if((pRes = (char*) getNOW(NOW_QHOUR)) == NULL) { - return "***OUT OF MEMORY***"; + if((pRes = getNOW(NOW_QHOUR)) == NULL) { + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ break; case PROP_SYS_MINUTE: - if((pRes = (char*) getNOW(NOW_MINUTE)) == NULL) { - return "***OUT OF MEMORY***"; + if((pRes = getNOW(NOW_MINUTE)) == NULL) { + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ break; case PROP_SYS_MYHOSTNAME: - pRes = (char*) glbl.GetLocalHostName(); + pRes = glbl.GetLocalHostName(); break; default: /* there is no point in continuing, we may even otherwise render the * error message unreadable. rgerhards, 2007-07-10 */ dbgprintf("invalid property id: '%d'\n", propID); - return "**INVALID PROPERTY NAME**"; + return UCHAR_CONSTANT("**INVALID PROPERTY NAME**"); } @@ -2310,8 +2320,8 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, */ if(pTpe->data.field.has_fields == 1) { size_t iCurrFld; - char *pFld; - char *pFldEnd; + uchar *pFld; + uchar *pFldEnd; /* first, skip to the field in question. The field separator * is always one character and is stored in the template entry. */ @@ -2349,7 +2359,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, if(*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } /* now copy */ memcpy(pBuf, pFld, iLen); @@ -2366,12 +2376,12 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, if(*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; - return "**FIELD NOT FOUND**"; + return UCHAR_CONSTANT("**FIELD NOT FOUND**"); } } else if(pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) { /* we need to obtain a private copy */ int iFrom, iTo; - char *pSb; + uchar *pSb; iFrom = pTpe->data.field.iFromPos; iTo = pTpe->data.field.iToPos; /* need to zero-base to and from (they are 1-based!) */ @@ -2379,44 +2389,55 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, --iFrom; if(iTo > 0) --iTo; - iLen = iTo - iFrom + 1; /* the +1 is for an actual char, NOT \0! */ - pBufStart = pBuf = malloc((iLen + 1) * sizeof(char)); - if(pBuf == NULL) { - if(*pbMustBeFreed == 1) - free(pRes); - *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; - } - pSb = pRes; - if(iFrom) { - /* skip to the start of the substring (can't do pointer arithmetic - * because the whole string might be smaller!!) - */ - while(*pSb && iFrom) { - --iFrom; + if(bufLen == -1) + bufLen = ustrlen(pRes); + if(iFrom == 0 && iTo >= bufLen) { + /* in this case, the requested string is a superset of what we already have, + * so there is no need to do any processing. This is a frequent case for size-limited + * fields like TAG in the default forwarding template (so it is a useful optimization + * to check for this condition ;)). -- rgerhards, 2009-07-09 + */ + ; /*DO NOTHING*/ + } else { + iLen = iTo - iFrom + 1; /* the +1 is for an actual char, NOT \0! */ + pBufStart = pBuf = malloc((iLen + 1) * sizeof(char)); + if(pBuf == NULL) { + if(*pbMustBeFreed == 1) + free(pRes); + *pbMustBeFreed = 0; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); + } + pSb = pRes; + if(iFrom) { + /* skip to the start of the substring (can't do pointer arithmetic + * because the whole string might be smaller!!) + */ + while(*pSb && iFrom) { + --iFrom; + ++pSb; + } + } + /* OK, we are at the begin - now let's copy... */ + bufLen = iLen; + while(*pSb && iLen) { + *pBuf++ = *pSb; ++pSb; + --iLen; } + *pBuf = '\0'; + bufLen -= iLen; /* subtract remaining length if the string was smaller! */ + if(*pbMustBeFreed == 1) + free(pRes); + pRes = pBufStart; + *pbMustBeFreed = 1; } - /* OK, we are at the begin - now let's copy... */ - bufLen = iLen; - while(*pSb && iLen) { - *pBuf++ = *pSb; - ++pSb; - --iLen; - } - *pBuf = '\0'; - bufLen -= iLen; /* subtract remaining lenght if the string was smaller! */ - if(*pbMustBeFreed == 1) - free(pRes); - pRes = pBufStart; - *pbMustBeFreed = 1; #ifdef FEATURE_REGEXP } else { /* Check for regular expressions */ if (pTpe->data.field.has_regex != 0) { if (pTpe->data.field.has_regex == 2) /* Could not compile regex before! */ - return "**NO MATCH** **BAD REGULAR EXPRESSION**"; + return UCHAR_CONSTANT("**NO MATCH** **BAD REGULAR EXPRESSION**"); dbgprintf("string to match for regex is: %s\n", pRes); @@ -2429,7 +2450,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, */ while(!bFound) { int iREstat; - iREstat = regexp.regexec(&pTpe->data.field.re, pRes + iOffs, nmatch, pmatch, 0); + iREstat = regexp.regexec(&pTpe->data.field.re, (char*)(pRes + iOffs), nmatch, pmatch, 0); dbgprintf("regexec return is %d\n", iREstat); if(iREstat == 0) { if(pmatch[0].rm_so == -1) { @@ -2457,11 +2478,11 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, *pbMustBeFreed = 0; } if(pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_DFLTSTR) - return "**NO MATCH**"; + return UCHAR_CONSTANT("**NO MATCH**"); else if(pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_ZERO) - return "0"; + return UCHAR_CONSTANT("0"); else - return ""; + return UCHAR_CONSTANT(""); } } else { /* Match- but did it match the one we wanted? */ @@ -2473,24 +2494,24 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, *pbMustBeFreed = 0; } if(pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_DFLTSTR) - return "**NO MATCH**"; + return UCHAR_CONSTANT("**NO MATCH**"); else - return ""; + return UCHAR_CONSTANT(""); } } /* OK, we have a usable match - we now need to malloc pB */ int iLenBuf; - char *pB; + uchar *pB; iLenBuf = pmatch[pTpe->data.field.iSubMatchToUse].rm_eo - pmatch[pTpe->data.field.iSubMatchToUse].rm_so; - pB = (char *) malloc((iLenBuf + 1) * sizeof(char)); + pB = malloc((iLenBuf + 1) * sizeof(uchar)); if (pB == NULL) { if (*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; - return "**OUT OF MEMORY ALLOCATING pBuf**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } /* Lets copy the matched substring to the buffer */ @@ -2513,7 +2534,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, free(pRes); *pbMustBeFreed = 0; } - return "***REGEXP NOT AVAILABLE***"; + return UCHAR_CONSTANT("***REGEXP NOT AVAILABLE***"); } } #endif /* #ifdef FEATURE_REGEXP */ @@ -2525,7 +2546,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, uchar cFirst = *pRes; /* save first char */ if(*pbMustBeFreed == 1) free(pRes); - pRes = (cFirst == ' ') ? "" : " "; + pRes = (cFirst == ' ') ? UCHAR_CONSTANT("") : UCHAR_CONSTANT(" "); bufLen = (cFirst == ' ') ? 0 : 1; *pbMustBeFreed = 0; } @@ -2537,21 +2558,21 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, if(pTpe->data.field.eCaseConv != tplCaseConvNo) { /* we need to obtain a private copy */ if(bufLen == -1) - bufLen = strlen(pRes); - char *pBStart; - char *pB; - char *pSrc; + bufLen = ustrlen(pRes); + uchar *pBStart; + uchar *pB; + uchar *pSrc; pBStart = pB = malloc((bufLen + 1) * sizeof(char)); if(pB == NULL) { if(*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } pSrc = pRes; while(*pSrc) { *pB++ = (pTpe->data.field.eCaseConv == tplCaseConvUpper) ? - (char)toupper((int)*pSrc) : (char)tolower((int)*pSrc); + (uchar)toupper((int)*pSrc) : (uchar)tolower((int)*pSrc); /* currently only these two exist */ ++pSrc; } @@ -2575,10 +2596,10 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, */ if(pTpe->data.field.options.bDropCC) { int iLenBuf = 0; - char *pSrc = pRes; - char *pDstStart; - char *pDst; - char bDropped = 0; + uchar *pSrc = pRes; + uchar *pDstStart; + uchar *pDst; + uchar bDropped = 0; while(*pSrc) { if(!iscntrl((int) *pSrc++)) @@ -2593,7 +2614,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, if(*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } for(pSrc = pRes; *pSrc; pSrc++) { if(!iscntrl((int) *pSrc)) @@ -2607,9 +2628,9 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, *pbMustBeFreed = 1; } } else if(pTpe->data.field.options.bSpaceCC) { - char *pSrc; - char *pDstStart; - char *pDst; + uchar *pSrc; + uchar *pDstStart; + uchar *pDst; if(*pbMustBeFreed == 1) { /* in this case, we already work on dynamic @@ -2623,13 +2644,13 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, } } else { if(bufLen == -1) - bufLen = strlen(pRes); + bufLen = ustrlen(pRes); pDst = pDstStart = malloc(bufLen + 1); if(pDst == NULL) { if(*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } for(pSrc = pRes; *pSrc; pSrc++) { if(iscntrl((int) *pSrc)) @@ -2649,7 +2670,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, */ int iNumCC = 0; int iLenBuf = 0; - char *pB; + uchar *pB; for(pB = pRes ; *pB ; ++pB) { ++iLenBuf; @@ -2659,21 +2680,21 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, if(iNumCC > 0) { /* if 0, there is nothing to escape, so we are done */ /* OK, let's do the escaping... */ - char *pBStart; - char szCCEsc[8]; /* buffer for escape sequence */ + uchar *pBStart; + uchar szCCEsc[8]; /* buffer for escape sequence */ int i; iLenBuf += iNumCC * 4; - pBStart = pB = malloc((iLenBuf + 1) * sizeof(char)); + pBStart = pB = malloc((iLenBuf + 1) * sizeof(uchar)); if(pB == NULL) { if(*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } while(*pRes) { if(iscntrl((int) *pRes)) { - snprintf(szCCEsc, sizeof(szCCEsc), "#%3.3d", *pRes); + snprintf((char*)szCCEsc, sizeof(szCCEsc), "#%3.3d", *pRes); for(i = 0 ; i < 4 ; ++i) *pB++ = szCCEsc[i]; } else { @@ -2697,10 +2718,10 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, if(pTpe->data.field.options.bSecPathDrop || pTpe->data.field.options.bSecPathReplace) { if(pTpe->data.field.options.bSecPathDrop) { int iLenBuf = 0; - char *pSrc = pRes; - char *pDstStart; - char *pDst; - char bDropped = 0; + uchar *pSrc = pRes; + uchar *pDstStart; + uchar *pDst; + uchar bDropped = 0; while(*pSrc) { if(*pSrc++ != '/') @@ -2715,7 +2736,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, if(*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } for(pSrc = pRes; *pSrc; pSrc++) { if(*pSrc != '/') @@ -2729,9 +2750,9 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, *pbMustBeFreed = 1; } } else { - char *pSrc; - char *pDstStart; - char *pDst; + uchar *pSrc; + uchar *pDstStart; + uchar *pDst; if(*pbMustBeFreed == 1) { /* here, again, we can modify the string as we already obtained @@ -2745,13 +2766,13 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, } } else { if(bufLen == -1) - bufLen = strlen(pRes); + bufLen = ustrlen(pRes); pDst = pDstStart = malloc(bufLen + 1); if(pDst == NULL) { if(*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } for(pSrc = pRes; *pSrc; pSrc++) { if(*pSrc == '/') @@ -2771,19 +2792,19 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, /* check for "." and ".." (note the parenthesis in the if condition!) */ if((*pRes == '.') && (*(pRes + 1) == '\0' || (*(pRes + 1) == '.' && *(pRes + 2) == '\0'))) { - char *pTmp = pRes; + uchar *pTmp = pRes; if(*(pRes + 1) == '\0') - pRes = "_"; + pRes = UCHAR_CONSTANT("_"); else - pRes = "_.";; + pRes = UCHAR_CONSTANT("_.");; if(*pbMustBeFreed == 1) free(pTmp); *pbMustBeFreed = 0; } else if(*pRes == '\0') { if(*pbMustBeFreed == 1) free(pRes); - pRes = "_"; + pRes = UCHAR_CONSTANT("_"); bufLen = 1; *pbMustBeFreed = 0; } @@ -2794,19 +2815,19 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, */ if(pTpe->data.field.options.bDropLastLF && !pTpe->data.field.options.bEscapeCC) { int iLn; - char *pB; + uchar *pB; if(bufLen == -1) - bufLen = strlen(pRes); + bufLen = ustrlen(pRes); iLn = bufLen; if(iLn > 0 && *(pRes + iLn - 1) == '\n') { /* we have a LF! */ /* check if we need to obtain a private copy */ if(*pbMustBeFreed == 0) { /* ok, original copy, need a private one */ - pB = malloc((iLn + 1) * sizeof(char)); + pB = malloc((iLn + 1) * sizeof(uchar)); if(pB == NULL) { *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } memcpy(pB, pRes, iLn - 1); pRes = pB; @@ -2825,19 +2846,19 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, if(pTpe->data.field.options.bCSV) { /* we need to obtain a private copy, as we need to at least add the double quotes */ int iBufLen; - char *pBStart; - char *pDst; - char *pSrc; + uchar *pBStart; + uchar *pDst; + uchar *pSrc; if(bufLen == -1) - bufLen = strlen(pRes); + bufLen = ustrlen(pRes); iBufLen = bufLen; /* the malloc may be optimized, we currently use the worst case... */ - pBStart = pDst = malloc((2 * iBufLen + 3) * sizeof(char)); + pBStart = pDst = malloc((2 * iBufLen + 3) * sizeof(uchar)); if(pDst == NULL) { if(*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; + return UCHAR_CONSTANT("**OUT OF MEMORY**"); } pSrc = pRes; *pDst++ = '"'; /* starting quote */ @@ -2856,7 +2877,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, } if(bufLen == -1) - bufLen = strlen(pRes); + bufLen = ustrlen(pRes); *pPropLen = bufLen; ENDfunc diff --git a/runtime/msg.h b/runtime/msg.h index c20fb005..98b3599a 100644 --- a/runtime/msg.h +++ b/runtime/msg.h @@ -159,7 +159,7 @@ void MsgSetMSGoffs(msg_t *pMsg, short offs); void MsgSetRawMsgWOSize(msg_t *pMsg, char* pszRawMsg); void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg, size_t lenMsg); rsRetVal MsgReplaceMSG(msg_t *pThis, uchar* pszMSG, int lenMSG); -char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, +uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, propid_t propID, size_t *pPropLen, unsigned short *pbMustBeFreed); char *textpri(char *pRes, size_t pResLen, int pri); rsRetVal msgGetMsgVar(msg_t *pThis, cstr_t *pstrPropName, var_t **ppVar); @@ -168,7 +168,7 @@ uchar *getRcvFrom(msg_t *pM); /* TODO: remove these five (so far used in action.c) */ -char *getMSG(msg_t *pM); +uchar *getMSG(msg_t *pM); char *getHOSTNAME(msg_t *pM); char *getPROCID(msg_t *pM, bool bLockMutex); char *getAPPNAME(msg_t *pM, bool bLockMutex); @@ -176,7 +176,7 @@ int getMSGLen(msg_t *pM); char *getHOSTNAME(msg_t *pM); int getHOSTNAMELen(msg_t *pM); -char *getProgramName(msg_t *pM, bool bLockMutex); +uchar *getProgramName(msg_t *pM, bool bLockMutex); int getProgramNameLen(msg_t *pM, bool bLockMutex); uchar *getRcvFrom(msg_t *pM); rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID); diff --git a/runtime/rule.c b/runtime/rule.c index 3a257a90..182d616a 100644 --- a/runtime/rule.c +++ b/runtime/rule.c @@ -39,6 +39,7 @@ #include "vm.h" #include "var.h" #include "srUtils.h" +#include "unicode-helper.h" #include "dirty.h" /* for getFIOPName */ /* static data */ @@ -104,7 +105,7 @@ shouldProcessThisMessage(rule_t *pRule, msg_t *pMsg, int *bProcessMsg) { DEFiRet; unsigned short pbMustBeFreed; - char *pszPropVal; + uchar *pszPropVal; int bRet = 0; size_t propLen; vm_t *pVM = NULL; @@ -189,12 +190,12 @@ shouldProcessThisMessage(rule_t *pRule, msg_t *pMsg, int *bProcessMsg) break; case FIOP_ISEQUAL: if(rsCStrSzStrCmp(pRule->f_filterData.prop.pCSCompValue, - (uchar*) pszPropVal, strlen(pszPropVal)) == 0) + pszPropVal, ustrlen(pszPropVal)) == 0) bRet = 1; /* process message! */ break; case FIOP_STARTSWITH: if(rsCStrSzStrStartsWithCStr(pRule->f_filterData.prop.pCSCompValue, - (uchar*) pszPropVal, strlen(pszPropVal)) == 0) + pszPropVal, ustrlen(pszPropVal)) == 0) bRet = 1; /* process message! */ break; case FIOP_REGEX: diff --git a/tests/Makefile.am b/tests/Makefile.am index e5b1f819..6ca0c069 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,6 +15,7 @@ TESTS = $(TESTRUNS) cfg.sh \ if ENABLE_OMSTDOUT TESTS += omod-if-array.sh \ + proprepltest.sh \ parsertest.sh \ timestamp.sh \ inputname.sh \ @@ -124,6 +125,11 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ testsuites/threadingmq.conf \ threadingmqaq.sh \ testsuites/threadingmqaq.conf \ + proprepltest.sh \ + testsuites/rfctag.conf \ + testsuites/master.rfctag \ + testsuites/nolimittag.conf \ + testsuites/master.nolimittag \ DiagTalker.java \ cfg.sh diff --git a/tests/diag.sh b/tests/diag.sh index 299c5d71..13bb877d 100755 --- a/tests/diag.sh +++ b/tests/diag.sh @@ -83,6 +83,7 @@ case $1 in fi ;; 'nettester') # perform nettester-based tests + # use -v for verbose output! ./nettester -t$2 -i$3 if [ "$?" -ne "0" ]; then exit 1 diff --git a/tests/nettester.c b/tests/nettester.c index 73abc46e..209c2a6f 100644 --- a/tests/nettester.c +++ b/tests/nettester.c @@ -38,6 +38,7 @@ #include <sys/socket.h> #include <sys/wait.h> #include <sys/stat.h> +#include <sys/time.h> #include <arpa/inet.h> #include <assert.h> #include <unistd.h> @@ -82,14 +83,27 @@ static char *inputMode2Str(inputMode_t mode) void readLine(int fd, char *ln) { + char *orig = ln; char c; int lenRead; + + if(verbose) + fprintf(stderr, "begin readLine\n"); lenRead = read(fd, &c, 1); while(lenRead == 1 && c != '\n') { + if(c == '\0') { + *ln = c; + fprintf(stderr, "Warning: there was a '\\0'-Byte in the read response " + "right after this string: '%s'\n", orig); + c = '?'; + } *ln++ = c; - lenRead = read(fd, &c, 1); + lenRead = read(fd, &c, 1); } *ln = '\0'; + + if(verbose) + fprintf(stderr, "end readLine, val read '%s'\n", orig); } @@ -133,8 +147,7 @@ tcpSend(char *buf, int lenBuf) fprintf(stderr, "connect() failed\n"); return(1); } else { - fprintf(stderr, "connect() failed, retry %d\n", retries); - usleep(100000); /* ms = 1000 us! */ + usleep(100000); /* 0.1 sec, these are us! */ } } } @@ -209,7 +222,6 @@ int openPipe(char *configFile, pid_t *pid, int *pfd) "RSYSLOG_DEBUGLOG=log", NULL }; */ - sprintf(confFile, "-f%s/testsuites/%s.conf", srcdir, (pszCustomConf == NULL) ? configFile : pszCustomConf); newargv[1] = confFile; diff --git a/tests/parsertest.sh b/tests/parsertest.sh index 8e04b95e..ef33256e 100755 --- a/tests/parsertest.sh +++ b/tests/parsertest.sh @@ -1,13 +1,5 @@ -echo test parsertest via udp -$srcdir/killrsyslog.sh # kill rsyslogd if it runs for some reason - -echo test parsertest via tcp -./nettester -tparse1 -itcp -if [ "$?" -ne "0" ]; then - exit 1 -fi - -./nettester -tparse1 -iudp -if [ "$?" -ne "0" ]; then - exit 1 -fi +echo TEST: parsertest.sh - various parser tests +source $srcdir/diag.sh init +source $srcdir/diag.sh nettester parse1 udp +source $srcdir/diag.sh nettester parse1 tcp +source $srcdir/diag.sh init diff --git a/tests/proprepltest.sh b/tests/proprepltest.sh new file mode 100755 index 00000000..3c252e52 --- /dev/null +++ b/tests/proprepltest.sh @@ -0,0 +1,7 @@ +echo TEST: proprepltest.sh - various tests for the property replacer +source $srcdir/diag.sh init +source $srcdir/diag.sh nettester rfctag udp +source $srcdir/diag.sh nettester rfctag tcp +source $srcdir/diag.sh nettester nolimittag udp +source $srcdir/diag.sh nettester nolimittag tcp +source $srcdir/diag.sh init diff --git a/tests/testsuites/master.nolimittag b/tests/testsuites/master.nolimittag new file mode 100644 index 00000000..502d9d5d --- /dev/null +++ b/tests/testsuites/master.nolimittag @@ -0,0 +1,11 @@ +<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message... ++TAG:+ +# now one char, no colon +<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message... ++0+ +# Now exactly with 32 characters +<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message... ++01234567890123456789012345678901+ +# Now oversize, should be completely output with this config +<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message... ++01234567890123456789012345678901-toolong+ diff --git a/tests/testsuites/master.rfctag b/tests/testsuites/master.rfctag new file mode 100644 index 00000000..3f1e0c66 --- /dev/null +++ b/tests/testsuites/master.rfctag @@ -0,0 +1,11 @@ +<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message... ++TAG:+ +# now one char, no colon +<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message... ++0+ +# Now exactly with 32 characters +<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message... ++01234567890123456789012345678901+ +# Now oversize, should be truncated with this config +<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message... ++01234567890123456789012345678901+ diff --git a/tests/testsuites/nolimittag.conf b/tests/testsuites/nolimittag.conf new file mode 100644 index 00000000..0b6ec387 --- /dev/null +++ b/tests/testsuites/nolimittag.conf @@ -0,0 +1,8 @@ +$ModLoad ../plugins/omstdout/.libs/omstdout +$IncludeConfig nettest.input.conf # This picks the to be tested input from the test driver! + +$ErrorMessagesToStderr off + +# use a special format +$template fmt,"+%syslogtag%+\n" +*.* :omstdout:;fmt diff --git a/tests/testsuites/rfctag.conf b/tests/testsuites/rfctag.conf new file mode 100644 index 00000000..8619e89e --- /dev/null +++ b/tests/testsuites/rfctag.conf @@ -0,0 +1,9 @@ +$ModLoad ../plugins/omstdout/.libs/omstdout +$IncludeConfig nettest.input.conf # This picks the to be tested input from the test driver! + +$ErrorMessagesToStderr off + +# use a special format +# Note: the plus signs are necessary to detect truncated logs! +$template fmt,"+%syslogtag:1:32%+\n" +*.* :omstdout:;fmt diff --git a/tools/syslogd.c b/tools/syslogd.c index e4daff54..ea267f58 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -920,239 +920,6 @@ finalize_it: RETiRet; } -#if 0 // Code obsoleted by merge imfile, but check for changes if there are problems -//thus I leave it in for the time being TODO: remove -/* 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<<pMsg->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); - } - - /* MULTIQUEUE: look at this below! (I say: batch states!) */ - 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 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 -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 -} - -#endif // if 0 from merge omfile /* The consumer of dequeued messages. This function is called by the * queue engine on dequeueing of a message. It runs on a SEPARATE |