summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--syslogd.c36
-rw-r--r--template.c10
-rw-r--r--template.h4
-rw-r--r--test.conf51
4 files changed, 92 insertions, 9 deletions
diff --git a/syslogd.c b/syslogd.c
index 8d611aba..067351f6 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -959,7 +959,7 @@ int Initialized = 0; /* set when we have initialized ourselves
extern int errno;
/* hardcoded standard templates (used for defaults) */
-static char template_TraditionalFormat[] = "\"%timegenerated% %HOSTNAME% %syslogtag%%msg%\n\"";
+static char template_TraditionalFormat[] = "\"%timegenerated% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\"";
static char template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r\"";
static char template_StdFwdFmt[] = "\"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%\"";
static char template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\"";
@@ -1924,14 +1924,12 @@ char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe, unsigned short *p
*/
// ++iFrom; /* nbr of chars to skip! */
while(*pRes && iFrom) {
- printf("%c", *pRes);
--iFrom;
++pRes;
}
}
/* OK, we are at the begin - now let's copy... */
while(*pRes && iLen) {
- printf("%c", *pRes);
*pBuf++ = *pRes;
++pRes;
--iLen;
@@ -1943,8 +1941,8 @@ char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe, unsigned short *p
*pbMustBeFreed = 1;
}
- /* case conversations (should go last, because so we are able to
- * work on the smalles possible buffer).
+ /* case conversations (should go after substring, because so we are able to
+ * work on the smallest possible buffer).
*/
if(pTpe->data.field.eCaseConv != tplCaseConvNo) {
/* we need to obtain a private copy */
@@ -1971,6 +1969,32 @@ char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe, unsigned short *p
*pbMustBeFreed = 1;
}
+ /* Now drop last LF if present (pls note that this must not be done
+ * if bEscapeCC was set! - once that is implemented ;)).
+ */
+ if(pTpe->data.field.options.bDropLastLF) {
+ int iLen = strlen(pRes);
+ char *pBuf;
+ if(*(pRes + iLen - 1) == '\n') {
+ /* we have a LF! */
+ /* check if we need to obtain a private copy */
+ if(pbMustBeFreed == 0) {
+ /* ok, original copy, need a private one */
+ pBuf = malloc((iLen + 1) * sizeof(char));
+ if(pBuf == NULL) {
+ if(*pbMustBeFreed == 1)
+ free(pRes);
+ *pbMustBeFreed = 0;
+ return "**OUT OF MEMORY**";
+ }
+ memcpy(pBuf, pRes, iLen - 1);
+ pRes = pBuf;
+ *pbMustBeFreed = 1;
+ }
+ *(pRes + iLen - 1) = '\0'; /* drop LF ;) */
+ }
+ }
+
/*dprintf("MsgGetProp(\"%s\"): \"%s\"\n", pName, pRes); only for verbose debug logging */
return(pRes);
}
@@ -3654,7 +3678,7 @@ const char *cvthname(f)
}
hp = gethostbyaddr((char *) &f->sin_addr, sizeof(struct in_addr), \
f->sin_family);
- if (hp == 0) {
+ if (hp == NULL) {
dprintf("Host name for your address (%s) unknown.\n",
inet_ntoa(f->sin_addr));
return (inet_ntoa(f->sin_addr));
diff --git a/template.c b/template.c
index 85829c27..73b7bcf8 100644
--- a/template.c
+++ b/template.c
@@ -207,6 +207,10 @@ static void doOptions(char **pp, struct templateEntry *pTpe)
pTpe->data.field.eCaseConv = tplCaseConvLower;
} else if(!strcmp(Buf, "uppercase")) {
pTpe->data.field.eCaseConv = tplCaseConvUpper;
+ } else if(!strcmp(Buf, "escape-cc")) {
+ pTpe->data.field.options.bEscapeCC = 1;
+ } else if(!strcmp(Buf, "drop-last-lf")) {
+ pTpe->data.field.options.bDropLastLF = 1;
} else {
dprintf("Invalid field option '%s' specified - ignored.\n", Buf);
}
@@ -488,6 +492,12 @@ void tplPrintList(void)
dprintf("[Converted to Upper Case] ");
break;
}
+ if(pTpe->data.field.options.bEscapeCC) {
+ dprintf("[escape control-characters] ");
+ }
+ if(pTpe->data.field.options.bDropLastLF) {
+ dprintf("[drop last LF in msg] ");
+ }
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 c9e71875..eabe9aa9 100644
--- a/template.h
+++ b/template.h
@@ -37,7 +37,9 @@ struct templateEntry {
unsigned iToPos; /* up to that one... */
enum tplFormatTypes eDateFormat;
enum tplFormatCaseConvTypes eCaseConv;
- struct {
+ struct { /* bit fields! */
+ unsigned bEscapeCC: 1; /* escape control characters? */
+ unsigned bDropLastLF: 1; /* drop last LF char in msg (PIX!) */
} options; /* options as bit fields */
} field;
} data;
diff --git a/test.conf b/test.conf
index 72c58ab8..e3e04a9f 100644
--- a/test.conf
+++ b/test.conf
@@ -16,7 +16,54 @@
# \ = \\
# --> '\' is used to escape (as in C)
#$template TraditionalFormat,%timegenerated% %HOSTNAME% %syslogtag%%msg%\n"
-$template TraditionalFormat,"%timegenerated% %HOSTNAME% %syslogtag%%msg%\n"
+
+# Properties can be accessed by the property replacer. They are accessed
+# inside the template by putting them between percent signs. Properties
+# can be modifed by the property replacer. The full syntax is as follows:
+#
+# %propname:fromChar:toChar:options%
+#
+# propname is the name of the property to access. This IS case-sensitive!
+# Currently supported are:
+# msg the MSG part of the message (aka "the message" ;))
+# rawmsg the message excactly as it was received from the
+# socket. Should be useful for debugging.
+# UxTradMsg will disappear soon - do NOT use!
+# HOSTNAME hostname from the message
+# source alias for HOSTNAME
+# syslogtag TAG from the message
+# PRI PRI part of the message - undecoded (single value)
+# IUT the monitorware InfoUnitType - used when talking to a
+# MonitorWare backend (also for phpLogCon)
+# syslogfacility the facility from the message - in numerical form
+# syslogpriority the priority (actully severity!) from the
+# message - in numerical form
+# timegenerated timestamp when the message was RECEIVED. Always in high
+# resolution
+# timereported timestamp from the message. Resolution depends on what
+# was provided in the message (in most cases, only seconds)
+# TIMESTAMP alias for timereported
+#
+# FromChar and toChar are used to build substrings. They specify the
+# offset within the string that should be copied. Offset counting
+# starts at 1, so if you need to obtain the first 2 characters of the
+# message text, you can use this syntax: "%msg:1:2%".
+# If you do not whish to specify from and to, but you want to
+# specify options, you still need to include the colons. For example,
+# if you would like to convert the full message text to lower case
+# only, use "%msg:::lowercase%".
+#
+# property options are case-insensitive, currently defined are:
+# uppercase convert property to lowercase only
+# lowercase convert property text to uppercase only
+# drop-last-lf The last LF in the message (if any), is dropped.
+# Especially useful for PIX.
+# date-mysql format as mysql date
+# date-rfc3164 format as RFC 3164 date
+# date-rfc3339 format as RFC 3339 date
+# escape-cc NOT yet implemented
+
+$template TraditionalFormat,"%timegenerated% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n"
$template precise,"%syslogpriority%,%syslogfacility%,%timegenerated%,%HOSTNAME%,%syslogtag%,%msg%\n",1024
$template RFC3164fmt,"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%"
#$template precise,"%syslogpriority%,%syslogfacility%,%timegenerated::fulltime%,%HOSTNAME%,%syslogtag%,%msg%\n",1024
@@ -26,7 +73,7 @@ $template MySQLInsert,"insert iut, message, receivedat values ('%iut%', '%msg:::
# the template below emulates winsyslog format, but we need to check the time
# stamps used. for now, it is good enough ;)
-$template WinSyslogFmt,"%timegenerated:1:10:date-rfc3339%,%timegenerated:12:19:date-rfc3339%,%timegenerated:1:10:date-rfc3339%,%timegenerated:12:19:date-rfc3339%,%syslogfacility%,%syslogpriority%,%syslogtag%%msg%\n"
+$template WinSyslogFmt,"%HOSTNAME%,%timegenerated:1:10:date-rfc3339%,%timegenerated:12:19:date-rfc3339%,%timegenerated:1:10:date-rfc3339%,%timegenerated:12:19:date-rfc3339%,%syslogfacility%,%syslogpriority%,%syslogtag%%msg%\n"
#$template wallmsg,"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated:::date-rfc3339% ...\r\n %syslogtag%%msg%\n\r"
# Selector lines are now modified