]> source.dussan.org Git - rspamd.git/commitdiff
Add logging section handler.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 23 Aug 2013 23:49:33 +0000 (00:49 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 23 Aug 2013 23:49:33 +0000 (00:49 +0100)
src/cfg_rcl.c

index 7ca1751235eedab855b69b5ac2025a04dff97d48..864a0c93541e4ad2c59d2a48f2f11748a6072c5b 100644 (file)
 #include "cfg_rcl.h"
 #include "main.h"
 
+/*
+ * Common section handlers
+ */
+gboolean rspamd_rcl_logging_handler (struct config_file *cfg, rspamd_cl_object_t *obj,
+               gpointer ud, struct rspamd_rcl_section *section, GError **err)
+{
+       rspamd_cl_object_t *val;
+       gchar *filepath;
+       const gchar *facility, *log_type, *log_level;
+
+       obj = obj->value.ov;
+
+       HASH_FIND_STR (obj, "type", val);
+       if (val != NULL && rspamd_cl_obj_tostring_safe (val, &log_type)) {
+               if (g_ascii_strcasecmp (log_type, "file") == 0) {
+                       /* Need to get filename */
+                       HASH_FIND_STR (obj, "filename", val);
+                       if (val == NULL || val->type != RSPAMD_CL_STRING) {
+                               g_set_error (err, CFG_RCL_ERROR, ENOENT, "filename attribute must be specified for file logging type");
+                               return FALSE;
+                       }
+                       if ((filepath = realpath (rspamd_cl_obj_tostring (val), NULL)) == NULL ||
+                                       access (filepath, W_OK) == -1) {
+                               g_set_error (err, CFG_RCL_ERROR, errno, "log file is inaccessible");
+                               return FALSE;
+                       }
+                       cfg->log_type = RSPAMD_LOG_FILE;
+                       cfg->log_file = memory_pool_strdup (cfg->cfg_pool, filepath);
+               }
+               else if (g_ascii_strcasecmp (log_type, "syslog") == 0) {
+                       /* Need to get facility */
+                       cfg->log_facility = LOG_DAEMON;
+                       cfg->log_type = RSPAMD_LOG_SYSLOG;
+                       HASH_FIND_STR (obj, "facility", val);
+                       if (val != NULL && rspamd_cl_obj_tostring_safe (val, &facility)) {
+                               if (g_ascii_strcasecmp (facility, "LOG_AUTH") == 0 ||
+                                               g_ascii_strcasecmp (facility, "auth") == 0 ) {
+                                       cfg->log_facility = LOG_AUTH;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_CRON") == 0 ||
+                                               g_ascii_strcasecmp (facility, "cron") == 0 ) {
+                                       cfg->log_facility = LOG_CRON;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_DAEMON") == 0 ||
+                                               g_ascii_strcasecmp (facility, "daemon") == 0 ) {
+                                       cfg->log_facility = LOG_DAEMON;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_MAIL") == 0 ||
+                                               g_ascii_strcasecmp (facility, "mail") == 0) {
+                                       cfg->log_facility = LOG_MAIL;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_USER") == 0 ||
+                                               g_ascii_strcasecmp (facility, "user") == 0 ) {
+                                       cfg->log_facility = LOG_USER;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_LOCAL0") == 0 ||
+                                               g_ascii_strcasecmp (facility, "local0") == 0) {
+                                       cfg->log_facility = LOG_LOCAL0;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_LOCAL1") == 0 ||
+                                               g_ascii_strcasecmp (facility, "local1") == 0) {
+                                       cfg->log_facility = LOG_LOCAL1;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_LOCAL2") == 0 ||
+                                               g_ascii_strcasecmp (facility, "local2") == 0) {
+                                       cfg->log_facility = LOG_LOCAL2;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_LOCAL3") == 0 ||
+                                               g_ascii_strcasecmp (facility, "local3") == 0) {
+                                       cfg->log_facility = LOG_LOCAL3;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_LOCAL4") == 0 ||
+                                               g_ascii_strcasecmp (facility, "local4") == 0) {
+                                       cfg->log_facility = LOG_LOCAL4;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_LOCAL5") == 0 ||
+                                               g_ascii_strcasecmp (facility, "local5") == 0) {
+                                       cfg->log_facility = LOG_LOCAL5;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_LOCAL6") == 0 ||
+                                               g_ascii_strcasecmp (facility, "local6") == 0) {
+                                       cfg->log_facility = LOG_LOCAL6;
+                               }
+                               else if (g_ascii_strcasecmp (facility, "LOG_LOCAL7") == 0 ||
+                                               g_ascii_strcasecmp (facility, "local7") == 0) {
+                                       cfg->log_facility = LOG_LOCAL7;
+                               }
+                               else {
+                                       g_set_error (err, CFG_RCL_ERROR, EINVAL, "invalid log facility: %s", facility);
+                                       return FALSE;
+                               }
+                       }
+               }
+               else if (g_ascii_strcasecmp (log_type, "stderr") == 0 || g_ascii_strcasecmp (log_type, "console") == 0) {
+                       cfg->log_type = RSPAMD_LOG_CONSOLE;
+               }
+               else {
+                       g_set_error (err, CFG_RCL_ERROR, EINVAL, "invalid log type: %s", log_type);
+                       return FALSE;
+               }
+       }
+       else {
+               /* No type specified */
+               msg_warn ("logging type is not specified correctly, log output to the console");
+       }
+
+       /* Handle log level */
+       HASH_FIND_STR (obj, "level", val);
+       if (val != NULL && rspamd_cl_obj_tostring_safe (val, &log_level)) {
+               if (g_ascii_strcasecmp (log_level, "error") == 0) {
+                       cfg->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL;
+               }
+               else if (g_ascii_strcasecmp (log_level, "warning") == 0) {
+                       cfg->log_level = G_LOG_LEVEL_WARNING;
+               }
+               else if (g_ascii_strcasecmp (log_level, "info") == 0) {
+                       cfg->log_level = G_LOG_LEVEL_INFO | G_LOG_LEVEL_MESSAGE;
+               }
+               else if (g_ascii_strcasecmp (log_level, "debug") == 0) {
+                       cfg->log_level = G_LOG_LEVEL_DEBUG;
+               }
+               else {
+                       g_set_error (err, CFG_RCL_ERROR, EINVAL, "invalid log level: %s", log_level);
+                       return FALSE;
+               }
+       }
+
+       return TRUE;
+}
+
+static inline void
+rspamd_rcl_add_section (struct rspamd_rcl_section *top,
+               const gchar *name, rspamd_rcl_handler_t handler,
+               enum rspamd_cl_type type, gboolean required, gboolean strict_type)
+{
+       struct rspamd_rcl_section *new;
+
+       new = g_slice_alloc0 (sizeof (struct rspamd_rcl_section));
+       new->name = name;
+       new->handler = handler;
+       new->type = type;
+       new->strict_type = strict_type;
+
+       HASH_ADD_KEYPTR (hh, top, new->name, strlen (new->name), new);
+}
+
 struct rspamd_rcl_section*
 rspamd_rcl_config_init (void)
 {
@@ -32,6 +178,8 @@ rspamd_rcl_config_init (void)
        new = g_slice_alloc0 (sizeof (struct rspamd_rcl_section));
 
        /* TODO: add all known rspamd sections here */
+       rspamd_rcl_add_section (new, "logging", rspamd_rcl_logging_handler, RSPAMD_CL_OBJECT,
+                       FALSE, TRUE);
 
        return new;
 }