[syslog-ng]template() and template_escape() extension for all destination drivers
Achim Gsell
achim@cybercity.ch
Thu, 30 Jan 2003 19:42:14 +0100
--------------Boundary-00=_EMIJ9GU8G94XFM4QI2NW
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 8bit
Hi,
On Wed, Oct 30, 2002 at 20:47:55+0100, Balazs Scheidler wrote:
> I came to having some time to integrate pending patches, and found your
> patch. I have a couple of comments, which needs to be fixed before releasing
> a syslog-ng with these parts integrated.
>
> * expand_macro & friends should be declared in a header file instead of
> declaring it in every referencing module. maybe a new file called
> macros.c would be a good way of resolving this problem.
> * expand_macros returns a newly allocated string, which must be freed, so
> constructs like this cause memory leaks:
> + if (self->template_output)
> + A_WRITE_STRING(&self->dest_buf->super,
> + c_format("<%i>%S\n",
> + msg->pri,
> expand_macros(self->cfg, self->template_output, self->template_escape, msg)));
>
> c_format() has an option to free an ol_string by specifying 'f' like this:
>
> c_format("%fS", expand_macros()) ...
> Otherwise your patch looks ok to me. If you want to have it integrated prior
> to 1.6.0 is being released, please send a modified diff.
In the attachment you find a revised version of the patch. The functions
"expand_macros()" & friend are now declared in "macros.h" and coded in
"macros.c". The memory leaks are fixed ...
Achim
--------------Boundary-00=_EMIJ9GU8G94XFM4QI2NW
Content-Type: text/x-diff;
charset="us-ascii";
name="template.diff"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="template.diff"
diff -urN syslog-ng-1.5.25/src/Makefile.am syslog-ng-1.5.25.template-patch/src/Makefile.am
--- syslog-ng-1.5.25/src/Makefile.am 2001-07-08 19:04:21.000000000 +0200
+++ syslog-ng-1.5.25.template-patch/src/Makefile.am 2003-01-29 08:54:04.000000000 +0100
@@ -23,7 +23,8 @@
afremctrl.h \
utils.h \
syslog-names.h \
- nscache.h
+ nscache.h \
+ macros.h
dist_x_files = \
cfgfile.h.x \
@@ -71,7 +72,8 @@
afremctrl.c \
nscache.c \
utils.c \
- syslog-names.c
+ syslog-names.c \
+ macros.c
syslog_ng_LDADD = @LIBOBJS@
diff -urN syslog-ng-1.5.25/src/affile.c syslog-ng-1.5.25.template-patch/src/affile.c
--- syslog-ng-1.5.25/src/affile.c 2003-01-08 10:31:37.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/affile.c 2003-01-29 09:53:04.000000000 +0100
@@ -63,6 +63,7 @@
#include "center.h"
#include "resource.h"
#include "cfgfile.h"
+#include "macros.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -85,9 +86,6 @@
#include <netinet/in.h>
#include <arpa/inet.h>
-struct ol_string *
-expand_macros(struct syslog_config *cfg, struct ol_string *template, int template_escape, struct log_info *msg);
-
static int do_open_file(struct ol_string *name, int flags,
int uid, int gid, int mode,
@@ -314,12 +312,19 @@
CAST(affile_dest_writer, self, c);
if (self->dest) {
- struct ol_string *l;
- if (self->owner->template_output)
- l = expand_macros(self->owner->cfg, self->owner->template_output, self->owner->template_escape, msg);
- else
- l = c_format("%S %S %S\n", msg->date, msg->host, msg->msg);
- A_WRITE_STRING(&self->dest->buffer->super, l);
+ struct ol_string *msg_line;
+
+ if (self->owner->template_output) {
+ msg_line = expand_macros(
+ self->owner->cfg,
+ self->owner->template_output,
+ self->owner->template_escape, msg);
+ } else {
+ msg_line = c_format("%S %S %S\n",
+ msg->date,
+ msg->host, msg->msg);
+ }
+ A_WRITE_STRING(&self->dest->buffer->super, msg_line);
if (self->reap)
io_callout_set_timeout(self->reap, self->time_reap);
}
@@ -484,452 +489,6 @@
}
-
-#define MAX_MACRO_ARGS 32
-#define MAX_EXPANDED_MACRO 2048
-
-struct macro_def {
- char *name;
- int id;
-};
-
-#define M_FACILITY 0
-#define M_LEVEL 1
-#define M_TAG 2
-
-#define M_DATE 3
-#define M_FULLDATE 4
-#define M_ISODATE 5
-#define M_YEAR 6
-#define M_MONTH 7
-#define M_DAY 8
-#define M_HOUR 9
-#define M_MIN 10
-#define M_SEC 11
-#define M_WEEKDAY 12
-#define M_TZOFFSET 13
-#define M_TZ 14
-#define M_UNIXTIME 15
-
-#define M_DATE_RECVD 16
-#define M_FULLDATE_RECVD 17
-#define M_ISODATE_RECVD 18
-#define M_YEAR_RECVD 19
-#define M_MONTH_RECVD 20
-#define M_DAY_RECVD 21
-#define M_HOUR_RECVD 22
-#define M_MIN_RECVD 23
-#define M_SEC_RECVD 24
-#define M_WEEKDAY_RECVD 25
-#define M_TZOFFSET_RECVD 26
-#define M_TZ_RECVD 27
-#define M_UNIXTIME_RECVD 28
-
-#define M_DATE_STAMP 30
-#define M_FULLDATE_STAMP 31
-#define M_ISODATE_STAMP 32
-#define M_YEAR_STAMP 33
-#define M_MONTH_STAMP 34
-#define M_DAY_STAMP 35
-#define M_HOUR_STAMP 36
-#define M_MIN_STAMP 37
-#define M_SEC_STAMP 38
-#define M_WEEKDAY_STAMP 39
-#define M_TZOFFSET_STAMP 40
-#define M_TZ_STAMP 41
-#define M_UNIXTIME_STAMP 42
-
-#define M_FULLHOST 43
-#define M_HOST 44
-#define M_FULLHOST_FROM 45
-#define M_HOST_FROM 46
-#define M_PROGRAM 47
-
-#define M_MESSAGE 48
-
-#define M_SOURCE_IP 49
-
-int append_string(char **dest, int *left, char *str, int length, int escape)
-{
- int l;
-
- if (!escape) {
- l = MIN(length, *left - 1);
- strncpy(*dest, str, l);
- }
- else {
- char *p;
-
- l = 0;
- for (p = str; length && ((*left - l) > 1); p++, length--, l++) {
- if (*p == '\'' || *p == '\"' || *p == '\\') {
- if ((*left - l) < 3)
- break;
- *(*dest + l) = '\\';
- *(*dest + l + 1) = *p;
- l++;
- }
- else {
- *(*dest + l) = *p;
- }
- }
- }
- return l;
-}
-
-void expand_macro(struct syslog_config *cfg, int id, int escape, char **dest, unsigned int *left, struct log_info *msg)
-{
- int length = 0;
-
- switch (id) {
- case M_FACILITY: {
- /* facility */
- char *n = syslog_lookup_value(msg->pri & LOG_FACMASK, sl_facilities);
- if (n) {
- length = append_string(dest, left, n, strlen(n), 0);
- }
- else {
- length = snprintf(*dest, *left, "%x", (msg->pri & LOG_FACMASK) >> 3);
- }
- break;
- }
- case M_LEVEL: {
- /* level */
- char *n = syslog_lookup_value(msg->pri & LOG_PRIMASK, sl_levels);
- if (n) {
- length = append_string(dest, left, n, strlen(n), 0);
- }
- else {
- /* should never happen */
- length = snprintf(*dest, *left, "%d", msg->pri & LOG_PRIMASK);
- }
-
- break;
- }
- case M_TAG: {
- length = snprintf(*dest, *left, "%02x", msg->pri);
- break;
- }
- case M_SOURCE_IP: {
- char *ip;
-
- if (msg->saddr) {
- CAST(inet_address_info, addr, msg->saddr);
-
- ip = inet_ntoa(addr->sa.sin_addr);
- }
- else {
- ip = "127.0.0.1";
- }
- length = append_string(dest, left, ip, strlen(ip), escape);
- break;
- }
- case M_FULLHOST_FROM:
- case M_FULLHOST: {
- struct ol_string *host = (id == M_FULLHOST ? msg->host : msg->host_from);
- /* full hostname */
- length = append_string(dest, left, host->data, host->length, escape);
- break;
- }
- case M_HOST_FROM:
- case M_HOST: {
- /* host */
- struct ol_string *host = (id == M_HOST ? msg->host : msg->host_from);
- UINT8 *p1;
- UINT8 *p2;
- int remaining;
-
- p1 = memchr(host->data, '@', host->length);
- if (p1)
- p1++;
- else
- p1 = host->data;
- remaining = host->length - (p1 - host->data);
- p2 = memchr(p1, '/', remaining);
- if (p2) {
- length = MIN((unsigned int) (p2 - p1), *left);
- }
- else {
- length = MIN(*left, (unsigned int) (host->length - (p1 - host->data)));
- }
- length = append_string(dest, left, p1, length, escape);
- break;
- }
- case M_PROGRAM: {
- /* program */
- if (msg->program) {
- length = append_string(dest, left, msg->program->data, msg->program->length, escape);
- }
- break;
- }
- case M_FULLDATE_RECVD:
- case M_ISODATE_RECVD:
- case M_WEEKDAY_RECVD:
- case M_DATE_RECVD:
- case M_YEAR_RECVD:
- case M_MONTH_RECVD:
- case M_DAY_RECVD:
- case M_HOUR_RECVD:
- case M_MIN_RECVD:
- case M_SEC_RECVD:
- case M_TZOFFSET_RECVD:
- case M_TZ_RECVD:
- case M_UNIXTIME_RECVD:
-
- case M_FULLDATE_STAMP:
- case M_ISODATE_STAMP:
- case M_WEEKDAY_STAMP:
- case M_DATE_STAMP:
- case M_YEAR_STAMP:
- case M_MONTH_STAMP:
- case M_DAY_STAMP:
- case M_HOUR_STAMP:
- case M_MIN_STAMP:
- case M_SEC_STAMP:
- case M_TZOFFSET_STAMP:
- case M_TZ_STAMP:
- case M_UNIXTIME_STAMP:
-
- case M_FULLDATE:
- case M_ISODATE:
- case M_WEEKDAY:
- case M_DATE:
- case M_YEAR:
- case M_MONTH:
- case M_DAY:
- case M_HOUR:
- case M_MIN:
- case M_SEC:
- case M_TZOFFSET:
- case M_TZ:
- case M_UNIXTIME: {
- /* year, month, day */
- struct tm *tm;
- time_t unixtime;
-
- switch(id) {
- case M_FULLDATE_RECVD:
- case M_ISODATE_RECVD:
- case M_WEEKDAY_RECVD:
- case M_DATE_RECVD:
- case M_YEAR_RECVD:
- case M_MONTH_RECVD:
- case M_DAY_RECVD:
- case M_HOUR_RECVD:
- case M_MIN_RECVD:
- case M_SEC_RECVD:
- case M_TZOFFSET_RECVD:
- case M_TZ_RECVD:
- case M_UNIXTIME_RECVD:
- unixtime = msg->recvd;
- break;
- case M_FULLDATE_STAMP:
- case M_ISODATE_STAMP:
- case M_WEEKDAY_STAMP:
- case M_DATE_STAMP:
- case M_YEAR_STAMP:
- case M_MONTH_STAMP:
- case M_DAY_STAMP:
- case M_HOUR_STAMP:
- case M_MIN_STAMP:
- case M_SEC_STAMP:
- case M_TZOFFSET_STAMP:
- case M_TZ_STAMP:
- case M_UNIXTIME_STAMP:
- unixtime = msg->stamp;
- break;
- default:
- if (cfg->use_time_recvd)
- unixtime = msg->recvd;
- else
- unixtime = msg->stamp;
- break;
- }
-
- tm = localtime(&unixtime);
-
- switch (id) {
- case M_WEEKDAY:
- case M_WEEKDAY_RECVD:
- case M_WEEKDAY_STAMP:
- length = strftime(*dest, *left - 1, "%a", tm);
- break;
- case M_YEAR:
- case M_YEAR_RECVD:
- case M_YEAR_STAMP:
- length = snprintf(*dest, *left, "%04d", tm->tm_year + 1900);
- break;
- case M_MONTH:
- case M_MONTH_RECVD:
- case M_MONTH_STAMP:
- length = snprintf(*dest, *left, "%02d", tm->tm_mon + 1);
- break;
- case M_DAY:
- case M_DAY_RECVD:
- case M_DAY_STAMP:
- length = snprintf(*dest, *left, "%02d", tm->tm_mday);
- break;
- case M_HOUR:
- case M_HOUR_RECVD:
- case M_HOUR_STAMP:
- length = snprintf(*dest, *left, "%02d", tm->tm_hour);
- break;
- case M_MIN:
- case M_MIN_RECVD:
- case M_MIN_STAMP:
- length = snprintf(*dest, *left, "%02d", tm->tm_min);
- break;
- case M_SEC:
- case M_SEC_RECVD:
- case M_SEC_STAMP:
- length = snprintf(*dest, *left, "%02d", tm->tm_sec);
- break;
- case M_ISODATE:
- case M_ISODATE_RECVD:
- case M_ISODATE_STAMP:
- length = strftime(*dest, *left - 1, "%Y-%m-%dT%H:%M:%S%z", tm);
- break;
- case M_FULLDATE:
- case M_FULLDATE_RECVD:
- case M_FULLDATE_STAMP:
- length = strftime(*dest, *left - 1, "%Y %h %e %H:%M:%S", tm);
- break;
- case M_DATE:
- case M_DATE_RECVD:
- case M_DATE_STAMP:
- length = strftime(*dest, *left - 1, "%h %e %H:%M:%S", tm);
- break;
- case M_TZOFFSET:
- case M_TZOFFSET_RECVD:
- case M_TZOFFSET_STAMP:
- length = strftime(*dest, *left -1, "%z", tm);
- break;
- case M_TZ:
- case M_TZ_RECVD:
- case M_TZ_STAMP:
- length = strftime(*dest, *left -1, "%Z", tm);
- break;
- case M_UNIXTIME:
- case M_UNIXTIME_RECVD:
- case M_UNIXTIME_STAMP:
- length = snprintf(*dest, *left, "%ld", (long) unixtime);
- break;
- }
- break;
- }
- case M_MESSAGE: {
- /* message */
- length = append_string(dest, left, msg->msg->data, msg->msg->length, escape);
- break;
- }
- default:
- break;
- }
- if (length < 0 || length > *left)
- length = *left;
-
- *left -= length;
- *dest += length;
-}
-
-struct ol_string *
-expand_macros(struct syslog_config *cfg, struct ol_string *template, int template_escape, struct log_info *msg)
-{
- static struct macro_def macros[] = {
- { "FACILITY", M_FACILITY },
- { "PRIORITY", M_LEVEL },
- { "LEVEL", M_LEVEL },
- { "TAG", M_TAG },
-
- { "DATE", M_DATE },
- { "FULLDATE", M_FULLDATE },
- { "ISODATE", M_ISODATE },
- { "YEAR", M_YEAR },
- { "MONTH", M_MONTH },
- { "DAY", M_DAY },
- { "HOUR", M_HOUR },
- { "MIN", M_MIN },
- { "SEC", M_SEC },
- { "WEEKDAY", M_WEEKDAY },
- { "UNIXTIME", M_UNIXTIME },
- { "TZOFFSET", M_TZOFFSET },
- { "TZ", M_TZ },
-
- { "R_DATE", M_DATE_RECVD },
- { "R_FULLDATE", M_FULLDATE_RECVD },
- { "R_ISODATE", M_ISODATE_RECVD },
- { "R_YEAR", M_YEAR_RECVD },
- { "R_MONTH", M_MONTH_RECVD },
- { "R_DAY", M_DAY_RECVD },
- { "R_HOUR", M_HOUR_RECVD },
- { "R_MIN", M_MIN_RECVD },
- { "R_SEC", M_SEC_RECVD },
- { "R_WEEKDAY", M_WEEKDAY_RECVD },
- { "R_UNIXTIME", M_UNIXTIME_RECVD },
- { "R_TZOFFSET", M_TZOFFSET_RECVD },
- { "R_TZ", M_TZ_RECVD },
-
- { "S_DATE", M_DATE_STAMP },
- { "S_FULLDATE", M_FULLDATE_STAMP },
- { "S_ISODATE", M_ISODATE_STAMP },
- { "S_YEAR", M_YEAR_STAMP },
- { "S_MONTH", M_MONTH_STAMP },
- { "S_DAY", M_DAY_STAMP },
- { "S_HOUR", M_HOUR_STAMP },
- { "S_MIN", M_MIN_STAMP },
- { "S_SEC", M_SEC_STAMP },
- { "S_WEEKDAY", M_WEEKDAY_STAMP },
- { "S_UNIXTIME", M_UNIXTIME_STAMP },
- { "S_TZOFFSET", M_TZOFFSET_STAMP },
- { "S_TZ", M_TZ_STAMP },
-
- { "HOST_FROM", M_HOST_FROM },
- { "FULLHOST_FROM", M_FULLHOST_FROM },
- { "HOST", M_HOST },
- { "FULLHOST", M_FULLHOST },
-
- { "PROGRAM", M_PROGRAM },
- { "MSG", M_MESSAGE },
- { "MESSAGE", M_MESSAGE },
- { "SOURCEIP", M_SOURCE_IP }
- };
- char format[cfg->log_msg_size + 1], *format_ptr = format;
- unsigned int left = sizeof(format) - 1;
- unsigned int i, j;
-
- i = 0;
- while (left && (i < template->length)) {
-
- if (template->data[i] == '$') {
- /* beginning of a macro */
- for (j = 0; j < (sizeof(macros) / sizeof(struct macro_def)); j++) {
- if (strncmp(macros[j].name, &template->data[i + 1], strlen(macros[j].name)) == 0) {
- break;
- }
- }
- if (j == (sizeof(macros) / sizeof(struct macro_def))) {
- i++;
- while ((template->data[i] >= 'A' &&
- template->data[i] <= 'Z') ||
- template->data[i] == '_')
- i++;
- }
- else {
- i += strlen(macros[j].name) + 1;
- expand_macro(cfg, macros[j].id, template_escape, &format_ptr, &left, msg);
- }
- }
- else {
- *format_ptr = template->data[i];
- format_ptr++;
- i++;
- left--;
- }
- }
- *format_ptr = 0;
- return c_format_cstring("%z", format);
-}
-
/* FIXME: a binary search would be nicer */
static struct affile_dest_writer *
affile_find_writer(struct affile_dest *self,
diff -urN syslog-ng-1.5.25/src/afinet.c syslog-ng-1.5.25.template-patch/src/afinet.c
--- syslog-ng-1.5.25/src/afinet.c 2003-01-08 10:31:37.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/afinet.c 2003-01-29 11:52:09.000000000 +0100
@@ -39,6 +39,7 @@
#endif
#include "afinet.c.x"
+#include "macros.h"
void inet_address_setip(struct address_info **a, const char *ip)
{
@@ -386,6 +387,9 @@
(dest_buf object abstract_buffer)
(sync_freq simple UINT32)
(conn_fd object connect_fd)
+ (template_fname string)
+ (template_output string)
+ (template_escape . int)
(cfg object syslog_config)))
*/
/* af_inet destination */
@@ -422,6 +426,20 @@
inet_address_setport(&dest->bind_addr, port, service, proto);
}
+void afinet_dest_set_template(struct log_dest_driver *c, char *t)
+{
+ CAST(afinet_dest, self, c);
+
+ self->template_output = c_format("%z", t);
+}
+
+void afinet_dest_set_template_escape(struct log_dest_driver *c, int enable)
+{
+ CAST(afinet_dest, self, c);
+
+ self->template_escape = enable;
+}
+
void afinet_dest_set_destport(struct log_dest_driver *c, UINT32 port,
const char *service, const char *proto)
{
@@ -527,7 +545,21 @@
CAST(afinet_dest, self, c);
if (self->dest_buf) {
- A_WRITE_STRING(&self->dest_buf->super, c_format("<%i>%S %S %S\n", msg->pri, msg->date, msg->host, msg->msg));
+ struct ol_string *msg_line;
+
+ if (self->template_output) {
+ msg_line = c_format("<%i>%fS",
+ msg->pri,
+ expand_macros(
+ self->cfg,
+ self->template_output,
+ self->template_escape, msg));
+ } else {
+ msg_line = c_format("<%i>%S %S %S\n",
+ msg->pri,
+ msg->date, msg->host, msg->msg);
+ }
+ A_WRITE_STRING(&self->dest_buf->super, msg_line);
}
log_info_free(msg);
}
diff -urN syslog-ng-1.5.25/src/afinet.c.x syslog-ng-1.5.25.template-patch/src/afinet.c.x
--- syslog-ng-1.5.25/src/afinet.c.x 2003-01-08 16:38:39.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/afinet.c.x 2003-01-29 11:57:37.000000000 +0100
@@ -33,6 +33,9 @@
struct abstract_buffer *dest_buf;
UINT32 sync_freq;
struct connect_fd *conn_fd;
+ struct ol_string *template_fname;
+ struct ol_string *template_output;
+ int template_escape;
struct syslog_config *cfg;
};
extern struct ol_class afinet_dest_class;
@@ -49,11 +52,18 @@
mark((struct ol_object *) i->cfg);
}
+static void do_afinet_dest_free(struct ol_object *o)
+{
+ struct afinet_dest *i = (struct afinet_dest *) o;
+ ol_string_free(i->template_fname);
+ ol_string_free(i->template_output);
+}
+
struct ol_class afinet_dest_class =
{ STATIC_HEADER,
&afsocket_dest_class, "afinet_dest", sizeof(struct afinet_dest),
do_afinet_dest_mark,
- NULL
+ do_afinet_dest_free
};
#endif /* !CLASS_DECLARE */
diff -urN syslog-ng-1.5.25/src/afinter.c syslog-ng-1.5.25.template-patch/src/afinter.c
--- syslog-ng-1.5.25/src/afinter.c 2002-04-26 11:43:54.000000000 +0200
+++ syslog-ng-1.5.25.template-patch/src/afinter.c 2003-01-29 08:31:50.000000000 +0100
@@ -82,6 +82,9 @@
{
CAST(log_source_driver, self, c);
cfg->internal = self->super.next;
+ if (assigned_configuration == NULL) {
+ assigned_configuration = cfg;
+ }
return ST_OK | ST_GOON;
}
diff -urN syslog-ng-1.5.25/src/afprogram.c syslog-ng-1.5.25.template-patch/src/afprogram.c
--- syslog-ng-1.5.25/src/afprogram.c 2001-07-08 19:04:21.000000000 +0200
+++ syslog-ng-1.5.25.template-patch/src/afprogram.c 2003-01-29 12:04:32.000000000 +0100
@@ -37,6 +37,7 @@
#include <fcntl.h>
#include "afprogram.c.x"
+#include "macros.h"
/* CLASS:
(class
@@ -44,7 +45,11 @@
(super log_dest_driver)
(vars
(progname string)
- (dest object io_fd)))
+ (dest object io_fd)
+ (template_fname string)
+ (template_output string)
+ (template_escape . int)
+ (cfg object syslog_config)))
*/
/* CLASS:
@@ -55,6 +60,22 @@
(pid simple pid_t)
(dest object io_fd)))
*/
+void
+afprogram_dest_set_template(struct log_dest_driver *c, char *t)
+{
+ CAST(afprogram_dest, self, c);
+
+ self->template_output = c_format("%z", t);
+}
+
+void
+afprogram_dest_set_template_escape(struct log_dest_driver *c, int enable)
+{
+ CAST(afprogram_dest, self, c);
+
+ self->template_escape = enable;
+}
+
static void do_kill_child(struct resource *c)
{
@@ -94,6 +115,7 @@
}
else {
NEW(afprogram_child, prg);
+ self->cfg = cfg;
prg->super.kill = do_kill_child;
prg->pid = pid;
@@ -109,18 +131,31 @@
return ST_OK | ST_GOON;
}
-static void do_handle_afprogram_dest(struct log_handler *c,
+
+
+static void
+do_handle_afprogram_dest(struct log_handler *c,
struct log_info *msg)
{
CAST(afprogram_dest, self, c);
- if (self->dest)
- A_WRITE_STRING(&self->dest->buffer->super,
- c_format("<%i>%S %S %S\n",
- msg->pri,
- msg->date,
- msg->host,
- msg->msg));
+ if (self->dest) {
+ struct ol_string *msg_line;
+
+ if (self->template_output) {
+ msg_line = c_format("<%i>%fS",
+ msg->pri,
+ expand_macros(
+ self->cfg,
+ self->template_output,
+ self->template_escape, msg));
+ } else {
+ msg_line = c_format("<%i>%S %S %S\n",
+ msg->pri,
+ msg->date, msg->host, msg->msg);
+ }
+ A_WRITE_STRING(&self->dest->buffer->super, msg_line);
+ }
log_info_free(msg);
}
diff -urN syslog-ng-1.5.25/src/afprogram.c.x syslog-ng-1.5.25.template-patch/src/afprogram.c.x
--- syslog-ng-1.5.25/src/afprogram.c.x 2003-01-08 10:11:26.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/afprogram.c.x 2003-01-29 12:04:35.000000000 +0100
@@ -4,6 +4,10 @@
struct log_dest_driver super;
struct ol_string *progname;
struct io_fd *dest;
+ struct ol_string *template_fname;
+ struct ol_string *template_output;
+ int template_escape;
+ struct syslog_config *cfg;
};
extern struct ol_class afprogram_dest_class;
#endif /* !CLASS_DEFINE */
@@ -14,12 +18,15 @@
{
struct afprogram_dest *i = (struct afprogram_dest *) o;
mark((struct ol_object *) i->dest);
+ mark((struct ol_object *) i->cfg);
}
static void do_afprogram_dest_free(struct ol_object *o)
{
struct afprogram_dest *i = (struct afprogram_dest *) o;
ol_string_free(i->progname);
+ ol_string_free(i->template_fname);
+ ol_string_free(i->template_output);
}
struct ol_class afprogram_dest_class =
diff -urN syslog-ng-1.5.25/src/afprogram.h syslog-ng-1.5.25.template-patch/src/afprogram.h
--- syslog-ng-1.5.25/src/afprogram.h 2001-02-25 13:00:22.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/afprogram.h 2003-01-29 08:31:50.000000000 +0100
@@ -29,5 +29,7 @@
#include "syslog-ng.h"
struct log_dest_driver *make_afprogram_dest(const char *cmd);
+void afprogram_dest_set_template(struct log_dest_driver *c, char *t);
+void afprogram_dest_set_template_escape(struct log_dest_driver *c, int enable);
#endif
diff -urN syslog-ng-1.5.25/src/afsocket.h syslog-ng-1.5.25.template-patch/src/afsocket.h
--- syslog-ng-1.5.25/src/afsocket.h 2001-04-14 11:10:34.000000000 +0200
+++ syslog-ng-1.5.25.template-patch/src/afsocket.h 2003-01-29 08:31:50.000000000 +0100
@@ -138,12 +138,16 @@
void afinet_dest_set_mac(struct log_dest_driver *c, UINT32 value);
void afinet_dest_set_encrypt(struct log_dest_driver *c, UINT32 value);
void afinet_dest_set_syncfreq(struct log_dest_driver *c, UINT32 value);
+void afinet_dest_set_template(struct log_dest_driver *c, char *t);
+void afinet_dest_set_template_escape(struct log_dest_driver *c, int enable);
struct log_source_driver *
make_afunix_source(struct address_info *bind_addr, UINT32 flags);
struct log_dest_driver *
make_afunix_dest(struct address_info *dest_addr, UINT32 flags);
+void afunix_dest_set_template(struct log_dest_driver *c, char *t);
+void afunix_dest_set_template_escape(struct log_dest_driver *c, int enable);
struct log_source_driver *
make_afinet_source(struct address_info *bind_addr, UINT32 flags);
diff -urN syslog-ng-1.5.25/src/afunix.c syslog-ng-1.5.25.template-patch/src/afunix.c
--- syslog-ng-1.5.25/src/afunix.c 2003-01-08 10:31:37.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/afunix.c 2003-01-30 14:47:01.000000000 +0100
@@ -40,6 +40,8 @@
#include <assert.h>
#include "afunix.c.x"
+#include "macros.h"
+
/* af_unix source connection */
@@ -316,16 +318,51 @@
(vars
(dest object io_fd)
(dest_buf object abstract_buffer)
+ (template_fname string)
+ (template_output string)
+ (template_escape . int)
(cfg object syslog_config)))
*/
-void do_handle_afunix_dest(struct log_handler *c, struct log_info *msg)
+void
+afunix_dest_set_template(struct log_dest_driver *c, char *t)
+{
+ CAST(afunix_dest, self, c);
+
+ self->template_output = c_format("%z", t);
+}
+
+void
+afunix_dest_set_template_escape(struct log_dest_driver *c, int enable)
+{
+ CAST(afunix_dest, self, c);
+
+ self->template_escape = enable;
+}
+
+static void
+do_handle_afunix_dest(struct log_handler *c, struct log_info *msg)
{
CAST(afunix_dest, self, c);
if (self->dest_buf) {
- A_WRITE_STRING(&self->dest_buf->super, c_format("<%i>%S %S%c", msg->pri, msg->date, msg->msg, 0));
+ struct ol_string *msg_line;
+
+ if (self->template_output) {
+ msg_line = c_format("<%i>%fS",
+ msg->pri,
+ expand_macros(
+ self->cfg,
+ self->template_output,
+ self->template_escape, msg));
+ } else {
+ msg_line = c_format("<%i>%S %S %S\n",
+ msg->pri,
+ msg->date, msg->host, msg->msg);
+ }
+ A_WRITE_STRING(&self->dest_buf->super, msg_line);
}
+
log_info_free(msg);
}
diff -urN syslog-ng-1.5.25/src/afunix.c.x syslog-ng-1.5.25.template-patch/src/afunix.c.x
--- syslog-ng-1.5.25/src/afunix.c.x 2003-01-08 16:38:38.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/afunix.c.x 2003-01-30 14:47:02.000000000 +0100
@@ -34,6 +34,9 @@
struct afsocket_dest super;
struct io_fd *dest;
struct abstract_buffer *dest_buf;
+ struct ol_string *template_fname;
+ struct ol_string *template_output;
+ int template_escape;
struct syslog_config *cfg;
};
extern struct ol_class afunix_dest_class;
@@ -49,11 +52,18 @@
mark((struct ol_object *) i->cfg);
}
+static void do_afunix_dest_free(struct ol_object *o)
+{
+ struct afunix_dest *i = (struct afunix_dest *) o;
+ ol_string_free(i->template_fname);
+ ol_string_free(i->template_output);
+}
+
struct ol_class afunix_dest_class =
{ STATIC_HEADER,
&afsocket_dest_class, "afunix_dest", sizeof(struct afunix_dest),
do_afunix_dest_mark,
- NULL
+ do_afunix_dest_free
};
#endif /* !CLASS_DECLARE */
diff -urN syslog-ng-1.5.25/src/afuser.c syslog-ng-1.5.25.template-patch/src/afuser.c
--- syslog-ng-1.5.25/src/afuser.c 2001-07-08 18:07:27.000000000 +0200
+++ syslog-ng-1.5.25.template-patch/src/afuser.c 2003-01-29 12:04:30.000000000 +0100
@@ -36,30 +36,66 @@
#include <utmp.h>
#include "afuser.c.x"
+#include "macros.h"
/* CLASS:
(class
(name afuser_dest)
(super log_dest_driver)
(vars
- (username string)))
+ (username string)
+ (template_fname string)
+ (template_output string)
+ (template_escape . int)
+ (cfg object syslog_config)))
*/
+void
+afuser_dest_set_template(struct log_dest_driver *c, char *t)
+{
+ CAST(afuser_dest, self, c);
+
+ self->template_output = c_format("%z", t);
+}
+
+void
+afuser_dest_set_template_escape(struct log_dest_driver *c, int enable)
+{
+ CAST(afuser_dest, self, c);
+
+ self->template_escape = enable;
+}
+
static int
do_init_afuser_dest(struct log_handler *c,
struct syslog_config *cfg,
struct persistent_config *persistent)
{
+ CAST(afuser_dest, self, c);
+
+ self->cfg = cfg;
+
return ST_OK | ST_GOON;
}
-static void do_handle_afuser_log(struct log_handler *c, struct log_info *msg)
+static void
+do_handle_afuser_log(struct log_handler *c, struct log_info *msg)
{
CAST(afuser_dest, self, c);
struct utmp *ut;
struct ol_string *msg_line;
- msg_line = c_format("%S %S %S\n", msg->date, msg->host, msg->msg);
+ if (self->template_output) {
+ msg_line = c_format("%fS",
+ expand_macros(
+ self->cfg,
+ self->template_output,
+ self->template_escape, msg));
+ } else {
+ msg_line = c_format("%S %S %S\n",
+ msg->date, msg->host, msg->msg);
+ }
+
while ((ut = getutent())) {
#if HAVE_MODERN_UTMP
if (ut->ut_type == USER_PROCESS &&
diff -urN syslog-ng-1.5.25/src/afuser.c.x syslog-ng-1.5.25.template-patch/src/afuser.c.x
--- syslog-ng-1.5.25/src/afuser.c.x 2003-01-08 10:11:25.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/afuser.c.x 2003-01-29 12:04:34.000000000 +0100
@@ -3,21 +3,34 @@
{
struct log_dest_driver super;
struct ol_string *username;
+ struct ol_string *template_fname;
+ struct ol_string *template_output;
+ int template_escape;
+ struct syslog_config *cfg;
};
extern struct ol_class afuser_dest_class;
#endif /* !CLASS_DEFINE */
#ifndef CLASS_DECLARE
+static void do_afuser_dest_mark(struct ol_object *o,
+void (*mark)(struct ol_object *o))
+{
+ struct afuser_dest *i = (struct afuser_dest *) o;
+ mark((struct ol_object *) i->cfg);
+}
+
static void do_afuser_dest_free(struct ol_object *o)
{
struct afuser_dest *i = (struct afuser_dest *) o;
ol_string_free(i->username);
+ ol_string_free(i->template_fname);
+ ol_string_free(i->template_output);
}
struct ol_class afuser_dest_class =
{ STATIC_HEADER,
&log_dest_driver_class, "afuser_dest", sizeof(struct afuser_dest),
- NULL,
+ do_afuser_dest_mark,
do_afuser_dest_free
};
#endif /* !CLASS_DECLARE */
diff -urN syslog-ng-1.5.25/src/afuser.h syslog-ng-1.5.25.template-patch/src/afuser.h
--- syslog-ng-1.5.25/src/afuser.h 2001-02-25 13:00:22.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/afuser.h 2003-01-29 08:31:50.000000000 +0100
@@ -29,5 +29,7 @@
#include "syslog-ng.h"
struct log_dest_driver *make_afuser_dest(const char *username);
+void afuser_dest_set_template(struct log_dest_driver *c, char *t);
+void afuser_dest_set_template_escape(struct log_dest_driver *c, int enable);
#endif
diff -urN syslog-ng-1.5.25/src/cfg-grammar.h syslog-ng-1.5.25.template-patch/src/cfg-grammar.h
--- syslog-ng-1.5.25/src/cfg-grammar.h 2003-01-06 09:45:10.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/cfg-grammar.h 2003-01-29 08:42:09.000000000 +0100
@@ -53,7 +53,7 @@
# define KW_DIR_OWNER 296
# define KW_DIR_GROUP 297
# define KW_DIR_PERM 298
-# define KW_FILE_TEMPLATE 299
+# define KW_TEMPLATE 299
# define KW_TEMPLATE_ESCAPE 300
# define KW_OWNER 301
# define KW_GROUP 302
diff -urN syslog-ng-1.5.25/src/cfg-grammar.y syslog-ng-1.5.25.template-patch/src/cfg-grammar.y
--- syslog-ng-1.5.25/src/cfg-grammar.y 2003-01-08 10:31:37.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/cfg-grammar.y 2003-01-29 08:31:50.000000000 +0100
@@ -80,7 +80,7 @@
%token KW_TIME_REOPEN KW_TIME_REAP KW_USE_TIME_RECVD
%token KW_USE_DNS KW_USE_FQDN KW_GC_BUSY_THRESHOLD
%token KW_GC_IDLE_THRESHOLD KW_CREATE_DIRS
-%token KW_DIR_OWNER KW_DIR_GROUP KW_DIR_PERM KW_FILE_TEMPLATE KW_TEMPLATE_ESCAPE
+%token KW_DIR_OWNER KW_DIR_GROUP KW_DIR_PERM KW_TEMPLATE KW_TEMPLATE_ESCAPE
%token KW_OWNER KW_GROUP KW_PERM KW_KEEP_ALIVE KW_MAX_CONNECTIONS
%token KW_LOCALIP KW_IP KW_LOCALPORT KW_PORT KW_DESTPORT
%token KW_COMPRESS KW_MAC KW_AUTH KW_ENCRYPT
@@ -136,7 +136,9 @@
%type <ptr> dest_afinet_udp_params
%type <ptr> dest_afinet_tcp_params
%type <ptr> dest_afuser
+%type <ptr> dest_afuser_params
%type <ptr> dest_afprogram
+%type <ptr> dest_afprogram_params
%type <ptr> dest_afremctrl
%type <ptr> log_items
@@ -408,7 +410,7 @@
| KW_DIR_PERM '(' NUMBER ')' { affile_set_dir_perm(last_dest_driver, $3); }
| KW_CREATE_DIRS '(' yesno ')' { affile_set_create_dirs(last_dest_driver, $3); }
| KW_REMOVE_IF_OLDER '(' NUMBER ')' { affile_set_remove_if_older(last_dest_driver, $3); }
- | KW_FILE_TEMPLATE '(' string ')' { affile_set_file_template(last_dest_driver, $3); free($3); }
+ | KW_TEMPLATE '(' string ')' { affile_set_file_template(last_dest_driver, $3); free($3); }
| KW_TEMPLATE_ESCAPE '(' yesno ')' { affile_set_template_escape(last_dest_driver, $3); }
| KW_FSYNC '(' yesno ')' { affile_set_fsync(last_dest_driver, $3); }
;
@@ -436,7 +438,7 @@
: KW_OWNER '(' string ')' { affile_set_owner(last_dest_driver, $3); free($3); }
| KW_GROUP '(' string ')' { affile_set_group(last_dest_driver, $3); free($3); }
| KW_PERM '(' NUMBER ')' { affile_set_perm(last_dest_driver, $3); }
- | KW_FILE_TEMPLATE '(' string ')' { affile_set_file_template(last_dest_driver, $3); free($3); }
+ | KW_TEMPLATE '(' string ')' { affile_set_file_template(last_dest_driver, $3); free($3); }
| KW_TEMPLATE_ESCAPE '(' yesno ')' { affile_set_template_escape(last_dest_driver, $3); }
;
@@ -448,23 +450,35 @@
| KW_TCP '(' dest_afinet_tcp_params ')' { $$ = $3; }
;
+/* options are common between dgram & stream */
+dest_afunix_option
+ : KW_TEMPLATE '(' string ')' { afunix_dest_set_template(last_dest_driver, $3); free($3); }
+ | KW_TEMPLATE_ESCAPE '(' yesno ')' { afunix_dest_set_template_escape(last_dest_driver, $3); }
+ ;
+
+dest_afunix_options
+ : dest_afunix_options dest_afunix_option
+ |
+ ;
+
dest_afunix_dgram_params
- : string { $$ = make_afunix_dest(
+ : string { last_dest_driver = make_afunix_dest(
&make_unix_address_c($1)->super,
AFSOCKET_DGRAM);
free($1);
}
+ dest_afunix_options { $$ = last_dest_driver; }
;
dest_afunix_stream_params
- : string { $$ = make_afunix_dest(
+ : string { last_dest_driver = make_afunix_dest(
&make_unix_address_c($1)->super,
AFSOCKET_STREAM);
free($1);
}
+ dest_afunix_options { $$ = last_dest_driver; }
;
-
dest_afinet_udp_params
: string
{
@@ -486,6 +500,8 @@
| KW_LOCALPORT '(' NUMBER ')' { afinet_dest_set_localport(last_dest_driver, $3, NULL, NULL); }
| KW_PORT '(' NUMBER ')' { afinet_dest_set_destport(last_dest_driver, $3, NULL, NULL); }
| KW_DESTPORT '(' NUMBER ')' { afinet_dest_set_destport(last_dest_driver, $3, NULL, NULL); }
+ | KW_TEMPLATE '(' string ')' { afinet_dest_set_template(last_dest_driver, $3); free($3); }
+ | KW_TEMPLATE_ESCAPE '(' yesno ')' { afinet_dest_set_template_escape(last_dest_driver, $3); }
;
dest_afinet_udp_option
@@ -522,13 +538,42 @@
| KW_SYNC_FREQ '(' NUMBER ')' { afinet_dest_set_syncfreq(last_dest_driver, $3); }
;
-
dest_afuser
- : KW_USER '(' string ')' { $$ = make_afuser_dest($3); free($3); }
+ : KW_USER '(' dest_afuser_params ')' { $$ = $3; }
+ ;
+
+dest_afuser_params
+ : string { last_dest_driver = make_afuser_dest($1); free($1); }
+ dest_afuser_options { $$ = last_dest_driver; }
+ ;
+
+dest_afuser_option
+ : KW_TEMPLATE '(' string ')' { afuser_dest_set_template(last_dest_driver, $3); free($3); }
+ | KW_TEMPLATE_ESCAPE '(' yesno ')' { afuser_dest_set_template_escape(last_dest_driver, $3); }
+ ;
+
+dest_afuser_options
+ : dest_afuser_options dest_afuser_option
+ |
;
dest_afprogram
- : KW_PROGRAM '(' string ')' { $$ = make_afprogram_dest($3); free($3); }
+ : KW_PROGRAM '(' dest_afprogram_params ')' { $$ = $3; }
+ ;
+
+dest_afprogram_params
+ : string { last_dest_driver = make_afprogram_dest($1); free($1); }
+ dest_afprogram_options { $$ = last_dest_driver; }
+ ;
+
+dest_afprogram_option
+ : KW_TEMPLATE '(' string ')' { afprogram_dest_set_template(last_dest_driver, $3); free($3); }
+ | KW_TEMPLATE_ESCAPE '(' yesno ')' { afprogram_dest_set_template_escape(last_dest_driver, $3); }
+ ;
+
+dest_afprogram_options
+ : dest_afprogram_options dest_afprogram_option
+ |
;
dest_afremctrl
diff -urN syslog-ng-1.5.25/src/cfg-lex.c syslog-ng-1.5.25.template-patch/src/cfg-lex.c
--- syslog-ng-1.5.25/src/cfg-lex.c 2003-01-08 16:38:35.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/cfg-lex.c 2003-01-29 08:31:50.000000000 +0100
@@ -485,7 +485,7 @@
{ "dir_owner", KW_DIR_OWNER },
{ "dir_group", KW_DIR_GROUP },
{ "dir_perm", KW_DIR_PERM },
- { "template", KW_FILE_TEMPLATE },
+ { "template", KW_TEMPLATE },
{ "template-escape", KW_TEMPLATE_ESCAPE },
{ "template_escape", KW_TEMPLATE_ESCAPE },
{ "keep-alive", KW_KEEP_ALIVE },
diff -urN syslog-ng-1.5.25/src/macros.c syslog-ng-1.5.25.template-patch/src/macros.c
--- syslog-ng-1.5.25/src/macros.c 1970-01-01 01:00:00.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/macros.c 2003-01-29 10:09:06.000000000 +0100
@@ -0,0 +1,518 @@
+/***************************************************************************
+ *
+ * Copyright (c) 1999 Balázs Scheidler
+ * Copyright (c) 1999-2001 BalaBit IT Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Inspired by nsyslog, originally written by Darren Reed.
+ *
+ * $Id:$
+ *
+ ***************************************************************************/
+
+/*
+ * Several patches to the macro expansion function were contributed
+ * by Gert Menke.
+ *
+ * Portions Copyright (c) 2002 by Gert Menke
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * The patch to add the "template" and "template_escape" options to all
+ * destination drivers was contributed by Achim Gsell.
+ */
+
+#include <string.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+
+#include "format.h"
+#include "cfgfile.h"
+#include "macros.h"
+#include "syslog-names.h"
+
+
+#define MAX_MACRO_ARGS 32
+#define MAX_EXPANDED_MACRO 2048
+
+struct macro_def {
+ char *name;
+ int id;
+};
+
+#define M_FACILITY 0
+#define M_LEVEL 1
+#define M_TAG 2
+
+#define M_DATE 3
+#define M_FULLDATE 4
+#define M_ISODATE 5
+#define M_YEAR 6
+#define M_MONTH 7
+#define M_DAY 8
+#define M_HOUR 9
+#define M_MIN 10
+#define M_SEC 11
+#define M_WEEKDAY 12
+#define M_TZOFFSET 13
+#define M_TZ 14
+#define M_UNIXTIME 15
+
+#define M_DATE_RECVD 16
+#define M_FULLDATE_RECVD 17
+#define M_ISODATE_RECVD 18
+#define M_YEAR_RECVD 19
+#define M_MONTH_RECVD 20
+#define M_DAY_RECVD 21
+#define M_HOUR_RECVD 22
+#define M_MIN_RECVD 23
+#define M_SEC_RECVD 24
+#define M_WEEKDAY_RECVD 25
+#define M_TZOFFSET_RECVD 26
+#define M_TZ_RECVD 27
+#define M_UNIXTIME_RECVD 28
+
+#define M_DATE_STAMP 30
+#define M_FULLDATE_STAMP 31
+#define M_ISODATE_STAMP 32
+#define M_YEAR_STAMP 33
+#define M_MONTH_STAMP 34
+#define M_DAY_STAMP 35
+#define M_HOUR_STAMP 36
+#define M_MIN_STAMP 37
+#define M_SEC_STAMP 38
+#define M_WEEKDAY_STAMP 39
+#define M_TZOFFSET_STAMP 40
+#define M_TZ_STAMP 41
+#define M_UNIXTIME_STAMP 42
+
+#define M_FULLHOST 43
+#define M_HOST 44
+#define M_FULLHOST_FROM 45
+#define M_HOST_FROM 46
+#define M_PROGRAM 47
+
+#define M_MESSAGE 48
+
+#define M_SOURCE_IP 49
+
+static int
+append_string(char **dest, int *left, char *str, int length, int escape)
+{
+ int l;
+
+ if (!escape) {
+ l = MIN(length, *left - 1);
+ strncpy(*dest, str, l);
+ }
+ else {
+ char *p;
+
+ l = 0;
+ for (p = str; length && ((*left - l) > 1); p++, length--, l++) {
+ if (*p == '\'' || *p == '\"' || *p == '\\') {
+ if ((*left - l) < 3)
+ break;
+ *(*dest + l) = '\\';
+ *(*dest + l + 1) = *p;
+ l++;
+ }
+ else {
+ *(*dest + l) = *p;
+ }
+ }
+ }
+ return l;
+}
+
+
+static void
+expand_macro(struct syslog_config *cfg, int id, int escape, char **dest, unsigned int *left, struct log_info *msg)
+{
+ int length = 0;
+
+ switch (id) {
+ case M_FACILITY: {
+ /* facility */
+ char *n = syslog_lookup_value(msg->pri & LOG_FACMASK, sl_facilities);
+ if (n) {
+ length = append_string(dest, left, n, strlen(n), 0);
+ }
+ else {
+ length = snprintf(*dest, *left, "%x", (msg->pri & LOG_FACMASK) >> 3);
+ }
+ break;
+ }
+ case M_LEVEL: {
+ /* level */
+ char *n = syslog_lookup_value(msg->pri & LOG_PRIMASK, sl_levels);
+ if (n) {
+ length = append_string(dest, left, n, strlen(n), 0);
+ }
+ else {
+ /* should never happen */
+ length = snprintf(*dest, *left, "%d", msg->pri & LOG_PRIMASK);
+ }
+
+ break;
+ }
+ case M_TAG: {
+ length = snprintf(*dest, *left, "%02x", msg->pri);
+ break;
+ }
+ case M_SOURCE_IP: {
+ char *ip;
+
+ if (msg->saddr) {
+ CAST(inet_address_info, addr, msg->saddr);
+
+ ip = inet_ntoa(addr->sa.sin_addr);
+ }
+ else {
+ ip = "127.0.0.1";
+ }
+ length = append_string(dest, left, ip, strlen(ip), escape);
+ break;
+ }
+ case M_FULLHOST_FROM:
+ case M_FULLHOST: {
+ struct ol_string *host = (id == M_FULLHOST ? msg->host : msg->host_from);
+ /* full hostname */
+ length = append_string(dest, left, host->data, host->length, escape);
+ break;
+ }
+ case M_HOST_FROM:
+ case M_HOST: {
+ /* host */
+ struct ol_string *host = (id == M_HOST ? msg->host : msg->host_from);
+ UINT8 *p1;
+ UINT8 *p2;
+ int remaining;
+
+ p1 = memchr(host->data, '@', host->length);
+ if (p1)
+ p1++;
+ else
+ p1 = host->data;
+ remaining = host->length - (p1 - host->data);
+ p2 = memchr(p1, '/', remaining);
+ if (p2) {
+ length = MIN((unsigned int) (p2 - p1), *left);
+ }
+ else {
+ length = MIN(*left, (unsigned int) (host->length - (p1 - host->data)));
+ }
+ length = append_string(dest, left, p1, length, escape);
+ break;
+ }
+ case M_PROGRAM: {
+ /* program */
+ if (msg->program) {
+ length = append_string(dest, left, msg->program->data, msg->program->length, escape);
+ }
+ break;
+ }
+ case M_FULLDATE_RECVD:
+ case M_ISODATE_RECVD:
+ case M_WEEKDAY_RECVD:
+ case M_DATE_RECVD:
+ case M_YEAR_RECVD:
+ case M_MONTH_RECVD:
+ case M_DAY_RECVD:
+ case M_HOUR_RECVD:
+ case M_MIN_RECVD:
+ case M_SEC_RECVD:
+ case M_TZOFFSET_RECVD:
+ case M_TZ_RECVD:
+ case M_UNIXTIME_RECVD:
+
+ case M_FULLDATE_STAMP:
+ case M_ISODATE_STAMP:
+ case M_WEEKDAY_STAMP:
+ case M_DATE_STAMP:
+ case M_YEAR_STAMP:
+ case M_MONTH_STAMP:
+ case M_DAY_STAMP:
+ case M_HOUR_STAMP:
+ case M_MIN_STAMP:
+ case M_SEC_STAMP:
+ case M_TZOFFSET_STAMP:
+ case M_TZ_STAMP:
+ case M_UNIXTIME_STAMP:
+
+ case M_FULLDATE:
+ case M_ISODATE:
+ case M_WEEKDAY:
+ case M_DATE:
+ case M_YEAR:
+ case M_MONTH:
+ case M_DAY:
+ case M_HOUR:
+ case M_MIN:
+ case M_SEC:
+ case M_TZOFFSET:
+ case M_TZ:
+ case M_UNIXTIME: {
+ /* year, month, day */
+ struct tm *tm;
+ time_t unixtime;
+
+ switch(id) {
+ case M_FULLDATE_RECVD:
+ case M_ISODATE_RECVD:
+ case M_WEEKDAY_RECVD:
+ case M_DATE_RECVD:
+ case M_YEAR_RECVD:
+ case M_MONTH_RECVD:
+ case M_DAY_RECVD:
+ case M_HOUR_RECVD:
+ case M_MIN_RECVD:
+ case M_SEC_RECVD:
+ case M_TZOFFSET_RECVD:
+ case M_TZ_RECVD:
+ case M_UNIXTIME_RECVD:
+ unixtime = msg->recvd;
+ break;
+ case M_FULLDATE_STAMP:
+ case M_ISODATE_STAMP:
+ case M_WEEKDAY_STAMP:
+ case M_DATE_STAMP:
+ case M_YEAR_STAMP:
+ case M_MONTH_STAMP:
+ case M_DAY_STAMP:
+ case M_HOUR_STAMP:
+ case M_MIN_STAMP:
+ case M_SEC_STAMP:
+ case M_TZOFFSET_STAMP:
+ case M_TZ_STAMP:
+ case M_UNIXTIME_STAMP:
+ unixtime = msg->stamp;
+ break;
+ default:
+ if (cfg->use_time_recvd)
+ unixtime = msg->recvd;
+ else
+ unixtime = msg->stamp;
+ break;
+ }
+
+ tm = localtime(&unixtime);
+
+ switch (id) {
+ case M_WEEKDAY:
+ case M_WEEKDAY_RECVD:
+ case M_WEEKDAY_STAMP:
+ length = strftime(*dest, *left - 1, "%a", tm);
+ break;
+ case M_YEAR:
+ case M_YEAR_RECVD:
+ case M_YEAR_STAMP:
+ length = snprintf(*dest, *left, "%04d", tm->tm_year + 1900);
+ break;
+ case M_MONTH:
+ case M_MONTH_RECVD:
+ case M_MONTH_STAMP:
+ length = snprintf(*dest, *left, "%02d", tm->tm_mon + 1);
+ break;
+ case M_DAY:
+ case M_DAY_RECVD:
+ case M_DAY_STAMP:
+ length = snprintf(*dest, *left, "%02d", tm->tm_mday);
+ break;
+ case M_HOUR:
+ case M_HOUR_RECVD:
+ case M_HOUR_STAMP:
+ length = snprintf(*dest, *left, "%02d", tm->tm_hour);
+ break;
+ case M_MIN:
+ case M_MIN_RECVD:
+ case M_MIN_STAMP:
+ length = snprintf(*dest, *left, "%02d", tm->tm_min);
+ break;
+ case M_SEC:
+ case M_SEC_RECVD:
+ case M_SEC_STAMP:
+ length = snprintf(*dest, *left, "%02d", tm->tm_sec);
+ break;
+ case M_ISODATE:
+ case M_ISODATE_RECVD:
+ case M_ISODATE_STAMP:
+ length = strftime(*dest, *left - 1, "%Y-%m-%dT%H:%M:%S%z", tm);
+ break;
+ case M_FULLDATE:
+ case M_FULLDATE_RECVD:
+ case M_FULLDATE_STAMP:
+ length = strftime(*dest, *left - 1, "%Y %h %e %H:%M:%S", tm);
+ break;
+ case M_DATE:
+ case M_DATE_RECVD:
+ case M_DATE_STAMP:
+ length = strftime(*dest, *left - 1, "%h %e %H:%M:%S", tm);
+ break;
+ case M_TZOFFSET:
+ case M_TZOFFSET_RECVD:
+ case M_TZOFFSET_STAMP:
+ length = strftime(*dest, *left -1, "%z", tm);
+ break;
+ case M_TZ:
+ case M_TZ_RECVD:
+ case M_TZ_STAMP:
+ length = strftime(*dest, *left -1, "%Z", tm);
+ break;
+ case M_UNIXTIME:
+ case M_UNIXTIME_RECVD:
+ case M_UNIXTIME_STAMP:
+ length = snprintf(*dest, *left, "%ld", (long) unixtime);
+ break;
+ }
+ break;
+ }
+ case M_MESSAGE: {
+ /* message */
+ length = append_string(dest, left, msg->msg->data, msg->msg->length, escape);
+ break;
+ }
+ default:
+ break;
+ }
+ if (length < 0 || length > *left)
+ length = *left;
+
+ *left -= length;
+ *dest += length;
+}
+
+struct ol_string *
+expand_macros(struct syslog_config *cfg, struct ol_string *template, int template_escape, struct log_info *msg)
+{
+ static struct macro_def macros[] = {
+ { "FACILITY", M_FACILITY },
+ { "PRIORITY", M_LEVEL },
+ { "LEVEL", M_LEVEL },
+ { "TAG", M_TAG },
+
+ { "DATE", M_DATE },
+ { "FULLDATE", M_FULLDATE },
+ { "ISODATE", M_ISODATE },
+ { "YEAR", M_YEAR },
+ { "MONTH", M_MONTH },
+ { "DAY", M_DAY },
+ { "HOUR", M_HOUR },
+ { "MIN", M_MIN },
+ { "SEC", M_SEC },
+ { "WEEKDAY", M_WEEKDAY }, { "UNIXTIME", M_UNIXTIME },
+ { "TZOFFSET", M_TZOFFSET },
+ { "TZ", M_TZ },
+
+ { "R_DATE", M_DATE_RECVD },
+ { "R_FULLDATE", M_FULLDATE_RECVD },
+ { "R_ISODATE", M_ISODATE_RECVD },
+ { "R_YEAR", M_YEAR_RECVD },
+ { "R_MONTH", M_MONTH_RECVD },
+ { "R_DAY", M_DAY_RECVD },
+ { "R_HOUR", M_HOUR_RECVD },
+ { "R_MIN", M_MIN_RECVD },
+ { "R_SEC", M_SEC_RECVD },
+ { "R_WEEKDAY", M_WEEKDAY_RECVD },
+ { "R_UNIXTIME", M_UNIXTIME_RECVD },
+ { "R_TZOFFSET", M_TZOFFSET_RECVD },
+ { "R_TZ", M_TZ_RECVD },
+
+ { "S_DATE", M_DATE_STAMP },
+ { "S_FULLDATE", M_FULLDATE_STAMP },
+ { "S_ISODATE", M_ISODATE_STAMP },
+ { "S_YEAR", M_YEAR_STAMP },
+ { "S_MONTH", M_MONTH_STAMP },
+ { "S_DAY", M_DAY_STAMP },
+ { "S_HOUR", M_HOUR_STAMP },
+ { "S_MIN", M_MIN_STAMP },
+ { "S_SEC", M_SEC_STAMP },
+ { "S_WEEKDAY", M_WEEKDAY_STAMP },
+ { "S_UNIXTIME", M_UNIXTIME_STAMP },
+ { "S_TZOFFSET", M_TZOFFSET_STAMP },
+ { "S_TZ", M_TZ_STAMP },
+
+ { "HOST_FROM", M_HOST_FROM },
+ { "FULLHOST_FROM", M_FULLHOST_FROM },
+ { "HOST", M_HOST },
+ { "FULLHOST", M_FULLHOST },
+
+ { "PROGRAM", M_PROGRAM },
+ { "MSG", M_MESSAGE },
+ { "MESSAGE", M_MESSAGE },
+ { "SOURCEIP", M_SOURCE_IP }
+ };
+ char format[cfg->log_msg_size + 1], *format_ptr = format;
+ unsigned int left = sizeof(format) - 1;
+ unsigned int i, j;
+
+ i = 0;
+ while (left && (i < template->length)) {
+
+ if (template->data[i] == '$') {
+ /* beginning of a macro */
+ for (j = 0; j < (sizeof(macros) / sizeof(struct macro_def)); j++) {
+ if (strncmp(macros[j].name, &template->data[i + 1], strlen(macros[j].name)) == 0) {
+ break;
+ }
+ }
+ if (j == (sizeof(macros) / sizeof(struct macro_def))) {
+ i++;
+ while ((template->data[i] >= 'A' &&
+ template->data[i] <= 'Z') ||
+ template->data[i] == '_')
+ i++;
+ }
+ else {
+ i += strlen(macros[j].name) + 1;
+ expand_macro(cfg, macros[j].id, template_escape, &format_ptr, &left, msg);
+ }
+ }
+ else {
+ *format_ptr = template->data[i];
+ format_ptr++;
+ i++;
+ left--;
+ }
+ }
+ *format_ptr = 0;
+ return c_format_cstring("%z", format);
+}
diff -urN syslog-ng-1.5.25/src/macros.h syslog-ng-1.5.25.template-patch/src/macros.h
--- syslog-ng-1.5.25/src/macros.h 1970-01-01 01:00:00.000000000 +0100
+++ syslog-ng-1.5.25.template-patch/src/macros.h 2003-01-29 08:42:09.000000000 +0100
@@ -0,0 +1,31 @@
+/***************************************************************************
+ *
+ * Copyright (c)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Inspired by nsyslog, originally written by Darren Reed.
+ *
+ * $Id:$
+ *
+ ***************************************************************************/
+
+#ifndef __MACROS_H
+#define __MACROS_H
+
+struct ol_string *
+expand_macros(struct syslog_config *cfg, struct ol_string *template, int template_escape, struct log_info *msg);
+
+#endif
--------------Boundary-00=_EMIJ9GU8G94XFM4QI2NW--