diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2013-08-24 00:49:33 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2013-08-24 00:49:33 +0100 |
commit | 65dd73840b8795f6744ed02570027ef3d840ef75 (patch) | |
tree | 74a9849cce6cb46ebe4d9e8fff810a7c8ff1c6b8 | |
parent | 5787cb059702f2677c0ec6abc87f3d1de5d1aff9 (diff) | |
download | rspamd-65dd73840b8795f6744ed02570027ef3d840ef75.tar.gz rspamd-65dd73840b8795f6744ed02570027ef3d840ef75.zip |
Add logging section handler.
-rw-r--r-- | src/cfg_rcl.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/cfg_rcl.c b/src/cfg_rcl.c index 7ca175123..864a0c935 100644 --- a/src/cfg_rcl.c +++ b/src/cfg_rcl.c @@ -24,6 +24,152 @@ #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; } |