--- a/src/modules/logwatch_filter.c Sat Apr 11 04:26:46 2009 +0300
+++ b/src/modules/logwatch_filter.c Sat Apr 11 04:41:44 2009 +0300
@@ -1,4 +1,5 @@
#include "logwatch.h"
+#include "../str.h"
#include <stdlib.h>
#include <string.h>
@@ -63,22 +64,24 @@
// number of pcre ovec elemnents required
#define LOGWATCH_FILTER_OVEC_ITEMS ((LOGWATCH_FILTER_GROUPS_MAX + 1) * 3)
+// length of output line prefix
+#define LOGWATCH_FILTER_OUT_PREFIX_LEN 16
+
err_t logwatch_filter_apply (const struct logwatch_filter *filter, const struct logwatch_source *source, const char *line, struct error_info *err)
{
int ovec[LOGWATCH_FILTER_OVEC_ITEMS], ret;
- char out_buf[LOGWATCH_FILTER_OUT_MAX + 1];
+ 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: prefix output with filter->name tag
// XXX: implement output formatting
- // XXX: escape the output data
// XXX: what to do for truncated data?
// discard based on source?
if (filter->source && source != filter->source)
return SUCCESS;
- // match against the regexp
- if ((ret = pcre_exec(filter->regexp, NULL, line, strlen(line), 0, 0, ovec, LOGWATCH_FILTER_OVEC_ITEMS)) <= 0) {
+ // match against the regexp?
+ if (filter->regexp && (ret = pcre_exec(filter->regexp, NULL, line, strlen(line), 0, 0, ovec, LOGWATCH_FILTER_OVEC_ITEMS)) <= 0) {
if (ret == PCRE_ERROR_NOMATCH)
// no match, ignore
return SUCCESS;
@@ -92,20 +95,20 @@
RETURN_SET_ERROR_EXTRA(err, ERR_PCRE_EXEC, ret);
}
+ // format header
+ buf_ptr += str_advance(NULL, &buf_size, str_append_fmt(buf_ptr, buf_size, "[%.12s] ", filter->name));
+
// format?
if (filter->format) {
return SET_ERROR(err, -2);
} else {
- // copy the line directly
- if (strlen(line) > LOGWATCH_FILTER_OUT_MAX)
- return SET_ERROR(err, -3);
-
- strcpy(out_buf, line);
+ // quote the entire line
+ buf_ptr += str_advance(NULL, &buf_size, str_quote(buf_ptr, buf_size, line, -1));
}
// then send it as a notice
- if ((ERROR_CODE(err) = irc_chan_NOTICE(filter->chan, out_buf)))
+ if ((ERROR_CODE(err) = irc_chan_NOTICE(filter->chan, buf)))
goto error;
// ok
--- a/src/str.c Sat Apr 11 04:26:46 2009 +0300
+++ b/src/str.c Sat Apr 11 04:41:44 2009 +0300
@@ -6,12 +6,7 @@
#include <string.h>
#include <assert.h>
-/**
- * Writes the given string into the given buffer, writing at most buf_size bytes, including the terminating NUL.
- *
- * Returns the number of input bytes that would have been written, not including the terminating NUL.
- */
-static size_t str_append (char *buf, size_t buf_size, const char *str)
+size_t str_append (char *buf, size_t buf_size, const char *str)
{
size_t str_len;
@@ -31,12 +26,7 @@
return str_len;
}
-/**
- * Like str_append, but only a single char.
- *
- * @see str_append()
- */
-static size_t str_append_char (char *buf, size_t buf_size, char c)
+size_t str_append_char (char *buf, size_t buf_size, char c)
{
if (buf_size > 1)
*buf++ = c;
@@ -47,12 +37,7 @@
return 1;
}
-/**
- * Like str_append, but using formatted input instead.
- *
- * @see str_append()
- */
-static size_t str_append_fmt (char *buf, size_t buf_size, const char *fmt, ...)
+size_t str_append_fmt (char *buf, size_t buf_size, const char *fmt, ...)
{
va_list vargs;
int ret;
@@ -86,10 +71,7 @@
{ 0, NULL }
};
-/**
- * Use str_append* to write out the quoted char value to the given buffer.
- */
-static size_t str_quote_char (char *buf, size_t buf_size, char c)
+size_t str_quote_char (char *buf, size_t buf_size, char c)
{
const struct str_quote_item *quote_item = _quote_table;
@@ -121,6 +103,9 @@
return len;
}
+/**
+ * Number of bytes reserved by str_quote for the trailing overflow stuff
+ */
#define STR_QUOTE_RESERVED 5
size_t str_quote (char *buf, size_t buf_size, const char *str, ssize_t str_len)
--- a/src/str.h Sat Apr 11 04:26:46 2009 +0300
+++ b/src/str.h Sat Apr 11 04:41:44 2009 +0300
@@ -9,6 +9,42 @@
#include <sys/types.h>
/**
+ * Writes the given string into the given buffer, writing at most buf_size bytes, including the terminating NUL.
+ *
+ * Returns the number of input bytes that would have been written, not including the terminating NUL.
+ */
+size_t str_append (char *buf, size_t buf_size, const char *str);
+
+/**
+ * Like str_append, but only a single char.
+ *
+ * @see str_append()
+ */
+size_t str_append_char (char *buf, size_t buf_size, char c);
+
+/**
+ * Like str_append, but using formatted input instead.
+ *
+ * @see str_append()
+ */
+size_t str_append_fmt (char *buf, size_t buf_size, const char *fmt, ...);
+
+/**
+ * Use str_append* to write out the quoted char value to the given buffer.
+ */
+size_t str_quote_char (char *buf, size_t buf_size, char c);
+
+/**
+ * Update data_size to add len (if given), then update buf_size to remove to min(buf_size, len), and return len.
+ *
+ * Intended to be used like:
+ * \code
+ * buf += str_advance(&data_size, &buf_size, str_append_fmt(buf, buf_size, "...", ...));
+ * \endcode
+ */
+size_t str_advance (size_t *data_size, size_t *buf_size, size_t len);
+
+/**
* Copy the given \a str into \buf, surrounding it with quotes and escaping any data inside.
*
* At most \a str_len bytes of input will be read, unless given as -1, whereupon str will be read up to the first \0 byte.