diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2010-12-03 17:11:03 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2010-12-03 17:11:03 +0100 |
commit | 4618773be685488e081bebb397db32851dc16782 (patch) | |
tree | 744a80610a877eaa0f8ff5f552e17a5cbf0563a3 /runtime | |
parent | f871bd135a33c88a013f49402d0af87fb1f1de5d (diff) | |
download | rsyslog-4618773be685488e081bebb397db32851dc16782.tar.gz rsyslog-4618773be685488e081bebb397db32851dc16782.tar.xz rsyslog-4618773be685488e081bebb397db32851dc16782.zip |
milestone: added support for CEE-variables to RainerScript
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/ctok.c | 3 | ||||
-rw-r--r-- | runtime/ctok_token.h | 1 | ||||
-rw-r--r-- | runtime/expr.c | 5 | ||||
-rw-r--r-- | runtime/msg.c | 57 | ||||
-rw-r--r-- | runtime/msg.h | 2 | ||||
-rw-r--r-- | runtime/stringbuf.c | 29 | ||||
-rw-r--r-- | runtime/stringbuf.h | 2 | ||||
-rw-r--r-- | runtime/var.h | 1 | ||||
-rw-r--r-- | runtime/vm.c | 27 | ||||
-rw-r--r-- | runtime/vmop.h | 1 |
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 |