diff options
-rw-r--r-- | AUTHORS | 2 | ||||
-rw-r--r-- | linux/Makefile | 3 | ||||
-rw-r--r-- | syslogd.c | 63 | ||||
-rw-r--r-- | template.c | 100 | ||||
-rw-r--r-- | template.h | 10 |
5 files changed, 157 insertions, 21 deletions
@@ -2,6 +2,6 @@ Rainer Gerhards <rgerhards@adiscon.com>, Adiscon GmbH Michael Meckelein <mmeckelein@hq.adiscon.com>, 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 # # -------------------- # @@ -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", @@ -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'; @@ -3,6 +3,12 @@ * This code is placed under the GPL. * begun 2004-11-17 rgerhards */ + +#ifdef FEATURE_REGEXP
+/* Include regular expressions */
+#include <regex.h> +#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! */ |