From 64dc3591f4cd8a7eab27d689f2b8f5db4eb56517 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 27 Sep 2006 15:54:07 +0000 Subject: made the field-delimiter inside property replacer (templates) configurable --- NEWS | 2 ++ syslogd.c | 18 ++++++++++-------- syslogd.h | 1 + template.c | 43 ++++++++++++++++++++++++++++++++++--------- template.h | 3 ++- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/NEWS b/NEWS index 53365153..e53349de 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ Version 1.12.x (RGer), 2006-xx-xx but should be kept for further us - added (interim) -u 1 option to turn off hostname and tag parsing - done some modifications to better support Fedora +- made the field delimiter inside property replace configurable via + template --------------------------------------------------------------------------- Version 1.12.2 (RGer), 2006-02-15 - fixed a bug in the RFC 3339 date formatter. An extra space was added diff --git a/syslogd.c b/syslogd.c index de293c5d..b6fe4d0f 100644 --- a/syslogd.c +++ b/syslogd.c @@ -895,7 +895,6 @@ static void wallmsg(register struct filed *f); static void reapchild(); static const char *cvthname(struct sockaddr_in *f); static void debug_switch(); -static void logerrorInt(char *type, int errCode); static rsRetVal cfline(char *line, register struct filed *f); static int decode(char *name, struct code *codetab); static void sighup_handler(); @@ -3151,17 +3150,20 @@ static char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe, int iCurrFld; char *pFld; char *pFldEnd; - /* first, skip to the field in question. For now, a field - * is made up of HT (tab) characters. This should be - * configurable over time. + /* first, skip to the field in question. The field separator + * is always one character and is stored in the template entry. */ iCurrFld = 1; pFld = pRes; while(*pFld && iCurrFld < pTpe->data.field.iToPos) { /* skip fields until the requested field or end of string is found */ - while(*pFld && *pFld != '\t') +dprintf("compare %d != %d: %d (field %d)\n", (unsigned char) *pFld, pTpe->data.field.field_delim, + ((unsigned char) *pFld != pTpe->data.field.field_delim), + pFld +); + while(*pFld && (unsigned char) *pFld != pTpe->data.field.field_delim) ++pFld; /* skip to field terminator */ - if(*pFld == '\t') { + if(*pFld == pTpe->data.field.field_delim) { ++pFld; /* eat it */ ++iCurrFld; } @@ -3173,7 +3175,7 @@ static char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe, /* field found, now extract it */ /* first of all, we need to find the end */ pFldEnd = pFld; - while(*pFldEnd && *pFldEnd != '\t') + while(*pFldEnd && *pFldEnd != pTpe->data.field.field_delim) ++pFldEnd; if(*pFldEnd == '\0') --pFldEnd; /* back of to last real char */ @@ -5601,7 +5603,7 @@ void logerrorSz(char *type, char *errMsg) * correctly formatted for it (containing a single %d param). * rgerhards 2005-09-19 */ -static void logerrorInt(char *type, int errCode) +void logerrorInt(char *type, int errCode) { char buf[1024]; diff --git a/syslogd.h b/syslogd.h index ed11e76a..b4bfa05c 100644 --- a/syslogd.h +++ b/syslogd.h @@ -5,5 +5,6 @@ void dprintf(char *, ...); void logerror(char *type); void logerrorSz(char *type, char *errMsg); +void logerrorInt(char *type, int iErr); #include "rsyslog.h" diff --git a/template.c b/template.c index e30856f6..0947018a 100644 --- a/template.c +++ b/template.c @@ -288,17 +288,42 @@ static int do_Parameter(char **pp, struct template *pTpl) if(*p == 'F') { /* we have a field counter, so indicate it in the template */ ++p; /* eat 'F' */ - if (*p != ':') { - /* There is something more than an F, this is invalid ! */ - /* 2005-12-23 rgerhards: later, we will add modifiers, so - * extra characters will then be valid. this is the number 1 - * reason why this code is NOT combined with the "R" case. + if (*p == ':') { + /* no delimiter specified, so use the default (HT) */ + pTpe->data.field.has_fields = 1; + pTpe->data.field.field_delim = 9; + } else if (*p == ',') { + ++p; /* eat ',' */ + /* configured delimiter follows, so we need to obtain + * it. Important: the following number must be the + * **DECIMAL** ASCII value of the delimiter character. + */ + pTpe->data.field.has_fields = 1; + if(!isdigit(*p)) { + /* complain and use default */ + logerrorSz + ("error: invalid character in frompos after \"F,\", property: '%%%s' - using 9 (HT) as field delimiter", + *pp); + pTpe->data.field.field_delim = 9; + } else { + iNum = 0; + while(isdigit(*p)) + iNum = iNum * 10 + *p++ - '0'; + if(iNum < 0 || iNum > 255) { + logerrorInt + ("error: non-USASCII delimiter character value in template - using 9 (HT) as substitute", iNum); + pTpe->data.field.field_delim = 9; + } else { + pTpe->data.field.field_delim = iNum; + } + } + } else { + /* invalid character after F, so we need to reject + * this. */ logerrorSz ("error: invalid character in frompos after \"F\", property: '%%%s'", *pp); - } else { - pTpe->data.field.has_fields = 1; } } else { /* we now have a simple offset in frompos (the previously "normal" case) */ @@ -645,8 +670,8 @@ void tplPrintList(void) dprintf("[drop last LF in msg] "); } if(pTpe->data.field.has_fields == 1) { - dprintf("[substring, field #%d only] ", - pTpe->data.field.iToPos); + dprintf("[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) { dprintf("[substring, from character %d to %d] ", diff --git a/template.h b/template.h index 8fde34a9..591a8c98 100644 --- a/template.h +++ b/template.h @@ -48,7 +48,8 @@ struct templateEntry { regex_t re; /* APR: this is the regular expression */ unsigned has_regex; #endif - unsigned has_fields; /* support for field-couting */ + unsigned has_fields; /* support for field-counting: field to extract */ + unsigned char field_delim; /* support for field-counting: field delemiter char */ enum tplFormatTypes eDateFormat; enum tplFormatCaseConvTypes eCaseConv; struct { /* bit fields! */ -- cgit