summaryrefslogtreecommitdiffstats
path: root/runtime/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/msg.c')
-rw-r--r--runtime/msg.c217
1 files changed, 133 insertions, 84 deletions
diff --git a/runtime/msg.c b/runtime/msg.c
index 810a396e..f457e072 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -37,6 +37,8 @@
#include <ctype.h>
#include <sys/socket.h>
#include <netdb.h>
+#include <libestr.h>
+#include <libee/libee.h>
#if HAVE_MALLOC_H
# include <malloc.h>
#endif
@@ -45,7 +47,6 @@
#include "stringbuf.h"
#include "template.h"
#include "msg.h"
-#include "var.h"
#include "datetime.h"
#include "glbl.h"
#include "regexp.h"
@@ -57,7 +58,6 @@
/* static data */
DEFobjStaticHelpers
-DEFobjCurrIf(var)
DEFobjCurrIf(datetime)
DEFobjCurrIf(glbl)
DEFobjCurrIf(regexp)
@@ -479,16 +479,13 @@ getRcvFromIP(msg_t *pM)
}
-
-/* map a property name (string) to a property ID */
-rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID)
+/* map a property name (C string) to a property ID */
+rsRetVal
+propNameStrToID(uchar *pName, propid_t *pPropID)
{
- uchar *pName;
DEFiRet;
- assert(pCSPropName != NULL);
- assert(pPropID != NULL);
- pName = rsCStrGetSzStrNoNULL(pCSPropName);
+ assert(pName != NULL);
/* sometimes there are aliases to the original MonitoWare
* property names. These come after || in the ifs below. */
@@ -503,11 +500,6 @@ rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID)
*pPropID = PROP_SYSLOGTAG;
} else if(!strcmp((char*) pName, "rawmsg")) {
*pPropID = PROP_RAWMSG;
- /* enable this, if someone actually uses UxTradMsg, delete after some time has
- * passed and nobody complained -- rgerhards, 2009-06-16
- } else if(!strcmp((char*) pName, "uxtradmsg")) {
- pRes = getUxTradMsg(pMsg);
- */
} else if(!strcmp((char*) pName, "inputname")) {
*pPropID = PROP_INPUTNAME;
} else if(!strcmp((char*) pName, "fromhost")) {
@@ -561,6 +553,10 @@ rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID)
*pPropID = PROP_SYS_MINUTE;
} else if(!strcmp((char*) pName, "$myhostname")) {
*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(!strcmp((char*) pName, "$bom")) {
*pPropID = PROP_SYS_BOM;
} else {
@@ -572,6 +568,21 @@ rsRetVal propNameToID(cstr_t *pCSPropName, 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)
{
@@ -586,12 +597,6 @@ uchar *propIDToName(propid_t propID)
return UCHAR_CONSTANT("syslogtag");
case PROP_RAWMSG:
return UCHAR_CONSTANT("rawmsg");
- /* enable this, if someone actually uses UxTradMsg, delete after some time has
- * passed and nobody complained -- rgerhards, 2009-06-16
- case PROP_UXTRADMSG:
- pRes = getUxTradMsg(pMsg);
- break;
- */
case PROP_INPUTNAME:
return UCHAR_CONSTANT("inputname");
case PROP_FROMHOST:
@@ -644,6 +649,10 @@ uchar *propIDToName(propid_t propID)
return UCHAR_CONSTANT("$MINUTE");
case PROP_SYS_MYHOSTNAME:
return UCHAR_CONSTANT("$MYHOSTNAME");
+ case PROP_CEE:
+ return UCHAR_CONSTANT("*CEE-based property*");
+ case PROP_CEE_ALL_JSON:
+ return UCHAR_CONSTANT("$!all-json");
case PROP_SYS_BOM:
return UCHAR_CONSTANT("$BOM");
default:
@@ -714,6 +723,7 @@ static inline rsRetVal msgBaseConstruct(msg_t **ppThis)
pM->pRcvFromIP = NULL;
pM->rcvFrom.pRcvFrom = NULL;
pM->pRuleset = NULL;
+ pM->event = NULL;
memset(&pM->tRcvdAt, 0, sizeof(pM->tRcvdAt));
memset(&pM->tTIMESTAMP, 0, sizeof(pM->tTIMESTAMP));
pM->TAG.pszTAG = NULL;
@@ -849,6 +859,8 @@ CODESTARTobjDestruct(msg)
rsCStrDestruct(&pThis->pCSPROCID);
if(pThis->pCSMSGID != NULL)
rsCStrDestruct(&pThis->pCSMSGID);
+ if(pThis->event != NULL)
+ ee_deleteEvent(pThis->event);
# ifndef HAVE_ATOMIC_BUILTINS
MsgUnlock(pThis);
# endif
@@ -961,10 +973,6 @@ msg_t* MsgDup(msg_t* pOld)
pNew->pInputName = pOld->pInputName;
prop.AddRef(pNew->pInputName);
}
- /* enable this, if someone actually uses UxTradMsg, delete after some time has
- * passed and nobody complained -- rgerhards, 2009-06-16
- pNew->offAfterPRI = pOld->offAfterPRI;
- */
if(pOld->iLenTAG > 0) {
if(pOld->iLenTAG < CONF_TAG_BUFSIZE) {
memcpy(pNew->TAG.szBuf, pOld->TAG.szBuf, pOld->iLenTAG + 1);
@@ -1036,10 +1044,6 @@ static rsRetVal MsgSerialize(msg_t *pThis, strm_t *pStrm)
objSerializeSCALAR(pStrm, ttGenTime, INT);
objSerializeSCALAR(pStrm, tRcvdAt, SYSLOGTIME);
objSerializeSCALAR(pStrm, tTIMESTAMP, SYSLOGTIME);
- /* enable this, if someone actually uses UxTradMsg, delete after some time has
- * passed and nobody complained -- rgerhards, 2009-06-16
- objSerializeSCALAR(pStrm, offsAfterPRI, SHORT);
- */
CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszTAG"), PROPTYPE_PSZ, (void*)
((pThis->iLenTAG < CONF_TAG_BUFSIZE) ? pThis->TAG.szBuf : pThis->TAG.pszTAG)));
@@ -1215,7 +1219,7 @@ char *getProtocolVersionString(msg_t *pM)
}
-static inline void
+void
getRawMsg(msg_t *pM, uchar **pBuf, int *piLen)
{
if(pM == NULL) {
@@ -1233,18 +1237,6 @@ getRawMsg(msg_t *pM, uchar **pBuf, int *piLen)
}
-/* enable this, if someone actually uses UxTradMsg, delete after some time has
- * passed and nobody complained -- rgerhards, 2009-06-16
-char *getUxTradMsg(msg_t *pM)
-{
- if(pM == NULL)
- return "";
- else
- return (char*)pM->pszRawMsg + pM->offAfterPRI;
-}
-*/
-
-
int getMSGLen(msg_t *pM)
{
return((pM == NULL) ? 0 : pM->iLenMSG);
@@ -2226,8 +2218,8 @@ char *textpri(char *pRes, size_t pResLen, int pri)
assert(pRes != NULL);
assert(pResLen > 0);
- snprintf(pRes, pResLen, "%s.%s<%d>", syslog_fac_names[LOG_FAC(pri)],
- syslog_severity_names[LOG_PRI(pri)], pri);
+ snprintf(pRes, pResLen, "%s.%s", syslog_fac_names[LOG_FAC(pri)],
+ syslog_severity_names[LOG_PRI(pri)]);
return pRes;
}
@@ -2284,6 +2276,41 @@ 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)
+{
+ es_str_t *str = NULL;
+ int r;
+
+ if(*pbMustBeFreed)
+ free(*pRes);
+ *pRes = NULL;
+
+ 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;
+ }
+ *pRes = (unsigned char*) es_str2cstr(str, "#000");
+ es_deleteStr(str);
+ *buflen = (int) ustrlen(*pRes);
+ *pbMustBeFreed = 1;
+
+finalize_it:
+ if(*pRes == NULL) {
+ /* could not find any value, so set it to empty */
+ *pRes = (unsigned char*)"";
+ *pbMustBeFreed = 0;
+ }
+}
+
/* This function returns a string-representation of the
* requested message property. This is a generic function used
* to abstract properties so that these can be easier
@@ -2326,7 +2353,7 @@ static uchar *getNOW(eNOWType eNow)
*pPropLen = sizeof("**OUT OF MEMORY**") - 1; \
return(UCHAR_CONSTANT("**OUT OF MEMORY**"));}
uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
- propid_t propID, size_t *pPropLen,
+ propid_t propid, es_str_t *propName, size_t *pPropLen,
unsigned short *pbMustBeFreed)
{
uchar *pRes; /* result pointer */
@@ -2335,6 +2362,7 @@ 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);
@@ -2348,7 +2376,7 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*pbMustBeFreed = 0;
- switch(propID) {
+ switch(propid) {
case PROP_MSG:
pRes = getMSG(pMsg);
bufLen = getMSGLen(pMsg);
@@ -2366,12 +2394,6 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
case PROP_RAWMSG:
getRawMsg(pMsg, &pRes, &bufLen);
break;
- /* enable this, if someone actually uses UxTradMsg, delete after some time has
- * passed and nobody complained -- rgerhards, 2009-06-16
- case PROP_UXTRADMSG:
- pRes = getUxTradMsg(pMsg);
- break;
- */
case PROP_INPUTNAME:
getInputName(pMsg, &pRes, &bufLen);
break;
@@ -2481,6 +2503,15 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
case PROP_SYS_MYHOSTNAME:
pRes = glbl.GetLocalHostName();
break;
+ case PROP_CEE_ALL_JSON:
+ ee_fmtEventToJSON(pMsg->event, &str);
+ pRes = (uchar*) es_str2cstr(str, "#000");
+ es_deleteStr(str);
+ *pbMustBeFreed = 1; /* all of these functions allocate dyn. memory */
+ break;
+ case PROP_CEE:
+ getCEEPropVal(pMsg, propName, &pRes, &bufLen, pbMustBeFreed);
+ break;
case PROP_SYS_BOM:
if(*pbMustBeFreed == 1)
free(pRes);
@@ -2491,7 +2522,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", propid);
*pbMustBeFreed = 0;
*pPropLen = sizeof("**INVALID PROPERTY NAME**") - 1;
return UCHAR_CONSTANT("**INVALID PROPERTY NAME**");
@@ -2499,6 +2530,7 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
/* If we did not receive a template pointer, we are already done... */
if(pTpe == NULL) {
+ *pPropLen = (bufLen == -1) ? ustrlen(pRes) : bufLen;
return pRes;
}
@@ -3087,48 +3119,71 @@ dbgprintf("end prop repl, pRes='%s', len %d\n", pRes, bufLen);
}
-/* The returns a message variable suitable for use with RainerScript. Most importantly, this means
- * that the value is returned in a var_t object. The var_t is constructed inside this function and
- * MUST be freed by the caller.
- * rgerhards, 2008-02-25
+/* The function returns a cee 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
*/
-rsRetVal
-msgGetMsgVar(msg_t *pThis, cstr_t *pstrPropName, var_t **ppVar)
+es_str_t*
+msgGetCEEVarNew(msg_t *pMsg, char *name)
+{
+ es_str_t *estr = NULL;
+ es_str_t *epropName = NULL;
+ struct ee_field *field;
+
+ ISOBJ_TYPE_assert(pMsg, msg);
+
+ if(pMsg->event == 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) {
+ estr = ee_getFieldValueAsStr(field, 0);
+ }
+ if(estr == NULL) {
+ DBGPRINTF("msgGetCEEVar: error obtaining var (field=%p, var='%s')\n",
+ field, name);
+ estr = es_newStrFromCStr("*ERROR*", sizeof("*ERROR*") - 1);
+ }
+ es_deleteStr(epropName);
+
+done:
+ return estr;
+}
+
+
+/* Return an es_str_t for given message property.
+ */
+es_str_t*
+msgGetMsgVarNew(msg_t *pThis, uchar *name)
{
- DEFiRet;
- var_t *pVar;
size_t propLen;
uchar *pszProp = NULL;
- cstr_t *pstrProp;
propid_t propid;
unsigned short bMustBeFreed = 0;
+ es_str_t *estr;
ISOBJ_TYPE_assert(pThis, msg);
- ASSERT(pstrPropName != NULL);
- ASSERT(ppVar != NULL);
-
- /* make sure we have a var_t instance */
- CHKiRet(var.Construct(&pVar));
- CHKiRet(var.ConstructFinalize(pVar));
/* always call MsgGetProp() without a template specifier */
/* TODO: optimize propNameToID() call -- rgerhards, 2009-06-26 */
- propNameToID(pstrPropName, &propid);
- pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, &propLen, &bMustBeFreed);
-
- /* now create a string object out of it and hand that over to the var */
- CHKiRet(rsCStrConstructFromszStr(&pstrProp, pszProp));
- CHKiRet(var.SetString(pVar, pstrProp));
-
- /* finally store var */
- *ppVar = pVar;
+ propNameStrToID(name, &propid);
+ pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, NULL, &propLen, &bMustBeFreed);
-finalize_it:
+dbgprintf("ZZZZ: var %s returns '%s'\n", name, pszProp);
+ estr = es_newStrFromCStr((char*)pszProp, propLen);
if(bMustBeFreed)
free(pszProp);
- RETiRet;
+ 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
@@ -3158,11 +3213,6 @@ rsRetVal MsgSetProperty(msg_t *pThis, var_t *pProp)
MsgSetMSGoffs(pThis, pProp->val.num);
} else if(isProp("pszRawMsg")) {
MsgSetRawMsg(pThis, (char*) rsCStrGetSzStrNoNULL(pProp->val.pStr), cstrLen(pProp->val.pStr));
- /* enable this, if someone actually uses UxTradMsg, delete after some time has
- * passed and nobody complained -- rgerhards, 2009-06-16
- } else if(isProp("offAfterPRI")) {
- pThis->offAfterPRI = pProp->val.num;
- */
} else if(isProp("pszUxTradMsg")) {
/*IGNORE*/; /* this *was* a property, but does no longer exist */
} else if(isProp("pszTAG")) {
@@ -3241,7 +3291,6 @@ rsRetVal msgQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; }
*/
BEGINObjClassInit(msg, 1, OBJ_IS_CORE_MODULE)
/* request objects we use */
- CHKiRet(objUse(var, CORE_COMPONENT));
CHKiRet(objUse(datetime, CORE_COMPONENT));
CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(objUse(prop, CORE_COMPONENT));