summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/msg.c67
-rw-r--r--runtime/msg.h3
-rw-r--r--runtime/rsyslog.h7
-rw-r--r--runtime/ruleset.c5
4 files changed, 69 insertions, 13 deletions
diff --git a/runtime/msg.c b/runtime/msg.c
index c6663c14..e1c97188 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -320,6 +320,7 @@ static int getAPPNAMELen(msg_t *pM, sbool bLockMutex);
static rsRetVal jsonPathFindParent(struct json_object *jroot, uchar *name, uchar *leaf, struct json_object **parent, int bCreate);
static uchar * jsonPathGetLeaf(uchar *name, int lenName);
static struct json_object *jsonDeepCopy(struct json_object *src);
+static rsRetVal msgAddJSONObj(msg_t *pM, uchar *name, struct json_object *json, struct json_object **pjroot);
/* the locking and unlocking implementations: */
@@ -536,6 +537,8 @@ propNameStrToID(uchar *pName, propid_t *pPropID)
*pPropID = PROP_CEE_ALL_JSON;
} else if(!strncmp((char*) pName, "$!", 2)) {
*pPropID = PROP_CEE;
+ } else if(!strncmp((char*) pName, "$.", 2)) {
+ *pPropID = PROP_LOCAL_VAR;
} else if(!strcmp((char*) pName, "$bom")) {
*pPropID = PROP_SYS_BOM;
} else if(!strcmp((char*) pName, "$uptime")) {
@@ -634,6 +637,8 @@ uchar *propIDToName(propid_t propID)
return UCHAR_CONSTANT("$MYHOSTNAME");
case PROP_CEE:
return UCHAR_CONSTANT("*CEE-based property*");
+ case PROP_LOCAL_VAR:
+ return UCHAR_CONSTANT("*LOCAL_VARIABLE*");
case PROP_CEE_ALL_JSON:
return UCHAR_CONSTANT("$!all-json");
case PROP_SYS_BOM:
@@ -708,6 +713,7 @@ static inline rsRetVal msgBaseConstruct(msg_t **ppThis)
pM->rcvFrom.pRcvFrom = NULL;
pM->pRuleset = NULL;
pM->json = NULL;
+ pM->localvars = NULL;
memset(&pM->tRcvdAt, 0, sizeof(pM->tRcvdAt));
memset(&pM->tTIMESTAMP, 0, sizeof(pM->tTIMESTAMP));
pM->TAG.pszTAG = NULL;
@@ -853,6 +859,8 @@ CODESTARTobjDestruct(msg)
rsCStrDestruct(&pThis->pCSMSGID);
if(pThis->json != NULL)
json_object_put(pThis->json);
+ if(pThis->localvars != NULL)
+ json_object_put(pThis->localvars);
if(pThis->pszUUID != NULL)
free(pThis->pszUUID);
# ifndef HAVE_ATOMIC_BUILTINS
@@ -1002,6 +1010,8 @@ msg_t* MsgDup(msg_t* pOld)
if(pOld->json != NULL)
pNew->json = jsonDeepCopy(pOld->json);
+ if(pOld->localvars != NULL)
+ pNew->localvars = jsonDeepCopy(pOld->localvars);
/* we do not copy all other cache properties, as we do not even know
* if they are needed once again. So we let them re-create if needed.
@@ -1060,6 +1070,10 @@ static rsRetVal MsgSerialize(msg_t *pThis, strm_t *pStrm)
psz = (uchar*) json_object_get_string(pThis->json);
CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("json"), PROPTYPE_PSZ, (void*) psz));
}
+ if(pThis->localvars != NULL) {
+ psz = (uchar*) json_object_get_string(pThis->localvars);
+ CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("localvars"), PROPTYPE_PSZ, (void*) psz));
+ }
objSerializePTR(pStrm, pCSStrucData, CSTR);
objSerializePTR(pStrm, pCSAPPNAME, CSTR);
@@ -2556,6 +2570,12 @@ getCEEPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, rs_size_t *buflen, un
return getJSONPropVal(pM->json, propName, pRes, buflen, pbMustBeFreed);
}
+rsRetVal
+getLocalVarPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed)
+{
+ return getJSONPropVal(pM->localvars, propName, pRes, buflen, pbMustBeFreed);
+}
+
/* Get a JSON-based-variable as native json object */
rsRetVal
@@ -2594,6 +2614,12 @@ msgGetCEEPropJSON(msg_t *pM, es_str_t *propName, struct json_object **pjson)
return msgGetJSONPropJSON(pM->json, propName, pjson);
}
+rsRetVal
+msgGetLocalVarJSON(msg_t *pM, es_str_t *propName, struct json_object **pjson)
+{
+ return msgGetJSONPropJSON(pM->localvars, propName, pjson);
+}
+
/* Encode a JSON value and add it to provided string. Note that
* the string object may be NULL. In this case, it is created
* if and only if escaping is needed.
@@ -2991,6 +3017,9 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
case PROP_CEE:
getCEEPropVal(pMsg, propName, &pRes, &bufLen, pbMustBeFreed);
break;
+ case PROP_LOCAL_VAR:
+ getLocalVarPropVal(pMsg, propName, &pRes, &bufLen, pbMustBeFreed);
+ break;
case PROP_SYS_BOM:
if(*pbMustBeFreed == 1)
free(pRes);
@@ -3697,6 +3726,12 @@ msgGetCEEVarNew(msg_t *pMsg, char *name)
return msgGetJSONVarNew(pMsg, pMsg->json, name);
}
+es_str_t*
+msgGetLocalVarNew(msg_t *pMsg, char *name)
+{
+ return msgGetJSONVarNew(pMsg, pMsg->localvars, name);
+}
+
/* Return an es_str_t for given message property.
*/
es_str_t*
@@ -3824,16 +3859,22 @@ static uchar *
jsonPathGetLeaf(uchar *name, int lenName)
{
int i;
- for(i = lenName ; name[i] != '!' && i >= 0 ; --i)
- /* just skip */;
- if(name[i] == '!')
+ for(i = lenName ; i >= 0 ; --i)
+ if(i == 0) {
+ if(name[0] == '.' || name[0] == '!')
+ break;
+ } else {
+ if(name[i] == '!')
+ break;
+ }
+ if(name[i] == '!' || name[i] == '.')
++i;
return name + i;
}
static rsRetVal
-jsonPathFindNext(struct json_object *root, uchar **name, uchar *leaf,
+jsonPathFindNext(struct json_object *root, uchar *namestart, uchar **name, uchar *leaf,
struct json_object **found, int bCreate)
{
uchar namebuf[1024];
@@ -3842,9 +3883,9 @@ jsonPathFindNext(struct json_object *root, uchar **name, uchar *leaf,
uchar *p = *name;
DEFiRet;
- if(*p == '!')
+ if(*p == '!' || (*name == namestart && *p == '.'))
++p;
- for(i = 0 ; *p && *p != '!' && p != leaf && i < sizeof(namebuf)-1 ; ++i, ++p)
+ for(i = 0 ; *p && !(p == namestart && *p == '.') && *p != '!' && p != leaf && i < sizeof(namebuf)-1 ; ++i, ++p)
namebuf[i] = *p;
if(i > 0) {
namebuf[i] = '\0';
@@ -3870,10 +3911,12 @@ finalize_it:
static rsRetVal
jsonPathFindParent(struct json_object *jroot, uchar *name, uchar *leaf, struct json_object **parent, int bCreate)
{
+ uchar *namestart;
DEFiRet;
+ namestart = name;
*parent = jroot;
while(name < leaf-1) {
- jsonPathFindNext(*parent, &name, leaf, parent, bCreate);
+ jsonPathFindNext(*parent, namestart, &name, leaf, parent, bCreate);
}
RETiRet;
}
@@ -3937,7 +3980,7 @@ msgAddJSONObj(msg_t *pM, uchar *name, struct json_object *json, struct json_obje
DEFiRet;
MsgLock(pM);
- if(name[0] == '!' && name[1] == '\0') {
+ if((name[0] == '!' || name[0] == '.') && name[1] == '\0') {
if(*pjroot == NULL)
*pjroot = json;
else
@@ -3998,7 +4041,7 @@ msgDelJSONVar(msg_t *pM, struct json_object **jroot, uchar *name)
dbgprintf("AAAA: unset variable '%s'\n", name);
MsgLock(pM);
- if(name[0] == '!' && name[1] == '\0') {
+ if((name[0] == '!' || 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.
*/
@@ -4105,7 +4148,11 @@ msgSetJSONFromVar(msg_t *pMsg, uchar *varname, struct var *v)
v->datatype);
ABORT_FINALIZE(RS_RET_ERR);
}
- msgAddJSON(pMsg, varname+1, json);
+ /* we always know strlen(varname) > 2 */
+ if(varname[1] == '.')
+ msgAddJSONObj(pMsg, varname+1, json, &pMsg->localvars);
+ else
+ msgAddJSONObj(pMsg, varname+1, json, &pMsg->json);
finalize_it:
RETiRet;
}
diff --git a/runtime/msg.h b/runtime/msg.h
index efa36d91..f9ffc5e3 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -108,6 +108,7 @@ struct msg {
struct syslogTime tRcvdAt;/* time the message entered this program */
struct syslogTime tTIMESTAMP;/* (parsed) value of the timestamp */
struct json_object *json;
+ struct json_object *localvars;
/* some fixed-size buffers to save malloc()/free() for frequently used fields (from the default templates) */
uchar szRawMsg[CONF_RAWMSG_BUFSIZE]; /* most messages are small, and these are stored here (without malloc/free!) */
uchar szHOSTNAME[CONF_HOSTNAME_BUFSIZE];
@@ -186,6 +187,7 @@ 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);
es_str_t* msgGetCEEVarNew(msg_t *pMsg, char *name);
+es_str_t* msgGetLocalVarNew(msg_t *pMsg, char *name);
rsRetVal msgAddJSON(msg_t *pM, uchar *name, struct json_object *json);
rsRetVal getCEEPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed);
rsRetVal MsgGetSeverity(msg_t *pThis, int *piSeverity);
@@ -206,6 +208,7 @@ 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 msgGetLocalVarJSON(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);
rsRetVal jsonFind(struct json_object *jroot, es_str_t *propName, struct json_object **jsonres);
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index 63112627..9fd527fd 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -140,11 +140,12 @@ typedef uintTiny propid_t;
#define PROP_SYS_QHOUR 156
#define PROP_SYS_MINUTE 157
#define PROP_SYS_MYHOSTNAME 158
-#define PROP_CEE 200
-#define PROP_CEE_ALL_JSON 201
#define PROP_SYS_BOM 159
#define PROP_SYS_UPTIME 160
-#define PROP_UUID 161
+#define PROP_UUID 161
+#define PROP_CEE 200
+#define PROP_CEE_ALL_JSON 201
+#define PROP_LOCAL_VAR 202
/* The error codes below are orginally "borrowed" from
diff --git a/runtime/ruleset.c b/runtime/ruleset.c
index 36222cfb..6c4eae26 100644
--- a/runtime/ruleset.c
+++ b/runtime/ruleset.c
@@ -447,6 +447,11 @@ evalPROPFILT(struct cnfstmt *stmt, msg_t *pMsg)
DBGPRINTF("Filter: check for CEE property '%s' (value '%s') ",
cstr, pszPropVal);
free(cstr);
+ } else if(stmt->d.s_propfilt.propID == PROP_LOCAL_VAR) {
+ cstr = es_str2cstr(stmt->d.s_propfilt.propName, NULL);
+ DBGPRINTF("Filter: check for local var '%s' (value '%s') ",
+ cstr, pszPropVal);
+ free(cstr);
} else {
DBGPRINTF("Filter: check for property '%s' (value '%s') ",
propIDToName(stmt->d.s_propfilt.propID), pszPropVal);