# HG changeset patch # User Tero Marttila # Date 1239419004 -10800 # Node ID ffefb6d85ea61aff17507ab88afabc030acb103b # Parent 361740b82fe5f096211f1f7ec8ea327c22f603f1 implement logwatch_filter::format using str_format diff -r 361740b82fe5 -r ffefb6d85ea6 src/modules/logwatch.c --- a/src/modules/logwatch.c Sat Apr 11 06:03:08 2009 +0300 +++ b/src/modules/logwatch.c Sat Apr 11 06:03:24 2009 +0300 @@ -91,7 +91,7 @@ pattern = config_get_string (option, values, "pattern" ); format = config_get_string (option, values, "format" ); chan = config_get_irc_chan (option, values, "chan" ); - + // invoke if ((filter = logwatch_filter(ctx, name, source, pattern, format, chan, err)) == NULL) goto error; diff -r 361740b82fe5 -r ffefb6d85ea6 src/modules/logwatch.h --- a/src/modules/logwatch.h Sat Apr 11 06:03:08 2009 +0300 +++ b/src/modules/logwatch.h Sat Apr 11 06:03:24 2009 +0300 @@ -129,7 +129,7 @@ struct logwatch_chan* logwatch_add_chan (struct logwatch *ctx, struct irc_chan *chan, struct error_info *err); /** - * Add a new filter + * Add a new filter. */ struct logwatch_filter* logwatch_filter (struct logwatch *ctx, const char *name, const struct logwatch_source *source, const char *pattern, const char *fmt, struct irc_chan *chan, struct error_info *err); diff -r 361740b82fe5 -r ffefb6d85ea6 src/modules/logwatch_filter.c --- a/src/modules/logwatch_filter.c Sat Apr 11 06:03:08 2009 +0300 +++ b/src/modules/logwatch_filter.c Sat Apr 11 06:03:24 2009 +0300 @@ -1,9 +1,12 @@ #include "logwatch.h" #include "../str.h" +#include "../log.h" #include #include +#include + struct logwatch_filter* logwatch_filter (struct logwatch *ctx, const char *name, const struct logwatch_source *source, const char *pattern, const char *format, struct irc_chan *chan, struct error_info *err) { @@ -61,6 +64,48 @@ free(filter); } +/** + * str_format context for logwatch_filter_apply operation + */ +struct logwatch_filter_str_format_ctx { + /** The regexp we are processing */ + pcre *regexp; + + /** The subject string */ + const char *subject; + + /** The match group vector */ + int *groups; + + /** Number of match items in groups */ + size_t group_count; +}; + +static err_t logwatch_filter_str_format_cb (const char *name, const char **value, ssize_t *value_len, void *arg) +{ + struct logwatch_filter_str_format_ctx *ctx = arg; + int num; + + // look it up + if (!ctx->regexp || (num = pcre_get_stringnumber(ctx->regexp, name)) < 0) + // no such capture group + return ERR_STR_FMT_NAME; + + // sanity check + assert((size_t) num < ctx->group_count); + + // look up the start/end offsets + int start = ctx->groups[num * 2 + 0]; + int end = ctx->groups[num * 2 + 1]; + + // return a pointer to the subject + *value = ctx->subject + start; + *value_len = end - start; + + // ok + return SUCCESS; +} + // number of pcre ovec elemnents required #define LOGWATCH_FILTER_OVEC_ITEMS ((LOGWATCH_FILTER_GROUPS_MAX + 1) * 3) @@ -73,7 +118,6 @@ char buf[LOGWATCH_FILTER_OUT_PREFIX_LEN + LOGWATCH_FILTER_OUT_MAX + 1], *buf_ptr = buf; size_t buf_size = LOGWATCH_FILTER_OUT_PREFIX_LEN + LOGWATCH_FILTER_OUT_MAX + 1; - // XXX: implement output formatting // XXX: what to do for truncated data? // discard based on source? @@ -96,17 +140,29 @@ } // format header - buf_ptr += str_advance(NULL, &buf_size, str_append_fmt(buf_ptr, buf_size, "[%.12s] ", filter->name)); + buf_ptr += str_advance(NULL, &buf_size, str_append_fmt(buf_ptr, LOGWATCH_FILTER_OUT_PREFIX_LEN + 1, "[%.12s] ", filter->name)); // format? if (filter->format) { - return SET_ERROR(err, -2); + // setup the ctx + struct logwatch_filter_str_format_ctx ctx = { + .regexp = filter->regexp, + .subject = line, + .groups = ovec, + .group_count = ret + }; + + // operate + if ((ERROR_CODE(err) = str_format(buf_ptr, buf_size, filter->format, logwatch_filter_str_format_cb, &ctx))) + goto error; } else { // quote the entire line buf_ptr += str_advance(NULL, &buf_size, str_quote(buf_ptr, buf_size, line, -1)); } + log_info("%s:%p -> %s:%s", line, source, irc_chan_name(filter->chan), buf); + // then send it as a notice if ((ERROR_CODE(err) = irc_chan_NOTICE(filter->chan, buf))) goto error;