2007-01-24 [colin] 2.7.1cvs54
authorColin Leroy <colin@colino.net>
Wed, 24 Jan 2007 17:56:39 +0000 (17:56 +0000)
committerColin Leroy <colin@colino.net>
Wed, 24 Jan 2007 17:56:39 +0000 (17:56 +0000)
* src/folder.c
* src/common/xml.c
* src/common/xml.h
Make sure folderlist.xml is correctly
written before overwriting it.
* src/procmsg.c
* src/procmsg.h
* src/summaryview.c
* src/plugins/bogofilter/bogofilter.c
* src/plugins/bogofilter/bogofilter.h
* src/plugins/bogofilter/bogofilter_gtk.c
* src/plugins/spamassassin/spamassassin.c
* src/plugins/spamassassin/spamassassin.h
* src/plugins/spamassassin/spamassassin_gtk.c
Move spam to the correct trash folder after
learning, if spam directory isn't set.

15 files changed:
ChangeLog
PATCHSETS
configure.ac
src/common/xml.c
src/common/xml.h
src/folder.c
src/plugins/bogofilter/bogofilter.c
src/plugins/bogofilter/bogofilter.h
src/plugins/bogofilter/bogofilter_gtk.c
src/plugins/spamassassin/spamassassin.c
src/plugins/spamassassin/spamassassin.h
src/plugins/spamassassin/spamassassin_gtk.c
src/procmsg.c
src/procmsg.h
src/summaryview.c

index 0a5eafa..9d13131 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2007-01-24 [colin]     2.7.1cvs54
+
+       * src/folder.c
+       * src/common/xml.c
+       * src/common/xml.h
+               Make sure folderlist.xml is correctly
+               written before overwriting it.
+       * src/procmsg.c
+       * src/procmsg.h
+       * src/summaryview.c
+       * src/plugins/bogofilter/bogofilter.c
+       * src/plugins/bogofilter/bogofilter.h
+       * src/plugins/bogofilter/bogofilter_gtk.c
+       * src/plugins/spamassassin/spamassassin.c
+       * src/plugins/spamassassin/spamassassin.h
+       * src/plugins/spamassassin/spamassassin_gtk.c
+               Move spam to the correct trash folder after
+               learning, if spam directory isn't set.
+
 2007-01-23 [paul]      2.7.1cvs53
 
        * src/plugins/bogofilter/bogofilter_gtk.c
index 7b72f0f..2c7dc7e 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.5.2.49 -r 1.5.2.50 src/gtk/gtkutils.c;  ) > 2.7.1cvs51.patchset
 ( cvs diff -u -r 1.15.2.11 -r 1.15.2.12 src/addrcache.c;  cvs diff -u -r 1.9.2.6 -r 1.9.2.7 src/addrcache.h;  cvs diff -u -r 1.13.2.9 -r 1.13.2.10 src/addritem.c;  cvs diff -u -r 1.12.2.7 -r 1.12.2.8 src/addritem.h;  cvs diff -u -r 1.65.2.54 -r 1.65.2.55 src/codeconv.c;  cvs diff -u -r 1.15.2.18 -r 1.15.2.19 src/codeconv.h;  cvs diff -u -r 1.18.2.23 -r 1.18.2.24 src/jpilot.c;  cvs diff -u -r 1.10.2.4 -r 1.10.2.5 src/jpilot.h;  cvs diff -u -r 1.2.2.7 -r 1.2.2.8 src/ldapctrl.c;  cvs diff -u -r 1.1.4.7 -r 1.1.4.8 src/ldapctrl.h;  cvs diff -u -r 1.4.2.9 -r 1.4.2.10 src/ldapquery.h;  cvs diff -u -r 1.12.2.11 -r 1.12.2.12 src/ldif.c;  cvs diff -u -r 1.5.2.4 -r 1.5.2.5 src/ldif.h;  cvs diff -u -r 1.43.2.60 -r 1.43.2.61 src/toolbar.c;  cvs diff -u -r 1.1.4.5 -r 1.1.4.6 src/etpan/etpan-thread-manager.c;  cvs diff -u -r 1.1.4.4 -r 1.1.4.5 src/etpan/etpan-thread-manager.h;  cvs diff -u -r 1.5.2.50 -r 1.5.2.51 src/gtk/gtkutils.c;  cvs diff -u -r 1.4.2.30 -r 1.4.2.31 src/gtk/gtkutils.h;  ) > 2.7.1cvs52.patchset
 ( cvs diff -u -r 1.1.2.17 -r 1.1.2.18 src/plugins/bogofilter/bogofilter_gtk.c;  ) > 2.7.1cvs53.patchset
+( cvs diff -u -r 1.213.2.133 -r 1.213.2.134 src/folder.c;  cvs diff -u -r 1.150.2.90 -r 1.150.2.91 src/procmsg.c;  cvs diff -u -r 1.60.2.40 -r 1.60.2.41 src/procmsg.h;  cvs diff -u -r 1.395.2.281 -r 1.395.2.282 src/summaryview.c;  cvs diff -u -r 1.1.4.17 -r 1.1.4.18 src/common/xml.c;  cvs diff -u -r 1.1.4.8 -r 1.1.4.9 src/common/xml.h;  cvs diff -u -r 1.1.2.25 -r 1.1.2.26 src/plugins/bogofilter/bogofilter.c;  cvs diff -u -r 1.1.2.9 -r 1.1.2.10 src/plugins/bogofilter/bogofilter.h;  cvs diff -u -r 1.1.2.18 -r 1.1.2.19 src/plugins/bogofilter/bogofilter_gtk.c;  cvs diff -u -r 1.18.2.47 -r 1.18.2.48 src/plugins/spamassassin/spamassassin.c;  cvs diff -u -r 1.4.2.13 -r 1.4.2.14 src/plugins/spamassassin/spamassassin.h;  cvs diff -u -r 1.23.2.36 -r 1.23.2.37 src/plugins/spamassassin/spamassassin_gtk.c;  ) > 2.7.1cvs54.patchset
index 8b00df6..8c97e67 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=7
 MICRO_VERSION=1
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=53
+EXTRA_VERSION=54
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 8fe0a69..e8ef621 100644 (file)
@@ -542,7 +542,7 @@ gint xml_file_put_escape_str(FILE *fp, const gchar *str)
        const gchar *dest_codeset = CS_INTERNAL;
        gchar *tmpstr = NULL;
        const gchar *p;
-
+       int result = 0;
        g_return_val_if_fail(fp != NULL, -1);
 
        if (!str) return 0;
@@ -556,28 +556,28 @@ gint xml_file_put_escape_str(FILE *fp, const gchar *str)
        for (p = tmpstr; *p != '\0'; p++) {
                switch (*p) {
                case '<':
-                       fputs("&lt;", fp);
+                       result = fputs("&lt;", fp);
                        break;
                case '>':
-                       fputs("&gt;", fp);
+                       result = fputs("&gt;", fp);
                        break;
                case '&':
-                       fputs("&amp;", fp);
+                       result = fputs("&amp;", fp);
                        break;
                case '\'':
-                       fputs("&apos;", fp);
+                       result = fputs("&apos;", fp);
                        break;
                case '\"':
-                       fputs("&quot;", fp);
+                       result = fputs("&quot;", fp);
                        break;
                default:
-                       fputc(*p, fp);
+                       result = fputc(*p, fp);
                }
        }
 
        g_free(tmpstr);
-
-       return 0;
+       
+       return (result == EOF ? -1 : 0);
 }
 
 gint xml_file_put_xml_decl(FILE *fp)
@@ -585,8 +585,7 @@ gint xml_file_put_xml_decl(FILE *fp)
        g_return_val_if_fail(fp != NULL, -1);
        XML_STRING_TABLE_CREATE();
 
-       fprintf(fp, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", CS_INTERNAL);
-       return 0;
+       return fprintf(fp, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", CS_INTERNAL);
 }
 
 gint xml_file_put_node(FILE *fp, XMLNode *node)
@@ -682,27 +681,37 @@ static gint xml_get_parenthesis(XMLFile *file, gchar *buf, gint len)
        return 0;
 }
 
-static void xml_write_tree_recursive(GNode *node, FILE *fp)
+#define TRY(func) \
+if (!(func)) \
+{ \
+       g_warning("failed to write part of xml tree\n"); \
+       return -1; \
+} \
+
+static int xml_write_tree_recursive(GNode *node, FILE *fp)
 {
        gint i, depth;
        XMLTag *tag;
        GList *cur;
 
-       g_return_if_fail(node != NULL);
-       g_return_if_fail(fp != NULL);
+       g_return_val_if_fail(node != NULL, -1);
+       g_return_val_if_fail(fp != NULL, -1);
 
        depth = g_node_depth(node) - 1;
        for (i = 0; i < depth; i++)
-               fputs("    ", fp);
+               TRY(fputs("    ", fp) != EOF);
+
        tag = ((XMLNode *) node->data)->tag;
 
-       fprintf(fp, "<%s", tag->tag);
+       TRY(fprintf(fp, "<%s", tag->tag) > 0);
+
        for (cur = tag->attr; cur != NULL; cur = g_list_next(cur)) {
                XMLAttr *attr = (XMLAttr *) cur->data;
 
-               fprintf(fp, " %s=\"", attr->name);
-               xml_file_put_escape_str(fp, attr->value);
-               fputs("\"", fp);
+               TRY(fprintf(fp, " %s=\"", attr->name) > 0);
+               TRY(xml_file_put_escape_str(fp, attr->value) == 0);
+               TRY(fputs("\"", fp) != EOF);
+               
        }
 
        if (node->children) {
@@ -715,19 +724,23 @@ static void xml_write_tree_recursive(GNode *node, FILE *fp)
 
                        cur = child;
                        child = cur->next;
-                       xml_write_tree_recursive(cur, fp);
+                       TRY(xml_write_tree_recursive(cur, fp) == 0);
                }
 
                for (i = 0; i < depth; i++)
-                       fputs("    ", fp);
-               fprintf(fp, "</%s>\n", tag->tag);
+                       TRY(fputs("    ", fp) != EOF);
+               TRY(fprintf(fp, "</%s>\n", tag->tag) > 0);
        } else
-               fputs(" />\n", fp);
+               TRY(fputs(" />\n", fp) != EOF);
+       
+       return 0;
 }
 
-void xml_write_tree(GNode *node, FILE *fp)
+#undef TRY
+
+int xml_write_tree(GNode *node, FILE *fp)
 {
-       xml_write_tree_recursive(node, fp);
+       return xml_write_tree_recursive(node, fp);
 }
 
 static gpointer copy_node_func(gpointer nodedata, gpointer data)
index 3d7b025..f7084cf 100644 (file)
@@ -109,7 +109,7 @@ void xml_free_node          (XMLNode        *node);
 void xml_free_tree             (GNode          *node);
 
 void xml_free_tag              (XMLTag         *tag);
-void xml_write_tree            (GNode          *node,
+int  xml_write_tree            (GNode          *node,
                                 FILE           *fp);
 GNode *xml_copy_tree           (GNode          *node);
 
index 3eb9180..df78ee3 100644 (file)
@@ -792,7 +792,11 @@ void folder_write_list(void)
        path = folder_get_list_path();
        if ((pfile = prefs_write_open(path)) == NULL) return;
 
-       xml_file_put_xml_decl(pfile->fp);
+       if (xml_file_put_xml_decl(pfile->fp) < 0) {
+               prefs_file_close_revert(pfile);
+               g_warning("failed to start write folder list.\n");
+               return;         
+       }
        tag = xml_tag_new("folderlist");
 
        xmlnode = xml_node_new(tag, NULL);
@@ -814,11 +818,12 @@ void folder_write_list(void)
                g_node_append(rootnode, (gpointer) xml_copy_tree(node));
        }
 
-       xml_write_tree(rootnode, pfile->fp);
-
-       if (prefs_file_close(pfile) < 0)
+       if (xml_write_tree(rootnode, pfile->fp) < 0) {
+               prefs_file_close_revert(pfile);
                g_warning("failed to write folder list.\n");
-
+       } else if (prefs_file_close(pfile) < 0) {
+               g_warning("failed to write folder list.\n");
+       }
        xml_free_tree(rootnode);
 }
 
index 94f9c9d..5d89812 100644 (file)
@@ -856,12 +856,38 @@ gint plugin_init(gchar **error)
        }
 
        procmsg_register_spam_learner(bogofilter_learn);
-       procmsg_spam_set_folder(config.save_folder);
+       procmsg_spam_set_folder(config.save_folder, bogofilter_get_spam_folder);
 
        return 0;
        
 }
 
+FolderItem *bogofilter_get_spam_folder(MsgInfo *msginfo)
+{
+       FolderItem *item = folder_find_item_from_identifier(config.save_folder);
+
+       if (item || msginfo == NULL || msginfo->folder == NULL)
+               return item;
+
+       if (msginfo->folder->folder &&
+           msginfo->folder->folder->account && 
+           msginfo->folder->folder->account->set_trash_folder) {
+               item = folder_find_item_from_identifier(
+                       msginfo->folder->folder->account->trash_folder);
+       }
+
+       if (item == NULL && 
+           msginfo->folder->folder &&
+           msginfo->folder->folder->trash)
+               item = msginfo->folder->folder->trash;
+               
+       if (item == NULL)
+               item = folder_get_default_trash();
+               
+       debug_print("bogo spam dir: %s\n", folder_item_get_path(item));
+       return item;
+}
+
 void plugin_done(void)
 {
        if (hook_id != -1) {
@@ -873,7 +899,7 @@ void plugin_done(void)
        g_free(config.save_folder);
        bogofilter_gtk_done();
        procmsg_unregister_spam_learner(bogofilter_learn);
-       procmsg_spam_set_folder(NULL);
+       procmsg_spam_set_folder(NULL, NULL);
        debug_print("Bogofilter plugin unloaded\n");
 }
 
index 233e1ef..c504f6b 100644 (file)
@@ -21,6 +21,7 @@
 #define BOGOFILTER_H 1
 
 #include <glib.h>
+#include "folder.h"
 
 typedef struct _BogofilterConfig BogofilterConfig;
 
@@ -48,4 +49,5 @@ void bogofilter_gtk_done(void);
 int bogofilter_learn(MsgInfo *msginfo, GSList *msglist, gboolean spam);
 void bogofilter_register_hook(void);
 void bogofilter_unregister_hook(void);
+FolderItem *bogofilter_get_spam_folder(MsgInfo *msginfo);
 #endif
index 348dc92..e1275b6 100644 (file)
@@ -376,7 +376,7 @@ static void bogofilter_save_func(PrefsPage *_page)
        }
 
        procmsg_register_spam_learner(bogofilter_learn);
-       procmsg_spam_set_folder(config->save_folder);
+       procmsg_spam_set_folder(config->save_folder, bogofilter_get_spam_folder);
 
        bogofilter_save_config();
 }
index ff00b75..b6b59e3 100644 (file)
@@ -456,7 +456,7 @@ gboolean spamassassin_check_username(void)
                                spamassassin_unregister_hook();
                        }
                        procmsg_unregister_spam_learner(spamassassin_learn);
-                       procmsg_spam_set_folder(NULL);
+                       procmsg_spam_set_folder(NULL, NULL);
                        return FALSE;
                }
        }
@@ -501,7 +501,7 @@ gint plugin_init(gchar **error)
                if (config.transport == SPAMASSASSIN_TRANSPORT_TCP)
                        debug_print("Enabling learner with a remote spamassassin server requires spamc/spamd 3.1.x\n");
                procmsg_register_spam_learner(spamassassin_learn);
-               procmsg_spam_set_folder(config.save_folder);
+               procmsg_spam_set_folder(config.save_folder, spamassassin_get_spam_folder);
        }
 
        return 0;
@@ -517,7 +517,7 @@ void plugin_done(void)
        g_free(config.save_folder);
        spamassassin_gtk_done();
        procmsg_unregister_spam_learner(spamassassin_learn);
-       procmsg_spam_set_folder(NULL);
+       procmsg_spam_set_folder(NULL, NULL);
        debug_print("SpamAssassin plugin unloaded\n");
 }
 
@@ -582,3 +582,30 @@ void spamassassin_unregister_hook(void)
        }
        hook_id = -1;
 }
+
+FolderItem *spamassassin_get_spam_folder(MsgInfo *msginfo)
+{
+       FolderItem *item = folder_find_item_from_identifier(config.save_folder);
+
+       if (item || msginfo == NULL || msginfo->folder == NULL)
+               return item;
+
+       if (msginfo->folder->folder &&
+           msginfo->folder->folder->account && 
+           msginfo->folder->folder->account->set_trash_folder) {
+               item = folder_find_item_from_identifier(
+                       msginfo->folder->folder->account->trash_folder);
+       }
+
+       if (item == NULL && 
+           msginfo->folder->folder &&
+           msginfo->folder->folder->trash)
+               item = msginfo->folder->folder->trash;
+               
+       if (item == NULL)
+               item = folder_get_default_trash();
+               
+       debug_print("SA spam dir: %s\n", folder_item_get_path(item));
+       return item;
+}
+
index 207c461..08a3c5e 100644 (file)
@@ -21,6 +21,7 @@
 #define SPAMASSASSIN_H 1
 
 #include <glib.h>
+#include "folder.h"
 
 typedef struct _SpamAssassinConfig SpamAssassinConfig;
 
@@ -57,4 +58,6 @@ void spamassassin_gtk_done(void);
 int spamassassin_learn(MsgInfo *msginfo, GSList *msglist, gboolean spam);
 void spamassassin_register_hook(void);
 void spamassassin_unregister_hook(void);
+FolderItem *spamassassin_get_spam_folder(MsgInfo *msginfo);
+
 #endif
index b78b4c5..ac1c553 100644 (file)
@@ -519,12 +519,12 @@ static void spamassassin_save_func(PrefsPage *_page)
 
        if (!config->enable) {
                procmsg_unregister_spam_learner(spamassassin_learn);
-               procmsg_spam_set_folder(NULL);
+               procmsg_spam_set_folder(NULL, NULL);
        } else {
                if (config->transport == SPAMASSASSIN_TRANSPORT_TCP)
                        debug_print("enabling learner with a remote spamassassin server requires spamc/spamd 3.1.x\n");
                procmsg_register_spam_learner(spamassassin_learn);
-               procmsg_spam_set_folder(config->save_folder);
+               procmsg_spam_set_folder(config->save_folder, spamassassin_get_spam_folder);
        }
 
        spamassassin_save_config();
index 3256084..5b34da3 100644 (file)
@@ -2286,19 +2286,31 @@ int procmsg_spam_learner_learn (MsgInfo *info, GSList *list, gboolean spam)
 }
 
 static gchar *spam_folder_item = NULL;
-void procmsg_spam_set_folder (const char *item_identifier)
+static FolderItem * (*procmsg_spam_get_folder_func)(MsgInfo *msginfo) = NULL;
+void procmsg_spam_set_folder (const char *item_identifier, FolderItem *(*spam_get_folder_func)(MsgInfo *info))
 {
        g_free(spam_folder_item);
        if (item_identifier)
                spam_folder_item = g_strdup(item_identifier);
        else
                spam_folder_item = NULL;
+       if (spam_get_folder_func != NULL)
+               procmsg_spam_get_folder_func = spam_get_folder_func;
+       else
+               procmsg_spam_get_folder_func = NULL;
 }
 
-FolderItem *procmsg_spam_get_folder (void)
+FolderItem *procmsg_spam_get_folder (MsgInfo *msginfo)
 {
-       FolderItem *item = spam_folder_item ? folder_find_item_from_identifier(spam_folder_item) : NULL;
-       return item ? item : folder_get_default_trash();
+       FolderItem *item = NULL;
+       
+       if (procmsg_spam_get_folder_func) 
+               item = procmsg_spam_get_folder_func(msginfo);
+       if (item == NULL && spam_folder_item)
+               item = folder_find_item_from_identifier(spam_folder_item);
+       if (item == NULL)
+               item = folder_get_default_trash();
+       return item;
 }
 
 static void item_has_queued_mails(FolderItem *item, gpointer data)
index 5ddd9ed..81b74ea 100644 (file)
@@ -353,8 +353,8 @@ MsgInfo *procmsg_msginfo_new_from_mimeinfo
 void procmsg_register_spam_learner (int (*learn_func)(MsgInfo *info, GSList *list, gboolean spam));
 void procmsg_unregister_spam_learner (int (*learn_func)(MsgInfo *info, GSList *list, gboolean spam));
 gboolean procmsg_spam_can_learn                (void);
-void procmsg_spam_set_folder           (const char *item_identifier);
-FolderItem *procmsg_spam_get_folder    (void);
+void procmsg_spam_set_folder           (const char *item_identifier, FolderItem *(*spam_get_folder_func)(MsgInfo *info));
+FolderItem *procmsg_spam_get_folder    (MsgInfo *msginfo);
 int procmsg_spam_learner_learn         (MsgInfo *msginfo, GSList *msglist, gboolean spam);
 gboolean procmsg_have_queued_mails_fast (void);
 gboolean procmsg_is_sending(void);
index 537f78d..28a496d 100644 (file)
@@ -3544,8 +3544,9 @@ void summary_mark_as_spam(SummaryView *summaryview, guint action, GtkWidget *wid
                                continue;
                        if (is_spam) {
                                summary_msginfo_change_flags(msginfo, MSG_SPAM, 0, MSG_NEW|MSG_UNREAD, 0);
-                               if (procmsg_spam_get_folder() != summaryview->folder_item) {
-                                       summary_move_row_to(summaryview, row, procmsg_spam_get_folder());
+                               if (procmsg_spam_get_folder(msginfo) != summaryview->folder_item) {
+                                       summary_move_row_to(summaryview, row,
+                                                       procmsg_spam_get_folder(msginfo));
                                        moved = TRUE;
                                }
                        } else {
@@ -5942,7 +5943,8 @@ static gint func_name(GtkCList *clist,                                     \
 CMP_FUNC_DEF(summary_cmp_by_mark,
             MSG_IS_MARKED(msginfo1->flags) - MSG_IS_MARKED(msginfo2->flags))
 CMP_FUNC_DEF(summary_cmp_by_status,
-            MSG_IS_UNREAD(msginfo1->flags) - MSG_IS_UNREAD(msginfo2->flags))
+            (-(MSG_IS_SPAM(msginfo1->flags))+(MSG_IS_UNREAD(msginfo1->flags)<<1)+(MSG_IS_NEW(msginfo1->flags)<<2)) 
+            - (-(MSG_IS_SPAM(msginfo2->flags))+(MSG_IS_UNREAD(msginfo2->flags)<<1)+(MSG_IS_NEW(msginfo2->flags)<<2)) )
 CMP_FUNC_DEF(summary_cmp_by_mime,
             MSG_IS_WITH_ATTACHMENT(msginfo1->flags) - MSG_IS_WITH_ATTACHMENT(msginfo2->flags))
 CMP_FUNC_DEF(summary_cmp_by_label,