+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
( 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
MICRO_VERSION=1
INTERFACE_AGE=0
BINARY_AGE=0
-EXTRA_VERSION=53
+EXTRA_VERSION=54
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=
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;
for (p = tmpstr; *p != '\0'; p++) {
switch (*p) {
case '<':
- fputs("<", fp);
+ result = fputs("<", fp);
break;
case '>':
- fputs(">", fp);
+ result = fputs(">", fp);
break;
case '&':
- fputs("&", fp);
+ result = fputs("&", fp);
break;
case '\'':
- fputs("'", fp);
+ result = fputs("'", fp);
break;
case '\"':
- fputs(""", fp);
+ result = fputs(""", 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)
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)
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) {
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)
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);
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);
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);
}
}
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) {
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");
}
#define BOGOFILTER_H 1
#include <glib.h>
+#include "folder.h"
typedef struct _BogofilterConfig BogofilterConfig;
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
}
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();
}
spamassassin_unregister_hook();
}
procmsg_unregister_spam_learner(spamassassin_learn);
- procmsg_spam_set_folder(NULL);
+ procmsg_spam_set_folder(NULL, NULL);
return FALSE;
}
}
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;
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");
}
}
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;
+}
+
#define SPAMASSASSIN_H 1
#include <glib.h>
+#include "folder.h"
typedef struct _SpamAssassinConfig SpamAssassinConfig;
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
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();
}
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)
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);
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 {
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,