summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/msg.c349
-rw-r--r--runtime/msg.h27
-rw-r--r--runtime/rsconf.c110
-rw-r--r--runtime/rsyslog.h48
-rw-r--r--runtime/ruleset.c32
-rw-r--r--runtime/ruleset.h2
-rw-r--r--runtime/typedefs.h55
7 files changed, 223 insertions, 400 deletions
diff --git a/runtime/msg.c b/runtime/msg.c
index f795242f..21ab18e5 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -65,6 +65,7 @@
#include "net.h"
#include "var.h"
#include "rsconf.h"
+#include "parserif.h"
/* TODO: move the global variable root to the config object - had no time to to it
* right now before vacation -- rgerhards, 2013-07-22
@@ -326,7 +327,6 @@ 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: */
@@ -452,14 +452,12 @@ getRcvFromIP(msg_t *pM)
}
-/* map a property name (C string) to a property ID */
+/* map a property name (string) to a property ID */
rsRetVal
-propNameStrToID(uchar *pName, propid_t *pPropID)
+propNameToID(uchar *pName, propid_t *pPropID)
{
DEFiRet;
- assert(pName != NULL);
-
/* sometimes there are aliases to the original MonitoWare
* property names. These come after || in the ifs below. */
if(!strcmp((char*) pName, "msg")) {
@@ -534,16 +532,16 @@ propNameStrToID(uchar *pName, propid_t *pPropID)
*pPropID = PROP_SYS_MYHOSTNAME;
} else if(!strcmp((char*) pName, "$!all-json")) {
*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(!strncmp((char*) pName, "$/", 2)) {
- *pPropID = PROP_GLOBAL_VAR;
} else if(!strcmp((char*) pName, "$bom")) {
*pPropID = PROP_SYS_BOM;
} else if(!strcmp((char*) pName, "$uptime")) {
*pPropID = PROP_SYS_UPTIME;
+ } else if(!strncmp((char*) pName, "$!", 2) || pName[0] == '!') {
+ *pPropID = PROP_CEE;
+ } else if(!strncmp((char*) pName, "$.", 2) || pName[0] == '.') {
+ *pPropID = PROP_LOCAL_VAR;
+ } else if(!strncmp((char*) pName, "$/", 2) || pName[0] == '/') {
+ *pPropID = PROP_GLOBAL_VAR;
} else {
DBGPRINTF("PROP_INVALID for name '%s'\n", pName);
*pPropID = PROP_INVALID;
@@ -554,21 +552,6 @@ propNameStrToID(uchar *pName, propid_t *pPropID)
}
-/* map a property name (string) to a property ID */
-rsRetVal
-propNameToID(cstr_t *pCSPropName, propid_t *pPropID)
-{
- uchar *pName;
- DEFiRet;
-
- assert(pCSPropName != NULL);
- assert(pPropID != NULL);
- pName = rsCStrGetSzStrNoNULL(pCSPropName);
- iRet = propNameStrToID(pName, pPropID);
- RETiRet;
-}
-
-
/* map a property ID to a name string (useful for displaying) */
uchar *propIDToName(propid_t propID)
{
@@ -641,8 +624,6 @@ uchar *propIDToName(propid_t propID)
return UCHAR_CONSTANT("*CEE-based property*");
case PROP_LOCAL_VAR:
return UCHAR_CONSTANT("*LOCAL_VARIABLE*");
- case PROP_GLOBAL_VAR:
- return UCHAR_CONSTANT("*GLOBAL_VARIABLE*");
case PROP_CEE_ALL_JSON:
return UCHAR_CONSTANT("$!all-json");
case PROP_SYS_BOM:
@@ -2476,11 +2457,17 @@ typedef enum ENOWType { NOW_NOW, NOW_YEAR, NOW_MONTH, NOW_DAY, NOW_HOUR, NOW_HHO
static uchar *getNOW(eNOWType eNow, struct syslogTime *t)
{
uchar *pBuf;
+ struct syslogTime tt;
if((pBuf = (uchar*) MALLOC(sizeof(uchar) * tmpBUFSIZE)) == NULL) {
return NULL;
}
+ if(t == NULL) { /* can happen if called via script engine */
+ datetime.getCurrTime(&tt, NULL);
+ t = &tt;
+ }
+
if(t->year == 0) { /* not yet set! */
datetime.getCurrTime(t, NULL);
}
@@ -2524,11 +2511,11 @@ static uchar *getNOW(eNOWType eNow, struct syslogTime *t)
/* Get a JSON-Property as string value (used for various types of JSON-based vars) */
-static rsRetVal
-getJSONPropVal(struct json_object *jroot, es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed)
+rsRetVal
+getJSONPropVal(msg_t *pMsg, msgPropDescr_t *pProp, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed)
{
- uchar *name = NULL;
uchar *leaf;
+ struct json_object *jroot;
struct json_object *parent;
struct json_object *field;
DEFiRet;
@@ -2536,15 +2523,26 @@ getJSONPropVal(struct json_object *jroot, es_str_t *propName, uchar **pRes, rs_s
if(*pbMustBeFreed)
free(*pRes);
*pRes = NULL;
- // TODO: mutex?
+
+ if(pProp->id == PROP_CEE) {
+ jroot = pMsg->json;
+ } else if(pProp->id == PROP_LOCAL_VAR) {
+ jroot = pMsg->localvars;
+ } else if(pProp->id == PROP_GLOBAL_VAR) {
+ pthread_rwlock_rdlock(&glblVars_rwlock);
+ jroot = global_var_root;
+ } else {
+ DBGPRINTF("msgGetJSONPropVal; invalid property id %d\n",
+ pProp->id);
+ ABORT_FINALIZE(RS_RET_NOT_FOUND);
+ }
if(jroot == NULL) goto finalize_it;
- if(!es_strbufcmp(propName, (uchar*)"!", 1)) {
+ if(!strcmp((char*)pProp->name, "!")) {
field = jroot;
} else {
- name = (uchar*)es_str2cstr(propName, NULL);
- leaf = jsonPathGetLeaf(name+1, ustrlen(name-1));
- CHKiRet(jsonPathFindParent(jroot, name+1, leaf, &parent, 1));
+ leaf = jsonPathGetLeaf(pProp->name, pProp->nameLen);
+ CHKiRet(jsonPathFindParent(jroot, pProp->name, leaf, &parent, 1));
field = json_object_object_get(parent, (char*)leaf);
}
if(field != NULL) {
@@ -2554,7 +2552,8 @@ getJSONPropVal(struct json_object *jroot, es_str_t *propName, uchar **pRes, rs_s
}
finalize_it:
- free(name);
+ if(pProp->id == PROP_GLOBAL_VAR)
+ pthread_rwlock_unlock(&glblVars_rwlock);
if(*pRes == NULL) {
/* could not find any value, so set it to empty */
*pRes = (unsigned char*)"";
@@ -2563,81 +2562,51 @@ finalize_it:
RETiRet;
}
-rsRetVal
-getCEEPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed)
-{
- 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);
-}
-
-rsRetVal
-getGlobalVarPropVal( es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed)
-{
- DEFiRet;
- pthread_rwlock_rdlock(&glblVars_rwlock);
- iRet = getJSONPropVal(global_var_root, propName, pRes, buflen, pbMustBeFreed);
- pthread_rwlock_unlock(&glblVars_rwlock);
- RETiRet;
-}
-
/* Get a JSON-based-variable as native json object */
rsRetVal
-msgGetJSONPropJSON(struct json_object *jroot, es_str_t *propName, struct json_object **pjson)
+msgGetJSONPropJSON(msg_t *pMsg, msgPropDescr_t *pProp, struct json_object **pjson)
{
- uchar *name = NULL;
+ struct json_object *jroot;
uchar *leaf;
struct json_object *parent;
DEFiRet;
- // TODO: mutex?
+ if(pProp->id == PROP_CEE) {
+ jroot = pMsg->json;
+ } else if(pProp->id == PROP_LOCAL_VAR) {
+ jroot = pMsg->localvars;
+ } else if(pProp->id == PROP_GLOBAL_VAR) {
+ pthread_rwlock_rdlock(&glblVars_rwlock);
+ jroot = global_var_root;
+ } else {
+ DBGPRINTF("msgGetJSONPropJSON; invalid property id %d\n",
+ pProp->id);
+ ABORT_FINALIZE(RS_RET_NOT_FOUND);
+ }
if(jroot == NULL) {
+ DBGPRINTF("msgGetJSONPropJSON; jroot empty for property %s\n",
+ pProp->name);
ABORT_FINALIZE(RS_RET_NOT_FOUND);
}
- if(!es_strbufcmp(propName, (uchar*)"!", 1)) {
+ if(!strcmp((char*)pProp->name, "!")) {
*pjson = jroot;
FINALIZE;
}
- name = (uchar*)es_str2cstr(propName, NULL);
- leaf = jsonPathGetLeaf(name, ustrlen(name));
- CHKiRet(jsonPathFindParent(jroot, name, leaf, &parent, 1));
+ leaf = jsonPathGetLeaf(pProp->name, pProp->nameLen);
+ CHKiRet(jsonPathFindParent(jroot, pProp->name, leaf, &parent, 1));
*pjson = json_object_object_get(parent, (char*)leaf);
if(*pjson == NULL) {
ABORT_FINALIZE(RS_RET_NOT_FOUND);
}
finalize_it:
- free(name);
+ if(pProp->id == PROP_GLOBAL_VAR)
+ pthread_rwlock_unlock(&glblVars_rwlock);
RETiRet;
}
-rsRetVal
-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);
-}
-
-rsRetVal
-msgGetGlobalVarJSON(es_str_t *propName, struct json_object **pjson)
-{
- DEFiRet;
- pthread_rwlock_rdlock(&glblVars_rwlock);
- iRet = msgGetJSONPropJSON(global_var_root, propName, pjson);
- pthread_rwlock_unlock(&glblVars_rwlock);
- RETiRet;
-}
/* Encode a JSON value and add it to provided string. Note that
* the string object may be NULL. In this case, it is created
@@ -2839,7 +2808,7 @@ finalize_it:
*pPropLen = sizeof("**OUT OF MEMORY**") - 1; \
return(UCHAR_CONSTANT("**OUT OF MEMORY**"));}
uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
- propid_t propid, es_str_t *propName, rs_size_t *pPropLen,
+ msgPropDescr_t *pProp, rs_size_t *pPropLen,
unsigned short *pbMustBeFreed, struct syslogTime *ttNow)
{
uchar *pRes; /* result pointer */
@@ -2862,7 +2831,7 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*pbMustBeFreed = 0;
- switch(propid) {
+ switch(pProp->id) {
case PROP_MSG:
pRes = getMSG(pMsg);
bufLen = getMSGLen(pMsg);
@@ -3034,13 +3003,9 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
}
break;
case PROP_CEE:
- getCEEPropVal(pMsg, propName, &pRes, &bufLen, pbMustBeFreed);
- break;
case PROP_LOCAL_VAR:
- getLocalVarPropVal(pMsg, propName, &pRes, &bufLen, pbMustBeFreed);
- break;
case PROP_GLOBAL_VAR:
- getGlobalVarPropVal(propName, &pRes, &bufLen, pbMustBeFreed);
+ getJSONPropVal(pMsg, pProp, &pRes, &bufLen, pbMustBeFreed);
break;
case PROP_SYS_BOM:
if(*pbMustBeFreed == 1)
@@ -3101,7 +3066,7 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
/* there is no point in continuing, we may even otherwise render the
* error message unreadable. rgerhards, 2007-07-10
*/
- dbgprintf("invalid property id: '%d'\n", propid);
+ dbgprintf("invalid property id: '%d'\n", pProp->id);
*pbMustBeFreed = 0;
*pPropLen = sizeof("**INVALID PROPERTY NAME**") - 1;
return UCHAR_CONSTANT("**INVALID PROPERTY NAME**");
@@ -3709,80 +3674,6 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
}
-/* The function returns a json variable suitable for use with RainerScript.
- * Note: caller must free the returned string.
- * 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
- */
-static es_str_t*
-msgGetJSONVarNew(msg_t *pMsg, struct json_object *jroot, char *name)
-{
- uchar *leaf;
- char *val;
- es_str_t *estr = NULL;
- struct json_object *json, *parent;
-
- ISOBJ_TYPE_assert(pMsg, msg);
-
- if(jroot == NULL) {
- estr = es_newStr(1);
- goto done;
- }
- leaf = jsonPathGetLeaf((uchar*)name, strlen(name));
- if(jsonPathFindParent(jroot, (uchar*)name, leaf, &parent, 1) != RS_RET_OK) {
- estr = es_newStr(1);
- goto done;
- }
- json = json_object_object_get(parent, (char*)leaf);
- val = (char*)json_object_get_string(json);
- estr = es_newStrFromCStr(val, strlen(val));
-done:
- return estr;
-}
-
-es_str_t*
-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*
-msgGetMsgVarNew(msg_t *pThis, uchar *name)
-{
- rs_size_t propLen;
- uchar *pszProp = NULL;
- propid_t propid;
- unsigned short bMustBeFreed = 0;
- es_str_t *estr;
- es_str_t *propName;
-
- ISOBJ_TYPE_assert(pThis, msg);
-
- /* always call MsgGetProp() without a template specifier */
- /* TODO: optimize propNameToID() call -- rgerhards, 2009-06-26 */
- propNameStrToID(name, &propid);
- propName = es_newStrFromCStr((char*)name, ustrlen(name)); // TODO: optimize!
- pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, propName, &propLen, &bMustBeFreed, NULL);
- es_deleteStr(propName);
-
- estr = es_newStrFromCStr((char*)pszProp, propLen);
- if(bMustBeFreed)
- free(pszProp);
-
- return estr;
-}
-
-
/* 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
@@ -3968,9 +3859,8 @@ DBGPRINTF("AAAA jsonMerge adds '%s'\n", it.key);
/* find a JSON structure element (field or container doesn't matter). */
rsRetVal
-jsonFind(struct json_object *jroot, es_str_t *propName, struct json_object **jsonres)
+jsonFind(struct json_object *jroot, msgPropDescr_t *pProp, struct json_object **jsonres)
{
- uchar *name = NULL;
uchar *leaf;
struct json_object *parent;
struct json_object *field;
@@ -3981,31 +3871,39 @@ jsonFind(struct json_object *jroot, es_str_t *propName, struct json_object **jso
goto finalize_it;
}
- if(!es_strbufcmp(propName, (uchar*)"!", 1)) {
+ if(!strcmp((char*)pProp->name, "!")) {
field = jroot;
} else {
- name = (uchar*)es_str2cstr(propName, NULL);
- leaf = jsonPathGetLeaf(name, ustrlen(name));
- CHKiRet(jsonPathFindParent(jroot, name, leaf, &parent, 0));
+ leaf = jsonPathGetLeaf(pProp->name, pProp->nameLen);
+ CHKiRet(jsonPathFindParent(jroot, pProp->name, leaf, &parent, 0));
field = json_object_object_get(parent, (char*)leaf);
}
*jsonres = field;
finalize_it:
- free(name);
RETiRet;
}
-static rsRetVal
-msgAddJSONObj(msg_t *pM, uchar *name, struct json_object *json, struct json_object **pjroot)
+rsRetVal
+msgAddJSON(msg_t *pM, uchar *name, struct json_object *json)
{
/* TODO: error checks! This is a quick&dirty PoC! */
+ struct json_object **pjroot;
struct json_object *parent, *leafnode;
uchar *leaf;
DEFiRet;
MsgLock(pM);
- if((name[0] == '!' || name[0] == '.' || name[0] == '/') && name[1] == '\0') {
+ if(name[0] == '!') {
+ pjroot = &pM->json;
+ } else if(name[0] == '.') {
+ pjroot = &pM->localvars;
+ } else { /* globl var */
+ pthread_rwlock_wrlock(&glblVars_rwlock);
+ pjroot = &global_var_root;
+ }
+
+ if(name[1] == '\0') { /* full tree? */
if(*pjroot == NULL)
*pjroot = json;
else
@@ -4054,26 +3952,40 @@ msgAddJSONObj(msg_t *pM, uchar *name, struct json_object *json, struct json_obje
}
finalize_it:
+ if(name[0] == '/')
+ pthread_rwlock_unlock(&glblVars_rwlock);
MsgUnlock(pM);
RETiRet;
}
-rsRetVal
-msgAddJSON(msg_t *pM, uchar *name, struct json_object *json) {
- return msgAddJSONObj(pM, name, json, &pM->json);
-}
rsRetVal
-msgDelJSONVar(msg_t *pM, struct json_object **jroot, uchar *name)
+msgDelJSON(msg_t *pM, uchar *name)
{
+ struct json_object **jroot;
struct json_object *parent, *leafnode;
uchar *leaf;
DEFiRet;
dbgprintf("AAAA: unset variable '%s'\n", name);
MsgLock(pM);
- if((name[0] == '!' || name[0] == '.' || name[0] == '/') && name[1] == '\0') {
- /* strange, but I think we should permit this. After all,
+
+ if(name[0] == '!') {
+ jroot = &pM->json;
+ } else if(name[0] == '.') {
+ jroot = &pM->localvars;
+ } else { /* globl var */
+ pthread_rwlock_wrlock(&glblVars_rwlock);
+ jroot = &global_var_root;
+ }
+ if(jroot == NULL) {
+ DBGPRINTF("msgDelJSONVar; jroot empty in unset for property %s\n",
+ name);
+ FINALIZE;
+ }
+
+ if(name[1] == '\0') {
+ /* full tree! 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");
@@ -4100,16 +4012,12 @@ DBGPRINTF("AAAA: unset found JSON value path '%s', " "leaf '%s', leafnode %p\n",
}
finalize_it:
+ if(name[0] == '/')
+ pthread_rwlock_unlock(&glblVars_rwlock);
MsgUnlock(pM);
RETiRet;
}
-rsRetVal
-msgDelJSON(msg_t *pM, uchar *name)
-{
- return msgDelJSONVar(pM, &pM->json, name);
-}
-
static struct json_object *
jsonDeepCopy(struct json_object *src)
{
@@ -4187,16 +4095,8 @@ msgSetJSONFromVar(msg_t *pMsg, uchar *varname, struct var *v)
v->datatype);
ABORT_FINALIZE(RS_RET_ERR);
}
- /* we always know strlen(varname) > 2 */
- if(varname[1] == '!')
- msgAddJSONObj(pMsg, varname+1, json, &pMsg->json);
- else if(varname[1] == '.')
- msgAddJSONObj(pMsg, varname+1, json, &pMsg->localvars);
- else { /* global - '/' */
- pthread_rwlock_wrlock(&glblVars_rwlock);
- msgAddJSONObj(pMsg, varname+1, json, &global_var_root);
- pthread_rwlock_unlock(&glblVars_rwlock);
- }
+
+ msgAddJSON(pMsg, varname, json);
finalize_it:
RETiRet;
}
@@ -4222,6 +4122,49 @@ finalize_it:
}
+/* Fill a message propert description. Space must already be alloced
+ * by the caller. This is for efficiency, as we expect this to happen
+ * as part of a larger structure alloc.
+ * Note that CEE/LOCAL_VAR properties can come in either as
+ * "$!xx"/"$.xx" or "!xx"/".xx" - we will unify them here.
+ */
+rsRetVal
+msgPropDescrFill(msgPropDescr_t *pProp, uchar *name, int nameLen)
+{
+ propid_t id;
+ int offs;
+ DEFiRet;
+ if(propNameToID(name, &id) != RS_RET_OK) {
+ parser_errmsg("invalid property '%s'", name);
+ ABORT_FINALIZE(RS_RET_INVLD_PROP);
+ }
+ if(id == PROP_CEE || id == PROP_LOCAL_VAR || id == PROP_GLOBAL_VAR) {
+ /* in these cases, we need the field name for later processing */
+ /* normalize name: remove $ if present */
+ offs = (name[0] == '$') ? 1 : 0;
+ pProp->name = ustrdup(name + offs);
+ pProp->nameLen = nameLen - offs;
+ /* we patch the root name, so that support functions do not need to
+ * check for different root chars. */
+ pProp->name[0] = '!';
+ }
+ pProp->id = id;
+finalize_it:
+ RETiRet;
+}
+
+void
+msgPropDescrDestruct(msgPropDescr_t *pProp)
+{
+ if(pProp != NULL) {
+ if(pProp->id == PROP_CEE ||
+ pProp->id == PROP_LOCAL_VAR ||
+ pProp->id == PROP_GLOBAL_VAR)
+ free(pProp->name);
+ }
+}
+
+
/* dummy */
rsRetVal msgQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; }
diff --git a/runtime/msg.h b/runtime/msg.h
index ed15622a..a2392a20 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -3,7 +3,7 @@
*
* File begun on 2007-07-13 by RGerhards (extracted from syslogd.c)
*
- * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007-2013 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@@ -183,21 +183,14 @@ void MsgSetMSGoffs(msg_t *pMsg, short offs);
void MsgSetRawMsgWOSize(msg_t *pMsg, char* pszRawMsg);
void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg, size_t lenMsg);
rsRetVal MsgReplaceMSG(msg_t *pThis, uchar* pszMSG, int lenMSG);
-uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
- propid_t propid, es_str_t *propName,
+uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, msgPropDescr_t *pProp,
rs_size_t *pPropLen, unsigned short *pbMustBeFreed, struct syslogTime *ttNow);
-rsRetVal msgGetMsgVar(msg_t *pThis, cstr_t *pstrPropName, var_t **ppVar);
-es_str_t* msgGetMsgVarNew(msg_t *pThis, uchar *name);
uchar *getRcvFrom(msg_t *pM);
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);
-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);
rsRetVal MsgDeserialize(msg_t *pMsg, strm_t *pStrm);
@@ -213,20 +206,16 @@ char *getHOSTNAME(msg_t *pM);
int getHOSTNAMELen(msg_t *pM);
uchar *getProgramName(msg_t *pM, sbool bLockMutex);
uchar *getRcvFrom(msg_t *pM);
-rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID);
+rsRetVal propNameToID(uchar *pName, propid_t *pPropID);
uchar *propIDToName(propid_t propID);
-rsRetVal msgGetCEEPropJSON(msg_t *pM, es_str_t *propName, struct json_object **pjson);
-rsRetVal getGlobalVarPropVal( es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed);
-rsRetVal msgGetLocalVarJSON(msg_t *pM, es_str_t *propName, struct json_object **pjson);
-rsRetVal msgGetGlobalVarJSON(es_str_t *propName, struct json_object **pjson);
+rsRetVal msgGetJSONPropJSON(msg_t *pMsg, msgPropDescr_t *pProp, struct json_object **pjson);
+rsRetVal getJSONPropVal(msg_t *pMsg, msgPropDescr_t *pProp, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed);
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);
+rsRetVal jsonFind(struct json_object *jroot, msgPropDescr_t *pProp, struct json_object **jsonres);
-static inline rsRetVal
-msgUnsetJSON(msg_t *pMsg, uchar *varname) {
- return msgDelJSON(pMsg, varname+1);
-}
+rsRetVal msgPropDescrFill(msgPropDescr_t *pProp, uchar *name, int nameLen);
+void msgPropDescrDestruct(msgPropDescr_t *pProp);
static inline int
msgGetProtocolVersion(msg_t *pM)
diff --git a/runtime/rsconf.c b/runtime/rsconf.c
index 6c7c5fd5..8c808786 100644
--- a/runtime/rsconf.c
+++ b/runtime/rsconf.c
@@ -254,92 +254,6 @@ CODESTARTobjDebugPrint(rsconf)
ENDobjDebugPrint(rsconf)
-/* This function returns the current date in different
- * variants. It is used to construct the $NOW series of
- * system properties. The returned buffer must be freed
- * by the caller when no longer needed. If the function
- * can not allocate memory, it returns a NULL pointer.
- * TODO: this was taken from msg.c and we should consolidate it with the code
- * there. This is especially important when we increase the number of system
- * variables (what we definitely want to do).
- */
-typedef enum ENOWType { NOW_NOW, NOW_YEAR, NOW_MONTH, NOW_DAY, NOW_HOUR, NOW_MINUTE } eNOWType;
-static rsRetVal
-getNOW(eNOWType eNow, es_str_t **estr)
-{
- DEFiRet;
- uchar szBuf[16];
- struct syslogTime t;
- es_size_t len;
-
- datetime.getCurrTime(&t, NULL);
- switch(eNow) {
- case NOW_NOW:
- len = snprintf((char*) szBuf, sizeof(szBuf)/sizeof(uchar),
- "%4.4d-%2.2d-%2.2d", t.year, t.month, t.day);
- break;
- case NOW_YEAR:
- len = snprintf((char*) szBuf, sizeof(szBuf)/sizeof(uchar), "%4.4d", t.year);
- break;
- case NOW_MONTH:
- len = snprintf((char*) szBuf, sizeof(szBuf)/sizeof(uchar), "%2.2d", t.month);
- break;
- case NOW_DAY:
- len = snprintf((char*) szBuf, sizeof(szBuf)/sizeof(uchar), "%2.2d", t.day);
- break;
- case NOW_HOUR:
- len = snprintf((char*) szBuf, sizeof(szBuf)/sizeof(uchar), "%2.2d", t.hour);
- break;
- case NOW_MINUTE:
- len = snprintf((char*) szBuf, sizeof(szBuf)/sizeof(uchar), "%2.2d", t.minute);
- break;
- default:
- len = snprintf((char*) szBuf, sizeof(szBuf)/sizeof(uchar), "*invld eNow*");
- break;
- }
-
- /* now create a string object out of it and hand that over to the var */
- *estr = es_newStrFromCStr((char*)szBuf, len);
-
- RETiRet;
-}
-
-
-
-static inline es_str_t *
-getSysVar(char *name)
-{
- es_str_t *estr = NULL;
- rsRetVal iRet = RS_RET_OK;
-
- if(!strcmp(name, "now")) {
- CHKiRet(getNOW(NOW_NOW, &estr));
- } else if(!strcmp(name, "year")) {
- CHKiRet(getNOW(NOW_YEAR, &estr));
- } else if(!strcmp(name, "month")) {
- CHKiRet(getNOW(NOW_MONTH, &estr));
- } else if(!strcmp(name, "day")) {
- CHKiRet(getNOW(NOW_DAY, &estr));
- } else if(!strcmp(name, "hour")) {
- CHKiRet(getNOW(NOW_HOUR, &estr));
- } else if(!strcmp(name, "minute")) {
- CHKiRet(getNOW(NOW_MINUTE, &estr));
- } else if(!strcmp(name, "myhostname")) {
- char *hn = (char*)glbl.GetLocalHostName();
- estr = es_newStrFromCStr(hn, strlen(hn));
- } else {
- ABORT_FINALIZE(RS_RET_SYSVAR_NOT_FOUND);
- }
-finalize_it:
- if(iRet != RS_RET_OK) {
- dbgprintf("getSysVar error iRet %d\n", iRet);
- if(estr == NULL)
- estr = es_newStrFromCStr("*ERROR*", sizeof("*ERROR*") - 1);
- }
- return estr;
-}
-
-
/* Process input() objects */
rsRetVal
inputProcessCnf(struct cnfobj *o)
@@ -479,30 +393,6 @@ void cnfDoBSDHost(char *ln)
"solution (Block '%s')", ln);
free(ln);
}
-
-es_str_t*
-cnfGetVar(char *name, void *usrptr)
-{
- es_str_t *estr;
- if(name[0] == '$') {
- if(name[1] == '$')
- estr = getSysVar(name+2);
- else if(name[1] == '!')
- estr = msgGetCEEVarNew((msg_t*) usrptr, name+2);
- else
- estr = msgGetMsgVarNew((msg_t*) usrptr, (uchar*)name);
- } else { /* if this happens, we have a program logic error */
- estr = es_newStrFromCStr("err: var must start with $",
- sizeof("err: var must start with $")-1);
- }
- if(Debug) {
- char *s;
- s = es_str2cstr(estr, NULL);
- dbgprintf("rainerscript: var '%s': '%s'\n", name, s);
- free(s);
- }
- return estr;
-}
/*------------------------------ end interface to flex/bison parser ------------------------------*/
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index 85381b8d..edf0c593 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -102,52 +102,6 @@
#define _PATH_CONSOLE "/dev/console"
#endif
-/* properties are now encoded as (tiny) integers. I do not use an enum as I would like
- * to keep the memory footprint small (and thus cache hits high).
- * rgerhards, 2009-06-26
- */
-typedef uintTiny propid_t;
-#define PROP_INVALID 0
-#define PROP_MSG 1
-#define PROP_TIMESTAMP 2
-#define PROP_HOSTNAME 3
-#define PROP_SYSLOGTAG 4
-#define PROP_RAWMSG 5
-#define PROP_INPUTNAME 6
-#define PROP_FROMHOST 7
-#define PROP_FROMHOST_IP 8
-#define PROP_PRI 9
-#define PROP_PRI_TEXT 10
-#define PROP_IUT 11
-#define PROP_SYSLOGFACILITY 12
-#define PROP_SYSLOGFACILITY_TEXT 13
-#define PROP_SYSLOGSEVERITY 14
-#define PROP_SYSLOGSEVERITY_TEXT 15
-#define PROP_TIMEGENERATED 16
-#define PROP_PROGRAMNAME 17
-#define PROP_PROTOCOL_VERSION 18
-#define PROP_STRUCTURED_DATA 19
-#define PROP_APP_NAME 20
-#define PROP_PROCID 21
-#define PROP_MSGID 22
-#define PROP_PARSESUCCESS 23
-#define PROP_SYS_NOW 150
-#define PROP_SYS_YEAR 151
-#define PROP_SYS_MONTH 152
-#define PROP_SYS_DAY 153
-#define PROP_SYS_HOUR 154
-#define PROP_SYS_HHOUR 155
-#define PROP_SYS_QHOUR 156
-#define PROP_SYS_MINUTE 157
-#define PROP_SYS_MYHOSTNAME 158
-#define PROP_SYS_BOM 159
-#define PROP_SYS_UPTIME 160
-#define PROP_UUID 161
-#define PROP_CEE 200
-#define PROP_CEE_ALL_JSON 201
-#define PROP_LOCAL_VAR 202
-#define PROP_GLOBAL_VAR 203
-
/* The error codes below are orginally "borrowed" from
* liblogging. As such, we reserve values up to -2999
@@ -401,7 +355,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_RULESET_EXISTS = -2306,/**< ruleset already exists */
RS_RET_DEPRECATED = -2307,/**< deprecated functionality is used */
RS_RET_DS_PROP_SEQ_ERR = -2308,/**< property sequence error deserializing object */
- RS_RET_TPL_INVLD_PROP = -2309,/**< property name error in template (unknown name) */
+ RS_RET_INVLD_PROP = -2309,/**< property name error (unknown name) */
RS_RET_NO_RULEBASE = -2310,/**< mmnormalize: rulebase can not be found or otherwise invalid */
RS_RET_INVLD_MODE = -2311,/**< invalid mode specified in configuration */
RS_RET_INVLD_ANON_BITS = -2312,/**< mmanon: invalid number of bits to anonymize specified */
diff --git a/runtime/ruleset.c b/runtime/ruleset.c
index dae5bbaa..15e9e5ea 100644
--- a/runtime/ruleset.c
+++ b/runtime/ruleset.c
@@ -261,7 +261,7 @@ execUnset(struct cnfstmt *stmt, batch_t *pBatch, sbool *active)
for(i = 0 ; i < batchNumMsgs(pBatch) && !*(pBatch->pbShutdownImmediate) ; ++i) {
if( pBatch->eltState[i] != BATCH_STATE_DISC
&& (active == NULL || active[i])) {
- msgUnsetJSON(pBatch->pElem[i].pMsg, stmt->d.s_unset.varname);
+ msgDelJSON(pBatch->pElem[i].pMsg, stmt->d.s_unset.varname);
}
}
RETiRet;
@@ -392,12 +392,11 @@ evalPROPFILT(struct cnfstmt *stmt, msg_t *pMsg)
int bRet = 0;
rs_size_t propLen;
- if(stmt->d.s_propfilt.propID == PROP_INVALID)
+ if(stmt->d.s_propfilt.prop.id == PROP_INVALID)
goto done;
- pszPropVal = MsgGetProp(pMsg, NULL, stmt->d.s_propfilt.propID,
- stmt->d.s_propfilt.propName, &propLen,
- &pbMustBeFreed, NULL);
+ pszPropVal = MsgGetProp(pMsg, NULL, &stmt->d.s_propfilt.prop,
+ &propLen, &pbMustBeFreed, NULL);
/* Now do the compares (short list currently ;)) */
switch(stmt->d.s_propfilt.operation ) {
@@ -441,25 +440,18 @@ evalPROPFILT(struct cnfstmt *stmt, msg_t *pMsg)
bRet = (bRet == 1) ? 0 : 1;
if(Debug) {
- char *cstr;
- if(stmt->d.s_propfilt.propID == PROP_CEE) {
- cstr = es_str2cstr(stmt->d.s_propfilt.propName, NULL);
+ if(stmt->d.s_propfilt.prop.id == PROP_CEE) {
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);
+ stmt->d.s_propfilt.prop.name, pszPropVal);
+ } else if(stmt->d.s_propfilt.prop.id == PROP_LOCAL_VAR) {
DBGPRINTF("Filter: check for local var '%s' (value '%s') ",
- cstr, pszPropVal);
- free(cstr);
- } else if(stmt->d.s_propfilt.propID == PROP_GLOBAL_VAR) {
- cstr = es_str2cstr(stmt->d.s_propfilt.propName, NULL);
- DBGPRINTF("Filter: check for global var '%s' (value '%s') ",
- cstr, pszPropVal);
- free(cstr);
+ stmt->d.s_propfilt.prop.name, pszPropVal);
+ //} else if(stmt->d.s_propfilt.propID == PROP_GLOBAL_VAR) {
+ //DBGPRINTF("Filter: check for global var '%s' (value '%s') ",
+ //stmt->d.s_propfilt.propName, pszPropVal);
} else {
DBGPRINTF("Filter: check for property '%s' (value '%s') ",
- propIDToName(stmt->d.s_propfilt.propID), pszPropVal);
+ propIDToName(stmt->d.s_propfilt.prop.id), pszPropVal);
}
if(stmt->d.s_propfilt.isNegated)
DBGPRINTF("NOT ");
diff --git a/runtime/ruleset.h b/runtime/ruleset.h
index cbf8243b..8bfd4920 100644
--- a/runtime/ruleset.h
+++ b/runtime/ruleset.h
@@ -2,7 +2,7 @@
*
* This implements rulesets within rsyslog.
*
- * Copyright 2009-2012 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2009-2013 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
diff --git a/runtime/typedefs.h b/runtime/typedefs.h
index a929b30c..2efd7d65 100644
--- a/runtime/typedefs.h
+++ b/runtime/typedefs.h
@@ -64,6 +64,7 @@ typedef struct nsdsel_ptcp_s nsdsel_ptcp_t;
typedef struct nsdsel_gtls_s nsdsel_gtls_t;
typedef struct nsdpoll_ptcp_s nsdpoll_ptcp_t;
typedef struct wti_s wti_t;
+typedef struct msgPropDescr_s msgPropDescr_t;
typedef struct msg msg_t;
typedef struct queue_s qqueue_t;
typedef struct prop_s prop_t;
@@ -163,6 +164,53 @@ typedef enum {
typedef off_t off64_t;
#endif
+
+/* properties are now encoded as (tiny) integers. I do not use an enum as I would like
+ * to keep the memory footprint small (and thus cache hits high).
+ * rgerhards, 2009-06-26
+ */
+typedef uintTiny propid_t;
+#define PROP_INVALID 0
+#define PROP_MSG 1
+#define PROP_TIMESTAMP 2
+#define PROP_HOSTNAME 3
+#define PROP_SYSLOGTAG 4
+#define PROP_RAWMSG 5
+#define PROP_INPUTNAME 6
+#define PROP_FROMHOST 7
+#define PROP_FROMHOST_IP 8
+#define PROP_PRI 9
+#define PROP_PRI_TEXT 10
+#define PROP_IUT 11
+#define PROP_SYSLOGFACILITY 12
+#define PROP_SYSLOGFACILITY_TEXT 13
+#define PROP_SYSLOGSEVERITY 14
+#define PROP_SYSLOGSEVERITY_TEXT 15
+#define PROP_TIMEGENERATED 16
+#define PROP_PROGRAMNAME 17
+#define PROP_PROTOCOL_VERSION 18
+#define PROP_STRUCTURED_DATA 19
+#define PROP_APP_NAME 20
+#define PROP_PROCID 21
+#define PROP_MSGID 22
+#define PROP_PARSESUCCESS 23
+#define PROP_SYS_NOW 150
+#define PROP_SYS_YEAR 151
+#define PROP_SYS_MONTH 152
+#define PROP_SYS_DAY 153
+#define PROP_SYS_HOUR 154
+#define PROP_SYS_HHOUR 155
+#define PROP_SYS_QHOUR 156
+#define PROP_SYS_MINUTE 157
+#define PROP_SYS_MYHOSTNAME 158
+#define PROP_SYS_BOM 159
+#define PROP_SYS_UPTIME 160
+#define PROP_UUID 161
+#define PROP_CEE 200
+#define PROP_CEE_ALL_JSON 201
+#define PROP_LOCAL_VAR 202
+#define PROP_GLOBAL_VAR 203
+
/* types of configuration handlers
*/
typedef enum cslCmdHdlrType {
@@ -213,6 +261,13 @@ struct multi_submit_s {
msg_t **ppMsgs;
};
+/* the following structure is a helper to describe a message property */
+struct msgPropDescr_s {
+ propid_t id;
+ uchar *name; /* name and lenName are only set for dynamic */
+ int nameLen; /* properties (JSON) */
+};
+
#endif /* multi-include protection */
/* vim:set ai:
*/