diff options
author | Michael Biebl <biebl@debian.org> | 2008-03-29 12:14:33 +0100 |
---|---|---|
committer | Michael Biebl <biebl@debian.org> | 2008-03-29 12:14:33 +0100 |
commit | db2b679ef6aa0ac3d4679ad3e00a72993204ea78 (patch) | |
tree | 0f95fbe227c3276e051ac79a921045c533b06dda /msg.c | |
parent | 2bff2e5d72345617f3b3e394ff28823067024f7a (diff) | |
download | rsyslog-db2b679ef6aa0ac3d4679ad3e00a72993204ea78.tar.gz |
Imported Upstream version 1.19.7upstream/1.19.7
Diffstat (limited to 'msg.c')
-rw-r--r-- | msg.c | 416 |
1 files changed, 269 insertions, 147 deletions
@@ -88,7 +88,6 @@ void MsgDestruct(msg_t * pM) { assert(pM != NULL); /* DEV Debugging only ! dbgprintf("MsgDestruct\t0x%x, Ref now: %d\n", (int)pM, pM->iRefCount - 1); */ - MsgLock(); if(--pM->iRefCount == 0) { /* DEV Debugging Only! dbgprintf("MsgDestruct\t0x%x, RefCount now 0, doing DESTROY\n", (int)pM); */ @@ -126,9 +125,18 @@ void MsgDestruct(msg_t * pM) free(pM->pszTIMESTAMP_MySQL); if(pM->pszPRI != NULL) free(pM->pszPRI); + if(pM->pCSProgName != NULL) + rsCStrDestruct(pM->pCSProgName); + if(pM->pCSStrucData != NULL) + rsCStrDestruct(pM->pCSStrucData); + if(pM->pCSAPPNAME != NULL) + rsCStrDestruct(pM->pCSAPPNAME); + if(pM->pCSPROCID != NULL) + rsCStrDestruct(pM->pCSPROCID); + if(pM->pCSMSGID != NULL) + rsCStrDestruct(pM->pCSMSGID); free(pM); } - MsgUnlock(); } @@ -811,10 +819,10 @@ char *getMSGID(msg_t *pM) * function is a performance optimization over MsgSetTAG(). * rgerhards 2004-11-19 */ -void MsgAssignTAG(msg_t *pMsg, char *pBuf) +void MsgAssignTAG(msg_t *pMsg, uchar *pBuf) { assert(pMsg != NULL); - pMsg->iLenTAG = (pBuf == NULL) ? 0 : strlen(pBuf); + pMsg->iLenTAG = (pBuf == NULL) ? 0 : strlen((char*)pBuf); pMsg->pszTAG = (uchar*) pBuf; } @@ -844,7 +852,7 @@ void MsgSetTAG(msg_t *pMsg, char* pszTAG) static void tryEmulateTAG(msg_t *pM) { int iTAGLen; - char *pBuf; + uchar *pBuf; assert(pM != NULL); if(pM->pszTAG != NULL) @@ -859,7 +867,7 @@ static void tryEmulateTAG(msg_t *pM) iTAGLen = getAPPNAMELen(pM) + getPROCIDLen(pM) + 3; if((pBuf = malloc(iTAGLen * sizeof(char))) == NULL) return; /* nothing we can do */ - snprintf(pBuf, iTAGLen, "%s[%s]", getAPPNAME(pM), getPROCID(pM)); + snprintf((char*)pBuf, iTAGLen, "%s[%s]", getAPPNAME(pM), getPROCID(pM)); MsgAssignTAG(pM, pBuf); } } @@ -1242,7 +1250,7 @@ static uchar *getNOW(eNOWType eNow) char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, rsCStrObj *pCSPropName, unsigned short *pbMustBeFreed) { - char *pName; + uchar *pName; char *pRes; /* result pointer */ char *pBufStart; char *pBuf; @@ -1261,28 +1269,28 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, assert(pTpe != NULL); pName = pTpe->data.field.pPropRepl; } else { - pName = (char*) rsCStrGetSzStr(pCSPropName); + pName = rsCStrGetSzStrNoNULL(pCSPropName); } *pbMustBeFreed = 0; /* sometimes there are aliases to the original MonitoWare * property names. These come after || in the ifs below. */ - if(!strcmp(pName, "msg")) { + if(!strcmp((char*) pName, "msg")) { pRes = getMSG(pMsg); - } else if(!strcmp(pName, "rawmsg")) { + } else if(!strcmp((char*) pName, "rawmsg")) { pRes = getRawMsg(pMsg); - } else if(!strcmp(pName, "UxTradMsg")) { + } else if(!strcmp((char*) pName, "UxTradMsg")) { pRes = getUxTradMsg(pMsg); - } else if(!strcmp(pName, "FROMHOST")) { + } else if(!strcmp((char*) pName, "FROMHOST")) { pRes = getRcvFrom(pMsg); - } else if(!strcmp(pName, "source") - || !strcmp(pName, "HOSTNAME")) { + } else if(!strcmp((char*) pName, "source") + || !strcmp((char*) pName, "HOSTNAME")) { pRes = getHOSTNAME(pMsg); - } else if(!strcmp(pName, "syslogtag")) { + } else if(!strcmp((char*) pName, "syslogtag")) { pRes = getTAG(pMsg); - } else if(!strcmp(pName, "PRI")) { + } else if(!strcmp((char*) pName, "PRI")) { pRes = getPRI(pMsg); - } else if(!strcmp(pName, "PRI-text")) { + } else if(!strcmp((char*) pName, "PRI-text")) { pBuf = malloc(20 * sizeof(char)); if(pBuf == NULL) { *pbMustBeFreed = 0; @@ -1291,60 +1299,60 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, *pbMustBeFreed = 1; pRes = textpri(pBuf, 20, getPRIi(pMsg)); } - } else if(!strcmp(pName, "iut")) { + } else if(!strcmp((char*) pName, "iut")) { pRes = "1"; /* always 1 for syslog messages (a MonitorWare thing;)) */ - } else if(!strcmp(pName, "syslogfacility")) { + } else if(!strcmp((char*) pName, "syslogfacility")) { pRes = getFacility(pMsg); - } else if(!strcmp(pName, "syslogfacility-text")) { + } else if(!strcmp((char*) pName, "syslogfacility-text")) { pRes = getFacilityStr(pMsg); - } else if(!strcmp(pName, "syslogseverity") || !strcmp(pName, "syslogpriority")) { + } else if(!strcmp((char*) pName, "syslogseverity") || !strcmp((char*) pName, "syslogpriority")) { pRes = getSeverity(pMsg); - } else if(!strcmp(pName, "syslogseverity-text") || !strcmp(pName, "syslogpriority-text")) { + } else if(!strcmp((char*) pName, "syslogseverity-text") || !strcmp((char*) pName, "syslogpriority-text")) { pRes = getSeverityStr(pMsg); - } else if(!strcmp(pName, "timegenerated")) { + } else if(!strcmp((char*) pName, "timegenerated")) { pRes = getTimeGenerated(pMsg, pTpe->data.field.eDateFormat); - } else if(!strcmp(pName, "timereported") - || !strcmp(pName, "TIMESTAMP")) { + } else if(!strcmp((char*) pName, "timereported") + || !strcmp((char*) pName, "TIMESTAMP")) { pRes = getTimeReported(pMsg, pTpe->data.field.eDateFormat); - } else if(!strcmp(pName, "programname")) { + } else if(!strcmp((char*) pName, "programname")) { pRes = getProgramName(pMsg); - } else if(!strcmp(pName, "PROTOCOL-VERSION")) { + } else if(!strcmp((char*) pName, "PROTOCOL-VERSION")) { pRes = getProtocolVersionString(pMsg); - } else if(!strcmp(pName, "STRUCTURED-DATA")) { + } else if(!strcmp((char*) pName, "STRUCTURED-DATA")) { pRes = getStructuredData(pMsg); - } else if(!strcmp(pName, "APP-NAME")) { + } else if(!strcmp((char*) pName, "APP-NAME")) { pRes = getAPPNAME(pMsg); - } else if(!strcmp(pName, "PROCID")) { + } else if(!strcmp((char*) pName, "PROCID")) { pRes = getPROCID(pMsg); - } else if(!strcmp(pName, "MSGID")) { + } else if(!strcmp((char*) pName, "MSGID")) { pRes = getMSGID(pMsg); /* here start system properties (those, that do not relate to the message itself */ - } else if(!strcmp(pName, "$NOW")) { + } else if(!strcmp((char*) pName, "$NOW")) { if((pRes = (char*) getNOW(NOW_NOW)) == NULL) { return "***OUT OF MEMORY***"; } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ - } else if(!strcmp(pName, "$YEAR")) { + } else if(!strcmp((char*) pName, "$YEAR")) { if((pRes = (char*) getNOW(NOW_YEAR)) == NULL) { return "***OUT OF MEMORY***"; } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ - } else if(!strcmp(pName, "$MONTH")) { + } else if(!strcmp((char*) pName, "$MONTH")) { if((pRes = (char*) getNOW(NOW_MONTH)) == NULL) { return "***OUT OF MEMORY***"; } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ - } else if(!strcmp(pName, "$DAY")) { + } else if(!strcmp((char*) pName, "$DAY")) { if((pRes = (char*) getNOW(NOW_DAY)) == NULL) { return "***OUT OF MEMORY***"; } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ - } else if(!strcmp(pName, "$HOUR")) { + } else if(!strcmp((char*) pName, "$HOUR")) { if((pRes = (char*) getNOW(NOW_HOUR)) == NULL) { return "***OUT OF MEMORY***"; } else *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */ - } else if(!strcmp(pName, "$MINUTE")) { + } else if(!strcmp((char*) pName, "$MINUTE")) { if((pRes = (char*) getNOW(NOW_MINUTE)) == NULL) { return "***OUT OF MEMORY***"; } else @@ -1427,6 +1435,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, } else if(pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) { /* we need to obtain a private copy */ int iFrom, iTo; + char *pSb; iFrom = pTpe->data.field.iFromPos; iTo = pTpe->data.field.iToPos; /* need to zero-base to and from (they are 1-based!) */ @@ -1442,19 +1451,20 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, *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(*pRes && iFrom) { + while(*pSb && iFrom) { --iFrom; - ++pRes; + ++pSb; } } /* OK, we are at the begin - now let's copy... */ - while(*pRes && iLen) { - *pBuf++ = *pRes; - ++pRes; + while(*pSb && iLen) { + *pBuf++ = *pSb; + ++pSb; --iLen; } *pBuf = '\0'; @@ -1507,96 +1517,29 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, #endif /* #ifdef FEATURE_REGEXP */ } - /* case conversations (should go after substring, because so we are able to - * work on the smallest possible buffer). - */ - if(pTpe->data.field.eCaseConv != tplCaseConvNo) { - /* we need to obtain a private copy */ - int iBufLen = strlen(pRes); - char *pBStart; - char *pB; - pBStart = pB = malloc((iBufLen + 1) * sizeof(char)); - if(pB == NULL) { - if(*pbMustBeFreed == 1) - free(pRes); - *pbMustBeFreed = 0; - return "**OUT OF MEMORY**"; - } - while(*pRes) { - *pB++ = (pTpe->data.field.eCaseConv == tplCaseConvUpper) ? - toupper(*pRes) : tolower(*pRes); - /* currently only these two exist */ - ++pRes; - } - *pB = '\0'; - if(*pbMustBeFreed == 1) - free(pRes); - pRes = pBStart; - *pbMustBeFreed = 1; - } - - /* now do control character dropping/escaping/replacement - * Only one of these can be used. If multiple options are given, the - * result is random (though currently there obviously is an order of - * preferrence, see code below. But this is NOT guaranteed. - * RGerhards, 2006-11-17 - */ - if(pTpe->data.field.options.bDropCC) { - char *pSrc = pRes; - char *pDst = pRes; - - while(*pSrc) { - if(!iscntrl((int) *pSrc)) - *pDst++ = *pSrc; - ++pSrc; - } - *pDst = '\0'; - } else if(pTpe->data.field.options.bSpaceCC) { - char *pB = pRes; - while(*pB) { - if(iscntrl((int) *pB)) - *pB = ' '; - ++pB; - } - } else if(pTpe->data.field.options.bEscapeCC) { - /* we must first count how many control charactes are - * present, because we need this to compute the new string - * buffer length. While doing so, we also compute the string - * length. + if(*pRes) { + /* case conversations (should go after substring, because so we are able to + * work on the smallest possible buffer). */ - int iNumCC = 0; - int iLenBuf = 0; - char *pB; - - for(pB = pRes ; *pB ; ++pB) { - ++iLenBuf; - if(iscntrl((int) *pB)) - ++iNumCC; - } - - if(iNumCC > 0) { /* if 0, there is nothing to escape, so we are done */ - /* OK, let's do the escaping... */ + if(pTpe->data.field.eCaseConv != tplCaseConvNo) { + /* we need to obtain a private copy */ + int iBufLen = strlen(pRes); char *pBStart; - char szCCEsc[8]; /* buffer for escape sequence */ - int i; - - iLenBuf += iNumCC * 4; - pBStart = pB = malloc((iLenBuf + 1) * sizeof(char)); + char *pB; + char *pSrc; + pBStart = pB = malloc((iBufLen + 1) * sizeof(char)); if(pB == NULL) { if(*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; return "**OUT OF MEMORY**"; } - while(*pRes) { - if(iscntrl((int) *pRes)) { - snprintf(szCCEsc, sizeof(szCCEsc), "#%3.3d", *pRes); - for(i = 0 ; i < 4 ; ++i) - *pB++ = szCCEsc[i]; - } else { - *pB++ = *pRes; - } - ++pRes; + pSrc = pRes; + while(*pSrc) { + *pB++ = (pTpe->data.field.eCaseConv == tplCaseConvUpper) ? + toupper(*pSrc) : tolower(*pSrc); + /* currently only these two exist */ + ++pSrc; } *pB = '\0'; if(*pbMustBeFreed == 1) @@ -1604,6 +1547,130 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, pRes = pBStart; *pbMustBeFreed = 1; } + + /* now do control character dropping/escaping/replacement + * Only one of these can be used. If multiple options are given, the + * result is random (though currently there obviously is an order of + * preferrence, see code below. But this is NOT guaranteed. + * RGerhards, 2006-11-17 + * We must copy the strings if we modify them, because they may either + * point to static memory or may point into the message object, in which + * case we would actually modify the original property (which of course + * is wrong). + * This was found and fixed by varmojefkoj on 2007-09-11 + */ + if(pTpe->data.field.options.bDropCC) { + int iLenBuf = 0; + char *pSrc = pRes; + char *pDstStart; + char *pDst; + char bDropped = 0; + + while(*pSrc) { + if(!iscntrl((int) *pSrc++)) + iLenBuf++; + else + bDropped = 1; + } + + if(bDropped) { + pDst = pDstStart = malloc(iLenBuf + 1); + if(pDst == NULL) { + if(*pbMustBeFreed == 1) + free(pRes); + *pbMustBeFreed = 0; + return "**OUT OF MEMORY**"; + } + for(pSrc = pRes; *pSrc; pSrc++) { + if(!iscntrl((int) *pSrc)) + *pDst++ = *pSrc; + } + *pDst = '\0'; + if(*pbMustBeFreed == 1) + free(pRes); + pRes = pDstStart; + *pbMustBeFreed = 1; + } + } else if(pTpe->data.field.options.bSpaceCC) { + char *pSrc; + char *pDstStart; + char *pDst; + + if(*pbMustBeFreed == 1) { + /* in this case, we already work on dynamic + * memory, so there is no need to copy it - we can + * modify it in-place without any harm. This is a + * performance optiomization. + */ + for(pDst = pRes; *pDst; pDst++) { + if(iscntrl((int) *pDst)) + *pDst = ' '; + } + } else { + pDst = pDstStart = malloc(strlen(pRes) + 1); + if(pDst == NULL) { + if(*pbMustBeFreed == 1) + free(pRes); + *pbMustBeFreed = 0; + return "**OUT OF MEMORY**"; + } + for(pSrc = pRes; *pSrc; pSrc++) { + if(iscntrl((int) *pSrc)) + *pDst++ = ' '; + else + *pDst++ = *pSrc; + } + *pDst = '\0'; + pRes = pDstStart; + *pbMustBeFreed = 1; + } + } else if(pTpe->data.field.options.bEscapeCC) { + /* we must first count how many control charactes are + * present, because we need this to compute the new string + * buffer length. While doing so, we also compute the string + * length. + */ + int iNumCC = 0; + int iLenBuf = 0; + char *pB; + + for(pB = pRes ; *pB ; ++pB) { + ++iLenBuf; + if(iscntrl((int) *pB)) + ++iNumCC; + } + + 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 */ + int i; + + iLenBuf += iNumCC * 4; + pBStart = pB = malloc((iLenBuf + 1) * sizeof(char)); + if(pB == NULL) { + if(*pbMustBeFreed == 1) + free(pRes); + *pbMustBeFreed = 0; + return "**OUT OF MEMORY**"; + } + while(*pRes) { + if(iscntrl((int) *pRes)) { + snprintf(szCCEsc, sizeof(szCCEsc), "#%3.3d", *pRes); + for(i = 0 ; i < 4 ; ++i) + *pB++ = szCCEsc[i]; + } else { + *pB++ = *pRes; + } + ++pRes; + } + *pB = '\0'; + if(*pbMustBeFreed == 1) + free(pRes); + pRes = pBStart; + *pbMustBeFreed = 1; + } + } } /* Take care of spurious characters to make the property safe @@ -1611,37 +1678,92 @@ 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 *pDst = pRes; + char *pDstStart; + char *pDst; + char bDropped = 0; + while(*pSrc) { - if(*pSrc != '/') - *pDst++ = *pSrc; - pSrc++; + if(*pSrc++ != '/') + iLenBuf++; + else + bDropped = 1; + } + + if(bDropped) { + pDst = pDstStart = malloc(iLenBuf + 1); + if(pDst == NULL) { + if(*pbMustBeFreed == 1) + free(pRes); + *pbMustBeFreed = 0; + return "**OUT OF MEMORY**"; + } + for(pSrc = pRes; *pSrc; pSrc++) { + if(*pSrc != '/') + *pDst++ = *pSrc; + } + *pDst = '\0'; + if(*pbMustBeFreed == 1) + free(pRes); + pRes = pDstStart; + *pbMustBeFreed = 1; } - *pDst = '\0'; } else { - char *pB = pRes; - while(*pB) { - if(*pB == '/') - *pB = '_'; - pB++; + char *pSrc; + char *pDstStart; + char *pDst; + + if(*pbMustBeFreed == 1) { + /* here, again, we can modify the string as we already obtained + * a private buffer. As we do not change the size of that buffer, + * in-place modification is possible. This is a performance + * enhancement. + */ + for(pDst = pRes; *pDst; pDst++) { + if(*pDst == '/') + *pDst++ = '_'; + } + } else { + pDst = pDstStart = malloc(strlen(pRes) + 1); + if(pDst == NULL) { + if(*pbMustBeFreed == 1) + free(pRes); + *pbMustBeFreed = 0; + return "**OUT OF MEMORY**"; + } + for(pSrc = pRes; *pSrc; pSrc++) { + if(*pSrc == '/') + *pDst++ = '_'; + else + *pDst++ = *pSrc; + } + *pDst = '\0'; + /* we must NOT check if it needs to be freed, because we have done + * this in the if above. So if we come to hear, the pSrc string needs + * not to be freed (and we do not need to care about it). + */ + pRes = pDstStart; + *pbMustBeFreed = 1; } } - if(*pRes == '.' && (*(pRes + 1) == '\0' || (*(pRes + 1) == '.' && *(pRes + 2) == '\0'))) - *pRes = '_'; - - if(*pRes == '\0') { + /* check for "." and ".." (note the parenthesis in the if condition!) */ + if((*pRes == '.') && (*(pRes + 1) == '\0' || (*(pRes + 1) == '.' && *(pRes + 2) == '\0'))) { + char *pTmp = pRes; + + if(*(pRes + 1) == '\0') + pRes = "_"; + else + pRes = "_.";; + if(*pbMustBeFreed == 1) + free(pTmp); + *pbMustBeFreed = 0; + } else if(*pRes == '\0') { if(*pbMustBeFreed == 1) free(pRes); - pRes = malloc(2); - if(pRes == NULL) { - *pbMustBeFreed = 0; - return "**OUT OF MEMORY ALLOCATING pBuf**"; - } - *pRes = '_'; - *(pRes + 1) = '\0'; - *pbMustBeFreed = 1; + pRes = "_"; + *pbMustBeFreed = 0; } } @@ -1651,7 +1773,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, if(pTpe->data.field.options.bDropLastLF && !pTpe->data.field.options.bEscapeCC) { int iLn = strlen(pRes); char *pB; - if(*(pRes + iLn - 1) == '\n') { + if(iLn > 0 && *(pRes + iLn - 1) == '\n') { /* we have a LF! */ /* check if we need to obtain a private copy */ if(*pbMustBeFreed == 0) { |