summaryrefslogtreecommitdiffstats
path: root/src/libmime
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2014-07-23 12:45:28 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2014-07-23 12:45:28 +0100
commite0483657ff6cf1adc828ccce457814d61fe90a0d (patch)
tree5183e4163f40b81b3e7d5f51488d360883782154 /src/libmime
parent7962087e808fb824aa3af6d41d02abc92916ba1e (diff)
downloadrspamd-e0483657ff6cf1adc828ccce457814d61fe90a0d.tar.gz
rspamd-e0483657ff6cf1adc828ccce457814d61fe90a0d.zip
Unify code style.
Diffstat (limited to 'src/libmime')
-rw-r--r--src/libmime/expressions.c553
-rw-r--r--src/libmime/expressions.h53
-rw-r--r--src/libmime/filter.c529
-rw-r--r--src/libmime/filter.h68
-rw-r--r--src/libmime/images.c56
-rw-r--r--src/libmime/images.h2
-rw-r--r--src/libmime/message.c918
-rw-r--r--src/libmime/message.h17
-rw-r--r--src/libmime/smtp_proto.c799
-rw-r--r--src/libmime/smtp_proto.h24
-rw-r--r--src/libmime/smtp_utils.c220
-rw-r--r--src/libmime/smtp_utils.h5
12 files changed, 1986 insertions, 1258 deletions
diff --git a/src/libmime/expressions.c b/src/libmime/expressions.c
index 5d19626bb..c17388315 100644
--- a/src/libmime/expressions.c
+++ b/src/libmime/expressions.c
@@ -22,36 +22,56 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "util.h"
#include "cfg_file.h"
-#include "main.h"
-#include "message.h"
-#include "fuzzy.h"
+#include "config.h"
+#include "diff.h"
#include "expressions.h"
+#include "fuzzy.h"
#include "html.h"
#include "lua/lua_common.h"
-#include "diff.h"
+#include "main.h"
+#include "message.h"
+#include "util.h"
-gboolean rspamd_compare_encoding (struct rspamd_task *task, GList * args, void *unused);
-gboolean rspamd_header_exists (struct rspamd_task *task, GList * args, void *unused);
-gboolean rspamd_parts_distance (struct rspamd_task *task, GList * args, void *unused);
-gboolean rspamd_recipients_distance (struct rspamd_task *task, GList * args, void *unused);
-gboolean rspamd_has_only_html_part (struct rspamd_task *task, GList * args, void *unused);
-gboolean rspamd_is_recipients_sorted (struct rspamd_task *task, GList * args, void *unused);
-gboolean rspamd_compare_transfer_encoding (struct rspamd_task *task, GList * args, void *unused);
-gboolean rspamd_is_html_balanced (struct rspamd_task *task, GList * args, void *unused);
-gboolean rspamd_has_html_tag (struct rspamd_task *task, GList * args, void *unused);
-gboolean rspamd_has_fake_html (struct rspamd_task *task, GList * args, void *unused);
+gboolean rspamd_compare_encoding (struct rspamd_task *task,
+ GList * args,
+ void *unused);
+gboolean rspamd_header_exists (struct rspamd_task *task,
+ GList * args,
+ void *unused);
+gboolean rspamd_parts_distance (struct rspamd_task *task,
+ GList * args,
+ void *unused);
+gboolean rspamd_recipients_distance (struct rspamd_task *task,
+ GList * args,
+ void *unused);
+gboolean rspamd_has_only_html_part (struct rspamd_task *task,
+ GList * args,
+ void *unused);
+gboolean rspamd_is_recipients_sorted (struct rspamd_task *task,
+ GList * args,
+ void *unused);
+gboolean rspamd_compare_transfer_encoding (struct rspamd_task *task,
+ GList * args,
+ void *unused);
+gboolean rspamd_is_html_balanced (struct rspamd_task *task,
+ GList * args,
+ void *unused);
+gboolean rspamd_has_html_tag (struct rspamd_task *task,
+ GList * args,
+ void *unused);
+gboolean rspamd_has_fake_html (struct rspamd_task *task,
+ GList * args,
+ void *unused);
/*
* List of internal functions of rspamd
* Sorted by name to use bsearch
*/
static struct _fl {
- const gchar *name;
- rspamd_internal_func_t func;
- void *user_data;
+ const gchar *name;
+ rspamd_internal_func_t func;
+ void *user_data;
} rspamd_functions_list[] = {
{"compare_encoding", rspamd_compare_encoding, NULL},
{"compare_parts_distance", rspamd_parts_distance, NULL},
@@ -65,30 +85,32 @@ static struct _fl {
{"is_recipients_sorted", rspamd_is_recipients_sorted, NULL}
};
-static struct _fl *list_ptr = &rspamd_functions_list[0];
-static guint32 functions_number = sizeof (rspamd_functions_list) / sizeof (struct _fl);
-static gboolean list_allocated = FALSE;
+static struct _fl *list_ptr = &rspamd_functions_list[0];
+static guint32 functions_number = sizeof (rspamd_functions_list) /
+ sizeof (struct _fl);
+static gboolean list_allocated = FALSE;
/* Bsearch routine */
static gint
fl_cmp (const void *s1, const void *s2)
{
- struct _fl *fl1 = (struct _fl *)s1;
- struct _fl *fl2 = (struct _fl *)s2;
+ struct _fl *fl1 = (struct _fl *)s1;
+ struct _fl *fl2 = (struct _fl *)s2;
return strcmp (fl1->name, fl2->name);
}
/* Cache for regular expressions that are used in functions */
-void *
+void *
re_cache_check (const gchar *line, rspamd_mempool_t *pool)
{
- GHashTable *re_cache;
-
+ GHashTable *re_cache;
+
re_cache = rspamd_mempool_get_variable (pool, "re_cache");
if (re_cache == NULL) {
re_cache = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- rspamd_mempool_set_variable (pool, "re_cache", re_cache, (rspamd_mempool_destruct_t)g_hash_table_destroy);
+ rspamd_mempool_set_variable (pool, "re_cache", re_cache,
+ (rspamd_mempool_destruct_t)g_hash_table_destroy);
return NULL;
}
return g_hash_table_lookup (re_cache, line);
@@ -97,13 +119,14 @@ re_cache_check (const gchar *line, rspamd_mempool_t *pool)
void
re_cache_add (const gchar *line, void *pointer, rspamd_mempool_t *pool)
{
- GHashTable *re_cache;
-
+ GHashTable *re_cache;
+
re_cache = rspamd_mempool_get_variable (pool, "re_cache");
if (re_cache == NULL) {
re_cache = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- rspamd_mempool_set_variable (pool, "re_cache", re_cache, (rspamd_mempool_destruct_t)g_hash_table_destroy);
+ rspamd_mempool_set_variable (pool, "re_cache", re_cache,
+ (rspamd_mempool_destruct_t)g_hash_table_destroy);
}
g_hash_table_insert (re_cache, (gpointer)line, pointer);
@@ -112,7 +135,7 @@ re_cache_add (const gchar *line, void *pointer, rspamd_mempool_t *pool)
void
re_cache_del (const gchar *line, rspamd_mempool_t *pool)
{
- GHashTable *re_cache;
+ GHashTable *re_cache;
re_cache = rspamd_mempool_get_variable (pool, "re_cache");
@@ -126,17 +149,19 @@ re_cache_del (const gchar *line, rspamd_mempool_t *pool)
* Functions for parsing expressions
*/
struct expression_stack {
- gchar op;
- struct expression_stack *next;
+ gchar op;
+ struct expression_stack *next;
};
/*
- * Push operand or operator to stack
+ * Push operand or operator to stack
*/
static struct expression_stack *
-push_expression_stack (rspamd_mempool_t * pool, struct expression_stack *head, gchar op)
+push_expression_stack (rspamd_mempool_t * pool,
+ struct expression_stack *head,
+ gchar op)
{
- struct expression_stack *new;
+ struct expression_stack *new;
new = rspamd_mempool_alloc (pool, sizeof (struct expression_stack));
new->op = op;
new->next = head;
@@ -149,8 +174,8 @@ push_expression_stack (rspamd_mempool_t * pool, struct expression_stack *head, g
static gchar
delete_expression_stack (struct expression_stack **head)
{
- struct expression_stack *cur;
- gchar res;
+ struct expression_stack *cur;
+ gchar res;
if (*head == NULL)
return 0;
@@ -185,7 +210,7 @@ logic_priority (gchar a)
* Return FALSE if symbol is not operation symbol (operand)
* Return TRUE if symbol is operation symbol
*/
-static gboolean
+static gboolean
is_operation_symbol (gchar *a)
{
switch (*a) {
@@ -197,19 +222,22 @@ is_operation_symbol (gchar *a)
return TRUE;
case 'O':
case 'o':
- if (g_ascii_strncasecmp (a, "or", sizeof ("or") - 1) == 0&& g_ascii_isspace (a[2])) {
+ if (g_ascii_strncasecmp (a, "or",
+ sizeof ("or") - 1) == 0 && g_ascii_isspace (a[2])) {
return TRUE;
}
break;
case 'A':
case 'a':
- if (g_ascii_strncasecmp (a, "and", sizeof ("and") - 1) == 0&& g_ascii_isspace (a[3])) {
+ if (g_ascii_strncasecmp (a, "and",
+ sizeof ("and") - 1) == 0 && g_ascii_isspace (a[3])) {
return TRUE;
}
break;
case 'N':
case 'n':
- if (g_ascii_strncasecmp (a, "not", sizeof ("not") - 1) == 0 && g_ascii_isspace (a[3])) {
+ if (g_ascii_strncasecmp (a, "not",
+ sizeof ("not") - 1) == 0 && g_ascii_isspace (a[3])) {
return TRUE;
}
break;
@@ -259,7 +287,7 @@ op_to_char (gchar *a, gchar **next)
/*
* Return TRUE if symbol can be regexp flag
*/
-static gboolean
+static gboolean
is_regexp_flag (gchar a)
{
switch (a) {
@@ -284,9 +312,14 @@ is_regexp_flag (gchar a)
}
static void
-insert_expression (rspamd_mempool_t * pool, struct expression **head, gint type, gchar op, void *operand, const gchar *orig)
+insert_expression (rspamd_mempool_t * pool,
+ struct expression **head,
+ gint type,
+ gchar op,
+ void *operand,
+ const gchar *orig)
{
- struct expression *new, *cur;
+ struct expression *new, *cur;
new = rspamd_mempool_alloc (pool, sizeof (struct expression));
new->type = type;
@@ -311,11 +344,11 @@ insert_expression (rspamd_mempool_t * pool, struct expression **head, gint type,
}
}
-static struct expression *
+static struct expression *
maybe_parse_expression (rspamd_mempool_t * pool, gchar *line)
{
- struct expression *expr;
- gchar *p = line;
+ struct expression *expr;
+ gchar *p = line;
while (*p) {
if (is_operation_symbol (p)) {
@@ -336,17 +369,17 @@ maybe_parse_expression (rspamd_mempool_t * pool, gchar *line)
* Make inverse polish record for specified expression
* Memory is allocated from given pool
*/
-struct expression *
+struct expression *
parse_expression (rspamd_mempool_t * pool, gchar *line)
{
- struct expression *expr = NULL;
- struct expression_stack *stack = NULL;
- struct expression_function *func = NULL;
- struct expression *arg;
- GQueue *function_stack;
- gchar *p, *c, *str, op, newop, *copy, *next;
- gboolean in_regexp = FALSE;
- gint brackets = 0;
+ struct expression *expr = NULL;
+ struct expression_stack *stack = NULL;
+ struct expression_function *func = NULL;
+ struct expression *arg;
+ GQueue *function_stack;
+ gchar *p, *c, *str, op, newop, *copy, *next;
+ gboolean in_regexp = FALSE;
+ gint brackets = 0;
enum {
SKIP_SPACES,
@@ -396,7 +429,12 @@ parse_expression (rspamd_mempool_t * pool, gchar *line)
while (stack && stack->op != '(') {
op = delete_expression_stack (&stack);
if (op != '(') {
- insert_expression (pool, &expr, EXPR_OPERATION, op, NULL, copy);
+ insert_expression (pool,
+ &expr,
+ EXPR_OPERATION,
+ op,
+ NULL,
+ copy);
}
}
if (stack) {
@@ -421,15 +459,23 @@ parse_expression (rspamd_mempool_t * pool, gchar *line)
else {
newop = op_to_char (p, &next);
if (newop != '\0') {
- if (logic_priority (stack->op) < logic_priority (newop)) {
+ if (logic_priority (stack->op) <
+ logic_priority (newop)) {
stack = push_expression_stack (pool, stack, newop);
}
else {
/* Pop all operations that have higher priority than this one */
- while ((stack != NULL) && (logic_priority (stack->op) >= logic_priority (newop))) {
+ while ((stack != NULL) &&
+ (logic_priority (stack->op) >=
+ logic_priority (newop))) {
op = delete_expression_stack (&stack);
if (op != '(') {
- insert_expression (pool, &expr, EXPR_OPERATION, op, NULL, copy);
+ insert_expression (pool,
+ &expr,
+ EXPR_OPERATION,
+ op,
+ NULL,
+ copy);
}
}
stack = push_expression_stack (pool, stack, newop);
@@ -459,7 +505,8 @@ parse_expression (rspamd_mempool_t * pool, gchar *line)
case READ_REGEXP_FLAGS:
if (!is_regexp_flag (*p) || *(p + 1) == '\0') {
if (c != p) {
- if ((is_regexp_flag (*p) || *p == '/') && *(p + 1) == '\0') {
+ if ((is_regexp_flag (*p) || *p ==
+ '/') && *(p + 1) == '\0') {
p++;
}
str = rspamd_mempool_alloc (pool, p - c + 2);
@@ -467,7 +514,12 @@ parse_expression (rspamd_mempool_t * pool, gchar *line)
g_strstrip (str);
msg_debug ("found regexp: %s", str);
if (strlen (str) > 0) {
- insert_expression (pool, &expr, EXPR_REGEXP, 0, str, copy);
+ insert_expression (pool,
+ &expr,
+ EXPR_REGEXP,
+ 0,
+ str,
+ copy);
}
}
c = p;
@@ -486,7 +538,9 @@ parse_expression (rspamd_mempool_t * pool, gchar *line)
p++;
}
else if (*p == '(') {
- func = rspamd_mempool_alloc (pool, sizeof (struct expression_function));
+ func =
+ rspamd_mempool_alloc (pool,
+ sizeof (struct expression_function));
func->name = rspamd_mempool_alloc (pool, p - c + 1);
func->args = NULL;
rspamd_strlcpy (func->name, c, (p - c + 1));
@@ -586,14 +640,14 @@ parse_expression (rspamd_mempool_t * pool, gchar *line)
/*
* Rspamd regexp utility functions
*/
-struct rspamd_regexp *
+struct rspamd_regexp *
parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode)
{
- const gchar *begin, *end, *p, *src, *start;
- gchar *dbegin, *dend;
- struct rspamd_regexp *result, *check;
- gint regexp_flags = G_REGEX_OPTIMIZE | G_REGEX_NO_AUTO_CAPTURE;
- GError *err = NULL;
+ const gchar *begin, *end, *p, *src, *start;
+ gchar *dbegin, *dend;
+ struct rspamd_regexp *result, *check;
+ gint regexp_flags = G_REGEX_OPTIMIZE | G_REGEX_NO_AUTO_CAPTURE;
+ GError *err = NULL;
if (line == NULL) {
msg_err ("cannot parse NULL line");
@@ -621,7 +675,7 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode)
end = p;
break;
}
- p --;
+ p--;
}
if (end) {
result->header = rspamd_mempool_alloc (pool, end - line + 1);
@@ -650,7 +704,9 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode)
}
else {
/* We got header name earlier but have not found // expression, so it is invalid regexp */
- msg_warn ("got no header name (eg. header=) but without corresponding regexp, %s", src);
+ msg_warn (
+ "got no header name (eg. header=) but without corresponding regexp, %s",
+ src);
return NULL;
}
/* Find end */
@@ -695,7 +751,7 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode)
result->is_raw = TRUE;
p++;
break;
- /* Type flags */
+ /* Type flags */
case 'H':
if (result->type == REGEXP_NONE) {
result->type = REGEXP_HEADER;
@@ -728,13 +784,13 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode)
break;
case 'T':
result->is_test = TRUE;
- p ++;
+ p++;
break;
case 'S':
result->is_strong = TRUE;
- p ++;
+ p++;
break;
- /* Stop flags parsing */
+ /* Stop flags parsing */
default:
p = NULL;
break;
@@ -751,9 +807,12 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode)
}
/* Avoid multiply regexp structures for similar regexps */
- if ((check = (struct rspamd_regexp *)re_cache_check (result->regexp_text, pool)) != NULL) {
+ if ((check =
+ (struct rspamd_regexp *)re_cache_check (result->regexp_text,
+ pool)) != NULL) {
/* Additional check for headers */
- if (result->type == REGEXP_HEADER || result->type == REGEXP_RAW_HEADER) {
+ if (result->type == REGEXP_HEADER || result->type ==
+ REGEXP_RAW_HEADER) {
if (result->header && check->header) {
if (strcmp (result->header, check->header) == 0) {
return check;
@@ -769,20 +828,31 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode)
result->raw_regexp = result->regexp;
}
else {
- result->raw_regexp = g_regex_new (dbegin, regexp_flags | G_REGEX_RAW, 0, &err);
- rspamd_mempool_add_destructor (pool, (rspamd_mempool_destruct_t) g_regex_unref, (void *)result->raw_regexp);
- }
- rspamd_mempool_add_destructor (pool, (rspamd_mempool_destruct_t) g_regex_unref, (void *)result->regexp);
+ result->raw_regexp = g_regex_new (dbegin,
+ regexp_flags | G_REGEX_RAW,
+ 0,
+ &err);
+ rspamd_mempool_add_destructor (pool,
+ (rspamd_mempool_destruct_t) g_regex_unref,
+ (void *)result->raw_regexp);
+ }
+ rspamd_mempool_add_destructor (pool,
+ (rspamd_mempool_destruct_t) g_regex_unref,
+ (void *)result->regexp);
*dend = '/';
if (result->regexp == NULL || err != NULL) {
- msg_warn ("could not read regexp: %s while reading regexp %s", err->message, src);
+ msg_warn ("could not read regexp: %s while reading regexp %s",
+ err->message,
+ src);
return NULL;
}
if (result->raw_regexp == NULL || err != NULL) {
- msg_warn ("could not read raw regexp: %s while reading regexp %s", err->message, src);
+ msg_warn ("could not read raw regexp: %s while reading regexp %s",
+ err->message,
+ src);
return NULL;
}
@@ -792,13 +862,19 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode)
}
gboolean
-call_expression_function (struct expression_function * func, struct rspamd_task * task, lua_State *L)
+call_expression_function (struct expression_function * func,
+ struct rspamd_task * task,
+ lua_State *L)
{
- struct _fl *selected, key;
+ struct _fl *selected, key;
key.name = func->name;
- selected = bsearch (&key, list_ptr, functions_number, sizeof (struct _fl), fl_cmp);
+ selected = bsearch (&key,
+ list_ptr,
+ functions_number,
+ sizeof (struct _fl),
+ fl_cmp);
if (selected == NULL) {
/* Try to check lua function */
return FALSE;
@@ -807,21 +883,26 @@ call_expression_function (struct expression_function * func, struct rspamd_task
return selected->func (task, func->args, selected->user_data);
}
-struct expression_argument *
-get_function_arg (struct expression *expr, struct rspamd_task *task, gboolean want_string)
+struct expression_argument *
+get_function_arg (struct expression *expr,
+ struct rspamd_task *task,
+ gboolean want_string)
{
- GQueue *stack;
- gsize cur, op1, op2;
- struct expression_argument *res;
- struct expression *it;
+ GQueue *stack;
+ gsize cur, op1, op2;
+ struct expression_argument *res;
+ struct expression *it;
if (expr == NULL) {
msg_warn ("NULL expression passed");
return NULL;
}
if (expr->next == NULL) {
- res = rspamd_mempool_alloc (task->task_pool, sizeof (struct expression_argument));
- if (expr->type == EXPR_REGEXP || expr->type == EXPR_STR || expr->type == EXPR_REGEXP_PARSED) {
+ res =
+ rspamd_mempool_alloc (task->task_pool,
+ sizeof (struct expression_argument));
+ if (expr->type == EXPR_REGEXP || expr->type == EXPR_STR || expr->type ==
+ EXPR_REGEXP_PARSED) {
res->type = EXPRESSION_ARGUMENT_NORMAL;
res->data = expr->content.operand;
}
@@ -831,27 +912,36 @@ get_function_arg (struct expression *expr, struct rspamd_task *task, gboolean wa
res->data = GSIZE_TO_POINTER (cur);
}
else {
- msg_warn ("cannot parse argument: it contains operator or bool expression that is not wanted");
+ msg_warn (
+ "cannot parse argument: it contains operator or bool expression that is not wanted");
return NULL;
}
return res;
}
else if (!want_string) {
- res = rspamd_mempool_alloc (task->task_pool, sizeof (struct expression_argument));
+ res =
+ rspamd_mempool_alloc (task->task_pool,
+ sizeof (struct expression_argument));
res->type = EXPRESSION_ARGUMENT_BOOL;
stack = g_queue_new ();
it = expr;
while (it) {
- if (it->type == EXPR_REGEXP || it->type == EXPR_REGEXP_PARSED || it->type == EXPR_STR) {
+ if (it->type == EXPR_REGEXP || it->type == EXPR_REGEXP_PARSED ||
+ it->type == EXPR_STR) {
g_queue_free (stack);
res->type = EXPRESSION_ARGUMENT_EXPR;
res->data = expr;
return res;
}
else if (it->type == EXPR_FUNCTION) {
- cur = (gsize) call_expression_function ((struct expression_function *)it->content.operand, task, NULL);
- debug_task ("function %s returned %s", ((struct expression_function *)it->content.operand)->name, cur ? "true" : "false");
+ cur =
+ (gsize) call_expression_function ((struct
+ expression_function
+ *)it->content.operand, task, NULL);
+ debug_task ("function %s returned %s",
+ ((struct expression_function *)it->content.operand)->name,
+ cur ? "true" : "false");
}
else if (it->type == EXPR_OPERATION) {
if (g_queue_is_empty (stack)) {
@@ -901,9 +991,11 @@ get_function_arg (struct expression *expr, struct rspamd_task *task, gboolean wa
}
void
-register_expression_function (const gchar *name, rspamd_internal_func_t func, void *user_data)
+register_expression_function (const gchar *name,
+ rspamd_internal_func_t func,
+ void *user_data)
{
- static struct _fl *new;
+ static struct _fl *new;
functions_number++;
@@ -924,7 +1016,7 @@ register_expression_function (const gchar *name, rspamd_internal_func_t func, vo
gboolean
rspamd_compare_encoding (struct rspamd_task *task, GList * args, void *unused)
{
- struct expression_argument *arg;
+ struct expression_argument *arg;
if (args == NULL || task == NULL) {
return FALSE;
@@ -943,8 +1035,8 @@ rspamd_compare_encoding (struct rspamd_task *task, GList * args, void *unused)
gboolean
rspamd_header_exists (struct rspamd_task * task, GList * args, void *unused)
{
- struct expression_argument *arg;
- GList *headerlist;
+ struct expression_argument *arg;
+ GList *headerlist;
if (args == NULL || task == NULL) {
return FALSE;
@@ -957,7 +1049,10 @@ rspamd_header_exists (struct rspamd_task * task, GList * args, void *unused)
}
debug_task ("try to get header %s", (gchar *)arg->data);
- headerlist = message_get_header (task->task_pool, task->message, (gchar *)arg->data, FALSE);
+ headerlist = message_get_header (task->task_pool,
+ task->message,
+ (gchar *)arg->data,
+ FALSE);
if (headerlist) {
g_list_free (headerlist);
return TRUE;
@@ -967,20 +1062,20 @@ rspamd_header_exists (struct rspamd_task * task, GList * args, void *unused)
/*
* This function is designed to find difference between text/html and text/plain parts
- * It takes one argument: difference threshold, if we have two text parts, compare
+ * It takes one argument: difference threshold, if we have two text parts, compare
* its hashes and check for threshold, if value is greater than threshold, return TRUE
* and return FALSE otherwise.
*/
gboolean
rspamd_parts_distance (struct rspamd_task * task, GList * args, void *unused)
{
- gint threshold, threshold2 = -1, diff;
- struct mime_text_part *p1, *p2;
- GList *cur;
- struct expression_argument *arg;
- GMimeObject *parent;
- const GMimeContentType *ct;
- gint *pdiff;
+ gint threshold, threshold2 = -1, diff;
+ struct mime_text_part *p1, *p2;
+ GList *cur;
+ struct expression_argument *arg;
+ GMimeObject *parent;
+ const GMimeContentType *ct;
+ gint *pdiff;
if (args == NULL) {
debug_task ("no threshold is specified, assume it 100");
@@ -991,7 +1086,8 @@ rspamd_parts_distance (struct rspamd_task * task, GList * args, void *unused)
arg = get_function_arg (args->data, task, TRUE);
threshold = strtoul ((gchar *)arg->data, NULL, 10);
if (errno != 0) {
- msg_info ("bad numeric value for threshold \"%s\", assume it 100", (gchar *)args->data);
+ msg_info ("bad numeric value for threshold \"%s\", assume it 100",
+ (gchar *)args->data);
threshold = 100;
}
if (args->next) {
@@ -999,17 +1095,22 @@ rspamd_parts_distance (struct rspamd_task * task, GList * args, void *unused)
errno = 0;
threshold2 = strtoul ((gchar *)arg->data, NULL, 10);
if (errno != 0) {
- msg_info ("bad numeric value for threshold \"%s\", ignore it", (gchar *)arg->data);
+ msg_info ("bad numeric value for threshold \"%s\", ignore it",
+ (gchar *)arg->data);
threshold2 = -1;
}
}
}
- if ((pdiff = rspamd_mempool_get_variable (task->task_pool, "parts_distance")) != NULL) {
+ if ((pdiff =
+ rspamd_mempool_get_variable (task->task_pool,
+ "parts_distance")) != NULL) {
diff = *pdiff;
if (diff != -1) {
if (threshold2 > 0) {
- if (diff >= MIN (threshold, threshold2) && diff < MAX (threshold, threshold2)) {
+ if (diff >=
+ MIN (threshold,
+ threshold2) && diff < MAX (threshold, threshold2)) {
return TRUE;
}
}
@@ -1042,32 +1143,52 @@ rspamd_parts_distance (struct rspamd_task * task, GList * args, void *unused)
parent = p1->parent;
ct = g_mime_object_get_content_type (parent);
#ifndef GMIME24
- if (ct == NULL || ! g_mime_content_type_is_type (ct, "multipart", "alternative")) {
+ if (ct == NULL ||
+ !g_mime_content_type_is_type (ct, "multipart", "alternative")) {
#else
- if (ct == NULL || ! g_mime_content_type_is_type ((GMimeContentType *)ct, "multipart", "alternative")) {
+ if (ct == NULL ||
+ !g_mime_content_type_is_type ((GMimeContentType *)ct,
+ "multipart", "alternative")) {
#endif
- debug_task ("two parts are not belong to multipart/alternative container, skip check");
- rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL);
+ debug_task (
+ "two parts are not belong to multipart/alternative container, skip check");
+ rspamd_mempool_set_variable (task->task_pool,
+ "parts_distance",
+ pdiff,
+ NULL);
return FALSE;
}
}
else {
- debug_task ("message contains two parts but they are in different multi-parts");
- rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL);
+ debug_task (
+ "message contains two parts but they are in different multi-parts");
+ rspamd_mempool_set_variable (task->task_pool,
+ "parts_distance",
+ pdiff,
+ NULL);
return FALSE;
}
if (!p1->is_empty && !p2->is_empty) {
if (p1->diff_str != NULL && p2->diff_str != NULL) {
- diff = compare_diff_distance_normalized (p1->diff_str, p2->diff_str);
+ diff = compare_diff_distance_normalized (p1->diff_str,
+ p2->diff_str);
}
else {
diff = fuzzy_compare_parts (p1, p2);
}
- debug_task ("got likeliness between parts of %d%%, threshold is %d%%", diff, threshold);
+ debug_task (
+ "got likeliness between parts of %d%%, threshold is %d%%",
+ diff,
+ threshold);
*pdiff = diff;
- rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL);
+ rspamd_mempool_set_variable (task->task_pool,
+ "parts_distance",
+ pdiff,
+ NULL);
if (threshold2 > 0) {
- if (diff >= MIN (threshold, threshold2) && diff < MAX (threshold, threshold2)) {
+ if (diff >=
+ MIN (threshold,
+ threshold2) && diff < MAX (threshold, threshold2)) {
return TRUE;
}
}
@@ -1077,41 +1198,51 @@ rspamd_parts_distance (struct rspamd_task * task, GList * args, void *unused)
}
}
}
- else if ((p1->is_empty && !p2->is_empty) || (!p1->is_empty && p2->is_empty)) {
+ else if ((p1->is_empty &&
+ !p2->is_empty) || (!p1->is_empty && p2->is_empty)) {
/* Empty and non empty parts are different */
*pdiff = 0;
- rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL);
+ rspamd_mempool_set_variable (task->task_pool,
+ "parts_distance",
+ pdiff,
+ NULL);
return TRUE;
}
}
else {
- debug_task ("message has too many text parts, so do not try to compare them with each other");
- rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL);
+ debug_task (
+ "message has too many text parts, so do not try to compare them with each other");
+ rspamd_mempool_set_variable (task->task_pool,
+ "parts_distance",
+ pdiff,
+ NULL);
return FALSE;
}
- rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL);
+ rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff,
+ NULL);
return FALSE;
}
struct addr_list {
- const gchar *name;
- const gchar *addr;
+ const gchar *name;
+ const gchar *addr;
};
#define COMPARE_RCPT_LEN 3
#define MIN_RCPT_TO_COMPARE 7
gboolean
-rspamd_recipients_distance (struct rspamd_task *task, GList * args, void *unused)
+rspamd_recipients_distance (struct rspamd_task *task, GList * args,
+ void *unused)
{
- struct expression_argument *arg;
- InternetAddressList *cur;
- InternetAddress *addr;
- double threshold;
- struct addr_list *ar;
- gchar *c;
- gint num, i, j, hits = 0, total = 0;
+ struct expression_argument *arg;
+ InternetAddressList *cur;
+ InternetAddress *addr;
+ double threshold;
+ struct addr_list *ar;
+ gchar *c;
+ gint num, i, j, hits = 0, total = 0;
if (args == NULL) {
msg_warn ("no parameters to function");
@@ -1122,7 +1253,9 @@ rspamd_recipients_distance (struct rspamd_task *task, GList * args, void *unused
errno = 0;
threshold = strtod ((gchar *)arg->data, NULL);
if (errno != 0) {
- msg_warn ("invalid numeric value '%s': %s", (gchar *)arg->data, strerror (errno));
+ msg_warn ("invalid numeric value '%s': %s",
+ (gchar *)arg->data,
+ strerror (errno));
return FALSE;
}
@@ -1133,14 +1266,17 @@ rspamd_recipients_distance (struct rspamd_task *task, GList * args, void *unused
if (num < MIN_RCPT_TO_COMPARE) {
return FALSE;
}
- ar = rspamd_mempool_alloc0 (task->task_pool, num * sizeof (struct addr_list));
+ ar =
+ rspamd_mempool_alloc0 (task->task_pool, num *
+ sizeof (struct addr_list));
/* Fill array */
cur = task->rcpts;
#ifdef GMIME24
- for (i = 0; i < num; i ++) {
+ for (i = 0; i < num; i++) {
addr = internet_address_list_get_address (cur, i);
- ar[i].name = rspamd_mempool_strdup (task->task_pool, internet_address_get_name (addr));
+ ar[i].name = rspamd_mempool_strdup (task->task_pool,
+ internet_address_get_name (addr));
if (ar[i].name != NULL && (c = strchr (ar[i].name, '@')) != NULL) {
*c = '\0';
ar[i].addr = c + 1;
@@ -1151,7 +1287,8 @@ rspamd_recipients_distance (struct rspamd_task *task, GList * args, void *unused
while (cur) {
addr = internet_address_list_get_address (cur);
if (addr && internet_address_get_type (addr) == INTERNET_ADDRESS_NAME) {
- ar[i].name = rspamd_mempool_strdup (task->task_pool, internet_address_get_addr (addr));
+ ar[i].name = rspamd_mempool_strdup (task->task_pool,
+ internet_address_get_addr (addr));
if (ar[i].name != NULL && (c = strchr (ar[i].name, '@')) != NULL) {
*c = '\0';
ar[i].addr = c + 1;
@@ -1168,11 +1305,14 @@ rspamd_recipients_distance (struct rspamd_task *task, GList * args, void *unused
/* Cycle all elements in array */
for (i = 0; i < num; i++) {
for (j = i + 1; j < num; j++) {
- if (ar[i].name && ar[j].name && g_ascii_strncasecmp (ar[i].name, ar[j].name, COMPARE_RCPT_LEN) == 0) {
+ if (ar[i].name && ar[j].name &&
+ g_ascii_strncasecmp (ar[i].name, ar[j].name,
+ COMPARE_RCPT_LEN) == 0) {
/* Common name part */
hits++;
}
- else if (ar[i].addr && ar[j].addr && g_ascii_strcasecmp (ar[i].addr, ar[j].addr) == 0) {
+ else if (ar[i].addr && ar[j].addr &&
+ g_ascii_strcasecmp (ar[i].addr, ar[j].addr) == 0) {
/* Common address part, but different name */
hits++;
}
@@ -1188,11 +1328,12 @@ rspamd_recipients_distance (struct rspamd_task *task, GList * args, void *unused
}
gboolean
-rspamd_has_only_html_part (struct rspamd_task * task, GList * args, void *unused)
+rspamd_has_only_html_part (struct rspamd_task * task, GList * args,
+ void *unused)
{
- struct mime_text_part *p;
- GList *cur;
- gboolean res = FALSE;
+ struct mime_text_part *p;
+ GList *cur;
+ gboolean res = FALSE;
cur = g_list_first (task->text_parts);
while (cur) {
@@ -1210,30 +1351,34 @@ rspamd_has_only_html_part (struct rspamd_task * task, GList * args, void *unused
return res;
}
-static gboolean
+static gboolean
is_recipient_list_sorted (const InternetAddressList * ia)
{
- const InternetAddressList *cur;
- InternetAddress *addr;
- gboolean res = TRUE;
- struct addr_list current = { NULL, NULL }, previous = {
- NULL, NULL};
+ const InternetAddressList *cur;
+ InternetAddress *addr;
+ gboolean res = TRUE;
+ struct addr_list current = { NULL, NULL }, previous = {
+ NULL, NULL
+ };
#ifdef GMIME24
- gint num, i;
+ gint num, i;
#endif
/* Do not check to short address lists */
- if (internet_address_list_length ((InternetAddressList *)ia) < MIN_RCPT_TO_COMPARE) {
+ if (internet_address_list_length ((InternetAddressList *)ia) <
+ MIN_RCPT_TO_COMPARE) {
return FALSE;
}
#ifdef GMIME24
num = internet_address_list_length ((InternetAddressList *)ia);
cur = ia;
- for (i = 0; i < num; i ++) {
- addr = internet_address_list_get_address ((InternetAddressList *)cur, i);
+ for (i = 0; i < num; i++) {
+ addr =
+ internet_address_list_get_address ((InternetAddressList *)cur, i);
current.addr = (gchar *)internet_address_get_name (addr);
if (previous.addr != NULL) {
- if (current.addr && g_ascii_strcasecmp (current.addr, previous.addr) < 0) {
+ if (current.addr &&
+ g_ascii_strcasecmp (current.addr, previous.addr) < 0) {
res = FALSE;
break;
}
@@ -1247,7 +1392,8 @@ is_recipient_list_sorted (const InternetAddressList * ia)
if (internet_address_get_type (addr) == INTERNET_ADDRESS_NAME) {
current.addr = internet_address_get_addr (addr);
if (previous.addr != NULL) {
- if (current.addr && g_ascii_strcasecmp (current.addr, previous.addr) < 0) {
+ if (current.addr &&
+ g_ascii_strcasecmp (current.addr, previous.addr) < 0) {
res = FALSE;
break;
}
@@ -1262,16 +1408,21 @@ is_recipient_list_sorted (const InternetAddressList * ia)
}
gboolean
-rspamd_is_recipients_sorted (struct rspamd_task * task, GList * args, void *unused)
+rspamd_is_recipients_sorted (struct rspamd_task * task,
+ GList * args,
+ void *unused)
{
/* Check all types of addresses */
- if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message, GMIME_RECIPIENT_TYPE_TO)) == TRUE) {
+ if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message,
+ GMIME_RECIPIENT_TYPE_TO)) == TRUE) {
return TRUE;
}
- if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message, GMIME_RECIPIENT_TYPE_BCC)) == TRUE) {
+ if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message,
+ GMIME_RECIPIENT_TYPE_BCC)) == TRUE) {
return TRUE;
}
- if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message, GMIME_RECIPIENT_TYPE_CC)) == TRUE) {
+ if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message,
+ GMIME_RECIPIENT_TYPE_CC)) == TRUE) {
return TRUE;
}
@@ -1279,15 +1430,17 @@ rspamd_is_recipients_sorted (struct rspamd_task * task, GList * args, void *unus
}
gboolean
-rspamd_compare_transfer_encoding (struct rspamd_task * task, GList * args, void *unused)
+rspamd_compare_transfer_encoding (struct rspamd_task * task,
+ GList * args,
+ void *unused)
{
- GMimeObject *part;
+ GMimeObject *part;
#ifndef GMIME24
- GMimePartEncodingType enc_req, part_enc;
+ GMimePartEncodingType enc_req, part_enc;
#else
- GMimeContentEncoding enc_req, part_enc;
+ GMimeContentEncoding enc_req, part_enc;
#endif
- struct expression_argument *arg;
+ struct expression_argument *arg;
if (args == NULL) {
msg_warn ("no parameters to function");
@@ -1324,7 +1477,9 @@ rspamd_compare_transfer_encoding (struct rspamd_task * task, GList * args, void
#endif
- debug_task ("got encoding in part: %d and compare with %d", (gint)part_enc, (gint)enc_req);
+ debug_task ("got encoding in part: %d and compare with %d",
+ (gint)part_enc,
+ (gint)enc_req);
#ifndef GMIME24
g_object_unref (part);
#endif
@@ -1342,9 +1497,9 @@ rspamd_compare_transfer_encoding (struct rspamd_task * task, GList * args, void
gboolean
rspamd_is_html_balanced (struct rspamd_task * task, GList * args, void *unused)
{
- struct mime_text_part *p;
- GList *cur;
- gboolean res = TRUE;
+ struct mime_text_part *p;
+ GList *cur;
+ gboolean res = TRUE;
cur = g_list_first (task->text_parts);
while (cur) {
@@ -1366,15 +1521,15 @@ rspamd_is_html_balanced (struct rspamd_task * task, GList * args, void *unused)
}
struct html_callback_data {
- struct html_tag *tag;
- gboolean *res;
+ struct html_tag *tag;
+ gboolean *res;
};
-static gboolean
+static gboolean
search_html_node_callback (GNode * node, gpointer data)
{
- struct html_callback_data *cd = data;
- struct html_node *nd;
+ struct html_callback_data *cd = data;
+ struct html_node *nd;
nd = node->data;
if (nd) {
@@ -1390,12 +1545,12 @@ search_html_node_callback (GNode * node, gpointer data)
gboolean
rspamd_has_html_tag (struct rspamd_task * task, GList * args, void *unused)
{
- struct mime_text_part *p;
- GList *cur;
- struct expression_argument *arg;
- struct html_tag *tag;
- gboolean res = FALSE;
- struct html_callback_data cd;
+ struct mime_text_part *p;
+ GList *cur;
+ struct expression_argument *arg;
+ struct html_tag *tag;
+ gboolean res = FALSE;
+ struct html_callback_data cd;
if (args == NULL) {
msg_warn ("no parameters to function");
@@ -1405,7 +1560,8 @@ rspamd_has_html_tag (struct rspamd_task * task, GList * args, void *unused)
arg = get_function_arg (args->data, task, TRUE);
tag = get_tag_by_name (arg->data);
if (tag == NULL) {
- msg_warn ("unknown tag type passed as argument: %s", (gchar *)arg->data);
+ msg_warn ("unknown tag type passed as argument: %s",
+ (gchar *)arg->data);
return FALSE;
}
@@ -1416,7 +1572,12 @@ rspamd_has_html_tag (struct rspamd_task * task, GList * args, void *unused)
while (cur && res == FALSE) {
p = cur->data;
if (!p->is_empty && p->is_html && p->html_nodes) {
- g_node_traverse (p->html_nodes, G_PRE_ORDER, G_TRAVERSE_ALL, -1, search_html_node_callback, &cd);
+ g_node_traverse (p->html_nodes,
+ G_PRE_ORDER,
+ G_TRAVERSE_ALL,
+ -1,
+ search_html_node_callback,
+ &cd);
}
cur = g_list_next (cur);
}
@@ -1428,9 +1589,9 @@ rspamd_has_html_tag (struct rspamd_task * task, GList * args, void *unused)
gboolean
rspamd_has_fake_html (struct rspamd_task * task, GList * args, void *unused)
{
- struct mime_text_part *p;
- GList *cur;
- gboolean res = FALSE;
+ struct mime_text_part *p;
+ GList *cur;
+ gboolean res = FALSE;
cur = g_list_first (task->text_parts);
diff --git a/src/libmime/expressions.h b/src/libmime/expressions.h
index 954cc74f7..1ba02d956 100644
--- a/src/libmime/expressions.h
+++ b/src/libmime/expressions.h
@@ -16,8 +16,8 @@ struct rspamd_regexp;
* Rspamd expression function
*/
struct expression_function {
- gchar *name; /**< name of function */
- GList *args; /**< its args */
+ gchar *name; /**< name of function */
+ GList *args; /**< its args */
};
/**
@@ -28,30 +28,31 @@ struct expression_argument {
EXPRESSION_ARGUMENT_NORMAL,
EXPRESSION_ARGUMENT_BOOL,
EXPRESSION_ARGUMENT_EXPR,
- } type; /**< type of argument (text or other function) */
- void *data; /**< pointer to its data */
+ } type; /**< type of argument (text or other function) */
+ void *data; /**< pointer to its data */
};
-/**
- * Logic expression
+/**
+ * Logic expression
*/
struct expression {
- enum {
+ enum {
EXPR_REGEXP,
- EXPR_OPERATION,
- EXPR_FUNCTION,
- EXPR_STR,
+ EXPR_OPERATION,
+ EXPR_FUNCTION,
+ EXPR_STR,
EXPR_REGEXP_PARSED,
- } type; /**< expression type */
+ } type; /**< expression type */
union {
void *operand;
gchar operation;
- } content; /**< union for storing operand or operation code */
- const gchar *orig; /**< original line */
- struct expression *next; /**< chain link */
+ } content; /**< union for storing operand or operation code */
+ const gchar *orig; /**< original line */
+ struct expression *next; /**< chain link */
};
-typedef gboolean (*rspamd_internal_func_t)(struct rspamd_task *, GList *args, void *user_data);
+typedef gboolean (*rspamd_internal_func_t)(struct rspamd_task *, GList *args,
+ void *user_data);
/**
* Parse regexp line to regexp structure
@@ -59,7 +60,9 @@ typedef gboolean (*rspamd_internal_func_t)(struct rspamd_task *, GList *args, vo
* @param line incoming line
* @return regexp structure or NULL in case of error
*/
-struct rspamd_regexp* parse_regexp (rspamd_mempool_t *pool, const gchar *line, gboolean raw_mode);
+struct rspamd_regexp * parse_regexp (rspamd_mempool_t *pool,
+ const gchar *line,
+ gboolean raw_mode);
/**
* Parse composites line to composites structure (eg. "SYMBOL1&SYMBOL2|!SYMBOL3")
@@ -67,7 +70,7 @@ struct rspamd_regexp* parse_regexp (rspamd_mempool_t *pool, const gchar *line, g
* @param line incoming line
* @return expression structure or NULL in case of error
*/
-struct expression* parse_expression (rspamd_mempool_t *pool, gchar *line);
+struct expression * parse_expression (rspamd_mempool_t *pool, gchar *line);
/**
* Call specified fucntion and return boolean result
@@ -76,14 +79,18 @@ struct expression* parse_expression (rspamd_mempool_t *pool, gchar *line);
* @param L lua specific state
* @return TRUE or FALSE depending on function result
*/
-gboolean call_expression_function (struct expression_function *func, struct rspamd_task *task, lua_State *L);
+gboolean call_expression_function (struct expression_function *func,
+ struct rspamd_task *task,
+ lua_State *L);
/**
* Register specified function to rspamd internal functions list
* @param name name of function
* @param func pointer to function
*/
-void register_expression_function (const gchar *name, rspamd_internal_func_t func, void *user_data);
+void register_expression_function (const gchar *name,
+ rspamd_internal_func_t func,
+ void *user_data);
/**
* Add regexp to regexp cache
@@ -111,7 +118,9 @@ void re_cache_del (const gchar *line, rspamd_mempool_t *pool);
* @param pointer regexp data
* @param result numeric result of this regexp
*/
-void task_cache_add (struct rspamd_task *task, struct rspamd_regexp *re, gint32 result);
+void task_cache_add (struct rspamd_task *task,
+ struct rspamd_regexp *re,
+ gint32 result);
/**
* Check regexp in cache
@@ -128,6 +137,8 @@ gint32 task_cache_check (struct rspamd_task *task, struct rspamd_regexp *re);
* @param want_string return NULL if argument is not a string
* @return expression argument structure or NULL if failed
*/
-struct expression_argument *get_function_arg (struct expression *expr, struct rspamd_task *task, gboolean want_string);
+struct expression_argument * get_function_arg (struct expression *expr,
+ struct rspamd_task *task,
+ gboolean want_string);
#endif
diff --git a/src/libmime/filter.c b/src/libmime/filter.c
index 2068c79e3..f296617cf 100644
--- a/src/libmime/filter.c
+++ b/src/libmime/filter.c
@@ -22,18 +22,18 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "binlog.h"
+#include "cfg_file.h"
+#include "classifiers/classifiers.h"
#include "config.h"
-#include "mem_pool.h"
+#include "diff.h"
+#include "expressions.h"
#include "filter.h"
#include "main.h"
+#include "mem_pool.h"
#include "message.h"
-#include "cfg_file.h"
-#include "util.h"
-#include "expressions.h"
-#include "binlog.h"
-#include "diff.h"
-#include "classifiers/classifiers.h"
#include "tokenizers/tokenizers.h"
+#include "util.h"
#ifdef WITH_LUA
# include "lua/lua_common.h"
@@ -44,44 +44,56 @@
#ifndef PARAM_H_HAS_BITSET
/* Bit map related macros. */
#define NBBY 8 /* number of bits in a byte */
-#define setbit(a,i) (((unsigned char *)(a))[(i)/NBBY] |= 1<<((i)%NBBY))
-#define clrbit(a,i) (((unsigned char *)(a))[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define setbit(a, \
+ i) (((unsigned char *)(a))[(i) / NBBY] |= 1 << ((i) % NBBY))
+#define clrbit(a, \
+ i) (((unsigned char *)(a))[(i) / NBBY] &= ~(1 << ((i) % NBBY)))
#define isset(a,i) \
- (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
+ (((const unsigned char *)(a))[(i) / NBBY] & (1 << ((i) % NBBY)))
#define isclr(a,i) \
- ((((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+ ((((const unsigned char *)(a))[(i) / NBBY] & (1 << ((i) % NBBY))) == 0)
#endif
-#define BITSPERBYTE (8*sizeof (gchar))
-#define NBYTES(nbits) (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE)
+#define BITSPERBYTE (8 * sizeof (gchar))
+#define NBYTES(nbits) (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE)
-static inline GQuark
+static inline GQuark
filter_error_quark (void)
{
return g_quark_from_static_string ("g-filter-error-quark");
}
static void
-insert_metric_result (struct rspamd_task *task, struct metric *metric, const gchar *symbol,
- double flag, GList * opts, gboolean single)
+insert_metric_result (struct rspamd_task *task,
+ struct metric *metric,
+ const gchar *symbol,
+ double flag,
+ GList * opts,
+ gboolean single)
{
- struct metric_result *metric_res;
- struct symbol *s;
- gdouble *weight, w;
+ struct metric_result *metric_res;
+ struct symbol *s;
+ gdouble *weight, w;
metric_res = g_hash_table_lookup (task->results, metric->name);
if (metric_res == NULL) {
/* Create new metric chain */
- metric_res = rspamd_mempool_alloc (task->task_pool, sizeof (struct metric_result));
- metric_res->symbols = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
+ metric_res =
+ rspamd_mempool_alloc (task->task_pool,
+ sizeof (struct metric_result));
+ metric_res->symbols = g_hash_table_new (rspamd_str_hash,
+ rspamd_str_equal);
metric_res->checked = FALSE;
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_hash_table_unref, metric_res->symbols);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_hash_table_unref,
+ metric_res->symbols);
metric_res->metric = metric;
metric_res->grow_factor = 0;
metric_res->score = 0;
- g_hash_table_insert (task->results, (gpointer) metric->name, metric_res);
+ g_hash_table_insert (task->results, (gpointer) metric->name,
+ metric_res);
}
-
+
weight = g_hash_table_lookup (metric->symbols, symbol);
if (weight == NULL) {
w = 0.0;
@@ -94,7 +106,7 @@ insert_metric_result (struct rspamd_task *task, struct metric *metric, const gch
if ((s = g_hash_table_lookup (metric_res->symbols, symbol)) != NULL) {
if (s->options && opts && opts != s->options) {
/* Append new options */
- s->options = g_list_concat (s->options, g_list_copy(opts));
+ s->options = g_list_concat (s->options, g_list_copy (opts));
/*
* Note that there is no need to add new destructor of GList as elements of appended
* GList are used directly, so just free initial GList
@@ -102,7 +114,8 @@ insert_metric_result (struct rspamd_task *task, struct metric *metric, const gch
}
else if (opts) {
s->options = g_list_copy (opts);
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_list_free, s->options);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_list_free, s->options);
}
if (!single) {
/* Handle grow factor */
@@ -139,7 +152,8 @@ insert_metric_result (struct rspamd_task *task, struct metric *metric, const gch
if (opts) {
s->options = g_list_copy (opts);
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_list_free, s->options);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_list_free, s->options);
}
else {
s->options = NULL;
@@ -147,22 +161,30 @@ insert_metric_result (struct rspamd_task *task, struct metric *metric, const gch
g_hash_table_insert (metric_res->symbols, (gpointer) symbol, s);
}
- debug_task ("symbol %s, score %.2f, metric %s, factor: %f", symbol, s->score, metric->name, w);
-
+ debug_task ("symbol %s, score %.2f, metric %s, factor: %f",
+ symbol,
+ s->score,
+ metric->name,
+ w);
+
}
#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
-static GStaticMutex result_mtx = G_STATIC_MUTEX_INIT;
+static GStaticMutex result_mtx = G_STATIC_MUTEX_INIT;
#else
G_LOCK_DEFINE (result_mtx);
#endif
static void
-insert_result_common (struct rspamd_task *task, const gchar *symbol, double flag, GList * opts, gboolean single)
+insert_result_common (struct rspamd_task *task,
+ const gchar *symbol,
+ double flag,
+ GList * opts,
+ gboolean single)
{
- struct metric *metric;
- struct cache_item *item;
- GList *cur, *metric_list;
+ struct metric *metric;
+ struct cache_item *item;
+ GList *cur, *metric_list;
/* Avoid concurrenting inserting of results */
#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
@@ -173,7 +195,7 @@ insert_result_common (struct rspamd_task *task, const gchar *symbol, double flag
metric_list = g_hash_table_lookup (task->cfg->metrics_symbols, symbol);
if (metric_list) {
cur = metric_list;
-
+
while (cur) {
metric = cur->data;
insert_metric_result (task, metric, symbol, flag, opts, single);
@@ -182,7 +204,12 @@ insert_result_common (struct rspamd_task *task, const gchar *symbol, double flag
}
else {
/* Insert symbol to default metric */
- insert_metric_result (task, task->cfg->default_metric, symbol, flag, opts, single);
+ insert_metric_result (task,
+ task->cfg->default_metric,
+ symbol,
+ flag,
+ opts,
+ single);
}
/* Process cache item */
@@ -206,21 +233,27 @@ insert_result_common (struct rspamd_task *task, const gchar *symbol, double flag
/* Insert result that may be increased on next insertions */
void
-insert_result (struct rspamd_task *task, const gchar *symbol, double flag, GList * opts)
+insert_result (struct rspamd_task *task,
+ const gchar *symbol,
+ double flag,
+ GList * opts)
{
insert_result_common (task, symbol, flag, opts, task->cfg->one_shot_mode);
}
/* Insert result as a single option */
void
-insert_result_single (struct rspamd_task *task, const gchar *symbol, double flag, GList * opts)
+insert_result_single (struct rspamd_task *task,
+ const gchar *symbol,
+ double flag,
+ GList * opts)
{
insert_result_common (task, symbol, flag, opts, TRUE);
}
static gboolean
check_metric_settings (struct rspamd_task *task, struct metric *metric,
- double *score)
+ double *score)
{
const ucl_object_t *mobj, *reject;
double val;
@@ -243,11 +276,11 @@ check_metric_settings (struct rspamd_task *task, struct metric *metric,
}
/* Return true if metric has score that is more than spam score for it */
-static gboolean
+static gboolean
check_metric_is_spam (struct rspamd_task *task, struct metric *metric)
{
- struct metric_result *res;
- double ms;
+ struct metric_result *res;
+ double ms;
/* Avoid concurrency while checking results */
#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
@@ -280,9 +313,9 @@ check_metric_is_spam (struct rspamd_task *task, struct metric *metric)
gint
process_filters (struct rspamd_task *task)
{
- GList *cur;
- struct metric *metric;
- gpointer item = NULL;
+ GList *cur;
+ struct metric *metric;
+ gpointer item = NULL;
/* Process metrics symbols */
while (call_symbol_callback (task, task->cfg->cache, &item)) {
@@ -291,8 +324,8 @@ process_filters (struct rspamd_task *task)
while (cur) {
metric = cur->data;
if (!task->pass_all_filters &&
- metric->actions[METRIC_ACTION_REJECT].score > 0 &&
- check_metric_is_spam (task, metric)) {
+ metric->actions[METRIC_ACTION_REJECT].score > 0 &&
+ check_metric_is_spam (task, metric)) {
task->state = WRITE_REPLY;
return 1;
}
@@ -307,22 +340,22 @@ process_filters (struct rspamd_task *task)
struct composites_data {
- struct rspamd_task *task;
- struct metric_result *metric_res;
- GTree *symbols_to_remove;
- guint8 *checked;
+ struct rspamd_task *task;
+ struct metric_result *metric_res;
+ GTree *symbols_to_remove;
+ guint8 *checked;
};
struct symbol_remove_data {
- struct symbol *ms;
- gboolean remove_weight;
- gboolean remove_symbol;
+ struct symbol *ms;
+ gboolean remove_weight;
+ gboolean remove_symbol;
};
static gint
remove_compare_data (gconstpointer a, gconstpointer b)
{
- const gchar *ca = a, *cb = b;
+ const gchar *ca = a, *cb = b;
return strcmp (ca, cb);
}
@@ -330,16 +363,16 @@ remove_compare_data (gconstpointer a, gconstpointer b)
static void
composites_foreach_callback (gpointer key, gpointer value, void *data)
{
- struct composites_data *cd = (struct composites_data *)data;
- struct rspamd_composite *composite = value, *ncomp;
- struct expression *expr;
- GQueue *stack;
- GList *symbols = NULL, *s;
- gsize cur, op1, op2;
- gchar logbuf[256], *sym, *check_sym;
- gint r;
- struct symbol *ms;
- struct symbol_remove_data *rd;
+ struct composites_data *cd = (struct composites_data *)data;
+ struct rspamd_composite *composite = value, *ncomp;
+ struct expression *expr;
+ GQueue *stack;
+ GList *symbols = NULL, *s;
+ gsize cur, op1, op2;
+ gchar logbuf[256], *sym, *check_sym;
+ gint r;
+ struct symbol *ms;
+ struct symbol_remove_data *rd;
expr = composite->expr;
@@ -355,16 +388,19 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
/* Find corresponding symbol */
sym = expr->content.operand;
if (*sym == '~' || *sym == '-') {
- sym ++;
+ sym++;
}
if (g_hash_table_lookup (cd->metric_res->symbols, sym) == NULL) {
cur = 0;
- if ((ncomp = g_hash_table_lookup (cd->task->cfg->composite_symbols, sym)) != NULL) {
+ if ((ncomp =
+ g_hash_table_lookup (cd->task->cfg->composite_symbols,
+ sym)) != NULL) {
/* Set checked for this symbol to avoid cyclic references */
if (isclr (cd->checked, ncomp->id)) {
setbit (cd->checked, composite->id);
composites_foreach_callback (sym, ncomp, cd);
- if (g_hash_table_lookup (cd->metric_res->symbols, sym) != NULL) {
+ if (g_hash_table_lookup (cd->metric_res->symbols,
+ sym) != NULL) {
cur = 1;
}
}
@@ -412,7 +448,11 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
if (op1) {
/* Remove all symbols that are in composite symbol */
s = g_list_first (symbols);
- r = rspamd_snprintf (logbuf, sizeof (logbuf), "<%s>, insert symbol %s instead of symbols: ", cd->task->message_id, key);
+ r = rspamd_snprintf (logbuf,
+ sizeof (logbuf),
+ "<%s>, insert symbol %s instead of symbols: ",
+ cd->task->message_id,
+ key);
while (s) {
sym = s->data;
if (*sym == '~' || *sym == '-') {
@@ -425,18 +465,23 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
if (ms == NULL) {
/* Try to process other composites */
- if ((ncomp = g_hash_table_lookup (cd->task->cfg->composite_symbols, check_sym)) != NULL) {
+ if ((ncomp =
+ g_hash_table_lookup (cd->task->cfg->composite_symbols,
+ check_sym)) != NULL) {
/* Set checked for this symbol to avoid cyclic references */
if (isclr (cd->checked, ncomp->id)) {
setbit (cd->checked, composite->id);
composites_foreach_callback (check_sym, ncomp, cd);
- ms = g_hash_table_lookup (cd->metric_res->symbols, check_sym);
+ ms = g_hash_table_lookup (cd->metric_res->symbols,
+ check_sym);
}
}
}
if (ms != NULL) {
- rd = rspamd_mempool_alloc (cd->task->task_pool, sizeof (struct symbol_remove_data));
+ rd =
+ rspamd_mempool_alloc (cd->task->task_pool,
+ sizeof (struct symbol_remove_data));
rd->ms = ms;
if (G_UNLIKELY (*sym == '~')) {
rd->remove_weight = FALSE;
@@ -451,7 +496,9 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
rd->remove_weight = TRUE;
}
if (!g_tree_lookup (cd->symbols_to_remove, rd)) {
- g_tree_insert (cd->symbols_to_remove, (gpointer)ms->name, rd);
+ g_tree_insert (cd->symbols_to_remove,
+ (gpointer)ms->name,
+ rd);
}
}
else {
@@ -459,10 +506,16 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
}
if (s->next) {
- r += rspamd_snprintf (logbuf + r, sizeof (logbuf) -r, "%s, ", s->data);
+ r += rspamd_snprintf (logbuf + r,
+ sizeof (logbuf) - r,
+ "%s, ",
+ s->data);
}
else {
- r += rspamd_snprintf (logbuf + r, sizeof (logbuf) -r, "%s", s->data);
+ r += rspamd_snprintf (logbuf + r,
+ sizeof (logbuf) - r,
+ "%s",
+ s->data);
}
s = g_list_next (s);
}
@@ -479,12 +532,13 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
return;
}
-static gboolean
-check_autolearn (struct statfile_autolearn_params *params, struct rspamd_task *task)
+static gboolean
+check_autolearn (struct statfile_autolearn_params *params,
+ struct rspamd_task *task)
{
- gchar *metric_name = DEFAULT_METRIC;
- struct metric_result *metric_res;
- GList *cur;
+ gchar *metric_name = DEFAULT_METRIC;
+ struct metric_result *metric_res;
+ GList *cur;
if (params->metric != NULL) {
metric_name = (gchar *)params->metric;
@@ -502,12 +556,16 @@ check_autolearn (struct statfile_autolearn_params *params, struct rspamd_task *t
}
else {
/* Process score of metric */
- if ((params->threshold_min != 0 && metric_res->score > params->threshold_min) || (params->threshold_max != 0 && metric_res->score < params->threshold_max)) {
+ if ((params->threshold_min != 0 && metric_res->score >
+ params->threshold_min) ||
+ (params->threshold_max != 0 && metric_res->score <
+ params->threshold_max)) {
/* Now check for specific symbols */
if (params->symbols) {
cur = params->symbols;
while (cur) {
- if (g_hash_table_lookup (metric_res->symbols, cur->data) == NULL) {
+ if (g_hash_table_lookup (metric_res->symbols,
+ cur->data) == NULL) {
return FALSE;
}
cur = g_list_next (cur);
@@ -522,28 +580,47 @@ check_autolearn (struct statfile_autolearn_params *params, struct rspamd_task *t
}
void
-process_autolearn (struct rspamd_statfile_config *st, struct rspamd_task *task, GTree * tokens, struct classifier *classifier, gchar *filename, struct classifier_ctx *ctx)
+process_autolearn (struct rspamd_statfile_config *st,
+ struct rspamd_task *task,
+ GTree * tokens,
+ struct classifier *classifier,
+ gchar *filename,
+ struct classifier_ctx *ctx)
{
- stat_file_t *statfile;
- struct rspamd_statfile_config *unused;
+ stat_file_t *statfile;
+ struct rspamd_statfile_config *unused;
if (check_autolearn (st->autolearn, task)) {
if (tokens) {
/* Take care of subject */
tokenize_subject (task, &tokens);
- msg_info ("message with id <%s> autolearned statfile '%s'", task->message_id, filename);
-
+ msg_info ("message with id <%s> autolearned statfile '%s'",
+ task->message_id,
+ filename);
+
/* Get or create statfile */
- statfile = get_statfile_by_symbol (task->worker->srv->statfile_pool, ctx->cfg,
- st->symbol, &unused, TRUE);
-
+ statfile = get_statfile_by_symbol (task->worker->srv->statfile_pool,
+ ctx->cfg,
+ st->symbol,
+ &unused,
+ TRUE);
+
if (statfile == NULL) {
return;
}
- classifier->learn_func (ctx, task->worker->srv->statfile_pool, st->symbol, tokens, TRUE, NULL, 1., NULL);
+ classifier->learn_func (ctx,
+ task->worker->srv->statfile_pool,
+ st->symbol,
+ tokens,
+ TRUE,
+ NULL,
+ 1.,
+ NULL);
maybe_write_binlog (ctx->cfg, st, statfile, tokens);
- statfile_pool_plan_invalidate (task->worker->srv->statfile_pool, DEFAULT_STATFILE_INVALIDATE_TIME, DEFAULT_STATFILE_INVALIDATE_JITTER);
+ statfile_pool_plan_invalidate (task->worker->srv->statfile_pool,
+ DEFAULT_STATFILE_INVALIDATE_TIME,
+ DEFAULT_STATFILE_INVALIDATE_JITTER);
}
}
}
@@ -551,8 +628,8 @@ process_autolearn (struct rspamd_statfile_config *st, struct rspamd_task *task,
static gboolean
composites_remove_symbols (gpointer key, gpointer value, gpointer data)
{
- struct composites_data *cd = data;
- struct symbol_remove_data *rd = value;
+ struct composites_data *cd = data;
+ struct symbol_remove_data *rd = value;
if (rd->remove_symbol) {
g_hash_table_remove (cd->metric_res->symbols, key);
@@ -567,17 +644,22 @@ composites_remove_symbols (gpointer key, gpointer value, gpointer data)
static void
composites_metric_callback (gpointer key, gpointer value, gpointer data)
{
- struct rspamd_task *task = (struct rspamd_task *)data;
- struct composites_data *cd = rspamd_mempool_alloc (task->task_pool, sizeof (struct composites_data));
- struct metric_result *metric_res = (struct metric_result *)value;
+ struct rspamd_task *task = (struct rspamd_task *)data;
+ struct composites_data *cd =
+ rspamd_mempool_alloc (task->task_pool, sizeof (struct composites_data));
+ struct metric_result *metric_res = (struct metric_result *)value;
cd->task = task;
cd->metric_res = (struct metric_result *)metric_res;
cd->symbols_to_remove = g_tree_new (remove_compare_data);
- cd->checked = rspamd_mempool_alloc0 (task->task_pool, NBYTES (g_hash_table_size (task->cfg->composite_symbols)));
+ cd->checked =
+ rspamd_mempool_alloc0 (task->task_pool,
+ NBYTES (g_hash_table_size (task->cfg->composite_symbols)));
/* Process hash table */
- g_hash_table_foreach (task->cfg->composite_symbols, composites_foreach_callback, cd);
+ g_hash_table_foreach (task->cfg->composite_symbols,
+ composites_foreach_callback,
+ cd);
/* Remove symbols that are in composites */
g_tree_foreach (cd->symbols_to_remove, composites_remove_symbols, cd);
@@ -599,30 +681,32 @@ struct classifiers_cbdata {
static void
classifiers_callback (gpointer value, void *arg)
{
- struct classifiers_cbdata *cbdata = arg;
- struct rspamd_task *task;
- struct rspamd_classifier_config *cl = value;
- struct classifier_ctx *ctx;
- struct mime_text_part *text_part, *p1, *p2;
- struct rspamd_statfile_config *st;
- GTree *tokens = NULL;
- GList *cur;
- f_str_t c;
- gchar *header = NULL;
- gint *dist = NULL, diff;
- gboolean is_twopart = FALSE;
-
+ struct classifiers_cbdata *cbdata = arg;
+ struct rspamd_task *task;
+ struct rspamd_classifier_config *cl = value;
+ struct classifier_ctx *ctx;
+ struct mime_text_part *text_part, *p1, *p2;
+ struct rspamd_statfile_config *st;
+ GTree *tokens = NULL;
+ GList *cur;
+ f_str_t c;
+ gchar *header = NULL;
+ gint *dist = NULL, diff;
+ gboolean is_twopart = FALSE;
+
task = cbdata->task;
if ((header = g_hash_table_lookup (cl->opts, "header")) != NULL) {
- cur = message_get_header (task->task_pool, task->message, header, FALSE);
+ cur =
+ message_get_header (task->task_pool, task->message, header, FALSE);
if (cur) {
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_list_free, cur);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t)g_list_free, cur);
}
}
else {
cur = g_list_first (task->text_parts);
- dist = rspamd_mempool_get_variable (task->task_pool, "parts_distance");
+ dist = rspamd_mempool_get_variable (task->task_pool, "parts_distance");
if (cur != NULL && cur->next != NULL && cur->next->next == NULL) {
is_twopart = TRUE;
}
@@ -635,7 +719,8 @@ classifiers_callback (gpointer value, void *arg)
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, FALSE, NULL)) {
+ if (!cl->tokenizer->tokenize_func (cl->tokenizer,
+ task->task_pool, &c, &tokens, FALSE, FALSE, NULL)) {
msg_info ("cannot tokenize input");
return;
}
@@ -651,7 +736,9 @@ classifiers_callback (gpointer value, void *arg)
/* Compare part's content */
if (*dist >= COMMON_PART_FACTOR) {
- msg_info ("message <%s> has two common text parts, ignore the last one", task->message_id);
+ msg_info (
+ "message <%s> has two common text parts, ignore the last one",
+ task->message_id);
break;
}
}
@@ -659,21 +746,25 @@ classifiers_callback (gpointer value, void *arg)
p1 = cur->prev->data;
p2 = text_part;
if (p1->diff_str != NULL && p2->diff_str != NULL) {
- diff = compare_diff_distance (p1->diff_str, p2->diff_str);
+ diff =
+ compare_diff_distance (p1->diff_str, p2->diff_str);
}
else {
diff = fuzzy_compare_parts (p1, p2);
}
if (diff >= COMMON_PART_FACTOR) {
- msg_info ("message <%s> has two common text parts, ignore the last one", task->message_id);
+ msg_info (
+ "message <%s> has two common text parts, ignore the last one",
+ task->message_id);
break;
}
}
c.begin = (gchar *)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, text_part->is_utf, text_part->urls_offset)) {
+ if (!cl->tokenizer->tokenize_func (cl->tokenizer,
+ task->task_pool, &c, &tokens,
+ FALSE, text_part->is_utf, text_part->urls_offset)) {
msg_info ("cannot tokenize input");
return;
}
@@ -692,12 +783,20 @@ classifiers_callback (gpointer value, void *arg)
if (cbdata->nL != NULL) {
rspamd_mutex_lock (cbdata->nL->m);
- cl->classifier->classify_func (ctx, task->worker->srv->statfile_pool, tokens, task, cbdata->nL->L);
+ cl->classifier->classify_func (ctx,
+ task->worker->srv->statfile_pool,
+ tokens,
+ task,
+ cbdata->nL->L);
rspamd_mutex_unlock (cbdata->nL->m);
}
else {
/* Non-threaded case */
- cl->classifier->classify_func (ctx, task->worker->srv->statfile_pool, tokens, task, task->cfg->lua_state);
+ cl->classifier->classify_func (ctx,
+ task->worker->srv->statfile_pool,
+ tokens,
+ task,
+ task->cfg->lua_state);
}
/* Autolearning */
@@ -707,7 +806,12 @@ classifiers_callback (gpointer value, void *arg)
if (st->autolearn) {
if (check_autolearn (st->autolearn, task)) {
/* Process autolearn */
- process_autolearn (st, task, tokens, cl->classifier, st->path, ctx);
+ process_autolearn (st,
+ task,
+ tokens,
+ cl->classifier,
+ st->path,
+ ctx);
}
}
cur = g_list_next (cur);
@@ -718,7 +822,7 @@ classifiers_callback (gpointer value, void *arg)
void
process_statfiles (struct rspamd_task *task)
{
- struct classifiers_cbdata cbdata;
+ struct classifiers_cbdata cbdata;
if (task->is_skipped) {
return;
@@ -726,7 +830,8 @@ process_statfiles (struct rspamd_task *task)
if (task->tokens == NULL) {
task->tokens = g_hash_table_new (g_direct_hash, g_direct_equal);
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_hash_table_unref, task->tokens);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t)g_hash_table_unref, task->tokens);
}
cbdata.task = task;
cbdata.nL = NULL;
@@ -739,9 +844,9 @@ process_statfiles (struct rspamd_task *task)
void
process_statfiles_threaded (gpointer data, gpointer user_data)
{
- struct rspamd_task *task = (struct rspamd_task *)data;
- struct lua_locked_state *nL = user_data;
- struct classifiers_cbdata cbdata;
+ struct rspamd_task *task = (struct rspamd_task *)data;
+ struct lua_locked_state *nL = user_data;
+ struct classifiers_cbdata cbdata;
if (task->is_skipped) {
remove_async_thread (task->s);
@@ -750,7 +855,8 @@ process_statfiles_threaded (gpointer data, gpointer user_data)
if (task->tokens == NULL) {
task->tokens = g_hash_table_new (g_direct_hash, g_direct_equal);
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_hash_table_unref, task->tokens);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t)g_hash_table_unref, task->tokens);
}
cbdata.task = task;
@@ -760,18 +866,22 @@ process_statfiles_threaded (gpointer data, gpointer user_data)
}
static void
-insert_metric_header (gpointer metric_name, gpointer metric_value, gpointer data)
+insert_metric_header (gpointer metric_name, gpointer metric_value,
+ gpointer data)
{
#ifndef GLIB_HASH_COMPAT
- struct rspamd_task *task = (struct rspamd_task *)data;
- gint r = 0;
+ struct rspamd_task *task = (struct rspamd_task *)data;
+ gint r = 0;
/* Try to be rfc2822 compatible and avoid long headers with folding */
- gchar header_name[128], outbuf[1000];
- GList *symbols = NULL, *cur;
- struct metric_result *metric_res = (struct metric_result *)metric_value;
- double ms;
+ gchar header_name[128], outbuf[1000];
+ GList *symbols = NULL, *cur;
+ struct metric_result *metric_res = (struct metric_result *)metric_value;
+ double ms;
- rspamd_snprintf (header_name, sizeof (header_name), "X-Spam-%s", metric_res->metric->name);
+ rspamd_snprintf (header_name,
+ sizeof (header_name),
+ "X-Spam-%s",
+ metric_res->metric->name);
if (!check_metric_settings (task, metric_res->metric, &ms)) {
ms = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
@@ -800,7 +910,8 @@ insert_metric_header (gpointer metric_name, gpointer metric_value, gpointer data
}
g_list_free (symbols);
#ifdef GMIME24
- g_mime_object_append_header (GMIME_OBJECT (task->message), header_name, outbuf);
+ g_mime_object_append_header (GMIME_OBJECT (
+ task->message), header_name, outbuf);
#else
g_mime_message_add_header (task->message, header_name, outbuf);
#endif
@@ -820,13 +931,16 @@ check_action_str (const gchar *data, gint *result)
if (g_ascii_strncasecmp (data, "reject", sizeof ("reject") - 1) == 0) {
*result = METRIC_ACTION_REJECT;
}
- else if (g_ascii_strncasecmp (data, "greylist", sizeof ("greylist") - 1) == 0) {
+ else if (g_ascii_strncasecmp (data, "greylist",
+ sizeof ("greylist") - 1) == 0) {
*result = METRIC_ACTION_GREYLIST;
}
- else if (g_ascii_strncasecmp (data, "add_header", sizeof ("add_header") - 1) == 0) {
+ else if (g_ascii_strncasecmp (data, "add_header", sizeof ("add_header") -
+ 1) == 0) {
*result = METRIC_ACTION_ADD_HEADER;
}
- else if (g_ascii_strncasecmp (data, "rewrite_subject", sizeof ("rewrite_subject") - 1) == 0) {
+ else if (g_ascii_strncasecmp (data, "rewrite_subject",
+ sizeof ("rewrite_subject") - 1) == 0) {
*result = METRIC_ACTION_REWRITE_SUBJECT;
}
else {
@@ -861,9 +975,9 @@ str_action_metric (enum rspamd_metric_action action)
gint
check_metric_action (double score, double required_score, struct metric *metric)
{
- struct metric_action *action, *selected_action = NULL;
- double max_score = 0;
- int i;
+ struct metric_action *action, *selected_action = NULL;
+ double max_score = 0;
+ int i;
if (score >= required_score) {
return METRIC_ACTION_REJECT;
@@ -872,7 +986,7 @@ check_metric_action (double score, double required_score, struct metric *metric)
return METRIC_ACTION_NOACTION;
}
else {
- for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
+ for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) {
action = &metric->actions[i];
if (action->score < 0) {
continue;
@@ -894,24 +1008,26 @@ check_metric_action (double score, double required_score, struct metric *metric)
gboolean
learn_task (const gchar *statfile, struct rspamd_task *task, GError **err)
{
- GList *cur, *ex;
- struct rspamd_classifier_config *cl;
- struct classifier_ctx *cls_ctx;
- gchar *s;
- f_str_t c;
- GTree *tokens = NULL;
- struct rspamd_statfile_config *st;
- stat_file_t *stf;
- gdouble sum;
- struct mime_text_part *part, *p1, *p2;
- gboolean is_utf = FALSE, is_twopart = FALSE;
- gint diff;
+ GList *cur, *ex;
+ struct rspamd_classifier_config *cl;
+ struct classifier_ctx *cls_ctx;
+ gchar *s;
+ f_str_t c;
+ GTree *tokens = NULL;
+ struct rspamd_statfile_config *st;
+ stat_file_t *stf;
+ gdouble sum;
+ struct mime_text_part *part, *p1, *p2;
+ gboolean is_utf = FALSE, is_twopart = FALSE;
+ gint diff;
/* Load classifier by symbol */
cl = g_hash_table_lookup (task->cfg->classifiers_symbols, statfile);
if (cl == NULL) {
- g_set_error (err, filter_error_quark(), 1, "Statfile %s is not configured in any classifier", statfile);
+ g_set_error (err,
+ filter_error_quark (), 1, "Statfile %s is not configured in any classifier",
+ statfile);
return FALSE;
}
@@ -919,7 +1035,8 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err)
if ((s = g_hash_table_lookup (cl->opts, "header")) != NULL) {
cur = message_get_header (task->task_pool, task->message, s, FALSE);
if (cur) {
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_list_free, cur);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t)g_list_free, cur);
}
}
else {
@@ -959,7 +1076,9 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err)
diff = fuzzy_compare_parts (p1, p2);
}
if (diff >= COMMON_PART_FACTOR) {
- msg_info ("message <%s> has two common text parts, ignore the last one", task->message_id);
+ msg_info (
+ "message <%s> has two common text parts, ignore the last one",
+ task->message_id);
break;
}
}
@@ -968,7 +1087,8 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err)
if (!cl->tokenizer->tokenize_func (
cl->tokenizer, task->task_pool,
&c, &tokens, FALSE, is_utf, ex)) {
- g_set_error (err, filter_error_quark(), 2, "Cannot tokenize message");
+ g_set_error (err,
+ filter_error_quark (), 2, "Cannot tokenize message");
return FALSE;
}
cur = g_list_next (cur);
@@ -976,8 +1096,10 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err)
/* Handle messages without text */
if (tokens == NULL) {
- g_set_error (err, filter_error_quark(), 3, "Cannot tokenize message, no text data");
- msg_info ("learn failed for message <%s>, no tokens to extract", task->message_id);
+ g_set_error (err,
+ filter_error_quark (), 3, "Cannot tokenize message, no text data");
+ msg_info ("learn failed for message <%s>, no tokens to extract",
+ task->message_id);
return FALSE;
}
@@ -986,7 +1108,7 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err)
/* Init classifier */
cls_ctx = cl->classifier->init_func (
- task->task_pool, cl);
+ task->task_pool, cl);
/* Get or create statfile */
stf = get_statfile_by_symbol (task->worker->srv->statfile_pool,
cl, statfile, &st, TRUE);
@@ -997,12 +1119,17 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err)
statfile, tokens, TRUE, &sum,
1.0, err)) {
if (*err) {
- msg_info ("learn failed for message <%s>, learn error: %s", task->message_id, (*err)->message);
+ msg_info ("learn failed for message <%s>, learn error: %s",
+ task->message_id,
+ (*err)->message);
return FALSE;
}
else {
- g_set_error (err, filter_error_quark(), 4, "Learn failed, unknown learn classifier error");
- msg_info ("learn failed for message <%s>, unknown learn error", task->message_id);
+ g_set_error (err,
+ filter_error_quark (), 4,
+ "Learn failed, unknown learn classifier error");
+ msg_info ("learn failed for message <%s>, unknown learn error",
+ task->message_id);
return FALSE;
}
}
@@ -1010,25 +1137,31 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err)
task->worker->srv->stat->messages_learned++;
maybe_write_binlog (cl, st, stf, tokens);
- msg_info ("learn success for message <%s>, for statfile: %s, sum weight: %.2f",
- task->message_id, statfile, sum);
+ msg_info (
+ "learn success for message <%s>, for statfile: %s, sum weight: %.2f",
+ task->message_id,
+ statfile,
+ sum);
statfile_pool_plan_invalidate (task->worker->srv->statfile_pool,
- DEFAULT_STATFILE_INVALIDATE_TIME,
- DEFAULT_STATFILE_INVALIDATE_JITTER);
+ DEFAULT_STATFILE_INVALIDATE_TIME,
+ DEFAULT_STATFILE_INVALIDATE_JITTER);
return TRUE;
}
gboolean
-learn_task_spam (struct rspamd_classifier_config *cl, struct rspamd_task *task, gboolean is_spam, GError **err)
+learn_task_spam (struct rspamd_classifier_config *cl,
+ struct rspamd_task *task,
+ gboolean is_spam,
+ GError **err)
{
- GList *cur, *ex;
- struct classifier_ctx *cls_ctx;
- f_str_t c;
- GTree *tokens = NULL;
- struct mime_text_part *part, *p1, *p2;
- gboolean is_utf = FALSE, is_twopart = FALSE;
- gint diff;
+ GList *cur, *ex;
+ struct classifier_ctx *cls_ctx;
+ f_str_t c;
+ GTree *tokens = NULL;
+ struct mime_text_part *part, *p1, *p2;
+ gboolean is_utf = FALSE, is_twopart = FALSE;
+ gint diff;
cur = g_list_first (task->text_parts);
if (cur != NULL && cur->next != NULL && cur->next->next == NULL) {
@@ -1061,7 +1194,9 @@ learn_task_spam (struct rspamd_classifier_config *cl, struct rspamd_task *task,
diff = fuzzy_compare_parts (p1, p2);
}
if (diff >= COMMON_PART_FACTOR) {
- msg_info ("message <%s> has two common text parts, ignore the last one", task->message_id);
+ msg_info (
+ "message <%s> has two common text parts, ignore the last one",
+ task->message_id);
break;
}
}
@@ -1069,7 +1204,8 @@ learn_task_spam (struct rspamd_classifier_config *cl, struct rspamd_task *task,
if (!cl->tokenizer->tokenize_func (
cl->tokenizer, task->task_pool,
&c, &tokens, FALSE, is_utf, ex)) {
- g_set_error (err, filter_error_quark(), 2, "Cannot tokenize message");
+ g_set_error (err,
+ filter_error_quark (), 2, "Cannot tokenize message");
return FALSE;
}
cur = g_list_next (cur);
@@ -1077,8 +1213,10 @@ learn_task_spam (struct rspamd_classifier_config *cl, struct rspamd_task *task,
/* Handle messages without text */
if (tokens == NULL) {
- g_set_error (err, filter_error_quark(), 3, "Cannot tokenize message, no text data");
- msg_info ("learn failed for message <%s>, no tokens to extract", task->message_id);
+ g_set_error (err,
+ filter_error_quark (), 3, "Cannot tokenize message, no text data");
+ msg_info ("learn failed for message <%s>, no tokens to extract",
+ task->message_id);
return FALSE;
}
@@ -1087,18 +1225,23 @@ learn_task_spam (struct rspamd_classifier_config *cl, struct rspamd_task *task,
/* Init classifier */
cls_ctx = cl->classifier->init_func (
- task->task_pool, cl);
+ task->task_pool, cl);
/* Learn */
if (!cl->classifier->learn_spam_func (
cls_ctx, task->worker->srv->statfile_pool,
tokens, task, is_spam, task->cfg->lua_state, err)) {
if (*err) {
- msg_info ("learn failed for message <%s>, learn error: %s", task->message_id, (*err)->message);
+ msg_info ("learn failed for message <%s>, learn error: %s",
+ task->message_id,
+ (*err)->message);
return FALSE;
}
else {
- g_set_error (err, filter_error_quark(), 4, "Learn failed, unknown learn classifier error");
- msg_info ("learn failed for message <%s>, unknown learn error", task->message_id);
+ g_set_error (err,
+ filter_error_quark (), 4,
+ "Learn failed, unknown learn classifier error");
+ msg_info ("learn failed for message <%s>, unknown learn error",
+ task->message_id);
return FALSE;
}
}
@@ -1106,14 +1249,14 @@ learn_task_spam (struct rspamd_classifier_config *cl, struct rspamd_task *task,
task->worker->srv->stat->messages_learned++;
msg_info ("learn success for message <%s>",
- task->message_id);
+ task->message_id);
statfile_pool_plan_invalidate (task->worker->srv->statfile_pool,
- DEFAULT_STATFILE_INVALIDATE_TIME,
- DEFAULT_STATFILE_INVALIDATE_JITTER);
+ DEFAULT_STATFILE_INVALIDATE_TIME,
+ DEFAULT_STATFILE_INVALIDATE_JITTER);
return TRUE;
}
-/*
- * vi:ts=4
+/*
+ * vi:ts=4
*/
diff --git a/src/libmime/filter.h b/src/libmime/filter.h
index 2891ebd00..f0a343483 100644
--- a/src/libmime/filter.h
+++ b/src/libmime/filter.h
@@ -14,7 +14,8 @@ struct rspamd_task;
struct rspamd_settings;
struct rspamd_classifier_config;
-typedef double (*metric_cons_func)(struct rspamd_task *task, const gchar *metric_name, const gchar *func_name);
+typedef double (*metric_cons_func)(struct rspamd_task *task,
+ const gchar *metric_name, const gchar *func_name);
typedef void (*filter_func)(struct rspamd_task *task);
enum filter_type { C_FILTER, PERL_FILTER };
@@ -23,17 +24,17 @@ enum filter_type { C_FILTER, PERL_FILTER };
* Filter structure
*/
struct filter {
- gchar *func_name; /**< function name */
- enum filter_type type; /**< filter type (c or perl) */
- module_t *module;
+ gchar *func_name; /**< function name */
+ enum filter_type type; /**< filter type (c or perl) */
+ module_t *module;
};
/**
* Rspamd symbol
*/
struct symbol {
- double score; /**< symbol's score */
- GList *options; /**< list of symbol's options */
+ double score; /**< symbol's score */
+ GList *options; /**< list of symbol's options */
const gchar *name;
};
@@ -46,25 +47,25 @@ struct metric_action {
* Common definition of metric
*/
struct metric {
- const gchar *name; /**< name of metric */
- gchar *func_name; /**< name of consolidation function */
- metric_cons_func func; /**< c consolidation function */
- double grow_factor; /**< grow factor for metric */
- GHashTable *symbols; /**< weights of symbols in metric */
- GHashTable *descriptions; /**< descriptions of symbols in metric */
+ const gchar *name; /**< name of metric */
+ gchar *func_name; /**< name of consolidation function */
+ metric_cons_func func; /**< c consolidation function */
+ double grow_factor; /**< grow factor for metric */
+ GHashTable *symbols; /**< weights of symbols in metric */
+ GHashTable *descriptions; /**< descriptions of symbols in metric */
struct metric_action actions[METRIC_ACTION_MAX]; /**< all actions of the metric */
- gchar *subject; /**< subject rewrite string */
+ gchar *subject; /**< subject rewrite string */
};
/**
* Result of metric processing
*/
struct metric_result {
- struct metric *metric; /**< pointer to metric structure */
- double score; /**< total score */
- GHashTable *symbols; /**< symbols of metric */
- gboolean checked; /**< whether metric result is consolidated */
- double grow_factor; /**< current grow factor */
+ struct metric *metric; /**< pointer to metric structure */
+ double score; /**< total score */
+ GHashTable *symbols; /**< symbols of metric */
+ gboolean checked; /**< whether metric result is consolidated */
+ double grow_factor; /**< current grow factor */
};
/**
@@ -102,7 +103,10 @@ void process_statfiles_threaded (gpointer data, gpointer user_data);
* @param flag numeric weight for symbol
* @param opts list of symbol's options
*/
-void insert_result (struct rspamd_task *task, const gchar *symbol, double flag, GList *opts);
+void insert_result (struct rspamd_task *task,
+ const gchar *symbol,
+ double flag,
+ GList *opts);
/**
* Insert a single result to task
@@ -112,7 +116,10 @@ void insert_result (struct rspamd_task *task, const gchar *symbol, double flag,
* @param flag numeric weight for symbol
* @param opts list of symbol's options
*/
-void insert_result_single (struct rspamd_task *task, const gchar *symbol, double flag, GList *opts);
+void insert_result_single (struct rspamd_task *task,
+ const gchar *symbol,
+ double flag,
+ GList *opts);
/**
* Process all results and form composite metrics from existent metrics as it is defined in config
@@ -121,13 +128,15 @@ void insert_result_single (struct rspamd_task *task, const gchar *symbol, double
void make_composites (struct rspamd_task *task);
/**
- * Default consolidation function for metric, it get all symbols and multiply symbol
+ * Default consolidation function for metric, it get all symbols and multiply symbol
* weight by some factor that is specified in config. Default factor is 1.
* @param task worker's task that present message from user
* @param metric_name name of metric
* @return result metric weight
*/
-double factor_consolidation_func (struct rspamd_task *task, const gchar *metric_name, const gchar *unused);
+double factor_consolidation_func (struct rspamd_task *task,
+ const gchar *metric_name,
+ const gchar *unused);
/*
* Learn specified statfile with message in a task
@@ -136,7 +145,9 @@ double factor_consolidation_func (struct rspamd_task *task, const gchar *metric_
* @param err pointer to GError
* @return true if learn succeed
*/
-gboolean learn_task (const gchar *statfile, struct rspamd_task *task, GError **err);
+gboolean learn_task (const gchar *statfile,
+ struct rspamd_task *task,
+ GError **err);
/*
* Learn specified statfile with message in a task
@@ -145,7 +156,10 @@ gboolean learn_task (const gchar *statfile, struct rspamd_task *task, GError **e
* @param err pointer to GError
* @return true if learn succeed
*/
-gboolean learn_task_spam (struct rspamd_classifier_config *cl, struct rspamd_task *task, gboolean is_spam, GError **err);
+gboolean learn_task_spam (struct rspamd_classifier_config *cl,
+ struct rspamd_task *task,
+ gboolean is_spam,
+ GError **err);
/*
* Get action from a string
@@ -155,11 +169,13 @@ gboolean check_action_str (const gchar *data, gint *result);
/*
* Return textual representation of action enumeration
*/
-const gchar *str_action_metric (enum rspamd_metric_action action);
+const gchar * str_action_metric (enum rspamd_metric_action action);
/*
* Get action for specific metric
*/
-gint check_metric_action (double score, double required_score, struct metric *metric);
+gint check_metric_action (double score,
+ double required_score,
+ struct metric *metric);
#endif
diff --git a/src/libmime/images.c b/src/libmime/images.c
index ff07bbd72..3b2ceecd1 100644
--- a/src/libmime/images.c
+++ b/src/libmime/images.c
@@ -32,19 +32,20 @@ static const guint8 jpg_sig2[] = {'J', 'F', 'I', 'F'};
static const guint8 gif_signature[] = {'G', 'I', 'F', '8'};
static const guint8 bmp_signature[] = {'B', 'M'};
-static void process_image (struct rspamd_task *task, struct mime_part *part);
+static void process_image (struct rspamd_task *task, struct mime_part *part);
void
process_images (struct rspamd_task *task)
{
- GList *cur;
- struct mime_part *part;
+ GList *cur;
+ struct mime_part *part;
cur = task->parts;
while (cur) {
part = cur->data;
- if (g_mime_content_type_is_type (part->type, "image", "*") && part->content->len > 0) {
+ if (g_mime_content_type_is_type (part->type, "image",
+ "*") && part->content->len > 0) {
process_image (task, part);
}
cur = g_list_next (cur);
@@ -85,9 +86,9 @@ detect_image_type (GByteArray *data)
static struct rspamd_image *
process_png_image (struct rspamd_task *task, GByteArray *data)
{
- struct rspamd_image *img;
- guint32 t;
- guint8 *p;
+ struct rspamd_image *img;
+ guint32 t;
+ guint8 *p;
if (data->len < 24) {
msg_info ("bad png detected (maybe striped): <%s>", task->message_id);
@@ -119,10 +120,10 @@ process_png_image (struct rspamd_task *task, GByteArray *data)
static struct rspamd_image *
process_jpg_image (struct rspamd_task *task, GByteArray *data)
{
- guint8 *p;
- guint16 t;
- gsize remain;
- struct rspamd_image *img;
+ guint8 *p;
+ guint16 t;
+ gsize remain;
+ struct rspamd_image *img;
img = rspamd_mempool_alloc (task->task_pool, sizeof (struct rspamd_image));
img->type = IMAGE_TYPE_JPG;
@@ -131,15 +132,16 @@ process_jpg_image (struct rspamd_task *task, GByteArray *data)
p = data->data;
remain = data->len;
/* In jpeg we should find any data stream (ff c0 .. ff c3) and extract its height and width */
- while (remain --) {
- if (*p == 0xFF && remain > 8 && (*(p + 1) >= 0xC0 && *(p + 1) <= 0xC3)) {
+ while (remain--) {
+ if (*p == 0xFF && remain > 8 &&
+ (*(p + 1) >= 0xC0 && *(p + 1) <= 0xC3)) {
memcpy (&t, p + 5, sizeof (guint16));
img->height = ntohs (t);
memcpy (&t, p + 7, sizeof (guint16));
img->width = ntohs (t);
return img;
}
- p ++;
+ p++;
}
return NULL;
@@ -148,9 +150,9 @@ process_jpg_image (struct rspamd_task *task, GByteArray *data)
static struct rspamd_image *
process_gif_image (struct rspamd_task *task, GByteArray *data)
{
- struct rspamd_image *img;
- guint8 *p;
- guint16 t;
+ struct rspamd_image *img;
+ guint8 *p;
+ guint16 t;
if (data->len < 10) {
msg_info ("bad gif detected (maybe striped): <%s>", task->message_id);
@@ -162,7 +164,7 @@ process_gif_image (struct rspamd_task *task, GByteArray *data)
img->data = data;
p = data->data + 6;
- memcpy (&t, p, sizeof (guint16));
+ memcpy (&t, p, sizeof (guint16));
img->width = GUINT16_FROM_LE (t);
memcpy (&t, p + 2, sizeof (guint16));
img->height = GUINT16_FROM_LE (t);
@@ -173,9 +175,9 @@ process_gif_image (struct rspamd_task *task, GByteArray *data)
static struct rspamd_image *
process_bmp_image (struct rspamd_task *task, GByteArray *data)
{
- struct rspamd_image *img;
- gint32 t;
- guint8 *p;
+ struct rspamd_image *img;
+ gint32 t;
+ guint8 *p;
@@ -188,7 +190,7 @@ process_bmp_image (struct rspamd_task *task, GByteArray *data)
img->type = IMAGE_TYPE_BMP;
img->data = data;
p = data->data + 18;
- memcpy (&t, p, sizeof (gint32));
+ memcpy (&t, p, sizeof (gint32));
img->width = abs (GINT32_FROM_LE (t));
memcpy (&t, p + 4, sizeof (gint32));
img->height = abs (GINT32_FROM_LE (t));
@@ -199,8 +201,8 @@ process_bmp_image (struct rspamd_task *task, GByteArray *data)
static void
process_image (struct rspamd_task *task, struct mime_part *part)
{
- enum known_image_types type;
- struct rspamd_image *img = NULL;
+ enum known_image_types type;
+ struct rspamd_image *img = NULL;
if ((type = detect_image_type (part->content)) != IMAGE_TYPE_UNKNOWN) {
switch (type) {
case IMAGE_TYPE_PNG:
@@ -223,9 +225,9 @@ process_image (struct rspamd_task *task, struct mime_part *part)
if (img != NULL) {
debug_task ("detected %s image of size %ud x %ud in message <%s>",
- image_type_str (img->type),
- img->width, img->height,
- task->message_id);
+ image_type_str (img->type),
+ img->width, img->height,
+ task->message_id);
img->filename = part->filename;
task->images = g_list_prepend (task->images, img);
}
diff --git a/src/libmime/images.h b/src/libmime/images.h
index c43941ebc..5648f030f 100644
--- a/src/libmime/images.h
+++ b/src/libmime/images.h
@@ -28,6 +28,6 @@ void process_images (struct rspamd_task *task);
/*
* Get textual representation of an image's type
*/
-const gchar *image_type_str (enum known_image_types type);
+const gchar * image_type_str (enum known_image_types type);
#endif /* IMAGES_H_ */
diff --git a/src/libmime/message.c b/src/libmime/message.c
index 4567869e9..c6de73782 100644
--- a/src/libmime/message.c
+++ b/src/libmime/message.c
@@ -22,26 +22,30 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "util.h"
-#include "main.h"
-#include "message.h"
#include "cfg_file.h"
+#include "config.h"
#include "html.h"
#include "images.h"
+#include "main.h"
+#include "message.h"
+#include "util.h"
#define RECURSION_LIMIT 30
#define UTF8_CHARSET "UTF-8"
-GByteArray *
-strip_html_tags (struct rspamd_task *task, rspamd_mempool_t * pool, struct mime_text_part *part, GByteArray * src, gint *stateptr)
+GByteArray *
+strip_html_tags (struct rspamd_task *task,
+ rspamd_mempool_t * pool,
+ struct mime_text_part *part,
+ GByteArray * src,
+ gint *stateptr)
{
- uint8_t *p, *rp, *tbegin = NULL, *end, c, lc;
- gint br, i = 0, depth = 0, in_q = 0;
- gint state = 0;
- GByteArray *buf;
- GNode *level_ptr = NULL;
- gboolean erase = FALSE;
+ uint8_t *p, *rp, *tbegin = NULL, *end, c, lc;
+ gint br, i = 0, depth = 0, in_q = 0;
+ gint state = 0;
+ GByteArray *buf;
+ GNode *level_ptr = NULL;
+ gboolean erase = FALSE;
if (stateptr)
state = *stateptr;
@@ -71,11 +75,11 @@ strip_html_tags (struct rspamd_task *task, rspamd_mempool_t * pool, struct mime_
}
else if (state == 1) {
/* Opening bracket without closing one */
- p --;
+ p--;
while (g_ascii_isspace (*p) && p > src->data) {
- p --;
+ p--;
}
- p ++;
+ p++;
goto unbreak_tag;
}
break;
@@ -115,13 +119,19 @@ strip_html_tags (struct rspamd_task *task, rspamd_mempool_t * pool, struct mime_
}
unbreak_tag:
switch (state) {
- case 1: /* HTML/XML */
+ case 1: /* HTML/XML */
lc = '>';
in_q = state = 0;
- erase = !add_html_node (task, pool, part, tbegin, p - tbegin, end - tbegin, &level_ptr);
+ erase = !add_html_node (task,
+ pool,
+ part,
+ tbegin,
+ p - tbegin,
+ end - tbegin,
+ &level_ptr);
break;
- case 2: /* PHP */
+ case 2: /* PHP */
if (!br && lc != '\"' && *(p - 1) == '?') {
in_q = state = 0;
}
@@ -131,7 +141,7 @@ unbreak_tag:
in_q = state = 0;
break;
- case 4: /* JavaScript/CSS/etc... */
+ case 4: /* JavaScript/CSS/etc... */
if (p >= src->data + 2 && *(p - 1) == '-' && *(p - 2) == '-') {
in_q = state = 0;
}
@@ -158,7 +168,8 @@ unbreak_tag:
else if (state == 0 && !erase) {
*(rp++) = c;
}
- if (state && p != src->data && *(p - 1) != '\\' && (!in_q || *p == in_q)) {
+ if (state && p != src->data && *(p - 1) != '\\' &&
+ (!in_q || *p == in_q)) {
if (in_q) {
in_q = 0;
}
@@ -182,7 +193,8 @@ unbreak_tag:
break;
case '-':
- if (state == 3 && p >= src->data + 2 && *(p - 1) == '-' && *(p - 2) == '!') {
+ if (state == 3 && p >= src->data + 2 && *(p - 1) == '-' &&
+ *(p - 2) == '!') {
state = 4;
}
else {
@@ -204,11 +216,14 @@ unbreak_tag:
if (state == 3 && p > src->data + 6
&& g_ascii_tolower (*(p - 1)) == 'p'
&& g_ascii_tolower (*(p - 2)) == 'y'
- && g_ascii_tolower (*(p - 3)) == 't' && g_ascii_tolower (*(p - 4)) == 'c' && g_ascii_tolower (*(p - 5)) == 'o' && g_ascii_tolower (*(p - 6)) == 'd') {
+ && g_ascii_tolower (*(p - 3)) == 't' &&
+ g_ascii_tolower (*(p - 4)) == 'c' &&
+ g_ascii_tolower (*(p - 5)) == 'o' &&
+ g_ascii_tolower (*(p - 6)) == 'd') {
state = 1;
break;
}
- /* fall-through */
+ /* fall-through */
case 'l':
@@ -216,14 +231,15 @@ unbreak_tag:
* state == 2 (PHP). Switch back to HTML.
*/
- if (state == 2 && p > src->data + 2 && *(p - 1) == 'm' && *(p - 2) == 'x') {
+ if (state == 2 && p > src->data + 2 && *(p - 1) == 'm' &&
+ *(p - 2) == 'x') {
state = 1;
break;
}
- /* fall-through */
+ /* fall-through */
default:
- reg_char:
+reg_char:
if (state == 0 && !erase) {
*(rp++) = c;
}
@@ -252,9 +268,11 @@ unbreak_tag:
}
static void
-parse_qmail_recv (rspamd_mempool_t * pool, gchar *line, struct received_header *r)
+parse_qmail_recv (rspamd_mempool_t * pool,
+ gchar *line,
+ struct received_header *r)
{
- gchar *s, *p, t;
+ gchar *s, *p, t;
/* We are interested only with received from network headers */
if ((p = strstr (line, "from network")) == NULL) {
@@ -269,7 +287,7 @@ parse_qmail_recv (rspamd_mempool_t * pool, gchar *line, struct received_header *
/* format is ip/host */
s = p;
if (*p) {
- while (g_ascii_isdigit (*++p) || *p == '.');
+ while (g_ascii_isdigit (*++p) || *p == '.') ;
if (*p != '/') {
r->is_error = 1;
return;
@@ -280,7 +298,8 @@ parse_qmail_recv (rspamd_mempool_t * pool, gchar *line, struct received_header *
*p = '/';
/* Now try to parse hostname */
s = ++p;
- while (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') {
+ while (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p ==
+ '_') {
p++;
}
t = *p;
@@ -292,9 +311,11 @@ parse_qmail_recv (rspamd_mempool_t * pool, gchar *line, struct received_header *
}
static void
-parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header *r)
+parse_recv_header (rspamd_mempool_t * pool,
+ gchar *line,
+ struct received_header *r)
{
- gchar *p, *s, t, **res = NULL;
+ gchar *p, *s, t, **res = NULL;
enum {
RSPAMD_RECV_STATE_INIT = 0,
RSPAMD_RECV_STATE_FROM,
@@ -305,8 +326,8 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
RSPAMD_RECV_STATE_SKIP_SPACES,
RSPAMD_RECV_STATE_ERROR
} state = RSPAMD_RECV_STATE_INIT,
- next_state = RSPAMD_RECV_STATE_INIT;
- gboolean is_exim = FALSE;
+ next_state = RSPAMD_RECV_STATE_INIT;
+ gboolean is_exim = FALSE;
g_strstrip (line);
p = line;
@@ -314,16 +335,18 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
while (*p) {
switch (state) {
- /* Initial state, search for from */
+ /* Initial state, search for from */
case RSPAMD_RECV_STATE_INIT:
if (*p == 'f' || *p == 'F') {
- if (g_ascii_tolower (*++p) == 'r' && g_ascii_tolower (*++p) == 'o' && g_ascii_tolower (*++p) == 'm') {
+ if (g_ascii_tolower (*++p) == 'r' && g_ascii_tolower (*++p) ==
+ 'o' && g_ascii_tolower (*++p) == 'm') {
p++;
state = RSPAMD_RECV_STATE_SKIP_SPACES;
next_state = RSPAMD_RECV_STATE_FROM;
}
}
- else if (g_ascii_tolower (*p) == 'b' && g_ascii_tolower (*(p + 1)) == 'y') {
+ else if (g_ascii_tolower (*p) == 'b' &&
+ g_ascii_tolower (*(p + 1)) == 'y') {
state = RSPAMD_RECV_STATE_IP_BLOCK;
}
else {
@@ -332,7 +355,7 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
return;
}
break;
- /* Read hostname */
+ /* Read hostname */
case RSPAMD_RECV_STATE_FROM:
if (*p == '[') {
/* This should be IP address */
@@ -341,7 +364,8 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
next_state = RSPAMD_RECV_STATE_IP_BLOCK;
s = ++p;
}
- else if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') {
+ else if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p ==
+ '_') {
p++;
}
else {
@@ -353,10 +377,11 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
next_state = RSPAMD_RECV_STATE_IP_BLOCK;
}
break;
- /* Try to extract additional info */
+ /* Try to extract additional info */
case RSPAMD_RECV_STATE_IP_BLOCK:
/* Try to extract ip or () info or by */
- if (g_ascii_tolower (*p) == 'b' && g_ascii_tolower (*(p + 1)) == 'y') {
+ if (g_ascii_tolower (*p) == 'b' && g_ascii_tolower (*(p + 1)) ==
+ 'y') {
p += 2;
/* Skip spaces after by */
state = RSPAMD_RECV_STATE_SKIP_SPACES;
@@ -378,11 +403,11 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
p++;
}
break;
- /* We are in () block. Here can be found real hostname and real ip, this is written by some MTA */
+ /* We are in () block. Here can be found real hostname and real ip, this is written by some MTA */
case RSPAMD_RECV_STATE_BRACES_BLOCK:
/* End of block */
if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' ||
- *p == '_' || *p == ':') {
+ *p == '_' || *p == ':') {
p++;
}
else if (*p == '[') {
@@ -404,41 +429,45 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
next_state = RSPAMD_RECV_STATE_BRACES_BLOCK;
}
else if (p - s == 4 && memcmp (s, "helo=", 5) == 0) {
- p ++;
+ p++;
is_exim = TRUE;
- if (r->real_hostname == NULL && r->from_hostname != NULL) {
+ if (r->real_hostname == NULL && r->from_hostname !=
+ NULL) {
r->real_hostname = r->from_hostname;
}
s = p;
- while (*p != ')' && !g_ascii_isspace (*p) && *p != '\0') {
- p ++;
+ while (*p != ')' && !g_ascii_isspace (*p) && *p !=
+ '\0') {
+ p++;
}
if (p > s) {
- r->from_hostname = rspamd_mempool_alloc (pool, p - s + 1);
+ r->from_hostname = rspamd_mempool_alloc (pool,
+ p - s + 1);
rspamd_strlcpy (r->from_hostname, s, p - s + 1);
}
}
else if (p - s == 4 && memcmp (s, "port=", 5) == 0) {
- p ++;
+ p++;
is_exim = TRUE;
while (g_ascii_isdigit (*p)) {
- p ++;
+ p++;
}
state = RSPAMD_RECV_STATE_SKIP_SPACES;
next_state = RSPAMD_RECV_STATE_BRACES_BLOCK;
}
else if (*p == '=' && is_exim) {
/* Just skip unknown pairs */
- p ++;
- while (!g_ascii_isspace (*p) && *p != ')' && *p != '\0') {
- p ++;
+ p++;
+ while (!g_ascii_isspace (*p) && *p != ')' && *p !=
+ '\0') {
+ p++;
}
state = RSPAMD_RECV_STATE_SKIP_SPACES;
next_state = RSPAMD_RECV_STATE_BRACES_BLOCK;
}
else {
/* skip all */
- while (*p++ != ')' && *p != '\0');
+ while (*p++ != ')' && *p != '\0') ;
state = RSPAMD_RECV_STATE_IP_BLOCK;
}
}
@@ -457,13 +486,13 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
continue;
}
if (*p == ')') {
- p ++;
+ p++;
state = RSPAMD_RECV_STATE_SKIP_SPACES;
next_state = RSPAMD_RECV_STATE_IP_BLOCK;
}
}
else if (*p == ')') {
- p ++;
+ p++;
state = RSPAMD_RECV_STATE_SKIP_SPACES;
next_state = RSPAMD_RECV_STATE_IP_BLOCK;
}
@@ -473,11 +502,11 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
}
}
break;
- /* Got by word */
+ /* Got by word */
case RSPAMD_RECV_STATE_BY_BLOCK:
/* Here can be only hostname */
if ((g_ascii_isalnum (*p) || *p == '.' || *p == '-'
- || *p == '_') && p[1] != '\0') {
+ || *p == '_') && p[1] != '\0') {
p++;
}
else {
@@ -499,7 +528,8 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
}
else if (r->from_ip == NULL && r->real_ip != NULL) {
r->from_ip = r->real_ip;
- if (r->real_hostname == NULL && r->from_hostname != NULL) {
+ if (r->real_hostname == NULL && r->from_hostname !=
+ NULL) {
r->real_hostname = r->from_hostname;
}
}
@@ -508,10 +538,10 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
}
break;
- /* Extract ip */
+ /* Extract ip */
case RSPAMD_RECV_STATE_PARSE_IP:
while (g_ascii_isxdigit (*p) || *p == '.' || *p == ':') {
- p ++;
+ p++;
}
if (*p != ']') {
/* Not an ip in fact */
@@ -527,7 +557,7 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
}
break;
- /* Skip spaces */
+ /* Skip spaces */
case RSPAMD_RECV_STATE_SKIP_SPACES:
if (!g_ascii_isspace (*p)) {
state = next_state;
@@ -552,10 +582,10 @@ parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header
static void
process_raw_headers (struct rspamd_task *task)
{
- struct raw_header *new = NULL, *lp;
- gchar *p, *c, *tmp, *tp;
- gint state = 0, l, next_state = 100, err_state = 100, t_state;
- gboolean valid_folding = FALSE;
+ struct raw_header *new = NULL, *lp;
+ gchar *p, *c, *tmp, *tp;
+ gint state = 0, l, next_state = 100, err_state = 100, t_state;
+ gboolean valid_folding = FALSE;
p = task->raw_headers_str;
c = p;
@@ -577,13 +607,15 @@ process_raw_headers (struct rspamd_task *task)
case 1:
/* We got something like header's name */
if (*p == ':') {
- new = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct raw_header));
+ new =
+ rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct raw_header));
l = p - c;
tmp = rspamd_mempool_alloc (task->task_pool, l + 1);
rspamd_strlcpy (tmp, c, l + 1);
new->name = tmp;
new->empty_separator = TRUE;
- p ++;
+ p++;
state = 2;
c = p;
}
@@ -593,7 +625,7 @@ process_raw_headers (struct rspamd_task *task)
next_state = 0;
}
else {
- p ++;
+ p++;
}
break;
case 2:
@@ -601,11 +633,11 @@ process_raw_headers (struct rspamd_task *task)
if (*p == '\t') {
new->tab_separated = TRUE;
new->empty_separator = FALSE;
- p ++;
+ p++;
}
else if (*p == ' ') {
new->empty_separator = FALSE;
- p ++;
+ p++;
}
else if (*p == '\n' || *p == '\r') {
/* Process folding */
@@ -643,7 +675,7 @@ process_raw_headers (struct rspamd_task *task)
state = 4;
}
else {
- p ++;
+ p++;
}
break;
case 4:
@@ -652,16 +684,16 @@ process_raw_headers (struct rspamd_task *task)
tmp = rspamd_mempool_alloc (task->task_pool, l + 1);
tp = tmp;
t_state = 0;
- while (l --) {
+ while (l--) {
if (t_state == 0) {
/* Before folding */
if (*c == '\n' || *c == '\r') {
t_state = 1;
- c ++;
- *tp ++ = ' ';
+ c++;
+ *tp++ = ' ';
}
else {
- *tp ++ = *c ++;
+ *tp++ = *c++;
}
}
else if (t_state == 1) {
@@ -671,18 +703,19 @@ process_raw_headers (struct rspamd_task *task)
}
else {
t_state = 0;
- *tp ++ = *c ++;
+ *tp++ = *c++;
}
}
}
/* Strip last space that can be added by \r\n parsing */
if (*(tp - 1) == ' ') {
- tp --;
+ tp--;
}
*tp = '\0';
new->value = tmp;
new->next = NULL;
- if ((lp = g_hash_table_lookup (task->raw_headers, new->name)) != NULL) {
+ if ((lp =
+ g_hash_table_lookup (task->raw_headers, new->name)) != NULL) {
while (lp->next != NULL) {
lp = lp->next;
}
@@ -698,7 +731,8 @@ process_raw_headers (struct rspamd_task *task)
/* Header has only name, no value */
new->next = NULL;
new->value = "";
- if ((lp = g_hash_table_lookup (task->raw_headers, new->name)) != NULL) {
+ if ((lp =
+ g_hash_table_lookup (task->raw_headers, new->name)) != NULL) {
while (lp->next != NULL) {
lp = lp->next;
}
@@ -717,12 +751,12 @@ process_raw_headers (struct rspamd_task *task)
}
else {
if (*p == '\r' || *p == '\n') {
- p ++;
+ p++;
valid_folding = FALSE;
}
else if (*p == '\t' || *p == ' ') {
/* Valid folding */
- p ++;
+ p++;
valid_folding = TRUE;
}
else {
@@ -742,24 +776,24 @@ process_raw_headers (struct rspamd_task *task)
/* Fail state, skip line */
if (*p == '\r') {
if (*(p + 1) == '\n') {
- p ++;
+ p++;
}
- p ++;
+ p++;
state = next_state;
}
else if (*p == '\n') {
if (*(p + 1) == '\r') {
- p ++;
+ p++;
}
- p ++;
+ p++;
state = next_state;
}
else if (*(p + 1) == '\0') {
state = next_state;
- p ++;
+ p++;
}
else {
- p ++;
+ p++;
}
break;
}
@@ -769,45 +803,62 @@ process_raw_headers (struct rspamd_task *task)
static void
free_byte_array_callback (void *pointer)
{
- GByteArray *arr = (GByteArray *) pointer;
+ GByteArray *arr = (GByteArray *) pointer;
g_byte_array_free (arr, TRUE);
}
-static GByteArray *
-convert_text_to_utf (struct rspamd_task *task, GByteArray * part_content, GMimeContentType * type, struct mime_text_part *text_part)
+static GByteArray *
+convert_text_to_utf (struct rspamd_task *task,
+ GByteArray * part_content,
+ GMimeContentType * type,
+ struct mime_text_part *text_part)
{
- GError *err = NULL;
- gsize read_bytes, write_bytes;
- const gchar *charset;
- gchar *res_str;
- GByteArray *result_array;
+ GError *err = NULL;
+ gsize read_bytes, write_bytes;
+ const gchar *charset;
+ gchar *res_str;
+ GByteArray *result_array;
if (task->cfg->raw_mode) {
text_part->is_raw = TRUE;
return part_content;
}
- if ((charset = g_mime_content_type_get_parameter (type, "charset")) == NULL) {
+ if ((charset =
+ g_mime_content_type_get_parameter (type, "charset")) == NULL) {
text_part->is_raw = TRUE;
return part_content;
}
- if (g_ascii_strcasecmp (charset, "utf-8") == 0 || g_ascii_strcasecmp (charset, "utf8") == 0) {
+ if (g_ascii_strcasecmp (charset,
+ "utf-8") == 0 || g_ascii_strcasecmp (charset, "utf8") == 0) {
if (g_utf8_validate (part_content->data, part_content->len, NULL)) {
text_part->is_raw = FALSE;
text_part->is_utf = TRUE;
return part_content;
}
else {
- msg_info ("<%s>: contains invalid utf8 characters, assume it as raw", task->message_id);
+ msg_info (
+ "<%s>: contains invalid utf8 characters, assume it as raw",
+ task->message_id);
text_part->is_raw = TRUE;
return part_content;
}
}
- res_str = g_convert_with_fallback (part_content->data, part_content->len, UTF8_CHARSET, charset, NULL, &read_bytes, &write_bytes, &err);
+ res_str = g_convert_with_fallback (part_content->data,
+ part_content->len,
+ UTF8_CHARSET,
+ charset,
+ NULL,
+ &read_bytes,
+ &write_bytes,
+ &err);
if (res_str == NULL) {
- msg_warn ("<%s>: cannot convert from %s to utf8: %s", task->message_id, charset, err ? err->message : "unknown problem");
+ msg_warn ("<%s>: cannot convert from %s to utf8: %s",
+ task->message_id,
+ charset,
+ err ? err->message : "unknown problem");
text_part->is_raw = TRUE;
return part_content;
}
@@ -815,7 +866,9 @@ convert_text_to_utf (struct rspamd_task *task, GByteArray * part_content, GMimeC
result_array = rspamd_mempool_alloc (task->task_pool, sizeof (GByteArray));
result_array->data = res_str;
result_array->len = write_bytes;
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_free, res_str);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_free,
+ res_str);
text_part->is_raw = FALSE;
text_part->is_utf = TRUE;
@@ -823,31 +876,43 @@ convert_text_to_utf (struct rspamd_task *task, GByteArray * part_content, GMimeC
}
static void
-process_text_part (struct rspamd_task *task, GByteArray *part_content, GMimeContentType *type,
- GMimeObject *part, GMimeObject *parent, gboolean is_empty)
+process_text_part (struct rspamd_task *task,
+ GByteArray *part_content,
+ GMimeContentType *type,
+ GMimeObject *part,
+ GMimeObject *parent,
+ gboolean is_empty)
{
- struct mime_text_part *text_part;
- const gchar *cd;
+ struct mime_text_part *text_part;
+ const gchar *cd;
/* Skip attachements */
#ifndef GMIME24
cd = g_mime_part_get_content_disposition (GMIME_PART (part));
- if (cd && g_ascii_strcasecmp (cd, "attachment") == 0 && !task->cfg->check_text_attachements) {
+ if (cd &&
+ g_ascii_strcasecmp (cd,
+ "attachment") == 0 && !task->cfg->check_text_attachements) {
debug_task ("skip attachments for checking as text parts");
return;
}
#else
cd = g_mime_object_get_disposition (GMIME_OBJECT (part));
- if (cd && g_ascii_strcasecmp (cd, GMIME_DISPOSITION_ATTACHMENT) == 0 && !task->cfg->check_text_attachements) {
+ if (cd &&
+ g_ascii_strcasecmp (cd,
+ GMIME_DISPOSITION_ATTACHMENT) == 0 &&
+ !task->cfg->check_text_attachements) {
debug_task ("skip attachments for checking as text parts");
return;
}
#endif
- if (g_mime_content_type_is_type (type, "text", "html") || g_mime_content_type_is_type (type, "text", "xhtml")) {
+ if (g_mime_content_type_is_type (type, "text",
+ "html") || g_mime_content_type_is_type (type, "text", "xhtml")) {
debug_task ("got urls from text/html part");
- text_part = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct mime_text_part));
+ text_part =
+ rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct mime_text_part));
text_part->is_html = TRUE;
if (is_empty) {
text_part->is_empty = TRUE;
@@ -856,18 +921,26 @@ process_text_part (struct rspamd_task *task, GByteArray *part_content, GMimeCont
task->text_parts = g_list_prepend (task->text_parts, text_part);
return;
}
- text_part->orig = convert_text_to_utf (task, part_content, type, text_part);
+ text_part->orig = convert_text_to_utf (task,
+ part_content,
+ type,
+ text_part);
text_part->is_balanced = TRUE;
text_part->html_nodes = NULL;
text_part->parent = parent;
- text_part->content = strip_html_tags (task, task->task_pool, text_part, text_part->orig, NULL);
+ text_part->content = strip_html_tags (task,
+ task->task_pool,
+ text_part,
+ text_part->orig,
+ NULL);
if (text_part->html_nodes == NULL) {
url_parse_text (task->task_pool, task, text_part, FALSE);
}
else {
- decode_entitles (text_part->content->data, &text_part->content->len);
+ decode_entitles (text_part->content->data,
+ &text_part->content->len);
url_parse_text (task->task_pool, task, text_part, FALSE);
#if 0
url_parse_text (task->task_pool, task, text_part, TRUE);
@@ -875,13 +948,17 @@ process_text_part (struct rspamd_task *task, GByteArray *part_content, GMimeCont
}
fuzzy_init_part (text_part, task->task_pool, task->cfg->max_diff);
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) free_byte_array_callback, text_part->content);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) free_byte_array_callback,
+ text_part->content);
task->text_parts = g_list_prepend (task->text_parts, text_part);
}
else if (g_mime_content_type_is_type (type, "text", "*")) {
debug_task ("got urls from text/plain part");
- text_part = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct mime_text_part));
+ text_part =
+ rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct mime_text_part));
text_part->is_html = FALSE;
text_part->parent = parent;
if (is_empty) {
@@ -891,7 +968,10 @@ process_text_part (struct rspamd_task *task, GByteArray *part_content, GMimeCont
task->text_parts = g_list_prepend (task->text_parts, text_part);
return;
}
- text_part->orig = convert_text_to_utf (task, part_content, type, text_part);
+ text_part->orig = convert_text_to_utf (task,
+ part_content,
+ type,
+ text_part);
text_part->content = text_part->orig;
url_parse_text (task->task_pool, task, text_part, FALSE);
fuzzy_init_part (text_part, task->task_pool, task->cfg->max_diff);
@@ -901,18 +981,20 @@ process_text_part (struct rspamd_task *task, GByteArray *part_content, GMimeCont
#ifdef GMIME24
static void
-mime_foreach_callback (GMimeObject * parent, GMimeObject * part, gpointer user_data)
+mime_foreach_callback (GMimeObject * parent,
+ GMimeObject * part,
+ gpointer user_data)
#else
static void
mime_foreach_callback (GMimeObject * part, gpointer user_data)
#endif
{
- struct rspamd_task *task = (struct rspamd_task *)user_data;
- struct mime_part *mime_part;
- GMimeContentType *type;
- GMimeDataWrapper *wrapper;
- GMimeStream *part_stream;
- GByteArray *part_content;
+ struct rspamd_task *task = (struct rspamd_task *)user_data;
+ struct mime_part *mime_part;
+ GMimeContentType *type;
+ GMimeDataWrapper *wrapper;
+ GMimeStream *part_stream;
+ GByteArray *part_content;
task->parts_count++;
@@ -921,7 +1003,7 @@ mime_foreach_callback (GMimeObject * part, gpointer user_data)
/* find out what class 'part' is... */
if (GMIME_IS_MESSAGE_PART (part)) {
/* message/rfc822 or message/news */
- GMimeMessage *message;
+ GMimeMessage *message;
/* g_mime_message_foreach_part() won't descend into
child message parts, so if we want to count any
@@ -957,11 +1039,13 @@ mime_foreach_callback (GMimeObject * part, gpointer user_data)
else if (GMIME_IS_MULTIPART (part)) {
/* multipart/mixed, multipart/alternative, multipart/related, multipart/signed, multipart/encrypted, etc... */
task->parser_parent_part = part;
-#ifndef GMIME24
+#ifndef GMIME24
debug_task ("detected multipart part");
/* we'll get to finding out if this is a signed/encrypted multipart later... */
if (task->parser_recursion++ < RECURSION_LIMIT) {
- g_mime_multipart_foreach ((GMimeMultipart *) part, mime_foreach_callback, task);
+ g_mime_multipart_foreach ((GMimeMultipart *) part,
+ mime_foreach_callback,
+ task);
}
else {
msg_err ("endless recursion detected: %d", task->parser_recursion);
@@ -972,17 +1056,21 @@ mime_foreach_callback (GMimeObject * part, gpointer user_data)
else if (GMIME_IS_PART (part)) {
/* a normal leaf part, could be text/plain or image/jpeg etc */
#ifdef GMIME24
- type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT (part));
+ type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT (
+ part));
#else
- type = (GMimeContentType *) g_mime_part_get_content_type (GMIME_PART (part));
+ type =
+ (GMimeContentType *) g_mime_part_get_content_type (GMIME_PART (part));
#endif
if (type == NULL) {
msg_warn ("type of part is unknown, assume text/plain");
type = g_mime_content_type_new ("text", "plain");
#ifdef GMIME24
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_object_unref, type);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_object_unref, type);
#else
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_mime_content_type_destroy, type);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_mime_content_type_destroy, type);
#endif
}
wrapper = g_mime_part_get_content_object (GMIME_PART (part));
@@ -992,29 +1080,45 @@ mime_foreach_callback (GMimeObject * part, gpointer user_data)
if (wrapper != NULL) {
#endif
part_stream = g_mime_stream_mem_new ();
- if (g_mime_data_wrapper_write_to_stream (wrapper, part_stream) != -1) {
- g_mime_stream_mem_set_owner (GMIME_STREAM_MEM (part_stream), FALSE);
- part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM (part_stream));
+ if (g_mime_data_wrapper_write_to_stream (wrapper,
+ part_stream) != -1) {
+ g_mime_stream_mem_set_owner (GMIME_STREAM_MEM (
+ part_stream), FALSE);
+ part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM (
+ part_stream));
g_object_unref (part_stream);
- mime_part = rspamd_mempool_alloc (task->task_pool, sizeof (struct mime_part));
+ mime_part =
+ rspamd_mempool_alloc (task->task_pool,
+ sizeof (struct mime_part));
mime_part->type = type;
mime_part->content = part_content;
mime_part->parent = task->parser_parent_part;
- mime_part->filename = g_mime_part_get_filename (GMIME_PART (part));
- debug_task ("found part with content-type: %s/%s", type->type, type->subtype);
+ mime_part->filename = g_mime_part_get_filename (GMIME_PART (
+ part));
+ debug_task ("found part with content-type: %s/%s",
+ type->type,
+ type->subtype);
task->parts = g_list_prepend (task->parts, mime_part);
/* Skip empty parts */
- process_text_part (task, part_content, type, part, task->parser_parent_part, (part_content->len <= 0));
+ process_text_part (task,
+ part_content,
+ type,
+ part,
+ task->parser_parent_part,
+ (part_content->len <= 0));
}
else {
- msg_warn ("write to stream failed: %d, %s", errno, strerror (errno));
+ msg_warn ("write to stream failed: %d, %s", errno,
+ strerror (errno));
}
#ifndef GMIME24
g_object_unref (wrapper);
#endif
}
else {
- msg_warn ("cannot get wrapper for mime part, type of part: %s/%s", type->type, type->subtype);
+ msg_warn ("cannot get wrapper for mime part, type of part: %s/%s",
+ type->type,
+ type->subtype);
}
}
else {
@@ -1025,7 +1129,7 @@ mime_foreach_callback (GMimeObject * part, gpointer user_data)
static void
destroy_message (void *pointer)
{
- GMimeMessage *msg = pointer;
+ GMimeMessage *msg = pointer;
msg_debug ("freeing pointer %p", msg);
g_object_unref (msg);
@@ -1034,33 +1138,34 @@ destroy_message (void *pointer)
gint
process_message (struct rspamd_task *task)
{
- GMimeMessage *message;
- GMimeParser *parser;
- GMimeStream *stream;
- GByteArray *tmp;
- GList *first, *cur;
- GMimePart *part;
- GMimeDataWrapper *wrapper;
- struct received_header *recv;
- gchar *mid, *url_str, *p, *end, *url_end;
- struct uri *subject_url;
- gsize len;
- gint rc;
+ GMimeMessage *message;
+ GMimeParser *parser;
+ GMimeStream *stream;
+ GByteArray *tmp;
+ GList *first, *cur;
+ GMimePart *part;
+ GMimeDataWrapper *wrapper;
+ struct received_header *recv;
+ gchar *mid, *url_str, *p, *end, *url_end;
+ struct uri *subject_url;
+ gsize len;
+ gint rc;
tmp = rspamd_mempool_alloc (task->task_pool, sizeof (GByteArray));
tmp->data = task->msg->str;
tmp->len = task->msg->len;
stream = g_mime_stream_mem_new_with_byte_array (tmp);
- /*
- * This causes g_mime_stream not to free memory by itself as it is memory allocated by
- * pool allocator
- */
+ /*
+ * This causes g_mime_stream not to free memory by itself as it is memory allocated by
+ * pool allocator
+ */
g_mime_stream_mem_set_owner (GMIME_STREAM_MEM (stream), FALSE);
if (task->is_mime) {
- debug_task ("construct mime parser from string length %d", (gint)task->msg->len);
+ debug_task ("construct mime parser from string length %d",
+ (gint)task->msg->len);
/* create a new parser object to parse the stream */
parser = g_mime_parser_new_with_stream (stream);
g_object_unref (stream);
@@ -1074,7 +1179,8 @@ process_message (struct rspamd_task *task)
}
task->message = message;
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) destroy_message, task->message);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) destroy_message, task->message);
/* Save message id for future use */
task->message_id = g_mime_message_get_message_id (task->message);
@@ -1101,7 +1207,8 @@ process_message (struct rspamd_task *task)
}
#ifdef GMIME24
- task->raw_headers_str = g_mime_object_get_headers (GMIME_OBJECT (task->message));
+ task->raw_headers_str =
+ g_mime_object_get_headers (GMIME_OBJECT (task->message));
#else
task->raw_headers_str = g_mime_message_get_headers (task->message);
#endif
@@ -1109,10 +1216,13 @@ process_message (struct rspamd_task *task)
process_images (task);
/* Parse received headers */
- first = message_get_header (task->task_pool, message, "Received", FALSE);
+ first =
+ message_get_header (task->task_pool, message, "Received", FALSE);
cur = first;
while (cur) {
- recv = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct received_header));
+ recv =
+ rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct received_header));
parse_recv_header (task->task_pool, cur->data, recv);
task->received = g_list_prepend (task->received, recv);
cur = g_list_next (cur);
@@ -1122,16 +1232,21 @@ process_message (struct rspamd_task *task)
}
if (task->raw_headers_str) {
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_free, task->raw_headers_str);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_free, task->raw_headers_str);
process_raw_headers (task);
}
task->rcpts = g_mime_message_get_all_recipients (message);
if (task->rcpts) {
#ifdef GMIME24
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_object_unref, task->rcpts);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_object_unref,
+ task->rcpts);
#else
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) internet_address_list_destroy, task->rcpts);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) internet_address_list_destroy,
+ task->rcpts);
#endif
}
@@ -1149,26 +1264,33 @@ process_message (struct rspamd_task *task)
/* Construct part for it */
part = g_mime_part_new_with_type ("text", "html");
#ifdef GMIME24
- wrapper = g_mime_data_wrapper_new_with_stream (stream, GMIME_CONTENT_ENCODING_8BIT);
+ wrapper = g_mime_data_wrapper_new_with_stream (stream,
+ GMIME_CONTENT_ENCODING_8BIT);
#else
- wrapper = g_mime_data_wrapper_new_with_stream (stream, GMIME_PART_ENCODING_8BIT);
+ wrapper = g_mime_data_wrapper_new_with_stream (stream,
+ GMIME_PART_ENCODING_8BIT);
#endif
g_mime_part_set_content_object (part, wrapper);
g_mime_message_set_mime_part (task->message, GMIME_OBJECT (part));
/* Register destructors */
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_object_unref, wrapper);
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_object_unref, part);
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) destroy_message, task->message);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_object_unref, wrapper);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_object_unref, part);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) destroy_message, task->message);
/* Now parse in a normal way */
task->parser_recursion = 0;
#ifdef GMIME24
g_mime_message_foreach (task->message, mime_foreach_callback, task);
#else
- g_mime_message_foreach_part (task->message, mime_foreach_callback, task);
+ g_mime_message_foreach_part (task->message, mime_foreach_callback,
+ task);
#endif
/* Generate message ID */
mid = g_mime_utils_generate_message_id ("localhost.localdomain");
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_free, mid);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t) g_free, mid);
g_mime_message_set_message_id (task->message, mid);
task->message_id = mid;
task->queue_id = mid;
@@ -1182,7 +1304,10 @@ process_message (struct rspamd_task *task)
if (task->rcpt) {
cur = task->rcpt;
while (cur) {
- g_mime_message_add_recipient (task->message, GMIME_RECIPIENT_TYPE_TO, NULL, (gchar *)cur->data);
+ g_mime_message_add_recipient (task->message,
+ GMIME_RECIPIENT_TYPE_TO,
+ NULL,
+ (gchar *)cur->data);
cur = g_list_next (cur);
}
}
@@ -1198,22 +1323,29 @@ process_message (struct rspamd_task *task)
while (p < end) {
/* Search to the end of url */
- if (url_try_text (task->task_pool, p, end - p, NULL, &url_end, &url_str, FALSE)) {
+ if (url_try_text (task->task_pool, p, end - p, NULL, &url_end,
+ &url_str, FALSE)) {
if (url_str != NULL) {
- subject_url = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct uri));
+ subject_url = rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct uri));
if (subject_url != NULL) {
/* Try to parse url */
rc = parse_uri (subject_url, url_str, task->task_pool);
- if ((rc == URI_ERRNO_OK || rc == URI_ERRNO_NO_SLASHES || rc == URI_ERRNO_NO_HOST_SLASH) &&
- subject_url->hostlen > 0) {
+ if ((rc == URI_ERRNO_OK || rc == URI_ERRNO_NO_SLASHES ||
+ rc == URI_ERRNO_NO_HOST_SLASH) &&
+ subject_url->hostlen > 0) {
if (subject_url->protocol != PROTOCOL_MAILTO) {
if (!g_tree_lookup (task->urls, subject_url)) {
- g_tree_insert (task->urls, subject_url, subject_url);
+ g_tree_insert (task->urls,
+ subject_url,
+ subject_url);
}
}
}
else if (rc != URI_ERRNO_OK) {
- msg_info ("extract of url '%s' failed: %s", url_str, url_strerror (rc));
+ msg_info ("extract of url '%s' failed: %s",
+ url_str,
+ url_strerror (rc));
}
}
}
@@ -1231,15 +1363,15 @@ process_message (struct rspamd_task *task)
}
struct gmime_raw_header {
- struct raw_header *next;
- gchar *name;
- gchar *value;
+ struct raw_header *next;
+ gchar *name;
+ gchar *value;
};
typedef struct _GMimeHeader {
- GHashTable *hash;
- GHashTable *writers;
- struct raw_header *headers;
+ GHashTable *hash;
+ GHashTable *writers;
+ struct raw_header *headers;
} local_GMimeHeader;
@@ -1261,13 +1393,20 @@ enum {
*/
#ifndef GMIME24
static void
-header_iterate (rspamd_mempool_t * pool, struct gmime_raw_header *h, GList ** ret, const gchar *field, gboolean strong)
+header_iterate (rspamd_mempool_t * pool,
+ struct gmime_raw_header *h,
+ GList ** ret,
+ const gchar *field,
+ gboolean strong)
{
while (h) {
if (G_LIKELY (!strong)) {
- if (h->value && !g_ascii_strncasecmp (field, h->name, strlen (field))) {
+ if (h->value &&
+ !g_ascii_strncasecmp (field, h->name, strlen (field))) {
if (pool != NULL) {
- *ret = g_list_prepend (*ret, rspamd_mempool_strdup (pool, h->value));
+ *ret =
+ g_list_prepend (*ret,
+ rspamd_mempool_strdup (pool, h->value));
}
else {
*ret = g_list_prepend (*ret, g_strdup (h->value));
@@ -1277,7 +1416,9 @@ header_iterate (rspamd_mempool_t * pool, struct gmime_raw_header *h, GList ** re
else {
if (h->value && !strncmp (field, h->name, strlen (field))) {
if (pool != NULL) {
- *ret = g_list_prepend (*ret, rspamd_mempool_strdup (pool, h->value));
+ *ret =
+ g_list_prepend (*ret,
+ rspamd_mempool_strdup (pool, h->value));
}
else {
*ret = g_list_prepend (*ret, g_strdup (h->value));
@@ -1289,11 +1430,15 @@ header_iterate (rspamd_mempool_t * pool, struct gmime_raw_header *h, GList ** re
}
#else
static void
-header_iterate (rspamd_mempool_t * pool, GMimeHeaderList * ls, GList ** ret, const gchar *field, gboolean strong)
+header_iterate (rspamd_mempool_t * pool,
+ GMimeHeaderList * ls,
+ GList ** ret,
+ const gchar *field,
+ gboolean strong)
{
/* Use iterator in case of gmime 2.4 */
- GMimeHeaderIter *iter;
- const gchar *name;
+ GMimeHeaderIter *iter;
+ const gchar *name;
if (ls == NULL) {
*ret = NULL;
@@ -1301,27 +1446,38 @@ header_iterate (rspamd_mempool_t * pool, GMimeHeaderList * ls, GList ** ret, con
}
iter = g_mime_header_iter_new ();
- if (g_mime_header_list_get_iter (ls, iter) && g_mime_header_iter_first (iter)) {
+ if (g_mime_header_list_get_iter (ls,
+ iter) && g_mime_header_iter_first (iter)) {
/* Iterate throught headers */
while (g_mime_header_iter_is_valid (iter)) {
name = g_mime_header_iter_get_name (iter);
if (G_LIKELY (!strong)) {
if (!g_ascii_strncasecmp (field, name, strlen (name))) {
if (pool != NULL) {
- *ret = g_list_prepend (*ret, rspamd_mempool_strdup (pool, g_mime_header_iter_get_value (iter)));
+ *ret =
+ g_list_prepend (*ret,
+ rspamd_mempool_strdup (pool,
+ g_mime_header_iter_get_value (iter)));
}
else {
- *ret = g_list_prepend (*ret, g_strdup (g_mime_header_iter_get_value (iter)));
+ *ret =
+ g_list_prepend (*ret,
+ g_strdup (g_mime_header_iter_get_value (iter)));
}
}
}
else {
if (!strncmp (field, name, strlen (name))) {
if (pool != NULL) {
- *ret = g_list_prepend (*ret, rspamd_mempool_strdup (pool, g_mime_header_iter_get_value (iter)));
+ *ret =
+ g_list_prepend (*ret,
+ rspamd_mempool_strdup (pool,
+ g_mime_header_iter_get_value (iter)));
}
else {
- *ret = g_list_prepend (*ret, g_strdup (g_mime_header_iter_get_value (iter)));
+ *ret =
+ g_list_prepend (*ret,
+ g_strdup (g_mime_header_iter_get_value (iter)));
}
}
}
@@ -1336,12 +1492,12 @@ header_iterate (rspamd_mempool_t * pool, GMimeHeaderList * ls, GList ** ret, con
struct multipart_cb_data {
- GList *ret;
- rspamd_mempool_t *pool;
- const gchar *field;
- gboolean try_search;
- gboolean strong;
- gint rec;
+ GList *ret;
+ rspamd_mempool_t *pool;
+ const gchar *field;
+ gboolean try_search;
+ gboolean strong;
+ gint rec;
};
#define MAX_REC 10
@@ -1353,21 +1509,21 @@ multipart_iterate (GMimeObject * parent, GMimeObject * part, gpointer user_data)
multipart_iterate (GMimeObject * part, gpointer user_data)
#endif
{
- struct multipart_cb_data *data = user_data;
+ struct multipart_cb_data *data = user_data;
#ifndef GMIME24
- struct gmime_raw_header *h;
+ struct gmime_raw_header *h;
#endif
- GList *l = NULL;
+ GList *l = NULL;
if (data->try_search && part != NULL && GMIME_IS_PART (part)) {
#ifdef GMIME24
- GMimeHeaderList *ls;
+ GMimeHeaderList *ls;
ls = g_mime_object_get_header_list (GMIME_OBJECT (part));
header_iterate (data->pool, ls, &l, data->field, data->strong);
#else
h = (struct gmime_raw_header *)part->headers->headers;
- header_iterate (data->pool, h, &l, data->field, data->strong);
+ header_iterate (data->pool, h, &l, data->field, data->strong);
#endif
if (l == NULL) {
/* Header not found, abandon search results */
@@ -1382,21 +1538,26 @@ multipart_iterate (GMimeObject * part, gpointer user_data)
else if (data->try_search && GMIME_IS_MULTIPART (part)) {
/* Maybe endless recursion here ? */
if (data->rec++ < MAX_REC) {
- g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, data);
+ g_mime_multipart_foreach (GMIME_MULTIPART (
+ part), multipart_iterate, data);
}
else {
- msg_info ("maximum recurse limit is over, stop recursing, %d", data->rec);
+ msg_info ("maximum recurse limit is over, stop recursing, %d",
+ data->rec);
data->try_search = FALSE;
}
}
}
-static GList *
-local_message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const gchar *field, gboolean strong)
+static GList *
+local_message_get_header (rspamd_mempool_t * pool,
+ GMimeMessage * message,
+ const gchar *field,
+ gboolean strong)
{
- GList *gret = NULL;
- GMimeObject *part;
- struct multipart_cb_data cb = {
+ GList *gret = NULL;
+ GMimeObject *part;
+ struct multipart_cb_data cb = {
.try_search = TRUE,
.rec = 0,
.ret = NULL,
@@ -1406,7 +1567,7 @@ local_message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const
cb.strong = strong;
#ifndef GMIME24
- struct gmime_raw_header *h;
+ struct gmime_raw_header *h;
if (field == NULL) {
return NULL;
@@ -1418,14 +1579,18 @@ local_message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const
if (gret == NULL) {
/* Try to iterate with mime part headers */
- msg_debug ("iterate over headers of mime part to find header %s", field);
+ msg_debug ("iterate over headers of mime part to find header %s",
+ field);
part = g_mime_message_get_mime_part (message);
if (part) {
h = (struct gmime_raw_header *)part->headers->headers;
header_iterate (pool, h, &gret, field, strong);
if (gret == NULL && GMIME_IS_MULTIPART (part)) {
- msg_debug ("iterate over headers of each multipart's subparts %s", field);
- g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, &cb);
+ msg_debug (
+ "iterate over headers of each multipart's subparts %s",
+ field);
+ g_mime_multipart_foreach (GMIME_MULTIPART (
+ part), multipart_iterate, &cb);
if (cb.ret != NULL) {
gret = cb.ret;
}
@@ -1438,7 +1603,7 @@ local_message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const
return gret;
#else
- GMimeHeaderList *ls;
+ GMimeHeaderList *ls;
ls = g_mime_object_get_header_list (GMIME_OBJECT (message));
header_iterate (pool, ls, &gret, field, strong);
@@ -1449,7 +1614,8 @@ local_message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const
ls = g_mime_object_get_header_list (GMIME_OBJECT (part));
header_iterate (pool, ls, &gret, field, strong);
if (gret == NULL && GMIME_IS_MULTIPART (part)) {
- g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, &cb);
+ g_mime_multipart_foreach (GMIME_MULTIPART (
+ part), multipart_iterate, &cb);
if (cb.ret != NULL) {
gret = cb.ret;
}
@@ -1466,17 +1632,18 @@ local_message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const
}
/**
-* g_mime_message_set_date_from_string: Set the message sent-date
-* @message: MIME Message
-* @string: A string of date
-*
-* Set the sent-date on a MIME Message.
-**/
+ * g_mime_message_set_date_from_string: Set the message sent-date
+ * @message: MIME Message
+ * @string: A string of date
+ *
+ * Set the sent-date on a MIME Message.
+ **/
void
-local_mime_message_set_date_from_string (GMimeMessage * message, const gchar * string)
+local_mime_message_set_date_from_string (GMimeMessage * message,
+ const gchar * string)
{
- time_t date;
- gint offset = 0;
+ time_t date;
+ gint offset = 0;
date = g_mime_utils_header_decode_date (string, &offset);
g_mime_message_set_date (message, date, offset);
@@ -1485,14 +1652,14 @@ local_mime_message_set_date_from_string (GMimeMessage * message, const gchar * s
/*
* Replacements for standart gmime functions but converting adresses to IA
*/
-static const gchar *
+static const gchar *
local_message_get_sender (GMimeMessage * message)
{
- gchar *res;
- const gchar *from = g_mime_message_get_sender (message);
- InternetAddressList *ia;
+ gchar *res;
+ const gchar *from = g_mime_message_get_sender (message);
+ InternetAddressList *ia;
-#ifndef GMIME24
+#ifndef GMIME24
ia = internet_address_parse_string (from);
#else
ia = internet_address_list_parse_string (from);
@@ -1501,7 +1668,7 @@ local_message_get_sender (GMimeMessage * message)
return NULL;
}
res = internet_address_list_to_string (ia, FALSE);
-#ifndef GMIME24
+#ifndef GMIME24
internet_address_list_destroy (ia);
#else
g_object_unref (ia);
@@ -1510,14 +1677,14 @@ local_message_get_sender (GMimeMessage * message)
return res;
}
-static const gchar *
+static const gchar *
local_message_get_reply_to (GMimeMessage * message)
{
- gchar *res;
- const gchar *from = g_mime_message_get_reply_to (message);
- InternetAddressList *ia;
+ gchar *res;
+ const gchar *from = g_mime_message_get_reply_to (message);
+ InternetAddressList *ia;
-#ifndef GMIME24
+#ifndef GMIME24
ia = internet_address_parse_string (from);
#else
ia = internet_address_list_parse_string (from);
@@ -1526,7 +1693,7 @@ local_message_get_reply_to (GMimeMessage * message)
return NULL;
}
res = internet_address_list_to_string (ia, FALSE);
-#ifndef GMIME24
+#ifndef GMIME24
internet_address_list_destroy (ia);
#else
g_object_unref (ia);
@@ -1537,122 +1704,161 @@ local_message_get_reply_to (GMimeMessage * message)
#ifdef GMIME24
-# define ADD_RECIPIENT_TEMPLATE(type,def) \
-static void \
-local_message_add_recipients_from_string_##type (GMimeMessage *message, const gchar *string, const gchar *value) \
-{ \
- InternetAddressList *il, *new; \
- \
- il = g_mime_message_get_recipients (message, (def)); \
- new = internet_address_list_parse_string (string); \
- internet_address_list_append (il, new); \
-} \
-
-ADD_RECIPIENT_TEMPLATE (to, GMIME_RECIPIENT_TYPE_TO)
- ADD_RECIPIENT_TEMPLATE (cc, GMIME_RECIPIENT_TYPE_CC)
- ADD_RECIPIENT_TEMPLATE (bcc, GMIME_RECIPIENT_TYPE_BCC)
-# define GET_RECIPIENT_TEMPLATE(type,def) \
-static InternetAddressList* \
-local_message_get_recipients_##type (GMimeMessage *message, const gchar *unused) \
-{ \
- return g_mime_message_get_recipients (message, (def)); \
-}
- GET_RECIPIENT_TEMPLATE (to, GMIME_RECIPIENT_TYPE_TO)
- GET_RECIPIENT_TEMPLATE (cc, GMIME_RECIPIENT_TYPE_CC)
- GET_RECIPIENT_TEMPLATE (bcc, GMIME_RECIPIENT_TYPE_BCC)
+# define ADD_RECIPIENT_TEMPLATE(type,def) \
+ static void \
+ local_message_add_recipients_from_string_ ## type (GMimeMessage * message, \
+ const gchar * string, \
+ const gchar * value) \
+ { \
+ InternetAddressList *il, *new; \
+ \
+ il = g_mime_message_get_recipients (message, (def)); \
+ new = internet_address_list_parse_string (string); \
+ internet_address_list_append (il, new); \
+ } \
+
+ADD_RECIPIENT_TEMPLATE (to, GMIME_RECIPIENT_TYPE_TO)
+ADD_RECIPIENT_TEMPLATE (cc, GMIME_RECIPIENT_TYPE_CC)
+ADD_RECIPIENT_TEMPLATE (bcc, GMIME_RECIPIENT_TYPE_BCC)
+# define GET_RECIPIENT_TEMPLATE(type,def) \
+ static InternetAddressList * \
+ local_message_get_recipients_ ## type (GMimeMessage * message, \
+ const gchar * unused) \
+ { \
+ return g_mime_message_get_recipients (message, (def)); \
+ }
+GET_RECIPIENT_TEMPLATE (to, GMIME_RECIPIENT_TYPE_TO)
+GET_RECIPIENT_TEMPLATE (cc, GMIME_RECIPIENT_TYPE_CC)
+GET_RECIPIENT_TEMPLATE (bcc, GMIME_RECIPIENT_TYPE_BCC)
#endif
/* different declarations for different types of set and get functions */
- typedef const gchar *(*GetFunc) (GMimeMessage * message);
- typedef InternetAddressList *(*GetRcptFunc) (GMimeMessage * message, const gchar *type);
- typedef GList *(*GetListFunc) (rspamd_mempool_t * pool, GMimeMessage * message, const gchar *type, gboolean strong);
- typedef void (*SetFunc) (GMimeMessage * message, const gchar *value);
- typedef void (*SetListFunc) (GMimeMessage * message, const gchar *field, const gchar *value);
+typedef const gchar *(*GetFunc) (GMimeMessage * message);
+typedef InternetAddressList *(*GetRcptFunc) (GMimeMessage * message,
+ const gchar *type);
+typedef GList *(*GetListFunc) (rspamd_mempool_t * pool, GMimeMessage * message,
+ const gchar *type, gboolean strong);
+typedef void (*SetFunc) (GMimeMessage * message, const gchar *value);
+typedef void (*SetListFunc) (GMimeMessage * message, const gchar *field,
+ const gchar *value);
/** different types of functions
-*
-* FUNC_CHARPTR
-* - function with no arguments
-* - get returns gchar*
-*
-* FUNC_IA (from Internet Address)
-* - function with additional "field" argument from the fieldfunc table,
-* - get returns Glist*
-*
-* FUNC_LIST
-* - function with additional "field" argument (given arbitrary header field name)
-* - get returns Glist*
-**/
- enum {
- FUNC_CHARPTR = 0,
- FUNC_CHARFREEPTR,
- FUNC_IA,
- FUNC_LIST
- };
+ *
+ * FUNC_CHARPTR
+ * - function with no arguments
+ * - get returns gchar*
+ *
+ * FUNC_IA (from Internet Address)
+ * - function with additional "field" argument from the fieldfunc table,
+ * - get returns Glist*
+ *
+ * FUNC_LIST
+ * - function with additional "field" argument (given arbitrary header field name)
+ * - get returns Glist*
+ **/
+enum {
+ FUNC_CHARPTR = 0,
+ FUNC_CHARFREEPTR,
+ FUNC_IA,
+ FUNC_LIST
+};
/**
-* fieldfunc struct: structure of MIME fields and corresponding get and set
-* functions.
-**/
- static struct {
- gchar *name;
- GetFunc func;
- GetRcptFunc rcptfunc;
- GetListFunc getlistfunc;
- SetFunc setfunc;
- SetListFunc setlfunc;
- gint functype;
- } fieldfunc[] =
+ * fieldfunc struct: structure of MIME fields and corresponding get and set
+ * functions.
+ **/
+static struct {
+ gchar *name;
+ GetFunc func;
+ GetRcptFunc rcptfunc;
+ GetListFunc getlistfunc;
+ SetFunc setfunc;
+ SetListFunc setlfunc;
+ gint functype;
+} fieldfunc[] =
{
{
- "From", local_message_get_sender, NULL, NULL, g_mime_message_set_sender, NULL, FUNC_CHARFREEPTR}, {
- "Reply-To", local_message_get_reply_to, NULL, NULL, g_mime_message_set_reply_to, NULL, FUNC_CHARFREEPTR},
+ "From", local_message_get_sender, NULL, NULL, g_mime_message_set_sender,
+ NULL, FUNC_CHARFREEPTR
+ }, {
+ "Reply-To", local_message_get_reply_to, NULL, NULL,
+ g_mime_message_set_reply_to, NULL, FUNC_CHARFREEPTR
+ },
#ifndef GMIME24
{
- "To", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA}, {
- "Cc", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA}, {
- "Bcc", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA}, {
- "Date", (GetFunc) g_mime_message_get_date_string, NULL, NULL, local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR},
+ "To", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL,
+ (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA
+ }, {
+ "Cc", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL,
+ (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA
+ }, {
+ "Bcc", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL,
+ (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA
+ }, {
+ "Date", (GetFunc) g_mime_message_get_date_string, NULL, NULL,
+ local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR
+ },
#else
{
- "To", NULL, local_message_get_recipients_to, NULL, NULL, local_message_add_recipients_from_string_to, FUNC_IA}, {
- "Cc", NULL, local_message_get_recipients_cc, NULL, NULL, local_message_add_recipients_from_string_cc, FUNC_IA}, {
- "Bcc", NULL, local_message_get_recipients_bcc, NULL, NULL, local_message_add_recipients_from_string_bcc, FUNC_IA}, {
- "Date", (GetFunc)g_mime_message_get_date_as_string, NULL, NULL, local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR},
+ "To", NULL, local_message_get_recipients_to, NULL, NULL,
+ local_message_add_recipients_from_string_to, FUNC_IA
+ }, {
+ "Cc", NULL, local_message_get_recipients_cc, NULL, NULL,
+ local_message_add_recipients_from_string_cc, FUNC_IA
+ }, {
+ "Bcc", NULL, local_message_get_recipients_bcc, NULL, NULL,
+ local_message_add_recipients_from_string_bcc, FUNC_IA
+ }, {
+ "Date", (GetFunc)g_mime_message_get_date_as_string, NULL, NULL,
+ local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR
+ },
#endif
{
- "Subject", g_mime_message_get_subject, NULL, NULL, g_mime_message_set_subject, NULL, FUNC_CHARPTR}, {
- "Message-Id", g_mime_message_get_message_id, NULL, NULL, g_mime_message_set_message_id, NULL, FUNC_CHARPTR},
+ "Subject", g_mime_message_get_subject, NULL, NULL,
+ g_mime_message_set_subject, NULL, FUNC_CHARPTR
+ }, {
+ "Message-Id", g_mime_message_get_message_id, NULL, NULL,
+ g_mime_message_set_message_id, NULL, FUNC_CHARPTR
+ },
#ifndef GMIME24
{
- NULL, NULL, NULL, local_message_get_header, NULL, g_mime_message_add_header, FUNC_LIST}
+ NULL, NULL, NULL, local_message_get_header, NULL,
+ g_mime_message_add_header, FUNC_LIST
+ }
#else
{
- NULL, NULL, NULL, local_message_get_header, NULL, (SetListFunc)g_mime_object_append_header, FUNC_LIST}
+ NULL, NULL, NULL, local_message_get_header, NULL,
+ (SetListFunc)g_mime_object_append_header, FUNC_LIST
+ }
#endif
};
/**
-* message_set_header: set header of any type excluding special (Content- and MIME-Version:)
-**/
+ * message_set_header: set header of any type excluding special (Content- and MIME-Version:)
+ **/
void
-message_set_header (GMimeMessage * message, const gchar *field, const gchar *value)
+message_set_header (GMimeMessage * message,
+ const gchar *field,
+ const gchar *value)
{
- gint i;
+ gint i;
- if (!g_ascii_strcasecmp (field, "MIME-Version:") || !g_ascii_strncasecmp (field, "Content-", 8)) {
+ if (!g_ascii_strcasecmp (field,
+ "MIME-Version:") || !g_ascii_strncasecmp (field, "Content-", 8)) {
return;
}
for (i = 0; i <= HEADER_UNKNOWN; ++i) {
- if (!fieldfunc[i].name || !g_ascii_strncasecmp (field, fieldfunc[i].name, strlen (fieldfunc[i].name))) {
+ if (!fieldfunc[i].name ||
+ !g_ascii_strncasecmp (field, fieldfunc[i].name,
+ strlen (fieldfunc[i].name))) {
switch (fieldfunc[i].functype) {
case FUNC_CHARPTR:
- (*(fieldfunc[i].setfunc)) (message, value);
+ (*(fieldfunc[i].setfunc))(message, value);
break;
case FUNC_IA:
- (*(fieldfunc[i].setlfunc)) (message, fieldfunc[i].name, value);
+ (*(fieldfunc[i].setlfunc))(message, fieldfunc[i].name, value);
break;
case FUNC_LIST:
- (*(fieldfunc[i].setlfunc)) (message, field, value);
+ (*(fieldfunc[i].setlfunc))(message, field, value);
break;
}
break;
@@ -1662,37 +1868,45 @@ message_set_header (GMimeMessage * message, const gchar *field, const gchar *val
/**
-* message_get_header: returns the list of 'any header' values
-* (except of unsupported yet Content- and MIME-Version special headers)
-*
-* You should free the GList list by yourself.
-**/
-GList *
-message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const gchar *field, gboolean strong)
+ * message_get_header: returns the list of 'any header' values
+ * (except of unsupported yet Content- and MIME-Version special headers)
+ *
+ * You should free the GList list by yourself.
+ **/
+GList *
+message_get_header (rspamd_mempool_t * pool,
+ GMimeMessage * message,
+ const gchar *field,
+ gboolean strong)
{
- gint i;
- gchar *ret = NULL, *ia_string;
- GList *gret = NULL;
- InternetAddressList *ia_list = NULL, *ia;
+ gint i;
+ gchar *ret = NULL, *ia_string;
+ GList *gret = NULL;
+ InternetAddressList *ia_list = NULL, *ia;
for (i = 0; i <= HEADER_UNKNOWN; ++i) {
- if (!fieldfunc[i].name || !g_ascii_strncasecmp (field, fieldfunc[i].name, strlen (fieldfunc[i].name))) {
+ if (!fieldfunc[i].name ||
+ !g_ascii_strncasecmp (field, fieldfunc[i].name,
+ strlen (fieldfunc[i].name))) {
switch (fieldfunc[i].functype) {
case FUNC_CHARFREEPTR:
- ret = (gchar *)(*(fieldfunc[i].func)) (message);
+ ret = (gchar *)(*(fieldfunc[i].func))(message);
break;
case FUNC_CHARPTR:
- ret = (gchar *)(*(fieldfunc[i].func)) (message);
+ ret = (gchar *)(*(fieldfunc[i].func))(message);
break;
case FUNC_IA:
- ia_list = (*(fieldfunc[i].rcptfunc)) (message, field);
+ ia_list = (*(fieldfunc[i].rcptfunc))(message, field);
ia = ia_list;
#ifndef GMIME24
while (ia && ia->address) {
- ia_string = internet_address_to_string ((InternetAddress *) ia->address, FALSE);
+ ia_string = internet_address_to_string (
+ (InternetAddress *) ia->address,
+ FALSE);
if (pool != NULL) {
- rspamd_mempool_add_destructor (pool, (rspamd_mempool_destruct_t) g_free, ia_string);
+ rspamd_mempool_add_destructor (pool,
+ (rspamd_mempool_destruct_t) g_free, ia_string);
}
gret = g_list_prepend (gret, ia_string);
ia = ia->next;
@@ -1700,16 +1914,21 @@ message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const gchar
#else
i = internet_address_list_length (ia);
while (--i >= 0) {
- ia_string = internet_address_to_string (internet_address_list_get_address (ia, i), FALSE);
+ ia_string = internet_address_to_string (internet_address_list_get_address (
+ ia,
+ i),
+ FALSE);
if (pool != NULL) {
- rspamd_mempool_add_destructor (pool, (rspamd_mempool_destruct_t) g_free, ia_string);
+ rspamd_mempool_add_destructor (pool,
+ (rspamd_mempool_destruct_t) g_free, ia_string);
}
gret = g_list_prepend (gret, ia_string);
}
#endif
break;
case FUNC_LIST:
- gret = (*(fieldfunc[i].getlistfunc)) (pool, message, field, strong);
+ gret =
+ (*(fieldfunc[i].getlistfunc))(pool, message, field, strong);
break;
}
break;
@@ -1730,11 +1949,13 @@ message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const gchar
return gret;
}
-GList*
-message_get_raw_header (struct rspamd_task *task, const gchar *field, gboolean strong)
+GList *
+message_get_raw_header (struct rspamd_task *task,
+ const gchar *field,
+ gboolean strong)
{
- GList *gret = NULL;
- struct raw_header *rh;
+ GList *gret = NULL;
+ struct raw_header *rh;
rh = g_hash_table_lookup (task->raw_headers, field);
@@ -1757,7 +1978,8 @@ message_get_raw_header (struct rspamd_task *task, const gchar *field, gboolean s
}
if (gret != NULL) {
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_list_free, gret);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t)g_list_free, gret);
}
return gret;
diff --git a/src/libmime/message.h b/src/libmime/message.h
index 5e27579d1..fdb987c8c 100644
--- a/src/libmime/message.h
+++ b/src/libmime/message.h
@@ -30,7 +30,7 @@ struct mime_text_part {
GByteArray *orig;
GByteArray *content;
GNode *html_nodes;
- GList *urls_offset; /**< list of offsets of urls */
+ GList *urls_offset; /**< list of offsets of urls */
fuzzy_hash_t *fuzzy;
fuzzy_hash_t *double_fuzzy;
GMimeObject *parent;
@@ -57,7 +57,7 @@ struct raw_header {
};
/**
- * Process message with all filters/statfiles, extract mime parts, urls and
+ * Process message with all filters/statfiles, extract mime parts, urls and
* call metrics consolidation functions
* @param task worker_task object
* @return 0 if we have delayed filters to process and 1 if we have finished with processing
@@ -67,7 +67,9 @@ gint process_message (struct rspamd_task *task);
/*
* Set header with specified name and value
*/
-void message_set_header (GMimeMessage *message, const gchar *field, const gchar *value);
+void message_set_header (GMimeMessage *message,
+ const gchar *field,
+ const gchar *value);
/*
* Get a list of header's values with specified header's name
@@ -77,7 +79,10 @@ void message_set_header (GMimeMessage *message, const gchar *field, const gchar
* @param strong if this flag is TRUE header's name is case sensitive, otherwise it is not
* @return A list of header's values or NULL. If list is not NULL it MUST be freed. If pool is NULL elements must be freed as well.
*/
-GList* message_get_header (rspamd_mempool_t *pool, GMimeMessage *message, const gchar *field, gboolean strong);
+GList * message_get_header (rspamd_mempool_t *pool,
+ GMimeMessage *message,
+ const gchar *field,
+ gboolean strong);
/*
* Get a list of header's values with specified header's name using raw headers
@@ -86,6 +91,8 @@ GList* message_get_header (rspamd_mempool_t *pool, GMimeMessage *message, const
* @param strong if this flag is TRUE header's name is case sensitive, otherwise it is not
* @return A list of header's values or NULL. Unlike previous function it is NOT required to free list or values. I should rework one of these functions some time.
*/
-GList* message_get_raw_header (struct rspamd_task *task, const gchar *field, gboolean strong);
+GList * message_get_raw_header (struct rspamd_task *task,
+ const gchar *field,
+ gboolean strong);
#endif
diff --git a/src/libmime/smtp_proto.c b/src/libmime/smtp_proto.c
index 3af1c3910..3c8395784 100644
--- a/src/libmime/smtp_proto.c
+++ b/src/libmime/smtp_proto.c
@@ -22,21 +22,24 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "cfg_file.h"
#include "config.h"
#include "main.h"
-#include "cfg_file.h"
-#include "util.h"
#include "smtp.h"
#include "smtp_proto.h"
#include "smtp_utils.h"
+#include "util.h"
-gchar *
-make_smtp_error (rspamd_mempool_t *pool, gint error_code, const gchar *format, ...)
+gchar *
+make_smtp_error (rspamd_mempool_t *pool,
+ gint error_code,
+ const gchar *format,
+ ...)
{
- va_list vp;
- gchar *result = NULL, *p;
- size_t len;
-
+ va_list vp;
+ gchar *result = NULL, *p;
+ size_t len;
+
va_start (vp, format);
len = g_printf_string_upper_bound (format, vp);
va_end (vp);
@@ -53,7 +56,9 @@ make_smtp_error (rspamd_mempool_t *pool, gint error_code, const gchar *format, .
gboolean
-parse_smtp_command (struct smtp_session *session, f_str_t *line, struct smtp_command **cmd)
+parse_smtp_command (struct smtp_session *session,
+ f_str_t *line,
+ struct smtp_command **cmd)
{
enum {
SMTP_PARSE_START = 0,
@@ -61,11 +66,11 @@ parse_smtp_command (struct smtp_session *session, f_str_t *line, struct smtp_com
SMTP_PARSE_ARGUMENT,
SMTP_PARSE_DONE
} state;
- gchar *p, *c, ch, cmd_buf[4];
- guint i;
- f_str_t *arg = NULL;
- struct smtp_command *pcmd;
-
+ gchar *p, *c, ch, cmd_buf[4];
+ guint i;
+ f_str_t *arg = NULL;
+ struct smtp_command *pcmd;
+
if (line->len == 0) {
return FALSE;
}
@@ -76,125 +81,129 @@ parse_smtp_command (struct smtp_session *session, f_str_t *line, struct smtp_com
*cmd = rspamd_mempool_alloc0 (session->pool, sizeof (struct smtp_command));
pcmd = *cmd;
- for (i = 0; i < line->len; i ++, p ++) {
+ for (i = 0; i < line->len; i++, p++) {
ch = *p;
switch (state) {
- case SMTP_PARSE_START:
- if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i == line->len - 1) {
- if (i == line->len - 1) {
- p ++;
+ case SMTP_PARSE_START:
+ if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i ==
+ line->len - 1) {
+ if (i == line->len - 1) {
+ p++;
+ }
+ if (p - c == 4) {
+ cmd_buf[0] = g_ascii_toupper (c[0]);
+ cmd_buf[1] = g_ascii_toupper (c[1]);
+ cmd_buf[2] = g_ascii_toupper (c[2]);
+ cmd_buf[3] = g_ascii_toupper (c[3]);
+
+ if (memcmp (cmd_buf, "HELO", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_HELO;
}
- if (p - c == 4) {
- cmd_buf[0] = g_ascii_toupper (c[0]);
- cmd_buf[1] = g_ascii_toupper (c[1]);
- cmd_buf[2] = g_ascii_toupper (c[2]);
- cmd_buf[3] = g_ascii_toupper (c[3]);
-
- if (memcmp (cmd_buf, "HELO", 4) == 0) {
- pcmd->command = SMTP_COMMAND_HELO;
- }
- else if (memcmp (cmd_buf, "EHLO", 4) == 0) {
- pcmd->command = SMTP_COMMAND_EHLO;
- }
- else if (memcmp (cmd_buf, "MAIL", 4) == 0) {
- pcmd->command = SMTP_COMMAND_MAIL;
- }
- else if (memcmp (cmd_buf, "RCPT", 4) == 0) {
- pcmd->command = SMTP_COMMAND_RCPT;
- }
- else if (memcmp (cmd_buf, "DATA", 4) == 0) {
- pcmd->command = SMTP_COMMAND_DATA;
- }
- else if (memcmp (cmd_buf, "QUIT", 4) == 0) {
- pcmd->command = SMTP_COMMAND_QUIT;
- }
- else if (memcmp (cmd_buf, "NOOP", 4) == 0) {
- pcmd->command = SMTP_COMMAND_NOOP;
- }
- else if (memcmp (cmd_buf, "EXPN", 4) == 0) {
- pcmd->command = SMTP_COMMAND_EXPN;
- }
- else if (memcmp (cmd_buf, "RSET", 4) == 0) {
- pcmd->command = SMTP_COMMAND_RSET;
- }
- else if (memcmp (cmd_buf, "HELP", 4) == 0) {
- pcmd->command = SMTP_COMMAND_HELP;
- }
- else if (memcmp (cmd_buf, "VRFY", 4) == 0) {
- pcmd->command = SMTP_COMMAND_VRFY;
- }
- else {
- msg_info ("invalid command: %*s", 4, cmd_buf);
- return FALSE;
- }
+ else if (memcmp (cmd_buf, "EHLO", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_EHLO;
}
- else {
- /* Invalid command */
- msg_info ("invalid command: %*s", 4, c);
- return FALSE;
+ else if (memcmp (cmd_buf, "MAIL", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_MAIL;
}
- /* Now check what we have */
- if (ch == ' ' || ch == ':') {
- state = SMTP_PARSE_SPACES;
+ else if (memcmp (cmd_buf, "RCPT", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_RCPT;
}
- else if (ch == CR) {
- state = SMTP_PARSE_DONE;
+ else if (memcmp (cmd_buf, "DATA", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_DATA;
}
- else if (ch == LF) {
- return TRUE;
+ else if (memcmp (cmd_buf, "QUIT", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_QUIT;
+ }
+ else if (memcmp (cmd_buf, "NOOP", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_NOOP;
+ }
+ else if (memcmp (cmd_buf, "EXPN", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_EXPN;
+ }
+ else if (memcmp (cmd_buf, "RSET", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_RSET;
+ }
+ else if (memcmp (cmd_buf, "HELP", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_HELP;
+ }
+ else if (memcmp (cmd_buf, "VRFY", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_VRFY;
+ }
+ else {
+ msg_info ("invalid command: %*s", 4, cmd_buf);
+ return FALSE;
}
}
- else if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
- msg_info ("invalid letter code in SMTP command: %d", (gint)ch);
+ else {
+ /* Invalid command */
+ msg_info ("invalid command: %*s", 4, c);
return FALSE;
}
- break;
- case SMTP_PARSE_SPACES:
- if (ch == CR) {
+ /* Now check what we have */
+ if (ch == ' ' || ch == ':') {
+ state = SMTP_PARSE_SPACES;
+ }
+ else if (ch == CR) {
state = SMTP_PARSE_DONE;
}
else if (ch == LF) {
- goto end;
+ return TRUE;
}
- else if (ch != ' ' && ch != ':') {
- state = SMTP_PARSE_ARGUMENT;
- arg = rspamd_mempool_alloc (session->pool, sizeof (f_str_t));
- c = p;
- }
- break;
- case SMTP_PARSE_ARGUMENT:
- if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i == line->len - 1) {
- if (i == line->len - 1 && (ch != ' ' && ch != CR && ch != LF)) {
- p ++;
- }
- arg->len = p - c;
- arg->begin = rspamd_mempool_alloc (session->pool, arg->len);
- memcpy (arg->begin, c, arg->len);
- pcmd->args = g_list_prepend (pcmd->args, arg);
- if (ch == ' ' || ch == ':') {
- state = SMTP_PARSE_SPACES;
- }
- else if (ch == CR) {
- state = SMTP_PARSE_DONE;
- }
- else {
- goto end;
- }
+ }
+ else if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
+ msg_info ("invalid letter code in SMTP command: %d", (gint)ch);
+ return FALSE;
+ }
+ break;
+ case SMTP_PARSE_SPACES:
+ if (ch == CR) {
+ state = SMTP_PARSE_DONE;
+ }
+ else if (ch == LF) {
+ goto end;
+ }
+ else if (ch != ' ' && ch != ':') {
+ state = SMTP_PARSE_ARGUMENT;
+ arg = rspamd_mempool_alloc (session->pool, sizeof (f_str_t));
+ c = p;
+ }
+ break;
+ case SMTP_PARSE_ARGUMENT:
+ if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i ==
+ line->len - 1) {
+ if (i == line->len - 1 && (ch != ' ' && ch != CR && ch != LF)) {
+ p++;
+ }
+ arg->len = p - c;
+ arg->begin = rspamd_mempool_alloc (session->pool, arg->len);
+ memcpy (arg->begin, c, arg->len);
+ pcmd->args = g_list_prepend (pcmd->args, arg);
+ if (ch == ' ' || ch == ':') {
+ state = SMTP_PARSE_SPACES;
+ }
+ else if (ch == CR) {
+ state = SMTP_PARSE_DONE;
}
- break;
- case SMTP_PARSE_DONE:
- if (ch == LF) {
+ else {
goto end;
}
- msg_info ("CR without LF in SMTP command");
- return FALSE;
+ }
+ break;
+ case SMTP_PARSE_DONE:
+ if (ch == LF) {
+ goto end;
+ }
+ msg_info ("CR without LF in SMTP command");
+ return FALSE;
}
}
end:
if (pcmd->args) {
pcmd->args = g_list_reverse (pcmd->args);
- rspamd_mempool_add_destructor (session->pool, (rspamd_mempool_destruct_t)g_list_free, pcmd->args);
+ rspamd_mempool_add_destructor (session->pool,
+ (rspamd_mempool_destruct_t)g_list_free,
+ pcmd->args);
}
return TRUE;
}
@@ -202,14 +211,14 @@ end:
static gboolean
check_smtp_path (f_str_t *path)
{
- guint i;
- gchar *p;
+ guint i;
+ gchar *p;
p = path->begin;
if (*p != '<' || path->len < 2) {
return FALSE;
}
- for (i = 0; i < path->len; i++, p ++) {
+ for (i = 0; i < path->len; i++, p++) {
if (*p == '>' && i != path->len - 1) {
return FALSE;
}
@@ -221,7 +230,7 @@ check_smtp_path (f_str_t *path)
gboolean
parse_smtp_helo (struct smtp_session *session, struct smtp_command *cmd)
{
- f_str_t *arg;
+ f_str_t *arg;
if (cmd->args == NULL) {
session->error = SMTP_ERROR_BAD_ARGUMENTS;
@@ -256,8 +265,8 @@ parse_smtp_helo (struct smtp_session *session, struct smtp_command *cmd)
gboolean
parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd)
{
- f_str_t *arg;
- GList *cur = cmd->args;
+ f_str_t *arg;
+ GList *cur = cmd->args;
if (cmd->args == NULL) {
session->error = SMTP_ERROR_BAD_ARGUMENTS;
@@ -266,10 +275,10 @@ parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd)
arg = cur->data;
/* First argument MUST be FROM */
if (arg->len != 4 || (
- g_ascii_toupper (arg->begin[0]) != 'F' ||
- g_ascii_toupper (arg->begin[1]) != 'R' ||
- g_ascii_toupper (arg->begin[2]) != 'O' ||
- g_ascii_toupper (arg->begin[3]) != 'M')) {
+ g_ascii_toupper (arg->begin[0]) != 'F' ||
+ g_ascii_toupper (arg->begin[1]) != 'R' ||
+ g_ascii_toupper (arg->begin[2]) != 'O' ||
+ g_ascii_toupper (arg->begin[3]) != 'M')) {
session->error = SMTP_ERROR_BAD_ARGUMENTS;
return FALSE;
}
@@ -294,8 +303,8 @@ parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd)
gboolean
parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd)
{
- f_str_t *arg;
- GList *cur = cmd->args;
+ f_str_t *arg;
+ GList *cur = cmd->args;
if (cmd->args == NULL) {
session->error = SMTP_ERROR_BAD_ARGUMENTS;
@@ -304,8 +313,8 @@ parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd)
arg = cur->data;
/* First argument MUST be FROM */
if (arg->len != 2 || (
- g_ascii_toupper (arg->begin[0]) != 'T' ||
- g_ascii_toupper (arg->begin[1]) != 'O')) {
+ g_ascii_toupper (arg->begin[0]) != 'T' ||
+ g_ascii_toupper (arg->begin[1]) != 'O')) {
session->error = SMTP_ERROR_BAD_ARGUMENTS;
return FALSE;
}
@@ -332,7 +341,7 @@ parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd)
static gint
check_smtp_ustream_reply (f_str_t *in, gchar success_code)
{
- gchar *p;
+ gchar *p;
/* Check for 250 at the begin of line */
if (in->len >= sizeof ("220 ") - 1) {
@@ -357,13 +366,13 @@ check_smtp_ustream_reply (f_str_t *in, gchar success_code)
size_t
smtp_upstream_write_list (GList *args, gchar *buf, size_t buflen)
{
- GList *cur = args;
- size_t r = 0;
- f_str_t *arg;
+ GList *cur = args;
+ size_t r = 0;
+ f_str_t *arg;
while (cur && r < buflen - 3) {
arg = cur->data;
- r += rspamd_snprintf (buf + r, buflen - r, " %V", arg);
+ r += rspamd_snprintf (buf + r, buflen - r, " %V", arg);
cur = g_list_next (cur);
}
@@ -374,288 +383,351 @@ smtp_upstream_write_list (GList *args, gchar *buf, size_t buflen)
return r;
}
-gboolean
+gboolean
smtp_upstream_write_socket (void *arg)
{
- struct smtp_session *session = arg;
-
+ struct smtp_session *session = arg;
+
if (session->upstream_state == SMTP_STATE_IN_SENDFILE) {
session->upstream_state = SMTP_STATE_AFTER_DATA;
- return rspamd_dispatcher_write (session->upstream_dispatcher, CRLF DATA_END_TRAILER, sizeof (CRLF DATA_END_TRAILER) - 1, FALSE, TRUE);
+ return rspamd_dispatcher_write (session->upstream_dispatcher,
+ CRLF DATA_END_TRAILER,
+ sizeof (CRLF DATA_END_TRAILER) - 1,
+ FALSE,
+ TRUE);
}
return TRUE;
}
-gboolean
+gboolean
smtp_upstream_read_socket (f_str_t * in, void *arg)
{
- struct smtp_session *session = arg;
- gchar outbuf[BUFSIZ];
- gint r;
-
+ struct smtp_session *session = arg;
+ gchar outbuf[BUFSIZ];
+ gint r;
+
msg_debug ("in: %V, state: %d", in, session->upstream_state);
switch (session->upstream_state) {
- case SMTP_STATE_GREETING:
- r = check_smtp_ustream_reply (in, '2');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
- goto err;
- }
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- destroy_session (session->s);
- return FALSE;
+ case SMTP_STATE_GREETING:
+ r = check_smtp_ustream_reply (in, '2');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ in->len, FALSE, TRUE)) {
+ goto err;
}
- else if (r == 1) {
- if (session->ctx->use_xclient) {
- r = rspamd_snprintf (outbuf, sizeof (outbuf), "XCLIENT NAME=%s ADDR=%s" CRLF,
- session->resolved ? session->hostname : "[UNDEFINED]",
- inet_ntoa (session->client_addr));
- session->upstream_state = SMTP_STATE_HELO;
- return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
- }
- else {
- session->upstream_state = SMTP_STATE_FROM;
- if (session->helo) {
- r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF,
- session->esmtp ? "EHLO" : "HELO",
- session->helo);
- }
- else {
- return smtp_upstream_read_socket (in, arg);
- }
- return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
- }
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
+ sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
}
- break;
- case SMTP_STATE_HELO:
- r = check_smtp_ustream_reply (in, '2');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
- goto err;
- }
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- destroy_session (session->s);
- return FALSE;
+ destroy_session (session->s);
+ return FALSE;
+ }
+ else if (r == 1) {
+ if (session->ctx->use_xclient) {
+ r = rspamd_snprintf (outbuf,
+ sizeof (outbuf),
+ "XCLIENT NAME=%s ADDR=%s" CRLF,
+ session->resolved ? session->hostname : "[UNDEFINED]",
+ inet_ntoa (session->client_addr));
+ session->upstream_state = SMTP_STATE_HELO;
+ return rspamd_dispatcher_write (session->upstream_dispatcher,
+ outbuf,
+ r,
+ FALSE,
+ FALSE);
}
- else if (r == 1) {
+ else {
session->upstream_state = SMTP_STATE_FROM;
if (session->helo) {
- r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF,
- session->esmtp ? "EHLO" : "HELO",
- session->helo);
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF,
+ session->esmtp ? "EHLO" : "HELO",
+ session->helo);
}
else {
return smtp_upstream_read_socket (in, arg);
}
- return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
+ return rspamd_dispatcher_write (session->upstream_dispatcher,
+ outbuf,
+ r,
+ FALSE,
+ FALSE);
}
- break;
- case SMTP_STATE_FROM:
- r = check_smtp_ustream_reply (in, '2');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
- goto err;
- }
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- destroy_session (session->s);
- return FALSE;
+ }
+ break;
+ case SMTP_STATE_HELO:
+ r = check_smtp_ustream_reply (in, '2');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ in->len, FALSE, TRUE)) {
+ goto err;
}
- else if (r == 1) {
- r = rspamd_snprintf (outbuf, sizeof (outbuf), "MAIL FROM: ");
- r += smtp_upstream_write_list (session->from, outbuf + r, sizeof (outbuf) - r);
- session->upstream_state = SMTP_STATE_RCPT;
- return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
+ sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
}
- break;
- case SMTP_STATE_RCPT:
- r = check_smtp_ustream_reply (in, '2');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
- goto err;
- }
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- destroy_session (session->s);
- return FALSE;
+ destroy_session (session->s);
+ return FALSE;
+ }
+ else if (r == 1) {
+ session->upstream_state = SMTP_STATE_FROM;
+ if (session->helo) {
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF,
+ session->esmtp ? "EHLO" : "HELO",
+ session->helo);
}
- else if (r == 1) {
- r = rspamd_snprintf (outbuf, sizeof (outbuf), "RCPT TO: ");
- session->cur_rcpt = g_list_first (session->rcpt);
- r += smtp_upstream_write_list (session->cur_rcpt->data, outbuf + r, sizeof (outbuf) - r);
- session->cur_rcpt = g_list_next (session->cur_rcpt);
- session->upstream_state = SMTP_STATE_BEFORE_DATA;
- return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
+ else {
+ return smtp_upstream_read_socket (in, arg);
}
- break;
- case SMTP_STATE_BEFORE_DATA:
- r = check_smtp_ustream_reply (in, '2');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
- goto err;
- }
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- if (session->cur_rcpt) {
- session->rcpt = g_list_delete_link (session->rcpt, session->cur_rcpt);
- }
- else {
- session->rcpt = g_list_delete_link (session->rcpt, session->rcpt);
- }
- session->errors ++;
- session->state = SMTP_STATE_RCPT;
- return TRUE;
- }
- else if (r == 1) {
- if (session->cur_rcpt != NULL) {
- r = rspamd_snprintf (outbuf, sizeof (outbuf), "RCPT TO: ");
- r += smtp_upstream_write_list (session->cur_rcpt, outbuf + r, sizeof (outbuf) - r);
- session->cur_rcpt = g_list_next (session->cur_rcpt);
- if (! rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE)) {
- goto err;
- }
- }
- else {
- session->upstream_state = SMTP_STATE_DATA;
- rspamd_dispatcher_pause (session->upstream_dispatcher);
- }
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* Write to client */
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
- goto err;
- }
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- if (session->state == SMTP_STATE_WAIT_UPSTREAM) {
- rspamd_dispatcher_restore (session->dispatcher);
- session->state = SMTP_STATE_RCPT;
- }
+ return rspamd_dispatcher_write (session->upstream_dispatcher,
+ outbuf,
+ r,
+ FALSE,
+ FALSE);
+ }
+ break;
+ case SMTP_STATE_FROM:
+ r = check_smtp_ustream_reply (in, '2');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ in->len, FALSE, TRUE)) {
+ goto err;
}
- break;
- case SMTP_STATE_DATA:
- r = check_smtp_ustream_reply (in, '3');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
- goto err;
- }
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- destroy_session (session->s);
- return FALSE;
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
+ sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
}
- else if (r == 1) {
- if (! make_smtp_tempfile (session)) {
- session->error = SMTP_ERROR_FILE;
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
- goto err;
- }
- destroy_session (session->s);
- return FALSE;
- }
- session->state = SMTP_STATE_AFTER_DATA;
- session->error = SMTP_ERROR_DATA_OK;
- rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ destroy_session (session->s);
+ return FALSE;
+ }
+ else if (r == 1) {
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "MAIL FROM: ");
+ r +=
+ smtp_upstream_write_list (session->from,
+ outbuf + r,
+ sizeof (outbuf) - r);
+ session->upstream_state = SMTP_STATE_RCPT;
+ return rspamd_dispatcher_write (session->upstream_dispatcher,
+ outbuf,
+ r,
+ FALSE,
+ FALSE);
+ }
+ break;
+ case SMTP_STATE_RCPT:
+ r = check_smtp_ustream_reply (in, '2');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ in->len, FALSE, TRUE)) {
+ goto err;
+ }
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
+ sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ destroy_session (session->s);
+ return FALSE;
+ }
+ else if (r == 1) {
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "RCPT TO: ");
+ session->cur_rcpt = g_list_first (session->rcpt);
+ r += smtp_upstream_write_list (session->cur_rcpt->data,
+ outbuf + r,
+ sizeof (outbuf) - r);
+ session->cur_rcpt = g_list_next (session->cur_rcpt);
+ session->upstream_state = SMTP_STATE_BEFORE_DATA;
+ return rspamd_dispatcher_write (session->upstream_dispatcher,
+ outbuf,
+ r,
+ FALSE,
+ FALSE);
+ }
+ break;
+ case SMTP_STATE_BEFORE_DATA:
+ r = check_smtp_ustream_reply (in, '2');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ in->len, FALSE, TRUE)) {
+ goto err;
+ }
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
+ sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ if (session->cur_rcpt) {
+ session->rcpt = g_list_delete_link (session->rcpt,
+ session->cur_rcpt);
+ }
+ else {
+ session->rcpt =
+ g_list_delete_link (session->rcpt, session->rcpt);
+ }
+ session->errors++;
+ session->state = SMTP_STATE_RCPT;
+ return TRUE;
+ }
+ else if (r == 1) {
+ if (session->cur_rcpt != NULL) {
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "RCPT TO: ");
+ r += smtp_upstream_write_list (session->cur_rcpt,
+ outbuf + r,
+ sizeof (outbuf) - r);
+ session->cur_rcpt = g_list_next (session->cur_rcpt);
+ if (!rspamd_dispatcher_write (session->upstream_dispatcher,
+ outbuf, r, FALSE, FALSE)) {
goto err;
}
+ }
+ else {
+ session->upstream_state = SMTP_STATE_DATA;
rspamd_dispatcher_pause (session->upstream_dispatcher);
- rspamd_set_dispatcher_policy (session->dispatcher, BUFFER_LINE, 0);
- session->dispatcher->strip_eol = FALSE;
- return TRUE;
}
- break;
- case SMTP_STATE_AFTER_DATA:
session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
rspamd_strlcpy (session->error, in->begin, in->len + 1);
- session->state = SMTP_STATE_DATA;
- rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ /* Write to client */
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ in->len, FALSE, TRUE)) {
goto err;
}
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
+ sizeof (CRLF) - 1, FALSE, TRUE)) {
goto err;
}
- if (! rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, sizeof ("QUIT" CRLF) - 1, FALSE, TRUE)) {
+ if (session->state == SMTP_STATE_WAIT_UPSTREAM) {
+ rspamd_dispatcher_restore (session->dispatcher);
+ session->state = SMTP_STATE_RCPT;
+ }
+ }
+ break;
+ case SMTP_STATE_DATA:
+ r = check_smtp_ustream_reply (in, '3');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ 0, FALSE, TRUE)) {
goto err;
}
- session->upstream_state = SMTP_STATE_END;
- return TRUE;
- break;
- case SMTP_STATE_END:
- r = check_smtp_ustream_reply (in, '5');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
+ sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ destroy_session (session->s);
+ return FALSE;
+ }
+ else if (r == 1) {
+ if (!make_smtp_tempfile (session)) {
+ session->error = SMTP_ERROR_FILE;
session->state = SMTP_STATE_CRITICAL_ERROR;
rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
- goto err;
- }
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher,
+ session->error, 0, FALSE, TRUE)) {
goto err;
}
destroy_session (session->s);
return FALSE;
}
- else {
- remove_normal_event (session->s, (event_finalizer_t)smtp_upstream_finalize_connection, session);
+ session->state = SMTP_STATE_AFTER_DATA;
+ session->error = SMTP_ERROR_DATA_OK;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ 0, FALSE, TRUE)) {
+ goto err;
}
- return FALSE;
- break;
- default:
- msg_err ("got upstream reply at unexpected state: %d, reply: %V", session->upstream_state, in);
+ rspamd_dispatcher_pause (session->upstream_dispatcher);
+ rspamd_set_dispatcher_policy (session->dispatcher, BUFFER_LINE, 0);
+ session->dispatcher->strip_eol = FALSE;
+ return TRUE;
+ }
+ break;
+ case SMTP_STATE_AFTER_DATA:
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ session->state = SMTP_STATE_DATA;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0,
+ FALSE, TRUE)) {
+ goto err;
+ }
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) -
+ 1, FALSE, TRUE)) {
+ goto err;
+ }
+ if (!rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF,
+ sizeof ("QUIT" CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ session->upstream_state = SMTP_STATE_END;
+ return TRUE;
+ break;
+ case SMTP_STATE_END:
+ r = check_smtp_ustream_reply (in, '5');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
session->state = SMTP_STATE_CRITICAL_ERROR;
rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ 0, FALSE, TRUE)) {
goto err;
}
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
+ sizeof (CRLF) - 1, FALSE, TRUE)) {
goto err;
}
destroy_session (session->s);
return FALSE;
+ }
+ else {
+ remove_normal_event (session->s,
+ (event_finalizer_t)smtp_upstream_finalize_connection,
+ session);
+ }
+ return FALSE;
+ break;
+ default:
+ msg_err ("got upstream reply at unexpected state: %d, reply: %V",
+ session->upstream_state,
+ in);
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0,
+ FALSE, TRUE)) {
+ goto err;
+ }
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) -
+ 1, FALSE, TRUE)) {
+ goto err;
+ }
+ destroy_session (session->s);
+ return FALSE;
}
return TRUE;
@@ -664,20 +736,24 @@ err:
return FALSE;
}
-void
+void
smtp_upstream_err_socket (GError *err, void *arg)
{
- struct smtp_session *session = arg;
+ struct smtp_session *session = arg;
- msg_info ("abnormally closing connection with upstream %s, error: %s", session->upstream->name, err->message);
+ msg_info ("abnormally closing connection with upstream %s, error: %s",
+ session->upstream->name,
+ err->message);
session->error = SMTP_ERROR_UPSTREAM;
session->state = SMTP_STATE_CRITICAL_ERROR;
/* XXX: assume upstream errors as critical errors */
rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE,
+ TRUE)) {
return;
}
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1,
+ FALSE, TRUE)) {
return;
}
upstream_fail (&session->upstream->up, session->session_time);
@@ -687,10 +763,11 @@ smtp_upstream_err_socket (GError *err, void *arg)
void
smtp_upstream_finalize_connection (gpointer data)
{
- struct smtp_session *session = data;
-
+ struct smtp_session *session = data;
+
if (session->state != SMTP_STATE_CRITICAL_ERROR) {
- if (! rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF,
+ 0, FALSE, TRUE)) {
msg_warn ("cannot send correctly closing message to upstream");
}
}
diff --git a/src/libmime/smtp_proto.h b/src/libmime/smtp_proto.h
index 42fecd255..7c5787926 100644
--- a/src/libmime/smtp_proto.h
+++ b/src/libmime/smtp_proto.h
@@ -6,12 +6,14 @@
/* SMTP errors */
#define SMTP_ERROR_BAD_COMMAND "500 Syntax error, command unrecognized" CRLF
-#define SMTP_ERROR_BAD_ARGUMENTS "501 Syntax error in parameters or arguments" CRLF
+#define SMTP_ERROR_BAD_ARGUMENTS "501 Syntax error in parameters or arguments" \
+ CRLF
#define SMTP_ERROR_SEQUENCE "503 Bad sequence of commands" CRLF
#define SMTP_ERROR_RECIPIENTS "554 No valid recipients" CRLF
#define SMTP_ERROR_UNIMPLIMENTED "502 Command not implemented" CRLF
#define SMTP_ERROR_LIMIT "505 Too many errors. Aborting." CRLF
-#define SMTP_ERROR_UPSTREAM "421 Service not available, closing transmission channel" CRLF
+#define SMTP_ERROR_UPSTREAM \
+ "421 Service not available, closing transmission channel" CRLF
#define SMTP_ERROR_FILE "420 Service not available, filesystem error" CRLF
#define SMTP_ERROR_OK "250 Requested mail action okay, completed" CRLF
#define SMTP_ERROR_DATA_OK "354 Start mail input; end with <CRLF>.<CRLF>" CRLF
@@ -43,27 +45,35 @@ struct smtp_command {
/*
* Generate SMTP error message
*/
-gchar * make_smtp_error (rspamd_mempool_t *pool, gint error_code, const gchar *format, ...);
+gchar * make_smtp_error (rspamd_mempool_t *pool,
+ gint error_code,
+ const gchar *format,
+ ...);
/*
* Parse a single SMTP command
*/
-gboolean parse_smtp_command (struct smtp_session *session, f_str_t *line, struct smtp_command **cmd);
+gboolean parse_smtp_command (struct smtp_session *session,
+ f_str_t *line,
+ struct smtp_command **cmd);
/*
* Parse HELO command
*/
-gboolean parse_smtp_helo (struct smtp_session *session, struct smtp_command *cmd);
+gboolean parse_smtp_helo (struct smtp_session *session,
+ struct smtp_command *cmd);
/*
* Parse MAIL command
*/
-gboolean parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd);
+gboolean parse_smtp_from (struct smtp_session *session,
+ struct smtp_command *cmd);
/*
* Parse RCPT command
*/
-gboolean parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd);
+gboolean parse_smtp_rcpt (struct smtp_session *session,
+ struct smtp_command *cmd);
/* Upstream SMTP */
diff --git a/src/libmime/smtp_utils.c b/src/libmime/smtp_utils.c
index 8ed169fa7..a4fb4582e 100644
--- a/src/libmime/smtp_utils.c
+++ b/src/libmime/smtp_utils.c
@@ -22,15 +22,15 @@
*/
#include "config.h"
-#include "main.h"
#include "filter.h"
+#include "main.h"
#include "smtp.h"
#include "smtp_proto.h"
void
free_smtp_session (gpointer arg)
{
- struct smtp_session *session = arg;
+ struct smtp_session *session = arg;
if (session) {
if (session->task) {
@@ -60,12 +60,17 @@ free_smtp_session (gpointer arg)
gboolean
create_smtp_upstream_connection (struct smtp_session *session)
{
- struct smtp_upstream *selected;
+ struct smtp_upstream *selected;
/* Try to select upstream */
- selected = (struct smtp_upstream *)get_upstream_round_robin (session->ctx->upstreams,
- session->ctx->upstream_num, sizeof (struct smtp_upstream),
- session->session_time, DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS);
+ selected = (struct smtp_upstream *)get_upstream_round_robin (
+ session->ctx->upstreams,
+ session->ctx->upstream_num,
+ sizeof (struct smtp_upstream),
+ session->session_time,
+ DEFAULT_UPSTREAM_ERROR_TIME,
+ DEFAULT_UPSTREAM_DEAD_TIME,
+ DEFAULT_UPSTREAM_MAXERRORS);
if (selected == NULL) {
msg_err ("no upstreams suitable found");
return FALSE;
@@ -74,19 +79,32 @@ create_smtp_upstream_connection (struct smtp_session *session)
session->upstream = selected;
/* Now try to create socket */
- session->upstream_sock = make_universal_socket (selected->addr, selected->port, SOCK_STREAM, TRUE, FALSE, FALSE);
+ session->upstream_sock = make_universal_socket (selected->addr,
+ selected->port,
+ SOCK_STREAM,
+ TRUE,
+ FALSE,
+ FALSE);
if (session->upstream_sock == -1) {
msg_err ("cannot make a connection to %s", selected->name);
upstream_fail (&selected->up, session->session_time);
return FALSE;
}
/* Create a dispatcher for upstream connection */
- session->upstream_dispatcher = rspamd_create_dispatcher (session->ev_base, session->upstream_sock, BUFFER_LINE,
- smtp_upstream_read_socket, smtp_upstream_write_socket, smtp_upstream_err_socket,
- &session->ctx->smtp_timeout, session);
+ session->upstream_dispatcher = rspamd_create_dispatcher (session->ev_base,
+ session->upstream_sock,
+ BUFFER_LINE,
+ smtp_upstream_read_socket,
+ smtp_upstream_write_socket,
+ smtp_upstream_err_socket,
+ &session->ctx->smtp_timeout,
+ session);
session->state = SMTP_STATE_WAIT_UPSTREAM;
session->upstream_state = SMTP_STATE_GREETING;
- register_async_event (session->s, (event_finalizer_t)smtp_upstream_finalize_connection, session, g_quark_from_static_string ("smtp proxy"));
+ register_async_event (session->s,
+ (event_finalizer_t)smtp_upstream_finalize_connection,
+ session,
+ g_quark_from_static_string ("smtp proxy"));
return TRUE;
}
@@ -98,7 +116,8 @@ smtp_send_upstream_message (struct smtp_session *session)
session->upstream_state = SMTP_STATE_IN_SENDFILE;
session->state = SMTP_STATE_WAIT_UPSTREAM;
- if (! rspamd_dispatcher_sendfile (session->upstream_dispatcher, session->temp_fd, session->temp_size)) {
+ if (!rspamd_dispatcher_sendfile (session->upstream_dispatcher,
+ session->temp_fd, session->temp_size)) {
msg_err ("sendfile failed: %s", strerror (errno));
goto err;
}
@@ -107,7 +126,8 @@ smtp_send_upstream_message (struct smtp_session *session)
err:
session->error = SMTP_ERROR_FILE;
session->state = SMTP_STATE_CRITICAL_ERROR;
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE,
+ TRUE)) {
return FALSE;
}
destroy_session (session->s);
@@ -115,32 +135,35 @@ err:
}
struct smtp_metric_callback_data {
- struct smtp_session *session;
- enum rspamd_metric_action action;
- struct metric_result *res;
- gchar *log_buf;
- gint log_offset;
- gint log_size;
- gboolean alive;
+ struct smtp_session *session;
+ enum rspamd_metric_action action;
+ struct metric_result *res;
+ gchar *log_buf;
+ gint log_offset;
+ gint log_size;
+ gboolean alive;
};
static void
smtp_metric_symbols_callback (gpointer key, gpointer value, void *user_data)
{
- struct smtp_metric_callback_data *cd = user_data;
+ struct smtp_metric_callback_data *cd = user_data;
- cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "%s,", (gchar *)key);
+ cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
+ cd->log_size - cd->log_offset,
+ "%s,",
+ (gchar *)key);
}
static void
smtp_metric_callback (gpointer key, gpointer value, gpointer ud)
{
struct smtp_metric_callback_data *cd = ud;
- struct metric_result *metric_res = value;
- enum rspamd_metric_action action = METRIC_ACTION_NOACTION;
- double ms = 0, rs = 0;
- gboolean is_spam = FALSE;
- struct rspamd_task *task;
+ struct metric_result *metric_res = value;
+ enum rspamd_metric_action action = METRIC_ACTION_NOACTION;
+ double ms = 0, rs = 0;
+ gboolean is_spam = FALSE;
+ struct rspamd_task *task;
task = cd->session->task;
@@ -152,8 +175,10 @@ smtp_metric_callback (gpointer key, gpointer value, gpointer ud)
ms = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
rs = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
}
- if (! check_metric_action_settings (task, metric_res, metric_res->score, &action)) {
- action = check_metric_action (metric_res->score, ms, metric_res->metric);
+ if (!check_metric_action_settings (task, metric_res, metric_res->score,
+ &action)) {
+ action =
+ check_metric_action (metric_res->score, ms, metric_res->metric);
}
#endif
if (metric_res->score >= ms) {
@@ -165,42 +190,70 @@ smtp_metric_callback (gpointer key, gpointer value, gpointer ud)
}
if (!task->is_skipped) {
- cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "(%s: %c (%s): [%.2f/%.2f/%.2f] [",
- (gchar *)key, is_spam ? 'T' : 'F', str_action_metric (action), metric_res->score, ms, rs);
+ cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
+ cd->log_size - cd->log_offset,
+ "(%s: %c (%s): [%.2f/%.2f/%.2f] [",
+ (gchar *)key,
+ is_spam ? 'T' : 'F',
+ str_action_metric (action),
+ metric_res->score,
+ ms,
+ rs);
}
else {
- cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "(%s: %c (default): [%.2f/%.2f/%.2f] [",
- (gchar *)key, 'S', metric_res->score, ms, rs);
+ cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
+ cd->log_size - cd->log_offset,
+ "(%s: %c (default): [%.2f/%.2f/%.2f] [",
+ (gchar *)key,
+ 'S',
+ metric_res->score,
+ ms,
+ rs);
}
- g_hash_table_foreach (metric_res->symbols, smtp_metric_symbols_callback, cd);
+ g_hash_table_foreach (metric_res->symbols, smtp_metric_symbols_callback,
+ cd);
/* Remove last , from log buf */
if (cd->log_buf[cd->log_offset - 1] == ',') {
cd->log_buf[--cd->log_offset] = '\0';
}
#ifdef HAVE_CLOCK_GETTIME
- cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "]), len: %z, time: %s,",
- task->msg->len, calculate_check_time (&task->tv, &task->ts, task->cfg->clock_res, &task->scan_milliseconds));
+ cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
+ cd->log_size - cd->log_offset,
+ "]), len: %z, time: %s,",
+ task->msg->len,
+ calculate_check_time (&task->tv, &task->ts, task->cfg->clock_res,
+ &task->scan_milliseconds));
#else
- cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "]), len: %z, time: %s,",
- task->msg->len, calculate_check_time (&task->tv, task->cfg->clock_res, &task->scan_milliseconds));
+ cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
+ cd->log_size - cd->log_offset,
+ "]), len: %z, time: %s,",
+ task->msg->len,
+ calculate_check_time (&task->tv, task->cfg->clock_res,
+ &task->scan_milliseconds));
#endif
}
gboolean
make_smtp_tempfile (struct smtp_session *session)
{
- gsize r;
+ gsize r;
r = strlen (session->cfg->temp_dir) + sizeof ("/rspamd-XXXXXX");
session->temp_name = rspamd_mempool_alloc (session->pool, r);
- rspamd_snprintf (session->temp_name, r, "%s%crspamd-XXXXXX", session->cfg->temp_dir, G_DIR_SEPARATOR);
+ rspamd_snprintf (session->temp_name,
+ r,
+ "%s%crspamd-XXXXXX",
+ session->cfg->temp_dir,
+ G_DIR_SEPARATOR);
#ifdef HAVE_MKSTEMP
/* Umask is set before */
session->temp_fd = mkstemp (session->temp_name);
#else
- session->temp_fd = g_mkstemp_full (session->temp_name, O_RDWR, S_IWUSR | S_IRUSR);
+ session->temp_fd = g_mkstemp_full (session->temp_name,
+ O_RDWR,
+ S_IWUSR | S_IRUSR);
#endif
if (session->temp_fd == -1) {
msg_err ("mkstemp error: %s", strerror (errno));
@@ -214,23 +267,28 @@ make_smtp_tempfile (struct smtp_session *session)
gboolean
write_smtp_reply (struct smtp_session *session)
{
- gchar logbuf[1024], *new_subject;
- const gchar *old_subject;
+ gchar logbuf[1024], *new_subject;
+ const gchar *old_subject;
struct smtp_metric_callback_data cd;
- GMimeStream *stream;
- gint old_fd, sublen;
+ GMimeStream *stream;
+ gint old_fd, sublen;
/* Check metrics */
cd.session = session;
cd.action = METRIC_ACTION_NOACTION;
cd.res = NULL;
cd.log_buf = logbuf;
- cd.log_offset = rspamd_snprintf (logbuf, sizeof (logbuf), "id: <%s>, qid: <%s>, ",
- session->task->message_id, session->task->queue_id);
+ cd.log_offset = rspamd_snprintf (logbuf,
+ sizeof (logbuf),
+ "id: <%s>, qid: <%s>, ",
+ session->task->message_id,
+ session->task->queue_id);
cd.log_size = sizeof (logbuf);
if (session->task->user) {
- cd.log_offset += rspamd_snprintf (logbuf + cd.log_offset, sizeof (logbuf) - cd.log_offset,
- "user: %s, ", session->task->user);
+ cd.log_offset += rspamd_snprintf (logbuf + cd.log_offset,
+ sizeof (logbuf) - cd.log_offset,
+ "user: %s, ",
+ session->task->user);
}
g_hash_table_foreach (session->task->results, smtp_metric_callback, &cd);
@@ -238,22 +296,26 @@ write_smtp_reply (struct smtp_session *session)
msg_info ("%s", logbuf);
if (cd.action <= METRIC_ACTION_REJECT) {
- if (! rspamd_dispatcher_write (session->dispatcher, session->ctx->reject_message, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher,
+ session->ctx->reject_message, 0, FALSE, TRUE)) {
return FALSE;
}
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) -
+ 1, FALSE, TRUE)) {
return FALSE;
}
destroy_session (session->s);
return FALSE;
}
- else if (cd.action <= METRIC_ACTION_ADD_HEADER || cd.action <= METRIC_ACTION_REWRITE_SUBJECT) {
+ else if (cd.action <= METRIC_ACTION_ADD_HEADER || cd.action <=
+ METRIC_ACTION_REWRITE_SUBJECT) {
old_fd = session->temp_fd;
- if (! make_smtp_tempfile (session)) {
+ if (!make_smtp_tempfile (session)) {
session->error = SMTP_ERROR_FILE;
session->state = SMTP_STATE_CRITICAL_ERROR;
rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ 0, FALSE, TRUE)) {
goto err;
}
destroy_session (session->s);
@@ -266,7 +328,11 @@ write_smtp_reply (struct smtp_session *session)
if (old_subject != NULL) {
sublen = strlen (old_subject) + sizeof (SPAM_SUBJECT);
new_subject = rspamd_mempool_alloc (session->pool, sublen);
- rspamd_snprintf (new_subject, sublen, "%s%s", SPAM_SUBJECT, old_subject);
+ rspamd_snprintf (new_subject,
+ sublen,
+ "%s%s",
+ SPAM_SUBJECT,
+ old_subject);
}
else {
new_subject = SPAM_SUBJECT;
@@ -275,21 +341,26 @@ write_smtp_reply (struct smtp_session *session)
}
else if (cd.action <= METRIC_ACTION_ADD_HEADER) {
#ifndef GMIME24
- g_mime_message_add_header (session->task->message, "X-Spam", "true");
+ g_mime_message_add_header (session->task->message, "X-Spam",
+ "true");
#else
- g_mime_object_append_header (GMIME_OBJECT (session->task->message), "X-Spam", "true");
+ g_mime_object_append_header (GMIME_OBJECT (
+ session->task->message), "X-Spam", "true");
#endif
}
stream = g_mime_stream_fs_new (session->temp_fd);
g_mime_stream_fs_set_owner (GMIME_STREAM_FS (stream), FALSE);
close (old_fd);
- if (g_mime_object_write_to_stream (GMIME_OBJECT (session->task->message), stream) == -1) {
- msg_err ("cannot write MIME object to stream: %s", strerror (errno));
+ if (g_mime_object_write_to_stream (GMIME_OBJECT (session->task->message),
+ stream) == -1) {
+ msg_err ("cannot write MIME object to stream: %s",
+ strerror (errno));
session->error = SMTP_ERROR_FILE;
session->state = SMTP_STATE_CRITICAL_ERROR;
rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ 0, FALSE, TRUE)) {
goto err;
}
destroy_session (session->s);
@@ -302,7 +373,8 @@ write_smtp_reply (struct smtp_session *session)
err:
session->error = SMTP_ERROR_FILE;
session->state = SMTP_STATE_CRITICAL_ERROR;
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE,
+ TRUE)) {
return FALSE;
}
destroy_session (session->s);
@@ -310,29 +382,33 @@ err:
}
gboolean
-parse_upstreams_line (rspamd_mempool_t *pool, struct smtp_upstream *upstreams, const gchar *line, gsize *count)
+parse_upstreams_line (rspamd_mempool_t *pool,
+ struct smtp_upstream *upstreams,
+ const gchar *line,
+ gsize *count)
{
- gchar **strv, *p, *t, *tt, *err_str;
- guint32 num, i;
- struct smtp_upstream *cur;
- gchar resolved_path[PATH_MAX];
+ gchar **strv, *p, *t, *tt, *err_str;
+ guint32 num, i;
+ struct smtp_upstream *cur;
+ gchar resolved_path[PATH_MAX];
strv = g_strsplit_set (line, ",; ", -1);
num = g_strv_length (strv);
if (num >= MAX_SMTP_UPSTREAMS) {
- msg_err ("cannot define %d upstreams %d is max", num, MAX_SMTP_UPSTREAMS);
+ msg_err ("cannot define %d upstreams %d is max", num,
+ MAX_SMTP_UPSTREAMS);
return FALSE;
}
*count = 0;
- for (i = 0; i < num; i ++) {
+ for (i = 0; i < num; i++) {
p = strv[i];
cur = &upstreams[*count];
if ((t = strrchr (p, ':')) != NULL && (tt = strchr (p, ':')) != t) {
/* Assume that after last `:' we have weigth */
*t = '\0';
- t ++;
+ t++;
errno = 0;
cur->up.priority = strtoul (t, &err_str, 10);
if (errno != 0 || (err_str && *err_str != '\0')) {
@@ -349,15 +425,15 @@ parse_upstreams_line (rspamd_mempool_t *pool, struct smtp_upstream *upstreams, c
return FALSE;
}
cur->name = rspamd_mempool_strdup (pool, resolved_path);
- (*count) ++;
+ (*count)++;
}
else {
- if (! rspamd_parse_host_port (pool, p, &cur->addr, &cur->port)) {
+ if (!rspamd_parse_host_port (pool, p, &cur->addr, &cur->port)) {
g_strfreev (strv);
return FALSE;
}
cur->name = rspamd_mempool_strdup (pool, p);
- (*count) ++;
+ (*count)++;
}
}
diff --git a/src/libmime/smtp_utils.h b/src/libmime/smtp_utils.h
index 652b6759f..c09729180 100644
--- a/src/libmime/smtp_utils.h
+++ b/src/libmime/smtp_utils.h
@@ -58,6 +58,9 @@ void free_smtp_session (gpointer arg);
* @param count targeted count
* @return
*/
-gboolean parse_upstreams_line (rspamd_mempool_t *pool, struct smtp_upstream *upstreams, const gchar *line, gsize *count);
+gboolean parse_upstreams_line (rspamd_mempool_t *pool,
+ struct smtp_upstream *upstreams,
+ const gchar *line,
+ gsize *count);
#endif /* SMTP_UTILS_H_ */