From 8dc836cf04eaf061fb4ee31bcc771e2297f7630b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 19 Oct 2005 11:33:57 +0000 Subject: fixing a bug with the "startswith" comparison mode; more work on BSD-style host blocks --- NEWS | 2 ++ stringbuf.c | 38 +++++++++++++++++++++++++++++++++++--- stringbuf.h | 1 + syslogd.c | 40 +++++++++++++++++++++++++++++++--------- 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 74d5815d..693f42d2 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ Version 1.11.1 (RGer), 2005-10-13 - fixed a potential memory leak in the string buffer class destructor. As the destructur was previously never called, the leak did not actually appear. +- fixed a bug that rendered the "startswith" comparison operation to be + unusable. --------------------------------------------------------------------------- Version 1.11.0 (RGer), 2005-10-12 - support for receiving messages via RFC 3195; added rfc3195d for that diff --git a/stringbuf.c b/stringbuf.c index fb9a9f46..ea008e77 100755 --- a/stringbuf.c +++ b/stringbuf.c @@ -440,13 +440,47 @@ int rsCStrCStrCmp(rsCStrObj *pCS1, rsCStrObj *pCS2) } -/* check if a CStr object starts with a sz-type string. This function +/* check if a sz-type string start with a CStr object. This function * is initially written to support the "startswith" property-filter * comparison operation. Maybe it also has other needs. + * rgerhards 2005-10-19 + */ +int rsCStrSzStrStartsWithCStr(rsCStrObj *pCS1, char *psz, int iLenSz) +{ + register int i; + int iMax; + + rsCHECKVALIDOBJECT(pCS1, OIDrsCStr); + assert(psz != NULL); + assert(iLenSz == strlen(psz)); /* just make sure during debugging! */ + if(iLenSz >= pCS1->iStrLen) { + /* we need to checkusing pCS1->iStrLen charactes at maximum, thus + * we move it to iMax. + */ + iMax = pCS1->iStrLen; + if(iMax == 0) + return 0; /* yes, it starts with a zero-sized string ;) */ + else { /* we now have something to compare, so let's do it... */ + for(i = 0 ; i < iMax ; ++i) { + if(psz[i] != pCS1->pBuf[i]) + return psz[i] - pCS1->pBuf[i]; + } + /* if we arrive here, the string actually starts with pCS1 */ + return 0; + } + } + else + return -1; /* pCS1 is less then psz */ +} + + +/* check if a CStr object starts with a sz-type string. * rgerhards 2005-09-26 */ int rsCStrStartsWithSzStr(rsCStrObj *pCS1, char *psz, int iLenSz) { + register int i; + rsCHECKVALIDOBJECT(pCS1, OIDrsCStr); assert(psz != NULL); assert(iLenSz == strlen(psz)); /* just make sure during debugging! */ @@ -457,7 +491,6 @@ int rsCStrStartsWithSzStr(rsCStrObj *pCS1, char *psz, int iLenSz) if(iLenSz == 0) return 0; /* yes, it starts with a zero-sized string ;) */ else { /* we now have something to compare, so let's do it... */ - register int i; for(i = 0 ; i < iLenSz ; ++i) { if(pCS1->pBuf[i] != psz[i]) return pCS1->pBuf[i] - psz[i]; @@ -540,7 +573,6 @@ int rsCStrSzStrCmp(rsCStrObj *pCS1, char *psz, int iLenSz) { rsCHECKVALIDOBJECT(pCS1, OIDrsCStr); assert(psz != NULL); -printf("strlen('%s'): %d, given %d\n", psz, strlen(psz), iLenSz); assert(iLenSz == strlen(psz)); /* just make sure during debugging! */ if(pCS1->iStrLen == iLenSz) /* we are using iLenSz below, because the lengths diff --git a/stringbuf.h b/stringbuf.h index c4e6492d..3b039358 100755 --- a/stringbuf.h +++ b/stringbuf.h @@ -110,6 +110,7 @@ int rsCStrOffsetSzStrCmp(rsCStrObj *pCS1, int iOffset, char *psz, int iLenSz); int rsCStrLocateSzStr(rsCStrObj *pCStr, char *sz); int rsCStrLocateInSzStr(rsCStrObj *pThis, char *sz); int rsCStrStartsWithSzStr(rsCStrObj *pCS1, char *psz, int iLenSz); +int rsCStrSzStrStartsWithCStr(rsCStrObj *pCS1, char *psz, int iLenSz); /* now come inline-like functions */ #ifdef NDEBUG diff --git a/syslogd.c b/syslogd.c index 76b4891f..38f94013 100644 --- a/syslogd.c +++ b/syslogd.c @@ -413,10 +413,6 @@ struct msg { * sockets. All in all, the parser would need parse templates, that would * resolve all these issues... rgerhards, 2005-10-06 */ -#define SOURCE_INTERNAL 0 -#define SOURCE_STDIN 1 -#define SOURCE_UNIXAF 2 -#define SOURCE_INET 3 short iSeverity; /* the severity 0..7 */ char *pszSeverity; /* severity as string... */ int iLenSeverity; /* ... and its length. */ @@ -440,6 +436,7 @@ struct msg { int iLenHOSTNAME; /* Length of HOSTNAME */ char *pszRcvFrom; /* System message was received from */ int iLenRcvFrom; /* Length of pszRcvFrom */ + rsCStrObj *pCSProgName; /* the (BSD) program name */ struct syslogTime tRcvdAt;/* time the message entered this program */ char *pszRcvdAt3164; /* time as RFC3164 formatted string (always 15 charcters) */ char *pszRcvdAt3339; /* time as RFC3164 formatted string (32 charcters at most) */ @@ -1199,7 +1196,7 @@ static void TCPSessDataRcvd(int iTCPSess, char *pData, int iLen) * we are at end of message or not... */ *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ - printline(TCPSessions[iTCPSess].fromHost, pMsg, SOURCE_INET); + printline(TCPSessions[iTCPSess].fromHost, pMsg, 1); iMsg = 0; } if(*pData == '\0') { /* guard against \0 characters... */ @@ -1208,7 +1205,7 @@ static void TCPSessDataRcvd(int iTCPSess, char *pData, int iLen) ++pData; } else if(*pData == '\n') { /* record delemiter */ *(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */ - printline(TCPSessions[iTCPSess].fromHost, pMsg, SOURCE_INET); + printline(TCPSessions[iTCPSess].fromHost, pMsg, 1); iMsg = 0; ++pData; } else { @@ -2121,6 +2118,31 @@ static char *getRcvFrom(struct msg *pM) } +/* get the "programname". Programname is a BSD concept, it is the tag + * without any instance-specific information. Precisely, the programname + * is terminated by either (whichever occurs first): + * - end of tag + * - nonprintable character + * - ':' + * - '[' + * - '/' + * The above definition has been taken from the FreeBSD syslogd sources. + * + * The program name is not parsed by default, because it is infrequently-used. + * Thus, this function first checks if it already exists. If not, it is generated + * before being returned. A message must be provided, else a crash will occur. + * rgerhards, 2005-10-19 + */ +static char *getProgramName(struct msg *pM) +{ + assert(pM != NULL); + if(pM->pCSProgName == NULL) { + } else { + return pM->pszHOSTNAME; + } +} + + /* rgerhards 2004-11-16: set pszRcvFrom in msg object * returns 0 if OK, other value if not. In case of failure, * logs error message and destroys msg object. @@ -3631,7 +3653,7 @@ int shouldProcessThisMessage(struct filed *f, struct msg *pMsg) iRet = 1; /* process message! */ break; case FIOP_STARTSWITH: - if(rsCStrStartsWithSzStr(f->f_filterData.prop.pCSCompValue, + if(rsCStrSzStrStartsWithCStr(f->f_filterData.prop.pCSCompValue, pszPropVal, strlen(pszPropVal)) == 0) iRet = 1; /* process message! */ break; @@ -5973,7 +5995,7 @@ static rsRetVal cflineProcessHostSelector(char **pline, register struct filed *f assert(**pline == '-' || **pline == '+'); assert(f != NULL); - dprintf(" - host selector line (aka program selector)\n"); + dprintf(" - host selector line\n"); /* check include/exclude setting */ if(**pline == '+') { @@ -6026,7 +6048,7 @@ static rsRetVal cflineProcessTagSelector(char **pline, register struct filed *f) assert(**pline == '!'); assert(f != NULL); - dprintf(" - TAG selector line (aka program selector)\n"); + dprintf(" - programname selector line\n"); (*pline)++; /* eat '!' */ -- cgit