update logwatch_filter_apply
authorTero Marttila <terom@fixme.fi>
Sat, 11 Apr 2009 04:41:44 +0300
changeset 128 6c5a5fdfd1d5
parent 127 94e6c3b4230f
child 129 361740b82fe5
update logwatch_filter_apply
src/modules/logwatch_filter.c
src/str.c
src/str.h
--- 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.