summaryrefslogtreecommitdiffstats
path: root/runtime/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/msg.c')
-rw-r--r--runtime/msg.c254
1 files changed, 206 insertions, 48 deletions
diff --git a/runtime/msg.c b/runtime/msg.c
index 187f0c22..f1f7997c 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -39,7 +39,9 @@
#include <sys/sysinfo.h>
#include <netdb.h>
#include <libestr.h>
-#include <libee/libee.h>
+#include <json/json.h>
+/* For struct json_object_iter, should not be necessary in future versions */
+#include <json/json_object_private.h>
#if HAVE_MALLOC_H
# include <malloc.h>
#endif
@@ -291,6 +293,8 @@ static pthread_mutex_t mutTrimCtr; /* mutex to handle malloc trim */
/* some forward declarations */
static int getAPPNAMELen(msg_t *pM, sbool bLockMutex);
+static rsRetVal jsonPathFindParent(msg_t *pM, uchar *name, uchar *leaf, struct json_object **parent, int bCreate);
+static uchar * jsonPathGetLeaf(uchar *name, int lenName);
/* The following functions will support advanced output module
@@ -740,7 +744,7 @@ static inline rsRetVal msgBaseConstruct(msg_t **ppThis)
pM->pRcvFromIP = NULL;
pM->rcvFrom.pRcvFrom = NULL;
pM->pRuleset = NULL;
- pM->event = NULL;
+ pM->json = NULL;
memset(&pM->tRcvdAt, 0, sizeof(pM->tRcvdAt));
memset(&pM->tTIMESTAMP, 0, sizeof(pM->tTIMESTAMP));
pM->TAG.pszTAG = NULL;
@@ -879,8 +883,8 @@ CODESTARTobjDestruct(msg)
rsCStrDestruct(&pThis->pCSPROCID);
if(pThis->pCSMSGID != NULL)
rsCStrDestruct(&pThis->pCSMSGID);
- if(pThis->event != NULL)
- ee_deleteEvent(pThis->event);
+ if(pThis->json != NULL)
+ json_object_put(pThis->json);
if(pThis->pszUUID != NULL)
free(pThis->pszUUID);
# ifndef HAVE_ATOMIC_BUILTINS
@@ -2403,39 +2407,87 @@ static uchar *getNOW(eNOWType eNow)
#undef tmpBUFSIZE /* clean up */
-/* Get a CEE-Property from libee. This function probably should be
- * placed somewhere else, but this smells like a big restructuring
- * useful in any case. So for the time being, I'll simply leave the
- * function here, as the context seems good enough. -- rgerhards, 2010-12-01
- */
-static inline void
-getCEEPropVal(msg_t *pMsg, es_str_t *propName, uchar **pRes, int *buflen, unsigned short *pbMustBeFreed)
+/* Get a CEE-Property as string value*/
+static inline rsRetVal
+getCEEPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, int *buflen, unsigned short *pbMustBeFreed)
{
- es_str_t *str = NULL;
- int r;
+ uchar *name = NULL;
+ uchar *leaf;
+ struct json_object *parent;
+ struct json_object *field;
+ DEFiRet;
if(*pbMustBeFreed)
free(*pRes);
*pRes = NULL;
+dbgprintf("AAAA: enter getCEEPropVal\n");
+ // TODO: mutex?
+ if(pM->json == NULL) goto finalize_it;
- if(pMsg->event == NULL) goto finalize_it;
- r = ee_getEventFieldAsString(pMsg->event, propName, &str);
-
- if(r != EE_OK) {
- DBGPRINTF("msgGtCEEVar: libee error %d during ee_getEventFieldAsString\n", r);
- FINALIZE;
+ if(!es_strbufcmp(propName, (uchar*)"!", 1)) {
+ field = pM->json;
+ } else {
+ name = (uchar*)es_str2cstr(propName, NULL);
+dbgprintf("AAAA: name to search '%s'\n", name);
+ leaf = jsonPathGetLeaf(name, ustrlen(name));
+dbgprintf("AAAA: leaf '%s'\n", leaf);
+ CHKiRet(jsonPathFindParent(pM, name, leaf, &parent, 1));
+ field = json_object_object_get(parent, (char*)leaf);
+ }
+ if(field == 0) {
+ *pRes = (uchar*) "";
+ *pbMustBeFreed = 0;
+ } else {
+ *pRes = (uchar*) strdup(json_object_get_string(field));
+dbgprintf("AAAA: json_object_get_string() returns '%s'\n", *pRes);
+ *buflen = (int) ustrlen(*pRes);
+ *pbMustBeFreed = 1;
}
- *pRes = (unsigned char*) es_str2cstr(str, "#000");
- es_deleteStr(str);
- *buflen = (int) ustrlen(*pRes);
- *pbMustBeFreed = 1;
finalize_it:
+ free(name);
if(*pRes == NULL) {
/* could not find any value, so set it to empty */
*pRes = (unsigned char*)"";
*pbMustBeFreed = 0;
}
+ RETiRet;
+}
+
+
+/* Get a CEE-Property as native json object
+ */
+rsRetVal
+msgGetCEEPropJSON(msg_t *pM, es_str_t *propName, struct json_object **pjson)
+{
+ uchar *name = NULL;
+ uchar *leaf;
+ struct json_object *parent;
+ DEFiRet;
+
+dbgprintf("AAAA: enter getCEEPropJSON\n");
+ // TODO: mutex?
+ if(pM->json == NULL) {
+ ABORT_FINALIZE(RS_RET_NOT_FOUND);
+ }
+
+ if(!es_strbufcmp(propName, (uchar*)"!", 1)) {
+ *pjson = pM->json;
+ FINALIZE;
+ }
+ name = (uchar*)es_str2cstr(propName, NULL);
+dbgprintf("AAAA: name to search '%s'\n", name);
+ leaf = jsonPathGetLeaf(name, ustrlen(name));
+dbgprintf("AAAA: leaf '%s'\n", leaf);
+ CHKiRet(jsonPathFindParent(pM, 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);
+ RETiRet;
}
@@ -2648,7 +2700,6 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
uchar *pBuf;
int iLen;
short iOffs;
- es_str_t *str; /* for CEE handling, temp. string */
BEGINfunc
assert(pMsg != NULL);
@@ -2796,16 +2847,15 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
pRes = glbl.GetLocalHostName();
break;
case PROP_CEE_ALL_JSON:
- if(pMsg->event == NULL) {
- if(*pbMustBeFreed == 1)
- free(pRes);
- pRes = (uchar*) "{}";
- *pbMustBeFreed = 0;
+ if(pMsg->json == NULL) {
+ if(*pbMustBeFreed == 1)
+ free(pRes);
+ pRes = (uchar*) "{}";
+ bufLen = 2;
+ *pbMustBeFreed = 0;
} else {
- ee_fmtEventToJSON(pMsg->event, &str);
- pRes = (uchar*) es_str2cstr(str, "#000");
- es_deleteStr(str);
- *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */
+ pRes = (uchar*)strdup(json_object_get_string(pMsg->json));
+ *pbMustBeFreed = 1;
}
break;
case PROP_CEE:
@@ -3456,29 +3506,25 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
es_str_t*
msgGetCEEVarNew(msg_t *pMsg, char *name)
{
+ uchar *leaf;
+ char *val;
es_str_t *estr = NULL;
- es_str_t *epropName = NULL;
- struct ee_field *field;
+ struct json_object *json, *parent;
ISOBJ_TYPE_assert(pMsg, msg);
- if(pMsg->event == NULL) {
+ if(pMsg->json == NULL) {
estr = es_newStr(1);
goto done;
}
-
- epropName = es_newStrFromCStr(name, strlen(name)); // TODO: optimize (in grammar!)
- field = ee_getEventField(pMsg->event, epropName);
- if(field != NULL) {
- ee_getFieldAsString(field, &estr);
- }
- if(estr == NULL) {
- DBGPRINTF("msgGetCEEVar: error obtaining var (field=%p, var='%s')\n",
- field, name);
- estr = es_newStrFromCStr("*ERROR*", sizeof("*ERROR*") - 1);
+ leaf = jsonPathGetLeaf((uchar*)name, strlen(name));
+ if(jsonPathFindParent(pMsg, (uchar*)name, leaf, &parent, 1) != RS_RET_OK) {
+ estr = es_newStr(1);
+ goto done;
}
- es_deleteStr(epropName);
-
+ json = json_object_object_get(parent, (char*)leaf);
+ val = (char*)json_object_get_string(json);
+ estr = es_newStrFromCStr(val, strlen(val));
done:
return estr;
}
@@ -3613,6 +3659,118 @@ MsgGetSeverity(obj_t_ptr pThis, int *piSeverity)
}
+static uchar *
+jsonPathGetLeaf(uchar *name, int lenName)
+{
+ int i;
+ for(i = lenName ; name[i] != '!' && i >= 0 ; --i)
+ /* just skip */;
+ if(name[i] == '!')
+ ++i;
+ return name + i;
+}
+
+
+static rsRetVal
+jsonPathFindNext(struct json_object *root, uchar **name, uchar *leaf,
+ struct json_object **found, int bCreate)
+{
+ uchar namebuf[1024];
+ struct json_object *json;
+ size_t i;
+ uchar *p = *name;
+ DEFiRet;
+
+ if(*p == '!')
+ ++p;
+ for(i = 0 ; *p && *p != '!' && p != leaf && i < sizeof(namebuf)-1 ; ++i, ++p)
+ namebuf[i] = *p;
+ if(i == 0) {
+ namebuf[i] = '\0';
+ dbgprintf("AAAA: next JSONP elt: '%s'\n", namebuf);
+ json = json_object_object_get(root, (char*)namebuf);
+ } else
+ json = root;
+ if(json == NULL) {
+ if(!bCreate) {
+ ABORT_FINALIZE(RS_RET_JNAME_INVALID);
+ } else {
+ json = json_object_new_object();
+ json_object_object_add(root, (char*)namebuf, json);
+ }
+ }
+
+ *name = p;
+ *found = json;
+finalize_it:
+ RETiRet;
+}
+
+static rsRetVal
+jsonPathFindParent(msg_t *pM, uchar *name, uchar *leaf, struct json_object **parent, int bCreate)
+{
+ DEFiRet;
+ *parent = pM->json;
+ while(name < leaf-1) {
+ jsonPathFindNext(*parent, &name, leaf, parent, bCreate);
+dbgprintf("AAAA: name %p, leaf %p\n", name, leaf);
+ }
+ RETiRet;
+}
+
+static rsRetVal
+jsonMerge(struct json_object *existing, struct json_object *json)
+{
+ /* TODO: check & handle duplicate names */
+ DEFiRet;
+ struct json_object_iter it;
+
+ json_object_object_foreachC(json, it) {
+dbgprintf("AAAA jsonMerge adds '%s'\n", it.key);
+ json_object_object_add(existing, it.key,
+ json_object_get(it.val));
+ }
+ /* note: json-c does ref counting. We added all descandants refcounts
+ * in the loop above. So when we now free(_put) the root object, only
+ * root gets freed().
+ */
+ json_object_put(json);
+ RETiRet;
+}
+
+rsRetVal
+msgAddJSON(msg_t *pM, uchar *name, struct json_object *json)
+{
+ /* TODO: error checks! This is a quick&dirty PoC! */
+ struct json_object *parent, *leafnode;
+ uchar *leaf;
+ DEFiRet;
+
+ MsgLock(pM);
+ if(name[0] == '!' && name[1] == '\0') {
+ if(pM->json == NULL)
+ pM->json = json;
+ else
+ CHKiRet(jsonMerge(pM->json, json));
+ } else {
+ if(pM->json == NULL) {
+ /* now we need a root obj */
+ pM->json = json_object_new_object();
+ }
+ leaf = jsonPathGetLeaf(name, ustrlen(name));
+ CHKiRet(jsonPathFindParent(pM, name, leaf, &parent, 1));
+ leafnode = json_object_object_get(parent, (char*)leaf);
+ if(leafnode == NULL)
+ json_object_object_add(parent, (char*)leaf, json);
+ else
+ CHKiRet(jsonMerge(pM->json, json));
+ }
+
+finalize_it:
+ MsgUnlock(pM);
+ RETiRet;
+}
+
/* dummy */
rsRetVal msgQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; }