summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2013-03-29 16:09:19 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2013-03-29 16:09:19 +0100
commit7b45d0b4d2caa27df4835ca59617bd869ee34442 (patch)
treed30fbc00ca571f050c60eeede91a62fab8684136
parent1b2f93da31d0331244aa7c72068f4ec324e2cb71 (diff)
parent474877b9d7912a3d2abc2a350dbc41e4c3b050e4 (diff)
downloadrsyslog-7b45d0b4d2caa27df4835ca59617bd869ee34442.tar.gz
rsyslog-7b45d0b4d2caa27df4835ca59617bd869ee34442.tar.bz2
rsyslog-7b45d0b4d2caa27df4835ca59617bd869ee34442.zip
Merge branch 'v7-stable-info'
Conflicts: ChangeLog template.c
-rw-r--r--ChangeLog1
-rw-r--r--doc/property_replacer.html6
-rw-r--r--doc/rsyslog_conf_templates.html2
-rw-r--r--runtime/msg.c17
-rw-r--r--template.c44
-rw-r--r--template.h1
6 files changed, 56 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 54aacf0c..bbc635cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
---------------------------------------------------------------------------
Version 7.3.10 [devel] 2013-04-??
- added RainerScript re_extract() function
+- templates now permit substring extraction relative to end-of-string
- bugfix: imuxsock aborted under some conditions
regression from ratelimiting enhancements
---------------------------------------------------------------------------
diff --git a/doc/property_replacer.html b/doc/property_replacer.html
index c7624b2d..13ff41c3 100644
--- a/doc/property_replacer.html
+++ b/doc/property_replacer.html
@@ -413,6 +413,12 @@ option when forwarding to remote hosts - they may treat the date as invalid
<td>just the subseconds of a timestamp (always 0 for a low precision timestamp)</td>
</tr>
<tr>
+<td>pos-end-relative</td>
+ <td>the from and to position is relative to the end of the string
+ instead of the usual start of string. (available since rsyslog v7.3.10)
+ </td>
+</tr>
+<tr>
<td><b>ControlCharacters</b></td>
<td>Option values for how to process control characters</td>
</tr>
diff --git a/doc/rsyslog_conf_templates.html b/doc/rsyslog_conf_templates.html
index 0c189100..9a6e1619 100644
--- a/doc/rsyslog_conf_templates.html
+++ b/doc/rsyslog_conf_templates.html
@@ -134,6 +134,8 @@ csv-data is generated, "json", which formats proper json content (but without a
header) and "jsonf", which formats as a complete json field.
<li>position.from - obtain substring starting from this position (1 is the first position)
<li>position.to - obtain substring up to this position
+<li>position.relativeToEnd - the from and to position is relative to the end of the string
+ instead of the usual start of string. (available since rsyslog v7.3.10)
<li>field.number - obtain this field match
<li>field.delimiter - decimal value of delimiter character for field extraction
<li>regex.expression - expression to use
diff --git a/runtime/msg.c b/runtime/msg.c
index c302a050..1e61e632 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -3230,13 +3230,20 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
uchar *pSb;
iFrom = pTpe->data.field.iFromPos;
iTo = pTpe->data.field.iToPos;
- /* need to zero-base to and from (they are 1-based!) */
- if(iFrom > 0)
- --iFrom;
- if(iTo > 0)
- --iTo;
if(bufLen == -1)
bufLen = ustrlen(pRes);
+dbgprintf("DDDD: orginal iFrom %u, iTo %u, len %u\n", iFrom, iTo, bufLen);
+ if(pTpe->data.field.options.bFromPosEndRelative) {
+ iFrom = (bufLen < iFrom) ? 0 : bufLen - iFrom;
+ iTo = (bufLen < iTo)? 0 : bufLen - iTo;
+dbgprintf("DDDD: now iFrom %u, iTo %u\n", iFrom, iTo);
+ } else {
+ /* need to zero-base to and from (they are 1-based!) */
+ if(iFrom > 0)
+ --iFrom;
+ if(iTo > 0)
+ --iTo;
+ }
if(iFrom == 0 && iTo >= bufLen) {
/* in this case, the requested string is a superset of what we already have,
* so there is no need to do any processing. This is a frequent case for size-limited
diff --git a/template.c b/template.c
index 1ccb3752..c48bf4bd 100644
--- a/template.c
+++ b/template.c
@@ -79,6 +79,7 @@ static struct cnfparamdescr cnfparamdescrProperty[] = {
{ "format", eCmdHdlrString, 0 },
{ "position.from", eCmdHdlrInt, 0 },
{ "position.to", eCmdHdlrInt, 0 },
+ { "position.relativetoend", eCmdHdlrBinary, 0 },
{ "field.number", eCmdHdlrInt, 0 },
{ "field.delimiter", eCmdHdlrInt, 0 },
{ "regex.expression", eCmdHdlrString, 0 },
@@ -712,6 +713,8 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe)
pTpe->data.field.options.bSecPathDrop = 1;
} else if(!strcmp((char*)Buf, "secpath-replace")) {
pTpe->data.field.options.bSecPathReplace = 1;
+ } 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) {
errmsg.LogError(0, NO_ERRCODE, "error: can only specify "
@@ -1057,18 +1060,27 @@ do_Parameter(uchar **pp, struct template *pTpl)
#endif /* #ifdef FEATURE_REGEXP */
}
- if(pTpe->data.field.iToPos < pTpe->data.field.iFromPos) {
- iNum = pTpe->data.field.iToPos;
- pTpe->data.field.iToPos = pTpe->data.field.iFromPos;
- pTpe->data.field.iFromPos = iNum;
- }
-
/* check options */
if(*p == ':') {
++p; /* eat ':' */
doOptions(&p, pTpe);
}
+ if(pTpe->data.field.options.bFromPosEndRelative) {
+ if(pTpe->data.field.iToPos > pTpe->data.field.iFromPos) {
+ iNum = pTpe->data.field.iToPos;
+ pTpe->data.field.iToPos = pTpe->data.field.iFromPos;
+ pTpe->data.field.iFromPos = iNum;
+ }
+ } else {
+ if(pTpe->data.field.iToPos < pTpe->data.field.iFromPos) {
+ iNum = pTpe->data.field.iToPos;
+ pTpe->data.field.iToPos = pTpe->data.field.iFromPos;
+ pTpe->data.field.iFromPos = iNum;
+ }
+ }
+
+
/* check field name */
if(*p == ':') {
++p; /* eat ':' */
@@ -1356,6 +1368,7 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
int re_matchToUse = 0;
int re_submatchToUse = 0;
int bComplexProcessing = 0;
+ int bPosRelativeToEnd = 0;
char *re_expr = NULL;
struct cnfparamvals *pvals = NULL;
enum {F_NONE, F_CSV, F_JSON, F_JSONF} formatType = F_NONE;
@@ -1395,6 +1408,8 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
} else if(!strcmp(pblkProperty.descr[i].name, "position.to")) {
topos = pvals[i].val.d.n;
bComplexProcessing = 1;
+ } else if(!strcmp(pblkProperty.descr[i].name, "position.relativetoend")) {
+ bPosRelativeToEnd = pvals[i].val.d.n;
} else if(!strcmp(pblkProperty.descr[i].name, "field.number")) {
fieldnum = pvals[i].val.d.n;
bComplexProcessing = 1;
@@ -1537,10 +1552,18 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
topos = 2000000000; /* large enough ;) */
if(frompos == -1 && topos != -1)
frompos = 0;
- if(topos < frompos) {
- errmsg.LogError(0, RS_RET_ERR, "position.to=%d is lower than postion.from=%d\n",
- topos, frompos);
- ABORT_FINALIZE(RS_RET_ERR);
+ if(bPosRelativeToEnd) {
+ if(topos > frompos) {
+ errmsg.LogError(0, RS_RET_ERR, "position.to=%d is higher than postion.from=%d in 'relativeToEnd' mode\n",
+ topos, frompos);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ } else {
+ if(topos < frompos) {
+ errmsg.LogError(0, RS_RET_ERR, "position.to=%d is lower than postion.from=%d\n",
+ topos, frompos);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
}
if(fieldnum != -1 && re_expr != NULL) {
errmsg.LogError(0, RS_RET_ERR, "both field extraction and regex extraction "
@@ -1613,6 +1636,7 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
if(frompos != -1) {
pTpe->data.field.iFromPos = frompos;
pTpe->data.field.iToPos = topos;
+ pTpe->data.field.options.bFromPosEndRelative = bPosRelativeToEnd;
}
if(re_expr != NULL) {
rsRetVal iRetLocal;
diff --git a/template.h b/template.h
index 018e2f52..318db6f8 100644
--- a/template.h
+++ b/template.h
@@ -119,6 +119,7 @@ struct templateEntry {
unsigned bJSON: 1; /* format field JSON escaped */
unsigned bJSONf: 1; /* format field JSON *field* (n/v pair) */
unsigned bMandatory: 1; /* mandatory field - emit even if empty */
+ unsigned bFromPosEndRelative: 1;/* is From/To-Pos relative to end of string? */
} options; /* options as bit fields */
} field;
} data;