summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--grammar/rainerscript.c188
-rw-r--r--grammar/rainerscript.h2
-rw-r--r--runtime/ruleset.c21
4 files changed, 148 insertions, 65 deletions
diff --git a/ChangeLog b/ChangeLog
index 39b5a8ef..854a14d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,8 @@ Version 7.2.7 [v7-stable] 2013-03-??
The rsyslog debug log file is now continued to be written across the
fork.
- updated systemd files to match current systemd source
+- bugfix: nested if/prifilt conditions did not work properly
+ closes: http://bugzilla.adiscon.com/show_bug.cgi?id=415
- bugfix: script == comparison did not work properly on JSON objects
[backport from 7.3 branch]
- bugfix: imudp scheduling parameters did affect main thread, not imudp
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index c14295af..186887b4 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -1285,7 +1285,9 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
int bMustFree, bMustFree2;
long long n_r, n_l;
- dbgprintf("eval expr %p, type '%c'(%u)\n", expr, expr->nodetype, expr->nodetype);
+ DBGPRINTF("eval expr %p, type '%c'[%s](%u)\n", expr, expr->nodetype,
+
+ tokenval2str(expr->nodetype), expr->nodetype);
switch(expr->nodetype) {
/* note: comparison operations are extremely similar. The code can be copyied, only
* places flagged with "CMP" need to be changed.
@@ -1939,31 +1941,33 @@ cnfexprPrint(struct cnfexpr *expr, int indent)
break;
}
}
+/* print only the given stmt
+ * if "subtree" equals 1, the full statement subtree is printed, else
+ * really only the statement.
+ */
void
-cnfstmtPrint(struct cnfstmt *root, int indent)
+cnfstmtPrintOnly(struct cnfstmt *stmt, int indent, sbool subtree)
{
- struct cnfstmt *stmt;
char *cstr;
- //dbgprintf("stmt %p, indent %d, type '%c'\n", expr, indent, expr->nodetype);
- for(stmt = root ; stmt != NULL ; stmt = stmt->next) {
- switch(stmt->nodetype) {
- case S_NOP:
- doIndent(indent); dbgprintf("NOP\n");
- break;
- case S_STOP:
- doIndent(indent); dbgprintf("STOP\n");
- break;
- case S_CALL:
- cstr = es_str2cstr(stmt->d.s_call.name, NULL);
- doIndent(indent); dbgprintf("CALL [%s]\n", cstr);
- free(cstr);
- break;
- case S_ACT:
- doIndent(indent); dbgprintf("ACTION %p [%s]\n", stmt->d.act, stmt->printable);
- break;
- case S_IF:
- doIndent(indent); dbgprintf("IF\n");
- cnfexprPrint(stmt->d.s_if.expr, indent+1);
+ switch(stmt->nodetype) {
+ case S_NOP:
+ doIndent(indent); dbgprintf("NOP\n");
+ break;
+ case S_STOP:
+ doIndent(indent); dbgprintf("STOP\n");
+ break;
+ case S_CALL:
+ cstr = es_str2cstr(stmt->d.s_call.name, NULL);
+ doIndent(indent); dbgprintf("CALL [%s]\n", cstr);
+ free(cstr);
+ break;
+ case S_ACT:
+ doIndent(indent); dbgprintf("ACTION %p [%s]\n", stmt->d.act, stmt->printable);
+ break;
+ case S_IF:
+ doIndent(indent); dbgprintf("IF\n");
+ cnfexprPrint(stmt->d.s_if.expr, indent+1);
+ if(subtree) {
doIndent(indent); dbgprintf("THEN\n");
cnfstmtPrint(stmt->d.s_if.t_then, indent+1);
if(stmt->d.s_if.t_else != NULL) {
@@ -1971,54 +1975,67 @@ cnfstmtPrint(struct cnfstmt *root, int indent)
cnfstmtPrint(stmt->d.s_if.t_else, indent+1);
}
doIndent(indent); dbgprintf("END IF\n");
- break;
- case S_SET:
- doIndent(indent); dbgprintf("SET %s =\n",
- stmt->d.s_set.varname);
- cnfexprPrint(stmt->d.s_set.expr, indent+1);
- doIndent(indent); dbgprintf("END SET\n");
- break;
- case S_UNSET:
- doIndent(indent); dbgprintf("UNSET %s\n",
- stmt->d.s_unset.varname);
- break;
- case S_PRIFILT:
- doIndent(indent); dbgprintf("PRIFILT '%s'\n", stmt->printable);
- pmaskPrint(stmt->d.s_prifilt.pmask, indent);
+ }
+ break;
+ case S_SET:
+ doIndent(indent); dbgprintf("SET %s =\n",
+ stmt->d.s_set.varname);
+ cnfexprPrint(stmt->d.s_set.expr, indent+1);
+ doIndent(indent); dbgprintf("END SET\n");
+ break;
+ case S_UNSET:
+ doIndent(indent); dbgprintf("UNSET %s\n",
+ stmt->d.s_unset.varname);
+ break;
+ case S_PRIFILT:
+ doIndent(indent); dbgprintf("PRIFILT '%s'\n", stmt->printable);
+ pmaskPrint(stmt->d.s_prifilt.pmask, indent);
+ if(subtree) {
cnfstmtPrint(stmt->d.s_prifilt.t_then, indent+1);
if(stmt->d.s_prifilt.t_else != NULL) {
doIndent(indent); dbgprintf("ELSE\n");
cnfstmtPrint(stmt->d.s_prifilt.t_else, indent+1);
}
doIndent(indent); dbgprintf("END PRIFILT\n");
- break;
- case S_PROPFILT:
- doIndent(indent); dbgprintf("PROPFILT\n");
- doIndent(indent); dbgprintf("\tProperty.: '%s'\n",
- propIDToName(stmt->d.s_propfilt.propID));
- if(stmt->d.s_propfilt.propName != NULL) {
- cstr = es_str2cstr(stmt->d.s_propfilt.propName, NULL);
- doIndent(indent);
- dbgprintf("\tCEE-Prop.: '%s'\n", cstr);
- free(cstr);
- }
- doIndent(indent); dbgprintf("\tOperation: ");
- if(stmt->d.s_propfilt.isNegated)
- dbgprintf("NOT ");
- dbgprintf("'%s'\n", getFIOPName(stmt->d.s_propfilt.operation));
- if(stmt->d.s_propfilt.pCSCompValue != NULL) {
- doIndent(indent); dbgprintf("\tValue....: '%s'\n",
- rsCStrGetSzStrNoNULL(stmt->d.s_propfilt.pCSCompValue));
- }
+ }
+ break;
+ case S_PROPFILT:
+ doIndent(indent); dbgprintf("PROPFILT\n");
+ doIndent(indent); dbgprintf("\tProperty.: '%s'\n",
+ propIDToName(stmt->d.s_propfilt.propID));
+ if(stmt->d.s_propfilt.propName != NULL) {
+ cstr = es_str2cstr(stmt->d.s_propfilt.propName, NULL);
+ doIndent(indent);
+ dbgprintf("\tCEE-Prop.: '%s'\n", cstr);
+ free(cstr);
+ }
+ doIndent(indent); dbgprintf("\tOperation: ");
+ if(stmt->d.s_propfilt.isNegated)
+ dbgprintf("NOT ");
+ dbgprintf("'%s'\n", getFIOPName(stmt->d.s_propfilt.operation));
+ if(stmt->d.s_propfilt.pCSCompValue != NULL) {
+ doIndent(indent); dbgprintf("\tValue....: '%s'\n",
+ rsCStrGetSzStrNoNULL(stmt->d.s_propfilt.pCSCompValue));
+ }
+ if(subtree) {
doIndent(indent); dbgprintf("THEN\n");
cnfstmtPrint(stmt->d.s_propfilt.t_then, indent+1);
doIndent(indent); dbgprintf("END PROPFILT\n");
- break;
- default:
- dbgprintf("error: unknown stmt type %u\n",
- (unsigned) stmt->nodetype);
- break;
}
+ break;
+ default:
+ dbgprintf("error: unknown stmt type %u\n",
+ (unsigned) stmt->nodetype);
+ break;
+ }
+}
+void
+cnfstmtPrint(struct cnfstmt *root, int indent)
+{
+ struct cnfstmt *stmt;
+ //dbgprintf("stmt %p, indent %d, type '%c'\n", expr, indent, expr->nodetype);
+ for(stmt = root ; stmt != NULL ; stmt = stmt->next) {
+ cnfstmtPrintOnly(stmt, indent, 1);
}
}
@@ -3099,3 +3116,52 @@ unescapeStr(uchar *s, int len)
s[iDst] = '\0';
}
}
+
+char *
+tokenval2str(int tok)
+{
+ if(tok < 256) return "";
+ switch(tok) {
+ case NAME: return "NAME";
+ case FUNC: return "FUNC";
+ case BEGINOBJ: return "BEGINOBJ";
+ case ENDOBJ: return "ENDOBJ";
+ case BEGIN_ACTION: return "BEGIN_ACTION";
+ case BEGIN_PROPERTY: return "BEGIN_PROPERTY";
+ case BEGIN_CONSTANT: return "BEGIN_CONSTANT";
+ case BEGIN_TPL: return "BEGIN_TPL";
+ case BEGIN_RULESET: return "BEGIN_RULESET";
+ case STOP: return "STOP";
+ case SET: return "SET";
+ case UNSET: return "UNSET";
+ case CONTINUE: return "CONTINUE";
+ case CALL: return "CALL";
+ case LEGACY_ACTION: return "LEGACY_ACTION";
+ case LEGACY_RULESET: return "LEGACY_RULESET";
+ case PRIFILT: return "PRIFILT";
+ case PROPFILT: return "PROPFILT";
+ case BSD_TAG_SELECTOR: return "BSD_TAG_SELECTOR";
+ case BSD_HOST_SELECTOR: return "BSD_HOST_SELECTOR";
+ case IF: return "IF";
+ case THEN: return "THEN";
+ case ELSE: return "ELSE";
+ case OR: return "OR";
+ case AND: return "AND";
+ case NOT: return "NOT";
+ case VAR: return "VAR";
+ case STRING: return "STRING";
+ case NUMBER: return "NUMBER";
+ case CMP_EQ: return "CMP_EQ";
+ case CMP_NE: return "CMP_NE";
+ case CMP_LE: return "CMP_LE";
+ case CMP_GE: return "CMP_GE";
+ case CMP_LT: return "CMP_LT";
+ case CMP_GT: return "CMP_GT";
+ case CMP_CONTAINS: return "CMP_CONTAINS";
+ case CMP_CONTAINSI: return "CMP_CONTAINSI";
+ case CMP_STARTSWITH: return "CMP_STARTSWITH";
+ case CMP_STARTSWITHI: return "CMP_STARTSWITHI";
+ case UMINUS: return "UMINUS";
+ default: return "UNKNOWN TOKEN";
+ }
+}
diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h
index 59ce53f3..c9bcbcc9 100644
--- a/grammar/rainerscript.h
+++ b/grammar/rainerscript.h
@@ -317,6 +317,7 @@ int cnfparamvalsIsSet(struct cnfparamblk *params, struct cnfparamvals *vals);
void varDelete(struct var *v);
void cnfparamvalsDestruct(struct cnfparamvals *paramvals, struct cnfparamblk *blk);
struct cnfstmt * cnfstmtNew(unsigned s_type);
+void cnfstmtPrintOnly(struct cnfstmt *stmt, int indent, sbool subtree);
void cnfstmtPrint(struct cnfstmt *stmt, int indent);
struct cnfstmt* scriptAddStmt(struct cnfstmt *root, struct cnfstmt *s);
struct objlst* objlstAdd(struct objlst *root, struct cnfobj *o);
@@ -338,6 +339,7 @@ void cnfarrayContentDestruct(struct cnfarray *ar);
char* getFIOPName(unsigned iFIOP);
rsRetVal initRainerscript(void);
void unescapeStr(uchar *s, int len);
+char * tokenval2str(int tok);
/* debug helper */
void cstrPrint(char *text, es_str_t *estr);
diff --git a/runtime/ruleset.c b/runtime/ruleset.c
index b74f8ec8..79d2c09d 100644
--- a/runtime/ruleset.c
+++ b/runtime/ruleset.c
@@ -297,6 +297,7 @@ execIf(struct cnfstmt *stmt, batch_t *pBatch, sbool *active)
sbool *newAct;
int i;
sbool bRet;
+ sbool allInactive = 1;
DEFiRet;
newAct = newActive(pBatch);
for(i = 0 ; i < batchNumMsgs(pBatch) ; ++i) {
@@ -307,12 +308,19 @@ execIf(struct cnfstmt *stmt, batch_t *pBatch, sbool *active)
if(active == NULL || active[i]) {
bRet = cnfexprEvalBool(stmt->d.s_if.expr,
(msg_t*)(pBatch->pElem[i].pUsrp));
+ allInactive = 0;
} else
bRet = 0;
newAct[i] = bRet;
DBGPRINTF("batch: item %d: expr eval: %d\n", i, bRet);
}
+ if(allInactive) {
+ DBGPRINTF("execIf: all batch elements are inactive, holding execution\n");
+ freeActive(newAct);
+ FINALIZE;
+ }
+
if(stmt->d.s_if.t_then != NULL) {
scriptExec(stmt->d.s_if.t_then, pBatch, newAct);
}
@@ -320,7 +328,8 @@ execIf(struct cnfstmt *stmt, batch_t *pBatch, sbool *active)
for(i = 0 ; i < batchNumMsgs(pBatch) ; ++i) {
if(*(pBatch->pbShutdownImmediate))
FINALIZE;
- if(pBatch->pElem[i].state != BATCH_STATE_DISC)
+ if(pBatch->pElem[i].state != BATCH_STATE_DISC
+ && (active == NULL || active[i]))
newAct[i] = !newAct[i];
}
scriptExec(stmt->d.s_if.t_else, pBatch, newAct);
@@ -365,7 +374,8 @@ execPRIFILT(struct cnfstmt *stmt, batch_t *pBatch, sbool *active)
for(i = 0 ; i < batchNumMsgs(pBatch) ; ++i) {
if(*(pBatch->pbShutdownImmediate))
return;
- if(pBatch->pElem[i].state != BATCH_STATE_DISC)
+ if(pBatch->pElem[i].state != BATCH_STATE_DISC
+ && (active == NULL || active[i]))
newAct[i] = !newAct[i];
}
scriptExec(stmt->d.s_prifilt.t_else, pBatch, newAct);
@@ -504,7 +514,11 @@ scriptExec(struct cnfstmt *root, batch_t *pBatch, sbool *active)
struct cnfstmt *stmt;
for(stmt = root ; stmt != NULL ; stmt = stmt->next) {
-dbgprintf("RRRR: scriptExec: batch of %d elements, active %p, stmt %p, nodetype %u\n", batchNumMsgs(pBatch), active, stmt, stmt->nodetype);
+ if(Debug) {
+ dbgprintf("scriptExec: batch of %d elements, active %p, active[0]:%d\n",
+ batchNumMsgs(pBatch), active, (active == NULL ? 1 : active[0]));
+ cnfstmtPrintOnly(stmt, 2, 0);
+ }
switch(stmt->nodetype) {
case S_NOP:
break;
@@ -521,7 +535,6 @@ dbgprintf("RRRR: scriptExec: batch of %d elements, active %p, stmt %p, nodetype
execUnset(stmt, pBatch, active);
break;
case S_CALL:
- DBGPRINTF("calling ruleset\n"); // TODO: add Name
scriptExec(stmt->d.s_call.stmt, pBatch, active);
break;
case S_IF: