]> source.dussan.org Git - rspamd.git/commitdiff
Separate librspamdserver API from plugins and workers functions.
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 1 Mar 2012 16:14:32 +0000 (20:14 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 1 Mar 2012 16:14:32 +0000 (20:14 +0400)
Make tests compileable again.

src/expressions.c
src/plugins/regexp.c
src/util.c
test/CMakeLists.txt
test/rspamd_dns_test.c
test/rspamd_fuzzy_test.c
test/rspamd_test_suite.c

index 488ea5600e6f4dcadff441f73a6170ae79ad8894..f552a5a779d32f79d990144e0f7f5899d782150c 100644 (file)
 
 gboolean                        rspamd_compare_encoding (struct worker_task *task, GList * args, void *unused);
 gboolean                        rspamd_header_exists (struct worker_task *task, GList * args, void *unused);
-gboolean                        rspamd_content_type_compare_param (struct worker_task *task, GList * args, void *unused);
-gboolean                        rspamd_content_type_has_param (struct worker_task *task, GList * args, void *unused);
-gboolean                        rspamd_content_type_is_subtype (struct worker_task *task, GList * args, void *unused);
-gboolean                        rspamd_content_type_is_type (struct worker_task *task, GList * args, void *unused);
 gboolean                        rspamd_parts_distance (struct worker_task *task, GList * args, void *unused);
 gboolean                        rspamd_recipients_distance (struct worker_task *task, GList * args, void *unused);
-gboolean                        rspamd_has_content_part (struct worker_task *task, GList * args, void *unused);
-gboolean                        rspamd_has_content_part_len (struct worker_task *task, GList * args, void *unused);
 gboolean                        rspamd_has_only_html_part (struct worker_task *task, GList * args, void *unused);
 gboolean                        rspamd_is_recipients_sorted (struct worker_task *task, GList * args, void *unused);
 gboolean                        rspamd_compare_transfer_encoding (struct worker_task *task, GList * args, void *unused);
@@ -63,12 +57,6 @@ static struct _fl {
        {"compare_parts_distance", rspamd_parts_distance, NULL},
        {"compare_recipients_distance", rspamd_recipients_distance, NULL},
        {"compare_transfer_encoding", rspamd_compare_transfer_encoding, NULL},
-       {"content_type_compare_param", rspamd_content_type_compare_param, NULL},
-       {"content_type_has_param", rspamd_content_type_has_param, NULL},
-       {"content_type_is_subtype", rspamd_content_type_is_subtype, NULL},
-       {"content_type_is_type", rspamd_content_type_is_type, NULL},
-       {"has_content_part", rspamd_has_content_part, NULL},
-       {"has_content_part_len", rspamd_has_content_part_len, NULL},
        {"has_fake_html", rspamd_has_fake_html, NULL},
        {"has_html_tag", rspamd_has_html_tag, NULL},
        {"has_only_html_part", rspamd_has_only_html_part, NULL},
@@ -800,13 +788,13 @@ gboolean
 call_expression_function (struct expression_function * func, struct worker_task * task)
 {
        struct _fl                     *selected, key;
-       gboolean                        res;
 
        key.name = func->name;
 
        selected = bsearch (&key, list_ptr, functions_number, sizeof (struct _fl), fl_cmp);
        if (selected == NULL) {
                /* Try to check lua function */
+#if 0
                if (! lua_call_expression_func (NULL, func->name, task, func->args, &res)) {
                        msg_warn ("call to undefined function %s", key.name);
                        return FALSE;
@@ -814,6 +802,9 @@ call_expression_function (struct expression_function * func, struct worker_task
                else {
                        return res;
                }
+#else
+               return FALSE;
+#endif
        }
 
        return selected->func (task, func->args, selected->user_data);
@@ -1106,384 +1097,6 @@ rspamd_parts_distance (struct worker_task * task, GList * args, void *unused)
        return FALSE;
 }
 
-gboolean
-rspamd_content_type_compare_param (struct worker_task * task, GList * args, void *unused)
-{
-       gchar                           *param_name, *param_pattern;
-       const gchar                     *param_data;
-       struct rspamd_regexp           *re;
-       struct expression_argument     *arg, *arg1;
-       GMimeObject                    *part;
-       GMimeContentType               *ct;
-       gint                            r;
-       gboolean                        recursive = FALSE, result = FALSE;
-       GList                          *cur = NULL;
-       struct mime_part               *cur_part;
-
-       if (args == NULL) {
-               msg_warn ("no parameters to function");
-               return FALSE;
-       }
-       arg = get_function_arg (args->data, task, TRUE);
-       param_name = arg->data;
-       args = g_list_next (args);
-       if (args == NULL) {
-               msg_warn ("too few params to function");
-               return FALSE;
-       }
-       arg = get_function_arg (args->data, task, TRUE);
-       param_pattern = arg->data;
-
-
-       part = g_mime_message_get_mime_part (task->message);
-       if (part) {
-               ct = (GMimeContentType *)g_mime_object_get_content_type (part);
-               if (args->next) {
-                       args = g_list_next (args);
-                       arg1 = get_function_arg (args->data, task, TRUE);
-                       if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
-                               recursive = TRUE;
-                       }
-               }
-               else {
-                       /*
-                        * If user did not specify argument, let's assume that he wants
-                        * recursive search if mime part is multipart/mixed
-                        */
-                       if (g_mime_content_type_is_type (ct, "multipart", "*")) {
-                               recursive = TRUE;
-                       }
-               }
-
-               if (recursive) {
-                       cur = task->parts;
-               }
-
-#ifndef GMIME24
-               g_object_unref (part);
-#endif
-               for (;;) {
-                       if ((param_data = g_mime_content_type_get_parameter ((GMimeContentType *)ct, param_name)) == NULL) {
-                               result = FALSE;
-                       }
-                       else {
-                               if (*param_pattern == '/') {
-                                       /* This is regexp, so compile and create g_regexp object */
-                                       if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
-                                               re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
-                                               if (re == NULL) {
-                                                       msg_warn ("cannot compile regexp for function");
-                                                       return FALSE;
-                                               }
-                                               re_cache_add (param_pattern, re, task->cfg->cfg_pool);
-                                       }
-                                       if ((r = task_cache_check (task, re)) == -1) {
-                                               if (g_regex_match (re->regexp, param_data, 0, NULL) == TRUE) {
-                                                       task_cache_add (task, re, 1);
-                                                       return TRUE;
-                                               }
-                                               task_cache_add (task, re, 0);
-                                       }
-                                       else {
-
-                                       }
-                               }
-                               else {
-                                       /* Just do strcasecmp */
-                                       if (g_ascii_strcasecmp (param_data, param_pattern) == 0) {
-                                               return TRUE;
-                                       }
-                               }
-                       }
-                       /* Get next part */
-                       if (! recursive) {
-                               return result;
-                       }
-                       else if (cur != NULL) {
-                               cur_part = cur->data;
-                               if (cur_part->type != NULL) {
-                                       ct = cur_part->type;
-                               }
-                               cur = g_list_next (cur);
-                       }
-                       else {
-                               /* All is done */
-                               return result;
-                       }
-               }
-
-       }
-
-       return FALSE;
-}
-
-gboolean
-rspamd_content_type_has_param (struct worker_task * task, GList * args, void *unused)
-{
-       gchar                           *param_name;
-       const gchar                     *param_data;
-       struct expression_argument     *arg, *arg1;
-       GMimeObject                    *part;
-       GMimeContentType               *ct;
-       gboolean                        recursive = FALSE, result = FALSE;
-       GList                          *cur = NULL;
-       struct mime_part               *cur_part;
-
-       if (args == NULL) {
-               msg_warn ("no parameters to function");
-               return FALSE;
-       }
-       arg = get_function_arg (args->data, task, TRUE);
-       param_name = arg->data;
-
-       part = g_mime_message_get_mime_part (task->message);
-       if (part) {
-               ct = (GMimeContentType *)g_mime_object_get_content_type (part);
-               if (args->next) {
-                       args = g_list_next (args);
-                       arg1 = get_function_arg (args->data, task, TRUE);
-                       if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
-                               recursive = TRUE;
-                       }
-               }
-               else {
-                       /*
-                        * If user did not specify argument, let's assume that he wants
-                        * recursive search if mime part is multipart/mixed
-                        */
-                       if (g_mime_content_type_is_type (ct, "multipart", "*")) {
-                               recursive = TRUE;
-                       }
-               }
-
-               if (recursive) {
-                       cur = task->parts;
-               }
-
-#ifndef GMIME24
-               g_object_unref (part);
-#endif
-               for (;;) {
-                       if ((param_data = g_mime_content_type_get_parameter ((GMimeContentType *)ct, param_name)) != NULL) {
-                               return TRUE;
-                       }
-                       /* Get next part */
-                       if (! recursive) {
-                               return result;
-                       }
-                       else if (cur != NULL) {
-                               cur_part = cur->data;
-                               if (cur_part->type != NULL) {
-                                       ct = cur_part->type;
-                               }
-                               cur = g_list_next (cur);
-                       }
-                       else {
-                               /* All is done */
-                               return result;
-                       }
-               }
-
-       }
-
-       return TRUE;
-}
-
-gboolean
-rspamd_content_type_is_subtype (struct worker_task *task, GList * args, void *unused)
-{
-       gchar                          *param_pattern;
-       struct rspamd_regexp           *re;
-       struct expression_argument     *arg, *arg1;
-       GMimeObject                    *part;
-       GMimeContentType               *ct;
-       gint                            r;
-       gboolean                        recursive = FALSE, result = FALSE;
-       GList                          *cur = NULL;
-       struct mime_part               *cur_part;
-
-       if (args == NULL) {
-               msg_warn ("no parameters to function");
-               return FALSE;
-       }
-       arg = get_function_arg (args->data, task, TRUE);
-       param_pattern = arg->data;
-
-       part = g_mime_message_get_mime_part (task->message);
-       if (part) {
-               ct = (GMimeContentType *)g_mime_object_get_content_type (part);
-               if (args->next) {
-                       args = g_list_next (args);
-                       arg1 = get_function_arg (args->data, task, TRUE);
-                       if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
-                               recursive = TRUE;
-                       }
-               }
-               else {
-                       /*
-                        * If user did not specify argument, let's assume that he wants
-                        * recursive search if mime part is multipart/mixed
-                        */
-                       if (g_mime_content_type_is_type (ct, "multipart", "*")) {
-                               recursive = TRUE;
-                       }
-               }
-
-               if (recursive) {
-                       cur = task->parts;
-               }
-
-#ifndef GMIME24
-               g_object_unref (part);
-#endif
-               for (;;) {
-                       if (*param_pattern == '/') {
-                               /* This is regexp, so compile and create g_regexp object */
-                               if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
-                                       re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
-                                       if (re == NULL) {
-                                               msg_warn ("cannot compile regexp for function");
-                                               return FALSE;
-                                       }
-                                       re_cache_add (param_pattern, re, task->cfg->cfg_pool);
-                               }
-                               if ((r = task_cache_check (task, re)) == -1) {
-                                       if (g_regex_match (re->regexp, ct->subtype, 0, NULL) == TRUE) {
-                                               task_cache_add (task, re, 1);
-                                               return TRUE;
-                                       }
-                                       task_cache_add (task, re, 0);
-                               }
-                               else {
-
-                               }
-                       }
-                       else {
-                               /* Just do strcasecmp */
-                               if (g_ascii_strcasecmp (ct->subtype, param_pattern) == 0) {
-                                       return TRUE;
-                               }
-                       }
-                       /* Get next part */
-                       if (! recursive) {
-                               return result;
-                       }
-                       else if (cur != NULL) {
-                               cur_part = cur->data;
-                               if (cur_part->type != NULL) {
-                                       ct = cur_part->type;
-                               }
-                               cur = g_list_next (cur);
-                       }
-                       else {
-                               /* All is done */
-                               return result;
-                       }
-               }
-
-       }
-
-       return FALSE;
-}
-
-gboolean
-rspamd_content_type_is_type (struct worker_task * task, GList * args, void *unused)
-{
-       gchar                          *param_pattern;
-       struct rspamd_regexp           *re;
-       struct expression_argument     *arg, *arg1;
-       GMimeObject                    *part;
-       GMimeContentType               *ct;
-       gint                            r;
-       gboolean                        recursive = FALSE, result = FALSE;
-       GList                          *cur = NULL;
-       struct mime_part               *cur_part;
-
-       if (args == NULL) {
-               msg_warn ("no parameters to function");
-               return FALSE;
-       }
-       arg = get_function_arg (args->data, task, TRUE);
-       param_pattern = arg->data;
-
-
-       part = g_mime_message_get_mime_part (task->message);
-       if (part) {
-               ct = (GMimeContentType *)g_mime_object_get_content_type (part);
-               if (args->next) {
-                       args = g_list_next (args);
-                       arg1 = get_function_arg (args->data, task, TRUE);
-                       if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
-                               recursive = TRUE;
-                       }
-               }
-               else {
-                       /*
-                        * If user did not specify argument, let's assume that he wants
-                        * recursive search if mime part is multipart/mixed
-                        */
-                       if (g_mime_content_type_is_type (ct, "multipart", "*")) {
-                               recursive = TRUE;
-                       }
-               }
-
-               if (recursive) {
-                       cur = task->parts;
-               }
-
-#ifndef GMIME24
-               g_object_unref (part);
-#endif
-               for (;;) {
-                       if (*param_pattern == '/') {
-                               /* This is regexp, so compile and create g_regexp object */
-                               if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
-                                       re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
-                                       if (re == NULL) {
-                                               msg_warn ("cannot compile regexp for function");
-                                               return FALSE;
-                                       }
-                                       re_cache_add (param_pattern, re, task->cfg->cfg_pool);
-                               }
-                               if ((r = task_cache_check (task, re)) == -1) {
-                                       if (g_regex_match (re->regexp, ct->type, 0, NULL) == TRUE) {
-                                               task_cache_add (task, re, 1);
-                                               return TRUE;
-                                       }
-                                       task_cache_add (task, re, 0);
-                               }
-                               else {
-
-                               }
-                       }
-                       else {
-                               /* Just do strcasecmp */
-                               if (g_ascii_strcasecmp (ct->type, param_pattern) == 0) {
-                                       return TRUE;
-                               }
-                       }
-                       /* Get next part */
-                       if (! recursive) {
-                               return result;
-                       }
-                       else if (cur != NULL) {
-                               cur_part = cur->data;
-                               if (cur_part->type != NULL) {
-                                       ct = cur_part->type;
-                               }
-                               cur = g_list_next (cur);
-                       }
-                       else {
-                               /* All is done */
-                               return result;
-                       }
-               }
-
-       }
-
-       return FALSE;
-}
-
 struct addr_list {
        const gchar                     *name;
        const gchar                     *addr;
@@ -1668,207 +1281,6 @@ rspamd_is_recipients_sorted (struct worker_task * task, GList * args, void *unus
        return FALSE;
 }
 
-static inline                   gboolean
-compare_subtype (struct worker_task *task, GMimeContentType * ct, gchar *subtype)
-{
-       struct rspamd_regexp           *re;
-       gint                            r;
-
-       if (*subtype == '/') {
-               /* This is regexp, so compile and create g_regexp object */
-               if ((re = re_cache_check (subtype, task->cfg->cfg_pool)) == NULL) {
-                       re = parse_regexp (task->cfg->cfg_pool, subtype, task->cfg->raw_mode);
-                       if (re == NULL) {
-                               msg_warn ("cannot compile regexp for function");
-                               return FALSE;
-                       }
-                       re_cache_add (subtype, re, task->cfg->cfg_pool);
-               }
-               if ((r = task_cache_check (task, re)) == -1) {
-                       if (g_regex_match (re->regexp, subtype, 0, NULL) == TRUE) {
-                               task_cache_add (task, re, 1);
-                               return TRUE;
-                       }
-                       task_cache_add (task, re, 0);
-               }
-               else {
-                       return r == 1;
-               }
-       }
-       else {
-               /* Just do strcasecmp */
-               if (ct->subtype && g_ascii_strcasecmp (ct->subtype, subtype) == 0) {
-                       return TRUE;
-               }
-       }
-
-       return FALSE;
-}
-
-static inline                   gboolean
-compare_len (struct mime_part *part, guint min, guint max)
-{
-       if (min == 0 && max == 0) {
-               return TRUE;
-       }
-
-       if (min == 0) {
-               return part->content->len <= max;
-       }
-       else if (max == 0) {
-               return part->content->len >= min;
-       }
-       else {
-               return part->content->len >= min && part->content->len <= max;
-       }
-}
-
-gboolean
-common_has_content_part (struct worker_task * task, gchar *param_type, gchar *param_subtype, gint min_len, gint max_len)
-{
-       struct rspamd_regexp           *re;
-       struct mime_part               *part;
-       GList                          *cur;
-       GMimeContentType               *ct;
-       gint                            r;
-
-       cur = g_list_first (task->parts);
-       while (cur) {
-               part = cur->data;
-               ct = part->type;
-               if (ct == NULL) {
-                       cur = g_list_next (cur);
-                       continue;
-               }
-
-               if (*param_type == '/') {
-                       /* This is regexp, so compile and create g_regexp object */
-                       if ((re = re_cache_check (param_type, task->cfg->cfg_pool)) == NULL) {
-                               re = parse_regexp (task->cfg->cfg_pool, param_type, task->cfg->raw_mode);
-                               if (re == NULL) {
-                                       msg_warn ("cannot compile regexp for function");
-                                       cur = g_list_next (cur);
-                                       continue;
-                               }
-                               re_cache_add (param_type, re, task->cfg->cfg_pool);
-                       }
-                       if ((r = task_cache_check (task, re)) == -1) {
-                               if (ct->type && g_regex_match (re->regexp, ct->type, 0, NULL) == TRUE) {
-                                       if (param_subtype) {
-                                               if (compare_subtype (task, ct, param_subtype)) {
-                                                       if (compare_len (part, min_len, max_len)) {
-                                                               return TRUE;
-                                                       }
-                                               }
-                                       }
-                                       else {
-                                               if (compare_len (part, min_len, max_len)) {
-                                                       return TRUE;
-                                               }
-                                       }
-                                       task_cache_add (task, re, 1);
-                               }
-                               else {
-                                       task_cache_add (task, re, 0);
-                               }
-                       }
-                       else {
-                               if (r == 1) {
-                                       if (compare_subtype (task, ct, param_subtype)) {
-                                               if (compare_len (part, min_len, max_len)) {
-                                                       return TRUE;
-                                               }
-                                       }
-                               }
-                       }
-               }
-               else {
-                       /* Just do strcasecmp */
-                       if (ct->type && g_ascii_strcasecmp (ct->type, param_type) == 0) {
-                               if (param_subtype) {
-                                       if (compare_subtype (task, ct, param_subtype)) {
-                                               if (compare_len (part, min_len, max_len)) {
-                                                       return TRUE;
-                                               }
-                                       }
-                               }
-                               else {
-                                       if (compare_len (part, min_len, max_len)) {
-                                               return TRUE;
-                                       }
-                               }
-                       }
-               }
-               cur = g_list_next (cur);
-       }
-
-       return FALSE;
-}
-
-gboolean
-rspamd_has_content_part (struct worker_task * task, GList * args, void *unused)
-{
-       gchar                           *param_type = NULL, *param_subtype = NULL;
-       struct expression_argument     *arg;
-
-       if (args == NULL) {
-               msg_warn ("no parameters to function");
-               return FALSE;
-       }
-
-       arg = get_function_arg (args->data, task, TRUE);
-       param_type = arg->data;
-       args = args->next;
-       if (args) {
-               arg = args->data;
-               param_subtype = arg->data;
-       }
-
-       return common_has_content_part (task, param_type, param_subtype, 0, 0);
-}
-
-gboolean
-rspamd_has_content_part_len (struct worker_task * task, GList * args, void *unused)
-{
-       gchar                           *param_type = NULL, *param_subtype = NULL;
-       gint                            min = 0, max = 0;
-       struct expression_argument     *arg;
-
-       if (args == NULL) {
-               msg_warn ("no parameters to function");
-               return FALSE;
-       }
-
-       arg = get_function_arg (args->data, task, TRUE);
-       param_type = arg->data;
-       args = args->next;
-       if (args) {
-               arg = get_function_arg (args->data, task, TRUE);
-               param_subtype = arg->data;
-               args = args->next;
-               if (args) {
-                       arg = get_function_arg (args->data, task, TRUE);
-                       errno = 0;
-                       min = strtoul (arg->data, NULL, 10);
-                       if (errno != 0) {
-                               msg_warn ("invalid numeric value '%s': %s", (gchar *)arg->data, strerror (errno));
-                               return FALSE;
-                       }
-                       args = args->next;
-                       if (args) {
-                               arg = get_function_arg (args->data, task, TRUE);
-                               max = strtoul (arg->data, NULL, 10);
-                               if (errno != 0) {
-                                       msg_warn ("invalid numeric value '%s': %s", (gchar *)arg->data, strerror (errno));
-                                       return FALSE;
-                               }
-                       }
-               }
-       }
-
-       return common_has_content_part (task, param_type, param_subtype, min, max);
-}
-
 gboolean
 rspamd_compare_transfer_encoding (struct worker_task * task, GList * args, void *unused)
 {
index 35be00bd78d05bc36cd11d6125bb0246fc13334d..5b1eefe4241f853c07afcea09aa5ddce54587fb8 100644 (file)
@@ -87,12 +87,19 @@ static struct regexp_ctx       *regexp_module_ctx = NULL;
 static GMutex                             *workers_mtx = NULL;
 
 static gint                     regexp_common_filter (struct worker_task *task);
-static void                                            process_regexp_item_threaded (gpointer data, gpointer user_data);
+static void                                 process_regexp_item_threaded (gpointer data, gpointer user_data);
 static gboolean                 rspamd_regexp_match_number (struct worker_task *task, GList * args, void *unused);
 static gboolean                 rspamd_raw_header_exists (struct worker_task *task, GList * args, void *unused);
 static gboolean                 rspamd_check_smtp_data (struct worker_task *task, GList * args, void *unused);
 static gboolean                 rspamd_regexp_occurs_number (struct worker_task *task, GList * args, void *unused);
-static void                     process_regexp_item (struct worker_task *task, void *user_data);
+static gboolean                 rspamd_content_type_is_type (struct worker_task * task, GList * args, void *unused);
+static gboolean                 rspamd_content_type_is_subtype (struct worker_task *task, GList * args, void *unused);
+static gboolean                 rspamd_content_type_has_param (struct worker_task * task, GList * args, void *unused);
+static gboolean                 rspamd_content_type_compare_param (struct worker_task * task, GList * args, void *unused);
+static gboolean                 rspamd_has_content_part (struct worker_task *task, GList * args, void *unused);
+static gboolean                 rspamd_has_content_part_len (struct worker_task *task, GList * args, void *unused);
+static void                    process_regexp_item (struct worker_task *task, void *user_data);
+
 
 /* Initialization */
 gint regexp_module_init (struct config_file *cfg, struct module_ctx **ctx);
@@ -515,6 +522,12 @@ regexp_module_init (struct config_file *cfg, struct module_ctx **ctx)
        register_expression_function ("regexp_occurs_number", rspamd_regexp_occurs_number, NULL);
        register_expression_function ("raw_header_exists", rspamd_raw_header_exists, NULL);
        register_expression_function ("check_smtp_data", rspamd_check_smtp_data, NULL);
+       register_expression_function ("content_type_is_type", rspamd_content_type_is_type, NULL);
+       register_expression_function ("content_type_is_subtype", rspamd_content_type_is_subtype, NULL);
+       register_expression_function ("content_type_has_param", rspamd_content_type_has_param, NULL);
+       register_expression_function ("content_type_compare_param", rspamd_content_type_compare_param, NULL);
+       register_expression_function ("has_content_part", rspamd_has_content_part, NULL);
+       register_expression_function ("has_content_part_len", rspamd_has_content_part_len, NULL);
 
        (void)luaopen_regexp (cfg->lua_state);
        register_module_opt ("regexp", "dynamic_rules", MODULE_OPT_TYPE_STRING);
@@ -1643,3 +1656,582 @@ lua_regexp_match (lua_State *L)
 
        return 1;
 }
+
+static gboolean
+rspamd_content_type_compare_param (struct worker_task * task, GList * args, void *unused)
+{
+       gchar                           *param_name, *param_pattern;
+       const gchar                     *param_data;
+       struct rspamd_regexp           *re;
+       struct expression_argument     *arg, *arg1;
+       GMimeObject                    *part;
+       GMimeContentType               *ct;
+       gint                            r;
+       gboolean                        recursive = FALSE, result = FALSE;
+       GList                          *cur = NULL;
+       struct mime_part               *cur_part;
+
+       if (args == NULL) {
+               msg_warn ("no parameters to function");
+               return FALSE;
+       }
+       arg = get_function_arg (args->data, task, TRUE);
+       param_name = arg->data;
+       args = g_list_next (args);
+       if (args == NULL) {
+               msg_warn ("too few params to function");
+               return FALSE;
+       }
+       arg = get_function_arg (args->data, task, TRUE);
+       param_pattern = arg->data;
+
+
+       part = g_mime_message_get_mime_part (task->message);
+       if (part) {
+               ct = (GMimeContentType *)g_mime_object_get_content_type (part);
+               if (args->next) {
+                       args = g_list_next (args);
+                       arg1 = get_function_arg (args->data, task, TRUE);
+                       if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
+                               recursive = TRUE;
+                       }
+               }
+               else {
+                       /*
+                        * If user did not specify argument, let's assume that he wants
+                        * recursive search if mime part is multipart/mixed
+                        */
+                       if (g_mime_content_type_is_type (ct, "multipart", "*")) {
+                               recursive = TRUE;
+                       }
+               }
+
+               if (recursive) {
+                       cur = task->parts;
+               }
+
+#ifndef GMIME24
+               g_object_unref (part);
+#endif
+               for (;;) {
+                       if ((param_data = g_mime_content_type_get_parameter ((GMimeContentType *)ct, param_name)) == NULL) {
+                               result = FALSE;
+                       }
+                       else {
+                               if (*param_pattern == '/') {
+                                       /* This is regexp, so compile and create g_regexp object */
+                                       if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
+                                               re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
+                                               if (re == NULL) {
+                                                       msg_warn ("cannot compile regexp for function");
+                                                       return FALSE;
+                                               }
+                                               re_cache_add (param_pattern, re, task->cfg->cfg_pool);
+                                       }
+                                       if ((r = task_cache_check (task, re)) == -1) {
+                                               if (g_regex_match (re->regexp, param_data, 0, NULL) == TRUE) {
+                                                       task_cache_add (task, re, 1);
+                                                       return TRUE;
+                                               }
+                                               task_cache_add (task, re, 0);
+                                       }
+                                       else {
+
+                                       }
+                               }
+                               else {
+                                       /* Just do strcasecmp */
+                                       if (g_ascii_strcasecmp (param_data, param_pattern) == 0) {
+                                               return TRUE;
+                                       }
+                               }
+                       }
+                       /* Get next part */
+                       if (! recursive) {
+                               return result;
+                       }
+                       else if (cur != NULL) {
+                               cur_part = cur->data;
+                               if (cur_part->type != NULL) {
+                                       ct = cur_part->type;
+                               }
+                               cur = g_list_next (cur);
+                       }
+                       else {
+                               /* All is done */
+                               return result;
+                       }
+               }
+
+       }
+
+       return FALSE;
+}
+
+static gboolean
+rspamd_content_type_has_param (struct worker_task * task, GList * args, void *unused)
+{
+       gchar                           *param_name;
+       const gchar                     *param_data;
+       struct expression_argument     *arg, *arg1;
+       GMimeObject                    *part;
+       GMimeContentType               *ct;
+       gboolean                        recursive = FALSE, result = FALSE;
+       GList                          *cur = NULL;
+       struct mime_part               *cur_part;
+
+       if (args == NULL) {
+               msg_warn ("no parameters to function");
+               return FALSE;
+       }
+       arg = get_function_arg (args->data, task, TRUE);
+       param_name = arg->data;
+
+       part = g_mime_message_get_mime_part (task->message);
+       if (part) {
+               ct = (GMimeContentType *)g_mime_object_get_content_type (part);
+               if (args->next) {
+                       args = g_list_next (args);
+                       arg1 = get_function_arg (args->data, task, TRUE);
+                       if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
+                               recursive = TRUE;
+                       }
+               }
+               else {
+                       /*
+                        * If user did not specify argument, let's assume that he wants
+                        * recursive search if mime part is multipart/mixed
+                        */
+                       if (g_mime_content_type_is_type (ct, "multipart", "*")) {
+                               recursive = TRUE;
+                       }
+               }
+
+               if (recursive) {
+                       cur = task->parts;
+               }
+
+#ifndef GMIME24
+               g_object_unref (part);
+#endif
+               for (;;) {
+                       if ((param_data = g_mime_content_type_get_parameter ((GMimeContentType *)ct, param_name)) != NULL) {
+                               return TRUE;
+                       }
+                       /* Get next part */
+                       if (! recursive) {
+                               return result;
+                       }
+                       else if (cur != NULL) {
+                               cur_part = cur->data;
+                               if (cur_part->type != NULL) {
+                                       ct = cur_part->type;
+                               }
+                               cur = g_list_next (cur);
+                       }
+                       else {
+                               /* All is done */
+                               return result;
+                       }
+               }
+
+       }
+
+       return TRUE;
+}
+
+static gboolean
+rspamd_content_type_is_subtype (struct worker_task *task, GList * args, void *unused)
+{
+       gchar                          *param_pattern;
+       struct rspamd_regexp           *re;
+       struct expression_argument     *arg, *arg1;
+       GMimeObject                    *part;
+       GMimeContentType               *ct;
+       gint                            r;
+       gboolean                        recursive = FALSE, result = FALSE;
+       GList                          *cur = NULL;
+       struct mime_part               *cur_part;
+
+       if (args == NULL) {
+               msg_warn ("no parameters to function");
+               return FALSE;
+       }
+       arg = get_function_arg (args->data, task, TRUE);
+       param_pattern = arg->data;
+
+       part = g_mime_message_get_mime_part (task->message);
+       if (part) {
+               ct = (GMimeContentType *)g_mime_object_get_content_type (part);
+               if (args->next) {
+                       args = g_list_next (args);
+                       arg1 = get_function_arg (args->data, task, TRUE);
+                       if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
+                               recursive = TRUE;
+                       }
+               }
+               else {
+                       /*
+                        * If user did not specify argument, let's assume that he wants
+                        * recursive search if mime part is multipart/mixed
+                        */
+                       if (g_mime_content_type_is_type (ct, "multipart", "*")) {
+                               recursive = TRUE;
+                       }
+               }
+
+               if (recursive) {
+                       cur = task->parts;
+               }
+
+#ifndef GMIME24
+               g_object_unref (part);
+#endif
+               for (;;) {
+                       if (*param_pattern == '/') {
+                               /* This is regexp, so compile and create g_regexp object */
+                               if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
+                                       re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
+                                       if (re == NULL) {
+                                               msg_warn ("cannot compile regexp for function");
+                                               return FALSE;
+                                       }
+                                       re_cache_add (param_pattern, re, task->cfg->cfg_pool);
+                               }
+                               if ((r = task_cache_check (task, re)) == -1) {
+                                       if (g_regex_match (re->regexp, ct->subtype, 0, NULL) == TRUE) {
+                                               task_cache_add (task, re, 1);
+                                               return TRUE;
+                                       }
+                                       task_cache_add (task, re, 0);
+                               }
+                               else {
+
+                               }
+                       }
+                       else {
+                               /* Just do strcasecmp */
+                               if (g_ascii_strcasecmp (ct->subtype, param_pattern) == 0) {
+                                       return TRUE;
+                               }
+                       }
+                       /* Get next part */
+                       if (! recursive) {
+                               return result;
+                       }
+                       else if (cur != NULL) {
+                               cur_part = cur->data;
+                               if (cur_part->type != NULL) {
+                                       ct = cur_part->type;
+                               }
+                               cur = g_list_next (cur);
+                       }
+                       else {
+                               /* All is done */
+                               return result;
+                       }
+               }
+
+       }
+
+       return FALSE;
+}
+
+static gboolean
+rspamd_content_type_is_type (struct worker_task * task, GList * args, void *unused)
+{
+       gchar                          *param_pattern;
+       struct rspamd_regexp           *re;
+       struct expression_argument     *arg, *arg1;
+       GMimeObject                    *part;
+       GMimeContentType               *ct;
+       gint                            r;
+       gboolean                        recursive = FALSE, result = FALSE;
+       GList                          *cur = NULL;
+       struct mime_part               *cur_part;
+
+       if (args == NULL) {
+               msg_warn ("no parameters to function");
+               return FALSE;
+       }
+       arg = get_function_arg (args->data, task, TRUE);
+       param_pattern = arg->data;
+
+
+       part = g_mime_message_get_mime_part (task->message);
+       if (part) {
+               ct = (GMimeContentType *)g_mime_object_get_content_type (part);
+               if (args->next) {
+                       args = g_list_next (args);
+                       arg1 = get_function_arg (args->data, task, TRUE);
+                       if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
+                               recursive = TRUE;
+                       }
+               }
+               else {
+                       /*
+                        * If user did not specify argument, let's assume that he wants
+                        * recursive search if mime part is multipart/mixed
+                        */
+                       if (g_mime_content_type_is_type (ct, "multipart", "*")) {
+                               recursive = TRUE;
+                       }
+               }
+
+               if (recursive) {
+                       cur = task->parts;
+               }
+
+#ifndef GMIME24
+               g_object_unref (part);
+#endif
+               for (;;) {
+                       if (*param_pattern == '/') {
+                               /* This is regexp, so compile and create g_regexp object */
+                               if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
+                                       re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
+                                       if (re == NULL) {
+                                               msg_warn ("cannot compile regexp for function");
+                                               return FALSE;
+                                       }
+                                       re_cache_add (param_pattern, re, task->cfg->cfg_pool);
+                               }
+                               if ((r = task_cache_check (task, re)) == -1) {
+                                       if (g_regex_match (re->regexp, ct->type, 0, NULL) == TRUE) {
+                                               task_cache_add (task, re, 1);
+                                               return TRUE;
+                                       }
+                                       task_cache_add (task, re, 0);
+                               }
+                               else {
+
+                               }
+                       }
+                       else {
+                               /* Just do strcasecmp */
+                               if (g_ascii_strcasecmp (ct->type, param_pattern) == 0) {
+                                       return TRUE;
+                               }
+                       }
+                       /* Get next part */
+                       if (! recursive) {
+                               return result;
+                       }
+                       else if (cur != NULL) {
+                               cur_part = cur->data;
+                               if (cur_part->type != NULL) {
+                                       ct = cur_part->type;
+                               }
+                               cur = g_list_next (cur);
+                       }
+                       else {
+                               /* All is done */
+                               return result;
+                       }
+               }
+
+       }
+
+       return FALSE;
+}
+
+static                   gboolean
+compare_subtype (struct worker_task *task, GMimeContentType * ct, gchar *subtype)
+{
+       struct rspamd_regexp           *re;
+       gint                            r;
+
+       if (*subtype == '/') {
+               /* This is regexp, so compile and create g_regexp object */
+               if ((re = re_cache_check (subtype, task->cfg->cfg_pool)) == NULL) {
+                       re = parse_regexp (task->cfg->cfg_pool, subtype, task->cfg->raw_mode);
+                       if (re == NULL) {
+                               msg_warn ("cannot compile regexp for function");
+                               return FALSE;
+                       }
+                       re_cache_add (subtype, re, task->cfg->cfg_pool);
+               }
+               if ((r = task_cache_check (task, re)) == -1) {
+                       if (g_regex_match (re->regexp, subtype, 0, NULL) == TRUE) {
+                               task_cache_add (task, re, 1);
+                               return TRUE;
+                       }
+                       task_cache_add (task, re, 0);
+               }
+               else {
+                       return r == 1;
+               }
+       }
+       else {
+               /* Just do strcasecmp */
+               if (ct->subtype && g_ascii_strcasecmp (ct->subtype, subtype) == 0) {
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+static                   gboolean
+compare_len (struct mime_part *part, guint min, guint max)
+{
+       if (min == 0 && max == 0) {
+               return TRUE;
+       }
+
+       if (min == 0) {
+               return part->content->len <= max;
+       }
+       else if (max == 0) {
+               return part->content->len >= min;
+       }
+       else {
+               return part->content->len >= min && part->content->len <= max;
+       }
+}
+
+static gboolean
+common_has_content_part (struct worker_task * task, gchar *param_type, gchar *param_subtype, gint min_len, gint max_len)
+{
+       struct rspamd_regexp           *re;
+       struct mime_part               *part;
+       GList                          *cur;
+       GMimeContentType               *ct;
+       gint                            r;
+
+       cur = g_list_first (task->parts);
+       while (cur) {
+               part = cur->data;
+               ct = part->type;
+               if (ct == NULL) {
+                       cur = g_list_next (cur);
+                       continue;
+               }
+
+               if (*param_type == '/') {
+                       /* This is regexp, so compile and create g_regexp object */
+                       if ((re = re_cache_check (param_type, task->cfg->cfg_pool)) == NULL) {
+                               re = parse_regexp (task->cfg->cfg_pool, param_type, task->cfg->raw_mode);
+                               if (re == NULL) {
+                                       msg_warn ("cannot compile regexp for function");
+                                       cur = g_list_next (cur);
+                                       continue;
+                               }
+                               re_cache_add (param_type, re, task->cfg->cfg_pool);
+                       }
+                       if ((r = task_cache_check (task, re)) == -1) {
+                               if (ct->type && g_regex_match (re->regexp, ct->type, 0, NULL) == TRUE) {
+                                       if (param_subtype) {
+                                               if (compare_subtype (task, ct, param_subtype)) {
+                                                       if (compare_len (part, min_len, max_len)) {
+                                                               return TRUE;
+                                                       }
+                                               }
+                                       }
+                                       else {
+                                               if (compare_len (part, min_len, max_len)) {
+                                                       return TRUE;
+                                               }
+                                       }
+                                       task_cache_add (task, re, 1);
+                               }
+                               else {
+                                       task_cache_add (task, re, 0);
+                               }
+                       }
+                       else {
+                               if (r == 1) {
+                                       if (compare_subtype (task, ct, param_subtype)) {
+                                               if (compare_len (part, min_len, max_len)) {
+                                                       return TRUE;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               else {
+                       /* Just do strcasecmp */
+                       if (ct->type && g_ascii_strcasecmp (ct->type, param_type) == 0) {
+                               if (param_subtype) {
+                                       if (compare_subtype (task, ct, param_subtype)) {
+                                               if (compare_len (part, min_len, max_len)) {
+                                                       return TRUE;
+                                               }
+                                       }
+                               }
+                               else {
+                                       if (compare_len (part, min_len, max_len)) {
+                                               return TRUE;
+                                       }
+                               }
+                       }
+               }
+               cur = g_list_next (cur);
+       }
+
+       return FALSE;
+}
+
+static gboolean
+rspamd_has_content_part (struct worker_task * task, GList * args, void *unused)
+{
+       gchar                           *param_type = NULL, *param_subtype = NULL;
+       struct expression_argument     *arg;
+
+       if (args == NULL) {
+               msg_warn ("no parameters to function");
+               return FALSE;
+       }
+
+       arg = get_function_arg (args->data, task, TRUE);
+       param_type = arg->data;
+       args = args->next;
+       if (args) {
+               arg = args->data;
+               param_subtype = arg->data;
+       }
+
+       return common_has_content_part (task, param_type, param_subtype, 0, 0);
+}
+
+static gboolean
+rspamd_has_content_part_len (struct worker_task * task, GList * args, void *unused)
+{
+       gchar                           *param_type = NULL, *param_subtype = NULL;
+       gint                            min = 0, max = 0;
+       struct expression_argument     *arg;
+
+       if (args == NULL) {
+               msg_warn ("no parameters to function");
+               return FALSE;
+       }
+
+       arg = get_function_arg (args->data, task, TRUE);
+       param_type = arg->data;
+       args = args->next;
+       if (args) {
+               arg = get_function_arg (args->data, task, TRUE);
+               param_subtype = arg->data;
+               args = args->next;
+               if (args) {
+                       arg = get_function_arg (args->data, task, TRUE);
+                       errno = 0;
+                       min = strtoul (arg->data, NULL, 10);
+                       if (errno != 0) {
+                               msg_warn ("invalid numeric value '%s': %s", (gchar *)arg->data, strerror (errno));
+                               return FALSE;
+                       }
+                       args = args->next;
+                       if (args) {
+                               arg = get_function_arg (args->data, task, TRUE);
+                               max = strtoul (arg->data, NULL, 10);
+                               if (errno != 0) {
+                                       msg_warn ("invalid numeric value '%s': %s", (gchar *)arg->data, strerror (errno));
+                                       return FALSE;
+                               }
+                       }
+               }
+       }
+
+       return common_has_content_part (task, param_type, param_subtype, min, max);
+}
index 5fcf0858b03a9cb47b3ad8a5778f035f020cdb83..e7fe474ad1204c59692505cb227afcbf46b72c9b 100644 (file)
@@ -1335,8 +1335,8 @@ rspamd_strtoul (const gchar *s, gsize len, gulong *value)
 gint
 rspamd_fallocate (gint fd, off_t offset, off_t len)
 {
-#if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_KEEP_SIZE)
-       return fallocate (fd, FALLOC_FL_KEEP_SIZE, offset, len);
+#if defined(HAVE_FALLOCATE)
+       return fallocate (fd, 0, offset, len);
 #elif defined(HAVE_POSIX_FALLOCATE)
        return posix_fallocate (fd, offset, len);
 #else
index c6011d2a84281a7faf0e4504eb0a66d547dda4a6..c15f77b753f54827b25bc585f4ec23b1ce8bf31b 100644 (file)
@@ -15,6 +15,10 @@ TARGET_LINK_LIBRARIES(rspamd-test rspamdserver)
 TARGET_LINK_LIBRARIES(rspamd-test event)
 TARGET_LINK_LIBRARIES(rspamd-test ${GLIB2_LIBRARIES})
 TARGET_LINK_LIBRARIES(rspamd-test ${CMAKE_REQUIRED_LIBRARIES})
+IF(HAVE_LIBEVENT2)
+       TARGET_LINK_LIBRARIES(rspamd-test event_pthreads)
+ENDIF(HAVE_LIBEVENT2)
+INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/src")
 IF(GMIME2_FOUND)
        TARGET_LINK_LIBRARIES(rspamd-test ${GMIME2_LIBRARIES})
 ELSE(GMIME2_FOUND)
index c0b48080ed9a1688d7d5acda7529d5fe1570c836..839c00a79ea9472fdc6548fd3d5f586a1dc36c92 100644 (file)
@@ -8,6 +8,7 @@
 #include "../src/cfg_file.h"
 
 static guint requests = 0;
+extern struct event_base *base;
 
 static void
 test_dns_cb (struct rspamd_dns_reply *reply, gpointer arg)
@@ -49,7 +50,7 @@ test_dns_cb (struct rspamd_dns_reply *reply, gpointer arg)
        }
 }
 
-void
+gboolean
 session_fin (gpointer unused)
 {
        struct timeval tv;
@@ -57,6 +58,8 @@ session_fin (gpointer unused)
        tv.tv_sec = 0;
        tv.tv_usec = 0;
        event_loopexit (&tv);
+
+       return TRUE;
 }
 
 void
@@ -76,9 +79,9 @@ rspamd_dns_test_func ()
        pool = memory_pool_new (memory_pool_get_size ());
 
        event_init ();
-       s = new_async_session (pool, session_fin, NULL);
+       s = new_async_session (pool, session_fin, NULL, NULL, NULL);
 
-       resolver = dns_resolver_init (cfg);
+       resolver = dns_resolver_init (base, cfg);
 
        requests ++;
        g_assert (make_dns_request (resolver, s, pool, test_dns_cb, NULL, DNS_REQUEST_A, "google.com"));
index 004ebf3c0318ca21131bd4a8f4acf7e1d2eb0551..7805e4f42a2ff10514190027bd4a5f887a8be63f 100644 (file)
@@ -39,7 +39,7 @@ rspamd_fuzzy_test_func ()
        memory_pool_t *pool;
        fuzzy_hash_t *h1, *h2, *h3, *h4, *h5;
        f_str_t f1, f2, f3, f4, f5;
-       int diff1, diff2;
+       int diff2;
 
        pool = memory_pool_new (1024);
        f1.begin = s1;
@@ -59,7 +59,6 @@ rspamd_fuzzy_test_func ()
        h4 = fuzzy_init (&f4, pool);
        h5 = fuzzy_init (&f5, pool);
 
-       diff1 = fuzzy_compare_hashes (h3, h4) + fuzzy_compare_hashes (h2, h4);
        diff2 = fuzzy_compare_hashes (h2, h5);
        msg_debug ("rspamd_fuzzy_test_func: s1, s2 difference between strings is %d", fuzzy_compare_hashes (h1, h2));
        msg_debug ("rspamd_fuzzy_test_func: s1, s3 difference between strings is %d", fuzzy_compare_hashes (h1, h3));
index 423086506a6a2351ba515e4b4848415882451e7d..f035fcb8181cdc2eed01d6c6b4666c04d6a37658 100644 (file)
@@ -5,6 +5,8 @@
 
 static gboolean do_debug;
 struct rspamd_main             *rspamd_main = NULL;
+struct event_base              *base = NULL;
+worker_t *workers[] = { NULL };
 
 static GOptionEntry entries[] =
 {
@@ -15,7 +17,7 @@ static GOptionEntry entries[] =
 int
 main (int argc, char **argv)
 {
-       struct config_file             *cfg;
+       struct config_file            *cfg;
        GError                         *error = NULL;
        GOptionContext                 *context;
 
@@ -39,6 +41,8 @@ main (int argc, char **argv)
        bzero (cfg, sizeof (struct config_file));
        cfg->cfg_pool = memory_pool_new (memory_pool_get_size ());
 
+       base = event_init ();
+
        if (do_debug) {
                cfg->log_level = G_LOG_LEVEL_DEBUG;
        }
@@ -46,11 +50,13 @@ main (int argc, char **argv)
                cfg->log_level = G_LOG_LEVEL_INFO;
        }
        /* First set logger to console logger */
-       rspamd_set_logger (RSPAMD_LOG_CONSOLE, TYPE_MAIN, rspamd_main);
+       rspamd_set_logger (RSPAMD_LOG_CONSOLE, g_quark_from_static_string("rspamd-test"), rspamd_main);
        (void)open_log (rspamd_main->logger);
        g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger);
 
+#if 0
        g_test_add_func ("/rspamd/memcached", rspamd_memcached_test_func);
+#endif
        g_test_add_func ("/rspamd/mem_pool", rspamd_mem_pool_test_func);
        g_test_add_func ("/rspamd/fuzzy", rspamd_fuzzy_test_func);
        g_test_add_func ("/rspamd/url", rspamd_url_test_func);