--- 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;
--- 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);
--- 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 <stdlib.h>
#include <string.h>
+#include <assert.h>
+
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;