aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog14
-rw-r--r--mail/em-junk-filter.c451
-rw-r--r--mail/mail-session.c2
3 files changed, 365 insertions, 102 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 0592cf37f0..805549ef2f 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,17 @@
+2004-10-12 Radek Doulik <rodo@ximian.com>
+
+ * em-junk-filter.c: when starting new spamd, call it with
+ --socketpath parameter to use unix sockets instead of opening TCP
+ port. kill such started daemon in finalize callback which is
+ installed by atexit. also try to respawn spamd in case spamc
+ returns error, if respawning is too fast (8 restarts in last 5
+ minutes) fallback to spamassassin
+
+ * mail-component.c (impl_quit): call mail_session_quit
+
+ * mail-session.c (mail_session_init): call junk plugin init
+ (mail_session_quit): new method, called on evo exit
+
2004-11-22 Joan Sanfeliu <joan@fibranet.com>
* mail-config.glade : Evolution word spelled with an uppercase E
diff --git a/mail/em-junk-filter.c b/mail/em-junk-filter.c
index efc1cfdc3a..4084dbb825 100644
--- a/mail/em-junk-filter.c
+++ b/mail/em-junk-filter.c
@@ -33,11 +33,15 @@
#include <signal.h>
#include <string.h>
#include <pthread.h>
+#include <signal.h>
+#include <time.h>
#include <camel/camel-file-utils.h>
#include <camel/camel-data-wrapper.h>
#include <camel/camel-stream-fs.h>
+#include <camel/camel-stream-mem.h>
#include <camel/camel-i18n.h>
+#include <e-util/e-mktemp.h>
#include "mail-session.h"
#include "em-junk-filter.h"
@@ -48,12 +52,17 @@
static pthread_mutex_t em_junk_sa_init_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t em_junk_sa_report_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t em_junk_sa_preferred_socket_path_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t em_junk_sa_spamd_restart_lock = PTHREAD_MUTEX_INITIALIZER;
static const char *em_junk_sa_get_name (void);
static gboolean em_junk_sa_check_junk (CamelMimeMessage *msg);
static void em_junk_sa_report_junk (CamelMimeMessage *msg);
static void em_junk_sa_report_notjunk (CamelMimeMessage *msg);
static void em_junk_sa_commit_reports (void);
+static void em_junk_sa_init (void);
+static void em_junk_sa_finalize (void);
+static void em_junk_sa_kill_spamd (void);
static EMJunkPlugin spam_assassin_plugin = {
{
@@ -63,6 +72,7 @@ static EMJunkPlugin spam_assassin_plugin = {
em_junk_sa_report_junk,
em_junk_sa_report_notjunk,
em_junk_sa_commit_reports,
+ em_junk_sa_init,
},
NULL,
NULL
@@ -72,14 +82,24 @@ static gboolean em_junk_sa_tested = FALSE;
static gboolean em_junk_sa_spamd_tested = FALSE;
static gboolean em_junk_sa_use_spamc = FALSE;
static gboolean em_junk_sa_available = FALSE;
-static int em_junk_sa_spamd_port = -1;
+static gboolean em_junk_sa_system_spamd_available = FALSE;
+static gboolean em_junk_sa_new_daemon_started = FALSE;
+static char *em_junk_sa_socket_path = NULL;
+static char *em_junk_sa_spamd_pidfile = NULL;
static char *em_junk_sa_spamc_binary = NULL;
static GConfClient *em_junk_sa_gconf = NULL;
/* volatile so not cached between threads */
static volatile gboolean em_junk_sa_local_only;
static volatile gboolean em_junk_sa_use_daemon;
-static volatile int em_junk_sa_daemon_port;
+static char * em_junk_sa_preferred_socket_path;
+
+static char *em_junk_sa_spamc_binaries [3] = {"spamc", "/usr/sbin/spamc", NULL};
+static char *em_junk_sa_spamd_binaries [3] = {"spamd", "/usr/sbin/spamd", NULL};
+
+#define SPAMD_RESTARTS_SIZE 8
+static time_t em_junk_sa_spamd_restarts [SPAMD_RESTARTS_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0};
+static int em_junk_sa_spamd_restarts_count = 0;
static const char *
em_junk_sa_get_name (void)
@@ -88,9 +108,9 @@ em_junk_sa_get_name (void)
}
static int
-pipe_to_sa_with_error (CamelMimeMessage *msg, const char *in, char **argv, int rv_err)
+pipe_to_sa_full (CamelMimeMessage *msg, const char *in, char **argv, int rv_err, int wait_for_termination, GByteArray *output_buffer)
{
- int result, status, errnosav, fds[2];
+ int result, status, errnosav, fds[2], out_fds[2];
CamelStream *stream;
char *program;
pid_t pid;
@@ -120,6 +140,13 @@ pipe_to_sa_with_error (CamelMimeMessage *msg, const char *in, char **argv, int r
return rv_err;
}
+ if (output_buffer && pipe (out_fds) == -1) {
+ errnosav = errno;
+ d(printf ("failed to create a pipe (for use with spamassassin: %s\n", strerror (errno)));
+ errno = errnosav;
+ return rv_err;
+ }
+
if (!(pid = fork ())) {
/* child process */
int maxfd, fd, nullfd;
@@ -127,10 +154,14 @@ pipe_to_sa_with_error (CamelMimeMessage *msg, const char *in, char **argv, int r
nullfd = open ("/dev/null", O_WRONLY);
if (dup2 (fds[0], STDIN_FILENO) == -1 ||
- dup2 (nullfd, STDOUT_FILENO) == -1 ||
- dup2 (nullfd, STDERR_FILENO) == -1)
+ dup2 (nullfd, STDERR_FILENO) == -1 ||
+ (output_buffer == NULL && dup2 (nullfd, STDOUT_FILENO) == -1) ||
+ (output_buffer != NULL && dup2 (out_fds[1], STDOUT_FILENO) == -1))
_exit (rv_err & 0377);
-
+ close (fds [0]);
+ if (output_buffer)
+ close (out_fds [1]);
+
setsid ();
maxfd = sysconf (_SC_OPEN_MAX);
@@ -149,6 +180,8 @@ pipe_to_sa_with_error (CamelMimeMessage *msg, const char *in, char **argv, int r
/* parent process */
close (fds[0]);
+ if (output_buffer)
+ close (out_fds [1]);
if (msg) {
stream = camel_stream_fs_new_with_fd (fds[1]);
@@ -161,54 +194,92 @@ pipe_to_sa_with_error (CamelMimeMessage *msg, const char *in, char **argv, int r
camel_write (fds[1], in, strlen (in));
close (fds[1]);
}
+
+ if (output_buffer) {
+ CamelStreamMem *memstream;
+
+ stream = camel_stream_fs_new_with_fd (out_fds[0]);
+
+ memstream = (CamelStreamMem *) camel_stream_mem_new ();
+ camel_stream_mem_set_byte_array (memstream, output_buffer);
+
+ camel_stream_write_to_stream (stream, (CamelStream *) memstream);
+ camel_object_unref (stream);
+ g_byte_array_append (output_buffer, "", 1);
+
+ d(printf ("child process output: %s len: %d\n", output_buffer->data, output_buffer->len));
+ }
- result = waitpid (pid, &status, 0);
+ if (wait_for_termination) {
+ d(printf ("wait for child %d termination\n", pid));
+ result = waitpid (pid, &status, 0);
- if (result == -1 && errno == EINTR) {
- /* child process is hanging... */
- kill (pid, SIGTERM);
- sleep (1);
- result = waitpid (pid, &status, WNOHANG);
- if (result == 0) {
- /* ...still hanging, set phasers to KILL */
- kill (pid, SIGKILL);
+ d(printf ("child %d terminated with result %d status %d exited %d exitstatus %d\n", pid, result, status, WIFEXITED (status), WEXITSTATUS (status)));
+
+ if (result == -1 && errno == EINTR) {
+ /* child process is hanging... */
+ kill (pid, SIGTERM);
sleep (1);
result = waitpid (pid, &status, WNOHANG);
+ if (result == 0) {
+ /* ...still hanging, set phasers to KILL */
+ kill (pid, SIGKILL);
+ sleep (1);
+ result = waitpid (pid, &status, WNOHANG);
+ }
}
- }
- if (result != -1 && WIFEXITED (status))
- return WEXITSTATUS (status);
- else
- return rv_err;
+ if (result != -1 && WIFEXITED (status))
+ return WEXITSTATUS (status);
+ else
+ return rv_err;
+ } else
+ return 0;
}
static int
pipe_to_sa (CamelMimeMessage *msg, const char *in, char **argv)
{
- return pipe_to_sa_with_error (msg, in, argv, -1);
+ return pipe_to_sa_full (msg, in, argv, -1, 1, NULL);
+}
+
+static char *
+em_junk_sa_get_socket_path ()
+{
+ if (em_junk_sa_preferred_socket_path)
+ return em_junk_sa_preferred_socket_path;
+ else
+ return em_junk_sa_socket_path;
}
static gboolean
-em_junk_sa_test_spamd_running (char *binary, int port)
+em_junk_sa_test_spamd_running (char *binary, gboolean system)
{
- char port_buf[12], *argv[5];
+ char *argv[5];
int i = 0;
-
- d(fprintf (stderr, "test if spamd is running (port %d) using %s\n", port, binary));
+ gboolean rv;
+
+ pthread_mutex_lock (&em_junk_sa_preferred_socket_path_lock);
+
+ d(fprintf (stderr, "test if spamd is running (system %d) or using socket path %s\n", system, em_junk_sa_get_socket_path ()));
argv[i++] = binary;
argv[i++] = "-x";
- if (port > 0) {
- sprintf (port_buf, "%d", port);
- argv[i++] = "-p";
- argv[i++] = port_buf;
+ if (!system) {
+ argv[i++] = "-U";
+ argv[i++] = em_junk_sa_get_socket_path ();
}
argv[i] = NULL;
- return pipe_to_sa (NULL, "From test@127.0.0.1", argv) == 0;
+ rv = pipe_to_sa (NULL, "From test@127.0.0.1", argv) == 0;
+
+ d(fprintf (stderr, "result: %d (%s)\n", rv, rv ? "success" : "failed"));
+
+ pthread_mutex_unlock (&em_junk_sa_preferred_socket_path_lock);
+
+ return rv;
}
static void
@@ -231,37 +302,93 @@ em_junk_sa_test_spamassassin (void)
#define MAX_SPAMD_PORTS 1
static gboolean
-em_junk_sa_run_spamd (char *binary, int *port)
+em_junk_sa_run_spamd (char *binary)
{
- char *argv[6];
- char port_buf[12];
- int i, p = em_junk_sa_daemon_port;
+ char *argv[8];
+ int i;
+ gboolean rv = FALSE;
+
+ pthread_mutex_lock (&em_junk_sa_preferred_socket_path_lock);
d(fprintf (stderr, "looks like spamd is not running\n"));
i = 0;
argv[i++] = binary;
- argv[i++] = "--port";
- argv[i++] = port_buf;
+ argv[i++] = "--socketpath";
+ argv[i++] = em_junk_sa_get_socket_path ();
if (em_junk_sa_local_only)
argv[i++] = "--local";
- argv[i++] = "--daemonize";
+ //argv[i++] = "--daemonize";
+ argv[i++] = "--pidfile";
+ argv[i++] = em_junk_sa_spamd_pidfile;
argv[i] = NULL;
-
- for (i = 0; i < MAX_SPAMD_PORTS; i++, p++) {
- d(fprintf (stderr, "trying to run %s at port %d\n", binary, p));
+
+ d(fprintf (stderr, "trying to run %s with socket path %s\n", binary, em_junk_sa_get_socket_path ()));
- snprintf (port_buf, 11, "%d", p);
- if (!pipe_to_sa (NULL, NULL, argv)) {
- d(fprintf (stderr, "success at port %d\n", p));
- *port = p;
- return TRUE;
+ if (!pipe_to_sa_full (NULL, NULL, argv, -1, 0, NULL)) {
+ int i;
+ struct timespec time_req;
+ struct stat stat_buf;
+
+ d(fprintf (stderr, "success\n"));
+ d(fprintf (stderr, "waiting for spamd to come up\n"));
+
+ time_req.tv_sec = 0;
+ time_req.tv_nsec = 50000000;
+
+ for (i = 0; i < 100; i ++) {
+ if (stat (em_junk_sa_get_socket_path (), &stat_buf) == 0) {
+ d(fprintf (stderr, "socket created\n"));
+ break;
+ }
+ nanosleep (&time_req, NULL);
+ }
+ d(fprintf (stderr, "waiting is over (after %dms)\n", 50*i));
+
+ rv = TRUE;
+ }
+
+ pthread_mutex_unlock (&em_junk_sa_preferred_socket_path_lock);
+
+ return rv;
+}
+
+static void
+em_junk_sa_start_own_daemon ()
+{
+ int b;
+
+ em_junk_sa_new_daemon_started = FALSE;
+
+ em_junk_sa_socket_path = e_mktemp ("spamd-socket-path-XXXXXX");
+ em_junk_sa_spamd_pidfile = e_mktemp ("spamd-pid-file-XXXXXX");
+
+ for (b = 0; em_junk_sa_spamd_binaries [b]; b ++) {
+ em_junk_sa_use_spamc = em_junk_sa_run_spamd (em_junk_sa_spamd_binaries [b]);
+ if (em_junk_sa_use_spamc) {
+ em_junk_sa_new_daemon_started = TRUE;
+ break;
}
}
+}
- return FALSE;
+static void
+em_junk_sa_find_spamc ()
+{
+ if (em_junk_sa_use_spamc && em_junk_sa_new_daemon_started) {
+ int b;
+
+ em_junk_sa_use_spamc = FALSE;
+ for (b = 0; em_junk_sa_spamc_binaries [b]; b ++) {
+ em_junk_sa_spamc_binary = em_junk_sa_spamc_binaries [b];
+ if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, FALSE)) {
+ em_junk_sa_use_spamc = TRUE;
+ break;
+ }
+ }
+ }
}
static void
@@ -270,22 +397,19 @@ em_junk_sa_test_spamd (void)
char *argv[4];
int i, b;
gboolean try_system_spamd = TRUE;
- gboolean new_daemon_started = FALSE;
- char *spamc_binaries [3] = {"spamc", "/usr/sbin/spamc", NULL};
- char *spamd_binaries [3] = {"spamd", "/usr/sbin/spamd", NULL};
if (em_junk_sa_gconf) {
char *binary;
binary = gconf_client_get_string (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/spamc_binary", NULL);
if (binary) {
- spamc_binaries [0] = binary;
- spamc_binaries [1] = NULL;
+ em_junk_sa_spamc_binaries [0] = binary;
+ em_junk_sa_spamc_binaries [1] = NULL;
}
binary = gconf_client_get_string (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/spamd_binary", NULL);
if (binary) {
- spamd_binaries [0] = binary;
- spamd_binaries [1] = NULL;
+ em_junk_sa_spamd_binaries [0] = binary;
+ em_junk_sa_spamd_binaries [1] = NULL;
try_system_spamd = FALSE;
}
}
@@ -307,55 +431,36 @@ em_junk_sa_test_spamd (void)
/* try to use sytem spamd first */
if (try_system_spamd) {
- for (b = 0; spamc_binaries [b]; b ++) {
- em_junk_sa_spamc_binary = spamc_binaries [b];
- if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, -1)) {
+ for (b = 0; em_junk_sa_spamc_binaries [b]; b ++) {
+ em_junk_sa_spamc_binary = em_junk_sa_spamc_binaries [b];
+ if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, TRUE)) {
em_junk_sa_use_spamc = TRUE;
- em_junk_sa_spamd_port = -1;
+ em_junk_sa_system_spamd_available = TRUE;
break;
}
}
}
- /* if there's no system spamd running, try to use user one on evo spamd port */
- if (!em_junk_sa_use_spamc) {
- int port = em_junk_sa_daemon_port;
-
- for (i = 0; i < MAX_SPAMD_PORTS; i ++, port ++) {
- for (b = 0; spamc_binaries [b]; b ++) {
- em_junk_sa_spamc_binary = spamc_binaries [b];
- if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, port)) {
- em_junk_sa_use_spamc = TRUE;
- em_junk_sa_spamd_port = port;
- break;
- }
+ /* if there's no system spamd running, try to use user one with user specified socket */
+ if (!em_junk_sa_use_spamc && em_junk_sa_preferred_socket_path) {
+ for (b = 0; em_junk_sa_spamc_binaries [b]; b ++) {
+ em_junk_sa_spamc_binary = em_junk_sa_spamc_binaries [b];
+ if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, FALSE)) {
+ em_junk_sa_use_spamc = TRUE;
+ em_junk_sa_system_spamd_available = FALSE;
+ break;
}
}
}
/* unsuccessful? try to run one ourselfs */
if (!em_junk_sa_use_spamc)
- for (b = 0; spamd_binaries [b]; b ++) {
- em_junk_sa_use_spamc = em_junk_sa_run_spamd (spamd_binaries [b], &em_junk_sa_spamd_port);
- if (em_junk_sa_use_spamc) {
- new_daemon_started = TRUE;
- break;
- }
- }
-
+ em_junk_sa_start_own_daemon ();
+
/* new daemon started => let find spamc binary */
- if (em_junk_sa_use_spamc && new_daemon_started) {
- em_junk_sa_use_spamc = FALSE;
- for (b = 0; spamc_binaries [b]; b ++) {
- em_junk_sa_spamc_binary = spamc_binaries [b];
- if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, em_junk_sa_spamd_port)) {
- em_junk_sa_use_spamc = TRUE;
- break;
- }
- }
- }
+ em_junk_sa_find_spamc ();
- d(fprintf (stderr, "use spamd %d at port %d with %s\n", em_junk_sa_use_spamc, em_junk_sa_spamd_port, em_junk_sa_spamc_binary));
+ d(fprintf (stderr, "use spamd: %s\n", em_junk_sa_use_spamc ? "yes" : "no"));
em_junk_sa_spamd_tested = TRUE;
}
@@ -377,23 +482,84 @@ em_junk_sa_is_available (void)
}
static gboolean
+em_junk_sa_check_respawn_too_fast ()
+{
+ time_t time_now = time (NULL);
+ gboolean rv;
+
+ pthread_mutex_lock (&em_junk_sa_spamd_restart_lock);
+
+ if (em_junk_sa_spamd_restarts_count >= SPAMD_RESTARTS_SIZE) {
+ /* all restarts in last 5 minutes */
+ rv = (time_now - em_junk_sa_spamd_restarts [em_junk_sa_spamd_restarts_count % SPAMD_RESTARTS_SIZE] < 5*60);
+ } else
+ rv = FALSE;
+
+ em_junk_sa_spamd_restarts [em_junk_sa_spamd_restarts_count % SPAMD_RESTARTS_SIZE] = time_now;
+ em_junk_sa_spamd_restarts_count ++;
+
+ pthread_mutex_unlock (&em_junk_sa_spamd_restart_lock);
+
+ d(printf ("em_junk_sa_check_respawn_too_fast: %d\n", rv));
+
+ return rv;
+}
+
+static gboolean
+em_junk_sa_respawn_spamd ()
+{
+ d(printf ("em_junk_sa_respawn_spamd\n"));
+ if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, em_junk_sa_system_spamd_available)) {
+ /* false alert */
+ d(printf ("false alert, spamd still running\n"));
+
+ return FALSE;
+ }
+
+ d(printf ("going to kill old spamd and start new one\n"));
+ em_junk_sa_kill_spamd ();
+
+ if (em_junk_sa_check_respawn_too_fast ()) {
+ g_warning ("respawning of spamd too fast => fallback to use spamassassin directly");
+
+ em_junk_sa_use_spamc = em_junk_sa_use_daemon = FALSE;
+ return FALSE;
+ }
+
+ em_junk_sa_start_own_daemon ();
+ em_junk_sa_find_spamc ();
+
+ d(printf ("%s\n", em_junk_sa_use_spamc ? "success" : "failed"));
+
+ return em_junk_sa_use_spamc;
+}
+
+static gboolean
em_junk_sa_check_junk (CamelMimeMessage *msg)
{
- char *argv[5], buf[12];
- int i = 0;
-
+ GByteArray *out = NULL;
+ char *argv[7], *to_free = NULL;
+ int i = 0, socket_i;
+ gboolean rv;
+
d(fprintf (stderr, "em_junk_sa_check_junk\n"));
if (!em_junk_sa_is_available ())
return FALSE;
-
+
if (em_junk_sa_use_spamc && em_junk_sa_use_daemon) {
+ out = g_byte_array_new ();
argv[i++] = em_junk_sa_spamc_binary;
argv[i++] = "-c";
- if (em_junk_sa_spamd_port != -1) {
- sprintf (buf, "%d", em_junk_sa_spamd_port);
- argv[i++] = "-p";
- argv[i++] = buf;
+ argv[i++] = "-t";
+ argv[i++] = "60";
+ if (!em_junk_sa_system_spamd_available) {
+ argv[i++] = "-U";
+
+ pthread_mutex_lock (&em_junk_sa_preferred_socket_path_lock);
+ socket_i = i;
+ argv[i++] = to_free = g_strdup (em_junk_sa_get_socket_path ());
+ pthread_mutex_unlock (&em_junk_sa_preferred_socket_path_lock);
}
} else {
argv [i++] = "spamassassin";
@@ -404,7 +570,32 @@ em_junk_sa_check_junk (CamelMimeMessage *msg)
argv[i] = NULL;
- return pipe_to_sa_with_error (msg, NULL, argv, 0) != 0;
+ rv = pipe_to_sa_full (msg, NULL, argv, 0, 1, out) != 0;
+
+ if (!rv && out && !strcmp (out->data, "0/0\n")) {
+ /* an error occured */
+ if (em_junk_sa_respawn_spamd ()) {
+ g_byte_array_set_size (out, 0);
+
+ pthread_mutex_lock (&em_junk_sa_preferred_socket_path_lock);
+ g_free (to_free);
+ argv [socket_i] = to_free = g_strdup (em_junk_sa_get_socket_path ());
+ pthread_mutex_unlock (&em_junk_sa_preferred_socket_path_lock);
+
+ rv = pipe_to_sa_full (msg, NULL, argv, 0, 1, out) != 0;
+ } else if (!em_junk_sa_use_spamc)
+ /* in case respawning were too fast we fallback to spamassassin */
+ rv = em_junk_sa_check_junk (msg);
+ }
+
+ g_free (to_free);
+
+ d(fprintf (stderr, "em_junk_sa_check_junk rv = %d\n", rv));
+
+ if (out)
+ g_byte_array_free (out, TRUE);
+
+ return rv;
}
static void
@@ -495,25 +686,81 @@ em_junk_sa_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry,
em_junk_sa_local_only = gconf_value_get_bool(value);
else if (!strcmp(tkey, "use_daemon"))
em_junk_sa_use_daemon = gconf_value_get_bool(value);
- else if (!strcmp(tkey, "daemon_port"))
- em_junk_sa_daemon_port = gconf_value_get_int(value);
+ else if (!strcmp(tkey, "socket_path")) {
+ pthread_mutex_lock (&em_junk_sa_preferred_socket_path_lock);
+ g_free (em_junk_sa_preferred_socket_path);
+ em_junk_sa_preferred_socket_path = g_strdup (gconf_value_get_string(value));
+ pthread_mutex_unlock (&em_junk_sa_preferred_socket_path_lock);
+ }
}
const EMJunkPlugin *
em_junk_filter_get_plugin (void)
{
+ return &spam_assassin_plugin;
+}
+
+static void
+em_junk_sa_init (void)
+{
if (!em_junk_sa_gconf) {
em_junk_sa_gconf = gconf_client_get_default();
gconf_client_add_dir (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
em_junk_sa_local_only = gconf_client_get_bool (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/local_only", NULL);
em_junk_sa_use_daemon = gconf_client_get_bool (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/use_daemon", NULL);
- em_junk_sa_daemon_port = gconf_client_get_int (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/daemon_port", NULL);
+
+ pthread_mutex_lock (&em_junk_sa_preferred_socket_path_lock);
+ g_free (em_junk_sa_preferred_socket_path);
+ em_junk_sa_preferred_socket_path = g_strdup (gconf_client_get_string (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/socket_path", NULL));
+ pthread_mutex_unlock (&em_junk_sa_preferred_socket_path_lock);
gconf_client_notify_add(em_junk_sa_gconf, "/apps/evolution/mail/junk/sa",
(GConfClientNotifyFunc)em_junk_sa_setting_notify,
NULL, NULL, NULL);
}
- return &spam_assassin_plugin;
+ atexit (em_junk_sa_finalize);
+}
+
+static void
+em_junk_sa_kill_spamd (void)
+{
+ pthread_mutex_lock (&em_junk_sa_preferred_socket_path_lock);
+ g_free (em_junk_sa_preferred_socket_path);
+ em_junk_sa_preferred_socket_path = NULL;
+ pthread_mutex_unlock (&em_junk_sa_preferred_socket_path_lock);
+
+ if (em_junk_sa_new_daemon_started) {
+ int fd = open (em_junk_sa_spamd_pidfile, O_RDONLY);
+
+ if (fd != -1) {
+ char pid_str [16];
+ int bytes;
+
+ bytes = read (fd, pid_str, 15);
+ if (bytes > 0) {
+ int pid;
+
+ pid_str [bytes] = 0;
+ pid = atoi (pid_str);
+
+ if (pid > 0) {
+ kill (pid, SIGTERM);
+ d(fprintf (stderr, "em_junk_sa_finalize send SIGTERM to daemon with pid %d\n", pid));
+ waitpid (pid, NULL, 0);
+ }
+ }
+
+ close (fd);
+ }
+ }
+}
+
+static void
+em_junk_sa_finalize (void)
+{
+ d(fprintf (stderr, "em_junk_sa_finalize\n"));
+
+ em_junk_sa_kill_spamd ();
}
diff --git a/mail/mail-session.c b/mail/mail-session.c
index 3109c47c30..c88c5e8d1b 100644
--- a/mail/mail-session.c
+++ b/mail/mail-session.c
@@ -641,6 +641,8 @@ mail_session_init (const char *base_directory)
(GConfClientNotifyFunc) mail_session_check_junk_notify,
session, NULL, NULL);
session->junk_plugin = CAMEL_JUNK_PLUGIN (em_junk_filter_get_plugin ());
+ if (session->junk_plugin)
+ camel_junk_plugin_init (session->junk_plugin);
/* The shell will tell us to go online. */
camel_session_set_online ((CamelSession *) session, FALSE);