summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-04-27 09:55:11 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-04-27 09:55:11 +0200
commit9801893b29ea47ade4b915e3eac79bcdc5ce74aa (patch)
tree305e277ab9faa5941d151eae68f5d04fc41e9129
parentfb5cd633e6f4852841354fcf55c971063cc6a871 (diff)
parent9c76723c5b048afe4009f0528a6201741fec234a (diff)
downloadrsyslog-9801893b29ea47ade4b915e3eac79bcdc5ce74aa.tar.gz
rsyslog-9801893b29ea47ade4b915e3eac79bcdc5ce74aa.tar.xz
rsyslog-9801893b29ea47ade4b915e3eac79bcdc5ce74aa.zip
Merge branch 'v5-stable-field-substring' into v5-beta
-rw-r--r--ChangeLog1
-rw-r--r--doc/omudpspoof.html20
-rw-r--r--doc/property_replacer.html9
-rw-r--r--runtime/msg.c112
-rw-r--r--template.c37
-rw-r--r--template.h1
6 files changed, 107 insertions, 73 deletions
diff --git a/ChangeLog b/ChangeLog
index a171a359..a15cf345 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+- added capability to specify substrings for field extraction mode
---------------------------------------------------------------------------
Version 5.9.6 [V5-BETA], 2012-04-12
- added configuration directives to customize queue light delay marks
diff --git a/doc/omudpspoof.html b/doc/omudpspoof.html
index 16cb9b13..df14bbe1 100644
--- a/doc/omudpspoof.html
+++ b/doc/omudpspoof.html
@@ -16,7 +16,7 @@ spoof the sender address. Also, it enables to circle through a number of
source ports.
<p><b>Configuration Directives</b>:</p>
<ul>
-<li><b>$ActionOMUDPSpoofSourceNameTemplate</b> &lt;templatename&gt;<br>
+<li><b>$ActionOMOMUDPSpoofSourceNameTemplate</b> &lt;templatename&gt;<br>
This is the name of the template that contains a
numerical IP address that is to be used as the source system IP address.
While it may often be a constant value, it can be generated as usual via the
@@ -28,7 +28,7 @@ So in essence, the default template spoofs the address of the system the message
was received from. This is considered the most important use case.
<li><b>$ActionOMUDPSpoofTargetHost</b> &lt;hostname&gt;<br>
Host that the messages shall be sent to.
-<li><b>$ActionUDPSpoofTargetPort</b> &lt;port&gt;<br>
+<li><b>$ActionOMUDPSpoofTargetPort</b> &lt;port&gt;<br>
Remote port that the messages shall be sent to.
<li><b>$ActionOMUDPSpoofDefaultTemplate</b> &lt;templatename&gt;<br>
This setting instructs omudpspoof to use a template different from the
@@ -53,7 +53,7 @@ care about the source port. This example is considered the typical use case for
omudpspoof.
</p>
<textarea rows="5" cols="80">$ModLoad omudpspoof
-$ActionUDPSpoofTargetHost server.example.com
+$ActionOMUDPSpoofTargetHost server.example.com
*.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :omudpspoof:
</textarea>
@@ -64,10 +64,10 @@ source port 514 is used.
<textarea rows="8" cols="80">$ModLoad omudpspoof
$template spoofaddr,"192.0.2.1"
$template spooftemplate,"%rawmsg%"
-$ActionUDPSpoofSourceNameTemplate spoofaddr
-$ActionUDPSpoofTargetHost server.example.com
-$ActionUDPSpoofSourcePortStart 514
-$ActionUDPSpoofSourcePortEnd 514
+$ActionOMUDPSpoofSourceNameTemplate spoofaddr
+$ActionOMUDPSpoofTargetHost server.example.com
+$ActionOMUDPSpoofSourcePortStart 514
+$ActionOMUDPSpoofSourcePortEnd 514
*.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :omudpspoof:;spooftemplate
</textarea>
<p>The following sample is similar to the previous, but uses as many defaults as possible.
@@ -77,8 +77,8 @@ have been changed, the previously set defaults will be used!
</p>
<textarea rows="5" cols="80">$ModLoad omudpspoof
$template spoofaddr,"192.0.2.1"
-$ActionUDPSpoofSourceNameTemplate spoofaddr
-$ActionUDPSpoofTargetHost server.example.com
+$ActionOMUDPSpoofSourceNameTemplate spoofaddr
+$ActionOMUDPSpoofTargetHost server.example.com
*.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :omudpspoof:
</textarea>
<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>]
@@ -86,7 +86,7 @@ $ActionUDPSpoofTargetHost server.example.com
<p><font size="2">This documentation is part of the
<a href="http://www.rsyslog.com/">rsyslog</a>
project.<br>
-Copyright &copy; 2009 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and
+Copyright &copy; 2009-2012 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and
<a href="http://www.adiscon.com/">Adiscon</a>.
Released under the GNU GPL version 3 or higher.</font></p>
</body></html>
diff --git a/doc/property_replacer.html b/doc/property_replacer.html
index f0153f2a..5dbdc4c6 100644
--- a/doc/property_replacer.html
+++ b/doc/property_replacer.html
@@ -274,6 +274,15 @@ fields in the property is requested. The field number must be placed in
the "ToChar" parameter. An example where the 3rd field (delimited by
TAB) from the msg property is extracted is as follows: "%msg:F:3%". The
same example with semicolon as delimiter is "%msg:F,59:3%".</p>
+<p>The use of fields does not permit to select substrings, what is rather
+unfortunate. To solve this issue, starting with 6.3.9, fromPos and toPos
+can be specified for strings as well. However, the syntax is quite ugly, but
+it was the only way to integrate this functonality into the already-existing
+system. To do so, use ",fromPos" and ",toPos" during field extraction.
+Let's assume you want to extract the substring from position 5 to 9 in the previous
+example. Then, the syntax is as follows: "%msg:F,59,5:3,9%". As you can see,
+"F,59" means field-mode, with semicolon delimiter and ",5" means starting
+at position 5. Then "3,9" means field 3 and string extraction to position 9.
<p>Please note that the special characters "F" and "R" are
case-sensitive. Only upper case works, lower case will return an error.
There are no white spaces permitted inside the sequence (that will lead
diff --git a/runtime/msg.c b/runtime/msg.c
index f5c6184c..21de8e43 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -2536,7 +2536,7 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*/
iCurrFld = 1;
pFld = pRes;
- while(*pFld && iCurrFld < pTpe->data.field.iToPos) {
+ while(*pFld && iCurrFld < pTpe->data.field.iFieldNr) {
/* skip fields until the requested field or end of string is found */
while(*pFld && (uchar) *pFld != pTpe->data.field.field_delim)
++pFld; /* skip to field terminator */
@@ -2550,9 +2550,9 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
++iCurrFld;
}
}
- dbgprintf("field requested %d, field found %d\n", pTpe->data.field.iToPos, (int) iCurrFld);
+ dbgprintf("field requested %d, field found %d\n", pTpe->data.field.iFieldNr, (int) iCurrFld);
- if(iCurrFld == pTpe->data.field.iToPos) {
+ if(iCurrFld == pTpe->data.field.iFieldNr) {
/* field found, now extract it */
/* first of all, we need to find the end */
pFldEnd = pFld;
@@ -2587,58 +2587,6 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*pPropLen = sizeof("**FIELD NOT FOUND**") - 1;
return UCHAR_CONSTANT("**FIELD NOT FOUND**");
}
- } else if(pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) {
- /* we need to obtain a private copy */
- int iFrom, iTo;
- 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);
- 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
- * fields like TAG in the default forwarding template (so it is a useful optimization
- * to check for this condition ;)). -- rgerhards, 2009-07-09
- */
- ; /*DO NOTHING*/
- } else {
- iLen = iTo - iFrom + 1; /* the +1 is for an actual char, NOT \0! */
- pBufStart = pBuf = MALLOC((iLen + 1) * sizeof(char));
- if(pBuf == NULL) {
- if(*pbMustBeFreed == 1)
- free(pRes);
- RET_OUT_OF_MEMORY;
- }
- pSb = pRes;
- if(iFrom) {
- /* skip to the start of the substring (can't do pointer arithmetic
- * because the whole string might be smaller!!)
- */
- while(*pSb && iFrom) {
- --iFrom;
- ++pSb;
- }
- }
- /* OK, we are at the begin - now let's copy... */
- bufLen = iLen;
- while(*pSb && iLen) {
- *pBuf++ = *pSb;
- ++pSb;
- --iLen;
- }
- *pBuf = '\0';
- bufLen -= iLen; /* subtract remaining length if the string was smaller! */
- if(*pbMustBeFreed == 1)
- free(pRes);
- pRes = pBufStart;
- *pbMustBeFreed = 1;
- }
#ifdef FEATURE_REGEXP
} else {
/* Check for regular expressions */
@@ -2764,6 +2712,60 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
#endif /* #ifdef FEATURE_REGEXP */
}
+ if(pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) {
+ /* we need to obtain a private copy */
+ int iFrom, iTo;
+ 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);
+ 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
+ * fields like TAG in the default forwarding template (so it is a useful optimization
+ * to check for this condition ;)). -- rgerhards, 2009-07-09
+ */
+ ; /*DO NOTHING*/
+ } else {
+ iLen = iTo - iFrom + 1; /* the +1 is for an actual char, NOT \0! */
+ pBufStart = pBuf = MALLOC((iLen + 1) * sizeof(char));
+ if(pBuf == NULL) {
+ if(*pbMustBeFreed == 1)
+ free(pRes);
+ RET_OUT_OF_MEMORY;
+ }
+ pSb = pRes;
+ if(iFrom) {
+ /* skip to the start of the substring (can't do pointer arithmetic
+ * because the whole string might be smaller!!)
+ */
+ while(*pSb && iFrom) {
+ --iFrom;
+ ++pSb;
+ }
+ }
+ /* OK, we are at the begin - now let's copy... */
+ bufLen = iLen;
+ while(*pSb && iLen) {
+ *pBuf++ = *pSb;
+ ++pSb;
+ --iLen;
+ }
+ *pBuf = '\0';
+ bufLen -= iLen; /* subtract remaining length if the string was smaller! */
+ if(*pbMustBeFreed == 1)
+ free(pRes);
+ pRes = pBufStart;
+ *pbMustBeFreed = 1;
+ }
+ }
+
/* now check if we need to do our "SP if first char is non-space" hack logic */
if(*pRes && pTpe->data.field.options.bSPIffNo1stSP) {
/* here, we always destruct the buffer and return a new one */
diff --git a/template.c b/template.c
index 54ca95af..e58623d6 100644
--- a/template.c
+++ b/template.c
@@ -732,6 +732,13 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl)
pTpe->data.field.field_expand = 1;
p ++;
}
+ if(*p == ',') { /* real fromPos? */
+ ++p;
+ iNum = 0;
+ while(isdigit((int)*p))
+ iNum = iNum * 10 + *p++ - '0';
+ pTpe->data.field.iFromPos = iNum;
+ }
}
}
} else {
@@ -832,10 +839,24 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl)
/* fallthrough to "regular" ToPos code */
#endif /* #ifdef FEATURE_REGEXP */
- iNum = 0;
- while(isdigit((int)*p))
- iNum = iNum * 10 + *p++ - '0';
- pTpe->data.field.iToPos = iNum;
+ if(pTpe->data.field.has_fields == 1) {
+ iNum = 0;
+ while(isdigit((int)*p))
+ iNum = iNum * 10 + *p++ - '0';
+ pTpe->data.field.iFieldNr = iNum;
+ if(*p == ',') { /* get real toPos? */
+ ++p;
+ iNum = 0;
+ while(isdigit((int)*p))
+ iNum = iNum * 10 + *p++ - '0';
+ pTpe->data.field.iToPos = iNum;
+ }
+ } else {
+ iNum = 0;
+ while(isdigit((int)*p))
+ iNum = iNum * 10 + *p++ - '0';
+ pTpe->data.field.iToPos = iNum;
+ }
/* skip to next known good */
while(*p && *p != '%' && *p != ':') {
/* TODO: complain on extra characters */
@@ -847,7 +868,7 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl)
#endif /* #ifdef FEATURE_REGEXP */
}
- if((pTpe->data.field.has_fields == 0) && (pTpe->data.field.iToPos < pTpe->data.field.iFromPos)) {
+ 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;
@@ -1276,9 +1297,9 @@ void tplPrintList(void)
}
if(pTpe->data.field.has_fields == 1) {
dbgprintf("[substring, field #%d only (delemiter %d)] ",
- pTpe->data.field.iToPos, pTpe->data.field.field_delim);
- } else if(pTpe->data.field.iFromPos != 0 ||
- pTpe->data.field.iToPos != 0) {
+ pTpe->data.field.iFieldNr, pTpe->data.field.field_delim);
+ }
+ if(pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) {
dbgprintf("[substring, from character %d to %d] ",
pTpe->data.field.iFromPos,
pTpe->data.field.iToPos);
diff --git a/template.h b/template.h
index b5598b6d..e659659f 100644
--- a/template.h
+++ b/template.h
@@ -68,6 +68,7 @@ struct templateEntry {
propid_t propid; /* property to be used */
unsigned iFromPos; /* for partial strings only chars from this position ... */
unsigned iToPos; /* up to that one... */
+ unsigned iFieldNr; /* for field extraction: field to extract */
#ifdef FEATURE_REGEXP
regex_t re; /* APR: this is the regular expression */
short has_regex;