aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
authorRadek Doulik <rodo@ximian.com>2004-11-25 18:50:47 +0800
committerRadek Doulik <rodo@src.gnome.org>2004-11-25 18:50:47 +0800
commit94cc53a7057dec2a655102268772b73efe32384e (patch)
tree61f0813151e9bb8bee4d48c60db363faf00e3650 /mail
parent80e3070de9d43d2ad4fe7f856dfc159a96907538 (diff)
downloadgsoc2013-evolution-94cc53a7057dec2a655102268772b73efe32384e.tar
gsoc2013-evolution-94cc53a7057dec2a655102268772b73efe32384e.tar.gz
gsoc2013-evolution-94cc53a7057dec2a655102268772b73efe32384e.tar.bz2
gsoc2013-evolution-94cc53a7057dec2a655102268772b73efe32384e.tar.lz
gsoc2013-evolution-94cc53a7057dec2a655102268772b73efe32384e.tar.xz
gsoc2013-evolution-94cc53a7057dec2a655102268772b73efe32384e.tar.zst
gsoc2013-evolution-94cc53a7057dec2a655102268772b73efe32384e.zip
when starting new spamd, call it with --socketpath parameter to use unix
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 svn path=/trunk/; revision=27990
Diffstat (limited to 'mail')
-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);