summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-09-17 08:00:34 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-09-17 08:00:34 +0200
commit71f602c4e97a67097ede995642a5cb09c0ceca07 (patch)
treef37529e532f060b531ce1706d8be1c130a0189f2
parent8fe7507de1d9f800fedb82a2cf2e1f443db940f7 (diff)
downloadrsyslog-71f602c4e97a67097ede995642a5cb09c0ceca07.tar.gz
rsyslog-71f602c4e97a67097ede995642a5cb09c0ceca07.tar.bz2
rsyslog-71f602c4e97a67097ede995642a5cb09c0ceca07.zip
new ruleengine: Implent "unset" statement
-rw-r--r--runtime/msg.c42
-rw-r--r--runtime/msg.h7
-rw-r--r--runtime/rsyslog.h1
-rw-r--r--runtime/ruleset.c29
4 files changed, 72 insertions, 7 deletions
diff --git a/runtime/msg.c b/runtime/msg.c
index 15eb7abb..0cb60436 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -3779,6 +3779,48 @@ finalize_it:
}
rsRetVal
+msgDelJSON(msg_t *pM, uchar *name)
+{
+ struct json_object *parent, *leafnode;
+ uchar *leaf;
+ DEFiRet;
+
+dbgprintf("AAAA: unset variable '%s'\n", name);
+ MsgLock(pM);
+ if(name[0] == '!' && name[1] == '\0') {
+ /* strange, but I think we should permit this. After all,
+ * we trust rsyslog.conf to be written by the admin.
+ */
+ DBGPRINTF("unsetting JSON root object\n");
+ json_object_put(pM->json);
+ pM->json = NULL;
+ } else {
+ if(pM->json == NULL) {
+ /* now we need a root obj */
+ pM->json = json_object_new_object();
+ }
+ leaf = jsonPathGetLeaf(name, ustrlen(name));
+ CHKiRet(jsonPathFindParent(pM, name, leaf, &parent, 1));
+ leafnode = json_object_object_get(parent, (char*)leaf);
+DBGPRINTF("AAAA: unset found JSON value path '%s', " "leaf '%s', leafnode %p\n", name, leaf, leafnode);
+ if(leafnode == NULL) {
+ DBGPRINTF("unset JSON: could not find '%s'\n", name);
+ ABORT_FINALIZE(RS_RET_JNAME_NOTFOUND);
+ } else {
+ DBGPRINTF("deleting JSON value path '%s', "
+ "leaf '%s', type %d\n",
+ name, leaf, json_object_get_type(leafnode));
+ json_object_put(leafnode);
+ json_object_object_del(parent, (char*)leaf);
+ }
+ }
+
+finalize_it:
+ MsgUnlock(pM);
+ RETiRet;
+}
+
+rsRetVal
msgSetJSONFromVar(msg_t *pMsg, uchar *varname, struct var *var)
{
struct json_object *json = NULL;
diff --git a/runtime/msg.h b/runtime/msg.h
index 857eb673..477d1f1a 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -202,6 +202,13 @@ uchar *getRcvFrom(msg_t *pM);
rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID);
uchar *propIDToName(propid_t propID);
rsRetVal msgGetCEEPropJSON(msg_t *pM, es_str_t *propName, struct json_object **pjson);
+rsRetVal msgSetJSONFromVar(msg_t *pMsg, uchar *varname, struct var *var);
+rsRetVal msgDelJSON(msg_t *pMsg, uchar *varname);
+
+static inline rsRetVal
+msgUnsetJSON(msg_t *pMsg, uchar *varname) {
+ return msgDelJSON(pMsg, varname+1);
+}
/* The MsgPrepareEnqueue() function is a macro for performance reasons.
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index 2977f6f3..ceb277d0 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -387,6 +387,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_JNAME_INVALID = -2302, /**< JSON path is invalid */
RS_RET_JSON_PARSE_ERR = -2303, /**< we had a problem parsing JSON (or extra data) */
RS_RET_BSD_BLOCKS_UNSUPPORTED = -2304, /**< BSD-style config blocks are no longer supported */
+ RS_RET_JNAME_NOTFOUND = -2305, /**< JSON name not found (does not exist) */
RS_RET_INVLD_SETOP = -2305, /**< invalid variable set operation, incompatible type */
/* RainerScript error messages (range 1000.. 1999) */
diff --git a/runtime/ruleset.c b/runtime/ruleset.c
index 392473e9..a40e2ed1 100644
--- a/runtime/ruleset.c
+++ b/runtime/ruleset.c
@@ -219,7 +219,6 @@ dbgprintf("RRRR: execAct: batch of %d elements, active %p\n", batchNumMsgs(pBatc
RETiRet;
}
-/* for details, see scriptExec() header comment! */
static rsRetVal
execSet(struct cnfstmt *stmt, batch_t *pBatch, sbool *active)
{
@@ -230,8 +229,23 @@ execSet(struct cnfstmt *stmt, batch_t *pBatch, sbool *active)
if( pBatch->pElem[i].state != BATCH_STATE_DISC
&& (active == NULL || active[i])) {
cnfexprEval(stmt->d.s_set.expr, &result, pBatch->pElem[i].pUsrp);
- msgSetJSONFromVar(pBatch->pElem[i].pUsrp, stmt->d.s_set.varname,
+ msgSetJSONFromVar((msg_t*)pBatch->pElem[i].pUsrp, stmt->d.s_set.varname,
&result);
+ varDelete(&result);
+ }
+ }
+ RETiRet;
+}
+
+static rsRetVal
+execUnset(struct cnfstmt *stmt, batch_t *pBatch, sbool *active)
+{
+ int i;
+ DEFiRet;
+ for(i = 0 ; i < batchNumMsgs(pBatch) && !*(pBatch->pbShutdownImmediate) ; ++i) {
+ if( pBatch->pElem[i].state != BATCH_STATE_DISC
+ && (active == NULL || active[i])) {
+ msgUnsetJSON((msg_t*)pBatch->pElem[i].pUsrp, stmt->d.s_unset.varname);
}
}
RETiRet;
@@ -321,7 +335,6 @@ execPRIFILT(struct cnfstmt *stmt, batch_t *pBatch, sbool *active)
DBGPRINTF("batch: item %d PRIFILT %d\n", i, thenAct[i]);
}
-dbgprintf("RRRR: PRIFILT calling %p\n", stmt->d.s_prifilt.t_then);
scriptExec(stmt->d.s_prifilt.t_then, pBatch, thenAct);
freeActive(thenAct);
}
@@ -436,7 +449,6 @@ execPROPFILT(struct cnfstmt *stmt, batch_t *pBatch, sbool *active)
DBGPRINTF("batch: item %d PROPFILT %d\n", i, thenAct[i]);
}
-dbgprintf("RRRR: PROPFILT calling %p\n", stmt->d.s_propfilt.t_then);
scriptExec(stmt->d.s_propfilt.t_then, pBatch, thenAct);
freeActive(thenAct);
}
@@ -468,12 +480,15 @@ dbgprintf("RRRR: scriptExec: batch of %d elements, active %p, stmt %p, nodetype
case S_ACT:
execAct(stmt, pBatch, active);
break;
- case S_IF:
- execIf(stmt, pBatch, active);
- break;
case S_SET:
execSet(stmt, pBatch, active);
break;
+ case S_UNSET:
+ execUnset(stmt, pBatch, active);
+ break;
+ case S_IF:
+ execIf(stmt, pBatch, active);
+ break;
case S_PRIFILT:
execPRIFILT(stmt, pBatch, active);
break;