summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-08-25 19:08:07 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-08-25 19:08:07 +0200
commit00c4f69c559e5ba036e20a095843a1ca6eba57c8 (patch)
treedfabee1acb22794801a537d4b277689bb22514e8
parenta36b7131ab79204f43c400de7b5663613af62cc6 (diff)
downloadrsyslog-00c4f69c559e5ba036e20a095843a1ca6eba57c8.zip
rsyslog-00c4f69c559e5ba036e20a095843a1ca6eba57c8.tar.gz
rsyslog-00c4f69c559e5ba036e20a095843a1ca6eba57c8.tar.xz
milestone: LIST-type templates support full option set
-rw-r--r--template.c72
-rw-r--r--template.h10
2 files changed, 77 insertions, 5 deletions
diff --git a/template.c b/template.c
index 7a4c398..4cad7cb 100644
--- a/template.c
+++ b/template.c
@@ -1243,12 +1243,17 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
int topos = -1;
int fieldnum = -1;
int fielddelim = 9; /* default is HT (USACSII 9) */
+ int re_matchToUse = 0;
+ int re_submatchToUse = 0;
+ char *re_expr = NULL;
struct cnfparamvals *pvals;
enum {F_NONE, F_CSV, F_JSON, F_JSONF} 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;
enum tplFormatTypes datefmt = tplFmtDefault;
+ enum tplRegexType re_type = TPL_REGEX_BRE;
+ enum tlpRegexNoMatchType re_nomatchType = TPL_REGEX_NOMATCH_USE_DFLTSTR;
DEFiRet;
/* pull params */
@@ -1277,6 +1282,40 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
fieldnum = pvals[i].val.d.n;
} else if(!strcmp(pblkProperty.descr[i].name, "field.delimiter")) {
fielddelim = pvals[i].val.d.n;
+ } else if(!strcmp(pblkProperty.descr[i].name, "regex.expression")) {
+ re_expr = es_str2cstr(pvals[i].val.d.estr, NULL);
+ } else if(!strcmp(pblkProperty.descr[i].name, "regex.type")) {
+ if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"BRE", sizeof("BRE")-1)) {
+ re_type = TPL_REGEX_BRE;
+ } else if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"ERE", sizeof("ERE")-1)) {
+ re_type = TPL_REGEX_ERE;
+ } else {
+ uchar *typeStr = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
+ errmsg.LogError(0, RS_RET_ERR, "invalid regex.type '%s' for property",
+ typeStr);
+ free(typeStr);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ } else if(!strcmp(pblkProperty.descr[i].name, "regex.nomatchmode")) {
+ if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"DFLT", sizeof("DFLT")-1)) {
+ re_nomatchType = TPL_REGEX_NOMATCH_USE_DFLTSTR;
+ } else if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"BLANK", sizeof("BLANK")-1)) {
+ re_nomatchType = TPL_REGEX_NOMATCH_USE_BLANK;
+ } else if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"FIELD", sizeof("FIELD")-1)) {
+ re_nomatchType = TPL_REGEX_NOMATCH_USE_WHOLE_FIELD;
+ } else if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"ZERO", sizeof("ZERO")-1)) {
+ re_nomatchType = TPL_REGEX_NOMATCH_USE_ZERO;
+ } else {
+ uchar *typeStr = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
+ errmsg.LogError(0, RS_RET_ERR, "invalid format type '%s' for property",
+ typeStr);
+ free(typeStr);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ } else if(!strcmp(pblkProperty.descr[i].name, "regex.match")) {
+ re_matchToUse = pvals[i].val.d.n;
+ } else if(!strcmp(pblkProperty.descr[i].name, "regex.submatch")) {
+ re_submatchToUse = pvals[i].val.d.n;
} else if(!strcmp(pblkProperty.descr[i].name, "format")) {
if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"csv", sizeof("csv")-1)) {
formatType = F_CSV;
@@ -1369,6 +1408,11 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
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 "
+ "specified - this is not possible, remove one");
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
/* apply */
CHKmalloc(pTpe = tpeConstruct(pTpl));
@@ -1433,6 +1477,34 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o)
pTpe->data.field.iFromPos = frompos;
pTpe->data.field.iToPos = topos;
}
+ if(re_expr != NULL) {
+ rsRetVal iRetLocal;
+ pTpe->data.field.typeRegex = re_type;
+ pTpe->data.field.nomatchAction = re_nomatchType;
+ pTpe->data.field.iMatchToUse = re_matchToUse;
+ pTpe->data.field.iSubMatchToUse = re_submatchToUse;
+ pTpe->data.field.has_regex = 1;
+ if((iRetLocal = objUse(regexp, LM_REGEXP_FILENAME)) == RS_RET_OK) {
+ int iOptions;
+ iOptions = (pTpe->data.field.typeRegex == TPL_REGEX_ERE) ? REG_EXTENDED : 0;
+ if(regexp.regcomp(&(pTpe->data.field.re), (char*) re_expr, iOptions) != 0) {
+ dbgprintf("error: can not compile regex: '%s'\n", re_expr);
+ errmsg.LogError(0, NO_ERRCODE, "error compiling regex '%s'", re_expr);
+ pTpe->data.field.has_regex = 2;
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ } else {
+ /* regexp object could not be loaded */
+ if(bFirstRegexpErrmsg) { /* prevent flood of messages, maybe even an endless loop! */
+ bFirstRegexpErrmsg = 0;
+ errmsg.LogError(0, NO_ERRCODE, "regexp library could not be loaded (error %d), "
+ "regexp ignored", iRetLocal);
+ }
+ pTpe->data.field.has_regex = 2;
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ }
+
finalize_it:
RETiRet;
}
diff --git a/template.h b/template.h
index c58d452..65435cd 100644
--- a/template.h
+++ b/template.h
@@ -58,6 +58,9 @@ enum tplFormatTypes { tplFmtDefault = 0, tplFmtMySQLDate = 1,
tplFmtRFC3164Date = 2, tplFmtRFC3339Date = 3, tplFmtPgSQLDate = 4,
tplFmtSecFrac = 5, tplFmtRFC3164BuggyDate = 6, tplFmtUnixDate};
enum tplFormatCaseConvTypes { tplCaseConvNo = 0, tplCaseConvUpper = 1, tplCaseConvLower = 2 };
+enum tplRegexType { TPL_REGEX_BRE = 0, /* posix BRE */
+ TPL_REGEX_ERE = 1 /* posix ERE */
+ };
#include "msg.h"
@@ -80,11 +83,8 @@ struct templateEntry {
short has_regex;
short iMatchToUse;/* which match should be obtained (10 max) */
short iSubMatchToUse;/* which submatch should be obtained (10 max) */
- enum {
- TPL_REGEX_BRE = 0, /* posix BRE */
- TPL_REGEX_ERE = 1 /* posix ERE */
- } typeRegex;
- enum {
+ enum tplRegexType typeRegex;
+ enum tlpRegexNoMatchType {
TPL_REGEX_NOMATCH_USE_DFLTSTR = 0, /* use the (old style) default "**NO MATCH**" string */
TPL_REGEX_NOMATCH_USE_BLANK = 1, /* use a blank string */
TPL_REGEX_NOMATCH_USE_WHOLE_FIELD = 2, /* use the full field contents that we were searching in*/