From a1b8bbd8a22702232d4fe23ea7cf7d93bcea1daa Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 13 Sep 2005 13:57:28 +0000 Subject: merged Andres Riancho's regex extensions into the code (hopefully correctly) --- AUTHORS | 2 +- linux/Makefile | 3 ++ syslogd.c | 63 +++++++++++++++++++++++++++++++++--- template.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++--------- template.h | 10 ++++++ 5 files changed, 157 insertions(+), 21 deletions(-) diff --git a/AUTHORS b/AUTHORS index dfe1f9a3..3ebca99a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2,6 +2,6 @@ Rainer Gerhards , Adiscon GmbH Michael Meckelein , Adiscon GmbH Contributors -Andres Riancho +Andres Riancho (alias APR in code files) - supplied regexp functionality for the property replacer - a great feature. thanks! diff --git a/linux/Makefile b/linux/Makefile index e7a23fda..d93fe933 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -27,6 +27,9 @@ FEATURE_LARGEFILE=1 # on when support for MySQL is desired). FEATURE_DB=0 +# Enable regular expressions +FEATURE_REGEXP=0 + ############################################################# # END OF USER SETTINGS # # -------------------- # diff --git a/syslogd.c b/syslogd.c index a5f890c9..f9163372 100644 --- a/syslogd.c +++ b/syslogd.c @@ -897,7 +897,6 @@ void TCPSessDataRcvd(int iTCPSess, char *pData, int iLen) pEnd = pData + iLen; /* this is one off, which is intensional */ while(pData < pEnd) { -printf("## in loop\n"); if(iMsg >= MAXLINE) { /* emergency, we now need to flush, no matter if * we are at end of message or not... @@ -915,7 +914,6 @@ printf("## in loop\n"); printline(TCPSessions[iTCPSess].fromHost, pMsg, SOURCE_INET); iMsg = 0; ++pData; -printf("## record delim found\n"); } else { *(pMsg + iMsg++) = *pData++; } @@ -2004,11 +2002,19 @@ int MsgSetRawMsg(struct msg *pMsg, char* pszRawMsg) * a memory leak of a program abort (do to double-frees or frees on * the constant memory pool). So be careful to do it right. * rgerhards 2004-11-23 + * regular expression support contributed by Andres Riancho merged + * on 2005-09-13 */ char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe, unsigned short *pbMustBeFreed) { char *pName; char *pRes; /* result pointer */ + +#ifdef FEATURE_REGEXP + /* Variables necessary for regular expression matching */ + size_t nmatch = 2; + regmatch_t pmatch[2]; +#endif assert(pMsg != NULL); assert(pTpe != NULL); @@ -2095,6 +2101,55 @@ char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe, unsigned short *p 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**"; + + dprintf + ("debug: String to match for regex is: %s\n", + pRes); + + if (0 != + regexec(&pTpe->data.field.re, pRes, nmatch, + pmatch, 0)) { + /* we got no match! */ + return "**NO MATCH**"; + } else { + /* Match! */ + /* I need to malloc pBuf */ + int iLen; + char *pBuf; + + iLen = pmatch[1].rm_eo - pmatch[1].rm_so; + pBuf = (char *) malloc((iLen + 1) * sizeof(char)); + + if (pBuf == NULL) { + if (*pbMustBeFreed == 1) + free(pRes); + *pbMustBeFreed = 0; + return + "**OUT OF MEMORY ALLOCATING pBuf**"; + } + *pBuf = '\0'; + + /* Lets copy the matched substring to the buffer */ + /* TODO: RGer: I think we can use memcpy() here, too (faster) */ + strncpy(pBuf, pRes + pmatch[1].rm_so, + iLen); + pBuf[iLen] = '\0'; /* Null termination of string */ + + if (*pbMustBeFreed == 1) + free(pRes); + pRes = pBuf; + *pbMustBeFreed = 1; + } + } +#endif /* #ifdef FEATURE_REGEXP */ } /* case conversations (should go after substring, because so we are able to @@ -3781,9 +3836,7 @@ void fprintlog(f, flags) * some code to do it, but that code is defunct due to our changes! */ if (msg) { - /*v->iov_base = msg; - v->iov_len = strlen(msg); - */v->iov_base = f->f_pMsg->pszRawMsg; + v->iov_base = f->f_pMsg->pszRawMsg; v->iov_len = f->f_pMsg->iLenRawMsg; } else if (f->f_prevcount > 1) { (void) snprintf(repbuf, sizeof(repbuf), "last message repeated %d times", diff --git a/template.c b/template.c index 8c798600..b8d70304 100644 --- a/template.c +++ b/template.c @@ -33,15 +33,13 @@ struct templateEntry* tpeConstruct(struct template *pTpl) if((pTpe = calloc(1, sizeof(struct templateEntry))) == NULL) return NULL; - /* basic initialisaion is done via calloc() - need to + /* basic initialization is done via calloc() - need to * initialize only values != 0. */ - if(pTpl->pEntryLast == NULL) - { /* we are the first element! */ + if(pTpl->pEntryLast == NULL){ + /* we are the first element! */ pTpl->pEntryRoot = pTpl->pEntryLast = pTpe; - } - else - { + } else { pTpl->pEntryLast->pNext = pTpe; pTpl->pEntryLast = pTpe; } @@ -60,15 +58,13 @@ struct template* tplConstruct(void) if((pTpl = calloc(1, sizeof(struct template))) == NULL) return NULL; - /* basic initialisaion is done via calloc() - need to + /* basic initialisation is done via calloc() - need to * initialize only values != 0. */ - if(tplLast == NULL) - { /* we are the first element! */ + if(tplLast == NULL) { + /* we are the first element! */ tplRoot = tplLast = pTpl; - } - else - { + } else { tplLast->pNext = pTpl; tplLast = pTpl; } @@ -238,6 +234,13 @@ static int do_Parameter(char **pp, struct template *pTpl) struct templateEntry *pTpe; int iNum; /* to compute numbers */ +#ifdef FEATURE_REGEXP + /* APR: variables for regex */ + int longitud; + char *regex_char; + char *regex_end; +#endif + assert(pp != NULL); assert(*pp != NULL); assert(pTpl != NULL); @@ -262,9 +265,27 @@ static int do_Parameter(char **pp, struct template *pTpl) rsCStrFinish(pStrB); pTpe->data.field.pPropRepl = rsCStrConvSzStrAndDestruct(pStrB); - /* check frompos */ + /* Check frompos, if it has an R, then topos should be a regex */ if(*p == ':') { ++p; /* eat ':' */ +#ifdef FEATURE_REGEXP + if (*p == 'R') { + /* APR: R found! regex alarm ! :) */ + ++p; /* eat ':' */ + + if (*p != ':') { + /* There is something more than an R , this is invalid ! */ + /* Complain on extra characters */ + dprintf + ("error: extra character in frompos, only \"R\" and numbers are allowed: '%s'\n", + p); + /* TODO: rger- add/change to logerror? */ + } else { + pTpe->data.field.has_regex = 1; + } + } else { + /* now we fall through the "regular" FromPos code */ +#endif /* #ifdef FEATURE_REGEXP */ iNum = 0; while(isdigit(*p)) iNum = iNum * 10 + *p++ - '0'; @@ -276,10 +297,59 @@ static int do_Parameter(char **pp, struct template *pTpl) ++p; } } - - /* check topos */ + /* check topos (holds an regex if FromPos is "R"*/ if(*p == ':') { ++p; /* eat ':' */ + +#ifdef FEATURE_REGEXP + if (pTpe->data.field.has_regex) { + + dprintf("debug: has regex \n"); + + /* APR 2005-09 I need the string that represent the regex */ + /* The regex end is: "--end" */ + /* TODO : this is hardcoded and cant be escaped, please change */ + regex_end = strstr(p, "--end"); + if (regex_end == NULL) { + dprintf("error: Cant find regex end in: '%s'\n", p); + pTpe->data.field.has_regex = 0; + } else { + /* We get here ONLY if the regex end was found */ + longitud = regex_end - p; + /* Malloc for the regex string */ + regex_char = (char *) malloc(longitud + 1); + if (regex_char == NULL) { + dprintf + ("Could not allocate memory for template parameter!\n"); + pTpe->data.field.has_regex = 0; + return 1; + /* TODO: RGer: check if we can recover better... (probably not) */ + } + + regex_char[0] = '\0'; + + /* Get the regex string for compiling later */ + strncpy(regex_char, p, longitud); + + dprintf("debug: regex detected: '%s'\n", + regex_char); + + /* Now i compile the regex */ + /* Remember that the re is an attribute of the Template entry */ + if (regcomp(&(pTpe->data.field.re), regex_char, 0) != 0) { + dprintf("error: Cant compile regex: '%s'\n", regex_char); + pTpe->data.field.has_regex = 2; + } + + /* Finally we move the pointer to the end of the regex so it aint parsed twice or something weird */ + p = regex_end + 5/*strlen("--end")*/; + free(regex_char); + } + } else { + /* fallthrough to "regular" ToPos code */ + +#endif /* #ifdef FEATURE_REGEXP */ + iNum = 0; while(isdigit(*p)) iNum = iNum * 10 + *p++ - '0'; diff --git a/template.h b/template.h index ff714ae4..6e16f25a 100644 --- a/template.h +++ b/template.h @@ -3,6 +3,12 @@ * This code is placed under the GPL. * begun 2004-11-17 rgerhards */ + +#ifdef FEATURE_REGEXP +/* Include regular expressions */ +#include +#endif + struct template { struct template *pNext; char *pszName; @@ -35,6 +41,10 @@ struct templateEntry { char *pPropRepl; /* pointer to property replacer string */ unsigned iFromPos; /* for partial strings only chars from this position ... */ unsigned iToPos; /* up to that one... */ +#ifdef FEATURE_REGEXP + regex_t re; /* APR: this is the regular expression */ + unsigned has_regex; +#endif enum tplFormatTypes eDateFormat; enum tplFormatCaseConvTypes eCaseConv; struct { /* bit fields! */ -- cgit v1.2.3