summaryrefslogtreecommitdiff
path: root/template.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2014-04-03 03:12:18 +0200
committerMichael Biebl <biebl@debian.org>2014-04-03 03:12:18 +0200
commit86c2cb438891cc0cb621b231efac2aa1f3c780df (patch)
tree1c2550bbabfdbece7c9350ffe260bc053458e41f /template.c
parent362a79f22d4bc0e8c3f1d2fe1c57915a1e47ba7c (diff)
parent9374a46543e9c43c009f80def8c3b2506b0b377e (diff)
downloadrsyslog-86c2cb438891cc0cb621b231efac2aa1f3c780df.tar.gz
Merge tag 'upstream/8.2.0' into experimental
Upstream version 8.2.0
Diffstat (limited to 'template.c')
-rw-r--r--template.c102
1 files changed, 70 insertions, 32 deletions
diff --git a/template.c b/template.c
index 33dfa0e..2f7f4e6 100644
--- a/template.c
+++ b/template.c
@@ -116,16 +116,16 @@ static int bFirstRegexpErrmsg = 1; /**< did we already do a "can't load regexp"
/* helper to tplToString and strgen's, extends buffer */
#define ALLOC_INC 128
rsRetVal
-ExtendBuf(uchar **pBuf, size_t *pLenBuf, size_t iMinSize)
+ExtendBuf(actWrkrIParams_t *__restrict__ const iparam, const size_t iMinSize)
{
uchar *pNewBuf;
size_t iNewSize;
DEFiRet;
iNewSize = (iMinSize / ALLOC_INC + 1) * ALLOC_INC;
- CHKmalloc(pNewBuf = (uchar*) realloc(*pBuf, iNewSize));
- *pBuf = pNewBuf;
- *pLenBuf = iNewSize;
+ CHKmalloc(pNewBuf = (uchar*) realloc(iparam->param, iNewSize));
+ iparam->param = pNewBuf;
+ iparam->lenBuf = iNewSize;
finalize_it:
RETiRet;
@@ -137,29 +137,26 @@ finalize_it:
* The function takes a pointer to a template and a pointer to a msg object
* as well as a pointer to an output buffer and its size. Note that the output
* buffer pointer may be NULL, size 0, in which case a new one is allocated.
- * The outpub buffer is grown as required. It is the caller's duty to free the
+ * The output buffer is grown as required. It is the caller's duty to free the
* buffer when it is done. Note that it is advisable to reuse memory, as this
* offers big performance improvements.
* rewritten 2009-06-19 rgerhards
*/
rsRetVal
-tplToString(struct template *pTpl, msg_t *pMsg, uchar **ppBuf, size_t *pLenBuf,
- struct syslogTime *ttNow)
+tplToString(struct template *__restrict__ const pTpl,
+ msg_t *__restrict__ const pMsg,
+ actWrkrIParams_t *__restrict const iparam,
+ struct syslogTime *const ttNow)
{
DEFiRet;
- struct templateEntry *pTpe;
+ struct templateEntry *__restrict__ pTpe;
size_t iBuf;
unsigned short bMustBeFreed = 0;
uchar *pVal;
rs_size_t iLenVal = 0;
- assert(pTpl != NULL);
- assert(pMsg != NULL);
- assert(ppBuf != NULL);
- assert(pLenBuf != NULL);
-
if(pTpl->pStrgen != NULL) {
- CHKiRet(pTpl->pStrgen(pMsg, ppBuf, pLenBuf));
+ CHKiRet(pTpl->pStrgen(pMsg, iparam));
FINALIZE;
}
@@ -170,9 +167,9 @@ tplToString(struct template *pTpl, msg_t *pMsg, uchar **ppBuf, size_t *pLenBuf,
* in subtree mode and so most probably only used for debug & test.
*/
getJSONPropVal(pMsg, &pTpl->subtree, &pVal, &iLenVal, &bMustBeFreed);
- if(iLenVal >= (rs_size_t)*pLenBuf) /* we reserve one char for the final \0! */
- CHKiRet(ExtendBuf(ppBuf, pLenBuf, iLenVal + 1));
- memcpy(*ppBuf, pVal, iLenVal+1);
+ if(iLenVal >= (rs_size_t)iparam->lenBuf) /* we reserve one char for the final \0! */
+ CHKiRet(ExtendBuf(iparam, iLenVal + 1));
+ memcpy(iparam->param, pVal, iLenVal+1);
if(bMustBeFreed)
free(pVal);
FINALIZE;
@@ -211,10 +208,10 @@ tplToString(struct template *pTpl, msg_t *pMsg, uchar **ppBuf, size_t *pLenBuf,
/* got source, now copy over */
if(iLenVal > 0) { /* may be zero depending on property */
/* first, make sure buffer fits */
- if(iBuf + iLenVal >= *pLenBuf) /* we reserve one char for the final \0! */
- CHKiRet(ExtendBuf(ppBuf, pLenBuf, iBuf + iLenVal + 1));
+ if(iBuf + iLenVal >= iparam->lenBuf) /* we reserve one char for the final \0! */
+ CHKiRet(ExtendBuf(iparam, iBuf + iLenVal + 1));
- memcpy(*ppBuf + iBuf, pVal, iLenVal);
+ memcpy(iparam->param + iBuf, pVal, iLenVal);
iBuf += iLenVal;
}
@@ -224,15 +221,16 @@ tplToString(struct template *pTpl, msg_t *pMsg, uchar **ppBuf, size_t *pLenBuf,
pTpe = pTpe->pNext;
}
- if(iBuf == *pLenBuf) {
+ if(iBuf == iparam->lenBuf) {
/* in the weired case of an *empty* template, this can happen.
* it is debatable if we should really fix it here or simply
* forbid that case. However, performance toll is minimal, so
- * I tend to permit it. -- 201011-05 rgerhards
+ * I tend to permit it. -- 2010-11-05 rgerhards
*/
- CHKiRet(ExtendBuf(ppBuf, pLenBuf, iBuf + 1));
+ CHKiRet(ExtendBuf(iparam, iBuf + 1));
}
- (*ppBuf)[iBuf] = '\0';
+ iparam->param[iBuf] = '\0';
+ iparam->lenStr = iBuf;
finalize_it:
RETiRet;
@@ -645,6 +643,17 @@ finalize_it:
RETiRet;
}
+/* Helper that checks to see if a property already has a format
+ * type defined
+ */
+static int hasFormat(struct templateEntry *pTpe) {
+ return (
+ pTpe->data.field.options.bCSV ||
+ pTpe->data.field.options.bJSON ||
+ pTpe->data.field.options.bJSONf ||
+ pTpe->data.field.options.bJSONr
+ );
+}
/* Helper to do_Parameter(). This parses the formatting options
* specified in a template variable. It returns the passed-in pointer
@@ -715,26 +724,40 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe)
} else if(!strcmp((char*)Buf, "pos-end-relative")) {
pTpe->data.field.options.bFromPosEndRelative = 1;
} else if(!strcmp((char*)Buf, "csv")) {
- if(pTpe->data.field.options.bJSON || pTpe->data.field.options.bJSONf) {
+ if(hasFormat(pTpe)) {
errmsg.LogError(0, NO_ERRCODE, "error: can only specify "
- "one option out of (json, jsonf, csv) - csv ignored");
+ "one option out of (json, jsonf, jsonr, jsonfr, csv) - csv ignored");
} else {
pTpe->data.field.options.bCSV = 1;
}
} else if(!strcmp((char*)Buf, "json")) {
- if(pTpe->data.field.options.bCSV || pTpe->data.field.options.bJSON) {
+ if(hasFormat(pTpe)) {
errmsg.LogError(0, NO_ERRCODE, "error: can only specify "
- "one option out of (json, jsonf, csv) - json ignored");
+ "one option out of (json, jsonf, jsonr, jsonfr, csv) - json ignored");
} else {
pTpe->data.field.options.bJSON = 1;
}
} else if(!strcmp((char*)Buf, "jsonf")) {
- if(pTpe->data.field.options.bCSV || pTpe->data.field.options.bJSON) {
+ if(hasFormat(pTpe)) {
errmsg.LogError(0, NO_ERRCODE, "error: can only specify "
- "one option out of (json, jsonf, csv) - jsonf ignored");
+ "one option out of (json, jsonf, jsonr, jsonfr, csv) - jsonf ignored");
} else {
pTpe->data.field.options.bJSONf = 1;
}
+ } else if(!strcmp((char*)Buf, "jsonr")) {
+ if(hasFormat(pTpe)) {
+ errmsg.LogError(0, NO_ERRCODE, "error: can only specify "
+ "one option out of (json, jsonf, jsonr, jsonfr, csv) - jsonr ignored");
+ } else {
+ pTpe->data.field.options.bJSONr = 1;
+ }
+ } else if(!strcmp((char*)Buf, "jsonfr")) {
+ if(hasFormat(pTpe)) {
+ errmsg.LogError(0, NO_ERRCODE, "error: can only specify "
+ "one option out of (json, jsonf, jsonr, jsonfr, csv) - jsonfr ignored");
+ } else {
+ pTpe->data.field.options.bJSONfr = 1;
+ }
} else if(!strcmp((char*)Buf, "mandatory-field")) {
pTpe->data.field.options.bMandatory = 1;
} else {
@@ -746,7 +769,6 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe)
*pp = p;
}
-
/* helper to tplAddLine. Parses a parameter and generates
* the necessary structure.
*/
@@ -1361,7 +1383,7 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
int bPosRelativeToEnd = 0;
char *re_expr = NULL;
struct cnfparamvals *pvals = NULL;
- enum {F_NONE, F_CSV, F_JSON, F_JSONF} formatType = F_NONE;
+ enum {F_NONE, F_CSV, F_JSON, F_JSONF, F_JSONR, F_JSONFR} formatType = F_NONE;
enum {CC_NONE, CC_ESCAPE, CC_SPACE, CC_DROP} controlchr = CC_NONE;
enum {SP_NONE, SP_DROP, SP_REPLACE} secpath = SP_NONE;
enum tplFormatCaseConvTypes caseconv = tplCaseConvNo;
@@ -1453,6 +1475,10 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
formatType = F_JSON;
} else if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"jsonf", sizeof("jsonf")-1)) {
formatType = F_JSONF;
+ } else if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"jsonr", sizeof("jsonr")-1)) {
+ formatType = F_JSONR;
+ } else if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"jsonfr", sizeof("jsonfr")-1)) {
+ formatType = F_JSONFR;
} else {
uchar *typeStr = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
errmsg.LogError(0, RS_RET_ERR, "invalid format type '%s' for property",
@@ -1583,6 +1609,12 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
case F_JSONF:
pTpe->data.field.options.bJSONf = 1;
break;
+ case F_JSONR:
+ pTpe->data.field.options.bJSONr = 1;
+ break;
+ case F_JSONFR:
+ pTpe->data.field.options.bJSONfr = 1;
+ break;
}
switch(controlchr) {
case CC_NONE:
@@ -2141,6 +2173,12 @@ void tplPrintList(rsconf_t *conf)
if(pTpe->data.field.options.bJSONf) {
dbgprintf("[format as JSON field] ");
}
+ if(pTpe->data.field.options.bJSONr) {
+ dbgprintf("[format as JSON without re-escaping] ");
+ }
+ if(pTpe->data.field.options.bJSONfr) {
+ dbgprintf("[format as JSON field without re-escaping] ");
+ }
if(pTpe->data.field.options.bMandatory) {
dbgprintf("[mandatory field] ");
}