summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2005-09-19 10:29:24 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2005-09-19 10:29:24 +0000
commit3e8ba29e5cf041b9056b7a14f0000a9c1557fed0 (patch)
tree656ff16e27b6d43408daea9052819385b32b19aa
parente34ca1e7d952906fd2593850e3be47252211649c (diff)
downloadrsyslog-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.make2
-rw-r--r--parse.c133
-rw-r--r--parse.h3
-rw-r--r--rsyslog.h6
-rwxr-xr-xstringbuf.c139
-rwxr-xr-xstringbuf.h4
-rw-r--r--syslogd.c217
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
diff --git a/parse.c b/parse.c
index bcf0895b..4fb0a66b 100644
--- a/parse.c
+++ b/parse.c
@@ -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
diff --git a/parse.h b/parse.h
index 201c1a64..f5207d42 100644
--- a/parse.h
+++ b/parse.h
@@ -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
diff --git a/rsyslog.h b/rsyslog.h
index 95138e79..ccd5db89 100644
--- a/rsyslog.h
+++ b/rsyslog.h
@@ -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
diff --git a/syslogd.c b/syslogd.c
index 0fca256d..01ba77ee 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -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;
}