summaryrefslogtreecommitdiff
path: root/msg.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2008-03-29 12:14:33 +0100
committerMichael Biebl <biebl@debian.org>2008-03-29 12:14:33 +0100
commitdb2b679ef6aa0ac3d4679ad3e00a72993204ea78 (patch)
tree0f95fbe227c3276e051ac79a921045c533b06dda /msg.c
parent2bff2e5d72345617f3b3e394ff28823067024f7a (diff)
downloadrsyslog-db2b679ef6aa0ac3d4679ad3e00a72993204ea78.tar.gz
Imported Upstream version 1.19.7upstream/1.19.7
Diffstat (limited to 'msg.c')
-rw-r--r--msg.c416
1 files changed, 269 insertions, 147 deletions
diff --git a/msg.c b/msg.c
index be3c48a..632ef9b 100644
--- a/msg.c
+++ b/msg.c
@@ -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) {