diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2005-09-19 10:29:24 +0000 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2005-09-19 10:29:24 +0000 |
commit | 3e8ba29e5cf041b9056b7a14f0000a9c1557fed0 (patch) | |
tree | 656ff16e27b6d43408daea9052819385b32b19aa | |
parent | e34ca1e7d952906fd2593850e3be47252211649c (diff) | |
download | rsyslog-3e8ba29e5cf041b9056b7a14f0000a9c1557fed0.tar.gz rsyslog-3e8ba29e5cf041b9056b7a14f0000a9c1557fed0.tar.xz rsyslog-3e8ba29e5cf041b9056b7a14f0000a9c1557fed0.zip |
added parsing of property-filter (but not complete property selector line
yet)
-rw-r--r-- | master.make | 2 | ||||
-rw-r--r-- | parse.c | 133 | ||||
-rw-r--r-- | parse.h | 3 | ||||
-rw-r--r-- | rsyslog.h | 6 | ||||
-rwxr-xr-x | stringbuf.c | 139 | ||||
-rwxr-xr-x | stringbuf.h | 4 | ||||
-rw-r--r-- | syslogd.c | 217 |
7 files changed, 435 insertions, 69 deletions
diff --git a/master.make b/master.make index 6b42d26c..f8f2b55f 100644 --- a/master.make +++ b/master.make @@ -42,7 +42,7 @@ test: syslog_tst tsyslogd install: install_man install_exec syslogd: syslogd.o pidfile.o template.o stringbuf.o srUtils.o outchannel.o parse.o - ${CC} ${LDFLAGS} -o syslogd syslogd.o pidfile.o template.o outchannel.o stringbuf.o srUtils.o ${LIBS} + ${CC} ${LDFLAGS} -o syslogd syslogd.o pidfile.o template.o outchannel.o stringbuf.o srUtils.o parse.o ${LIBS} srUtils.o: srUtils.c srUtils.h liblogging-stub.h rsyslog.h stringbuf.o: stringbuf.c stringbuf.h rsyslog.h @@ -7,6 +7,7 @@ * Rainer Gerhards and Adiscon GmbH. All Rights Reserved. * This code is placed under the GPL. */ +#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <ctype.h> @@ -65,6 +66,43 @@ rsRetVal parsInt(rsParsObj *pThis, int* pInt) return RS_RET_OK; } +/* Skip everything up to a specified character. + * Returns with ParsePointer set BEHIND this character. + * Returns RS_RET_OK if found, RS_RET_NOT_FOUND if not + * found. In that case, the ParsePointer is moved to the + * last character of the string. + * 2005-09-19 rgerhards + */ +rsRetVal parsSkipAfterChar(rsParsObj *pThis, char c) +{ + register char *pC; + rsRetVal iRet; + + rsCHECKVALIDOBJECT(pThis, OIDrsPars); + + pC = rsCStrGetBufBeg(pThis->pCStr); + + while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)) { + if(pC[pThis->iCurrPos] == c) + break; + ++pThis->iCurrPos; + } + + /* delimiter found? */ + if(pC[pThis->iCurrPos] == c) { + if(pThis->iCurrPos+1 < rsCStrLen(pThis->pCStr)) { + iRet = RS_RET_OK; + pThis->iCurrPos++; /* 'eat' delimiter */ + } else { + iRet = RS_RET_FOUND_AT_STRING_END; + } + } else { + iRet = RS_RET_NOT_FOUND; + } + + return iRet; +} + /* Skip whitespace. Often used to trim parsable entries. * Returns with ParsePointer set to first non-whitespace * character (or at end of string). @@ -77,7 +115,7 @@ rsRetVal parsSkipWhitespace(rsParsObj *pThis) pC = rsCStrGetBufBeg(pThis->pCStr); - while(pThis->iCurrPos >= rsCStrLen(pThis->pCStr)) { + while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)) { if(!isspace(*(pC+pThis->iCurrPos))) break; ++pThis->iCurrPos; @@ -109,20 +147,28 @@ rsRetVal parsDelimCStr(rsParsObj *pThis, rsCStrObj **ppCStr, char cDelim, int bT if((pCStr = rsCStrConstruct()) == NULL) return RS_RET_OUT_OF_MEMORY; - pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos; - if(bTrimLeading) parsSkipWhitespace(pThis); - while(pThis->iCurrPos >= rsCStrLen(pThis->pCStr) + pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos; + +printf("after trim leading, len %d - %d, pC: %c, Delim '%c'\n", pThis->iCurrPos, rsCStrLen(pThis->pCStr), + *pC, cDelim); + while(pThis->iCurrPos < rsCStrLen(pThis->pCStr) && *pC != cDelim) { + printf("parse[%d,%d]: %c\n", pThis->iCurrPos, rsCStrLen(pThis->pCStr), *pC); if((iRet = rsCStrAppendChar(pCStr, *pC)) != RS_RET_OK) { RSFREEOBJ(pCStr); return(iRet); } ++pThis->iCurrPos; + ++pC; } + if(*pC == cDelim) { + ++pThis->iCurrPos; /* eat delimiter */ + } + /* We got the string, now take it and see if we need to * remove anything at its end. */ @@ -144,6 +190,85 @@ rsRetVal parsDelimCStr(rsParsObj *pThis, rsCStrObj **ppCStr, char cDelim, int bT return RS_RET_OK; } +/* Parse a quoted string ("-some-data") from the given position. + * Leading whitespace before the first quote is skipped. During + * parsing, escape sequences are detected and converted: + * \\ - backslash character + * \" - quote character + * any other value \<somechar> is reserved for future use. + * + * After return, the parse pointer is paced after the trailing + * quote. + * + * Output: + * ppCStr Pointer to the parsed string - must be freed by caller and + * does NOT include the quotes. + * rgerhards, 2005-09-19 + */ +rsRetVal parsQuotedCStr(rsParsObj *pThis, rsCStrObj **ppCStr) +{ + register char *pC; + rsCStrObj *pCStr; + rsRetVal iRet; + + rsCHECKVALIDOBJECT(pThis, OIDrsPars); + + if((iRet = parsSkipAfterChar(pThis, '"')) != RS_RET_OK) + return iRet; + pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos; + + /* OK, we most probably can obtain a value... */ + if((pCStr = rsCStrConstruct()) == NULL) + return RS_RET_OUT_OF_MEMORY; + +printf("at start of quoted string, len %d - %d, pC: '%c'\n", pThis->iCurrPos, rsCStrLen(pThis->pCStr), + *pC); + while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)) { + printf("parse[%d,%d]: '%c'\n", pThis->iCurrPos, rsCStrLen(pThis->pCStr), *pC); + if(*pC == '"') { + break; /* we are done! */ + } else if(*pC == '\\') { + ++pThis->iCurrPos; + ++pC; + if(pThis->iCurrPos < rsCStrLen(pThis->pCStr)) { + /* in this case, we copy the escaped character + * to the output buffer (but do not rely on this, + * we might later introduce other things, like \007! + */ + if((iRet = rsCStrAppendChar(pCStr, *pC)) != RS_RET_OK) { + RSFREEOBJ(pCStr); + return(iRet); + } + } + } else { /* regular character */ + if((iRet = rsCStrAppendChar(pCStr, *pC)) != RS_RET_OK) { + RSFREEOBJ(pCStr); + return(iRet); + } + } + ++pThis->iCurrPos; + ++pC; + } + + if(*pC == '"') { + ++pThis->iCurrPos; /* 'eat' trailing quote */ + } else { + /* error - improperly quoted string! */ + RSFREEOBJ(pCStr); + return RS_RET_MISSING_TRAIL_QUOTE; + } + + /* We got the string, let's finish it... */ + if((iRet = rsCStrFinish(pCStr)) != RS_RET_OK) { + RSFREEOBJ(pCStr); + return(iRet); + } + + /* done! */ + *ppCStr = pCStr; + return RS_RET_OK; +} + /* * Local variables: * c-indent-level: 8 @@ -46,6 +46,7 @@ typedef struct rsParsObject rsParsObj; * Construct a rsPars object. */ rsRetVal rsParsConstruct(rsParsObj **ppThis); +rsRetVal rsParsAssignString(rsParsObj *pThis, rsCStrObj *pCStr); /* parse an integer. The parse pointer is advanced */ rsRetVal parsInt(rsParsObj *pThis, int* pInt); @@ -67,6 +68,8 @@ rsRetVal parsSkipWhitespace(rsParsObj *pThis); */ rsRetVal parsDelimCStr(rsParsObj *pThis, rsCStrObj **ppCStr, char cDelim, int bTrimLeading, int bTrimTrailing); +rsRetVal parsSkipAfterChar(rsParsObj *pThis, char c); +rsRetVal parsQuotedCStr(rsParsObj *pThis, rsCStrObj **ppCStr); #if 0 /* later! */ /* Parse a property * This is a complex parsing routine. It parses an property @@ -31,7 +31,11 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth { RS_RET_OUT_OF_MEMORY = -6, /**< memory allocation failed */ RS_RET_PROVIDED_BUFFER_TOO_SMALL = -50,/**< the caller provided a buffer, but the called function sees the size of this buffer is too small - operation not carried out */ - RS_TRUNCAT_TOO_LARGE = -3000, /**< truncation operation where too many chars should be truncated */ + RS_RET_ERR = -3000, /**< generic failure */ + RS_TRUNCAT_TOO_LARGE = -3001, /**< truncation operation where too many chars should be truncated */ + RS_RET_FOUND_AT_STRING_END = -3002, /**< some value found, but at the last pos of string */ + RS_RET_NOT_FOUND = -3003, /**< some requested value not found */ + RS_RET_MISSING_TRAIL_QUOTE = -3004, /**< an expected trailing quote is missing */ RS_RET_OK = 0 /**< operation successful */ }; typedef enum rsRetVal_ rsRetVal; /**< friendly type for global return value */ diff --git a/stringbuf.c b/stringbuf.c index aa35a6c7..ccd2c184 100755 --- a/stringbuf.c +++ b/stringbuf.c @@ -38,7 +38,6 @@ rsCStrObj *rsCStrConstruct(void) pThis->pBuf = NULL; pThis->pszBuf = NULL; pThis->iBufSize = 0; - pThis->iBufPtr = 0; pThis->iStrLen = 0; pThis->iAllocIncrement = STRINGBUF_ALLOC_INCREMENT; @@ -125,7 +124,7 @@ rsRetVal rsCStrAppendChar(rsCStrObj *pThis, char c) rsCHECKVALIDOBJECT(pThis, OIDrsCStr); - if(pThis->iBufPtr >= pThis->iBufSize) + if(pThis->iStrLen >= pThis->iBufSize) { /* need more memory! */ if((pNewBuf = (char*) malloc((pThis->iBufSize + pThis->iAllocIncrement) * sizeof(char))) == NULL) return RS_RET_OUT_OF_MEMORY; @@ -138,13 +137,59 @@ rsRetVal rsCStrAppendChar(rsCStrObj *pThis, char c) } /* ok, when we reach this, we have sufficient memory */ - *(pThis->pBuf + pThis->iBufPtr++) = c; - pThis->iStrLen++; + *(pThis->pBuf + pThis->iStrLen++) = c; + + /* check if we need to invalidate an sz representation! */ + if(pThis->pszBuf != NULL) { + free(pThis->pszBuf); + pThis->pszBuf = NULL; + } return RS_RET_OK; } +/* Converts the CStr object to a classical zero-terminated C string + * and returns that string. The caller must not free it and must not + * destroy the CStr object as long as the ascii string is used. + * rgerhards, 2005-09-15 + */ +char* rsCStrGetSzStr(rsCStrObj *pThis) +{ + int i; + + rsCHECKVALIDOBJECT(pThis, OIDrsCStr); + + if(pThis->pBuf != NULL) + if(pThis->pszBuf == NULL) { + /* we do not yet have a usable sz version - so create it... */ + if((pThis->pszBuf = malloc(pThis->iStrLen + 1 * sizeof(char))) == NULL) { + /* TODO: think about what to do - so far, I have no bright + * idea... rgerhards 2005-09-07 + */ + } + else { /* we can create the sz String */ + /* now copy it while doing a sanity check. The string might contain a + * \0 byte. There is no way how a sz string can handle this. For + * the time being, we simply replace it with space - something that + * could definitely be improved (TODO). + * 2005-09-15 rgerhards + */ + for(i = 0 ; i < pThis->iStrLen ; ++i) { + if(pThis->pBuf[i] == '\0') + pThis->pszBuf[i] = ' '; + else + pThis->pszBuf[i] = pThis->pBuf[i]; + } + /* write terminator... */ + pThis->pszBuf[i] = '\0'; + } + } + + return(pThis->pszBuf); +} + + /* Converts the CStr object to a classical zero-terminated C string, * returns that string and destroys the CStr object. The returned string * MUST be freed by the caller. The function might return NULL if @@ -162,40 +207,15 @@ rsRetVal rsCStrAppendChar(rsCStrObj *pThis, char c) char* rsCStrConvSzStrAndDestruct(rsCStrObj *pThis) { char* pRetBuf; - int i; rsCHECKVALIDOBJECT(pThis, OIDrsCStr); - if(pThis->pszBuf == NULL) { - /* we do not yet have a usable sz version - so create it... */ - if((pThis->pszBuf = malloc(pThis->iStrLen + 1 * sizeof(char))) == NULL) { - /* TODO: think about what to do - so far, I have no bright - * idea... rgerhards 2005-09-07 - */ - } - else { - /* we can create the sz String */ - if(pThis->pBuf != NULL) - memcpy(pThis->pszBuf, pThis->pBuf, pThis->iStrLen); - *(pThis->pszBuf + pThis->iStrLen) = '\0'; - } - } - /* we now need to do a sanity check. The string mgiht contain a - * \0 byte. There is no way how a sz string can handle this. For - * the time being, we simply replace it with space - something that - * could definitely be improved (TODO). - * 2005-09-09 rgerhards - */ - for(i = 0 ; i < pThis->iStrLen ; ++i) { - if(*(pThis->pszBuf + i) == '\0') - *(pThis->pszBuf + i) = ' '; - } + pRetBuf = rsCStrGetSzStr(pThis); /* We got it, now free the object ourselfs. Please note * that we can NOT use the rsCStrDestruct function as it would * also free the sz String buffer, which we pass on to the user. */ - pRetBuf = pThis->pszBuf; if(pThis->pBuf != NULL) free(pThis->pBuf); RSFREEOBJ(pThis); @@ -229,7 +249,6 @@ rsRetVal rsCStrFinish(rsCStrObj *pThis) /* here, we need to do ... nothing ;) */ # endif - return RS_RET_OK; } @@ -268,6 +287,15 @@ rsRetVal rsCStrTruncate(rsCStrObj *pThis, int nTrunc) pThis->iStrLen -= nTrunc; + if(pThis->pszBuf != NULL) { + /* in this case, we adjust the psz representation + * by writing a new \0 terminator - this is by far + * the fastest way and outweights the additional memory + * required. 2005-9-19 rgerhards. + */ + pThis->pszBuf[pThis->iStrLen] = '\0'; + } + return RS_RET_OK; } @@ -281,7 +309,7 @@ rsRetVal rsCStrTrimTrailingWhiteSpace(rsCStrObj *pThis) i = pThis->iStrLen; pC = pThis->pBuf + i - 1; - while(i > 0 && !isspace(*pC)) { + while(i > 0 && isspace(*pC)) { --pC; --i; } @@ -291,6 +319,53 @@ rsRetVal rsCStrTrimTrailingWhiteSpace(rsCStrObj *pThis) return RS_RET_OK; } +/* compare two string objects - works like strcmp(), but operates + * on CStr objects. Please note that this version here is + * faster in the majority of cases, simply because it can + * rely on StrLen. + * rgerhards 2005-09-19 + */ +int rsCStrCStrCmp(rsCStrObj *pCS1, rsCStrObj *pCS2) +{ + rsCHECKVALIDOBJECT(pCS1, OIDrsCStr); + rsCHECKVALIDOBJECT(pCS2, OIDrsCStr); + if(pCS1->iStrLen == pCS2->iStrLen) + if(pCS1->iStrLen == 0) + return 0; /* zero-sized string are equal ;) */ + else + return pCS1->pBuf[pCS1->iStrLen - 1] + - pCS2->pBuf[pCS2->iStrLen - 1]; + else + return pCS1->iStrLen - pCS2->iStrLen; +} + +/* compare a string object with a classical zero-terminated C-string. + * this function is primarily meant to support comparisons with constants. + * It should not be used for variables (except with a very good reason). + * rgerhards 2005-09-19 + */ +int rsCStrSzCmp(rsCStrObj *pCStr, char *sz) +{ + int iszLen; + + rsCHECKVALIDOBJECT(pCStr, OIDrsCStr); + assert(sz != NULL); + + iszLen = strlen(sz); + + if(pCStr->iStrLen == iszLen) + /* note: we are using iszLen below, because it doesn't matter + * and the simple integer is faster to derefence... + */ + if(iszLen == 0) + return 0; /* zero-sized string are equal ;) */ + else + return pCStr->pBuf[iszLen - 1] - sz[iszLen - 1]; + else + return pCStr->iStrLen - iszLen; +} + + /* * Local variables: * c-indent-level: 8 diff --git a/stringbuf.h b/stringbuf.h index 1e2f5515..80eff56d 100755 --- a/stringbuf.h +++ b/stringbuf.h @@ -30,7 +30,6 @@ struct rsCStrObject char *pBuf; /**< pointer to the string buffer, may be NULL if string is empty */
char *pszBuf; /**< pointer to the sz version of the string (after it has been created )*/
int iBufSize; /**< current maximum size of the string buffer */
- int iBufPtr; /**< pointer (index) of next character position to be written to. */
int iStrLen; /**< length of the string in characters. */
int iAllocIncrement; /**< the amount of bytes the string should be expanded if it needs to */
};
@@ -101,7 +100,10 @@ void rsCStrSetAllocIncrement(rsCStrObj *pThis, int iNewIncrement); rsRetVal rsCStrAppendInt(rsCStrObj *pThis, int i);
+char* rsCStrGetSzStr(rsCStrObj *pThis);
char* rsCStrConvSzStrAndDestruct(rsCStrObj *pThis);
+int rsCStrCStrCmp(rsCStrObj *pCS1, rsCStrObj *pCS2);
+int rsCStrSzCmp(rsCStrObj *pCStr, char *sz);
/* now come inline-like functions */
#ifdef NDEBUG
@@ -177,11 +177,13 @@ #include <paths.h> #endif +#include "rsyslog.h" #include "template.h" #include "outchannel.h" #include "syslogd.h" #include "stringbuf.h" +#include "parse.h" #ifdef WITH_DB #define _DB_MAXDBLEN 128 /* maximum number of db */ @@ -433,12 +435,12 @@ struct filed { union { u_char f_pmask[LOG_NFACILITIES+1]; /* priority mask */ struct { - rsCStrObj pCSPropName; + rsCStrObj *pCSPropName; enum { FIOP_NOP = 0, /* do not use - No Operation */ FIOP_CONTAINS = 1, /* contains string? */ } operation; - rsCStrObj pCSCompValue; /* value to "compare" against */ + rsCStrObj *pCSCompValue; /* value to "compare" against */ } prop; } f_filterData; union { @@ -637,12 +639,14 @@ const char *cvthname(struct sockaddr_in *f); void domark(); void debug_switch(); void logerror(char *type); +void logerrorInt(char *type, int errCode); +void logerrorSz(char *type, char *errMsg); void die(int sig); #ifndef TESTING void doexit(int sig); #endif void init(); -void cfline(char *line, register struct filed *f); +rsRetVal cfline(char *line, register struct filed *f); int decode(char *name, struct code *codetab); void sighup_handler(); #ifdef WITH_DB @@ -4283,12 +4287,42 @@ void debug_switch() /* + * Add a string to error message and send it to logerror() + * The error message is passed to snprintf() and must be + * correctly formatted for it (containing a single %s param). + * rgerhards 2005-09-19 + */ +void logerrorSz(char *type, char *errMsg) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), type, errMsg); + logerror(buf); + return; +} + +/* + * Add an integer to error message and send it to logerror() + * The error message is passed to snprintf() and must be + * correctly formatted for it (containing a single %d param). + * rgerhards 2005-09-19 + */ +void logerrorInt(char *type, int errCode) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), type, errCode); + logerror(buf); + return; +} + +/* * Print syslogd errors some place. */ void logerror(type) char *type; { - char buf[256]; + char buf[1024]; dprintf("Called logerr, msg: %s\n", type); @@ -4980,19 +5014,13 @@ void cflineParseOutchannel(struct filed *f, char* p) /* - * Crack a configuration file line - * rgerhards 2004-11-17: well, I somewhat changed this function. It now does NOT - * handle config lines in general, but only lines that reflect actual filter - * pairs (the original syslog message line format). Extended lines (those starting - * with "$" have been filtered out by the caller and are passed to another function (cfsysline()). - * Please note, however, that I needed to make changes in the line syntax to support - * assignment of format definitions to a file. So it is not (yet) 100% transparent. - * Eventually, we can overcome this limitation by prefixing the actual action indicator - * (e.g. "/file..") by something (e.g. "$/file..") - but for now, we just modify it... + * Helper to cfline(). This function takes the filter part of a traditional, PRI + * based line and decodes the PRIs given in the selector line. It processed the + * line up to the beginning of the action part. A pointer to that beginnig is + * passed back to the caller. + * rgerhards 2005-09-15 */ -void cfline(line, f) - char *line; - register struct filed *f; +rsRetVal cflineProcessTradPRIFilter(char **pline, register struct filed *f) { char *p; register char *q; @@ -5001,22 +5029,17 @@ void cfline(line, f) int pri; int singlpri = 0; int ignorepri = 0; - int syncfile; -#ifdef SYSLOG_INET - struct hostent *hp; - int bErr; -#endif char buf[MAXLINE]; - char szTemplateName[128]; char xbuf[200]; -#ifdef WITH_DB - int iMySQLPropErr = 0; -#endif - dprintf("cfline(%s)\n", line); + assert(pline != NULL); + assert(*pline != NULL); + assert(f != NULL); + dprintf(" - traditional PRI filter\n"); errno = 0; /* keep strerror() stuff out of logerror messages */ + f->f_filter_type = FILTER_PRI; /* Note: file structure is pre-initialized to zero because it was * created with calloc()! */ @@ -5026,7 +5049,7 @@ void cfline(line, f) } /* scan through the list of selectors */ - for (p = line; *p && *p != '\t' && *p != ' ';) { + for (p = *pline; *p && *p != '\t' && *p != ' ';) { /* find the end of this facility name list */ for (q = p; *q && *q != '\t' && *q++ != '.'; ) @@ -5064,7 +5087,7 @@ void cfline(line, f) if (pri < 0) { (void) snprintf(xbuf, sizeof(xbuf), "unknown priority name \"%s\"", buf); logerror(xbuf); - return; + return RS_RET_ERR; } /* scan facilities */ @@ -5111,7 +5134,7 @@ void cfline(line, f) (void) snprintf(xbuf, sizeof(xbuf), "unknown facility name \"%s\"", buf); logerror(xbuf); - return; + return RS_RET_ERR; } if ( pri == INTERNAL_NOPRI ) { @@ -5151,6 +5174,140 @@ void cfline(line, f) while (*p == '\t' || *p == ' ') p++; + *pline = p; + return RS_RET_OK; +} + + +/* + * Helper to cfline(). This function takes the filter part of a property + * based filter and decodes it. It processes the line up to the beginning + * of the action part. A pointer to that beginnig is passed back to the caller. + * rgerhards 2005-09-15 + */ +rsRetVal cflineProcessPropFilter(char **pline, register struct filed *f) +{ + rsParsObj *pPars; + rsCStrObj *pCSLine; + rsCStrObj *pCSCompOp; + rsRetVal iRet; + + assert(pline != NULL); + assert(*pline != NULL); + assert(f != NULL); + + dprintf(" - property-based filter\n"); + errno = 0; /* keep strerror() stuff out of logerror messages */ + + f->f_filter_type = FILTER_PROP; + + /* create line string without leading colon */ + if((iRet = rsCStrConstructFromszStr(&pCSLine, (*pline)+1)) != RS_RET_OK) { + logerrorInt("Error %d allocating string space - ignoring selector", iRet); + return(iRet); + } + + /* create parser */ + if((iRet = rsParsConstruct(&pPars)) != RS_RET_OK) { + logerrorInt("error %d creating parser - ignoring selector", iRet); + RSFREEOBJ(pCSLine); + return(iRet); + } + + if((iRet = rsParsAssignString(pPars, pCSLine)) != RS_RET_OK) { + logerrorInt("error %d assigning string to parser - ignoring selector", iRet); + RSFREEOBJ(pPars); + RSFREEOBJ(pCSLine); + return(iRet); + } + + /* read property */ + iRet = parsDelimCStr(pPars, &f->f_filterData.prop.pCSPropName, ',', 1, 1); + if(iRet != RS_RET_OK) { + logerrorInt("error %d parsing filter property - ignoring selector", iRet); + RSFREEOBJ(pPars); + RSFREEOBJ(pCSLine); + return(iRet); + } + printf("after read prop, prop name '%s'\n", rsCStrGetSzStr(f->f_filterData.prop.pCSPropName)); + + /* read operation */ + iRet = parsDelimCStr(pPars, &pCSCompOp, ',', 1, 1); + if(iRet != RS_RET_OK) { + logerrorInt("error %d compare operation property - ignoring selector", iRet); + RSFREEOBJ(pPars); + RSFREEOBJ(pCSLine); + return(iRet); + } + printf("after read CompOp, prop name '%s'\n", rsCStrGetSzStr(pCSCompOp)); + if(!rsCStrSzCmp(pCSCompOp, "contains")) { + f->f_filterData.prop.operation = FIOP_CONTAINS; +dprintf("Contains filter!\n"); + } else { + logerrorSz("error: invalid compare operation '%s' - ignoring selector", + rsCStrGetSzStr(pCSCompOp)); + } + + /* read compare value */ + iRet = parsQuotedCStr(pPars, &f->f_filterData.prop.pCSCompValue); + if(iRet != RS_RET_OK) { + logerrorInt("error %d compare value property - ignoring selector", iRet); + RSFREEOBJ(pPars); + RSFREEOBJ(pCSLine); + return(iRet); + } + printf("after read CompVal, prop name '%s'\n", rsCStrGetSzStr(f->f_filterData.prop.pCSCompValue)); + + /* skip to action part */ + + /**pline = p;*/ + return RS_RET_OK; +} + + +/* + * Crack a configuration file line + * rgerhards 2004-11-17: well, I somewhat changed this function. It now does NOT + * handle config lines in general, but only lines that reflect actual filter + * pairs (the original syslog message line format). Extended lines (those starting + * with "$" have been filtered out by the caller and are passed to another function (cfsysline()). + * Please note, however, that I needed to make changes in the line syntax to support + * assignment of format definitions to a file. So it is not (yet) 100% transparent. + * Eventually, we can overcome this limitation by prefixing the actual action indicator + * (e.g. "/file..") by something (e.g. "$/file..") - but for now, we just modify it... + */ +rsRetVal cfline(char *line, register struct filed *f) +{ + char *p; + register char *q; + register int i; + int syncfile; + rsRetVal iRet; +#ifdef SYSLOG_INET + struct hostent *hp; + int bErr; +#endif + char szTemplateName[128]; +#ifdef WITH_DB + int iMySQLPropErr = 0; +#endif + + dprintf("cfline(%s)", line); + + errno = 0; /* keep strerror() stuff out of logerror messages */ + p = line; + + /* check which filter we need to pull... */ + if(*p == ':') { + iRet = cflineProcessPropFilter(&p, f); + } else { + iRet = cflineProcessTradPRIFilter(&p, f); + } + + /* check if that went well... */ + if(iRet != RS_RET_OK) + return iRet; + if (*p == '-') { syncfile = 0; @@ -5455,7 +5612,7 @@ void cfline(line, f) */ break; } - return; + return RS_RET_OK; } |