diff options
-rw-r--r-- | CMakeLists.txt | 63 | ||||
-rw-r--r-- | lib/CMakeLists.txt | 50 | ||||
-rw-r--r-- | lib/librspamdclient.c | 163 | ||||
-rw-r--r-- | src/buffer.c | 2 | ||||
-rw-r--r-- | src/cfg_file.h | 2 | ||||
-rw-r--r-- | src/cfg_utils.c | 10 | ||||
-rw-r--r-- | src/cfg_xml.c | 6 | ||||
-rw-r--r-- | src/client/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/controller.c | 2 | ||||
-rw-r--r-- | src/expressions.c | 6 | ||||
-rw-r--r-- | src/fuzzy_storage.c | 3 | ||||
-rw-r--r-- | src/greylist_storage.c | 1 | ||||
-rw-r--r-- | src/lmtp.c | 3 | ||||
-rw-r--r-- | src/logger.c | 244 | ||||
-rw-r--r-- | src/logger.h | 31 | ||||
-rw-r--r-- | src/lua/lua_common.c | 8 | ||||
-rw-r--r-- | src/main.c | 212 | ||||
-rw-r--r-- | src/main.h | 14 | ||||
-rw-r--r-- | src/mem_pool.c | 1 | ||||
-rw-r--r-- | src/message.c | 2 | ||||
-rw-r--r-- | src/printf.c | 566 | ||||
-rw-r--r-- | src/printf.h | 61 | ||||
-rw-r--r-- | src/smtp.c | 9 | ||||
-rw-r--r-- | src/symbols_cache.c | 4 | ||||
-rw-r--r-- | src/tokenizers/osb.c | 3 | ||||
-rw-r--r-- | src/util.c | 721 | ||||
-rw-r--r-- | src/util.h | 48 | ||||
-rw-r--r-- | src/worker.c | 187 | ||||
-rw-r--r-- | test/CMakeLists.txt | 29 | ||||
-rw-r--r-- | test/rspamd_dns_test.c | 1 | ||||
-rw-r--r-- | test/rspamd_test_suite.c | 15 | ||||
-rw-r--r-- | utils/statshow/CMakeLists.txt | 22 | ||||
-rw-r--r-- | utils/statshow/statshow.c | 56 |
33 files changed, 1383 insertions, 1163 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 47770487a..bbe628dd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -539,58 +539,17 @@ ENDIF(HG) ################################ SOURCES SECTION ########################### + SET(RSPAMDSRC src/modules.c - src/binlog.c - src/bloom.c - src/buffer.c - src/cfg_utils.c - src/cfg_xml.c src/controller.c - src/dns.c - src/events.c - src/expressions.c - src/filter.c - src/fstring.c - src/fuzzy.c src/fuzzy_storage.c src/greylist_storage.c - src/hash.c - src/html.c - src/images.c src/lmtp.c - src/lmtp_proto.c - src/logger.c src/main.c src/map.c - src/memcached.c - src/mem_pool.c - src/message.c - src/protocol.c - src/radix.c - src/settings.c - src/spf.c src/smtp.c - src/smtp_proto.c - src/smtp_utils.c - src/statfile.c - src/statfile_sync.c - src/symbols_cache.c - src/trie.c - src/upstream.c - src/url.c - src/util.c - src/view.c src/worker.c) -ADD_SUBDIRECTORY(src/lua) -ADD_SUBDIRECTORY(lib) -ADD_SUBDIRECTORY(src/client) - -ADD_SUBDIRECTORY(src/json) -ADD_SUBDIRECTORY(src/cdb) -ADD_SUBDIRECTORY(utils) -ADD_SUBDIRECTORY(test) - SET(TOKENIZERSSRC src/tokenizers/tokenizers.c src/tokenizers/osb.c) @@ -604,6 +563,17 @@ SET(PLUGINSSRC src/plugins/surbl.c src/plugins/fuzzy_check.c src/plugins/spf.c) +ADD_SUBDIRECTORY(src/lua) +ADD_SUBDIRECTORY(src/json) +ADD_SUBDIRECTORY(src/cdb) + +ADD_SUBDIRECTORY(lib) +ADD_SUBDIRECTORY(src/client) + +ADD_SUBDIRECTORY(utils) +ADD_SUBDIRECTORY(test) + + LIST(LENGTH PLUGINSSRC RSPAMD_MODULES_NUM) ############################ TARGETS SECTION ############################### @@ -617,13 +587,16 @@ CONFIGURE_FILE(contrib/exim/local_scan.c.in contrib/exim/local_scan_rspamd.c @ON CONFIGURE_FILE(rspamd.xml.sample conf/rspamd.xml.sample @ONLY) ######################### LINK SECTION ############################### + + ADD_EXECUTABLE(rspamd ${RSPAMDSRC} ${CONTRIBSRC} ${TOKENIZERSSRC} ${CLASSIFIERSSRC} ${PLUGINSSRC}) SET_TARGET_PROPERTIES(rspamd PROPERTIES LINKER_LANGUAGE C) SET_TARGET_PROPERTIES(rspamd PROPERTIES COMPILE_FLAGS "-DRSPAMD_MAIN") SET_TARGET_PROPERTIES(rspamd PROPERTIES VERSION ${RSPAMD_VERSION}) -TARGET_LINK_LIBRARIES(rspamd rspamd_lua) +TARGET_LINK_LIBRARIES(rspamd rspamdserver) + IF(ENABLE_LUAJIT MATCHES "ON") TARGET_LINK_LIBRARIES(rspamd "${LUAJIT_LIBRARY}") ELSE(ENABLE_LUAJIT MATCHES "ON") @@ -633,10 +606,8 @@ ENDIF(ENABLE_LUAJIT MATCHES "ON") IF(LIBJUDY_LIBRARY) TARGET_LINK_LIBRARIES(rspamd Judy) ENDIF(LIBJUDY_LIBRARY) -# TARGET_LINK_LIBRARIES(rspamd rspamd_evdns) TARGET_LINK_LIBRARIES(rspamd event) -TARGET_LINK_LIBRARIES(rspamd rspamd_json) -TARGET_LINK_LIBRARIES(rspamd rspamd_cdb) + TARGET_LINK_LIBRARIES(rspamd ${CMAKE_REQUIRED_LIBRARIES}) TARGET_LINK_LIBRARIES(rspamd ${GLIB2_LIBRARIES}) IF(GMIME2_FOUND) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 5b30f041b..951551e62 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,5 +1,5 @@ -# Librspamd -SET(LIBRSPAMDSRC librspamdclient.c ../src/util.c ../src/upstream.c ../src/mem_pool.c) +# Librspamdclient +SET(LIBRSPAMDSRC librspamdclient.c ../src/mem_pool.c ../src/upstream.c ../src/printf.c) ADD_LIBRARY(rspamdclient SHARED ${LIBRSPAMDSRC}) ADD_LIBRARY(rspamdclient_static STATIC ${LIBRSPAMDSRC}) @@ -9,6 +9,7 @@ SET_TARGET_PROPERTIES(rspamdclient_static PROPERTIES COMPILE_FLAGS "-fno-strict- TARGET_LINK_LIBRARIES(rspamdclient ${CMAKE_REQUIRED_LIBRARIES}) TARGET_LINK_LIBRARIES(rspamdclient ${GLIB2_LIBRARIES}) + TARGET_LINK_LIBRARIES(rspamdclient_static ${CMAKE_REQUIRED_LIBRARIES}) TARGET_LINK_LIBRARIES(rspamdclient_static ${GLIB2_LIBRARIES}) @@ -19,3 +20,48 @@ INSTALL(TARGETS rspamdclient rspamdclient_static LIBRARY PUBLIC_HEADER LIBRARY DESTINATION lib PUBLIC_HEADER DESTINATION include ARCHIVE DESTINATION lib) + + +# Librspamdserver +SET(RSPAMDLIBSRC ../src/binlog.c + ../src/bloom.c + ../src/buffer.c + ../src/cfg_utils.c + ../src/cfg_xml.c + ../src/dns.c + ../src/events.c + ../src/expressions.c + ../src/filter.c + ../src/fstring.c + ../src/fuzzy.c + ../src/hash.c + ../src/html.c + ../src/images.c + ../src/lmtp_proto.c + ../src/logger.c + ../src/map.c + ../src/memcached.c + ../src/mem_pool.c + ../src/message.c + ../src/printf.c + ../src/protocol.c + ../src/radix.c + ../src/settings.c + ../src/spf.c + ../src/smtp_proto.c + ../src/smtp_utils.c + ../src/statfile.c + ../src/statfile_sync.c + ../src/symbols_cache.c + ../src/trie.c + ../src/upstream.c + ../src/url.c + ../src/util.c + ../src/view.c) + +ADD_LIBRARY(rspamdserver STATIC ${RSPAMDLIBSRC}) +SET_TARGET_PROPERTIES(rspamdserver PROPERTIES LINKER_LANGUAGE C) +SET_TARGET_PROPERTIES(rspamdserver PROPERTIES COMPILE_FLAGS "-DRSPAMD_LIB") +TARGET_LINK_LIBRARIES(rspamdserver rspamd_lua) +TARGET_LINK_LIBRARIES(rspamdserver rspamd_json) +TARGET_LINK_LIBRARIES(rspamdserver rspamd_cdb)
\ No newline at end of file diff --git a/lib/librspamdclient.c b/lib/librspamdclient.c index fa92df208..0c624e2e2 100644 --- a/lib/librspamdclient.c +++ b/lib/librspamdclient.c @@ -27,10 +27,13 @@ #include "upstream.h" #include "util.h" #include "cfg_file.h" +#include "logger.h" #define MAX_RSPAMD_SERVERS 255 #define DEFAULT_CONNECT_TIMEOUT 500 #define DEFAULT_READ_TIMEOUT 5000 +/* Default connect timeout for sync sockets */ +#define CONNECT_TIMEOUT 3 #define G_RSPAMD_ERROR rspamd_error_quark () struct rspamd_server { @@ -60,6 +63,144 @@ struct rspamd_connection { static struct rspamd_client *client = NULL; +/** Util functions **/ +gint +make_socket_nonblocking (gint fd) +{ + gint ofl; + + ofl = fcntl (fd, F_GETFL, 0); + + if (fcntl (fd, F_SETFL, ofl | O_NONBLOCK) == -1) { + msg_warn ("fcntl failed: %d, '%s'", errno, strerror (errno)); + return -1; + } + return 0; +} + +gint +make_socket_blocking (gint fd) +{ + gint ofl; + + ofl = fcntl (fd, F_GETFL, 0); + + if (fcntl (fd, F_SETFL, ofl & (~O_NONBLOCK)) == -1) { + msg_warn ("fcntl failed: %d, '%s'", errno, strerror (errno)); + return -1; + } + return 0; +} + +gint +poll_sync_socket (gint fd, gint timeout, short events) +{ + gint r; + struct pollfd fds[1]; + + fds->fd = fd; + fds->events = events; + fds->revents = 0; + while ((r = poll (fds, 1, timeout)) < 0) { + if (errno != EINTR) { + break; + } + } + + return r; +} + +static gint +make_inet_socket (gint family, struct in_addr *addr, u_short port, gboolean is_server, gboolean async) +{ + gint fd, r, optlen, on = 1, s_error; + gint serrno; + struct sockaddr_in sin; + + /* Create socket */ + fd = socket (AF_INET, family, 0); + if (fd == -1) { + msg_warn ("socket failed: %d, '%s'", errno, strerror (errno)); + return -1; + } + + if (make_socket_nonblocking (fd) < 0) { + goto out; + } + + /* Set close on exec */ + if (fcntl (fd, F_SETFD, FD_CLOEXEC) == -1) { + msg_warn ("fcntl failed: %d, '%s'", errno, strerror (errno)); + goto out; + } + + memset (&sin, 0, sizeof (sin)); + + /* Bind options */ + sin.sin_family = AF_INET; + sin.sin_port = htons (port); + sin.sin_addr.s_addr = addr->s_addr; + + if (is_server) { + setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof (gint)); + r = bind (fd, (struct sockaddr *)&sin, sizeof (struct sockaddr_in)); + } + else { + r = connect (fd, (struct sockaddr *)&sin, sizeof (struct sockaddr_in)); + } + + if (r == -1) { + if (errno != EINPROGRESS) { + msg_warn ("bind/connect failed: %d, '%s'", errno, strerror (errno)); + goto out; + } + if (!async) { + /* Try to poll */ + if (poll_sync_socket (fd, CONNECT_TIMEOUT * 1000, POLLOUT) <= 0) { + errno = ETIMEDOUT; + msg_warn ("bind/connect failed: timeout"); + goto out; + } + else { + /* Make synced again */ + if (make_socket_blocking (fd) < 0) { + goto out; + } + } + } + } + else { + /* Still need to check SO_ERROR on socket */ + optlen = sizeof (s_error); + getsockopt (fd, SOL_SOCKET, SO_ERROR, (void *)&s_error, &optlen); + if (s_error) { + errno = s_error; + goto out; + } + } + + + return (fd); + + out: + serrno = errno; + close (fd); + errno = serrno; + return (-1); +} + +gint +make_tcp_socket (struct in_addr *addr, u_short port, gboolean is_server, gboolean async) +{ + return make_inet_socket (SOCK_STREAM, addr, port, is_server, async); +} + +gint +make_udp_socket (struct in_addr *addr, u_short port, gboolean is_server, gboolean async) +{ + return make_inet_socket (SOCK_DGRAM, addr, port, is_server, async); +} + /** Private functions **/ static inline GQuark rspamd_error_quark (void) @@ -847,16 +988,16 @@ rspamd_send_normal_command (struct rspamd_connection *c, const gchar *command, gint r; /* Write command */ - r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s RSPAMC/1.3\r\n", command); - r += rspamd_snprintf (outbuf + r, sizeof (outbuf) - r, "Content-Length: %uz\r\n", clen); + r = snprintf (outbuf, sizeof (outbuf), "%s RSPAMC/1.3\r\n", command); + r += snprintf (outbuf + r, sizeof (outbuf) - r, "Content-Length: %lu\r\n", (unsigned long)clen); /* Iterate through headers */ if (headers != NULL) { g_hash_table_iter_init (&it, headers); while (g_hash_table_iter_next (&it, &key, &value)) { - r += rspamd_snprintf (outbuf + r, sizeof (outbuf) - r, "%s: %s\r\n", key, value); + r += snprintf (outbuf + r, sizeof (outbuf) - r, "%s: %s\r\n", (const gchar *)key, (const gchar *)value); } } - r += rspamd_snprintf (outbuf + r, sizeof (outbuf) - r, "\r\n"); + r += snprintf (outbuf + r, sizeof (outbuf) - r, "\r\n"); if ((r = write (c->socket, outbuf, r)) == -1) { if (*err == NULL) { @@ -967,7 +1108,7 @@ rspamd_controller_auth (struct rspamd_connection *c, const gchar *password, GErr gint r; GString *in; - r = rspamd_snprintf (outbuf, sizeof (outbuf), "password %s\r\n", password); + r = snprintf (outbuf, sizeof (outbuf), "password %s\r\n", password); in = rspamd_send_controller_command (c, outbuf, r, -1, err); if (in == NULL) { @@ -1249,7 +1390,7 @@ rspamd_learn_memory (const guchar *message, gsize length, const gchar *symbol, c r = length + sizeof ("learn %s %uz\r\n") + strlen (symbol) + sizeof ("4294967296"); outbuf = g_malloc (r); - r = rspamd_snprintf (outbuf, r, "learn %s %uz\r\n%s", symbol, length, message); + r = snprintf (outbuf, r, "learn %s %lu\r\n%s", symbol, (unsigned long)length, message); in = rspamd_send_controller_command (c, outbuf, r, -1, err); g_free (outbuf); if (in == NULL) { @@ -1337,7 +1478,7 @@ rspamd_learn_fd (int fd, const gchar *symbol, const gchar *password, GError **er } r = sizeof ("learn %s %uz\r\n") + strlen (symbol) + sizeof ("4294967296"); outbuf = g_malloc (r); - r = rspamd_snprintf (outbuf, r, "learn %s %uz\r\n", symbol, st.st_size); + r = snprintf (outbuf, r, "learn %s %lu\r\n", symbol, (unsigned long)st.st_size); in = rspamd_send_controller_command (c, outbuf, r, fd, err); g_free (outbuf); if (in == NULL) { @@ -1397,10 +1538,10 @@ rspamd_fuzzy_memory (const guchar *message, gsize length, const gchar *password, r = length + sizeof ("fuzzy_add %uz %d %d\r\n") + sizeof ("4294967296") * 3; outbuf = g_malloc (r); if (delete) { - r = rspamd_snprintf (outbuf, r, "fuzzy_del %uz %d %d\r\n%s", length, weight, flag, message); + r = snprintf (outbuf, r, "fuzzy_del %lu %d %d\r\n%s", (unsigned long)length, weight, flag, message); } else { - r = rspamd_snprintf (outbuf, r, "fuzzy_add %uz %d %d\r\n%s", length, weight, flag, message); + r = snprintf (outbuf, r, "fuzzy_add %lu %d %d\r\n%s", (unsigned long)length, weight, flag, message); } in = rspamd_send_controller_command (c, outbuf, r, -1, err); g_free (outbuf); @@ -1489,10 +1630,10 @@ rspamd_fuzzy_fd (int fd, const gchar *password, gint weight, gint flag, gboolean r = sizeof ("fuzzy_add %uz %d %d\r\n") + sizeof ("4294967296") * 3; outbuf = g_malloc (r); if (delete) { - r = rspamd_snprintf (outbuf, r, "fuzzy_del %uz %d %d\r\n", st.st_size, weight, flag); + r = snprintf (outbuf, r, "fuzzy_del %lu %d %d\r\n", (unsigned long)st.st_size, weight, flag); } else { - r = rspamd_snprintf (outbuf, r, "fuzzy_add %uz %d %d\r\n", st.st_size, weight, flag); + r = snprintf (outbuf, r, "fuzzy_add %lu %d %d\r\n", (unsigned long)st.st_size, weight, flag); } in = rspamd_send_controller_command (c, outbuf, r, fd, err); diff --git a/src/buffer.c b/src/buffer.c index f19d49e5d..ed39d9205 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -27,7 +27,7 @@ #include "main.h" #define G_DISPATCHER_ERROR dispatcher_error_quark() -#define debug_ip(...) rspamd_conditional_debug(d->peer_addr, __FUNCTION__, __VA_ARGS__) +#define debug_ip(...) rspamd_conditional_debug(rspamd_main->logger, d->peer_addr, __FUNCTION__, __VA_ARGS__) static void dispatcher_cb (gint fd, short what, void *arg); diff --git a/src/cfg_file.h b/src/cfg_file.h index 6fb4065e5..2d3cb20a0 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -267,6 +267,7 @@ struct config_file { gboolean log_urls; /**< whether we should log URLs */ GList *debug_symbols; /**< symbols to debug */ gboolean log_color; /**< output colors for console output */ + gboolean log_extended; /**< log extended information */ gsize max_statfile_size; /**< maximum size for statfile */ @@ -291,6 +292,7 @@ struct config_file { GList *filters; /**< linked list of all filters */ GList *workers; /**< linked list of all workers params */ gchar *filters_str; /**< string of filters */ + guint modules_num; GHashTable* modules_opts; /**< hash for module options indexed by module name */ GHashTable* variables; /**< hash of $variables defined in config, indexed by variable name */ GHashTable* metrics; /**< hash of metrics indexed by metric name */ diff --git a/src/cfg_utils.c b/src/cfg_utils.c index 9acb442b5..99a4bc3d9 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -31,9 +31,7 @@ #include "settings.h" #include "classifiers/classifiers.h" #include "cfg_xml.h" -#ifdef WITH_LUA #include "lua/lua_common.h" -#endif #define DEFAULT_SCORE 10.0 @@ -183,6 +181,10 @@ init_defaults (struct config_file *cfg) cfg->classifiers_symbols = g_hash_table_new (g_str_hash, g_str_equal); cfg->cfg_params = g_hash_table_new (g_str_hash, g_str_equal); cfg->metrics_symbols = g_hash_table_new (g_str_hash, g_str_equal); + + cfg->log_level = G_LOG_LEVEL_WARNING; + cfg->log_extended = TRUE; + init_settings (cfg); } @@ -528,9 +530,9 @@ parse_filters_str (struct config_file *cfg, const gchar *str) while (*p) { cur = NULL; /* Search modules from known C modules */ - for (i = 0; i < MODULES_NUM; i++) { + for (i = 0; i < cfg->modules_num; i++) { g_strstrip (*p); - if (strcasecmp (modules[i].name, *p) == 0) { + if (modules[i].name != NULL && g_ascii_strcasecmp (modules[i].name, *p) == 0) { cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct filter)); cur->type = C_FILTER; msg_debug ("found C filter %s", *p); diff --git a/src/cfg_xml.c b/src/cfg_xml.c index b84d556b7..7fda9e14f 100644 --- a/src/cfg_xml.c +++ b/src/cfg_xml.c @@ -33,12 +33,14 @@ #include "util.h" #include "classifiers/classifiers.h" #include "tokenizers/tokenizers.h" -#include "lua/lua_common.h" + #include "view.h" #include "map.h" #include "expressions.h" #include "settings.h" +#include "lua/lua_common.h" + /* Maximum attributes for param */ #define MAX_PARAM 64 @@ -1077,7 +1079,6 @@ handle_lua (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable return FALSE; } } - return TRUE; } @@ -1510,6 +1511,7 @@ rspamd_xml_start_element (GMarkupParseContext *context, const gchar *element_nam struct classifier_config *ccf; gchar *res, *condition; + if (g_ascii_strcasecmp (element_name, "if") == 0) { /* Push current state to queue */ g_queue_push_head (ud->if_stack, GSIZE_TO_POINTER ((gsize)ud->state)); diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index dee29b667..38a482d3c 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -3,6 +3,7 @@ SET(RSPAMCSRC rspamc.c) ADD_EXECUTABLE(rspamc ${RSPAMCSRC}) SET_TARGET_PROPERTIES(rspamc PROPERTIES COMPILE_FLAGS "-I.. -I../../lib") +TARGET_LINK_LIBRARIES(rspamc rspamdserver) TARGET_LINK_LIBRARIES(rspamc rspamdclient) TARGET_LINK_LIBRARIES(rspamc ${CMAKE_REQUIRED_LIBRARIES}) TARGET_LINK_LIBRARIES(rspamc ${GLIB2_LIBRARIES}) diff --git a/src/controller.c b/src/controller.c index a06351bb6..b29af9ee1 100644 --- a/src/controller.c +++ b/src/controller.c @@ -109,7 +109,7 @@ sig_handler (gint signo, siginfo_t *info, void *unused) struct timeval tv; switch (signo) { case SIGUSR1: - reopen_log (); + reopen_log (rspamd_main->logger); break; case SIGINT: case SIGTERM: diff --git a/src/expressions.c b/src/expressions.c index da17912ce..deb77e795 100644 --- a/src/expressions.c +++ b/src/expressions.c @@ -758,16 +758,13 @@ gboolean call_expression_function (struct expression_function * func, struct worker_task * task) { struct _fl *selected, key; -#ifdef RSPAMD_MAIN gboolean res; -#endif key.name = func->name; selected = bsearch (&key, list_ptr, functions_number, sizeof (struct _fl), fl_cmp); if (selected == NULL) { /* Try to check lua function */ -#ifdef RSPAMD_MAIN if (! lua_call_expression_func (NULL, func->name, task, func->args, &res)) { msg_warn ("call to undefined function %s", key.name); return FALSE; @@ -775,9 +772,6 @@ call_expression_function (struct expression_function * func, struct worker_task else { return res; } -#else - return FALSE; -#endif } return selected->func (task, func->args, selected->user_data); diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c index 344a0e345..45f24b950 100644 --- a/src/fuzzy_storage.c +++ b/src/fuzzy_storage.c @@ -103,7 +103,7 @@ sig_handler (gint signo, siginfo_t *info, void *unused) { switch (signo) { case SIGUSR1: - reopen_log (); + reopen_log (rspamd_main->logger); break; case SIGINT: case SIGTERM: @@ -264,7 +264,6 @@ sigusr_handler (gint fd, short what, void *arg) event_del (&worker->sig_ev); event_del (&worker->bind_ev); close (worker->cf->listen_sock); - do_reopen_log = 1; msg_info ("worker's shutdown is pending in %d sec", SOFT_SHUTDOWN_TIME); event_loopexit (&tv); mods = ctx->max_mods + 1; diff --git a/src/greylist_storage.c b/src/greylist_storage.c index 94ef751ae..ec26ae27e 100644 --- a/src/greylist_storage.c +++ b/src/greylist_storage.c @@ -104,7 +104,6 @@ sigusr_handler (gint fd, short what, void *arg) event_del (&worker->sig_ev); event_del (&worker->bind_ev); close (worker->cf->listen_sock); - do_reopen_log = 1; msg_info ("worker's shutdown is pending in %d sec", SOFT_SHUTDOWN_TIME); event_loopexit (&tv); return; diff --git a/src/lmtp.c b/src/lmtp.c index d92656fad..043c78485 100644 --- a/src/lmtp.c +++ b/src/lmtp.c @@ -48,7 +48,7 @@ sig_handler (gint signo, siginfo_t *info, void *unused) { switch (signo) { case SIGUSR1: - reopen_log (); + reopen_log (rspamd_main->logger); break; case SIGINT: case SIGTERM: @@ -70,7 +70,6 @@ sigusr_handler (gint fd, short what, void *arg) tv.tv_usec = 0; event_del (&worker->sig_ev); event_del (&worker->bind_ev); - do_reopen_log = 1; msg_info ("lmtp worker's shutdown is pending in %d sec", SOFT_SHUTDOWN_TIME); event_loopexit (&tv); return; diff --git a/src/logger.c b/src/logger.c index 281a8385d..db4143ff3 100644 --- a/src/logger.c +++ b/src/logger.c @@ -33,39 +33,34 @@ #define REPEATS_MIN 3 #define REPEATS_MAX 300 -#ifdef RSPAMD_MAIN -sig_atomic_t do_reopen_log = 0; -#endif - /** * Static structure that store logging parameters * It is NOT shared between processes and is created by main process */ -typedef struct rspamd_logger_s { +struct rspamd_logger_s { rspamd_log_func_t log_func; struct config_file *cfg; struct { - guint32 size; - guint32 used; - u_char *buf; + guint32 size; + guint32 used; + u_char *buf; } io_buf; - gint fd; + gint fd; gboolean is_buffered; gboolean enabled; gboolean is_debug; gboolean throttling; time_t throttling_time; + sig_atomic_t do_reopen_log; enum rspamd_log_type type; pid_t pid; enum process_type process_type; radix_tree_t *debug_ip; - guint32 last_line_cksum; - guint32 repeats; + guint32 last_line_cksum; + guint32 repeats; gchar *saved_message; gchar *saved_function; -} rspamd_logger_t; - -rspamd_logger_t *rspamd_log = NULL; +}; static const gchar lf_chr = '\n'; @@ -103,7 +98,7 @@ rspamd_log_calculate_cksum (const gchar *message, size_t mlen) * Write a line to log file (unbuffered) */ static void -direct_write_log_line (void *data, gint count, gboolean is_iov) +direct_write_log_line (rspamd_logger_t *rspamd_log, void *data, gint count, gboolean is_iov) { gchar errmsg[128]; struct iovec *iov; @@ -124,10 +119,10 @@ direct_write_log_line (void *data, gint count, gboolean is_iov) r = rspamd_snprintf (errmsg, sizeof (errmsg), "direct_write_log_line: cannot write log line: %s", strerror (errno)); if (errno == EBADF || errno == EIO || errno == EINTR) { /* Descriptor is somehow invalid, try to restart */ - reopen_log (); + reopen_log (rspamd_log); if (write (rspamd_log->fd, errmsg, r) != -1) { /* Try again */ - direct_write_log_line (data, count, is_iov); + direct_write_log_line (rspamd_log, data, count, is_iov); } } else if (errno == EFAULT || errno == EINVAL || errno == EFBIG || errno == ENOSPC) { @@ -148,7 +143,7 @@ direct_write_log_line (void *data, gint count, gboolean is_iov) /* Logging utility functions */ gint -open_log (void) +open_log (rspamd_logger_t *rspamd_log) { rspamd_log->enabled = TRUE; @@ -172,10 +167,10 @@ open_log (void) } void -close_log (void) +close_log (rspamd_logger_t *rspamd_log) { gchar tmpbuf[256]; - flush_log_buf (); + flush_log_buf (rspamd_log); switch (rspamd_log->type) { case RSPAMD_LOG_CONSOLE: @@ -197,7 +192,7 @@ close_log (void) rspamd_log->saved_function = NULL; } /* It is safe to use temporary buffer here as it is not static */ - file_log_function (NULL, __FUNCTION__, rspamd_log->cfg->log_level, tmpbuf, TRUE, NULL); + file_log_function (NULL, __FUNCTION__, rspamd_log->cfg->log_level, tmpbuf, TRUE, rspamd_log); return; } @@ -216,57 +211,57 @@ close_log (void) * Setup logger */ void -rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct config_file *cfg) +rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct rspamd_main *rspamd) { gchar **strvec, *p, *err; gint num, i, k; struct in_addr addr; guint32 mask = 0xFFFFFFFF; - if (rspamd_log == NULL) { - rspamd_log = g_malloc (sizeof (rspamd_logger_t)); - bzero (rspamd_log, sizeof (rspamd_logger_t)); + if (rspamd->logger == NULL) { + rspamd->logger = g_malloc (sizeof (rspamd_logger_t)); + memset (rspamd->logger, 0, sizeof (rspamd_logger_t)); } - rspamd_log->type = type; - rspamd_log->pid = getpid (); - rspamd_log->process_type = ptype; + rspamd->logger->type = type; + rspamd->logger->pid = getpid (); + rspamd->logger->process_type = ptype; switch (type) { case RSPAMD_LOG_CONSOLE: - rspamd_log->log_func = file_log_function; - rspamd_log->fd = STDERR_FILENO; + rspamd->logger->log_func = file_log_function; + rspamd->logger->fd = STDERR_FILENO; break; case RSPAMD_LOG_SYSLOG: - rspamd_log->log_func = syslog_log_function; + rspamd->logger->log_func = syslog_log_function; break; case RSPAMD_LOG_FILE: - rspamd_log->log_func = file_log_function; + rspamd->logger->log_func = file_log_function; break; } - rspamd_log->cfg = cfg; + rspamd->logger->cfg = rspamd->cfg; /* Set up buffer */ - if (cfg->log_buffered) { - if (cfg->log_buf_size != 0) { - rspamd_log->io_buf.size = cfg->log_buf_size; + if (rspamd->cfg->log_buffered) { + if (rspamd->cfg->log_buf_size != 0) { + rspamd->logger->io_buf.size = rspamd->cfg->log_buf_size; } else { - rspamd_log->io_buf.size = BUFSIZ; + rspamd->logger->io_buf.size = BUFSIZ; } - rspamd_log->is_buffered = TRUE; - rspamd_log->io_buf.buf = g_malloc (rspamd_log->io_buf.size); + rspamd->logger->is_buffered = TRUE; + rspamd->logger->io_buf.buf = g_malloc (rspamd->logger->io_buf.size); } /* Set up conditional logging */ - if (cfg->debug_ip_map != NULL) { + if (rspamd->cfg->debug_ip_map != NULL) { /* Try to add it as map first of all */ - if (rspamd_log->debug_ip) { - radix_tree_free (rspamd_log->debug_ip); + if (rspamd->logger->debug_ip) { + radix_tree_free (rspamd->logger->debug_ip); } - rspamd_log->debug_ip = radix_tree_create (); - if (!add_map (cfg->debug_ip_map, read_radix_list, fin_radix_list, (void **)&rspamd_log->debug_ip)) { + rspamd->logger->debug_ip = radix_tree_create (); + if (!add_map (rspamd->cfg->debug_ip_map, read_radix_list, fin_radix_list, (void **)&rspamd->logger->debug_ip)) { /* Try to parse it as list */ - strvec = g_strsplit_set (cfg->debug_ip_map, ",; ", 0); + strvec = g_strsplit_set (rspamd->cfg->debug_ip_map, ",; ", 0); num = g_strv_length (strvec); for (i = 0; i < num; i++) { @@ -288,23 +283,23 @@ rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct co if (inet_aton (strvec[i], &addr)) { /* Check ip */ mask = mask << (32 - k); - radix32tree_insert (rspamd_log->debug_ip, ntohl (addr.s_addr), mask, 1); + radix32tree_insert (rspamd->logger->debug_ip, ntohl (addr.s_addr), mask, 1); } } g_strfreev (strvec); } } - else if (rspamd_log->debug_ip) { - radix_tree_free (rspamd_log->debug_ip); - rspamd_log->debug_ip = NULL; + else if (rspamd->logger->debug_ip) { + radix_tree_free (rspamd->logger->debug_ip); + rspamd->logger->debug_ip = NULL; } } gint -reopen_log (void) +reopen_log (rspamd_logger_t *rspamd_log) { - close_log (); - if (open_log () == 0) { + close_log (rspamd_log); + if (open_log (rspamd_log) == 0) { msg_info ("log file reopened"); return 0; } @@ -316,7 +311,7 @@ reopen_log (void) * Used after fork() for updating structure params */ void -update_log_pid (enum process_type ptype) +update_log_pid (enum process_type ptype, rspamd_logger_t *rspamd_log) { rspamd_log->pid = getpid (); rspamd_log->process_type = ptype; @@ -326,10 +321,10 @@ update_log_pid (enum process_type ptype) * Flush logging buffer */ void -flush_log_buf (void) +flush_log_buf (rspamd_logger_t *rspamd_log) { if (rspamd_log->is_buffered && (rspamd_log->type == RSPAMD_LOG_CONSOLE || rspamd_log->type == RSPAMD_LOG_FILE)) { - direct_write_log_line (rspamd_log->io_buf.buf, rspamd_log->io_buf.used, FALSE); + direct_write_log_line (rspamd_log, rspamd_log->io_buf.buf, rspamd_log->io_buf.used, FALSE); rspamd_log->io_buf.used = 0; } } @@ -338,7 +333,7 @@ flush_log_buf (void) * This log functions select real logger and write message if level is less or equal to configured log level */ void -rspamd_common_log_function (GLogLevelFlags log_level, const gchar *function, const gchar *fmt, ...) +rspamd_common_log_function (rspamd_logger_t *rspamd_log, GLogLevelFlags log_level, const gchar *function, const gchar *fmt, ...) { static gchar logbuf[BUFSIZ], escaped_logbuf[BUFSIZ]; va_list vp; @@ -350,7 +345,7 @@ rspamd_common_log_function (GLogLevelFlags log_level, const gchar *function, con *end = '\0'; (void)rspamd_escape_string (escaped_logbuf, logbuf, sizeof (escaped_logbuf)); va_end (vp); - rspamd_log->log_func (NULL, function, log_level, escaped_logbuf, FALSE, rspamd_log->cfg); + rspamd_log->log_func (NULL, function, log_level, escaped_logbuf, FALSE, rspamd_log); } } @@ -359,7 +354,7 @@ rspamd_common_log_function (GLogLevelFlags log_level, const gchar *function, con * Fill buffer with message (limits must be checked BEFORE this call) */ static void -fill_buffer (const struct iovec *iov, gint iovcnt) +fill_buffer (rspamd_logger_t *rspamd_log, const struct iovec *iov, gint iovcnt) { gint i; @@ -374,14 +369,14 @@ fill_buffer (const struct iovec *iov, gint iovcnt) * Write message to buffer or to file (using direct_write_log_line function) */ static void -file_log_helper (const struct iovec *iov, gint iovcnt) +file_log_helper (rspamd_logger_t *rspamd_log, const struct iovec *iov, gint iovcnt) { size_t len = 0; gint i; if (! rspamd_log->is_buffered) { /* Write string directly */ - direct_write_log_line ((void *)iov, iovcnt, TRUE); + direct_write_log_line (rspamd_log, (void *)iov, iovcnt, TRUE); } else { /* Calculate total length */ @@ -391,17 +386,17 @@ file_log_helper (const struct iovec *iov, gint iovcnt) /* Fill buffer */ if (rspamd_log->io_buf.size < len) { /* Buffer is too small to hold this string, so write it dirrectly */ - flush_log_buf (); - direct_write_log_line ((void *)iov, iovcnt, TRUE); + flush_log_buf (rspamd_log); + direct_write_log_line (rspamd_log, (void *)iov, iovcnt, TRUE); } else if (rspamd_log->io_buf.used + len >= rspamd_log->io_buf.size) { /* Buffer is full, try to write it dirrectly */ - flush_log_buf (); - fill_buffer (iov, iovcnt); + flush_log_buf (rspamd_log); + fill_buffer (rspamd_log, iov, iovcnt); } else { /* Copy incoming string to buffer */ - fill_buffer (iov, iovcnt); + fill_buffer (rspamd_log, iov, iovcnt); } } } @@ -412,13 +407,13 @@ file_log_helper (const struct iovec *iov, gint iovcnt) static void syslog_log_function (const gchar * log_domain, const gchar *function, GLogLevelFlags log_level, const gchar * message, gboolean forced, gpointer arg) { - struct config_file *cfg = (struct config_file *)arg; + rspamd_logger_t *rspamd_log = arg; if (! rspamd_log->enabled) { return; } if (function == NULL) { - if (forced || log_level <= cfg->log_level) { + if (forced || log_level <= rspamd_log->cfg->log_level) { if (forced || log_level >= G_LOG_LEVEL_DEBUG) { syslog (LOG_DEBUG, "%s", message); } @@ -434,7 +429,7 @@ syslog_log_function (const gchar * log_domain, const gchar *function, GLogLevelF } } else { - if (forced || log_level <= cfg->log_level) { + if (forced || log_level <= rspamd_log->cfg->log_level) { if (log_level >= G_LOG_LEVEL_DEBUG) { syslog (LOG_DEBUG, "%s: %s", function, message); } @@ -466,6 +461,7 @@ file_log_function (const gchar * log_domain, const gchar *function, GLogLevelFla size_t mlen; const gchar *cptype = NULL; gboolean got_time = FALSE; + rspamd_logger_t *rspamd_log = arg; if (! rspamd_log->enabled) { return; @@ -534,57 +530,74 @@ file_log_function (const gchar * log_domain, const gchar *function, GLogLevelFla } } - if (! got_time) { - now = time (NULL); - } + if (rspamd_log->cfg->log_extended) { + if (! got_time) { + now = time (NULL); + } - /* Format time */ - tms = localtime (&now); + /* Format time */ + tms = localtime (&now); - strftime (timebuf, sizeof (timebuf), "%F %H:%M:%S", tms); - cptype = process_to_str (rspamd_log->process_type); + strftime (timebuf, sizeof (timebuf), "%F %H:%M:%S", tms); + cptype = process_to_str (rspamd_log->process_type); - if (rspamd_log->cfg->log_color) { - if (log_level >= G_LOG_LEVEL_INFO) { - /* White */ - r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[1;37m"); + if (rspamd_log->cfg->log_color) { + if (log_level >= G_LOG_LEVEL_INFO) { + /* White */ + r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[1;37m"); + } + else if (log_level >= G_LOG_LEVEL_WARNING) { + /* Magenta */ + r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[2;32m"); + } + else if (log_level >= G_LOG_LEVEL_CRITICAL) { + /* Red */ + r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[1;31m"); + } } - else if (log_level >= G_LOG_LEVEL_WARNING) { - /* Magenta */ - r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[2;32m"); + else { + r = 0; } - else if (log_level >= G_LOG_LEVEL_CRITICAL) { - /* Red */ - r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[1;31m"); + if (function == NULL) { + r += rspamd_snprintf (tmpbuf + r, sizeof (tmpbuf) - r, "%s #%P(%s) ", timebuf, rspamd_log->pid, cptype); + } + else { + r += rspamd_snprintf (tmpbuf + r, sizeof (tmpbuf) -r, "%s #%P(%s) %s: ", timebuf, rspamd_log->pid, cptype, function); + } + /* Construct IOV for log line */ + iov[0].iov_base = tmpbuf; + iov[0].iov_len = r; + iov[1].iov_base = (void *)message; + iov[1].iov_len = mlen; + iov[2].iov_base = (void *)&lf_chr; + iov[2].iov_len = 1; + if (rspamd_log->cfg->log_color) { + iov[3].iov_base = "\033[0m"; + iov[3].iov_len = sizeof ("\033[0m") - 1; + /* Call helper (for buffering) */ + file_log_helper (rspamd_log, iov, 4); + } + else { + /* Call helper (for buffering) */ + file_log_helper (rspamd_log, iov, 3); } } else { - r = 0; - } - if (function == NULL) { - r += rspamd_snprintf (tmpbuf + r, sizeof (tmpbuf) - r, "%s #%P(%s) ", timebuf, rspamd_log->pid, cptype); - } - else { - r += rspamd_snprintf (tmpbuf + r, sizeof (tmpbuf) -r, "%s #%P(%s) %s: ", timebuf, rspamd_log->pid, cptype, function); - } - /* Construct IOV for log line */ - iov[0].iov_base = tmpbuf; - iov[0].iov_len = r; - iov[1].iov_base = (void *)message; - iov[1].iov_len = mlen; - iov[2].iov_base = (void *)&lf_chr; - iov[2].iov_len = 1; - if (rspamd_log->cfg->log_color) { - iov[3].iov_base = "\033[0m"; - iov[3].iov_len = sizeof ("\033[0m") - 1; - /* Call helper (for buffering) */ - file_log_helper (iov, 4); - } - else { - /* Call helper (for buffering) */ - file_log_helper (iov, 3); + iov[0].iov_base = (void *)message; + iov[0].iov_len = mlen; + iov[1].iov_base = (void *)&lf_chr; + iov[1].iov_len = 1; + if (rspamd_log->cfg->log_color) { + iov[2].iov_base = "\033[0m"; + iov[2].iov_len = sizeof ("\033[0m") - 1; + /* Call helper (for buffering) */ + file_log_helper (rspamd_log, iov, 3); + } + else { + /* Call helper (for buffering) */ + file_log_helper (rspamd_log, iov, 2); + } } - } } @@ -592,7 +605,7 @@ file_log_function (const gchar * log_domain, const gchar *function, GLogLevelFla * Write log line depending on ip */ void -rspamd_conditional_debug (guint32 addr, const gchar *function, const gchar *fmt, ...) +rspamd_conditional_debug (rspamd_logger_t *rspamd_log, guint32 addr, const gchar *function, const gchar *fmt, ...) { static gchar logbuf[BUFSIZ], escaped_logbuf[BUFSIZ]; va_list vp; @@ -606,7 +619,7 @@ rspamd_conditional_debug (guint32 addr, const gchar *function, const gchar *fmt, *end = '\0'; (void)rspamd_escape_string (escaped_logbuf, logbuf, sizeof (escaped_logbuf)); va_end (vp); - rspamd_log->log_func (NULL, function, G_LOG_LEVEL_DEBUG, escaped_logbuf, TRUE, rspamd_log->cfg); + rspamd_log->log_func (NULL, function, G_LOG_LEVEL_DEBUG, escaped_logbuf, TRUE, rspamd_log); } } @@ -617,10 +630,11 @@ void rspamd_glib_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer arg) { gchar escaped_logbuf[BUFSIZ]; + rspamd_logger_t *rspamd_log = arg; if (rspamd_log->enabled) { (void)rspamd_escape_string (escaped_logbuf, message, sizeof (escaped_logbuf)); - rspamd_log->log_func (log_domain, NULL, log_level, escaped_logbuf, FALSE, rspamd_log->cfg); + rspamd_log->log_func (log_domain, NULL, log_level, escaped_logbuf, FALSE, rspamd_log); } } @@ -628,7 +642,7 @@ rspamd_glib_log_function (const gchar *log_domain, GLogLevelFlags log_level, con * Temporary turn on debugging */ void -rspamd_log_debug () +rspamd_log_debug (rspamd_logger_t *rspamd_log) { rspamd_log->is_debug = TRUE; } @@ -637,7 +651,7 @@ rspamd_log_debug () * Turn off temporary debugging */ void -rspamd_log_nodebug () +rspamd_log_nodebug (rspamd_logger_t *rspamd_log) { rspamd_log->is_debug = FALSE; } diff --git a/src/logger.h b/src/logger.h index 7a3fade7c..f44dc56d9 100644 --- a/src/logger.h +++ b/src/logger.h @@ -11,31 +11,32 @@ typedef void (*rspamd_log_func_t)(const gchar * log_domain, const gchar *functio GLogLevelFlags log_level, const gchar * message, gboolean forced, gpointer arg); +typedef struct rspamd_logger_s rspamd_logger_t; /** * Init logger */ -void rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct config_file *cfg); +void rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct rspamd_main *main); /** * Open log file or initialize other structures */ -gint open_log (void); +gint open_log (rspamd_logger_t *logger); /** * Close log file or destroy other structures */ -void close_log (void); +void close_log (rspamd_logger_t *logger); /** * Close and open log again */ -gint reopen_log (void); +gint reopen_log (rspamd_logger_t *logger); /** * Set log pid */ -void update_log_pid (enum process_type ptype); +void update_log_pid (enum process_type ptype, rspamd_logger_t *logger); /** * Flush log buffer for some types of logging */ -void flush_log_buf (void); +void flush_log_buf (rspamd_logger_t *logger); /** * Log function that is compatible for glib messages */ @@ -44,32 +45,32 @@ void rspamd_glib_log_function (const gchar *log_domain, GLogLevelFlags log_level /** * Function with variable number of arguments support */ -void rspamd_common_log_function (GLogLevelFlags log_level, const gchar *function, const gchar *fmt, ...); +void rspamd_common_log_function (rspamd_logger_t *logger, GLogLevelFlags log_level, const gchar *function, const gchar *fmt, ...); /** * Conditional debug function */ -void rspamd_conditional_debug (guint32 addr, const gchar *function, const gchar *fmt, ...) ; +void rspamd_conditional_debug (rspamd_logger_t *logger, guint32 addr, const gchar *function, const gchar *fmt, ...) ; /** * Temporary turn on debug */ -void rspamd_log_debug (); +void rspamd_log_debug (rspamd_logger_t *logger); /** * Turn off debug */ -void rspamd_log_nodebug (); +void rspamd_log_nodebug (rspamd_logger_t *logger); /* Typical functions */ /* Logging in postfix style */ #if (defined(RSPAMD_MAIN) || defined(RSPAMD_LIB) || defined(RSPAMD_TEST)) -#define msg_err(...) rspamd_common_log_function(G_LOG_LEVEL_CRITICAL, __FUNCTION__, __VA_ARGS__) -#define msg_warn(...) rspamd_common_log_function(G_LOG_LEVEL_WARNING, __FUNCTION__, __VA_ARGS__) -#define msg_info(...) rspamd_common_log_function(G_LOG_LEVEL_INFO, __FUNCTION__, __VA_ARGS__) -#define msg_debug(...) rspamd_conditional_debug(-1, __FUNCTION__, __VA_ARGS__) -#define debug_task(...) rspamd_conditional_debug(task->from_addr.s_addr, __FUNCTION__, __VA_ARGS__) +#define msg_err(...) rspamd_common_log_function(rspamd_main->logger, G_LOG_LEVEL_CRITICAL, __FUNCTION__, __VA_ARGS__) +#define msg_warn(...) rspamd_common_log_function(rspamd_main->logger, G_LOG_LEVEL_WARNING, __FUNCTION__, __VA_ARGS__) +#define msg_info(...) rspamd_common_log_function(rspamd_main->logger, G_LOG_LEVEL_INFO, __FUNCTION__, __VA_ARGS__) +#define msg_debug(...) rspamd_conditional_debug(rspamd_main->logger, -1, __FUNCTION__, __VA_ARGS__) +#define debug_task(...) rspamd_conditional_debug(rspamd_main->logger, task->from_addr.s_addr, __FUNCTION__, __VA_ARGS__) #else #define msg_err(...) rspamd_fprintf(stderr, __VA_ARGS__) diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index ada44981b..6d8763682 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -139,18 +139,18 @@ lua_common_log (GLogLevelFlags level, lua_State *L, const gchar *msg) } rspamd_snprintf (func_buf, sizeof (func_buf), "%s:%d", p, d.currentline); if (level == G_LOG_LEVEL_DEBUG) { - rspamd_conditional_debug(-1, func_buf, msg); + rspamd_conditional_debug(rspamd_main->logger, -1, func_buf, msg); } else { - rspamd_common_log_function(level, func_buf, msg); + rspamd_common_log_function(rspamd_main->logger, level, func_buf, msg); } } else { if (level == G_LOG_LEVEL_DEBUG) { - rspamd_conditional_debug(-1, __FUNCTION__, msg); + rspamd_conditional_debug(rspamd_main->logger, -1, __FUNCTION__, msg); } else { - rspamd_common_log_function(level, __FUNCTION__, msg); + rspamd_common_log_function(rspamd_main->logger, level, __FUNCTION__, msg); } } } diff --git a/src/main.c b/src/main.c index d268bc3cb..6ef674856 100644 --- a/src/main.c +++ b/src/main.c @@ -32,21 +32,7 @@ #include "fuzzy_storage.h" #include "cfg_xml.h" #include "symbols_cache.h" - -#ifndef WITHOUT_PERL - -# include <EXTERN.h> /* from the Perl distribution */ -# include <perl.h> /* from the Perl distribution */ - -# ifndef PERL_IMPLICIT_CONTEXT -# undef dTHXa -# define dTHXa(a) -# endif -# include "perl.h" - -#elif defined(WITH_LUA) -# include "lua/lua_common.h" -#endif +#include "lua/lua_common.h" /* 2 seconds to fork new process in place of dead one */ #define SOFT_FORK_TIME 2 @@ -54,37 +40,39 @@ /* 10 seconds after getting termination signal to terminate all workers with SIGKILL */ #define HARD_TERMINATION_TIME 10 - -rspamd_hash_t *counters; +extern rspamd_hash_t *counters; static struct rspamd_worker *fork_worker (struct rspamd_main *, struct worker_conf *); static gboolean load_rspamd_config (struct config_file *cfg, gboolean init_modules); static void init_cfg_cache (struct config_file *cfg); -sig_atomic_t do_restart; -sig_atomic_t do_terminate; -sig_atomic_t child_dead; -sig_atomic_t got_alarm; +sig_atomic_t do_restart = 0; +sig_atomic_t do_reopen_log = 0; +sig_atomic_t do_terminate = 0; +sig_atomic_t child_dead = 0; +sig_atomic_t got_alarm = 0; #ifdef HAVE_SA_SIGINFO -GQueue *signals_info; +GQueue *signals_info = NULL; #endif -static gboolean config_test; -static gboolean no_fork; -static gchar *cfg_name; -static gchar *rspamd_user; -static gchar *rspamd_group; -static gchar *rspamd_pidfile; -static gboolean dump_vars; -static gboolean dump_cache; -static gboolean is_debug; +static gboolean config_test = FALSE; +static gboolean no_fork = FALSE; +static gchar *cfg_name = NULL; +static gchar *rspamd_user = NULL; +static gchar *rspamd_group = NULL; +static gchar *rspamd_pidfile = NULL; +static gboolean dump_vars = FALSE; +static gboolean dump_cache = FALSE; +static gboolean is_debug = FALSE; /* List of workers that are pending to start */ static GList *workers_pending = NULL; /* List of active listen sockets indexed by worker type */ -static GHashTable *listen_sockets; +static GHashTable *listen_sockets = NULL; + +struct rspamd_main *rspamd_main; /* Commandline options */ static GOptionEntry entries[] = @@ -239,8 +227,8 @@ drop_priv (struct config_file *cfg) static void config_logger (struct rspamd_main *rspamd, gboolean is_fatal) { - rspamd_set_logger (rspamd->cfg->log_type, TYPE_MAIN, rspamd->cfg); - if (open_log () == -1) { + rspamd_set_logger (rspamd->cfg->log_type, TYPE_MAIN, rspamd); + if (open_log (rspamd->logger) == -1) { if (is_fatal) { fprintf (stderr, "Fatal error, cannot open logfile, exiting\n"); exit (EXIT_FAILURE); @@ -276,7 +264,7 @@ reread_config (struct rspamd_main *rspamd) else { msg_debug ("replacing config"); free_config (rspamd->cfg); - close_log (); + close_log (rspamd->logger); g_free (rspamd->cfg); rspamd->cfg = tmp_cfg; /* Force debug log */ @@ -349,7 +337,7 @@ fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf) switch (cur->pid) { case 0: /* Update pid for logging */ - update_log_pid (cf->type); + update_log_pid (cf->type, rspamd->logger); /* Drop privilleges */ drop_priv (rspamd->cfg); /* Set limits */ @@ -812,7 +800,6 @@ init_workers_ctx (struct rspamd_main *main) gint main (gint argc, gchar **argv, gchar **env) { - struct rspamd_main *rspamd; gint res = 0; struct sigaction signals; struct rspamd_worker *cur; @@ -824,43 +811,40 @@ main (gint argc, gchar **argv, gchar **env) #ifdef HAVE_SA_SIGINFO signals_info = g_queue_new (); #endif - rspamd = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main)); - bzero (rspamd, sizeof (struct rspamd_main)); - rspamd->server_pool = memory_pool_new (memory_pool_get_size ()); - rspamd->cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); - if (!rspamd || !rspamd->cfg) { + rspamd_main = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main)); + memset (rspamd_main, 0, sizeof (struct rspamd_main)); + rspamd_main->server_pool = memory_pool_new (memory_pool_get_size ()); + rspamd_main->cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); + + if (!rspamd_main || !rspamd_main->cfg) { fprintf (stderr, "Cannot allocate memory\n"); exit (-errno); } - - do_terminate = 0; - do_restart = 0; - child_dead = 0; - do_reopen_log = 0; + rspamd_main->cfg->modules_num = MODULES_NUM; #ifndef HAVE_SETPROCTITLE init_title (argc, argv, env); #endif - rspamd->stat = memory_pool_alloc_shared (rspamd->server_pool, sizeof (struct rspamd_stat)); - bzero (rspamd->stat, sizeof (struct rspamd_stat)); + rspamd_main->stat = memory_pool_alloc_shared (rspamd_main->server_pool, sizeof (struct rspamd_stat)); + memset (rspamd_main->stat, 0, sizeof (struct rspamd_stat)); - bzero (rspamd->cfg, sizeof (struct config_file)); - rspamd->cfg->cfg_pool = memory_pool_new (memory_pool_get_size ()); - init_defaults (rspamd->cfg); + memset (rspamd_main->cfg, 0, sizeof (struct config_file)); + rspamd_main->cfg->cfg_pool = memory_pool_new (memory_pool_get_size ()); + init_defaults (rspamd_main->cfg); - bzero (&signals, sizeof (struct sigaction)); + memset (&signals, 0, sizeof (struct sigaction)); - read_cmd_line (argc, argv, rspamd->cfg); - if (rspamd->cfg->cfg_name == NULL) { - rspamd->cfg->cfg_name = FIXED_CONFIG_FILE; + read_cmd_line (argc, argv, rspamd_main->cfg); + if (rspamd_main->cfg->cfg_name == NULL) { + rspamd_main->cfg->cfg_name = FIXED_CONFIG_FILE; } - if (rspamd->cfg->config_test || is_debug) { - rspamd->cfg->log_level = G_LOG_LEVEL_DEBUG; + if (rspamd_main->cfg->config_test || is_debug) { + rspamd_main->cfg->log_level = G_LOG_LEVEL_DEBUG; } else { - rspamd->cfg->log_level = G_LOG_LEVEL_CRITICAL; + rspamd_main->cfg->log_level = G_LOG_LEVEL_CRITICAL; } #ifdef HAVE_SETLOCALE @@ -872,19 +856,19 @@ main (gint argc, gchar **argv, gchar **env) #endif /* First set logger to console logger */ - rspamd_set_logger (RSPAMD_LOG_CONSOLE, TYPE_MAIN, rspamd->cfg); - (void)open_log (); - g_log_set_default_handler (rspamd_glib_log_function, rspamd->cfg); + rspamd_set_logger (RSPAMD_LOG_CONSOLE, TYPE_MAIN, rspamd_main); + (void)open_log (rspamd_main->logger); + g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger); - init_lua (rspamd->cfg); + init_lua (rspamd_main->cfg); /* Init counters */ - counters = rspamd_hash_new_shared (rspamd->server_pool, g_str_hash, g_str_equal, 64); + counters = rspamd_hash_new_shared (rspamd_main->server_pool, g_str_hash, g_str_equal, 64); /* Init listen sockets hash */ listen_sockets = g_hash_table_new (g_direct_hash, g_direct_equal); /* Init contextes */ - init_workers_ctx (rspamd); + init_workers_ctx (rspamd_main); /* Init classifiers options */ register_classifier_opt ("bayes", "min_tokens"); @@ -892,53 +876,53 @@ main (gint argc, gchar **argv, gchar **env) register_classifier_opt ("winnow", "learn_threshold"); /* Pre-init of cache */ - rspamd->cfg->cache = g_new0 (struct symbols_cache, 1); - rspamd->cfg->cache->static_pool = memory_pool_new (memory_pool_get_size ()); - rspamd->cfg->cache->cfg = rspamd->cfg; + rspamd_main->cfg->cache = g_new0 (struct symbols_cache, 1); + rspamd_main->cfg->cache->static_pool = memory_pool_new (memory_pool_get_size ()); + rspamd_main->cfg->cache->cfg = rspamd_main->cfg; /* Load config */ - if (! load_rspamd_config (rspamd->cfg, TRUE)) { + if (! load_rspamd_config (rspamd_main->cfg, TRUE)) { exit (EXIT_FAILURE); } /* Force debug log */ if (is_debug) { - rspamd->cfg->log_level = G_LOG_LEVEL_DEBUG; + rspamd_main->cfg->log_level = G_LOG_LEVEL_DEBUG; } - if (rspamd->cfg->config_test || dump_vars || dump_cache) { + if (rspamd_main->cfg->config_test || dump_vars || dump_cache) { /* Init events to test modules */ event_init (); res = TRUE; - if (! init_lua_filters (rspamd->cfg)) { + if (! init_lua_filters (rspamd_main->cfg)) { res = FALSE; } - if (!check_modules_config (rspamd->cfg)) { + if (!check_modules_config (rspamd_main->cfg)) { res = FALSE; } /* Perform modules configuring */ - l = g_list_first (rspamd->cfg->filters); + l = g_list_first (rspamd_main->cfg->filters); while (l) { filt = l->data; if (filt->module) { - if (!filt->module->module_config_func (rspamd->cfg)) { + if (!filt->module->module_config_func (rspamd_main->cfg)) { res = FALSE; } } l = g_list_next (l); } /* Insert classifiers symbols */ - (void)insert_classifier_symbols (rspamd->cfg); + (void)insert_classifier_symbols (rspamd_main->cfg); - if (! validate_cache (rspamd->cfg->cache, rspamd->cfg, FALSE)) { + if (! validate_cache (rspamd_main->cfg->cache, rspamd_main->cfg, FALSE)) { res = FALSE; } if (dump_vars) { - dump_cfg_vars (rspamd->cfg); + dump_cfg_vars (rspamd_main->cfg); } if (dump_cache) { - print_symbols_cache (rspamd->cfg); + print_symbols_cache (rspamd_main->cfg); exit (EXIT_SUCCESS); } fprintf (stderr, "syntax %s\n", res ? "OK" : "BAD"); @@ -950,25 +934,25 @@ main (gint argc, gchar **argv, gchar **env) rlim.rlim_cur = 100 * 1024 * 1024; setrlimit (RLIMIT_STACK, &rlim); - config_logger (rspamd, TRUE); + config_logger (rspamd_main, TRUE); msg_info ("rspamd " RVERSION " is starting, build id: " RID); - rspamd->cfg->cfg_name = memory_pool_strdup (rspamd->cfg->cfg_pool, rspamd->cfg->cfg_name); + rspamd_main->cfg->cfg_name = memory_pool_strdup (rspamd_main->cfg->cfg_pool, rspamd_main->cfg->cfg_name); /* Daemonize */ - if (!rspamd->cfg->no_fork && daemon (0, 0) == -1) { + if (!rspamd_main->cfg->no_fork && daemon (0, 0) == -1) { fprintf (stderr, "Cannot daemonize\n"); exit (-errno); } /* Write info */ - rspamd->pid = getpid (); - rspamd->type = TYPE_MAIN; + rspamd_main->pid = getpid (); + rspamd_main->type = TYPE_MAIN; init_signals (&signals, sig_handler); - if (write_pid (rspamd) == -1) { - msg_err ("cannot write pid file %s", rspamd->cfg->pid_file); + if (write_pid (rspamd_main) == -1) { + msg_err ("cannot write pid file %s", rspamd_main->cfg->pid_file); exit (-errno); } @@ -978,30 +962,30 @@ main (gint argc, gchar **argv, gchar **env) setproctitle ("main process"); /* Init statfile pool */ - rspamd->statfile_pool = statfile_pool_new (rspamd->server_pool, rspamd->cfg->max_statfile_size); + rspamd_main->statfile_pool = statfile_pool_new (rspamd_main->server_pool, rspamd_main->cfg->max_statfile_size); event_init (); g_mime_init (0); /* Init lua filters */ - if (! init_lua_filters (rspamd->cfg)) { + if (! init_lua_filters (rspamd_main->cfg)) { msg_err ("error loading lua plugins"); exit (EXIT_FAILURE); } /* Check configuration for modules */ - (void)check_modules_config (rspamd->cfg); + (void)check_modules_config (rspamd_main->cfg); /* Insert classifiers symbols */ - (void)insert_classifier_symbols (rspamd->cfg); + (void)insert_classifier_symbols (rspamd_main->cfg); /* Perform modules configuring */ - l = g_list_first (rspamd->cfg->filters); + l = g_list_first (rspamd_main->cfg->filters); while (l) { filt = l->data; if (filt->module) { - if (!filt->module->module_config_func (rspamd->cfg)) { + if (!filt->module->module_config_func (rspamd_main->cfg)) { res = FALSE; } } @@ -1009,20 +993,20 @@ main (gint argc, gchar **argv, gchar **env) } /* Init config cache */ - init_cfg_cache (rspamd->cfg); + init_cfg_cache (rspamd_main->cfg); /* Validate cache */ - (void)validate_cache (rspamd->cfg->cache, rspamd->cfg, FALSE); + (void)validate_cache (rspamd_main->cfg->cache, rspamd_main->cfg, FALSE); /* Flush log */ - flush_log_buf (); + flush_log_buf (rspamd_main->logger); /* Preload all statfiles */ - preload_statfiles (rspamd); + preload_statfiles (rspamd_main); /* Spawn workers */ - rspamd->workers = g_hash_table_new (g_direct_hash, g_direct_equal); - spawn_workers (rspamd); + rspamd_main->workers = g_hash_table_new (g_direct_hash, g_direct_equal); + spawn_workers (rspamd_main); /* Signal processing cycle */ for (;;) { @@ -1034,7 +1018,7 @@ main (gint argc, gchar **argv, gchar **env) #endif if (do_terminate) { msg_debug ("catch termination signal, waiting for childs"); - pass_signal_worker (rspamd->workers, SIGTERM); + pass_signal_worker (rspamd_main->workers, SIGTERM); break; } if (child_dead) { @@ -1042,10 +1026,10 @@ main (gint argc, gchar **argv, gchar **env) msg_debug ("catch SIGCHLD signal, finding terminated worker"); /* Remove dead child form childs list */ wrk = waitpid (0, &res, 0); - if ((cur = g_hash_table_lookup (rspamd->workers, GSIZE_TO_POINTER (wrk))) != NULL) { + if ((cur = g_hash_table_lookup (rspamd_main->workers, GSIZE_TO_POINTER (wrk))) != NULL) { /* Unlink dead process from queue and hash table */ - g_hash_table_remove (rspamd->workers, GSIZE_TO_POINTER (wrk)); + g_hash_table_remove (rspamd_main->workers, GSIZE_TO_POINTER (wrk)); if (WIFEXITED (res) && WEXITSTATUS (res) == 0) { /* Normal worker termination, do not fork one more */ @@ -1070,21 +1054,21 @@ main (gint argc, gchar **argv, gchar **env) } if (do_restart) { do_restart = 0; - reopen_log (); + reopen_log (rspamd_main->logger); msg_info ("rspamd " RVERSION " is restarting"); - g_hash_table_foreach (rspamd->workers, kill_old_workers, NULL); + g_hash_table_foreach (rspamd_main->workers, kill_old_workers, NULL); remove_all_maps (); - reread_config (rspamd); - spawn_workers (rspamd); + reread_config (rspamd_main); + spawn_workers (rspamd_main); } if (do_reopen_log) { do_reopen_log = 0; - reopen_log (); - g_hash_table_foreach (rspamd->workers, reopen_log_handler, NULL); + reopen_log (rspamd_main->logger); + g_hash_table_foreach (rspamd_main->workers, reopen_log_handler, NULL); } if (got_alarm) { got_alarm = 0; - fork_delayed (rspamd); + fork_delayed (rspamd_main); } } @@ -1100,17 +1084,17 @@ main (gint argc, gchar **argv, gchar **env) /* Set alarm for hard termination */ set_alarm (HARD_TERMINATION_TIME); /* Wait for workers termination */ - g_hash_table_foreach_remove (rspamd->workers, wait_for_workers, NULL); + g_hash_table_foreach_remove (rspamd_main->workers, wait_for_workers, NULL); msg_info ("terminating..."); - statfile_pool_delete (rspamd->statfile_pool); + statfile_pool_delete (rspamd_main->statfile_pool); - close_log (); + close_log (rspamd_main->logger); - free_config (rspamd->cfg); - g_free (rspamd->cfg); - g_free (rspamd); + free_config (rspamd_main->cfg); + g_free (rspamd_main->cfg); + g_free (rspamd_main); return (res); } diff --git a/src/main.h b/src/main.h index 581883a6e..186ee9baa 100644 --- a/src/main.h +++ b/src/main.h @@ -96,6 +96,7 @@ struct rspamd_main { memory_pool_t *server_pool; /**< server's memory pool */ statfile_pool_t *statfile_pool; /**< shared statfiles pool */ GHashTable *workers; /**< workers pool indexed by pid */ + rspamd_logger_t *logger; }; struct counter_data { @@ -267,20 +268,9 @@ void start_greylist_storage (struct rspamd_worker *worker); void register_custom_controller_command (const gchar *name, controller_func_t handler, gboolean privilleged, gboolean require_message); /** - * Construct new task for worker - */ -struct worker_task* construct_task (struct rspamd_worker *worker); -/** - * Destroy task object and remove its IO dispatcher if it exists - */ -void free_task (struct worker_task *task, gboolean is_soft); -void free_task_hard (gpointer ud); -void free_task_soft (gpointer ud); - -/** * If set, reopen log file on next write */ -extern sig_atomic_t do_reopen_log; +extern struct rspamd_main *rspamd_main; #endif diff --git a/src/mem_pool.c b/src/mem_pool.c index 85b4a1233..5c48b55ee 100644 --- a/src/mem_pool.c +++ b/src/mem_pool.c @@ -26,6 +26,7 @@ #include "mem_pool.h" #include "fstring.h" #include "logger.h" +#include "main.h" /* Sleep time for spin lock in nanoseconds */ #define MUTEX_SLEEP_TIME 10000000L diff --git a/src/message.c b/src/message.c index 48eb4d89c..ab2e41206 100644 --- a/src/message.c +++ b/src/message.c @@ -1007,9 +1007,7 @@ process_message (struct worker_task *task) task->raw_headers = g_mime_message_get_headers (task->message); #endif -#ifdef RSPAMD_MAIN process_images (task); -#endif /* Parse received headers */ first = message_get_header (task->task_pool, message, "Received", FALSE); diff --git a/src/printf.c b/src/printf.c new file mode 100644 index 000000000..7bdb61cc3 --- /dev/null +++ b/src/printf.c @@ -0,0 +1,566 @@ +/* Copyright (c) 2010, Vsevolod Stakhov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "printf.h" +#include "fstring.h" +#include "main.h" + +static gchar * +rspamd_sprintf_num (gchar *buf, gchar *last, guint64 ui64, gchar zero, + guint hexadecimal, guint width) +{ + gchar *p, temp[sizeof ("18446744073709551615")]; + size_t len; + guint32 ui32; + static gchar hex[] = "0123456789abcdef"; + static gchar HEX[] = "0123456789ABCDEF"; + + p = temp + sizeof(temp); + + if (hexadecimal == 0) { + + if (ui64 <= G_MAXUINT32) { + + /* + * To divide 64-bit numbers and to find remainders + * on the x86 platform gcc and icc call the libc functions + * [u]divdi3() and [u]moddi3(), they call another function + * in its turn. On FreeBSD it is the qdivrem() function, + * its source code is about 170 lines of the code. + * The glibc counterpart is about 150 lines of the code. + * + * For 32-bit numbers and some divisors gcc and icc use + * a inlined multiplication and shifts. For example, + * guint "i32 / 10" is compiled to + * + * (i32 * 0xCCCCCCCD) >> 35 + */ + + ui32 = (guint32) ui64; + + do { + *--p = (gchar) (ui32 % 10 + '0'); + } while (ui32 /= 10); + + } else { + do { + *--p = (gchar) (ui64 % 10 + '0'); + } while (ui64 /= 10); + } + + } else if (hexadecimal == 1) { + + do { + + /* the "(guint32)" cast disables the BCC's warning */ + *--p = hex[(guint32) (ui64 & 0xf)]; + + } while (ui64 >>= 4); + + } else { /* hexadecimal == 2 */ + + do { + + /* the "(guint32)" cast disables the BCC's warning */ + *--p = HEX[(guint32) (ui64 & 0xf)]; + + } while (ui64 >>= 4); + } + + /* zero or space padding */ + + len = (temp + sizeof (temp)) - p; + + while (len++ < width && buf < last) { + *buf++ = zero; + } + + /* number safe copy */ + + len = (temp + sizeof (temp)) - p; + + if (buf + len > last) { + len = last - buf; + } + + return ((gchar *)memcpy (buf, p, len)) + len; +} + +gint +rspamd_fprintf (FILE *f, const gchar *fmt, ...) +{ + gchar *p; + va_list args; + gchar buf[BUFSIZ]; + gint r; + + va_start (args, fmt); + p = rspamd_vsnprintf (buf, sizeof (buf), fmt, args); + va_end (args); + + r = fprintf (f, "%s", buf); + + return r; +} + +gint +rspamd_sprintf (gchar *buf, const gchar *fmt, ...) +{ + gchar *p; + va_list args; + + va_start (args, fmt); + p = rspamd_vsnprintf (buf, /* STUB */ 65536, fmt, args); + va_end (args); + + return p - buf; +} + + +gint +rspamd_snprintf (gchar *buf, size_t max, const gchar *fmt, ...) +{ + gchar *p; + va_list args; + + va_start (args, fmt); + p = rspamd_vsnprintf (buf, max - 1, fmt, args); + va_end (args); + *p = '\0'; + + return p - buf; +} + +gchar * +rspamd_escape_string (gchar *dst, const gchar *src, gsize len) +{ + gchar *buf = dst, *last = dst + len; + guint8 c; + const gchar *p = src; + gunichar uc; + + while (*p && buf < last) { + /* Detect utf8 */ + uc = g_utf8_get_char_validated (p, last - buf); + if (uc > 0) { + c = g_unichar_to_utf8 (uc, buf); + buf += c; + p += c; + } + else { + c = *p ++; + if (G_UNLIKELY ((c & 0x80))) { + c &= 0x7F; + if (last - buf >= 3) { + *buf++ = 'M'; + *buf++ = '-'; + } + } + if (G_UNLIKELY ( g_ascii_iscntrl (c))) { + if (c == '\n') { + *buf++ = ' '; + } + else if (c == '\t') { + *buf++ = '\t'; + } + else { + *buf++ = '^'; + if (buf != last) { + *buf++ = c ^ 0100; + } + } + } + else { + *buf++ = c; + } + } + } + + *buf = '\0'; + + return buf; +} + +gchar * +rspamd_vsnprintf (gchar *buf, size_t max, const gchar *fmt, va_list args) +{ + gchar *p, zero, *last; + gint d; + long double f, scale; + size_t len, slen; + gint64 i64; + guint64 ui64; + guint width, sign, hex, max_width, frac_width, i; + f_str_t *v; + + if (max == 0) { + return buf; + } + + last = buf + max; + + while (*fmt && buf < last) { + + /* + * "buf < last" means that we could copy at least one character: + * the plain character, "%%", "%c", and minus without the checking + */ + + if (*fmt == '%') { + + i64 = 0; + ui64 = 0; + + zero = (gchar) ((*++fmt == '0') ? '0' : ' '); + width = 0; + sign = 1; + hex = 0; + max_width = 0; + frac_width = 0; + slen = (size_t) -1; + + while (*fmt >= '0' && *fmt <= '9') { + width = width * 10 + *fmt++ - '0'; + } + + + for ( ;; ) { + switch (*fmt) { + + case 'u': + sign = 0; + fmt++; + continue; + + case 'm': + max_width = 1; + fmt++; + continue; + + case 'X': + hex = 2; + sign = 0; + fmt++; + continue; + + case 'x': + hex = 1; + sign = 0; + fmt++; + continue; + case '.': + fmt++; + + while (*fmt >= '0' && *fmt <= '9') { + frac_width = frac_width * 10 + *fmt++ - '0'; + } + + break; + + case '*': + d = (gint)va_arg (args, gint); + if (G_UNLIKELY (d < 0)) { + msg_err ("crititcal error: size is less than 0"); + g_assert (0); + } + slen = (size_t)d; + fmt++; + continue; + + default: + break; + } + + break; + } + + + switch (*fmt) { + + case 'V': + v = va_arg (args, f_str_t *); + + len = v->len; + len = (buf + len < last) ? len : (size_t) (last - buf); + + buf = ((gchar *)memcpy (buf, v->begin, len)) + len; + fmt++; + + continue; + + case 's': + p = va_arg(args, gchar *); + if (p == NULL) { + p = "(NULL)"; + } + + if (slen == (size_t) -1) { + while (*p && buf < last) { + *buf++ = *p++; + } + + } else { + len = (buf + slen < last) ? slen : (size_t) (last - buf); + + buf = ((gchar *)memcpy (buf, p, len)) + len; + } + + fmt++; + + continue; + + case 'S': + p = va_arg(args, gchar *); + if (p == NULL) { + p = "(NULL)"; + } + + if (slen == (size_t) -1) { + buf = rspamd_escape_string (buf, p, last - buf); + + } else { + len = (buf + slen < last) ? slen : (size_t) (last - buf); + + buf = rspamd_escape_string (buf, p, len); + } + + fmt++; + + continue; + + case 'O': + i64 = (gint64) va_arg (args, off_t); + sign = 1; + break; + + case 'P': + i64 = (gint64) va_arg (args, pid_t); + sign = 1; + break; + + case 'T': + i64 = (gint64) va_arg (args, time_t); + sign = 1; + break; + + case 'z': + if (sign) { + i64 = (gint64) va_arg (args, ssize_t); + } else { + ui64 = (guint64) va_arg (args, size_t); + } + break; + + case 'd': + if (sign) { + i64 = (gint64) va_arg (args, gint); + } else { + ui64 = (guint64) va_arg (args, guint); + } + break; + + case 'l': + if (sign) { + i64 = (gint64) va_arg(args, long); + } else { + ui64 = (guint64) va_arg(args, guint32); + } + break; + + case 'D': + if (sign) { + i64 = (gint64) va_arg(args, gint32); + } else { + ui64 = (guint64) va_arg(args, guint32); + } + break; + + case 'L': + if (sign) { + i64 = va_arg (args, gint64); + } else { + ui64 = va_arg (args, guint64); + } + break; + + + case 'f': + f = (double) va_arg (args, double); + if (f < 0) { + *buf++ = '-'; + f = -f; + } + + ui64 = (gint64) f; + + buf = rspamd_sprintf_num (buf, last, ui64, zero, 0, width); + + if (frac_width) { + + if (buf < last) { + *buf++ = '.'; + } + + scale = 1.0; + + for (i = 0; i < frac_width; i++) { + scale *= 10.0; + } + + /* + * (gint64) cast is required for msvc6: + * it can not convert guint64 to double + */ + ui64 = (guint64) ((f - (gint64) ui64) * scale); + + buf = rspamd_sprintf_num (buf, last, ui64, '0', 0, frac_width); + } + + fmt++; + + continue; + + case 'F': + f = (long double) va_arg (args, long double); + + if (f < 0) { + *buf++ = '-'; + f = -f; + } + + ui64 = (gint64) f; + + buf = rspamd_sprintf_num (buf, last, ui64, zero, 0, width); + + if (frac_width) { + + if (buf < last) { + *buf++ = '.'; + } + + scale = 1.0; + + for (i = 0; i < frac_width; i++) { + scale *= 10.0; + } + + /* + * (gint64) cast is required for msvc6: + * it can not convert guint64 to double + */ + ui64 = (guint64) ((f - (gint64) ui64) * scale); + + buf = rspamd_sprintf_num (buf, last, ui64, '0', 0, frac_width); + } + + fmt++; + + continue; + + case 'g': + f = (long double) va_arg (args, double); + + if (f < 0) { + *buf++ = '-'; + f = -f; + } + g_ascii_formatd (buf, last - buf, "%g", (double)f); + buf += strlen (buf); + fmt++; + + continue; + + case 'G': + f = (long double) va_arg (args, long double); + + if (f < 0) { + *buf++ = '-'; + f = -f; + } + g_ascii_formatd (buf, last - buf, "%g", (double)f); + buf += strlen (buf); + fmt++; + + continue; + + case 'p': + ui64 = (uintptr_t) va_arg (args, void *); + hex = 2; + sign = 0; + zero = '0'; + width = sizeof (void *) * 2; + break; + + case 'c': + d = va_arg (args, gint); + *buf++ = (gchar) (d & 0xff); + fmt++; + + continue; + + case 'Z': + *buf++ = '\0'; + fmt++; + + continue; + + case 'N': + *buf++ = LF; + fmt++; + + continue; + + case '%': + *buf++ = '%'; + fmt++; + + continue; + + default: + *buf++ = *fmt++; + + continue; + } + + if (sign) { + if (i64 < 0) { + *buf++ = '-'; + ui64 = (guint64) -i64; + + } else { + ui64 = (guint64) i64; + } + } + + buf = rspamd_sprintf_num (buf, last, ui64, zero, hex, width); + + fmt++; + + } else { + *buf++ = *fmt++; + } + } + + return buf; +} + diff --git a/src/printf.h b/src/printf.h new file mode 100644 index 000000000..74f665a2d --- /dev/null +++ b/src/printf.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2010, Vsevolod Stakhov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef PRINTF_H_ +#define PRINTF_H_ + +#include "config.h" + +/* + * supported formats: + * %[0][width][x][X]O off_t + * %[0][width]T time_t + * %[0][width][u][x|X]z ssize_t/size_t + * %[0][width][u][x|X]d gint/guint + * %[0][width][u][x|X]l long + * %[0][width][u][x|X]D gint32/guint32 + * %[0][width][u][x|X]L gint64/guint64 + * %[0][width][.width]f double + * %[0][width][.width]F long double + * %[0][width][.width]g double + * %[0][width][.width]G long double + * %P pid_t + * %r rlim_t + * %p void * + * %V f_str_t * + * %s null-terminated string + * %S ascii null-terminated string + * %*s length and string + * %Z '\0' + * %N '\n' + * %c gchar + * %% % + * + */ +gint rspamd_sprintf (gchar *buf, const gchar *fmt, ...); +gint rspamd_fprintf (FILE *f, const gchar *fmt, ...); +gint rspamd_snprintf (gchar *buf, size_t max, const gchar *fmt, ...); +gchar *rspamd_vsnprintf (gchar *buf, size_t max, const gchar *fmt, va_list args); + +#endif /* PRINTF_H_ */ diff --git a/src/smtp.c b/src/smtp.c index 390e73117..c2fa22980 100644 --- a/src/smtp.c +++ b/src/smtp.c @@ -65,7 +65,7 @@ sig_handler (gint signo, siginfo_t *info, void *unused) switch (signo) { case SIGUSR1: - reopen_log (); + reopen_log (rspamd_main->logger); break; case SIGINT: case SIGTERM: @@ -97,7 +97,6 @@ sigusr_handler (gint fd, short what, void *arg) tv.tv_usec = 0; event_del (&worker->sig_ev); event_del (&worker->bind_ev); - do_reopen_log = 1; msg_info ("worker's shutdown is pending in %d sec", SOFT_SHUTDOWN_TIME); event_loopexit (&tv); } @@ -572,7 +571,7 @@ smtp_dns_cb (struct rspamd_dns_reply *reply, void *arg) case SMTP_STATE_RESOLVE_REVERSE: /* Parse reverse reply and start resolve of this ip */ if (reply->code != DNS_RC_NOERROR) { - rspamd_conditional_debug(session->client_addr.s_addr, __FUNCTION__, + rspamd_conditional_debug(rspamd_main->logger, session->client_addr.s_addr, __FUNCTION__, "DNS error: %s", dns_strerror (reply->code)); if (reply->code == DNS_RC_NXDOMAIN) { @@ -596,7 +595,7 @@ smtp_dns_cb (struct rspamd_dns_reply *reply, void *arg) break; case SMTP_STATE_RESOLVE_NORMAL: if (reply->code != DNS_RC_NOERROR) { - rspamd_conditional_debug(session->client_addr.s_addr, __FUNCTION__, + rspamd_conditional_debug(rspamd_main->logger, session->client_addr.s_addr, __FUNCTION__, "DNS error: %s", dns_strerror (reply->code)); if (reply->code == DNS_RC_NXDOMAIN) { @@ -1008,7 +1007,7 @@ start_smtp_worker (struct rspamd_worker *worker) event_loop (0); - close_log (); + close_log (rspamd_main->logger); exit (EXIT_SUCCESS); } diff --git a/src/symbols_cache.c b/src/symbols_cache.c index 0c4891df2..c4327b470 100644 --- a/src/symbols_cache.c +++ b/src/symbols_cache.c @@ -950,9 +950,9 @@ call_symbol_callback (struct worker_task * task, struct symbols_cache * cache, g } #endif if (G_UNLIKELY (check_debug_symbol (task->cfg, item->s->symbol))) { - rspamd_log_debug (); + rspamd_log_debug (rspamd_main->logger); item->func (task, item->user_data); - rspamd_log_nodebug (); + rspamd_log_nodebug (rspamd_main->logger); } else { item->func (task, item->user_data); diff --git a/src/tokenizers/osb.c b/src/tokenizers/osb.c index 41bcce737..1a04f3464 100644 --- a/src/tokenizers/osb.c +++ b/src/tokenizers/osb.c @@ -35,7 +35,8 @@ extern const int primes[]; int -osb_tokenize_text (struct tokenizer *tokenizer, memory_pool_t * pool, f_str_t * input, GTree ** tree, gboolean save_token) +osb_tokenize_text (struct tokenizer *tokenizer, memory_pool_t * pool, f_str_t * input, GTree ** tree, + gboolean save_token) { token_node_t *new = NULL; f_str_t token = { NULL, 0, 0 }, *res; diff --git a/src/util.c b/src/util.c index a420493dc..89bc13336 100644 --- a/src/util.c +++ b/src/util.c @@ -28,6 +28,8 @@ #include "cfg_file.h" #include "main.h" #include "statfile.h" +#include "filter.h" +#include "message.h" /* Check log messages intensity once per minute */ #define CHECK_TIME 60 @@ -36,9 +38,7 @@ /* Default connect timeout for sync sockets */ #define CONNECT_TIMEOUT 3 -#ifdef RSPAMD_MAIN -extern rspamd_hash_t *counters; -#endif +rspamd_hash_t *counters = NULL; static gchar* rspamd_sprintf_num (gchar *buf, gchar *last, guint64 ui64, gchar zero, guint hexadecimal, guint width); @@ -822,7 +822,6 @@ calculate_check_time (struct timeval *begin, gint resolution) double set_counter (const gchar *name, guint32 value) { -#ifdef RSPAMD_MAIN struct counter_data *cd; double alpha; gchar *key; @@ -847,9 +846,6 @@ set_counter (const gchar *name, guint32 value) } return cd->value; -#else - return 0; -#endif } #ifndef g_tolower @@ -912,7 +908,7 @@ fstr_strcase_hash (gconstpointer key) void gperf_profiler_init (struct config_file *cfg, const gchar *descr) { -#if defined(WITH_GPERF_TOOLS) && defined(RSPAMD_MAIN) +#if defined(WITH_GPERF_TOOLS) gchar prof_path[PATH_MAX]; if (getenv ("CPUPROFILE")) { @@ -1031,7 +1027,6 @@ unlock_file (gint fd, gboolean async) } #endif /* HAVE_FLOCK */ -#ifdef RSPAMD_MAIN stat_file_t * get_statfile_by_symbol (statfile_pool_t *pool, struct classifier_config *ccf, const gchar *symbol, struct statfile **st, gboolean try_create) @@ -1076,539 +1071,8 @@ get_statfile_by_symbol (statfile_pool_t *pool, struct classifier_config *ccf, return res; } -#endif /* RSPAMD_MAIN */ - - -gint -rspamd_fprintf (FILE *f, const gchar *fmt, ...) -{ - gchar *p; - va_list args; - gchar buf[BUFSIZ]; - gint r; - - va_start (args, fmt); - p = rspamd_vsnprintf (buf, sizeof (buf), fmt, args); - va_end (args); - - r = fprintf (f, "%s", buf); - - return r; -} - -gint -rspamd_sprintf (gchar *buf, const gchar *fmt, ...) -{ - gchar *p; - va_list args; - - va_start (args, fmt); - p = rspamd_vsnprintf (buf, /* STUB */ 65536, fmt, args); - va_end (args); - - return p - buf; -} - - -gint -rspamd_snprintf (gchar *buf, size_t max, const gchar *fmt, ...) -{ - gchar *p; - va_list args; - - va_start (args, fmt); - p = rspamd_vsnprintf (buf, max - 1, fmt, args); - va_end (args); - *p = '\0'; - - return p - buf; -} - -gchar * -rspamd_escape_string (gchar *dst, const gchar *src, gsize len) -{ - gchar *buf = dst, *last = dst + len; - guint8 c; - const gchar *p = src; - - while (*p && buf < last) { - c = *p++; - if (G_UNLIKELY ((c & 0x80))) { - c &= 0x7F; - if (last - buf >= 3) { - *buf++ = 'M'; - *buf++ = '-'; - } - } - - if (G_UNLIKELY ( g_ascii_iscntrl (c))) { - if (c == '\n') { - *buf++ = ' '; - } - else if (c == '\t') { - *buf++ = '\t'; - } - else { - *buf++ = '^'; - if (buf != last) { - *buf++ = c ^ 0100; - } - } - } - else { - *buf++ = c; - } - } - - *buf = '\0'; - - return buf; -} - -gchar * -rspamd_vsnprintf (gchar *buf, size_t max, const gchar *fmt, va_list args) -{ - gchar *p, zero, *last; - gint d; - long double f, scale; - size_t len, slen; - gint64 i64; - guint64 ui64; - guint width, sign, hex, max_width, frac_width, i; - f_str_t *v; - - if (max == 0) { - return buf; - } - - last = buf + max; - - while (*fmt && buf < last) { - - /* - * "buf < last" means that we could copy at least one character: - * the plain character, "%%", "%c", and minus without the checking - */ - - if (*fmt == '%') { - - i64 = 0; - ui64 = 0; - - zero = (gchar) ((*++fmt == '0') ? '0' : ' '); - width = 0; - sign = 1; - hex = 0; - max_width = 0; - frac_width = 0; - slen = (size_t) -1; - - while (*fmt >= '0' && *fmt <= '9') { - width = width * 10 + *fmt++ - '0'; - } - - - for ( ;; ) { - switch (*fmt) { - - case 'u': - sign = 0; - fmt++; - continue; - - case 'm': - max_width = 1; - fmt++; - continue; - - case 'X': - hex = 2; - sign = 0; - fmt++; - continue; - - case 'x': - hex = 1; - sign = 0; - fmt++; - continue; - case '.': - fmt++; - - while (*fmt >= '0' && *fmt <= '9') { - frac_width = frac_width * 10 + *fmt++ - '0'; - } - - break; - - case '*': - d = (gint)va_arg (args, gint); - if (G_UNLIKELY (d < 0)) { - msg_err ("crititcal error: size is less than 0"); - g_assert (0); - } - slen = (size_t)d; - fmt++; - continue; - - default: - break; - } - - break; - } - - - switch (*fmt) { - - case 'V': - v = va_arg (args, f_str_t *); - - len = v->len; - len = (buf + len < last) ? len : (size_t) (last - buf); - - buf = ((gchar *)memcpy (buf, v->begin, len)) + len; - fmt++; - - continue; - - case 's': - p = va_arg(args, gchar *); - if (p == NULL) { - p = "(NULL)"; - } - - if (slen == (size_t) -1) { - while (*p && buf < last) { - *buf++ = *p++; - } - - } else { - len = (buf + slen < last) ? slen : (size_t) (last - buf); - - buf = ((gchar *)memcpy (buf, p, len)) + len; - } - - fmt++; - - continue; - - case 'S': - p = va_arg(args, gchar *); - if (p == NULL) { - p = "(NULL)"; - } - - if (slen == (size_t) -1) { - buf = rspamd_escape_string (buf, p, last - buf); - - } else { - len = (buf + slen < last) ? slen : (size_t) (last - buf); - - buf = rspamd_escape_string (buf, p, len); - } - - fmt++; - - continue; - - case 'O': - i64 = (gint64) va_arg (args, off_t); - sign = 1; - break; - - case 'P': - i64 = (gint64) va_arg (args, pid_t); - sign = 1; - break; - - case 'T': - i64 = (gint64) va_arg (args, time_t); - sign = 1; - break; - - case 'z': - if (sign) { - i64 = (gint64) va_arg (args, ssize_t); - } else { - ui64 = (guint64) va_arg (args, size_t); - } - break; - - case 'd': - if (sign) { - i64 = (gint64) va_arg (args, gint); - } else { - ui64 = (guint64) va_arg (args, guint); - } - break; - - case 'l': - if (sign) { - i64 = (gint64) va_arg(args, long); - } else { - ui64 = (guint64) va_arg(args, guint32); - } - break; - - case 'D': - if (sign) { - i64 = (gint64) va_arg(args, gint32); - } else { - ui64 = (guint64) va_arg(args, guint32); - } - break; - - case 'L': - if (sign) { - i64 = va_arg (args, gint64); - } else { - ui64 = va_arg (args, guint64); - } - break; - - - case 'f': - f = (double) va_arg (args, double); - if (f < 0) { - *buf++ = '-'; - f = -f; - } - - ui64 = (gint64) f; - - buf = rspamd_sprintf_num (buf, last, ui64, zero, 0, width); - - if (frac_width) { - - if (buf < last) { - *buf++ = '.'; - } - - scale = 1.0; - - for (i = 0; i < frac_width; i++) { - scale *= 10.0; - } - - /* - * (gint64) cast is required for msvc6: - * it can not convert guint64 to double - */ - ui64 = (guint64) ((f - (gint64) ui64) * scale); - - buf = rspamd_sprintf_num (buf, last, ui64, '0', 0, frac_width); - } - - fmt++; - - continue; - - case 'F': - f = (long double) va_arg (args, long double); - - if (f < 0) { - *buf++ = '-'; - f = -f; - } - - ui64 = (gint64) f; - - buf = rspamd_sprintf_num (buf, last, ui64, zero, 0, width); - - if (frac_width) { - - if (buf < last) { - *buf++ = '.'; - } - - scale = 1.0; - - for (i = 0; i < frac_width; i++) { - scale *= 10.0; - } - - /* - * (gint64) cast is required for msvc6: - * it can not convert guint64 to double - */ - ui64 = (guint64) ((f - (gint64) ui64) * scale); - - buf = rspamd_sprintf_num (buf, last, ui64, '0', 0, frac_width); - } - fmt++; - continue; - - case 'g': - f = (long double) va_arg (args, double); - - if (f < 0) { - *buf++ = '-'; - f = -f; - } - g_ascii_formatd (buf, last - buf, "%g", (double)f); - buf += strlen (buf); - fmt++; - - continue; - - case 'G': - f = (long double) va_arg (args, long double); - - if (f < 0) { - *buf++ = '-'; - f = -f; - } - g_ascii_formatd (buf, last - buf, "%g", (double)f); - buf += strlen (buf); - fmt++; - - continue; - - case 'p': - ui64 = (uintptr_t) va_arg (args, void *); - hex = 2; - sign = 0; - zero = '0'; - width = sizeof (void *) * 2; - break; - - case 'c': - d = va_arg (args, gint); - *buf++ = (gchar) (d & 0xff); - fmt++; - - continue; - - case 'Z': - *buf++ = '\0'; - fmt++; - - continue; - - case 'N': - *buf++ = LF; - fmt++; - - continue; - - case '%': - *buf++ = '%'; - fmt++; - - continue; - - default: - *buf++ = *fmt++; - - continue; - } - - if (sign) { - if (i64 < 0) { - *buf++ = '-'; - ui64 = (guint64) -i64; - - } else { - ui64 = (guint64) i64; - } - } - - buf = rspamd_sprintf_num (buf, last, ui64, zero, hex, width); - - fmt++; - - } else { - *buf++ = *fmt++; - } - } - - return buf; -} - - -static gchar * -rspamd_sprintf_num (gchar *buf, gchar *last, guint64 ui64, gchar zero, - guint hexadecimal, guint width) -{ - gchar *p, temp[sizeof ("18446744073709551615")]; - size_t len; - guint32 ui32; - static gchar hex[] = "0123456789abcdef"; - static gchar HEX[] = "0123456789ABCDEF"; - - p = temp + sizeof(temp); - - if (hexadecimal == 0) { - - if (ui64 <= G_MAXUINT32) { - - /* - * To divide 64-bit numbers and to find remainders - * on the x86 platform gcc and icc call the libc functions - * [u]divdi3() and [u]moddi3(), they call another function - * in its turn. On FreeBSD it is the qdivrem() function, - * its source code is about 170 lines of the code. - * The glibc counterpart is about 150 lines of the code. - * - * For 32-bit numbers and some divisors gcc and icc use - * a inlined multiplication and shifts. For example, - * guint "i32 / 10" is compiled to - * - * (i32 * 0xCCCCCCCD) >> 35 - */ - - ui32 = (guint32) ui64; - - do { - *--p = (gchar) (ui32 % 10 + '0'); - } while (ui32 /= 10); - - } else { - do { - *--p = (gchar) (ui64 % 10 + '0'); - } while (ui64 /= 10); - } - - } else if (hexadecimal == 1) { - - do { - - /* the "(guint32)" cast disables the BCC's warning */ - *--p = hex[(guint32) (ui64 & 0xf)]; - - } while (ui64 >>= 4); - - } else { /* hexadecimal == 2 */ - - do { - - /* the "(guint32)" cast disables the BCC's warning */ - *--p = HEX[(guint32) (ui64 & 0xf)]; - - } while (ui64 >>= 4); - } - - /* zero or space padding */ - - len = (temp + sizeof (temp)) - p; - - while (len++ < width && buf < last) { - *buf++ = zero; - } - - /* number safe copy */ - - len = (temp + sizeof (temp)) - p; - - if (buf + len > last) { - len = last - buf; - } - - return ((gchar *)memcpy (buf, p, len)) + len; -} #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION < 22)) void @@ -1696,5 +1160,182 @@ str_to_process (const gchar *str) } /* + * Destructor for recipients list + */ +static void +rcpt_destruct (void *pointer) +{ + struct worker_task *task = (struct worker_task *) pointer; + + if (task->rcpt) { + g_list_free (task->rcpt); + } +} + + +/* Compare two emails for building emails tree */ +static gint +compare_email_func (gconstpointer a, gconstpointer b) +{ + const struct uri *u1 = a, *u2 = b; + gint r; + + if (u1->hostlen != u2->hostlen || u1->hostlen == 0) { + return u1->hostlen - u2->hostlen; + } + else { + if ((r = g_ascii_strncasecmp (u1->host, u2->host, u1->hostlen)) == 0){ + if (u1->userlen != u2->userlen || u1->userlen == 0) { + return u1->userlen - u2->userlen; + } + else { + return g_ascii_strncasecmp (u1->user, u2->user, u1->userlen); + } + } + else { + return r; + } + } + + return 0; +} + +static gint +compare_url_func (gconstpointer a, gconstpointer b) +{ + const struct uri *u1 = a, *u2 = b; + int r; + + if (u1->hostlen != u2->hostlen || u1->hostlen == 0) { + return u1->hostlen - u2->hostlen; + } + else { + r = g_ascii_strncasecmp (u1->host, u2->host, u1->hostlen); + } + + return r; +} + +/* + * Create new task + */ +struct worker_task * +construct_task (struct rspamd_worker *worker) +{ + struct worker_task *new_task; + + new_task = g_slice_alloc0 (sizeof (struct worker_task)); + + new_task->worker = worker; + new_task->state = READ_COMMAND; + new_task->cfg = worker->srv->cfg; + new_task->from_addr.s_addr = INADDR_NONE; + new_task->view_checked = FALSE; +#ifdef HAVE_CLOCK_GETTIME +# ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID + clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &new_task->ts); +# elif defined(HAVE_CLOCK_VIRTUAL) + clock_gettime (CLOCK_VIRTUAL, &new_task->ts); +# else + clock_gettime (CLOCK_REALTIME, &new_task->ts); +# endif +#endif + if (gettimeofday (&new_task->tv, NULL) == -1) { + msg_warn ("gettimeofday failed: %s", strerror (errno)); + } + + new_task->task_pool = memory_pool_new (memory_pool_get_size ()); + + /* Add destructor for recipients list (it would be better to use anonymous function here */ + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) rcpt_destruct, new_task); + new_task->results = g_hash_table_new (g_str_hash, g_str_equal); + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) g_hash_table_destroy, + new_task->results); + new_task->re_cache = g_hash_table_new (g_str_hash, g_str_equal); + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) g_hash_table_destroy, + new_task->re_cache); + new_task->emails = g_tree_new (compare_email_func); + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) g_tree_destroy, + new_task->emails); + new_task->urls = g_tree_new (compare_url_func); + memory_pool_add_destructor (new_task->task_pool, + (pool_destruct_func) g_tree_destroy, + new_task->urls); + new_task->s = + new_async_session (new_task->task_pool, free_task_hard, new_task); + new_task->sock = -1; + new_task->is_mime = TRUE; + + return new_task; +} + + +/* + * Free all structures of worker_task + */ +void +free_task (struct worker_task *task, gboolean is_soft) +{ + GList *part; + struct mime_part *p; + + if (task) { + debug_task ("free pointer %p", task); + while ((part = g_list_first (task->parts))) { + task->parts = g_list_remove_link (task->parts, part); + p = (struct mime_part *) part->data; + g_byte_array_free (p->content, TRUE); + g_list_free_1 (part); + } + if (task->text_parts) { + g_list_free (task->text_parts); + } + if (task->images) { + g_list_free (task->images); + } + if (task->messages) { + g_list_free (task->messages); + } + if (task->received) { + g_list_free (task->received); + } + memory_pool_delete (task->task_pool); + if (task->dispatcher) { + if (is_soft) { + /* Plan dispatcher shutdown */ + task->dispatcher->wanna_die = 1; + } + else { + rspamd_remove_dispatcher (task->dispatcher); + } + } + if (task->sock != -1) { + close (task->sock); + } + g_slice_free1 (sizeof (struct worker_task), task); + } +} + +void +free_task_hard (gpointer ud) +{ + struct worker_task *task = ud; + + free_task (task, FALSE); +} + +void +free_task_soft (gpointer ud) +{ + struct worker_task *task = ud; + + free_task (task, FALSE); +} + +/* * vi:ts=4 */ diff --git a/src/util.h b/src/util.h index f4eea0bd6..8f910e404 100644 --- a/src/util.h +++ b/src/util.h @@ -5,6 +5,7 @@ #include "mem_pool.h" #include "radix.h" #include "statfile.h" +#include "printf.h" struct config_file; struct rspamd_main; @@ -97,44 +98,13 @@ gboolean fstr_strcase_equal (gconstpointer v, gconstpointer v2); void gperf_profiler_init (struct config_file *cfg, const gchar *descr); -#ifdef RSPAMD_MAIN stat_file_t* get_statfile_by_symbol (statfile_pool_t *pool, struct classifier_config *ccf, const gchar *symbol, struct statfile **st, gboolean try_create); -#endif #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION < 22)) void g_ptr_array_unref (GPtrArray *array); #endif -/* - * supported formats: - * %[0][width][x][X]O off_t - * %[0][width]T time_t - * %[0][width][u][x|X]z ssize_t/size_t - * %[0][width][u][x|X]d gint/guint - * %[0][width][u][x|X]l long - * %[0][width][u][x|X]D gint32/guint32 - * %[0][width][u][x|X]L gint64/guint64 - * %[0][width][.width]f double - * %[0][width][.width]F long double - * %[0][width][.width]g double - * %[0][width][.width]G long double - * %P pid_t - * %r rlim_t - * %p void * - * %V f_str_t * - * %s null-terminated string - * %S ascii null-terminated string - * %*s length and string - * %Z '\0' - * %N '\n' - * %c gchar - * %% % - * - */ -gint rspamd_sprintf (gchar *buf, const gchar *fmt, ...); -gint rspamd_fprintf (FILE *f, const gchar *fmt, ...); -gint rspamd_snprintf (gchar *buf, size_t max, const gchar *fmt, ...); -gchar *rspamd_vsnprintf (gchar *buf, size_t max, const gchar *fmt, va_list args); + /* * Copy src to dest limited to len, in compare with standart strlcpy(3) rspamd strlcpy does not @@ -178,4 +148,18 @@ enum process_type str_to_process (const gchar *str); */ #define msec_to_tv(msec, tv) do { (tv)->tv_sec = (msec) / 1000; (tv)->tv_usec = ((msec) - (tv)->tv_sec * 1000) * 1000; } while(0) +struct worker_task; +struct rspamd_worker; + +/** + * Construct new task for worker + */ +struct worker_task* construct_task (struct rspamd_worker *worker); +/** + * Destroy task object and remove its IO dispatcher if it exists + */ +void free_task (struct worker_task *task, gboolean is_soft); +void free_task_hard (gpointer ud); +void free_task_soft (gpointer ud); + #endif diff --git a/src/worker.c b/src/worker.c index a9b05d64e..26ca8af24 100644 --- a/src/worker.c +++ b/src/worker.c @@ -41,13 +41,6 @@ #include "lua/lua_common.h" -#ifndef WITHOUT_PERL -# include <EXTERN.h> /* from the Perl distribution */ -# include <perl.h> /* from the Perl distribution */ - -extern PerlInterpreter *perl_interpreter; -#endif - #ifdef WITH_GPERF_TOOLS # include <glib/gprintf.h> #endif @@ -112,7 +105,7 @@ sig_handler (gint signo, siginfo_t * info, void *unused) switch (signo) { case SIGUSR1: - reopen_log (); + reopen_log (rspamd_main->logger); break; case SIGINT: case SIGTERM: @@ -145,26 +138,12 @@ sigusr_handler (gint fd, short what, void *arg) tv.tv_usec = 0; event_del (&worker->sig_ev); event_del (&worker->bind_ev); - do_reopen_log = 1; msg_info ("worker's shutdown is pending in %d sec", SOFT_SHUTDOWN_TIME); event_loopexit (&tv); } return; } -/* - * Destructor for recipients list - */ -static void -rcpt_destruct (void *pointer) -{ - struct worker_task *task = (struct worker_task *) pointer; - - if (task->rcpt) { - g_list_free (task->rcpt); - } -} - #ifndef BUILD_STATIC static void fin_custom_filters (struct worker_task *task) @@ -250,68 +229,6 @@ parse_line_custom (struct worker_task *task, f_str_t * in) #endif /* - * Free all structures of worker_task - */ -void -free_task (struct worker_task *task, gboolean is_soft) -{ - GList *part; - struct mime_part *p; - - if (task) { - debug_task ("free pointer %p", task); - while ((part = g_list_first (task->parts))) { - task->parts = g_list_remove_link (task->parts, part); - p = (struct mime_part *) part->data; - g_byte_array_free (p->content, TRUE); - g_list_free_1 (part); - } - if (task->text_parts) { - g_list_free (task->text_parts); - } - if (task->images) { - g_list_free (task->images); - } - if (task->messages) { - g_list_free (task->messages); - } - if (task->received) { - g_list_free (task->received); - } - memory_pool_delete (task->task_pool); - if (task->dispatcher) { - if (is_soft) { - /* Plan dispatcher shutdown */ - task->dispatcher->wanna_die = 1; - } - else { - rspamd_remove_dispatcher (task->dispatcher); - } - } - if (task->sock != -1) { - close (task->sock); - } - g_free (task); - } -} - -void -free_task_hard (gpointer ud) -{ - struct worker_task *task = ud; - - free_task (task, FALSE); -} - -void -free_task_soft (gpointer ud) -{ - struct worker_task *task = ud; - - free_task (task, FALSE); -} - -/* * Callback that is called when there is data to read in buffer */ static gboolean @@ -485,106 +402,6 @@ err_socket (GError * err, void *arg) } } -/* Compare two emails for building emails tree */ -static gint -compare_email_func (gconstpointer a, gconstpointer b) -{ - const struct uri *u1 = a, *u2 = b; - gint r; - - if (u1->hostlen != u2->hostlen || u1->hostlen == 0) { - return u1->hostlen - u2->hostlen; - } - else { - if ((r = g_ascii_strncasecmp (u1->host, u2->host, u1->hostlen)) == 0){ - if (u1->userlen != u2->userlen || u1->userlen == 0) { - return u1->userlen - u2->userlen; - } - else { - return g_ascii_strncasecmp (u1->user, u2->user, u1->userlen); - } - } - else { - return r; - } - } - - return 0; -} - -static gint -compare_url_func (gconstpointer a, gconstpointer b) -{ - const struct uri *u1 = a, *u2 = b; - int r; - - if (u1->hostlen != u2->hostlen || u1->hostlen == 0) { - return u1->hostlen - u2->hostlen; - } - else { - r = g_ascii_strncasecmp (u1->host, u2->host, u1->hostlen); - } - - return r; -} - -/* - * Create new task - */ -struct worker_task * -construct_task (struct rspamd_worker *worker) -{ - struct worker_task *new_task; - - new_task = g_malloc0 (sizeof (struct worker_task)); - - new_task->worker = worker; - new_task->state = READ_COMMAND; - new_task->cfg = worker->srv->cfg; - new_task->from_addr.s_addr = INADDR_NONE; - new_task->view_checked = FALSE; -#ifdef HAVE_CLOCK_GETTIME -# ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID - clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &new_task->ts); -# elif defined(HAVE_CLOCK_VIRTUAL) - clock_gettime (CLOCK_VIRTUAL, &new_task->ts); -# else - clock_gettime (CLOCK_REALTIME, &new_task->ts); -# endif -#endif - if (gettimeofday (&new_task->tv, NULL) == -1) { - msg_warn ("gettimeofday failed: %s", strerror (errno)); - } - - new_task->task_pool = memory_pool_new (memory_pool_get_size ()); - - /* Add destructor for recipients list (it would be better to use anonymous function here */ - memory_pool_add_destructor (new_task->task_pool, - (pool_destruct_func) rcpt_destruct, new_task); - new_task->results = g_hash_table_new (g_str_hash, g_str_equal); - memory_pool_add_destructor (new_task->task_pool, - (pool_destruct_func) g_hash_table_destroy, - new_task->results); - new_task->re_cache = g_hash_table_new (g_str_hash, g_str_equal); - memory_pool_add_destructor (new_task->task_pool, - (pool_destruct_func) g_hash_table_destroy, - new_task->re_cache); - new_task->emails = g_tree_new (compare_email_func); - memory_pool_add_destructor (new_task->task_pool, - (pool_destruct_func) g_tree_destroy, - new_task->emails); - new_task->urls = g_tree_new (compare_url_func); - memory_pool_add_destructor (new_task->task_pool, - (pool_destruct_func) g_tree_destroy, - new_task->urls); - new_task->s = - new_async_session (new_task->task_pool, free_task_hard, new_task); - new_task->sock = -1; - new_task->is_mime = TRUE; - - return new_task; -} - /* * Accept new connection and construct task */ @@ -839,7 +656,7 @@ start_worker (struct rspamd_worker *worker) } #endif - close_log (); + close_log (rspamd_main->logger); exit (EXIT_SUCCESS); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4255e7bf0..c6011d2a8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,27 +7,11 @@ SET(TESTSRC rspamd_expression_test.c rspamd_url_test.c rspamd_dns_test.c) -SET(TESTDEPENDS ../src/mem_pool.c - ../src/hash.c - ../src/url.c - ../src/trie.c - ../src/util.c - ../src/radix.c - ../src/fuzzy.c - ../src/map.c - ../src/logger.c - ../src/memcached.c - ../src/message.c - ../src/html.c - ../src/expressions.c - ../src/statfile.c - ../src/events.c - ../src/upstream.c - ../src/dns.c) - -ADD_EXECUTABLE(rspamd-test EXCLUDE_FROM_ALL ${TESTDEPENDS} ${CONTRIBSRC} ${TESTSRC}) +ADD_EXECUTABLE(rspamd-test EXCLUDE_FROM_ALL ${TESTSRC}) SET_TARGET_PROPERTIES(rspamd-test PROPERTIES LINKER_LANGUAGE C) SET_TARGET_PROPERTIES(rspamd-test PROPERTIES COMPILE_FLAGS "-DRSPAMD_TEST") +TARGET_LINK_LIBRARIES(rspamd-test rspamd_lua) +TARGET_LINK_LIBRARIES(rspamd-test rspamdserver) TARGET_LINK_LIBRARIES(rspamd-test event) TARGET_LINK_LIBRARIES(rspamd-test ${GLIB2_LIBRARIES}) TARGET_LINK_LIBRARIES(rspamd-test ${CMAKE_REQUIRED_LIBRARIES}) @@ -38,4 +22,9 @@ ELSE(GMIME2_FOUND) ENDIF(GMIME2_FOUND) IF(ENABLE_STATIC MATCHES "ON") TARGET_LINK_LIBRARIES(rspamd-test ${PCRE_LIBRARIES}) -ENDIF(ENABLE_STATIC MATCHES "ON")
\ No newline at end of file +ENDIF(ENABLE_STATIC MATCHES "ON") +IF(ENABLE_LUAJIT MATCHES "ON") + TARGET_LINK_LIBRARIES(rspamd-test "${LUAJIT_LIBRARY}") +ELSE(ENABLE_LUAJIT MATCHES "ON") + TARGET_LINK_LIBRARIES(rspamd-test "${LUA_LIBRARY}") +ENDIF(ENABLE_LUAJIT MATCHES "ON")
\ No newline at end of file diff --git a/test/rspamd_dns_test.c b/test/rspamd_dns_test.c index 822463948..c0b48080e 100644 --- a/test/rspamd_dns_test.c +++ b/test/rspamd_dns_test.c @@ -3,6 +3,7 @@ #include "tests.h" #include "../src/dns.h" #include "../src/logger.h" +#include "../src/main.h" #include "../src/events.h" #include "../src/cfg_file.h" diff --git a/test/rspamd_test_suite.c b/test/rspamd_test_suite.c index 0d300bc3a..423086506 100644 --- a/test/rspamd_test_suite.c +++ b/test/rspamd_test_suite.c @@ -3,9 +3,8 @@ #include "../src/cfg_file.h" #include "tests.h" -rspamd_hash_t *counters = NULL; - static gboolean do_debug; +struct rspamd_main *rspamd_main = NULL; static GOptionEntry entries[] = { @@ -32,7 +31,11 @@ main (int argc, char **argv) g_test_init (&argc, &argv, NULL); - cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); + rspamd_main = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main)); + memset (rspamd_main, 0, sizeof (struct rspamd_main)); + rspamd_main->server_pool = memory_pool_new (memory_pool_get_size ()); + rspamd_main->cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); + cfg = rspamd_main->cfg; bzero (cfg, sizeof (struct config_file)); cfg->cfg_pool = memory_pool_new (memory_pool_get_size ()); @@ -43,9 +46,9 @@ main (int argc, char **argv) cfg->log_level = G_LOG_LEVEL_INFO; } /* First set logger to console logger */ - rspamd_set_logger (RSPAMD_LOG_CONSOLE, TYPE_MAIN, cfg); - (void)open_log (); - g_log_set_default_handler (rspamd_glib_log_function, cfg); + rspamd_set_logger (RSPAMD_LOG_CONSOLE, TYPE_MAIN, rspamd_main); + (void)open_log (rspamd_main->logger); + g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger); g_test_add_func ("/rspamd/memcached", rspamd_memcached_test_func); g_test_add_func ("/rspamd/mem_pool", rspamd_mem_pool_test_func); diff --git a/utils/statshow/CMakeLists.txt b/utils/statshow/CMakeLists.txt index 12de6038e..2e28d019e 100644 --- a/utils/statshow/CMakeLists.txt +++ b/utils/statshow/CMakeLists.txt @@ -1,9 +1,21 @@ SET(STATSHOWSRC statshow.c) -ADD_EXECUTABLE(statshow EXCLUDE_FROM_ALL ${CLASSIFIERSSRC} ${TOKENIZERSSRC} ${STATSHOWSRC}) +FOREACH(_rs ${CLASSIFIERSSRC} ${TOKENIZERSSRC}) + LIST(APPEND STATSHOWSRC "../../${_rs}") + MESSAGE("${_rs}") +ENDFOREACH(_rs) + +ADD_EXECUTABLE(statshow EXCLUDE_FROM_ALL ${STATSHOWSRC}) SET_TARGET_PROPERTIES(statshow PROPERTIES LINKER_LANGUAGE C) -SET_TARGET_PROPERTIES(statshow PROPERTIES COMPILE_FLAGS "-I../../src") +SET_TARGET_PROPERTIES(statshow PROPERTIES COMPILE_FLAGS "-I../../src -DRSPAMD_MAIN") +TARGET_LINK_LIBRARIES(statshow rspamd_lua) +TARGET_LINK_LIBRARIES(statshow rspamdserver) TARGET_LINK_LIBRARIES(statshow event) +IF(ENABLE_LUAJIT MATCHES "ON") + TARGET_LINK_LIBRARIES(statshow "${LUAJIT_LIBRARY}") +ELSE(ENABLE_LUAJIT MATCHES "ON") + TARGET_LINK_LIBRARIES(statshow "${LUA_LIBRARY}") +ENDIF(ENABLE_LUAJIT MATCHES "ON") TARGET_LINK_LIBRARIES(statshow ${GLIB2_LIBRARIES}) TARGET_LINK_LIBRARIES(statshow ${CMAKE_REQUIRED_LIBRARIES}) IF(GMIME2_FOUND) @@ -11,12 +23,6 @@ IF(GMIME2_FOUND) ELSE(GMIME2_FOUND) TARGET_LINK_LIBRARIES(statshow ${GMIME24_LIBRARIES}) ENDIF(GMIME2_FOUND) -TARGET_LINK_LIBRARIES(statshow rspamd_lua) -IF(ENABLE_LUAJIT MATCHES "ON") - TARGET_LINK_LIBRARIES(statshow "${LUAJIT_LIBRARY}") -ELSE(ENABLE_LUAJIT MATCHES "ON") - TARGET_LINK_LIBRARIES(statshow "${LUA_LIBRARY}") -ENDIF(ENABLE_LUAJIT MATCHES "ON") IF(ENABLE_STATIC MATCHES "ON") TARGET_LINK_LIBRARIES(statshow ${PCRE_LIBRARIES}) ENDIF(ENABLE_STATIC MATCHES "ON")
\ No newline at end of file diff --git a/utils/statshow/statshow.c b/utils/statshow/statshow.c index 7dc040a37..a2e8dce68 100644 --- a/utils/statshow/statshow.c +++ b/utils/statshow/statshow.c @@ -30,9 +30,12 @@ #include "classifiers/classifiers.h" #include "tokenizers/tokenizers.h" #include "message.h" +#include "lua/lua_common.h" - +module_t modules[] = { {NULL, NULL, NULL, NULL} }; +struct rspamd_main *rspamd_main = NULL; static gchar *cfg_name; +extern rspamd_hash_t *counters; static GOptionEntry entries[] = { @@ -84,13 +87,14 @@ classifiers_callback (gpointer value, void *arg) ctx = cl->classifier->init_func (task->task_pool, cl); ctx->debug = TRUE; + cur = g_list_first (task->text_parts); if ((tokens = g_hash_table_lookup (task->tokens, cl->tokenizer)) == NULL) { while (cur != NULL) { if (header) { c.len = strlen (cur->data); if (c.len > 0) { c.begin = cur->data; - if (!cl->tokenizer->tokenize_func (cl->tokenizer, task->task_pool, &c, &tokens, FALSE)) { + if (!cl->tokenizer->tokenize_func (cl->tokenizer, task->task_pool, &c, &tokens, TRUE)) { msg_info ("cannot tokenize input"); return; } @@ -105,7 +109,7 @@ classifiers_callback (gpointer value, void *arg) c.begin = text_part->content->data; c.len = text_part->content->len; /* Tree would be freed at task pool freeing */ - if (!cl->tokenizer->tokenize_func (cl->tokenizer, task->task_pool, &c, &tokens, FALSE)) { + if (!cl->tokenizer->tokenize_func (cl->tokenizer, task->task_pool, &c, &tokens, TRUE)) { msg_info ("cannot tokenize input"); return; } @@ -207,55 +211,59 @@ process_file (const gchar *filename, struct rspamd_main *rspamd) gint main (gint argc, gchar **argv, gchar **env) { - struct config_file *cfg; - struct rspamd_main *rspamd; gchar **arg; - rspamd = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main)); - bzero (rspamd, sizeof (struct rspamd_main)); - rspamd->server_pool = memory_pool_new (memory_pool_get_size ()); - rspamd->cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); - if (!rspamd || !rspamd->cfg) { + rspamd_main = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main)); + memset (rspamd_main, 0, sizeof (struct rspamd_main)); + rspamd_main->server_pool = memory_pool_new (memory_pool_get_size ()); + rspamd_main->cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); + if (!rspamd_main || !rspamd_main->cfg) { fprintf (stderr, "Cannot allocate memory\n"); exit (-errno); } + rspamd_main->cfg->modules_num = 0; - bzero (rspamd->cfg, sizeof (struct config_file)); - rspamd->cfg->cfg_pool = memory_pool_new (memory_pool_get_size ()); - init_defaults (rspamd->cfg); + memset (rspamd_main->cfg, 0, sizeof (struct config_file)); + rspamd_main->cfg->cfg_pool = memory_pool_new (memory_pool_get_size ()); + init_defaults (rspamd_main->cfg); - read_cmd_line (&argc, &argv, rspamd->cfg); - if (rspamd->cfg->cfg_name == NULL) { - rspamd->cfg->cfg_name = FIXED_CONFIG_FILE; + read_cmd_line (&argc, &argv, rspamd_main->cfg); + if (rspamd_main->cfg->cfg_name == NULL) { + rspamd_main->cfg->cfg_name = FIXED_CONFIG_FILE; } /* First set logger to console logger */ - rspamd_set_logger (RSPAMD_LOG_CONSOLE, TYPE_MAIN, rspamd->cfg); - (void)open_log (); - g_log_set_default_handler (rspamd_glib_log_function, rspamd->cfg); + rspamd_set_logger (RSPAMD_LOG_CONSOLE, TYPE_MAIN, rspamd_main); + (void)open_log (rspamd_main->logger); + g_log_set_default_handler (rspamd_glib_log_function, rspamd_main); + init_lua (rspamd_main->cfg); + /* Init counters */ + counters = rspamd_hash_new_shared (rspamd_main->server_pool, g_str_hash, g_str_equal, 64); /* Init classifiers options */ register_classifier_opt ("bayes", "min_tokens"); register_classifier_opt ("winnow", "min_tokens"); register_classifier_opt ("winnow", "learn_threshold"); /* Load config */ - if (! load_rspamd_config (rspamd->cfg)) { + if (! load_rspamd_config (rspamd_main->cfg)) { exit (EXIT_FAILURE); } /* Init statfile pool */ - rspamd->statfile_pool = statfile_pool_new (rspamd->server_pool, rspamd->cfg->max_statfile_size); + rspamd_main->statfile_pool = statfile_pool_new (rspamd_main->server_pool, rspamd_main->cfg->max_statfile_size); + g_mime_init (0); + rspamd_main->cfg->log_extended = FALSE; /* Check argc */ if (argc > 1) { - arg = argv[1]; + arg = &argv[1]; while (*arg) { - process_file (*arg, rspamd); + process_file (*arg, rspamd_main); arg ++; } } else { - process_stdin (rspamd); + process_stdin (rspamd_main); } return 0; |