2006-02-27 [wwp] 2.0.0cvs86
authorTristan Chabredier <wwp@claws-mail.org>
Mon, 27 Feb 2006 22:15:06 +0000 (22:15 +0000)
committerTristan Chabredier <wwp@claws-mail.org>
Mon, 27 Feb 2006 22:15:06 +0000 (22:15 +0000)
* src/plugins/spamassassin/spamassassin.c
* src/plugins/spamassassin/spamassassin.h
* src/plugins/spamassassin/spamassassin_gtk.c
- added the ability to learn a remote spamassassin server (spamd),
using spamc.
- added the spamassassin option 'username', that applies to all
spamassassin operations (filtering, learning, local or remote).
The default username is the current unix user (if left blank
from gtk prefs or config file).
- commented out some unused code (notebook widget), removed unused
layout (hbox1).
- make more widgets sensitive to the transport type.

ChangeLog
PATCHSETS
configure.ac
src/plugins/spamassassin/spamassassin.c
src/plugins/spamassassin/spamassassin.h
src/plugins/spamassassin/spamassassin_gtk.c

index c0d73c44cefeedefff5de8cb1d7f8ecf65003c8b..3f7806f0c4974e9690bdb7098676e8218155ff86 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2006-02-27 [wwp]       2.0.0cvs86
+
+       * src/plugins/spamassassin/spamassassin.c
+       * src/plugins/spamassassin/spamassassin.h
+       * src/plugins/spamassassin/spamassassin_gtk.c
+               - added the ability to learn a remote spamassassin server (spamd),
+               using spamc.
+               - added the spamassassin option 'username', that applies to all
+               spamassassin operations (filtering, learning, local or remote).
+               The default username is the current unix user (if left blank
+               from gtk prefs or config file).
+               - commented out some unused code (notebook widget), removed unused
+               layout (hbox1).
+               - make more widgets sensitive to the transport type.
+
 2006-02-27 [colin]     2.0.0cvs85
 
        * src/plugins/spamassassin/spamassassin.c
 2006-02-27 [colin]     2.0.0cvs85
 
        * src/plugins/spamassassin/spamassassin.c
index 30feb1425ca62568d3564ba01b6a22e57ce9c5e5..98ee2dafeb021e4d4b20238c81a679f44568e369 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.150.2.52 -r 1.150.2.53 src/procmsg.c;  cvs diff -u -r 1.395.2.174 -r 1.395.2.175 src/summaryview.c;  cvs diff -u -r 1.68.2.16 -r 1.68.2.17 src/summaryview.h;  cvs diff -u -r 1.18.2.18 -r 1.18.2.19 src/plugins/spamassassin/spamassassin.c;  cvs diff -u -r 1.4.2.6 -r 1.4.2.7 src/plugins/spamassassin/spamassassin.h;  cvs diff -u -r 1.23.2.19 -r 1.23.2.20 src/plugins/spamassassin/spamassassin_gtk.c;  ) > 2.0.0cvs83.patchset
 ( cvs diff -u -r 1.654.2.1313 -r 1.654.2.1314 configure.ac;  cvs diff -u -r 1.155.2.36 -r 1.155.2.37 src/Makefile.am;  cvs diff -u -r 1.274.2.100 -r 1.274.2.101 src/mainwindow.c;  cvs diff -u -r 1.39.2.13 -r 1.39.2.14 src/mainwindow.h;  cvs diff -u -r 1.94.2.77 -r 1.94.2.78 src/messageview.c;  cvs diff -u -r 1.19.2.6 -r 1.19.2.7 src/messageview.h;  cvs diff -u -r 1.30.2.25 -r 1.30.2.26 src/prefs_toolbar.c;  cvs diff -u -r 1.150.2.53 -r 1.150.2.54 src/procmsg.c;  cvs diff -u -r 1.25.2.21 -r 1.25.2.22 src/stock_pixmap.c;  cvs diff -u -r 1.18.2.15 -r 1.18.2.16 src/stock_pixmap.h;  cvs diff -u -r 1.395.2.175 -r 1.395.2.176 src/summaryview.c;  cvs diff -u -r 1.43.2.39 -r 1.43.2.40 src/toolbar.c;  cvs diff -u -r 1.19.2.8 -r 1.19.2.9 src/toolbar.h;  diff -u /dev/null src/pixmaps/ham_btn.xpm;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/pixmaps/spam.xpm;  diff -u /dev/null src/pixmaps/spam_btn.xpm;  cvs diff -u -r 1.18.2.19 -r 1.18.2.20 src/plugins/spamassassin/spamassassin.c;  ) > 2.0.0cvs84.patchset
 ( cvs diff -u -r 1.18.2.20 -r 1.18.2.21 src/plugins/spamassassin/spamassassin.c;  ) > 2.0.0cvs85.patchset
 ( cvs diff -u -r 1.150.2.52 -r 1.150.2.53 src/procmsg.c;  cvs diff -u -r 1.395.2.174 -r 1.395.2.175 src/summaryview.c;  cvs diff -u -r 1.68.2.16 -r 1.68.2.17 src/summaryview.h;  cvs diff -u -r 1.18.2.18 -r 1.18.2.19 src/plugins/spamassassin/spamassassin.c;  cvs diff -u -r 1.4.2.6 -r 1.4.2.7 src/plugins/spamassassin/spamassassin.h;  cvs diff -u -r 1.23.2.19 -r 1.23.2.20 src/plugins/spamassassin/spamassassin_gtk.c;  ) > 2.0.0cvs83.patchset
 ( cvs diff -u -r 1.654.2.1313 -r 1.654.2.1314 configure.ac;  cvs diff -u -r 1.155.2.36 -r 1.155.2.37 src/Makefile.am;  cvs diff -u -r 1.274.2.100 -r 1.274.2.101 src/mainwindow.c;  cvs diff -u -r 1.39.2.13 -r 1.39.2.14 src/mainwindow.h;  cvs diff -u -r 1.94.2.77 -r 1.94.2.78 src/messageview.c;  cvs diff -u -r 1.19.2.6 -r 1.19.2.7 src/messageview.h;  cvs diff -u -r 1.30.2.25 -r 1.30.2.26 src/prefs_toolbar.c;  cvs diff -u -r 1.150.2.53 -r 1.150.2.54 src/procmsg.c;  cvs diff -u -r 1.25.2.21 -r 1.25.2.22 src/stock_pixmap.c;  cvs diff -u -r 1.18.2.15 -r 1.18.2.16 src/stock_pixmap.h;  cvs diff -u -r 1.395.2.175 -r 1.395.2.176 src/summaryview.c;  cvs diff -u -r 1.43.2.39 -r 1.43.2.40 src/toolbar.c;  cvs diff -u -r 1.19.2.8 -r 1.19.2.9 src/toolbar.h;  diff -u /dev/null src/pixmaps/ham_btn.xpm;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/pixmaps/spam.xpm;  diff -u /dev/null src/pixmaps/spam_btn.xpm;  cvs diff -u -r 1.18.2.19 -r 1.18.2.20 src/plugins/spamassassin/spamassassin.c;  ) > 2.0.0cvs84.patchset
 ( cvs diff -u -r 1.18.2.20 -r 1.18.2.21 src/plugins/spamassassin/spamassassin.c;  ) > 2.0.0cvs85.patchset
+( cvs diff -u -r 1.18.2.21 -r 1.18.2.22 src/plugins/spamassassin/spamassassin.c;  cvs diff -u -r 1.4.2.7 -r 1.4.2.8 src/plugins/spamassassin/spamassassin.h;  cvs diff -u -r 1.23.2.20 -r 1.23.2.21 src/plugins/spamassassin/spamassassin_gtk.c;  ) > 2.0.0cvs86.patchset
index 1b2dab29049c1baf789b1fffb65c1429f13e3a92..3e5b55e03b42ba45673a16b818f2318fd7a2858b 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=0
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=85
+EXTRA_VERSION=86
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 191c7130fa0245fcd8e2fe4c0a36155f98cacc01..38ad000110b24eeb38ac8c6bff11b51e2f64e0c0 100644 (file)
@@ -77,7 +77,6 @@ enum {
 
 static guint hook_id;
 static int flags = SPAMC_RAW_MODE | SPAMC_SAFE_FALLBACK | SPAMC_CHECK_ONLY;
 
 static guint hook_id;
 static int flags = SPAMC_RAW_MODE | SPAMC_SAFE_FALLBACK | SPAMC_CHECK_ONLY;
-static gchar *username = NULL;
 static MessageCallback message_callback;
 
 static SpamAssassinConfig config;
 static MessageCallback message_callback;
 
 static SpamAssassinConfig config;
@@ -99,6 +98,8 @@ static PrefParam param[] = {
         NULL, NULL, NULL},
        {"timeout", "30", &config.timeout, P_INT,
         NULL, NULL, NULL},
         NULL, NULL, NULL},
        {"timeout", "30", &config.timeout, P_INT,
         NULL, NULL, NULL},
+       {"username", "", &config.username, P_STRING,
+        NULL, NULL, NULL},
 
        {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
 };
 
        {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
 };
@@ -155,7 +156,7 @@ static gboolean msg_is_spam(FILE *fp)
                return FALSE;
        }
 
                return FALSE;
        }
 
-       if (message_filter(&trans, username, flags, &m) != EX_OK) {
+       if (message_filter(&trans, config.username, flags, &m) != EX_OK) {
                debug_print("filtering the message failed\n");
                message_cleanup(&m);
                return FALSE;
                debug_print("filtering the message failed\n");
                message_cleanup(&m);
                return FALSE;
@@ -268,41 +269,80 @@ void spamassassin_learn(MsgInfo *msginfo, GSList *msglist, gboolean spam)
                file = procmsg_get_message_file(msginfo);
                if (file == NULL)
                        return;
                file = procmsg_get_message_file(msginfo);
                if (file == NULL)
                        return;
-               cmd = g_strdup_printf("sa-learn %s %s %s", 
-                       prefs_common.work_offline?"-L":"",
-                       spam?"--spam":"--ham", file);
+               if (config.transport == SPAMASSASSIN_TRANSPORT_TCP) {
+                       cmd = g_strdup_printf("sa-learn -u %s %s %s %s",
+                                                       config.username,
+                                                       prefs_common.work_offline?"-L":"",
+                                                       spam?"--spam":"--ham", file);
+               } else {
+                       cmd = g_strdup_printf("spamc -d %s -p %u -u %s -t %u -s %u -L %s < %s",
+                                                       config.hostname, config.port, 
+                                                       config.username, config.timeout,
+                                                       config.max_size * 1024, spam?"spam":"ham", file);
+               }
        }
        if (msglist) {
        }
        if (msglist) {
-               GSList *cur;
+               GSList *cur = msglist;
                MsgInfo *info;
                MsgInfo *info;
-               cmd = g_strdup_printf("sa-learn %s %s", 
-                               prefs_common.work_offline?"-L":"",
-                               spam?"--spam":"--ham");
-               for (cur = msglist; cur; cur = cur->next) {
-                       info = (MsgInfo *)cur->data;
-                       gchar *tmpcmd = NULL;
-                       gchar *tmpfile = get_tmp_file();
-                       
-                       if (tmpfile &&
-                           copy_file(procmsg_get_message_file(info), tmpfile, TRUE) == 0) {                    
-                               tmpcmd = g_strconcat
-                                       (cmd, " ", tmpfile, NULL);
-                               g_free(cmd);
-                               cmd = tmpcmd;
+
+               if (config.transport == SPAMASSASSIN_TRANSPORT_TCP) {
+                       cmd = g_strdup_printf("spamc -d %s -p %u -u %s -t %u -s %u -L %s",
+                                                       config.hostname, config.port,
+                                                       config.username, config.timeout,
+                                                       config.max_size * 1024, spam?"spam":"ham");
+
+                       /* execute n-times the spamc command */
+                       for (; cur; cur = cur->next) {
+                               info = (MsgInfo *)cur->data;
+                               gchar *tmpcmd = NULL;
+                               gchar *tmpfile = get_tmp_file();
+
+                               if (tmpfile &&
+                               copy_file(procmsg_get_message_file(info), tmpfile, TRUE) == 0) {                        
+                                       tmpcmd = g_strconcat(cmd, " < ", tmpfile, NULL);
+                                       debug_print("%s\n", tmpcmd);
+                                       execute_command_line(tmpcmd, FALSE);
+                                       g_free(tmpcmd);
+                               }
+                               if (tmpfile)
+                                       g_free(tmpfile);
+                       }
+                       async = TRUE;
+
+                       g_free(cmd);
+                       return;
+               } else {
+                       cmd = g_strdup_printf("sa-learn -u %s %s %s",
+                                       config.username,
+                                       prefs_common.work_offline?"-L":"",
+                                       spam?"--spam":"--ham");
+
+                       /* concatenate all message tmpfiles to the sa-learn command-line */
+                       for (; cur; cur = cur->next) {
+                               info = (MsgInfo *)cur->data;
+                               gchar *tmpcmd = NULL;
+                               gchar *tmpfile = get_tmp_file();
+
+                               if (tmpfile &&
+                               copy_file(procmsg_get_message_file(info), tmpfile, TRUE) == 0) {                        
+                                       tmpcmd = g_strconcat(cmd, " ", tmpfile, NULL);
+                                       g_free(cmd);
+                                       cmd = tmpcmd;
+                               }
+                               if (tmpfile)
+                                       g_free(tmpfile);
                        }
                        }
-                       if (tmpfile)
-                               g_free(tmpfile);
+                       async = TRUE;
                }
                }
-               async = TRUE;
        }
        if (cmd == NULL)
                return;
        }
        if (cmd == NULL)
                return;
-       debug_print("%s\n",cmd);
+       debug_print("%s\n", cmd);
        /* only run async if we have a list, or we could end up
         * forking lots of perl processes and bury the machine */
        /* only run async if we have a list, or we could end up
         * forking lots of perl processes and bury the machine */
+       
        execute_command_line(cmd, async);
        g_free(cmd);
        execute_command_line(cmd, async);
        g_free(cmd);
-       
 }
 
 void spamassassin_save_config(void)
 }
 
 void spamassassin_save_config(void)
@@ -328,6 +368,20 @@ void spamassassin_save_config(void)
        prefs_file_close(pfile);
 }
 
        prefs_file_close(pfile);
 }
 
+gboolean spamassassin_check_username(void)
+{
+       if (config.username == NULL || config.username[0] == '\0') {
+               config.username = (gchar*)g_get_user_name();
+               if (config.username == NULL) {
+                       hooks_unregister_hook(MAIL_FILTERING_HOOKLIST, hook_id);
+                       procmsg_unregister_spam_learner(spamassassin_learn);
+                       procmsg_spam_set_folder(NULL);
+                       return FALSE;
+               }
+       }
+       return TRUE;
+}
+
 void spamassassin_set_message_callback(MessageCallback callback)
 {
        message_callback = callback;
 void spamassassin_set_message_callback(MessageCallback callback)
 {
        message_callback = callback;
@@ -353,17 +407,14 @@ gint plugin_init(gchar **error)
                return -1;
        }
 
                return -1;
        }
 
-       username = (gchar*)g_get_user_name();
-       if (username == NULL) {
-               hooks_unregister_hook(MAIL_FILTERING_HOOKLIST, hook_id);
-               *error = g_strdup("Failed to get username");
-               return -1;
-       }
-
        prefs_set_default(param);
        rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
        prefs_read_config(param, "SpamAssassin", rcpath, NULL);
        g_free(rcpath);
        prefs_set_default(param);
        rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
        prefs_read_config(param, "SpamAssassin", rcpath, NULL);
        g_free(rcpath);
+       if (!spamassassin_check_username()) {
+               *error = g_strdup("Failed to get username");
+               return -1;
+       }
        spamassassin_gtk_init();
                
        debug_print("Spamassassin plugin loaded\n");
        spamassassin_gtk_init();
                
        debug_print("Spamassassin plugin loaded\n");
@@ -371,13 +422,13 @@ gint plugin_init(gchar **error)
        if (config.transport == SPAMASSASSIN_DISABLED) {
                log_error("Spamassassin plugin is loaded but disabled by its preferences.\n");
        }
        if (config.transport == SPAMASSASSIN_DISABLED) {
                log_error("Spamassassin plugin is loaded but disabled by its preferences.\n");
        }
-       
-       if (config.transport != SPAMASSASSIN_DISABLED &&
-           config.transport != SPAMASSASSIN_TRANSPORT_TCP) {
+
+       if (config.transport != SPAMASSASSIN_DISABLED) {
+               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_register_spam_learner(spamassassin_learn);
                procmsg_spam_set_folder(config.save_folder);
-       } else if (config.transport == SPAMASSASSIN_TRANSPORT_TCP)
-               debug_print("disabling learner as it only works locally\n");
+       }
 
        return 0;
        
 
        return 0;
        
@@ -425,4 +476,3 @@ const gchar *plugin_version(void)
 {
        return VERSION;
 }
 {
        return VERSION;
 }
-
index e0526b856e2a0a6c634860d51fa338452473dce0..770a8f2a8d3174b8fc2c3bfe04a8cefdd3c1c890 100644 (file)
@@ -43,10 +43,12 @@ struct _SpamAssassinConfig
        gchar                   *save_folder;
        guint                    max_size;
        guint                    timeout;
        gchar                   *save_folder;
        guint                    max_size;
        guint                    timeout;
+       gchar                   *username;
 };
 
 SpamAssassinConfig *spamassassin_get_config          (void);
 void               spamassassin_save_config          (void);
 };
 
 SpamAssassinConfig *spamassassin_get_config          (void);
 void               spamassassin_save_config          (void);
+gint                   spamassassin_check_username           (void);  
 void               spamassassin_set_message_callback (MessageCallback callback);
 gint spamassassin_gtk_init(void);
 void spamassassin_gtk_done(void);
 void               spamassassin_set_message_callback (MessageCallback callback);
 gint spamassassin_gtk_init(void);
 void spamassassin_gtk_done(void);
index 2c779361031865d03f6cfa2c8dab40a5b19de2f1..b5c6b00186bdc9df007107bc600dfcc4c2fed634 100644 (file)
@@ -45,13 +45,15 @@ struct SpamAssassinPage
        PrefsPage page;
        
        GtkWidget *transport;
        PrefsPage page;
        
        GtkWidget *transport;
-       GtkWidget *transport_notebook;
+/*     GtkWidget *transport_notebook;*/
+       GtkWidget *username;
        GtkWidget *hostname;
        GtkWidget *colon;
        GtkWidget *port;
        GtkWidget *socket;
        GtkWidget *receive_spam;
        GtkWidget *save_folder;
        GtkWidget *hostname;
        GtkWidget *colon;
        GtkWidget *port;
        GtkWidget *socket;
        GtkWidget *receive_spam;
        GtkWidget *save_folder;
+       GtkWidget *save_folder_select;
        GtkWidget *max_size;
        GtkWidget *timeout;
 
        GtkWidget *max_size;
        GtkWidget *timeout;
 
@@ -108,28 +110,40 @@ static void show_transport(struct SpamAssassinPage *page, struct Transport *tran
                gtk_widget_show(page->colon);
                gtk_widget_show(page->port);
                gtk_widget_hide(page->socket);
                gtk_widget_show(page->colon);
                gtk_widget_show(page->port);
                gtk_widget_hide(page->socket);
+               gtk_widget_set_sensitive(page->username, FALSE);
                gtk_widget_set_sensitive(page->hostname, FALSE);
                gtk_widget_set_sensitive(page->colon, FALSE);
                gtk_widget_set_sensitive(page->port, FALSE);
                gtk_widget_set_sensitive(page->max_size, FALSE);
                gtk_widget_set_sensitive(page->timeout, FALSE);
                gtk_widget_set_sensitive(page->hostname, FALSE);
                gtk_widget_set_sensitive(page->colon, FALSE);
                gtk_widget_set_sensitive(page->port, FALSE);
                gtk_widget_set_sensitive(page->max_size, FALSE);
                gtk_widget_set_sensitive(page->timeout, FALSE);
+               gtk_widget_set_sensitive(page->receive_spam, FALSE);
+               gtk_widget_set_sensitive(page->save_folder, FALSE);
+               gtk_widget_set_sensitive(page->save_folder_select, FALSE);
                break;
        case PAGE_UNIX:
                gtk_widget_hide(page->hostname);
                gtk_widget_hide(page->colon);
                gtk_widget_hide(page->port);
                gtk_widget_show(page->socket);
                break;
        case PAGE_UNIX:
                gtk_widget_hide(page->hostname);
                gtk_widget_hide(page->colon);
                gtk_widget_hide(page->port);
                gtk_widget_show(page->socket);
+               gtk_widget_set_sensitive(page->username, TRUE);
                gtk_widget_set_sensitive(page->socket, TRUE);
                gtk_widget_set_sensitive(page->max_size, TRUE);
                gtk_widget_set_sensitive(page->timeout, TRUE);
                gtk_widget_set_sensitive(page->socket, TRUE);
                gtk_widget_set_sensitive(page->max_size, TRUE);
                gtk_widget_set_sensitive(page->timeout, TRUE);
+               gtk_widget_set_sensitive(page->receive_spam, TRUE);
+               gtk_widget_set_sensitive(page->save_folder, TRUE);
+               gtk_widget_set_sensitive(page->save_folder_select, TRUE);
                break;
        case PAGE_NETWORK:
                gtk_widget_show(page->hostname);
                gtk_widget_show(page->colon);
                gtk_widget_show(page->port);
                gtk_widget_hide(page->socket);
                break;
        case PAGE_NETWORK:
                gtk_widget_show(page->hostname);
                gtk_widget_show(page->colon);
                gtk_widget_show(page->port);
                gtk_widget_hide(page->socket);
+               gtk_widget_set_sensitive(page->username, TRUE);
                gtk_widget_set_sensitive(page->max_size, TRUE);
                gtk_widget_set_sensitive(page->timeout, TRUE);
                gtk_widget_set_sensitive(page->max_size, TRUE);
                gtk_widget_set_sensitive(page->timeout, TRUE);
+               gtk_widget_set_sensitive(page->receive_spam, TRUE);
+               gtk_widget_set_sensitive(page->save_folder, TRUE);
+               gtk_widget_set_sensitive(page->save_folder_select, TRUE);
                if (transport->pageflags & NETWORK_HOSTNAME) {
                        gtk_widget_set_sensitive(page->hostname, TRUE);
                        gtk_widget_set_sensitive(page->colon, TRUE);
                if (transport->pageflags & NETWORK_HOSTNAME) {
                        gtk_widget_set_sensitive(page->hostname, TRUE);
                        gtk_widget_set_sensitive(page->colon, TRUE);
@@ -143,7 +157,7 @@ static void show_transport(struct SpamAssassinPage *page, struct Transport *tran
        default:
                break;
        }
        default:
                break;
        }
-       gtk_notebook_set_current_page(GTK_NOTEBOOK(page->transport_notebook), transport->page);
+/*     gtk_notebook_set_current_page(GTK_NOTEBOOK(page->transport_notebook), transport->page);*/
 }
 
 static void transport_sel_cb(GtkMenuItem *menuitem, gpointer data)
 }
 
 static void transport_sel_cb(GtkMenuItem *menuitem, gpointer data)
@@ -164,14 +178,16 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
        guint i, active;
 
        GtkWidget *table;
        guint i, active;
 
        GtkWidget *table;
+       GtkWidget *label2;
        GtkWidget *label3;
        GtkWidget *label4;
        GtkWidget *label3;
        GtkWidget *label4;
+       GtkWidget *hbox1;
        GtkWidget *hbox4;
        GtkWidget *transport;
        GtkWidget *transport_menu;
        GtkWidget *hbox4;
        GtkWidget *transport;
        GtkWidget *transport_menu;
-       GtkWidget *transport_notebook;
-       GtkWidget *hbox1;
+/*     GtkWidget *transport_notebook;*/
        GtkWidget *spamd_hbox;
        GtkWidget *spamd_hbox;
+       GtkWidget *username;
        GtkWidget *hostname;
        GtkWidget *colon;
        GtkObject *port_adj;
        GtkWidget *hostname;
        GtkWidget *colon;
        GtkObject *port_adj;
@@ -195,7 +211,7 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
 
        tooltips = gtk_tooltips_new();
 
 
        tooltips = gtk_tooltips_new();
 
-       table = gtk_table_new(8, 3, FALSE);
+       table = gtk_table_new(9, 3, FALSE);
        gtk_widget_show(table);
        gtk_container_set_border_width(GTK_CONTAINER(table), 8);
        gtk_table_set_row_spacings(GTK_TABLE(table), 4);
        gtk_widget_show(table);
        gtk_container_set_border_width(GTK_CONTAINER(table), 8);
        gtk_table_set_row_spacings(GTK_TABLE(table), 4);
@@ -216,7 +232,7 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
        gtk_box_pack_end(GTK_BOX(hbox4), transport, FALSE, FALSE, 0);
        transport_menu = gtk_menu_new();
 
        gtk_box_pack_end(GTK_BOX(hbox4), transport, FALSE, FALSE, 0);
        transport_menu = gtk_menu_new();
 
-       transport_notebook = gtk_notebook_new();
+/*     transport_notebook = gtk_notebook_new();
        gtk_widget_show(transport_notebook);
        gtk_table_attach(GTK_TABLE(table), transport_notebook, 1, 2, 1, 2,
                         (GtkAttachOptions) (GTK_FILL),
        gtk_widget_show(transport_notebook);
        gtk_table_attach(GTK_TABLE(table), transport_notebook, 1, 2, 1, 2,
                         (GtkAttachOptions) (GTK_FILL),
@@ -226,14 +242,25 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
                                   FALSE);
        gtk_notebook_set_show_border(GTK_NOTEBOOK(transport_notebook),
                                     FALSE);
                                   FALSE);
        gtk_notebook_set_show_border(GTK_NOTEBOOK(transport_notebook),
                                     FALSE);
+*/
 
        hbox1 = gtk_hbox_new(FALSE, 8);
        gtk_widget_show(hbox1);
 
        hbox1 = gtk_hbox_new(FALSE, 8);
        gtk_widget_show(hbox1);
-       gtk_container_add(GTK_CONTAINER(transport_notebook), hbox1);
+       gtk_table_attach(GTK_TABLE(table), hbox1, 0, 1, 1, 2,
+                        (GtkAttachOptions) (GTK_FILL),
+                        (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+       label2 = gtk_label_new(_("User"));
+       gtk_widget_show(label2);
+       gtk_box_pack_start(GTK_BOX(hbox1), label2, FALSE, FALSE, 0);
+
+       username = gtk_entry_new();
+       gtk_widget_show(username);
+       gtk_box_pack_end(GTK_BOX(hbox1), username, FALSE, FALSE, 0);
 
        spamd_hbox = gtk_hbox_new (FALSE, 8);
        gtk_widget_show (spamd_hbox);
 
        spamd_hbox = gtk_hbox_new (FALSE, 8);
        gtk_widget_show (spamd_hbox);
-       gtk_table_attach (GTK_TABLE (table), spamd_hbox, 0, 1, 1, 2,
+       gtk_table_attach (GTK_TABLE (table), spamd_hbox, 0, 1, 2, 3,
                          (GtkAttachOptions) (GTK_FILL),
                          (GtkAttachOptions) (GTK_FILL), 0, 0);
 
                          (GtkAttachOptions) (GTK_FILL),
                          (GtkAttachOptions) (GTK_FILL), 0, 0);
 
@@ -268,7 +295,7 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
 
        hbox3 = gtk_hbox_new (FALSE, 8);
        gtk_widget_show (hbox3);
 
        hbox3 = gtk_hbox_new (FALSE, 8);
        gtk_widget_show (hbox3);
-       gtk_table_attach (GTK_TABLE (table), hbox3, 0, 1, 2, 3,
+       gtk_table_attach (GTK_TABLE (table), hbox3, 0, 1, 3, 4,
                          (GtkAttachOptions) (GTK_FILL),
                          (GtkAttachOptions) (GTK_FILL), 0, 0);
 
                          (GtkAttachOptions) (GTK_FILL),
                          (GtkAttachOptions) (GTK_FILL), 0, 0);
 
@@ -287,13 +314,13 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
 
        label11 = gtk_label_new(_("kB"));
        gtk_widget_show(label11);
 
        label11 = gtk_label_new(_("kB"));
        gtk_widget_show(label11);
-       gtk_table_attach(GTK_TABLE(table), label11, 1, 2, 2, 3,
+       gtk_table_attach(GTK_TABLE(table), label11, 1, 2, 3, 4,
                         (GtkAttachOptions) (GTK_FILL),
                         (GtkAttachOptions) (GTK_FILL), 0, 0);
 
        hbox6 = gtk_hbox_new(FALSE, 8);
        gtk_widget_show(hbox6);
                         (GtkAttachOptions) (GTK_FILL),
                         (GtkAttachOptions) (GTK_FILL), 0, 0);
 
        hbox6 = gtk_hbox_new(FALSE, 8);
        gtk_widget_show(hbox6);
-       gtk_table_attach(GTK_TABLE(table), hbox6, 0, 1, 3, 4,
+       gtk_table_attach(GTK_TABLE(table), hbox6, 0, 1, 4, 5,
                         (GtkAttachOptions) (GTK_FILL),
                         (GtkAttachOptions) (GTK_FILL), 0, 0);
 
                         (GtkAttachOptions) (GTK_FILL),
                         (GtkAttachOptions) (GTK_FILL), 0, 0);
 
@@ -312,13 +339,13 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
 
        label16 = gtk_label_new(_("s"));
        gtk_widget_show(label16);
 
        label16 = gtk_label_new(_("s"));
        gtk_widget_show(label16);
-       gtk_table_attach(GTK_TABLE(table), label16, 1, 2, 3, 4,
+       gtk_table_attach(GTK_TABLE(table), label16, 1, 2, 4, 5,
                         (GtkAttachOptions) (GTK_FILL),
                         (GtkAttachOptions) (GTK_FILL), 0, 0);
 
        receive_spam = gtk_check_button_new_with_label(_("Save Spam"));
        gtk_widget_show(receive_spam);
                         (GtkAttachOptions) (GTK_FILL),
                         (GtkAttachOptions) (GTK_FILL), 0, 0);
 
        receive_spam = gtk_check_button_new_with_label(_("Save Spam"));
        gtk_widget_show(receive_spam);
-       gtk_table_attach(GTK_TABLE(table), receive_spam, 0, 1, 4, 5,
+       gtk_table_attach(GTK_TABLE(table), receive_spam, 0, 1, 5, 6,
                         (GtkAttachOptions) (GTK_FILL),
                         (GtkAttachOptions) (0), 0, 0);
        gtk_tooltips_set_tip(tooltips, receive_spam,
                         (GtkAttachOptions) (GTK_FILL),
                         (GtkAttachOptions) (0), 0, 0);
        gtk_tooltips_set_tip(tooltips, receive_spam,
@@ -327,7 +354,7 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
 
        hbox2 = gtk_hbox_new (FALSE, 8);
        gtk_widget_show (hbox2);
 
        hbox2 = gtk_hbox_new (FALSE, 8);
        gtk_widget_show (hbox2);
-       gtk_table_attach (GTK_TABLE (table), hbox2, 0, 1, 5, 6,
+       gtk_table_attach (GTK_TABLE (table), hbox2, 0, 1, 6, 7,
                          (GtkAttachOptions) (GTK_FILL),
                          (GtkAttachOptions) (GTK_FILL), 0, 0);
        SET_TOGGLE_SENSITIVITY (receive_spam, hbox2);
                          (GtkAttachOptions) (GTK_FILL),
                          (GtkAttachOptions) (GTK_FILL), 0, 0);
        SET_TOGGLE_SENSITIVITY (receive_spam, hbox2);
@@ -356,6 +383,8 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
        g_signal_connect(G_OBJECT(save_folder_select), "released",
                         G_CALLBACK(foldersel_cb), page);
 
        g_signal_connect(G_OBJECT(save_folder_select), "released",
                         G_CALLBACK(foldersel_cb), page);
 
+       if (config->username != NULL)
+               gtk_entry_set_text(GTK_ENTRY(username), config->username);
        if (config->hostname != NULL)
                gtk_entry_set_text(GTK_ENTRY(hostname), config->hostname);
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(port), (float) config->port);
        if (config->hostname != NULL)
                gtk_entry_set_text(GTK_ENTRY(hostname), config->hostname);
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(port), (float) config->port);
@@ -366,13 +395,15 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(timeout), (float) config->timeout);
        
        page->transport = transport;
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(timeout), (float) config->timeout);
        
        page->transport = transport;
-       page->transport_notebook = transport_notebook;
+/*     page->transport_notebook = transport_notebook;*/
+       page->username = username;
        page->hostname = hostname;
        page->colon = colon;
        page->port = port;
        page->socket = socket;
        page->receive_spam = receive_spam;
        page->save_folder = save_folder;
        page->hostname = hostname;
        page->colon = colon;
        page->port = port;
        page->socket = socket;
        page->receive_spam = receive_spam;
        page->save_folder = save_folder;
+       page->save_folder_select = save_folder_select;
        page->max_size = max_size;
        page->timeout = timeout;
 
        page->max_size = max_size;
        page->timeout = timeout;
 
@@ -415,6 +446,11 @@ static void spamassassin_save_func(PrefsPage *_page)
        /* enable */
        config->transport = page->trans;
 
        /* enable */
        config->transport = page->trans;
 
+       /* username */
+       g_free(config->username);
+       config->username = gtk_editable_get_chars(GTK_EDITABLE(page->username), 0, -1);
+       spamassassin_check_username();
+
        /* hostname */
        g_free(config->hostname);
        config->hostname = gtk_editable_get_chars(GTK_EDITABLE(page->hostname), 0, -1);
        /* hostname */
        g_free(config->hostname);
        config->hostname = gtk_editable_get_chars(GTK_EDITABLE(page->hostname), 0, -1);
@@ -439,13 +475,12 @@ static void spamassassin_save_func(PrefsPage *_page)
        /* timeout */
        config->timeout = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(page->timeout));
 
        /* timeout */
        config->timeout = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(page->timeout));
 
-       if (config->transport == SPAMASSASSIN_DISABLED ||
-           config->transport == SPAMASSASSIN_TRANSPORT_TCP) {
+       if (config->transport == SPAMASSASSIN_DISABLED) {
                procmsg_unregister_spam_learner(spamassassin_learn);
                procmsg_spam_set_folder(NULL);
                procmsg_unregister_spam_learner(spamassassin_learn);
                procmsg_spam_set_folder(NULL);
-               if (config->transport == SPAMASSASSIN_TRANSPORT_TCP)
-                       debug_print("disabling learner as it only works locally\n");
        } else {
        } 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_register_spam_learner(spamassassin_learn);
                procmsg_spam_set_folder(config->save_folder);
        }