summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/ctok.c3
-rw-r--r--runtime/ctok_token.h1
-rw-r--r--runtime/expr.c5
-rw-r--r--runtime/msg.c57
-rw-r--r--runtime/msg.h2
-rw-r--r--runtime/stringbuf.c29
-rw-r--r--runtime/stringbuf.h2
-rw-r--r--runtime/var.h1
-rw-r--r--runtime/vm.c27
-rw-r--r--runtime/vmop.h1
10 files changed, 128 insertions, 0 deletions
diff --git a/runtime/ctok.c b/runtime/ctok.c
index 18ddaed2..6d97568e 100644
--- a/runtime/ctok.c
+++ b/runtime/ctok.c
@@ -277,6 +277,9 @@ ctokGetVar(ctok_t *pThis, ctok_token_t *pToken)
if(c == '$') { /* second dollar, we have a system variable */
pToken->tok = ctok_SYSVAR;
CHKiRet(ctokGetCharFromStream(pThis, &c)); /* "eat" it... */
+ } else if(c == '!') { /* cee variable indicator */
+ pToken->tok = ctok_CEEVAR;
+ CHKiRet(ctokGetCharFromStream(pThis, &c)); /* "eat" it... */
} else {
pToken->tok = ctok_MSGVAR;
}
diff --git a/runtime/ctok_token.h b/runtime/ctok_token.h
index d36689fa..1413c699 100644
--- a/runtime/ctok_token.h
+++ b/runtime/ctok_token.h
@@ -54,6 +54,7 @@ typedef struct {
ctok_FUNCTION = 17,
ctok_THEN = 18,
ctok_STRADD = 19,
+ ctok_CEEVAR = 20,
ctok_CMP_EQ = 100, /* all compare operations must be in a row */
ctok_CMP_NEQ = 101,
ctok_CMP_LT = 102,
diff --git a/runtime/expr.c b/runtime/expr.c
index e449d1c7..01431474 100644
--- a/runtime/expr.c
+++ b/runtime/expr.c
@@ -151,6 +151,11 @@ terminal(expr_t *pThis, ctok_t *tok)
CHKiRet(ctok_token.UnlinkVar(pToken, &pVar));
CHKiRet(vmprg.AddVarOperation(pThis->pVmprg, opcode_PUSHMSGVAR, pVar)); /* add to program */
break;
+ case ctok_CEEVAR:
+ dbgoprint((obj_t*) pThis, "SYSVAR\n");
+ CHKiRet(ctok_token.UnlinkVar(pToken, &pVar));
+ CHKiRet(vmprg.AddVarOperation(pThis->pVmprg, opcode_PUSHCEEVAR, pVar)); /* add to program */
+ break;
case ctok_SYSVAR:
dbgoprint((obj_t*) pThis, "SYSVAR\n");
CHKiRet(ctok_token.UnlinkVar(pToken, &pVar));
diff --git a/runtime/msg.c b/runtime/msg.c
index cca9d5f6..65ea101f 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -3074,6 +3074,61 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
}
+/* The function returns a cee variable suitable for use with RainerScript. Most importantly, this means
+ * that the value is returned in a var_t object. The var_t is constructed inside this function and
+ * MUST be freed by the caller.
+ * Note that we need to do a lot of conversions between es_str_t and cstr -- this will go away once
+ * we have moved larger parts of rsyslog to es_str_t. Acceptable for the moment, especially as we intend
+ * to rewrite the script engine as well!
+ * rgerhards, 2010-12-03
+ */
+rsRetVal
+msgGetCEEVar(msg_t *pMsg, cstr_t *propName, var_t **ppVar)
+{
+ DEFiRet;
+ var_t *pVar;
+ cstr_t *pstrProp;
+ es_str_t *str = NULL;
+ es_str_t *epropName = NULL;
+ struct ee_field *field;
+
+ ISOBJ_TYPE_assert(pMsg, msg);
+ ASSERT(propName != NULL);
+ ASSERT(ppVar != NULL);
+
+ /* make sure we have a var_t instance */
+ CHKiRet(var.Construct(&pVar));
+ CHKiRet(var.ConstructFinalize(pVar));
+
+ epropName = es_newStrFromBuf((char*)propName->pBuf, propName->iStrLen);
+ if((field = ee_getEventField(pMsg->event, epropName)) != NULL) {
+ /* right now, we always extract data from the first field value. A reason for this
+ * is that as of now (2010-12-01) liblognorm never populates more than one ;)
+ */
+ str = ee_getFieldValueAsStr(field, 0);
+ }
+
+ if(str == NULL) {
+ CHKiRet(cstrConstruct(&pstrProp));
+ CHKiRet(cstrFinalize(pstrProp));
+ } else {
+ CHKiRet(cstrConstructFromESStr(&pstrProp, str));
+ }
+
+ /* now create a string object out of it and hand that over to the var */
+ CHKiRet(var.SetString(pVar, pstrProp));
+ es_deleteStr(str);
+
+ /* finally store var */
+ *ppVar = pVar;
+
+finalize_it:
+ if(epropName != NULL)
+ es_deleteStr(epropName);
+ RETiRet;
+}
+
+
/* The returns a message variable suitable for use with RainerScript. Most importantly, this means
* that the value is returned in a var_t object. The var_t is constructed inside this function and
* MUST be freed by the caller.
@@ -3116,6 +3171,8 @@ finalize_it:
RETiRet;
}
+
+
/* 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 9d9df8d0..1fd95994 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -29,6 +29,7 @@
#define MSG_H_INCLUDED 1
#include <pthread.h>
+#include <libestr.h>
#include "obj.h"
#include "syslogd-types.h"
#include "template.h"
@@ -174,6 +175,7 @@ void getTAG(msg_t *pM, uchar **ppBuf, int *piLen);
char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt);
char *getPRI(msg_t *pMsg);
void getRawMsg(msg_t *pM, uchar **pBuf, int *piLen);
+rsRetVal msgGetCEEVar(msg_t *pThis, cstr_t *propName, var_t **ppVar);
/* TODO: remove these five (so far used in action.c) */
diff --git a/runtime/stringbuf.c b/runtime/stringbuf.c
index ccf115c1..f4a9caae 100644
--- a/runtime/stringbuf.c
+++ b/runtime/stringbuf.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
+#include <libestr.h>
#include "rsyslog.h"
#include "stringbuf.h"
#include "srUtils.h"
@@ -104,6 +105,34 @@ finalize_it:
RETiRet;
}
+
+/* construct from es_str_t string
+ * rgerhards 2010-12-03
+ */
+rsRetVal cstrConstructFromESStr(cstr_t **ppThis, es_str_t *str)
+{
+ DEFiRet;
+ cstr_t *pThis;
+
+ assert(ppThis != NULL);
+
+ CHKiRet(rsCStrConstruct(&pThis));
+
+ pThis->iBufSize = pThis->iStrLen = es_strlen(str);
+ if((pThis->pBuf = (uchar*) MALLOC(sizeof(uchar) * pThis->iStrLen)) == NULL) {
+ RSFREEOBJ(pThis);
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ }
+
+ /* we do NOT need to copy the \0! */
+ memcpy(pThis->pBuf, es_getBufAddr(str), pThis->iStrLen);
+
+ *ppThis = pThis;
+
+finalize_it:
+ RETiRet;
+}
+
/* construct from CStr object. only the counted string is
* copied, not the szString.
* rgerhards 2005-10-18
diff --git a/runtime/stringbuf.h b/runtime/stringbuf.h
index c5130238..df234012 100644
--- a/runtime/stringbuf.h
+++ b/runtime/stringbuf.h
@@ -36,6 +36,7 @@
#define _STRINGBUF_H_INCLUDED__ 1
#include <assert.h>
+#include <libestr.h>
/**
* The dynamic string buffer object.
@@ -57,6 +58,7 @@ typedef struct cstr_s
*/
rsRetVal cstrConstruct(cstr_t **ppThis);
#define rsCStrConstruct(x) cstrConstruct((x))
+rsRetVal cstrConstructFromESStr(cstr_t **ppThis, es_str_t *str);
rsRetVal rsCStrConstructFromszStr(cstr_t **ppThis, uchar *sz);
rsRetVal rsCStrConstructFromCStr(cstr_t **ppThis, cstr_t *pFrom);
diff --git a/runtime/var.h b/runtime/var.h
index 6d890ec9..ae971bb5 100644
--- a/runtime/var.h
+++ b/runtime/var.h
@@ -40,6 +40,7 @@ typedef struct var_s {
varType_t varType;
union {
number_t num;
+ es_str_t *str;
cstr_t *pStr;
syslogTime_t vSyslogTime;
diff --git a/runtime/vm.c b/runtime/vm.c
index 0ed174d1..c5521c31 100644
--- a/runtime/vm.c
+++ b/runtime/vm.c
@@ -448,6 +448,7 @@ BEGINop(PUSHMSGVAR) /* remember to set the instruction also in the ENDop macro!
var_t *pVal; /* the value to push */
cstr_t *pstrVal;
CODESTARTop(PUSHMSGVAR)
+dbgprintf("XXX: pushMSGVAR, var '%s'\n", rsCStrGetSzStr(pOp->operand.pVar->val.pStr));
if(pThis->pMsg == NULL) {
/* TODO: flag an error message! As a work-around, we permit
* execution to continue here with an empty string
@@ -468,6 +469,31 @@ finalize_it:
ENDop(PUSHMSGVAR)
+BEGINop(PUSHCEEVAR) /* remember to set the instruction also in the ENDop macro! */
+ var_t *pVal; /* the value to push */
+ cstr_t *pstrVal;
+CODESTARTop(PUSHCEEVAR)
+dbgprintf("XXX: pushCEEVAR, var '%s'\n", rsCStrGetSzStr(pOp->operand.pVar->val.pStr));
+ if(pThis->pMsg == NULL) {
+ /* TODO: flag an error message! As a work-around, we permit
+ * execution to continue here with an empty string
+ */
+ CHKiRet(var.Construct(&pVal));
+ CHKiRet(var.ConstructFinalize(pVal));
+ CHKiRet(rsCStrConstructFromszStr(&pstrVal, (uchar*)""));
+ CHKiRet(var.SetString(pVal, pstrVal));
+ } else {
+ /* we have a message, so pull value from there */
+ CHKiRet(msgGetCEEVar(pThis->pMsg, pOp->operand.pVar->val.pStr, &pVal));
+ }
+
+ /* if we reach this point, we have a valid pVal and can push it */
+ vmstk.Push(pThis->pStk, pVal);
+dbgprintf("XXX: pushCEEVAR, result '%s'\n", rsCStrGetSzStr(pVal->val.pStr));
+finalize_it:
+ENDop(PUSHCEEVAR)
+
+
BEGINop(PUSHSYSVAR) /* remember to set the instruction also in the ENDop macro! */
var_t *pVal; /* the value to push */
CODESTARTop(PUSHSYSVAR)
@@ -685,6 +711,7 @@ execProg(vm_t *pThis, vmprg_t *pProg)
doOP(NOT);
doOP(PUSHCONSTANT);
doOP(PUSHMSGVAR);
+ doOP(PUSHCEEVAR);
doOP(PUSHSYSVAR);
doOP(STRADD);
doOP(PLUS);
diff --git a/runtime/vmop.h b/runtime/vmop.h
index 67048c26..c085a940 100644
--- a/runtime/vmop.h
+++ b/runtime/vmop.h
@@ -59,6 +59,7 @@ typedef enum { /* do NOT start at 0 to detect uninitialized types after calloc(
opcode_PUSHSYSVAR = 1001, /* requires var operand */
opcode_PUSHMSGVAR = 1002, /* requires var operand */
opcode_PUSHCONSTANT = 1003, /* requires var operand */
+ opcode_PUSHCEEVAR = 1004, /* requires var operand */
opcode_UNARY_MINUS = 1010,
opcode_FUNC_CALL = 1012,
opcode_END_PROG = 2000