2008-11-27 [colin] 3.6.1cvs47
[claws.git] / src / filtering.c
index 48c10039a30cc3c8896093145375f2cd4df60127..c8ffe7f855e864c9505001b244b1069445d98e1d 100644 (file)
@@ -39,8 +39,6 @@
 #include "tags.h"
 #include "log.h"
 
-#define PREFSBUFSIZE           1024
-
 GSList * pre_global_processing = NULL;
 GSList * post_global_processing = NULL;
 GSList * filtering_rules = NULL;
@@ -176,6 +174,7 @@ void filteringprop_free(FilteringProp * prop)
         for (tmp = prop->action_list ; tmp != NULL ; tmp = tmp->next) {
                 filteringaction_free(tmp->data);
         }
+       g_slist_free(prop->action_list);
        g_free(prop->name);
        g_free(prop);
 }
@@ -185,7 +184,8 @@ void filtering_move_and_copy_msgs(GSList *msgs)
 {
        GSList *messages = g_slist_copy(msgs);
        FolderItem *last_item = NULL;
-       gboolean is_copy = FALSE, is_move = FALSE;
+       FiltOp cur_op = IS_NOTHING;
+
        debug_print("checking %d messages\n", g_slist_length(msgs));
        while (messages) {
                GSList *batch = NULL, *cur;
@@ -193,44 +193,61 @@ void filtering_move_and_copy_msgs(GSList *msgs)
                for (cur = messages; cur; cur = cur->next) {
                        MsgInfo *info = (MsgInfo *)cur->data;
                        if (last_item == NULL) {
-                               last_item = info->to_filter_folder;
+                               if (info->filter_op == IS_COPY || info->filter_op == IS_MOVE)
+                                       last_item = info->to_filter_folder;
+                               else if (info->filter_op == IS_DELE)
+                                       last_item = info->folder;
                        }
                        if (last_item == NULL)
                                continue;
-                       if (!is_copy && !is_move) {
-                               if (info->is_copy)
-                                       is_copy = TRUE;
-                               else if (info->is_move)
-                                       is_move = TRUE;
+                       if (cur_op == IS_NOTHING) {
+                               if (info->filter_op == IS_COPY)
+                                       cur_op = IS_COPY;
+                               else if (info->filter_op == IS_MOVE)
+                                       cur_op = IS_MOVE;
+                               else if (info->filter_op == IS_DELE)
+                                       cur_op = IS_DELE;
                        }
-                       found++;
-                       if (info->to_filter_folder == last_item 
-                       &&  info->is_copy == is_copy
-                       &&  info->is_move == is_move) {
-                               batch = g_slist_prepend(batch, info);
+                       if (info->filter_op == IS_COPY || info->filter_op == IS_MOVE) {
+                               if (info->to_filter_folder == last_item 
+                               &&  cur_op == info->filter_op) {
+                                       found++;
+                                       batch = g_slist_prepend(batch, info);
+                               }
+                       } else if (info->filter_op == IS_DELE) {
+                               if (info->folder == last_item 
+                               &&  cur_op == info->filter_op) {
+                                       found++;
+                                       batch = g_slist_prepend(batch, info);
+                               }
                        }
                }
                if (found == 0) {
-                       debug_print("no more messages to move/copy\n");
+                       debug_print("no more messages to move/copy/del\n");
                        break;
                } else {
                        debug_print("%d messages to %s in %s\n", found,
-                               is_copy ? "copy":"move", last_item->name ? last_item->name:"(noname)");
+                               cur_op==IS_COPY ? "copy":(cur_op==IS_DELE ?"delete":"move"), 
+                               last_item?(last_item->name ? last_item->name:"(noname)"):"nowhere");
                }
                for (cur = batch; cur; cur = cur->next) {
                        MsgInfo *info = (MsgInfo *)cur->data;
                        messages = g_slist_remove(messages, info);
+                       info->to_filter_folder = NULL;
+                       info->filter_op = IS_NOTHING;
                }
                batch = g_slist_reverse(batch);
                if (g_slist_length(batch)) {
                        MsgInfo *info = (MsgInfo *)batch->data;
-                       if (is_copy && last_item != info->folder) {
+                       if (cur_op == IS_COPY && last_item != info->folder) {
                                folder_item_copy_msgs(last_item, batch);
-                       } else if (is_move && last_item != info->folder) {
+                       } else if (cur_op == IS_MOVE && last_item != info->folder) {
                                if (folder_item_move_msgs(last_item, batch) < 0)
                                        folder_item_move_msgs(
                                                folder_get_default_inbox(), 
                                                batch);
+                       } else if (cur_op == IS_DELE && last_item == info->folder) {
+                               folder_item_remove_msgs(last_item, batch);
                        }
                        /* we don't reference the msginfos, because caller will do */
                        if (prefs_common.real_time_sync)
@@ -240,8 +257,7 @@ void filtering_move_and_copy_msgs(GSList *msgs)
                        GTK_EVENTS_FLUSH();
                }
                last_item = NULL;
-               is_copy = FALSE;
-               is_move = FALSE;
+               cur_op = IS_NOTHING;
        }
        /* we don't reference the msginfos, because caller will do */
        g_slist_free(messages);
@@ -254,10 +270,10 @@ void filtering_move_and_copy_msgs(GSList *msgs)
 */
 
 #define FLUSH_COPY_IF_NEEDED(info) {                                   \
-       if (info->is_copy && info->to_filter_folder) {                  \
+       if (info->filter_op == IS_COPY && info->to_filter_folder) {     \
                debug_print("must debatch pending copy\n");             \
                folder_item_copy_msg(info->to_filter_folder, info);     \
-               info->is_copy = FALSE;                                  \
+               info->filter_op = IS_NOTHING;                           \
        }                                                               \
 }
 
@@ -281,7 +297,7 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                
                FLUSH_COPY_IF_NEEDED(info);
                /* mark message to be moved */          
-               info->is_move = TRUE;
+               info->filter_op = IS_MOVE;
                info->to_filter_folder = dest_folder;
                return TRUE;
 
@@ -297,7 +313,7 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
 
                FLUSH_COPY_IF_NEEDED(info);
                /* mark message to be copied */         
-               info->is_copy = TRUE;
+               info->filter_op = IS_COPY;
                info->to_filter_folder = dest_folder;
                return TRUE;
 
@@ -319,8 +335,8 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                return TRUE;
 
        case MATCHACTION_DELETE:
-               if (folder_item_remove_msg(info->folder, info->msgnum) == -1)
-                       return FALSE;
+               FLUSH_COPY_IF_NEEDED(info);
+               info->filter_op = IS_DELE;
                return TRUE;
 
        case MATCHACTION_MARK:
@@ -358,7 +374,7 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                procmsg_spam_learner_learn(info, NULL, TRUE);
                procmsg_msginfo_change_flags(info, MSG_SPAM, 0, MSG_NEW|MSG_UNREAD, 0);
                if (procmsg_spam_get_folder(info)) {
-                       info->is_move = TRUE;
+                       info->filter_op = IS_MOVE;
                        info->to_filter_folder = procmsg_spam_get_folder(info);
                }
                return TRUE;
@@ -451,7 +467,7 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                        gint errors = 0;
 
                        if (!addressbook_peek_folder_exists(action->destination, &book, &folder)) {
-                               g_warning("addressbook folder not found '%s'\n", action->destination);
+                               g_warning("addressbook folder not found '%s'\n", action->destination?action->destination:"(null)");
                                return FALSE;
                        }
                        if (!book) {
@@ -472,7 +488,7 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                                gchar *path = NULL;
 
                                if (action->destination == NULL ||
-                                               strcasecmp(action->destination, _("Any")) == 0 ||
+                                               strcasecmp(action->destination, "Any") == 0 ||
                                                *(action->destination) == '\0')
                                        path = NULL;
                                else
@@ -501,7 +517,7 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                                g_slist_free(address_list);
                                end_address_completion();
                        } else {
-                               g_warning("header '%s' not set or empty\n", action->header);
+                               g_warning("header '%s' not set or empty\n", action->header?action->header:"(null)");
                        }
                        return (errors == 0);
                }
@@ -570,7 +586,7 @@ static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *inf
                                                log_status_ok(LOG_DEBUG_FILTERING,
                                                                _("rule is account-based [id=%d, name='%s'], "
                                                                "matching the account currently used to retrieve messages\n"),
-                                                               ac_prefs->account_id, ac_prefs->account_name);
+                                                               ac_prefs->account_id, ac_prefs?ac_prefs->account_name:_("NON_EXISTENT"));
                                        }
                                }
                        }
@@ -587,8 +603,8 @@ static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *inf
                                                log_status_skip(LOG_DEBUG_FILTERING,
                                                                _("rule is account-based [id=%d, name='%s'], "
                                                                "not matching the account currently used to retrieve messages [id=%d, name='%s']\n"),
-                                                               filtering->account_id, account->account_name,
-                                                               ac_prefs->account_id, ac_prefs->account_name);
+                                                               filtering->account_id, account?account->account_name:_("NON_EXISTENT"),
+                                                               ac_prefs->account_id, ac_prefs?ac_prefs->account_name:_("NON_EXISTENT"));
                                        }
                                }
                        }
@@ -612,7 +628,7 @@ static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *inf
                                                log_status_ok(LOG_DEBUG_FILTERING,
                                                                _("rule is account-based [id=%d, name='%s'], "
                                                                "but all rules are applied on user request\n"),
-                                                               filtering->account_id, account->account_name);
+                                                               filtering->account_id, account?account->account_name:_("NON_EXISTENT"));
                                        }
                                }
                        }
@@ -630,7 +646,7 @@ static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *inf
                                                log_status_skip(LOG_DEBUG_FILTERING,
                                                                _("rule is account-based [id=%d, name='%s'], "
                                                                "skipped on user request\n"),
-                                                               filtering->account_id, account->account_name);
+                                                               filtering->account_id, account?account->account_name:_("NON_EXISTENT"));
                                        } else {
                                                log_status_skip(LOG_DEBUG_FILTERING,
                                                                _("rule is account-based, "
@@ -657,8 +673,8 @@ static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *inf
                                                log_status_skip(LOG_DEBUG_FILTERING,
                                                                _("rule is account-based [id=%d, name='%s'], "
                                                                "not matching current account [id=%d, name='%s']\n"),
-                                                               filtering->account_id, account->account_name,
-                                                               cur_account->account_id, cur_account->account_name);
+                                                               filtering->account_id, account?account->account_name:_("NON_EXISTENT"),
+                                                               cur_account->account_id, cur_account?cur_account->account_name:_("NON_EXISTENT"));
                                        } else {
                                                log_status_skip(LOG_DEBUG_FILTERING,
                                                                _("rule is account-based, "
@@ -675,8 +691,8 @@ static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *inf
                                                        log_status_ok(LOG_DEBUG_FILTERING,
                                                                        _("rule is account-based [id=%d, name='%s'], "
                                                                        "current account [id=%d, name='%s']\n"),
-                                                                       account->account_id, account->account_name,
-                                                                       cur_account->account_id, cur_account->account_name);
+                                                                       account->account_id, account?account->account_name:_("NON_EXISTENT"),
+                                                                       cur_account->account_id, cur_account?cur_account->account_name:_("NON_EXISTENT"));
                                                }
                                        }
                                }
@@ -777,6 +793,7 @@ static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info, PrefsAcc
                                                _("processing rule <unnamed> [ %s ]\n"),
                                                buf);
                                }
+                               g_free(buf);
                        }
 
                        if (filtering_match_condition(filtering, info, ac_prefs)) {
@@ -833,7 +850,7 @@ gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info, PrefsAccount* a
 
        if (prefs_common.enable_filtering_debug) {
                gchar *tmp = _("undetermined");
-
+#ifndef G_OS_WIN32
                switch (context) {
                case FILTERING_INCORPORATION:
                        tmp = _("incorporation");
@@ -859,6 +876,9 @@ gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info, PrefsAccount* a
                        debug_filtering_session = FALSE;
                        break;
                }
+#else
+               debug_filtering_session = FALSE;
+#endif
                if (debug_filtering_session) {
                        gchar *file = procmsg_get_message_file_path(info);
                        gchar *spc = g_strnfill(LOG_TIME_LEN + 1, ' ');