diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | grammar/parserif.h | 1 | ||||
-rw-r--r-- | grammar/rainerscript.c | 68 | ||||
-rw-r--r-- | grammar/rainerscript.h | 4 | ||||
-rw-r--r-- | grammar/testdriver.c | 8 | ||||
-rw-r--r-- | runtime/msg.c | 55 | ||||
-rw-r--r-- | runtime/msg.h | 1 | ||||
-rw-r--r-- | runtime/rsconf.c | 14 | ||||
-rw-r--r-- | runtime/rule.c | 2 |
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... */ |