Add log_format configuration variable.
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Mon, 10 Nov 2008 23:46:23 +0000 (00:46 +0100)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Mon, 10 Nov 2008 23:46:23 +0000 (00:46 +0100)
Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
example/postlicyd.conf
postlicyd/config.c
postlicyd/config.h
postlicyd/filter.c
postlicyd/filter.h
postlicyd/greylist.c
postlicyd/main-postlicyd.c
postlicyd/query.c
postlicyd/query.h

index 61b2c2c..cff01b9 100644 (file)
@@ -346,4 +346,15 @@ recipient_filter = client_whitelist;
 
 port = 10000;
 
+
+# LOG FORMAT
+#
+# Format of the log printed in syslog. The actual format is "${log_format}: ..."
+#
+# This parameter uses the same format as used to reply to postfix (${field_name} to
+# add a field name).
+
+log_format = "request client=${client_name}[${client_address}] from=<${sender}> "
+             "to=<${recipient}> at ${protocol_state}";
+
 # vim:set syntax=conf:
index 9c28895..2541be6 100644 (file)
@@ -79,6 +79,12 @@ config_param_register("verify_filter");
 config_param_register("port");
 
 
+/* Format of the log message.
+ * The message exact format is $log: "reply"
+ */
+config_param_register("log_format");
+
+
 static config_t *global_config = NULL;
 
 static inline config_t *config_new(void)
@@ -95,6 +101,7 @@ static void config_close(config_t *config)
     }
     array_deep_wipe(config->filters, filter_wipe);
     array_deep_wipe(config->params, filter_params_wipe);
+    p_delete(&config->log_format);
 }
 
 void config_delete(config_t **config)
@@ -396,11 +403,17 @@ static bool config_build_structure(config_t *config)
           CASE(ETRN,        ETRN)
 #undef    CASE
           FILTER_PARAM_PARSE_INT(PORT, config->port);
+          FILTER_PARAM_PARSE_STRING(LOG_FORMAT, config->log_format, true);
           default: break;
         }
     }}
     array_deep_wipe(config->params, filter_params_wipe);
 
+    if (config->log_format && !query_format_check(config->log_format)) {
+        err("invalid log format: \"%s\"", config->log_format);
+        return false;
+    }
+
     if (!ok) {
         err("no entry point defined");
     }
index 26fb619..b60002d 100644 (file)
@@ -65,8 +65,16 @@ struct config_t {
      * The parameter from CLI override the parameter from configuration file.
      */
     uint16_t port;
+
+    /* Log message.
+     */
+    char *log_format;
 };
 
+#define DEFAULT_LOG_FORMAT                                                     \
+    "request client=${client_name}[${client_address}] from=<${sender}> "       \
+    "to=<${recipient}> at ${protocol_state}"
+
 __attribute__((nonnull(1)))
 config_t *config_read(const char *file);
 
index e108b25..ab608d8 100644 (file)
@@ -324,7 +324,7 @@ bool filter_add_hook(filter_t *filter, const char *name, int name_len,
         hook.cost    = 0;
     }
     hook.postfix = (strncmp(value, "postfix:", 8) == 0);
-    if (hook.postfix && query_format(NULL, 0, value + 8, NULL) == -1) {
+    if (hook.postfix && !query_format_check(value + 8)) {
         err("invalid formatted text \"%s\"", value + 8);
         return false;
     }
index 39c3119..c50169d 100644 (file)
@@ -242,9 +242,9 @@ bool filter_test(const filter_t *filter, const query_t *query,
 /* Parsing Helpers
  */
 
-#define FILTER_PARAM_PARSE_STRING(Param, Dest)                                 \
+#define FILTER_PARAM_PARSE_STRING(Param, Dest, Copy)                           \
     case ATK_ ## Param: {                                                      \
-        (Dest) = param->value;                                                 \
+        (Dest) = (Copy) ? m_strdup(param->value) : param->value;               \
     } break
 
 #define FILTER_PARAM_PARSE_INT(Param, Dest)                                    \
index 1a7d68e..9626c20 100644 (file)
@@ -506,8 +506,8 @@ static bool greylist_filter_constructor(filter_t *filter)
 
     foreach (filter_param_t *param, filter->params) {
         switch (param->type) {
-          FILTER_PARAM_PARSE_STRING(PATH,   path);
-          FILTER_PARAM_PARSE_STRING(PREFIX, prefix);
+          FILTER_PARAM_PARSE_STRING(PATH,   path, false);
+          FILTER_PARAM_PARSE_STRING(PREFIX, prefix, false);
           FILTER_PARAM_PARSE_BOOLEAN(LOOKUP_BY_HOST, config->lookup_by_host);
           FILTER_PARAM_PARSE_BOOLEAN(NO_SENDER, config->no_sender);
           FILTER_PARAM_PARSE_BOOLEAN(NO_RECIPIENT, config->no_recipient);
index dab0bf0..a4543ec 100644 (file)
@@ -103,21 +103,8 @@ static void policy_answer(client_t *pcy, const char *message)
 
     /* Write reply "action=ACTION [text]" */
     buffer_addstr(buf, "action=");
-    buffer_ensure(buf, m_strlen(message) + 64);
-
-    ssize_t size = array_size(*buf) - array_len(*buf);
-    ssize_t format_size = query_format(array_ptr(*buf, array_len(*buf)),
-                                       size, message, query);
-    if (format_size == -1) {
+    if (!query_format_buffer(buf, message, query)) {
         buffer_addstr(buf, message);
-    } else if (format_size > size) {
-        buffer_ensure(buf, format_size + 1);
-        query_format(array_ptr(*buf, array_len(*buf)),
-                     array_size(*buf) - array_len(*buf),
-                     message, query);
-        array_len(*buf) += format_size;
-    } else {
-        array_len(*buf) += format_size;
     }
     buffer_addstr(buf, "\n\n");
 
@@ -129,43 +116,49 @@ static void policy_answer(client_t *pcy, const char *message)
 
 static const filter_t *next_filter(client_t *pcy, const filter_t *filter,
                                    const query_t *query, const filter_hook_t *hook, bool *ok) {
-#define MESSAGE_FORMAT "request client=%s from=<%s> to=<%s> at %s: "
-#define MESSAGE_PARAMS query->client_name,                                          \
-                  query->sender == NULL ? "undefined" : query->sender,              \
-                  query->recipient == NULL ? "undefined" : query->recipient,        \
-                  smtp_state_names[query->state]
+    char log_prefix[BUFSIZ];
+    log_prefix[0] = '\0';
+
+#define log_reply(Level, Msg, ...)                                             \
+    if (log_level >= LOG_ ## Level) {                                          \
+        if (log_prefix[0] == '\0') {                                           \
+            query_format(log_prefix, BUFSIZ,                                   \
+                         config->log_format && config->log_format[0] ?         \
+                            config->log_format : DEFAULT_LOG_FORMAT, query);   \
+        }                                                                      \
+        __log(LOG_ ## Level, "%s: " Msg, log_prefix, ##__VA_ARGS__);           \
+    }
 
     if (hook != NULL) {
         query_context_t *context = client_data(pcy);
         if (hook->counter >= 0 && hook->counter < MAX_COUNTERS && hook->cost > 0) {
             context->context.counters[hook->counter] += hook->cost;
-            debug(MESSAGE_FORMAT "added %d to counter %d (now %u)", MESSAGE_PARAMS,
-                  hook->cost, hook->counter, context->context.counters[hook->counter]);
+            log_reply(DEBUG, "added %d to counter %d (now %u)",
+                      hook->cost, hook->counter,
+                      context->context.counters[hook->counter]);
         }
     }
     if (hook == NULL) {
-        warn(MESSAGE_FORMAT "aborted", MESSAGE_PARAMS);
+        log_reply(WARNING, "aborted");
         *ok = false;
         return NULL;
     } else if (hook->async) {
-        debug(MESSAGE_FORMAT "asynchronous filter from filter %s",
-              MESSAGE_PARAMS, filter->name);
+        log_reply(WARNING, "asynchronous filter from filter %s", filter->name);
         *ok = true;
         return NULL;
     } else if (hook->postfix) {
-        info(MESSAGE_FORMAT "awswer %s from filter %s: \"%s\"", MESSAGE_PARAMS,
-             htokens[hook->type], filter->name, hook->value);
+        log_reply(INFO, "awswer %s from filter %s: \"%s\"",
+                  htokens[hook->type], filter->name, hook->value);
         policy_answer(pcy, hook->value);
         *ok = true;
         return NULL;
     } else {
-        debug(MESSAGE_FORMAT "awswer %s from filter %s: next filter %s",
-              MESSAGE_PARAMS, htokens[hook->type], filter->name,
-              (array_ptr(config->filters, hook->filter_id))->name);
+        log_reply(DEBUG,  "awswer %s from filter %s: next filter %s",
+                  htokens[hook->type], filter->name,
+                  (array_ptr(config->filters, hook->filter_id))->name);
         return array_ptr(config->filters, hook->filter_id);
     }
-#undef MESSAGE_PARAMS
-#undef MESSAGE_FORMAT
+#undef log_reply
 }
 
 static bool policy_process(client_t *pcy, const config_t *mconfig)
index 4a4ae9c..599b9ec 100644 (file)
@@ -259,3 +259,24 @@ ssize_t query_format(char *dest, size_t len, const char *fmt, const query_t *que
     }
     return pos;
 }
+
+bool query_format_buffer(buffer_t *buf, const char *fmt, const query_t *query)
+{
+    buffer_ensure(buf, m_strlen(fmt) + 64);
+
+    ssize_t size = array_free_space(*buf);
+    ssize_t format_size = query_format(array_end(*buf),
+                                       size, fmt, query);
+    if (format_size == -1) {
+        return false;
+    } else if (format_size > size) {
+        buffer_ensure(buf, format_size + 1);
+        query_format(array_end(*buf),
+                     array_free_space(*buf),
+                     fmt, query);
+        array_len(*buf) += format_size;
+    } else {
+        array_len(*buf) += format_size;
+    }
+    return true;
+}
index 9dabfe0..7e9dc7f 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "mem.h"
 #include "common.h"
+#include "buffer.h"
 #include "policy_tokens.h"
 
 enum smtp_state {
@@ -122,4 +123,13 @@ const char *query_field_for_id(const query_t *query, postlicyd_token id);
 __attribute__((nonnull(3)))
 ssize_t query_format(char *dest, size_t len, const char* fmt, const query_t *query);
 
+/** Writes a query-formated string in a buffer.
+ */
+__attribute__((nonnull(1,2)))
+bool query_format_buffer(buffer_t *buf, const char *fmt, const query_t *query);
+
+/** Check the query-format string.
+ */
+#define query_format_check(fmt) (query_format(NULL, 0, fmt, NULL) >= 0)
+
 #endif