#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
+#include <ctype.h>
#include "intl.h"
#include "main.h"
#include "utils.h"
#include "procmsg.h"
#include "procheader.h"
-#include "send.h"
+#include "send_message.h"
#include "procmime.h"
#include "statusbar.h"
+#include "prefs_filtering.h"
+#include "filtering.h"
#include "folder.h"
#include "prefs_common.h"
#include "account.h"
#include "hooks.h"
#include "msgcache.h"
-typedef struct _FlagInfo FlagInfo;
-
-struct _FlagInfo
-{
- guint msgnum;
- MsgFlags flags;
-};
-
GHashTable *procmsg_msg_hash_table_create(GSList *mlist)
{
GHashTable *msg_table;
}
struct MarkSum {
- gint *new;
- gint *unread;
- gint *total;
+ gint *new_msgs;
+ gint *unread_msgs;
+ gint *total_msgs;
gint *min;
gint *max;
gint first;
return FALSE;
}
+/* CLAWS subject threading:
+
+ in the first round it inserts subject lines in a
+ relation (subject <-> node)
+
+ the second round finishes the threads by attaching
+ matching subject lines to the one found in the
+ relation. will use the oldest node with the same
+ subject that is not more then thread_by_subject_max_age
+ days old (see subject_relation_lookup)
+*/
+
+static void subject_relation_insert(GRelation *relation, GNode *node)
+{
+ gchar *subject;
+ MsgInfo *msginfo;
+
+ g_return_if_fail(relation != NULL);
+ g_return_if_fail(node != NULL);
+ msginfo = (MsgInfo *) node->data;
+ g_return_if_fail(msginfo != NULL);
+
+ subject = msginfo->subject;
+ if (subject == NULL)
+ return;
+ subject += subject_get_prefix_length(subject);
+
+ g_relation_insert(relation, subject, node);
+}
+
+static GNode *subject_relation_lookup(GRelation *relation, MsgInfo *msginfo)
+{
+ gchar *subject;
+ GTuples *tuples;
+ GNode *node = NULL;
+ gint prefix_length;
+
+ g_return_val_if_fail(relation != NULL, NULL);
+
+ subject = msginfo->subject;
+ if (subject == NULL)
+ return NULL;
+ prefix_length = subject_get_prefix_length(subject);
+ if (prefix_length <= 0)
+ return NULL;
+ subject += prefix_length;
+
+ tuples = g_relation_select(relation, subject, 0);
+ if (tuples == NULL)
+ return NULL;
+
+ if (tuples->len > 0) {
+ int i;
+ GNode *relation_node;
+ MsgInfo *relation_msginfo = NULL, *best_msginfo = NULL;
+ gboolean match;
+
+ /* check all nodes with the same subject to find the best parent */
+ for (i = 0; i < tuples->len; i++) {
+ relation_node = (GNode *) g_tuples_index(tuples, i, 1);
+ relation_msginfo = (MsgInfo *) relation_node->data;
+ match = FALSE;
+
+ /* best node should be the oldest in the found nodes */
+ /* parent node must not be older then msginfo */
+ if ((relation_msginfo->date_t < msginfo->date_t) &&
+ ((best_msginfo == NULL) ||
+ (best_msginfo->date_t > relation_msginfo->date_t)))
+ match = TRUE;
+
+ /* parent node must not be more then thread_by_subject_max_age
+ days older then msginfo */
+ if (abs(difftime(msginfo->date_t, relation_msginfo->date_t)) >
+ prefs_common.thread_by_subject_max_age * 3600 * 24)
+ match = FALSE;
+
+ /* can add new tests for all matching
+ nodes found by subject */
+
+ if (match) {
+ node = relation_node;
+ best_msginfo = relation_msginfo;
+ }
+ }
+ }
+
+ g_tuples_destroy(tuples);
+ return node;
+}
+
/* return the reversed thread tree */
GNode *procmsg_get_thread_tree(GSList *mlist)
{
- GNode *root, *parent, *node, *next;
+ GNode *root, *parent, *node, *next, *last;
+ GNode *prev; /* CLAWS */
GHashTable *msgid_table;
- GHashTable *subject_table;
+ GRelation *subject_relation;
MsgInfo *msginfo;
const gchar *msgid;
const gchar *subject;
- GNode *found_subject;
root = g_node_new(NULL);
msgid_table = g_hash_table_new(g_str_hash, g_str_equal);
- subject_table = g_hash_table_new(g_str_hash, g_str_equal);
+ subject_relation = g_relation_new(2);
+ g_relation_index(subject_relation, 0, g_str_hash, g_str_equal);
for (; mlist != NULL; mlist = mlist->next) {
msginfo = (MsgInfo *)mlist->data;
parent = g_hash_table_lookup(msgid_table, msginfo->inreplyto);
if (parent == NULL) {
parent = root;
- } else {
- if (MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) {
- procmsg_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0);
- procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0);
- }
}
}
node = g_node_insert_data_before
(parent, parent == root ? parent->children : NULL,
msginfo);
- if ((msgid = msginfo->msgid) &&
- g_hash_table_lookup(msgid_table, msgid) == NULL)
+ if ((msgid = msginfo->msgid) && g_hash_table_lookup(msgid_table, msgid) == NULL)
g_hash_table_insert(msgid_table, (gchar *)msgid, node);
+ /* CLAWS: add subject to relation (without prefix) */
if (prefs_common.thread_by_subject) {
- subject = msginfo->subject;
- found_subject = subject_table_lookup(subject_table,
- (gchar *) subject);
- if (found_subject == NULL)
- subject_table_insert(subject_table, (gchar *) subject,
- node);
- else {
- /* replace if msg in table is older than current one
- * can add here more stuff. */
- if ( ((MsgInfo*)(found_subject->data))->date_t >
- ((MsgInfo*)(node->data))->date_t ) {
- subject_table_remove(subject_table, (gchar *) subject);
- subject_table_insert(subject_table, (gchar *) subject, node);
- }
- }
+ subject_relation_insert(subject_relation, node);
}
}
/* complete the unfinished threads */
for (node = root->children; node != NULL; ) {
+ prev = node->prev; /* CLAWS: need the last node */
+ parent = NULL;
next = node->next;
msginfo = (MsgInfo *)node->data;
- parent = NULL;
- if (msginfo->inreplyto)
+ if (msginfo->inreplyto) {
parent = g_hash_table_lookup(msgid_table, msginfo->inreplyto);
- if (parent && parent != node) {
- g_node_unlink(node);
- g_node_insert_before
- (parent, parent->children, node);
- /* CLAWS: ignore thread */
- if (MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) {
- g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, procmsg_ignore_node, NULL);
- }
+ /* node should not be the parent, and node should not
+ be an ancestor of parent (circular reference) */
+ if (parent && parent != node &&
+ !g_node_is_ancestor(node, parent)) {
+ g_node_unlink(node);
+ g_node_insert_before
+ (parent, parent->children, node);
+ }
}
+ last = (next == NULL) ? prev : node;
node = next;
}
- /* CLAWS: now see if the first level (below root) still has some nodes that can be
- * threaded by subject line. we need to handle this in a special way to prevent
- * circular reference from a node that has already been threaded by IN-REPLY-TO
- * but is also in the subject line hash table */
if (prefs_common.thread_by_subject) {
- for (node = root->children; node != NULL; ) {
- next = node->next;
+ for (node = last; node && node != NULL;) {
+ next = node->prev;
msginfo = (MsgInfo *) node->data;
- parent = NULL;
- if (subject_is_reply(msginfo->subject)) {
- parent = subject_table_lookup(subject_table,
- msginfo->subject);
- /* the node may already be threaded by IN-REPLY-TO,
- so go up in the tree to find the parent node */
- if (parent != NULL) {
- if (g_node_is_ancestor(node, parent))
- parent = NULL;
- if (parent == node)
- parent = NULL;
- }
+
+ /* may not parentize if parent was delivered after childs */
+ if (subject != msginfo->subject)
+ parent = subject_relation_lookup(subject_relation, msginfo);
+ else
+ parent = NULL;
+
+ /* the node may already be threaded by IN-REPLY-TO, so go up in the tree to
+ find the parent node */
+ if (parent != NULL) {
+ if (g_node_is_ancestor(node, parent))
+ parent = NULL;
+ if (parent == node)
+ parent = NULL;
+ }
+
+ if (parent) {
+ g_node_unlink(node);
+ g_node_append(parent, node);
+ }
- if (parent) {
- g_node_unlink(node);
- g_node_append(parent, node);
- /* CLAWS: ignore thread */
- if (MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) {
- g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, procmsg_ignore_node, NULL);
- }
- }
- }
node = next;
}
}
- g_hash_table_destroy(subject_table);
+ g_relation_destroy(subject_relation);
g_hash_table_destroy(msgid_table);
return root;
} else if (dest == msginfo->to_folder) {
movelist = g_slist_append(movelist, msginfo);
} else {
- folder_item_move_msgs_with_dest(dest, movelist);
+ folder_item_move_msgs(dest, movelist);
g_slist_free(movelist);
movelist = NULL;
dest = msginfo->to_folder;
}
if (movelist) {
- folder_item_move_msgs_with_dest(dest, movelist);
+ folder_item_move_msgs(dest, movelist);
g_slist_free(movelist);
}
} else if (dest == msginfo->to_folder) {
copylist = g_slist_append(copylist, msginfo);
} else {
- folder_item_copy_msgs_with_dest(dest, copylist);
+ folder_item_copy_msgs(dest, copylist);
g_slist_free(copylist);
copylist = NULL;
dest = msginfo->to_folder;
}
if (copylist) {
- folder_item_copy_msgs_with_dest(dest, copylist);
+ folder_item_copy_msgs(dest, copylist);
g_slist_free(copylist);
}
gchar *procmsg_get_message_file_path(MsgInfo *msginfo)
{
- gchar *path, *file;
+ gchar *file;
g_return_val_if_fail(msginfo != NULL, NULL);
if (msginfo->plaintext_file)
file = g_strdup(msginfo->plaintext_file);
else {
- path = folder_item_get_path(msginfo->folder);
- file = g_strconcat(path, G_DIR_SEPARATOR_S,
- itos(msginfo->msgnum), NULL);
- g_free(path);
+ file = folder_item_fetch_msg(msginfo->folder, msginfo->msgnum);
}
return file;
return filename;
}
+GSList *procmsg_get_message_file_list(GSList *mlist)
+{
+ GSList *file_list = NULL;
+ MsgInfo *msginfo;
+ MsgFileInfo *fileinfo;
+ gchar *file;
+
+ while (mlist != NULL) {
+ msginfo = (MsgInfo *)mlist->data;
+ file = procmsg_get_message_file(msginfo);
+ if (!file) {
+ procmsg_message_file_list_free(file_list);
+ return NULL;
+ }
+ fileinfo = g_new(MsgFileInfo, 1);
+ fileinfo->msginfo = procmsg_msginfo_new_ref(msginfo);
+ fileinfo->file = file;
+ fileinfo->flags = g_new(MsgFlags, 1);
+ *fileinfo->flags = msginfo->flags;
+ file_list = g_slist_prepend(file_list, fileinfo);
+ mlist = mlist->next;
+ }
+
+ file_list = g_slist_reverse(file_list);
+
+ return file_list;
+}
+
+void procmsg_message_file_list_free(MsgInfoList *file_list)
+{
+ GSList *cur;
+ MsgFileInfo *fileinfo;
+
+ for (cur = file_list; cur != NULL; cur = cur->next) {
+ fileinfo = (MsgFileInfo *)cur->data;
+ procmsg_msginfo_free(fileinfo->msginfo);
+ g_free(fileinfo->file);
+ g_free(fileinfo->flags);
+ g_free(fileinfo);
+ }
+
+ g_slist_free(file_list);
+}
+
FILE *procmsg_open_message(MsgInfo *msginfo)
{
FILE *fp;
{
FILE *fp;
MimeInfo *mimeinfo_;
+ glong fpos;
g_return_val_if_fail(msginfo != NULL, NULL);
}
if (MSG_IS_ENCRYPTED(msginfo->flags) &&
- (!msginfo->plaintext_file || msginfo->decryption_failed)) {
+ !msginfo->plaintext_file &&
+ !msginfo->decryption_failed) {
+ fpos = ftell(fp);
rfc2015_decrypt_message(msginfo, mimeinfo_, fp);
if (msginfo->plaintext_file &&
!msginfo->decryption_failed) {
fclose(fp);
return NULL;
}
+ } else {
+ if (fseek(fp, fpos, SEEK_SET) < 0)
+ perror("fseek");
}
}
return ret;
}
+void procmsg_get_filter_keyword(MsgInfo *msginfo, gchar **header, gchar **key,
+ PrefsFilterType type)
+{
+ static HeaderEntry hentry[] = {{"X-BeenThere:", NULL, TRUE},
+ {"X-ML-Name:", NULL, TRUE},
+ {"X-List:", NULL, TRUE},
+ {"X-Mailing-list:", NULL, TRUE},
+ {"List-Id:", NULL, TRUE},
+ {"X-Sequence:", NULL, TRUE},
+ {NULL, NULL, FALSE}};
+ enum
+ {
+ H_X_BEENTHERE = 0,
+ H_X_ML_NAME = 1,
+ H_X_LIST = 2,
+ H_X_MAILING_LIST = 3,
+ H_LIST_ID = 4,
+ H_X_SEQUENCE = 5
+ };
+
+ FILE *fp;
+
+ g_return_if_fail(msginfo != NULL);
+ g_return_if_fail(header != NULL);
+ g_return_if_fail(key != NULL);
+
+ *header = NULL;
+ *key = NULL;
+
+ switch (type) {
+ case FILTER_BY_NONE:
+ return;
+ case FILTER_BY_AUTO:
+ if ((fp = procmsg_open_message(msginfo)) == NULL)
+ return;
+ procheader_get_header_fields(fp, hentry);
+ fclose(fp);
+
+#define SET_FILTER_KEY(hstr, idx) \
+{ \
+ *header = g_strdup(hstr); \
+ *key = hentry[idx].body; \
+ hentry[idx].body = NULL; \
+}
+
+ if (hentry[H_X_BEENTHERE].body != NULL) {
+ SET_FILTER_KEY("header \"X-BeenThere\"", H_X_BEENTHERE);
+ } else if (hentry[H_X_ML_NAME].body != NULL) {
+ SET_FILTER_KEY("header \"X-ML-Name\"", H_X_ML_NAME);
+ } else if (hentry[H_X_LIST].body != NULL) {
+ SET_FILTER_KEY("header \"X-List\"", H_X_LIST);
+ } else if (hentry[H_X_MAILING_LIST].body != NULL) {
+ SET_FILTER_KEY("header \"X-Mailing-List\"", H_X_MAILING_LIST);
+ } else if (hentry[H_LIST_ID].body != NULL) {
+ SET_FILTER_KEY("header \"List-Id\"", H_LIST_ID);
+ extract_list_id_str(*key);
+ } else if (hentry[H_X_SEQUENCE].body != NULL) {
+ gchar *p;
+
+ SET_FILTER_KEY("X-Sequence", H_X_SEQUENCE);
+ p = *key;
+ while (*p != '\0') {
+ while (*p != '\0' && !isspace(*p)) p++;
+ while (isspace(*p)) p++;
+ if (isdigit(*p)) {
+ *p = '\0';
+ break;
+ }
+ }
+ g_strstrip(*key);
+ } else if (msginfo->subject) {
+ *header = g_strdup("subject");
+ *key = g_strdup(msginfo->subject);
+ }
+
+#undef SET_FILTER_KEY
+
+ g_free(hentry[H_X_BEENTHERE].body);
+ hentry[H_X_BEENTHERE].body = NULL;
+ g_free(hentry[H_X_ML_NAME].body);
+ hentry[H_X_ML_NAME].body = NULL;
+ g_free(hentry[H_X_LIST].body);
+ hentry[H_X_LIST].body = NULL;
+ g_free(hentry[H_X_MAILING_LIST].body);
+ hentry[H_X_MAILING_LIST].body = NULL;
+ g_free(hentry[H_LIST_ID].body);
+ hentry[H_LIST_ID].body = NULL;
+
+ break;
+ case FILTER_BY_FROM:
+ *header = g_strdup("from");
+ *key = g_strdup(msginfo->from);
+ break;
+ case FILTER_BY_TO:
+ *header = g_strdup("to");
+ *key = g_strdup(msginfo->to);
+ break;
+ case FILTER_BY_SUBJECT:
+ *header = g_strdup("subject");
+ *key = g_strdup(msginfo->subject);
+ break;
+ default:
+ break;
+ }
+}
+
void procmsg_empty_trash(void)
{
FolderItem *trash;
for (cur = folder_get_list(); cur != NULL; cur = cur->next) {
trash = FOLDER(cur->data)->trash;
- if (trash && trash->total > 0)
+ if (trash && trash->total_msgs > 0)
folder_item_remove_all_msg(trash);
}
}
+/*!
+ *\brief Send messages in queue
+ *
+ *\param queue Queue folder to process
+ *\param save_msgs Unused
+ *
+ *\return Number of messages sent, negative if an error occurred
+ * positive if no error occurred
+ */
gint procmsg_send_queue(FolderItem *queue, gboolean save_msgs)
{
- gint ret = 0;
+ gint ret = 1, count = 0;
GSList *list, *elem;
if (!queue)
folder_item_scan(queue);
list = folder_item_get_msg_list(queue);
-
for (elem = list; elem != NULL; elem = elem->next) {
gchar *file;
MsgInfo *msginfo;
msginfo = (MsgInfo *)(elem->data);
-
- file = folder_item_fetch_msg(queue, msginfo->msgnum);
- if (file) {
- if (procmsg_send_message_queue(file) < 0) {
- g_warning("Sending queued message %d failed.\n", msginfo->msgnum);
- ret = -1;
- } else {
- /* CLAWS:
- * We save in procmsg_send_message_queue because
- * we need the destination folder from the queue
- * header
-
- if (save_msgs)
- procmsg_save_to_outbox
- (queue->folder->outbox,
- file, TRUE);
-*/
- folder_item_remove_msg(queue, msginfo->msgnum);
+ if (!MSG_IS_LOCKED(msginfo->flags)) {
+ file = folder_item_fetch_msg(queue, msginfo->msgnum);
+ if (file) {
+ if (procmsg_send_message_queue(file) < 0) {
+ g_warning("Sending queued message %d failed.\n",
+ msginfo->msgnum);
+ ret = -1;
+ } else {
+ /* CLAWS:
+ * We save in procmsg_send_message_queue because
+ * we need the destination folder from the queue
+ * header
+
+ if (save_msgs)
+ procmsg_save_to_outbox
+ (queue->folder->outbox,
+ file, TRUE);
+ */
+ count++;
+ folder_item_remove_msg(queue, msginfo->msgnum);
+ }
+ g_free(file);
}
- g_free(file);
}
+ /* FIXME: supposedly if only one message is locked, and queue
+ * is being flushed, the following free says something like
+ * "freeing msg ## in folder (nil)". */
procmsg_msginfo_free(msginfo);
}
- return ret;
+ return ret * count;
}
gint procmsg_remove_special_headers(const gchar *in, const gchar *out)
gboolean is_queued)
{
gint num;
- MsgInfo *msginfo;
+ MsgInfo *msginfo, *tmp_msginfo;
+ MsgFlags flag = {0, 0};
debug_print("saving sent message...\n");
return -1;
folder_item_scan(outbox);
- if ((num = folder_item_add_msg(outbox, tmp, TRUE)) < 0) {
+ if ((num = folder_item_add_msg(outbox, tmp, &flag, TRUE)) < 0) {
g_warning("can't save message\n");
unlink(tmp);
return -1;
}
} else {
folder_item_scan(outbox);
- if ((num = folder_item_add_msg(outbox, file, FALSE)) < 0) {
+ if ((num = folder_item_add_msg
+ (outbox, file, &flag, FALSE)) < 0) {
g_warning("can't save message\n");
return -1;
}
return -1;
}
- msginfo = folder_item_get_msginfo(outbox, num);
+ msginfo = folder_item_get_msginfo(outbox, num); /* refcnt++ */
+ tmp_msginfo = procmsg_msginfo_get_full_info(msginfo); /* refcnt++ */
if (msginfo != NULL) {
- procmsg_msginfo_unset_flags(msginfo, ~0, 0);
- procmsg_msginfo_free(msginfo);
+ procmsg_msginfo_unset_flags(msginfo, ~0, 0);
+ procmsg_msginfo_free(msginfo); /* refcnt-- */
+ /* tmp_msginfo == msginfo */
+ if (tmp_msginfo && (msginfo->dispositionnotificationto ||
+ msginfo->returnreceiptto)) {
+ procmsg_msginfo_set_flags(msginfo, MSG_RETRCPT_SENT, 0);
+ procmsg_msginfo_free(msginfo); /* refcnt-- */
+ }
}
folder_item_update(outbox, TRUE);
return msginfo;
}
-MsgInfo *procmsg_msginfo_new()
+MsgInfo *procmsg_msginfo_new(void)
{
MsgInfo *newmsginfo;
g_free(file);
if (!full_msginfo) return NULL;
+ /* CLAWS: make sure we add the missing members; see:
+ * procheader.c::procheader_get_headernames() */
+ if (!msginfo->xface)
+ msginfo->xface = g_strdup(full_msginfo->xface);
+ if (!msginfo->dispositionnotificationto)
+ msginfo->dispositionnotificationto =
+ g_strdup(full_msginfo->dispositionnotificationto);
+ if (!msginfo->returnreceiptto)
+ msginfo->returnreceiptto = g_strdup
+ (full_msginfo->returnreceiptto);
+ procmsg_msginfo_free(full_msginfo);
+
+ return procmsg_msginfo_new_ref(msginfo);
+#if 0
full_msginfo->msgnum = msginfo->msgnum;
full_msginfo->size = msginfo->size;
full_msginfo->mtime = msginfo->mtime;
procmsg_msginfo_set_to_folder(full_msginfo, msginfo->to_folder);
return full_msginfo;
+#endif
}
void procmsg_msginfo_free(MsgInfo *msginfo)
mailac->mail_command && (* mailac->mail_command)) {
mailval = send_message_local(mailac->mail_command, fp);
local = 1;
- } else if (prefs_common.use_extsend && prefs_common.extsend_cmd) {
- mailval = send_message_local(prefs_common.extsend_cmd, fp);
- local = 1;
} else {
if (!mailac) {
mailac = account_find_from_smtp_server(from, smtpserver);
mailval = send_message_smtp(&tmp_ac, to_list, fp);
}
}
- if (mailval < 0) {
- if (!local)
- alertpanel_error_log(
- _("Error occurred while sending the message to `%s'."),
- mailac ? mailac->smtp_server : smtpserver);
- else
- alertpanel_error_log(
- _("Error occurred while sending the message with command `%s'."),
- (mailac && mailac->use_mail_command &&
- mailac->mail_command && (*mailac->mail_command)) ?
- mailac->mail_command : prefs_common.extsend_cmd);
- }
}
fseek(fp, filepos, SEEK_SET);
else
tokens = g_strsplit(fwdmessageid, "\x7f", 0);
item = folder_find_item_from_identifier(tokens[0]);
- if (item != NULL) {
+
+ /* check if queued message has valid folder and message id */
+ if (item != NULL && tokens[2] != NULL) {
MsgInfo *msginfo;
msginfo = folder_item_get_msginfo(item, atoi(tokens[1]));
- if ((msginfo != NULL) && (strcmp(msginfo->msgid, tokens[2]) != 0)) {
+
+ /* check if referring message exists and has a message id */
+ if ((msginfo != NULL) &&
+ (msginfo->msgid != NULL) &&
+ (strcmp(msginfo->msgid, tokens[2]) != 0)) {
procmsg_msginfo_free(msginfo);
msginfo = NULL;
}
return (newsval != 0 ? newsval : mailval);
}
-static void update_folder_msg_counts(FolderItem *item, MsgInfo *msginfo, MsgPermFlags old)
+static void update_folder_msg_counts(FolderItem *item, MsgInfo *msginfo, MsgPermFlags old_flags)
{
- MsgPermFlags new = msginfo->flags.perm_flags;
+ MsgPermFlags new_flags = msginfo->flags.perm_flags;
/* NEW flag */
- if (!(old & MSG_NEW) && (new & MSG_NEW)) {
- item->new++;
+ if (!(old_flags & MSG_NEW) && (new_flags & MSG_NEW)) {
+ item->new_msgs++;
}
- if ((old & MSG_NEW) && !(new & MSG_NEW)) {
- item->new--;
+ if ((old_flags & MSG_NEW) && !(new_flags & MSG_NEW)) {
+ item->new_msgs--;
}
/* UNREAD flag */
- if (!(old & MSG_UNREAD) && (new & MSG_UNREAD)) {
- item->unread++;
+ if (!(old_flags & MSG_UNREAD) && (new_flags & MSG_UNREAD)) {
+ item->unread_msgs++;
if (procmsg_msg_has_marked_parent(msginfo))
- item->unreadmarked++;
+ item->unreadmarked_msgs++;
}
- if ((old & MSG_UNREAD) && !(new & MSG_UNREAD)) {
- item->unread--;
+ if ((old_flags & MSG_UNREAD) && !(new_flags & MSG_UNREAD)) {
+ item->unread_msgs--;
if (procmsg_msg_has_marked_parent(msginfo))
- item->unreadmarked--;
+ item->unreadmarked_msgs--;
}
/* MARK flag */
- if (!(old & MSG_MARKED) && (new & MSG_MARKED)) {
+ if (!(old_flags & MSG_MARKED) && (new_flags & MSG_MARKED)) {
procmsg_update_unread_children(msginfo, TRUE);
}
- if ((old & MSG_MARKED) && !(new & MSG_MARKED)) {
+ if ((old_flags & MSG_MARKED) && !(new_flags & MSG_MARKED)) {
procmsg_update_unread_children(msginfo, FALSE);
}
}
update_folder_msg_counts(item, msginfo, perm_flags_old);
msginfo_update.msginfo = msginfo;
+ msginfo_update.flags = MSGINFO_UPDATE_FLAGS;
hooks_invoke(MSGINFO_UPDATE_HOOKLIST, &msginfo_update);
folder_item_update(msginfo->folder, F_ITEM_UPDATE_MSGCNT);
}
update_folder_msg_counts(item, msginfo, perm_flags_old);
msginfo_update.msginfo = msginfo;
+ msginfo_update.flags = MSGINFO_UPDATE_FLAGS;
hooks_invoke(MSGINFO_UPDATE_HOOKLIST, &msginfo_update);
folder_item_update(msginfo->folder, F_ITEM_UPDATE_MSGCNT);
}
MsgInfo *tmp = (MsgInfo *)cur->data;
if(MSG_IS_UNREAD(tmp->flags) && !MSG_IS_IGNORE_THREAD(tmp->flags)) {
if(newly_marked)
- info->folder->unreadmarked++;
+ info->folder->unreadmarked_msgs++;
else
- info->folder->unreadmarked--;
+ info->folder->unreadmarked_msgs--;
folder_item_update(info->folder, F_ITEM_UPDATE_MSGCNT);
}
procmsg_msginfo_free(tmp);
folder_item_update(msginfo->to_folder, F_ITEM_UPDATE_MSGCNT);
}
}
+
+/**
+ * Apply filtering actions to the msginfo
+ *
+ * \param msginfo The MsgInfo describing the message that should be filtered
+ * \return TRUE if the message was moved and MsgInfo is now invalid,
+ * FALSE otherwise
+ */
+gboolean procmsg_msginfo_filter(MsgInfo *msginfo)
+{
+ MailFilteringData mail_filtering_data;
+
+ mail_filtering_data.msginfo = msginfo;
+ if (hooks_invoke(MAIL_FILTERING_HOOKLIST, &mail_filtering_data))
+ return TRUE;
+
+ /* filter if enabled in prefs or move to inbox if not */
+ if((global_processing != NULL) &&
+ filter_message_by_msginfo(global_processing, msginfo))
+ return TRUE;
+
+ return FALSE;
+}