summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2011-07-07 16:35:51 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2011-07-07 16:35:51 +0200
commit8a9e0cc68e3314b02065dcd3424201f25f176dfb (patch)
treee354a33f34575afc7eef45981902b8ae8c2fdbb8
parent5710b413963d2fde9d062127ed72672b8a58a07e (diff)
downloadrsyslog-8a9e0cc68e3314b02065dcd3424201f25f176dfb.tar.gz
rsyslog-8a9e0cc68e3314b02065dcd3424201f25f176dfb.tar.xz
rsyslog-8a9e0cc68e3314b02065dcd3424201f25f176dfb.zip
milestone/[PARTWORK]: obtaining msg vars integrated, "==" works for strings
-rw-r--r--configure.ac2
-rw-r--r--grammar/parserif.h1
-rw-r--r--grammar/rainerscript.c68
-rw-r--r--grammar/rainerscript.h4
-rw-r--r--grammar/testdriver.c8
-rw-r--r--runtime/msg.c55
-rw-r--r--runtime/msg.h1
-rw-r--r--runtime/rsconf.c14
-rw-r--r--runtime/rule.c2
9 files changed, 124 insertions, 31 deletions
diff --git a/configure.ac b/configure.ac
index 4f9113bd..5612b1b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,7 +38,7 @@ AC_CANONICAL_HOST
PKG_PROG_PKG_CONFIG
# modules we require
-PKG_CHECK_MODULES(LIBESTR, libestr >= 0.1.0)
+PKG_CHECK_MODULES(LIBESTR, libestr >= 0.1.1)
PKG_CHECK_MODULES(LIBEE, libee >= 0.3.1)
case "${host}" in
diff --git a/grammar/parserif.h b/grammar/parserif.h
index a04abb0c..bebb1dfb 100644
--- a/grammar/parserif.h
+++ b/grammar/parserif.h
@@ -16,4 +16,5 @@ void cnfDoRule(struct cnfrule *rule);
void cnfDoCfsysline(char *ln);
void cnfDoBSDTag(char *ln);
void cnfDoBSDHost(char *ln);
+es_str_t *cnfGetVar(char *name, void *usrptr);
#endif
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index 801a52b2..ea23dc1a 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -291,8 +291,9 @@ done:
static inline long long
exprret2Number(struct exprret *r)
{
+ long long n;
if(r->datatype == 'S') {
- dbgprintf("toNumber CONVERSION MISSING\n"); abort();
+ n = es_str2num(r->d.estr);
}
return r->d.n;
}
@@ -301,22 +302,24 @@ exprret2Number(struct exprret *r)
* emit error message and set number to 0.
*/
static inline es_str_t *
-exprret2String(struct exprret *r)
+exprret2String(struct exprret *r, int *bMustFree)
{
if(r->datatype == 'N') {
- dbgprintf("toString CONVERSION MISSING\n"); abort();
+ *bMustFree = 1;
+ return es_newStrFromNumber(r->d.n);
}
+ *bMustFree = 0;
return r->d.estr;
}
#define COMP_NUM_BINOP(x) \
- cnfexprEval(expr->l, &l); \
- cnfexprEval(expr->r, &r); \
+ cnfexprEval(expr->l, &l, usrptr); \
+ cnfexprEval(expr->r, &r, usrptr); \
ret->datatype = 'N'; \
ret->d.n = exprret2Number(&l) x exprret2Number(&r)
/* evaluate an expression.
- * Note that we try to avoid malloc whenever possible (because on
+ * Note that we try to avoid malloc whenever possible (because of
* the large overhead it has, especially on highly threaded programs).
* As such, the each caller level must provide buffer space for the
* result on its stack during recursion. This permits the callee to store
@@ -326,14 +329,35 @@ exprret2String(struct exprret *r)
* simply is no case where full evaluation would make any sense at all.
*/
void
-cnfexprEval(struct cnfexpr *expr, struct exprret *ret)
+cnfexprEval(struct cnfexpr *expr, struct exprret *ret, void* usrptr)
{
struct exprret r, l; /* memory for subexpression results */
+ es_str_t *estr;
+ int bMustFree;
//dbgprintf("eval expr %p, type '%c'(%u)\n", expr, expr->nodetype, expr->nodetype);
switch(expr->nodetype) {
case CMP_EQ:
- COMP_NUM_BINOP(==);
+ cnfexprEval(expr->l, &l, usrptr);
+ cnfexprEval(expr->r, &r, usrptr);
+ ret->datatype = 'N';
+ if(l.datatype == 'S') {
+ if(r.datatype == 'S') {
+ ret->d.n = !es_strcmp(l.d.estr, r.d.estr);
+ } else {
+ estr = exprret2String(&r, &bMustFree);
+ ret->d.n = !es_strcmp(l.d.estr, estr);
+ if(bMustFree) es_deleteStr(estr);
+ }
+ } else {
+ if(r.datatype == 'S') {
+ estr = exprret2String(&l, &bMustFree);
+ ret->d.n = !es_strcmp(r.d.estr, estr);
+ if(bMustFree) es_deleteStr(estr);
+ } else {
+ ret->d.n = (l.d.n == r.d.n);
+ }
+ }
break;
case CMP_NE:
COMP_NUM_BINOP(!=);
@@ -351,12 +375,12 @@ cnfexprEval(struct cnfexpr *expr, struct exprret *ret)
COMP_NUM_BINOP(>);
break;
case OR:
- cnfexprEval(expr->l, &l);
+ cnfexprEval(expr->l, &l, usrptr);
ret->datatype = 'N';
if(exprret2Number(&l)) {
ret->d.n = 1ll;
} else {
- cnfexprEval(expr->r, &r);
+ cnfexprEval(expr->r, &r, usrptr);
if(exprret2Number(&r))
ret->d.n = 1ll;
else
@@ -364,10 +388,10 @@ cnfexprEval(struct cnfexpr *expr, struct exprret *ret)
}
break;
case AND:
- cnfexprEval(expr->l, &l);
+ cnfexprEval(expr->l, &l, usrptr);
ret->datatype = 'N';
if(exprret2Number(&l)) {
- cnfexprEval(expr->r, &r);
+ cnfexprEval(expr->r, &r, usrptr);
if(exprret2Number(&r))
ret->d.n = 1ll;
else
@@ -377,7 +401,7 @@ cnfexprEval(struct cnfexpr *expr, struct exprret *ret)
}
break;
case NOT:
- cnfexprEval(expr->r, &r);
+ cnfexprEval(expr->r, &r, usrptr);
ret->datatype = 'N';
ret->d.n = !exprret2Number(&r);
break;
@@ -385,6 +409,14 @@ cnfexprEval(struct cnfexpr *expr, struct exprret *ret)
ret->datatype = 'N';
ret->d.n = ((struct cnfnumval*)expr)->val;
break;
+ case 'S':
+ ret->datatype = 'S';
+ ret->d.estr = es_strdup(((struct cnfstringval*)expr)->estr);
+ break;
+ case 'V':
+ ret->datatype = 'S';
+ ret->d.estr = cnfGetVar(((struct cnfvar*)expr)->name, usrptr);
+ break;
case '+':
COMP_NUM_BINOP(+);
break;
@@ -401,15 +433,15 @@ cnfexprEval(struct cnfexpr *expr, struct exprret *ret)
COMP_NUM_BINOP(%);
break;
case 'M':
- cnfexprEval(expr->r, &r);
+ cnfexprEval(expr->r, &r, usrptr);
ret->datatype = 'N';
ret->d.n = -exprret2Number(&r);
break;
default:
ret->datatype = 'N';
ret->d.n = 0ll;
- dbgprintf("eval error: unknown nodetype %u\n",
- (unsigned) expr->nodetype);
+ dbgprintf("eval error: unknown nodetype %u['%c']\n",
+ (unsigned) expr->nodetype, (char) expr->nodetype);
break;
}
}
@@ -419,10 +451,10 @@ cnfexprEval(struct cnfexpr *expr, struct exprret *ret)
* important.
*/
int
-cnfexprEvalBool(struct cnfexpr *expr)
+cnfexprEvalBool(struct cnfexpr *expr, void *usrptr)
{
struct exprret ret;
- cnfexprEval(expr, &ret);
+ cnfexprEval(expr, &ret, usrptr);
return exprret2Number(&ret);
}
diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h
index bab7e602..8b5c36de 100644
--- a/grammar/rainerscript.h
+++ b/grammar/rainerscript.h
@@ -161,8 +161,8 @@ struct cnfactlst* cnfactlstAddSysline(struct cnfactlst* actlst, char *line);
struct cnfactlst* cnfactlstReverse(struct cnfactlst *actlst);
struct cnfexpr* cnfexprNew(unsigned nodetype, struct cnfexpr *l, struct cnfexpr *r);
void cnfexprPrint(struct cnfexpr *expr, int indent);
-void cnfexprEval(struct cnfexpr *expr, struct exprret *ret);
-int cnfexprEvalBool(struct cnfexpr *expr);
+void cnfexprEval(struct cnfexpr *expr, struct exprret *ret, void *pusr);
+int cnfexprEvalBool(struct cnfexpr *expr, void *usrptr);
struct cnfnumval* cnfnumvalNew(long long val);
struct cnfstringval* cnfstringvalNew(es_str_t *estr);
struct cnfrule * cnfruleNew(enum cnfFiltType filttype, struct cnfactlst *actlst);
diff --git a/grammar/testdriver.c b/grammar/testdriver.c
index 52d2d0c7..3e161d38 100644
--- a/grammar/testdriver.c
+++ b/grammar/testdriver.c
@@ -86,6 +86,14 @@ void cnfDoBSDHost(char *ln)
dbgprintf("global:BSD host: %s\n", ln);
}
+es_str_t*
+cnfGetVar(char *name, void *usrptr)
+{
+ es_str_t *estr;
+ estr = es_newStrFromCStr("", 1);
+ return estr;
+}
+
int
main(int argc, char *argv[])
{
diff --git a/runtime/msg.c b/runtime/msg.c
index c5cbb5c8..96fe1b2c 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -37,6 +37,7 @@
#include <ctype.h>
#include <sys/socket.h>
#include <netdb.h>
+#include <libestr.h>
#include <libee/libee.h>
#if HAVE_MALLOC_H
# include <malloc.h>
@@ -480,16 +481,13 @@ getRcvFromIP(msg_t *pM)
}
-
-/* map a property name (string) to a property ID */
-rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID)
+/* map a property name (C string) to a property ID */
+rsRetVal
+propNameStrToID(uchar *pName, propid_t *pPropID)
{
- uchar *pName;
DEFiRet;
- assert(pCSPropName != NULL);
- assert(pPropID != NULL);
- pName = rsCStrGetSzStrNoNULL(pCSPropName);
+ assert(pName != NULL);
/* sometimes there are aliases to the original MonitoWare
* property names. These come after || in the ifs below. */
@@ -577,6 +575,21 @@ rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID)
}
+/* map a property name (string) to a property ID */
+rsRetVal
+propNameToID(cstr_t *pCSPropName, propid_t *pPropID)
+{
+ uchar *pName;
+ DEFiRet;
+
+ assert(pCSPropName != NULL);
+ assert(pPropID != NULL);
+ pName = rsCStrGetSzStrNoNULL(pCSPropName);
+ iRet = propNameStrToID(pName, pPropID);
+ RETiRet;
+}
+
+
/* map a property ID to a name string (useful for displaying) */
uchar *propIDToName(propid_t propID)
{
@@ -3190,6 +3203,34 @@ finalize_it:
}
+
+/* Return an es_str_t for given message property.
+ */
+es_str_t*
+msgGetMsgVarNew(msg_t *pThis, uchar *name)
+{
+ size_t propLen;
+ uchar *pszProp = NULL;
+ propid_t propid;
+ unsigned short bMustBeFreed = 0;
+ es_str_t *estr;
+
+ ISOBJ_TYPE_assert(pThis, msg);
+
+ /* always call MsgGetProp() without a template specifier */
+ /* TODO: optimize propNameToID() call -- rgerhards, 2009-06-26 */
+ propNameStrToID(name, &propid);
+ pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, NULL, &propLen, &bMustBeFreed);
+
+dbgprintf("ZZZZ: var %s returns '%s'\n", name, pszProp);
+ estr = es_newStrFromCStr((char*)pszProp, propLen);
+ if(bMustBeFreed)
+ free(pszProp);
+
+ return estr;
+}
+
+
/* This function can be used as a generic way to set properties.
* We have to handle a lot of legacy, so our return value is not always
* 100% correct (called functions do not always provide one, should
diff --git a/runtime/msg.h b/runtime/msg.h
index 01a1e059..19debb03 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -170,6 +170,7 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
size_t *pPropLen, unsigned short *pbMustBeFreed);
char *textpri(char *pRes, size_t pResLen, int pri);
rsRetVal msgGetMsgVar(msg_t *pThis, cstr_t *pstrPropName, var_t **ppVar);
+es_str_t* msgGetMsgVarNew(msg_t *pThis, uchar *name);
rsRetVal MsgEnableThreadSafety(void);
uchar *getRcvFrom(msg_t *pM);
void getTAG(msg_t *pM, uchar **ppBuf, int *piLen);
diff --git a/runtime/rsconf.c b/runtime/rsconf.c
index cb8eac50..459c9a17 100644
--- a/runtime/rsconf.c
+++ b/runtime/rsconf.c
@@ -222,7 +222,6 @@ cnfDoActlst(struct cnfactlst *actlst, rule_t *pRule)
{
struct cnfcfsyslinelst *cflst;
action_t *pAction;
- rsRetVal localRet;
uchar *str;
DEFiRet;
@@ -280,7 +279,7 @@ void cnfDoRule(struct cnfrule *cnfrule)
{
rule_t *pRule;
uchar *str;
- DEFiRet;
+ rsRetVal iRet = RS_RET_OK; //DEFiRet;
dbgprintf("cnf:global:rule\n");
cnfrulePrint(cnfrule);
@@ -346,6 +345,17 @@ void cnfDoBSDHost(char *ln)
dbgprintf("cnf:global:BSD host: %s\n", ln);
cflineProcessHostSelector((uchar**)&ln);
}
+
+es_str_t*
+cnfGetVar(char *name, void *usrptr)
+{
+ es_str_t *estr;
+ dbgprintf("ZZZZ: var '%s' requested", name);
+ if(name[0] == '$') {
+ estr = msgGetMsgVarNew((msg_t*) usrptr, (uchar*)name+1);
+ }
+ return estr;
+}
/*------------------------------ end interface to flex/bison parser ------------------------------*/
diff --git a/runtime/rule.c b/runtime/rule.c
index 8976c898..67ef8650 100644
--- a/runtime/rule.c
+++ b/runtime/rule.c
@@ -196,7 +196,7 @@ shouldProcessThisMessage(rule_t *pRule, msg_t *pMsg, sbool *bProcessMsg)
/* VM is destructed on function exit */
bRet = (pResult->val.num) ? 1 : 0;
#endif
- bRet = cnfexprEvalBool(pRule->f_filterData.expr);
+ bRet = cnfexprEvalBool(pRule->f_filterData.expr, pMsg);
dbgprintf("result of rainerscript filter evaluation: %d\n", bRet);
} else {
assert(pRule->f_filter_type == FILTER_PROP); /* assert() just in case... */