From 572241c51e547c681f6eb06f6602e51b9a779b9b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 21 Oct 2013 14:07:22 +0200 Subject: prep work to support one-char variable namepaces --- runtime/msg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index e159bba9..2e5d9358 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -534,16 +534,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; -- cgit v1.2.3 From f4f2a493b05b5d3247994769325598655afe7fe0 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 21 Oct 2013 17:12:07 +0200 Subject: work a bit toward string handling unification --- runtime/msg.c | 79 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 43 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 2e5d9358..c7e2bcc6 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -2538,9 +2538,8 @@ 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) +getJSONPropVal(struct json_object *jroot, uchar *propName, int propNameLen, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) { - uchar *name = NULL; uchar *leaf; struct json_object *parent; struct json_object *field; @@ -2549,15 +2548,15 @@ getJSONPropVal(struct json_object *jroot, es_str_t *propName, uchar **pRes, rs_s if(*pbMustBeFreed) free(*pRes); *pRes = NULL; - // TODO: mutex? if(jroot == NULL) goto finalize_it; - if(!es_strbufcmp(propName, (uchar*)"!", 1)) { + if(!strcmp((char*)propName, "!") || + !strcmp((char*)propName, ".") || + !strcmp((char*)propName, "/") ) { 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(propName, propNameLen); + CHKiRet(jsonPathFindParent(jroot, propName+1, leaf, &parent, 1)); field = json_object_object_get(parent, (char*)leaf); } if(field != NULL) { @@ -2567,7 +2566,6 @@ getJSONPropVal(struct json_object *jroot, es_str_t *propName, uchar **pRes, rs_s } finalize_it: - free(name); if(*pRes == NULL) { /* could not find any value, so set it to empty */ *pRes = (unsigned char*)""; @@ -2577,23 +2575,23 @@ finalize_it: } rsRetVal -getCEEPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) +getCEEPropVal(msg_t *pM, uchar *propName, int propNameLen, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) { - return getJSONPropVal(pM->json, propName, pRes, buflen, pbMustBeFreed); + return getJSONPropVal(pM->json, propName, propNameLen, pRes, buflen, pbMustBeFreed); } rsRetVal -getLocalVarPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) +getLocalVarPropVal(msg_t *pM, uchar *propName, int propNameLen, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) { - return getJSONPropVal(pM->localvars, propName, pRes, buflen, pbMustBeFreed); + return getJSONPropVal(pM->localvars, propName, propNameLen, pRes, buflen, pbMustBeFreed); } rsRetVal -getGlobalVarPropVal( es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) +getGlobalVarPropVal(uchar *propName, int propNameLen, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) { DEFiRet; pthread_rwlock_rdlock(&glblVars_rwlock); - iRet = getJSONPropVal(global_var_root, propName, pRes, buflen, pbMustBeFreed); + iRet = getJSONPropVal(global_var_root, propName, propNameLen, pRes, buflen, pbMustBeFreed); pthread_rwlock_unlock(&glblVars_rwlock); RETiRet; } @@ -2601,53 +2599,51 @@ getGlobalVarPropVal( es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsign /* Get a JSON-based-variable as native json object */ rsRetVal -msgGetJSONPropJSON(struct json_object *jroot, es_str_t *propName, struct json_object **pjson) +msgGetJSONPropJSON(struct json_object *jroot, uchar *propName, int propNameLen, struct json_object **pjson) { - uchar *name = NULL; uchar *leaf; struct json_object *parent; DEFiRet; - // TODO: mutex? if(jroot == NULL) { ABORT_FINALIZE(RS_RET_NOT_FOUND); } - if(!es_strbufcmp(propName, (uchar*)"!", 1)) { + if(!strcmp((char*)propName, "!") || + !strcmp((char*)propName, ".") || + !strcmp((char*)propName, "/") ) { *pjson = jroot; FINALIZE; } - name = (uchar*)es_str2cstr(propName, NULL); - leaf = jsonPathGetLeaf(name, ustrlen(name)); - CHKiRet(jsonPathFindParent(jroot, name, leaf, &parent, 1)); + leaf = jsonPathGetLeaf(propName, propNameLen); + CHKiRet(jsonPathFindParent(jroot, propName, 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; } rsRetVal -msgGetCEEPropJSON(msg_t *pM, es_str_t *propName, struct json_object **pjson) +msgGetCEEPropJSON(msg_t *pM, uchar *propName, int propNameLen, struct json_object **pjson) { - return msgGetJSONPropJSON(pM->json, propName, pjson); + return msgGetJSONPropJSON(pM->json, propName, propNameLen, pjson); } rsRetVal -msgGetLocalVarJSON(msg_t *pM, es_str_t *propName, struct json_object **pjson) +msgGetLocalVarJSON(msg_t *pM, uchar *propName, int propNameLen, struct json_object **pjson) { - return msgGetJSONPropJSON(pM->localvars, propName, pjson); + return msgGetJSONPropJSON(pM->localvars, propName, propNameLen, pjson); } rsRetVal -msgGetGlobalVarJSON(es_str_t *propName, struct json_object **pjson) +msgGetGlobalVarJSON(uchar *propName, int propNameLen, struct json_object **pjson) { DEFiRet; pthread_rwlock_rdlock(&glblVars_rwlock); - iRet = msgGetJSONPropJSON(global_var_root, propName, pjson); + iRet = msgGetJSONPropJSON(global_var_root, propName, propNameLen, pjson); pthread_rwlock_unlock(&glblVars_rwlock); RETiRet; } @@ -2852,7 +2848,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, + propid_t propid, uchar *propName, int propNameLen, rs_size_t *pPropLen, unsigned short *pbMustBeFreed, struct syslogTime *ttNow) { uchar *pRes; /* result pointer */ @@ -3047,13 +3043,13 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, } break; case PROP_CEE: - getCEEPropVal(pMsg, propName, &pRes, &bufLen, pbMustBeFreed); + getCEEPropVal(pMsg, propName, propNameLen, &pRes, &bufLen, pbMustBeFreed); break; case PROP_LOCAL_VAR: - getLocalVarPropVal(pMsg, propName, &pRes, &bufLen, pbMustBeFreed); + getLocalVarPropVal(pMsg, propName, propNameLen, &pRes, &bufLen, pbMustBeFreed); break; case PROP_GLOBAL_VAR: - getGlobalVarPropVal(propName, &pRes, &bufLen, pbMustBeFreed); + getGlobalVarPropVal(propName, propNameLen, &pRes, &bufLen, pbMustBeFreed); break; case PROP_SYS_BOM: if(*pbMustBeFreed == 1) @@ -3777,16 +3773,14 @@ 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 */ +#warning remove strlen() ? 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); + pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, name, ustrlen(name), &propLen, &bMustBeFreed, NULL); estr = es_newStrFromCStr((char*)pszProp, propLen); if(bMustBeFreed) @@ -3981,9 +3975,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, uchar *propName, int propNameLen, struct json_object **jsonres) { - uchar *name = NULL; uchar *leaf; struct json_object *parent; struct json_object *field; @@ -3994,18 +3987,18 @@ 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*)propName, "!") || + !strcmp((char*)propName, ".") || + !strcmp((char*)propName, "/") ) { field = jroot; } else { - name = (uchar*)es_str2cstr(propName, NULL); - leaf = jsonPathGetLeaf(name, ustrlen(name)); - CHKiRet(jsonPathFindParent(jroot, name, leaf, &parent, 0)); + leaf = jsonPathGetLeaf(propName, propNameLen); + CHKiRet(jsonPathFindParent(jroot, propName, leaf, &parent, 0)); field = json_object_object_get(parent, (char*)leaf); } *jsonres = field; finalize_it: - free(name); RETiRet; } -- cgit v1.2.3 From 7a15d40a42d6f2b30b70cfee6b5435133ada9ac7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 21 Oct 2013 17:22:32 +0200 Subject: refactor: somewhat simplify property-name-to-id mapping --- runtime/msg.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index c7e2bcc6..4ff0bbb5 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -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")) { @@ -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) { @@ -3779,7 +3762,7 @@ msgGetMsgVarNew(msg_t *pThis, uchar *name) /* always call MsgGetProp() without a template specifier */ /* TODO: optimize propNameToID() call -- rgerhards, 2009-06-26 */ #warning remove strlen() ? - propNameStrToID(name, &propid); + propNameToID(name, &propid); pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, name, ustrlen(name), &propLen, &bMustBeFreed, NULL); estr = es_newStrFromCStr((char*)pszProp, propLen); -- cgit v1.2.3 From 7d39740b3d88dbd0432806e5f8da32c49cdb69f1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 22 Oct 2013 17:55:35 +0200 Subject: refactor: use common code for message property description processing in all cases except script var access -- this comes next... --- runtime/msg.c | 66 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 15 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 4ff0bbb5..b1b912a4 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -540,8 +540,6 @@ propNameToID(uchar *pName, propid_t *pPropID) *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; @@ -624,8 +622,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: @@ -2831,7 +2827,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, uchar *propName, int propNameLen, rs_size_t *pPropLen, + msgPropDescr_t *pProp, rs_size_t *pPropLen, unsigned short *pbMustBeFreed, struct syslogTime *ttNow) { uchar *pRes; /* result pointer */ @@ -2854,7 +2850,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); @@ -3026,13 +3022,10 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, } break; case PROP_CEE: - getCEEPropVal(pMsg, propName, propNameLen, &pRes, &bufLen, pbMustBeFreed); + getCEEPropVal(pMsg, pProp->name, pProp->nameLen, &pRes, &bufLen, pbMustBeFreed); break; case PROP_LOCAL_VAR: - getLocalVarPropVal(pMsg, propName, propNameLen, &pRes, &bufLen, pbMustBeFreed); - break; - case PROP_GLOBAL_VAR: - getGlobalVarPropVal(propName, propNameLen, &pRes, &bufLen, pbMustBeFreed); + getLocalVarPropVal(pMsg, pProp->name, pProp->nameLen, &pRes, &bufLen, pbMustBeFreed); break; case PROP_SYS_BOM: if(*pbMustBeFreed == 1) @@ -3093,7 +3086,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**"); @@ -3753,8 +3746,8 @@ msgGetMsgVarNew(msg_t *pThis, uchar *name) { rs_size_t propLen; uchar *pszProp = NULL; - propid_t propid; unsigned short bMustBeFreed = 0; + msgPropDescr_t mProp; es_str_t *estr; ISOBJ_TYPE_assert(pThis, msg); @@ -3762,8 +3755,8 @@ msgGetMsgVarNew(msg_t *pThis, uchar *name) /* always call MsgGetProp() without a template specifier */ /* TODO: optimize propNameToID() call -- rgerhards, 2009-06-26 */ #warning remove strlen() ? - propNameToID(name, &propid); - pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, name, ustrlen(name), &propLen, &bMustBeFreed, NULL); + msgPropDescrFill(&mProp, name, ustrlen(name)); + pszProp = (uchar*) MsgGetProp(pThis, NULL, &mProp, &propLen, &bMustBeFreed, NULL); estr = es_newStrFromCStr((char*)pszProp, propLen); if(bMustBeFreed) @@ -3882,6 +3875,7 @@ jsonPathGetLeaf(uchar *name, int lenName) if(name[i] == '!') break; } +dbgprintf("DDDD: jsonPAthGetLeaf: name '%s', lenNAme %d, i %d\n", name, lenName, i); if(name[i] == '!' || name[i] == '.' || name[i] == '/') ++i; return name + i; @@ -4197,6 +4191,48 @@ 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) { +#warning enable error messages + //errmsg.LogError(0, RS_RET_TPL_INVLD_PROP, "invalid property '%s'", + //pTpl->pszName, cstrGetSzStrNoNULL(pStrProp)); + ABORT_FINALIZE(RS_RET_INVLD_PROP); + } + if(id == PROP_CEE || id == PROP_LOCAL_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] = '!'; +dbgprintf("DDDD: setting porpname '%s' (offs %d)\n", pProp->name, offs); + } + pProp->id = id; +finalize_it: + RETiRet; +} + +void +msgPropDescrDestruct(msgPropDescr_t *pProp) +{ + if(pProp != NULL) { + free(pProp->name); + } +} + /* dummy */ rsRetVal msgQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; } -- cgit v1.2.3 From eb9adf9baad5dca9dc2f30f45dc6eaf7607ac8f8 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 13:08:56 +0200 Subject: refactor: simplify JSON variable access --- runtime/msg.c | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index b1b912a4..407fee72 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -2578,54 +2578,43 @@ getGlobalVarPropVal(uchar *propName, int propNameLen, uchar **pRes, rs_size_t *b /* Get a JSON-based-variable as native json object */ rsRetVal -msgGetJSONPropJSON(struct json_object *jroot, uchar *propName, int propNameLen, struct json_object **pjson) +msgGetJSONPropJSON(msg_t *pMsg, msgPropDescr_t *pProp, struct json_object **pjson) { + struct json_object *jroot; uchar *leaf; struct json_object *parent; DEFiRet; - if(jroot == NULL) { + 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(!strcmp((char*)propName, "!") || - !strcmp((char*)propName, ".") || - !strcmp((char*)propName, "/") ) { + if(!strcmp((char*)pProp->name, "!")) { *pjson = jroot; FINALIZE; } - leaf = jsonPathGetLeaf(propName, propNameLen); - CHKiRet(jsonPathFindParent(jroot, propName, 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: + if(pProp->id == PROP_GLOBAL_VAR) + pthread_rwlock_unlock(&glblVars_rwlock); RETiRet; } -rsRetVal -msgGetCEEPropJSON(msg_t *pM, uchar *propName, int propNameLen, struct json_object **pjson) -{ - return msgGetJSONPropJSON(pM->json, propName, propNameLen, pjson); -} - -rsRetVal -msgGetLocalVarJSON(msg_t *pM, uchar *propName, int propNameLen, struct json_object **pjson) -{ - return msgGetJSONPropJSON(pM->localvars, propName, propNameLen, pjson); -} - -rsRetVal -msgGetGlobalVarJSON(uchar *propName, int propNameLen, struct json_object **pjson) -{ - DEFiRet; - pthread_rwlock_rdlock(&glblVars_rwlock); - iRet = msgGetJSONPropJSON(global_var_root, propName, propNameLen, 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 -- cgit v1.2.3 From a7ba3df55c3283da23ac202d13ed266cc3f0d02f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 14:21:14 +0200 Subject: fix potential segfault introduced by last refactoring --- runtime/msg.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 407fee72..1fe390c6 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -2597,6 +2597,11 @@ msgGetJSONPropJSON(msg_t *pMsg, msgPropDescr_t *pProp, struct json_object **pjso 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(!strcmp((char*)pProp->name, "!")) { *pjson = jroot; @@ -3864,7 +3869,6 @@ jsonPathGetLeaf(uchar *name, int lenName) if(name[i] == '!') break; } -dbgprintf("DDDD: jsonPAthGetLeaf: name '%s', lenNAme %d, i %d\n", name, lenName, i); if(name[i] == '!' || name[i] == '.' || name[i] == '/') ++i; return name + i; @@ -4207,7 +4211,6 @@ msgPropDescrFill(msgPropDescr_t *pProp, uchar *name, int nameLen) /* we patch the root name, so that support functions do not need to * check for different root chars. */ pProp->name[0] = '!'; -dbgprintf("DDDD: setting porpname '%s' (offs %d)\n", pProp->name, offs); } pProp->id = id; finalize_it: -- cgit v1.2.3 From ddcd6c0a61459d56f8b57a922c1b85b5bfc4215e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 14:23:32 +0200 Subject: remove no longer necessary cases --- runtime/msg.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 1fe390c6..ea14eefa 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -2529,9 +2529,7 @@ getJSONPropVal(struct json_object *jroot, uchar *propName, int propNameLen, ucha *pRes = NULL; if(jroot == NULL) goto finalize_it; - if(!strcmp((char*)propName, "!") || - !strcmp((char*)propName, ".") || - !strcmp((char*)propName, "/") ) { + if(!strcmp((char*)propName, "!")) { field = jroot; } else { leaf = jsonPathGetLeaf(propName, propNameLen); @@ -3957,9 +3955,7 @@ jsonFind(struct json_object *jroot, uchar *propName, int propNameLen, struct jso goto finalize_it; } - if(!strcmp((char*)propName, "!") || - !strcmp((char*)propName, ".") || - !strcmp((char*)propName, "/") ) { + if(!strcmp((char*)propName, "!")) { field = jroot; } else { leaf = jsonPathGetLeaf(propName, propNameLen); -- cgit v1.2.3 From c0f44743898954aee7f846ce630280a80297b80d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 15:12:30 +0200 Subject: refactor get.*PropVal() series of functions --- runtime/msg.c | 54 ++++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 30 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index ea14eefa..a0215ab6 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -2516,10 +2516,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, uchar *propName, int propNameLen, 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 *leaf; + struct json_object *jroot; struct json_object *parent; struct json_object *field; DEFiRet; @@ -2527,13 +2528,26 @@ getJSONPropVal(struct json_object *jroot, uchar *propName, int propNameLen, ucha if(*pbMustBeFreed) free(*pRes); *pRes = NULL; + + 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(!strcmp((char*)propName, "!")) { + if(!strcmp((char*)pProp->name, "!")) { field = jroot; } else { - leaf = jsonPathGetLeaf(propName, propNameLen); - CHKiRet(jsonPathFindParent(jroot, propName+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) { @@ -2543,6 +2557,8 @@ getJSONPropVal(struct json_object *jroot, uchar *propName, int propNameLen, ucha } finalize_it: + 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*)""; @@ -2551,28 +2567,6 @@ finalize_it: RETiRet; } -rsRetVal -getCEEPropVal(msg_t *pM, uchar *propName, int propNameLen, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) -{ - return getJSONPropVal(pM->json, propName, propNameLen, pRes, buflen, pbMustBeFreed); -} - -rsRetVal -getLocalVarPropVal(msg_t *pM, uchar *propName, int propNameLen, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) -{ - return getJSONPropVal(pM->localvars, propName, propNameLen, pRes, buflen, pbMustBeFreed); -} - -rsRetVal -getGlobalVarPropVal(uchar *propName, int propNameLen, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) -{ - DEFiRet; - pthread_rwlock_rdlock(&glblVars_rwlock); - iRet = getJSONPropVal(global_var_root, propName, propNameLen, pRes, buflen, pbMustBeFreed); - pthread_rwlock_unlock(&glblVars_rwlock); - RETiRet; -} - /* Get a JSON-based-variable as native json object */ rsRetVal @@ -3014,10 +3008,9 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, } break; case PROP_CEE: - getCEEPropVal(pMsg, pProp->name, pProp->nameLen, &pRes, &bufLen, pbMustBeFreed); - break; case PROP_LOCAL_VAR: - getLocalVarPropVal(pMsg, pProp->name, pProp->nameLen, &pRes, &bufLen, pbMustBeFreed); + case PROP_GLOBAL_VAR: + getJSONPropVal(pMsg, pProp, &pRes, &bufLen, pbMustBeFreed); break; case PROP_SYS_BOM: if(*pbMustBeFreed == 1) @@ -4221,6 +4214,7 @@ msgPropDescrDestruct(msgPropDescr_t *pProp) } } + /* dummy */ rsRetVal msgQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; } -- cgit v1.2.3 From e93ebb79dbb0d6715a297be2ddbf721ef2fda2bb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 15:50:42 +0200 Subject: refactor: remove now no-longer needed functions --- runtime/msg.c | 72 ----------------------------------------------------------- 1 file changed, 72 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index a0215ab6..5224ccea 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -3679,78 +3679,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; - unsigned short bMustBeFreed = 0; - msgPropDescr_t mProp; - es_str_t *estr; - - ISOBJ_TYPE_assert(pThis, msg); - - /* always call MsgGetProp() without a template specifier */ - /* TODO: optimize propNameToID() call -- rgerhards, 2009-06-26 */ -#warning remove strlen() ? - msgPropDescrFill(&mProp, name, ustrlen(name)); - pszProp = (uchar*) MsgGetProp(pThis, NULL, &mProp, &propLen, &bMustBeFreed, NULL); - - 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 -- cgit v1.2.3 From 059a3168246f803936de63ced1d356d649d4ad16 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 15:59:23 +0200 Subject: refactor: align jsonFind() calling interface with recent changes --- runtime/msg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 5224ccea..36444bbc 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -3864,7 +3864,7 @@ 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, uchar *propName, int propNameLen, struct json_object **jsonres) +jsonFind(struct json_object *jroot, msgPropDescr_t *pProp, struct json_object **jsonres) { uchar *leaf; struct json_object *parent; @@ -3876,11 +3876,11 @@ jsonFind(struct json_object *jroot, uchar *propName, int propNameLen, struct jso goto finalize_it; } - if(!strcmp((char*)propName, "!")) { + if(!strcmp((char*)pProp->name, "!")) { field = jroot; } else { - leaf = jsonPathGetLeaf(propName, propNameLen); - CHKiRet(jsonPathFindParent(jroot, propName, 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; -- cgit v1.2.3 From 4cc7f662087f3d2470ba4454c6f48a20c6c16070 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 17:08:13 +0200 Subject: enable error message for invalid property names also add some support for global vars back, as the syntax may not go away. --- runtime/msg.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 36444bbc..3690a8b4 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 @@ -4114,12 +4115,10 @@ msgPropDescrFill(msgPropDescr_t *pProp, uchar *name, int nameLen) int offs; DEFiRet; if(propNameToID(name, &id) != RS_RET_OK) { -#warning enable error messages - //errmsg.LogError(0, RS_RET_TPL_INVLD_PROP, "invalid property '%s'", - //pTpl->pszName, cstrGetSzStrNoNULL(pStrProp)); + parser_errmsg("invalid property '%s'", name); ABORT_FINALIZE(RS_RET_INVLD_PROP); } - if(id == PROP_CEE || id == PROP_LOCAL_VAR) { + 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; -- cgit v1.2.3 From 5cddb0533b53f8acfa36a65a4337ff368aa980de Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 17:29:04 +0200 Subject: fix VAR handling in script grammar and code The $-var designator is now correctly stripped off the varname. --- runtime/msg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 3690a8b4..c9ac507e 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -4068,9 +4068,9 @@ msgSetJSONFromVar(msg_t *pMsg, uchar *varname, struct var *v) ABORT_FINALIZE(RS_RET_ERR); } /* we always know strlen(varname) > 2 */ - if(varname[1] == '!') + if(varname[0] == '!') msgAddJSONObj(pMsg, varname+1, json, &pMsg->json); - else if(varname[1] == '.') + else if(varname[0] == '.') msgAddJSONObj(pMsg, varname+1, json, &pMsg->localvars); else { /* global - '/' */ pthread_rwlock_wrlock(&glblVars_rwlock); -- cgit v1.2.3 From 3a4ca82938dc8470fa1ceeef2ddb2058e896a803 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 18:08:34 +0200 Subject: bugfix: unset statement always worked on message var, even if local var was given --- runtime/msg.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index c9ac507e..eef69f85 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -3952,16 +3952,32 @@ msgAddJSON(msg_t *pM, uchar *name, struct json_object *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"); @@ -3988,16 +4004,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) { -- cgit v1.2.3 From 11d75c3d5ddcd6c665fb346f1d7e8bf8fb63a411 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 18:26:04 +0200 Subject: permit writing not only msg variables via the msgAddJSON() API --- runtime/msg.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index eef69f85..3a48fc09 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -327,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: */ @@ -3890,16 +3889,26 @@ finalize_it: 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 @@ -3942,14 +3951,12 @@ 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 msgDelJSON(msg_t *pM, uchar *name) @@ -4079,16 +4086,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[0] == '!') - msgAddJSONObj(pMsg, varname+1, json, &pMsg->json); - else if(varname[0] == '.') - 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; } -- cgit v1.2.3 From 675fab6d4eb5061f3687fcb9fb9ea82bb6abd1ff Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 18:28:47 +0200 Subject: refactoring regression fix: invalid free for JSON properties --- runtime/msg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 3a48fc09..12246777 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -4148,7 +4148,10 @@ void msgPropDescrDestruct(msgPropDescr_t *pProp) { if(pProp != NULL) { - free(pProp->name); + if(pProp->id == PROP_CEE || + pProp->id == PROP_LOCAL_VAR || + pProp->id == PROP_GLOBAL_VAR) + free(pProp->name); } } -- cgit v1.2.3 From a8ac45583ec470acc68f140bb68f4ec7d3ccac55 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Oct 2013 18:34:19 +0200 Subject: (temporarily?) re-enable global vars in string templates --- runtime/msg.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 12246777..895dbeb6 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -540,6 +540,8 @@ propNameToID(uchar *pName, propid_t *pPropID) *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; -- cgit v1.2.3 From 51551826ab4a3019950a7979160f68064e4780ff Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 24 Oct 2013 17:05:31 +0200 Subject: refactoring regression fix: segfault if $$now is used in script Thanks to Pavel Levshin for finding this bug. --- runtime/msg.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 7e01b185..f634329f 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -2470,11 +2470,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); } -- cgit v1.2.3