diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2009-04-03 12:52:53 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2009-04-03 12:52:53 +0200 |
commit | 1a08fa5ded3087a3b60d87a20d25a4ec589eba21 (patch) | |
tree | 9dd51c4b9db468be41a63f4286029d95bef0bf0b | |
parent | 5f397495524ffe460fe93d2f1069f3077f48b7b0 (diff) | |
parent | ec0e2c3e7df6addc02431628daddfeae49b92af7 (diff) | |
download | rsyslog-1a08fa5ded3087a3b60d87a20d25a4ec589eba21.tar.gz rsyslog-1a08fa5ded3087a3b60d87a20d25a4ec589eba21.tar.xz rsyslog-1a08fa5ded3087a3b60d87a20d25a4ec589eba21.zip |
Merge branch 'master' into oracle
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | action.c | 32 | ||||
-rw-r--r-- | action.h | 2 | ||||
-rw-r--r-- | doc/features.html | 3 | ||||
-rw-r--r-- | doc/rsyslog_conf_modules.html | 7 | ||||
-rw-r--r-- | plugins/imklog/linux.c | 2 | ||||
-rw-r--r-- | plugins/omstdout/omstdout.c | 80 | ||||
-rw-r--r-- | runtime/cfsysline.c | 4 | ||||
-rw-r--r-- | runtime/debug.c | 2 | ||||
-rw-r--r-- | runtime/modules.c | 2 | ||||
-rw-r--r-- | runtime/objomsr.c | 18 | ||||
-rw-r--r-- | runtime/objomsr.h | 6 | ||||
-rw-r--r-- | runtime/rsyslog.h | 5 | ||||
-rw-r--r-- | runtime/stringbuf.c | 38 | ||||
-rw-r--r-- | runtime/stringbuf.h | 3 | ||||
-rw-r--r-- | template.c | 56 | ||||
-rw-r--r-- | template.h | 1 | ||||
-rw-r--r-- | tools/omfile.c | 12 | ||||
-rw-r--r-- | tools/pidfile.c | 2 | ||||
-rw-r--r-- | tools/syslogd.c | 8 | ||||
-rw-r--r-- | tools/syslogd.h | 1 |
21 files changed, 259 insertions, 30 deletions
@@ -34,6 +34,11 @@ Version 4.1.6 [DEVEL] (rgerhards), 2009-03-?? the full high availability features of rsyslog's engine - bugfix: fixed some segaults on Solaris, where vsprintf() does not check for NULL pointers +- improved performance of regexp-based filters + Thanks to Arnaud Cornet for providing the idea and initial patch. +- added a new way how output plugins may be passed parameters. This is + more effcient for some outputs. They new can receive fields not only + as a single string but rather in an array where each string is seperated. --------------------------------------------------------------------------- Version 4.1.5 [DEVEL] (rgerhards), 2009-03-11 - bugfix: parser did not correctly parse fields in UDP-received messages @@ -425,6 +425,7 @@ actionCallDoAction(action_t *pAction, msg_t *pMsg) DEFiRet; int iRetries; int i; + int iArr; int iSleepPeriod; int bCallAction; int iCancelStateSave; @@ -439,7 +440,15 @@ actionCallDoAction(action_t *pAction, msg_t *pMsg) /* here we must loop to process all requested strings */ for(i = 0 ; i < pAction->iNumTpls ; ++i) { - CHKiRet(tplToString(pAction->ppTpl[i], pMsg, &(ppMsgs[i]))); + switch(pAction->eParamPassing) { + case ACT_STRING_PASSING: + CHKiRet(tplToString(pAction->ppTpl[i], pMsg, &(ppMsgs[i]))); + break; + case ACT_ARRAY_PASSING: + CHKiRet(tplToArray(pAction->ppTpl[i], pMsg, (uchar***) &(ppMsgs[i]))); + break; + default:assert(0); /* software bug if this happens! */ + } } iRetries = 0; /* We now must guard the output module against execution by multiple threads. The @@ -495,7 +504,19 @@ finalize_it: /* cleanup */ for(i = 0 ; i < pAction->iNumTpls ; ++i) { if(ppMsgs[i] != NULL) { - d_free(ppMsgs[i]); + switch(pAction->eParamPassing) { + case ACT_ARRAY_PASSING: + iArr = 0; + while(((char **)ppMsgs[i])[iArr] != NULL) + d_free(((char **)ppMsgs[i])[iArr++]); + d_free(ppMsgs[i]); + break; + case ACT_STRING_PASSING: + d_free(ppMsgs[i]); + break; + default: + assert(0); + } } } d_free(ppMsgs); @@ -905,6 +926,13 @@ addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringReques ABORT_FINALIZE(RS_RET_RQD_TPLOPT_MISSING); } + /* set parameter-passing mode */ + if(iTplOpts & OMSR_TPL_AS_ARRAY) { + pAction->eParamPassing = ACT_ARRAY_PASSING; + } else { + pAction->eParamPassing = ACT_STRING_PASSING; + } + dbgprintf("template: '%s' assigned\n", pTplName); } @@ -61,6 +61,8 @@ struct action_s { short f_ReduceRepeated;/* reduce repeated lines 0 - no, 1 - yes */ int f_prevcount; /* repetition cnt of prevline */ int f_repeatcount; /* number of "repeated" msgs */ + enum { ACT_STRING_PASSING = 0, ACT_ARRAY_PASSING = 1 } + eParamPassing; /* mode of parameter passing to action */ int iNumTpls; /* number of array entries for template element below */ struct template **ppTpl;/* array of template to use - strings must be passed to doAction * in this order. */ diff --git a/doc/features.html b/doc/features.html index 501f3304..17a995bf 100644 --- a/doc/features.html +++ b/doc/features.html @@ -95,6 +95,9 @@ via custom plugins</li> <li> an easy-to-write to plugin interface</li> <li> ability to send SNMP trap messages</li> <li> ability to filter out messages based on sequence of arrival</li> +<li>support for comma-seperated-values (CSV) output generation +(via the "csv" property replace option). The +CSV format supported is that from RFC 4180.</li> <li>support for arbitrary complex boolean, string and arithmetic expressions in message filters</li> </ul> diff --git a/doc/rsyslog_conf_modules.html b/doc/rsyslog_conf_modules.html index 890a55c8..a281d9e7 100644 --- a/doc/rsyslog_conf_modules.html +++ b/doc/rsyslog_conf_modules.html @@ -8,10 +8,9 @@ number of modules. Here is the entry point to their documentation and what they do (list is currently not complete)</p> <ul> -<li><a href="omsnmp.html">omsnmp</a> - SNMP -trap output module</li> -<li><a href="omrelp.html">omrelp</a> - RELP -output module</li> +<li><a href="omsnmp.html">omsnmp</a> - SNMP trap output module</li> +<li><a href="omstdout.html">omtdout</a> - stdout output module (mainly a test tool)</li> +<li><a href="omrelp.html">omrelp</a> - RELP output module</li> <li>omgssapi - output module for GSS-enabled syslog</li> <li><a href="ommysql.html">ommysql</a> - output module for MySQL</li> <li>ompgsql - output module for PostgreSQL</li> diff --git a/plugins/imklog/linux.c b/plugins/imklog/linux.c index 198b7c0e..0dd4320d 100644 --- a/plugins/imklog/linux.c +++ b/plugins/imklog/linux.c @@ -144,7 +144,7 @@ static enum LOGSRC GetKernelLogSrc(void) return(kernel); } - if ( (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 ) + if ( (kmsg = open(_PATH_KLOG, O_RDONLY|O_CLOEXEC)) < 0 ) { imklogLogIntMsg(LOG_ERR, "imklog: Cannot open proc file system, %d.\n", errno); ksyslog(7, NULL, 0); /* TODO: check this, implement more */ diff --git a/plugins/omstdout/omstdout.c b/plugins/omstdout/omstdout.c index 6e227ba9..e491005c 100644 --- a/plugins/omstdout/omstdout.c +++ b/plugins/omstdout/omstdout.c @@ -49,7 +49,12 @@ MODULE_TYPE_OUTPUT */ DEF_OMOD_STATIC_DATA +/* config variables */ +static int bUseArrayInterface; /* shall action use array instead of string template interface? */ + + typedef struct _instanceData { + int bUseArrayInterface; /* uses action use array instead of string template interface? */ } instanceData; BEGINcreateInstance @@ -79,12 +84,46 @@ CODESTARTtryResume ENDtryResume BEGINdoAction + char **szParams; + char *toWrite; + int iParamVal; + int iParam; + int iBuf; + char szBuf[65564]; CODESTARTdoAction - write(1, (char*)ppString[0], strlen((char*)ppString[0])); + if(pData->bUseArrayInterface) { + /* if we use array passing, we need to put together a string + * ourselves. At this point, please keep in mind that omstdout is + * primarily a testing aid. Other modules may do different processing + * if they would like to support downlevel versions which do not support + * array-passing, but also use that interface on cores who do... + * So this code here is also more or less an example of how to do that. + * rgerhards, 2009-04-03 + */ + szParams = (char**) (ppString[0]); + /* In array-passing mode, ppString[] contains a NULL-terminated array + * of char *pointers. + */ + iParam = 0; + iBuf = 0; + while(szParams[iParam] != NULL) { + iParamVal = 0; + while(szParams[iParam][iParamVal] != '\0' && iBuf < sizeof(szBuf)) { + szBuf[iBuf++] = szParams[iParam][iParamVal++]; + } + ++iParam; + } + szBuf[iBuf] = '\0'; + toWrite = szBuf; + } else { + toWrite = (char*) ppString[0]; + } + write(1, toWrite, strlen(toWrite)); /* 1 is stdout! */ ENDdoAction BEGINparseSelectorAct + int iTplOpts; CODESTARTparseSelectorAct CODE_STD_STRING_REQUESTparseSelectorAct(1) /* first check if this config line is actually for us */ @@ -99,7 +138,9 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) /* check if a non-standard template is to be applied */ if(*(p-1) == ';') --p; - CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, 0, (uchar*) "RSYSLOG_FileFormat")); + iTplOpts = (bUseArrayInterface == 0) ? 0 : OMSR_TPL_AS_ARRAY; + CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, iTplOpts, (uchar*) "RSYSLOG_FileFormat")); + pData->bUseArrayInterface = bUseArrayInterface; CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct @@ -115,10 +156,45 @@ CODEqueryEtryPt_STD_OMOD_QUERIES ENDqueryEtryPt + +/* Reset config variables for this module to default values. + */ +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + DEFiRet; + bUseArrayInterface = 0; + RETiRet; +} + + BEGINmodInit() + rsRetVal localRet; + rsRetVal (*pomsrGetSupportedTplOpts)(unsigned long *pOpts); + unsigned long opts; + int bArrayPassingSupported; /* does core support template passing as an array? */ CODESTARTmodInit *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr + /* check if the rsyslog core supports parameter passing code */ + bArrayPassingSupported = 0; + localRet = pHostQueryEtryPt((uchar*)"OMSRgetSupportedTplOpts", &pomsrGetSupportedTplOpts); + if(localRet == RS_RET_OK) { + /* found entry point, so let's see if core supports array passing */ + CHKiRet((*pomsrGetSupportedTplOpts)(&opts)); + if(opts & OMSR_TPL_AS_ARRAY) + bArrayPassingSupported = 1; + } else if(localRet != RS_RET_ENTRY_POINT_NOT_FOUND) { + ABORT_FINALIZE(localRet); /* Something else went wrong, what is not acceptable */ + } + DBGPRINTF("omstdout: array-passing is %ssupported by rsyslog core.\n", bArrayPassingSupported ? "" : "not "); + + if(bArrayPassingSupported) { + /* enable config comand only if core supports it */ + CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomstdoutarrayinterface", 0, eCmdHdlrBinary, NULL, + &bUseArrayInterface, STD_LOADABLE_MODULE_ID)); + } + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, + resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit /* vi:set ai: diff --git a/runtime/cfsysline.c b/runtime/cfsysline.c index c4490b48..e1e4a6a4 100644 --- a/runtime/cfsysline.c +++ b/runtime/cfsysline.c @@ -364,7 +364,7 @@ static rsRetVal doGetGID(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *p /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, pgBuf->gr_gid)); } - dbgprintf("gid %d obtained for group '%s'\n", pgBuf->gr_gid, szName); + dbgprintf("gid %d obtained for group '%s'\n", (int) pgBuf->gr_gid, szName); } skipWhiteSpace(pp); /* skip over any whitespace */ @@ -406,7 +406,7 @@ static rsRetVal doGetUID(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *p /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, ppwBuf->pw_uid)); } - dbgprintf("uid %d obtained for user '%s'\n", ppwBuf->pw_uid, szName); + dbgprintf("uid %d obtained for user '%s'\n", (int) ppwBuf->pw_uid, szName); } skipWhiteSpace(pp); /* skip over any whitespace */ diff --git a/runtime/debug.c b/runtime/debug.c index 96004e47..4ee90226 100644 --- a/runtime/debug.c +++ b/runtime/debug.c @@ -1343,7 +1343,7 @@ rsRetVal dbgClassInit(void) if(pszAltDbgFileName != NULL) { /* we have a secondary file, so let's open it) */ - if((altdbg = open(pszAltDbgFileName, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, S_IRUSR|S_IWUSR)) == -1) { + if((altdbg = open(pszAltDbgFileName, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_CLOEXEC, S_IRUSR|S_IWUSR)) == -1) { fprintf(stderr, "alternate debug file could not be opened, ignoring. Error: %s\n", strerror(errno)); } } diff --git a/runtime/modules.c b/runtime/modules.c index cef4eac6..9fdb48e7 100644 --- a/runtime/modules.c +++ b/runtime/modules.c @@ -225,6 +225,8 @@ static rsRetVal queryHostEtryPt(uchar *name, rsRetVal (**pEtryPoint)()) *pEtryPoint = regCfSysLineHdlr; } else if(!strcmp((char*) name, "objGetObjInterface")) { *pEtryPoint = objGetObjInterface; + } else if(!strcmp((char*) name, "OMSRgetSupportedTplOpts")) { + *pEtryPoint = OMSRgetSupportedTplOpts; } else { *pEtryPoint = NULL; /* to be on the safe side */ ABORT_FINALIZE(RS_RET_ENTRY_POINT_NOT_FOUND); diff --git a/runtime/objomsr.c b/runtime/objomsr.c index 21d284f3..8dddc4b8 100644 --- a/runtime/objomsr.c +++ b/runtime/objomsr.c @@ -141,5 +141,23 @@ int OMSRgetEntry(omodStringRequest_t *pThis, int iEntry, uchar **ppTplName, int return RS_RET_OK; } + + +/* return the full set of template options that are supported by this version of + * OMSR. They are returned in an unsigned long value. The caller can mask that + * value to check on the option he is interested in. + * Note that this interface was added in 4.1.6, so a plugin must obtain a pointer + * to this interface via queryHostEtryPt(). + * rgerhards, 2009-04-03 + */ +rsRetVal +OMSRgetSupportedTplOpts(unsigned long *pOpts) +{ + DEFiRet; + assert(pOpts != NULL); + *pOpts = OMSR_RQD_TPL_OPT_SQL | OMSR_TPL_AS_ARRAY; + RETiRet; +} + /* vim:set ai: */ diff --git a/runtime/objomsr.h b/runtime/objomsr.h index 2255e4f3..75ad0fb8 100644 --- a/runtime/objomsr.h +++ b/runtime/objomsr.h @@ -1,6 +1,6 @@ /* Definition of the omsr (omodStringRequest) object. * - * Copyright 2007 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * @@ -27,7 +27,8 @@ /* define flags for required template options */ #define OMSR_NO_RQD_TPL_OPTS 0 #define OMSR_RQD_TPL_OPT_SQL 1 -/* next option is 2, 4, 8, ... */ +#define OMSR_TPL_AS_ARRAY 2 /* introduced in 4.1.6, 2009-04-03 */ +/* next option is 4, 8, 16, ... */ struct omodStringRequest_s { /* strings requested by output module for doAction() */ int iNumEntries; /* number of array entries for data elements below */ @@ -40,6 +41,7 @@ typedef struct omodStringRequest_s omodStringRequest_t; rsRetVal OMSRdestruct(omodStringRequest_t *pThis); rsRetVal OMSRconstruct(omodStringRequest_t **ppThis, int iNumEntries); rsRetVal OMSRsetEntry(omodStringRequest_t *pThis, int iEntry, uchar *pTplName, int iTplOpts); +rsRetVal OMSRgetSupportedTplOpts(unsigned long *pOpts); int OMSRgetEntryCount(omodStringRequest_t *pThis); int OMSRgetEntry(omodStringRequest_t *pThis, int iEntry, uchar **ppTplName, int *piTplOpts); diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h index 899f5e13..032d8c04 100644 --- a/runtime/rsyslog.h +++ b/runtime/rsyslog.h @@ -341,6 +341,11 @@ typedef enum rsObjectID rsObjID; # define __attribute__(x) /*NOTHING*/ #endif +#ifndef O_CLOEXEC +/* of course, this limits the functionality... */ +# define O_CLOEXEC 0 +#endif + /* The following prototype is convenient, even though it may not be the 100% correct place.. -- rgerhards 2008-01-07 */ void dbgprintf(char *, ...) __attribute__((format(printf, 1, 2))); diff --git a/runtime/stringbuf.c b/runtime/stringbuf.c index a5dc625a..35ec44c6 100644 --- a/runtime/stringbuf.c +++ b/runtime/stringbuf.c @@ -703,17 +703,26 @@ int rsCStrCaseInsensitveStartsWithSzStr(cstr_t *pCS1, uchar *psz, size_t iLenSz) * never is a \0 *inside* a property string. * Note that the function returns -1 if regexp functionality is not available. * rgerhards: 2009-03-04: ERE support added, via parameter iType: 0 - BRE, 1 - ERE + * Arnaud Cornet/rgerhards: 2009-04-02: performance improvement by caching compiled regex + * If a caller does not need the cached version, it must still provide memory for it + * and must call rsCStrRegexDestruct() afterwards. */ -rsRetVal rsCStrSzStrMatchRegex(cstr_t *pCS1, uchar *psz, int iType) +rsRetVal rsCStrSzStrMatchRegex(cstr_t *pCS1, uchar *psz, int iType, void *rc) { - regex_t preq; + regex_t **cache = (regex_t**) rc; int ret; DEFiRet; + assert(pCS1 != NULL); + assert(psz != NULL); + assert(cache != NULL); + if(objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { - regexp.regcomp(&preq, (char*) rsCStrGetSzStr(pCS1), (iType == 1 ? REG_EXTENDED : 0) | REG_NOSUB); - ret = regexp.regexec(&preq, (char*) psz, 0, NULL, 0); - regexp.regfree(&preq); + if (*cache == NULL) { + *cache = calloc(sizeof(regex_t), 1); + regexp.regcomp(*cache, (char*) rsCStrGetSzStr(pCS1), (iType == 1 ? REG_EXTENDED : 0) | REG_NOSUB); + } + ret = regexp.regexec(*cache, (char*) psz, 0, NULL, 0); if(ret != 0) ABORT_FINALIZE(RS_RET_NOT_FOUND); } else { @@ -725,6 +734,25 @@ finalize_it: } +/* free a cached compiled regex + * Caller must provide a pointer to a buffer that was created by + * rsCStrSzStrMatchRegexCache() + */ +void rsCStrRegexDestruct(void *rc) +{ + regex_t **cache = rc; + + assert(cache != NULL); + assert(*cache != NULL); + + if(objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { + regexp.regfree(*cache); + free(*cache); + *cache = NULL; + } +} + + /* compare a rsCStr object with a classical sz string. This function * is almost identical to rsCStrZsStrCmp(), but it also takes an offset * to the CStr object from where the comparison is to start. diff --git a/runtime/stringbuf.h b/runtime/stringbuf.h index f3e08439..684133bb 100644 --- a/runtime/stringbuf.h +++ b/runtime/stringbuf.h @@ -136,7 +136,8 @@ int rsCStrCaseInsensitiveLocateInSzStr(cstr_t *pThis, uchar *sz); int rsCStrStartsWithSzStr(cstr_t *pCS1, uchar *psz, size_t iLenSz); int rsCStrCaseInsensitveStartsWithSzStr(cstr_t *pCS1, uchar *psz, size_t iLenSz); int rsCStrSzStrStartsWithCStr(cstr_t *pCS1, uchar *psz, size_t iLenSz); -rsRetVal rsCStrSzStrMatchRegex(cstr_t *pCS1, uchar *psz, int iType); +rsRetVal rsCStrSzStrMatchRegex(cstr_t *pCS1, uchar *psz, int iType, void *cache); +void rsCStrRegexDestruct(void *rc); rsRetVal rsCStrConvertToNumber(cstr_t *pStr, number_t *pNumber); rsRetVal rsCStrConvertToBool(cstr_t *pStr, number_t *pBool); rsRetVal rsCStrAppendCStr(cstr_t *pThis, cstr_t *pstrAppend); @@ -47,6 +47,8 @@ static struct template *tplRoot = NULL; /* the root of the template list */ static struct template *tplLast = NULL; /* points to the last element of the template list */ static struct template *tplLastStatic = NULL; /* last static element of the template list */ + + /* This functions converts a template into a string. It should * actually be in template.c, but this requires larger re-structuring * of the code (because all the property-access functions are static @@ -140,6 +142,60 @@ finalize_it: RETiRet; } + +/* This functions converts a template into an array of strings. + * For further general details, see the very similar funtion + * tpltoString(). + * Instead of a string, an array of string pointers is returned by + * thus function. The caller is repsonsible for destroying that array as + * well as all of its elements. The array is of fixed size. It's end + * is indicated by a NULL pointer. + * rgerhards, 2009-04-03 + */ +rsRetVal tplToArray(struct template *pTpl, msg_t *pMsg, uchar*** ppArr) +{ + DEFiRet; + struct templateEntry *pTpe; + uchar **pArr; + int iArr; + unsigned short bMustBeFreed; + uchar *pVal; + + assert(pTpl != NULL); + assert(pMsg != NULL); + assert(ppArr != NULL); + + /* loop through the template. We obtain one value, create a + * private copy (if necessary), add it to the string array + * and then on to the next until we have processed everything. + */ + + CHKmalloc(pArr = calloc(pTpl->tpenElements + 1, sizeof(uchar*))); + iArr = 0; + + pTpe = pTpl->pEntryRoot; + while(pTpe != NULL) { + if(pTpe->eEntryType == CONSTANT) { + CHKmalloc(pArr[iArr] = (uchar*)strdup((char*) pTpe->data.constant.pConstant)); + } else if(pTpe->eEntryType == FIELD) { + pVal = (uchar*) MsgGetProp(pMsg, pTpe, NULL, &bMustBeFreed); + if(bMustBeFreed) { /* if it must be freed, it is our own private copy... */ + pArr[iArr] = pVal; /* ... so we can use it! */ + } else { + CHKmalloc(pArr[iArr] = (uchar*)strdup((char*) pVal)); + } + } + iArr++; + pTpe = pTpe->pNext; + } + +finalize_it: + *ppArr = (iRet == RS_RET_OK) ? pArr : NULL; + + RETiRet; +} + + /* Helper to doSQLEscape. This is called if doSQLEscape * runs out of memory allocating the escaped string. * Then we are in trouble. We can @@ -126,6 +126,7 @@ void tplLastStaticInit(struct template *tpl); * BEFORE msg.h, even if your code file does not actually need it. * rgerhards, 2007-08-06 */ +rsRetVal tplToArray(struct template *pTpl, msg_t *pMsg, uchar*** ppArr); rsRetVal tplToString(struct template *pTpl, msg_t *pMsg, uchar** ppSz); rsRetVal doSQLEscape(uchar **pp, size_t *pLen, unsigned short *pbMustBeFreed, int escapeMode); diff --git a/tools/omfile.c b/tools/omfile.c index 5141b4da..36f160d1 100644 --- a/tools/omfile.c +++ b/tools/omfile.c @@ -301,7 +301,7 @@ int resolveFileSizeLimit(instanceData *pData) free(pCmd); - pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, + pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_CLOEXEC, pData->fCreateMode); actualFileSize = lseek(pData->fd, 0, SEEK_END); @@ -394,13 +394,13 @@ prepareFile(instanceData *pData, uchar *newFileName) { DEFiRet; if(pData->fileType == eTypePIPE) { - pData->fd = open((char*) pData->f_fname, O_RDWR|O_NONBLOCK); + pData->fd = open((char*) pData->f_fname, O_RDWR|O_NONBLOCK|O_CLOEXEC); FINALIZE; /* we are done in this case */ } if(access((char*)newFileName, F_OK) == 0) { /* file already exists */ - pData->fd = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, + pData->fd = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_CLOEXEC, pData->fCreateMode); } else { pData->fd = -1; @@ -419,7 +419,7 @@ prepareFile(instanceData *pData, uchar *newFileName) /* no matter if we needed to create directories or not, we now try to create * the file. -- rgerhards, 2008-12-18 (based on patch from William Tisater) */ - pData->fd = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, + pData->fd = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_CLOEXEC, pData->fCreateMode); if(pData->fd != -1) { /* check and set uid/gid */ @@ -653,7 +653,7 @@ again: && e == EBADF #endif ) { - pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_NOCTTY); + pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_NOCTTY|O_CLOEXEC); if (pData->fd < 0) { iRet = RS_RET_SUSPENDED; errmsg.LogError(0, NO_ERRCODE, "%s", pData->f_fname); @@ -742,7 +742,7 @@ CODESTARTparseSelectorAct pData->bDynamicName = 0; pData->fCreateMode = fCreateMode; /* preserve current setting */ pData->fDirCreateMode = fDirCreateMode; /* preserve current setting */ - pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, + pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_CLOEXEC, pData->fCreateMode); } break; diff --git a/tools/pidfile.c b/tools/pidfile.c index 2be13da6..e7744513 100644 --- a/tools/pidfile.c +++ b/tools/pidfile.c @@ -97,7 +97,7 @@ int write_pid (char *pidfile) int fd; int pid; - if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1) + if ( ((fd = open(pidfile, O_RDWR|O_CREAT|O_CLOEXEC, 0644)) == -1) || ((f = fdopen(fd, "r+")) == NULL) ) { fprintf(stderr, "Can't open or create %s.\n", pidfile); return 0; diff --git a/tools/syslogd.c b/tools/syslogd.c index c72160fb..b23c12a7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -429,6 +429,8 @@ 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); @@ -549,7 +551,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); @@ -1076,12 +1078,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) == RS_RET_OK) + (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: diff --git a/tools/syslogd.h b/tools/syslogd.h index f1b11a91..8b9bd131 100644 --- a/tools/syslogd.h +++ b/tools/syslogd.h @@ -73,6 +73,7 @@ struct filed { FIOP_REGEX = 4, /* matches a (BRE) regular expression? */ FIOP_EREREGEX = 5 /* matches a ERE regular expression? */ } operation; + regex_t *regex_cache; /* cache for compiled REs, if such are used */ cstr_t *pCSCompValue; /* value to "compare" against */ char isNegated; /* actually a boolean ;) */ } prop; |