summaryrefslogtreecommitdiffstats
path: root/runtime/msg.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2013-07-23 12:58:09 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2013-07-23 12:58:09 +0200
commit55452f4caaa47f90b9b921547a4567f5ea512977 (patch)
tree156a66f230918c99ac673e4a4ab69f7fb0d29013 /runtime/msg.c
parent18fc42beaf7419c4a134a4171352ebb0b151d425 (diff)
parent5939bf92784b5af5ebf4ae19c737d7ea1cb80d8d (diff)
downloadrsyslog-55452f4caaa47f90b9b921547a4567f5ea512977.tar.gz
rsyslog-55452f4caaa47f90b9b921547a4567f5ea512977.tar.bz2
rsyslog-55452f4caaa47f90b9b921547a4567f5ea512977.zip
Merge branch 'master-globalvars'
Diffstat (limited to 'runtime/msg.c')
-rw-r--r--runtime/msg.c64
1 files changed, 54 insertions, 10 deletions
diff --git a/runtime/msg.c b/runtime/msg.c
index 73fa0367..c7cd9406 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -66,6 +66,12 @@
#include "var.h"
#include "rsconf.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
+ */
+static pthread_rwlock_t glblVars_rwlock;
+struct json_object *global_var_root = NULL;
+
/* static data */
DEFobjStaticHelpers
DEFobjCurrIf(datetime)
@@ -539,11 +545,14 @@ propNameStrToID(uchar *pName, propid_t *pPropID)
*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 {
+ DBGPRINTF("PROP_INVALID for name '%s'\n", pName);
*pPropID = PROP_INVALID;
iRet = RS_RET_VAR_NOT_FOUND;
}
@@ -639,6 +648,8 @@ 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:
@@ -2584,6 +2595,16 @@ getLocalVarPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, rs_size_t *bufle
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
@@ -2628,6 +2649,16 @@ 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
* if and only if escaping is needed.
@@ -3028,6 +3059,9 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
case PROP_LOCAL_VAR:
getLocalVarPropVal(pMsg, propName, &pRes, &bufLen, pbMustBeFreed);
break;
+ case PROP_GLOBAL_VAR:
+ getGlobalVarPropVal(propName, &pRes, &bufLen, pbMustBeFreed);
+ break;
case PROP_SYS_BOM:
if(*pbMustBeFreed == 1)
free(pRes);
@@ -3750,13 +3784,16 @@ msgGetMsgVarNew(msg_t *pThis, uchar *name)
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);
- pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, NULL, &propLen, &bMustBeFreed, NULL);
+ propName = es_newStrFromCStr((char*)name+1, ustrlen(name)-1); // TODO: optimize!
+ pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, propName, &propLen, &bMustBeFreed, NULL);
+ es_deleteStr(propName);
estr = es_newStrFromCStr((char*)pszProp, propLen);
if(bMustBeFreed)
@@ -3869,13 +3906,13 @@ jsonPathGetLeaf(uchar *name, int lenName)
int i;
for(i = lenName ; i >= 0 ; --i)
if(i == 0) {
- if(name[0] == '.' || name[0] == '!')
+ if(name[0] == '!' || name[0] == '.' || name[0] == '/')
break;
} else {
if(name[i] == '!')
break;
}
- if(name[i] == '!' || name[i] == '.')
+ if(name[i] == '!' || name[i] == '.' || name[i] == '/')
++i;
return name + i;
}
@@ -3891,9 +3928,9 @@ jsonPathFindNext(struct json_object *root, uchar *namestart, uchar **name, uchar
uchar *p = *name;
DEFiRet;
- if(*p == '!' || (*name == namestart && *p == '.'))
+ if(*p == '!' || (*name == namestart && (*p == '.' || *p == '/')))
++p;
- for(i = 0 ; *p && !(p == namestart && *p == '.') && *p != '!' && p != leaf && i < sizeof(namebuf)-1 ; ++i, ++p)
+ for(i = 0 ; *p && !(p == namestart && (*p == '.' || *p == '/')) && *p != '!' && p != leaf && i < sizeof(namebuf)-1 ; ++i, ++p)
namebuf[i] = *p;
if(i > 0) {
namebuf[i] = '\0';
@@ -3988,7 +4025,7 @@ msgAddJSONObj(msg_t *pM, uchar *name, struct json_object *json, struct json_obje
DEFiRet;
MsgLock(pM);
- if((name[0] == '!' || name[0] == '.') && name[1] == '\0') {
+ if((name[0] == '!' || name[0] == '.' || name[0] == '/') && name[1] == '\0') {
if(*pjroot == NULL)
*pjroot = json;
else
@@ -4049,7 +4086,7 @@ msgDelJSONVar(msg_t *pM, struct json_object **jroot, uchar *name)
dbgprintf("AAAA: unset variable '%s'\n", name);
MsgLock(pM);
- if((name[0] == '!' || name[0] == '.') && name[1] == '\0') {
+ if((name[0] == '!' || 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.
*/
@@ -4157,10 +4194,15 @@ msgSetJSONFromVar(msg_t *pMsg, uchar *varname, struct var *v)
ABORT_FINALIZE(RS_RET_ERR);
}
/* we always know strlen(varname) > 2 */
- if(varname[1] == '.')
- msgAddJSONObj(pMsg, varname+1, json, &pMsg->localvars);
- else
+ 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);
+ }
finalize_it:
RETiRet;
}
@@ -4173,6 +4215,8 @@ rsRetVal msgQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; }
* rgerhards, 2008-01-04
*/
BEGINObjClassInit(msg, 1, OBJ_IS_CORE_MODULE)
+ pthread_rwlock_init(&glblVars_rwlock, NULL);
+
/* request objects we use */
CHKiRet(objUse(datetime, CORE_COMPONENT));
CHKiRet(objUse(glbl, CORE_COMPONENT));