From 8dfd4278a78e7d6ae30f92d50ee46029a5fbd106 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 12 Jul 2011 07:06:12 -0400 Subject: Convert junk filtering EPlugins to EExtensions. We now have a proper junk mail filtering API. All junk filtering extensions must subclass EMailJunkFilter for user preferences and availability testing, and implement the CamelJunkFilter interface for the actual junk filtering and learning operations. The bogofilter module should be feature-equivalent to its former EPlugin. The spamassassin module is far more complex. It's nearly feature-equivalent to its former EPlugin, but I ditched the spamd respawning code since it seemed unnecessary for a mail client to have to deal with. If there's a huge outcry from users about it I'll reluctantly put it back, but I don't expect one. This gets us a step closer to killing off EConfig, and eventually the EPlugin framework itself. --- plugins/bogo-junk-plugin/Makefile.am | 67 -- plugins/bogo-junk-plugin/README | 35 - plugins/bogo-junk-plugin/bf-junk-filter.c | 420 --------- .../bogo-junk-plugin/bogo-junk-plugin.schemas.in | 18 - .../org-gnome-bogo-junk-plugin.eplug.xml | 26 - plugins/sa-junk-plugin/Makefile.am | 31 - plugins/sa-junk-plugin/em-junk-filter.c | 966 --------------------- .../org-gnome-sa-junk-plugin.eplug.xml | 24 - 8 files changed, 1587 deletions(-) delete mode 100644 plugins/bogo-junk-plugin/Makefile.am delete mode 100644 plugins/bogo-junk-plugin/README delete mode 100644 plugins/bogo-junk-plugin/bf-junk-filter.c delete mode 100644 plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in delete mode 100644 plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml delete mode 100644 plugins/sa-junk-plugin/Makefile.am delete mode 100644 plugins/sa-junk-plugin/em-junk-filter.c delete mode 100644 plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml (limited to 'plugins') diff --git a/plugins/bogo-junk-plugin/Makefile.am b/plugins/bogo-junk-plugin/Makefile.am deleted file mode 100644 index c4ee4a65ac..0000000000 --- a/plugins/bogo-junk-plugin/Makefile.am +++ /dev/null @@ -1,67 +0,0 @@ -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-bogo-junk-plugin.eplug - -plugin_LTLIBRARIES = liborg-gnome-bogo-junk-plugin.la - -liborg_gnome_bogo_junk_plugin_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -DWELCOME_MESSAGE=\""$(privdatadir)/default/C/mail/local/Inbox"\" \ - $(GNOME_PLATFORM_CFLAGS) \ - $(EVOLUTION_MAIL_CFLAGS) - -liborg_gnome_bogo_junk_plugin_la_SOURCES = bf-junk-filter.c - -liborg_gnome_bogo_junk_plugin_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_bogo_junk_plugin_la_LIBADD = \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/shell/libeshell.la \ - $(EVOLUTION_MAIL_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -schemadir = $(GCONF_SCHEMA_FILE_DIR) -schema_in_files = bogo-junk-plugin.schemas.in -schema_DATA = $(schema_in_files:.schemas.in=.schemas) - -@INTLTOOL_SCHEMAS_RULE@ - -if GCONF_SCHEMAS_INSTALL - -if OS_WIN32 -install-data-local: - if test -z "$(DESTDIR)" ; then \ - for p in $(schema_DATA) ; do \ - (echo set GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE); \ - echo $(GCONFTOOL) --makefile-install-rule $$p) >_temp.bat; \ - cmd /c _temp.bat; \ - rm _temp.bat; \ - done \ - fi -else -install-data-local: - if test -z "$(DESTDIR)" ; then \ - for p in $(schema_DATA) ; do \ - GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) \ - $(GCONFTOOL) --makefile-install-rule $$p; \ - done \ - fi -endif - -endif - - -BUILT_SOURCES = $(plugin_DATA) $(error_DATA) - -CLEANFILES = $(BUILT_SOURCES) - -DISTCLEANFILES = $(schema_DATA) - -EXTRA_DIST = \ - org-gnome-bogo-junk-plugin.eplug.xml \ - $(schema_in_files) - - --include $(top_srcdir)/git.mk diff --git a/plugins/bogo-junk-plugin/README b/plugins/bogo-junk-plugin/README deleted file mode 100644 index a14bcf6dda..0000000000 --- a/plugins/bogo-junk-plugin/README +++ /dev/null @@ -1,35 +0,0 @@ -Bogofilter plugin for Evolution - -This plugin implements junk filtering for the Evolution mailer, -provided by the bogofilter utility. Bogofilter (http://www.bogofilter.org) -if a fast and nimble mail filter using a so-called Bayesian technique to -classify junk and non-junk email. - -CAVEATS: - -For Evolution versions before 2.5.2, the definition file for the stock -junk filter plugin, 'org-gnome-sa-junk-plugin.eplug', must be removed -from the plugin directory to avoid conflict with any alternate junk plugin. -Simply disabling the SA plugin in the configuration won't help. -This is due to a flaw in the loading code for this hook type -(see GNOME bug #313096). - -To be able to classify emails as spam, bogofilter needs to have some -messages in its ham (non-spam) wordlist. This presents something of a -chicken-and-egg problem for Evolution, because it can feed messages -to the junk filter for learning as non-junk only after these messages have been -classified as junk and moved into a junk folder (GNOME bug #322105). -Thus, if you haven't got a pre-existing bogofilter database, you may need -to feed it some messages known to be non-junk, using its -command line utility: - -bogofilter -n < saved-ham-message - -Alternatively, you may use Spam Trainer, which is a GUI tool that supports -drag-and-drop from Evolution: - -http://spamtrainer.sourceforge.net/ - -Set it up to use bogofilter commands for training: - Ham command: bogofilter -n < %f - Spam command: bogofilter -s < %f diff --git a/plugins/bogo-junk-plugin/bf-junk-filter.c b/plugins/bogo-junk-plugin/bf-junk-filter.c deleted file mode 100644 index 0d6726fd03..0000000000 --- a/plugins/bogo-junk-plugin/bf-junk-filter.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see - * - * - * Authors: - * Mikhail Zabaluev - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright 2005 Mikhail Zabaluev - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#define G_LOG_DOMAIN "bf-junk-filter" - -#ifndef G_OS_WIN32 -# include -#else -# include -#endif - -#include -#include -#include -#include "mail/em-config.h" -#include -#include -#include "shell/e-shell.h" - -#ifndef BOGOFILTER_BINARY -#define BOGOFILTER_BINARY "/usr/bin/bogofilter" -#endif - -#define BOGOFILTER_ERROR 3 - -#define EM_JUNK_BF_GCONF_DIR "/apps/evolution/mail/junk/bogofilter" - -#define d(x) (camel_debug("junk")?(x):0) - -static gboolean is_installed = FALSE; - -static gchar em_junk_bf_binary[] = BOGOFILTER_BINARY; - -static const gchar em_junk_bf_gconf_dir[] = EM_JUNK_BF_GCONF_DIR; -GtkWidget * org_gnome_bogo_convert_unicode (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data); - -/* plugin fonction prototypes */ -gboolean em_junk_bf_check_junk (EPlugin *ep, EMJunkTarget *target); -gpointer em_junk_bf_validate_binary (EPlugin *ep, EMJunkTarget *target); -void em_junk_bf_report_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_bf_report_non_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_bf_commit_reports (EPlugin *ep, EMJunkTarget *target); - -static gint -pipe_to_bogofilter (CamelMimeMessage *msg, - const gchar **argv, - GCancellable *cancellable, - GError **error); - -/* eplugin stuff */ -gint e_plugin_lib_enable (EPlugin *ep, gint enable); - -#define EM_JUNK_BF_GCONF_DIR_LENGTH (G_N_ELEMENTS (em_junk_bf_gconf_dir) - 1) - -static gboolean em_junk_bf_unicode = TRUE; - -static void -init_db (void) -{ - CamelStream *stream = camel_stream_fs_new_with_name (WELCOME_MESSAGE, O_RDONLY, 0, NULL); - CamelMimeParser *parser = camel_mime_parser_new (); - CamelMimeMessage *msg = camel_mime_message_new (); - const gchar *argv[] = { - em_junk_bf_binary, - "-n", - NULL, - NULL - }; - - camel_mime_parser_init_with_stream (parser, stream, NULL); - camel_mime_parser_scan_from (parser, FALSE); - g_object_unref (stream); - - camel_mime_part_construct_from_parser_sync ( - (CamelMimePart *) msg, parser, NULL, NULL); - g_object_unref (parser); - - d(fprintf (stderr, "Initing the bogofilter DB with Welcome message\n")); - - if (em_junk_bf_unicode) { - argv[2] = "--unicode=yes"; - } - - pipe_to_bogofilter (msg, argv, NULL, NULL); - g_object_unref (msg); - -} - -static gint -pipe_to_bogofilter (CamelMimeMessage *msg, - const gchar **argv, - GCancellable *cancellable, - GError **error) -{ - GPid child_pid; - gint bf_in; - CamelStream *stream; - GError *err = NULL; - gint status; - gint waitres; - gint res; - static gboolean only_once = FALSE; - -retry: - if (camel_debug_start ("junk")) { - gint i; - - printf ("pipe_to_bogofilter "); - for (i = 0; argv[i]; i++) - printf ("%s ", argv[i]); - printf ("\n"); - camel_debug_end (); - } - - if (!g_spawn_async_with_pipes (NULL, - (gchar **) argv, - NULL, - G_SPAWN_DO_NOT_REAP_CHILD | - G_SPAWN_STDOUT_TO_DEV_NULL, - NULL, - NULL, - &child_pid, - &bf_in, - NULL, - NULL, - &err)) - { - g_warning ("error occurred while spawning %s: %s", argv[0], err->message); - - if (g_error_matches (err, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT)) { - if (is_installed) - g_set_error (error, EM_JUNK_ERROR, err->code, _("Bogofilter is not available. Please install it first.")); - is_installed = FALSE; - } else { - /* For Translators: The first %s stands for the executable full path with a file name, the second is the error message itself. */ - g_set_error (error, EM_JUNK_ERROR, err->code, _("Error occurred while spawning %s: %s."), argv[0], err->message); - } - - g_error_free (err); - - return BOGOFILTER_ERROR; - } - - stream = camel_stream_fs_new_with_fd (bf_in); - camel_data_wrapper_write_to_stream_sync ( - CAMEL_DATA_WRAPPER (msg), stream, cancellable, NULL); - camel_stream_flush (stream, cancellable, NULL); - camel_stream_close (stream, cancellable, NULL); - g_object_unref (stream); - -#ifndef G_OS_WIN32 - waitres = waitpid (child_pid, &status, 0); - if (waitres < 0 && errno == EINTR) { - /* child process is hanging... */ - g_warning ("wait for bogofilter child process interrupted, terminating"); - kill (child_pid, SIGTERM); - sleep (1); - waitres = waitpid (child_pid, &status, WNOHANG); - if (waitres == 0) { - /* ...still hanging, set phasers to KILL */ - g_warning ("bogofilter child process does not respond, killing"); - kill (child_pid, SIGKILL); - sleep (1); - waitres = waitpid (child_pid, &status, WNOHANG); - g_set_error (error, EM_JUNK_ERROR, -2, _("Bogofilter child process does not respond, killing...")); - } else - g_set_error (error, EM_JUNK_ERROR, -3, _("Wait for Bogofilter child process interrupted, terminating...")); - } - - if (waitres >= 0 && WIFEXITED (status)) { - res = WEXITSTATUS (status); - } else { - res = BOGOFILTER_ERROR; - } -#else - WaitForSingleObject (child_pid, INFINITE); - GetExitCodeProcess (child_pid, &res); -#endif - - g_spawn_close_pid (child_pid); - - if (res < 0 || res > 2) { - if (!only_once) { - /* Create wordlist.db */ - only_once = TRUE; - init_db (); - - goto retry; - } - g_set_error (error, EM_JUNK_ERROR, res, _("Pipe to Bogofilter failed, error code: %d."), res); - - } - - return res; -} - -static void -em_junk_bf_setting_notify (GConfClient *gconf, - guint cnxn_id, - GConfEntry *entry, - void *data) -{ - const gchar *key; - GConfValue *value; - - value = gconf_entry_get_value (entry); - if (value == NULL) { - return; - } - - key = gconf_entry_get_key (entry); - g_return_if_fail (key != NULL); - - g_return_if_fail (!strncmp (key, em_junk_bf_gconf_dir, EM_JUNK_BF_GCONF_DIR_LENGTH)); - key += EM_JUNK_BF_GCONF_DIR_LENGTH; - - g_return_if_fail (*key == '/'); - ++key; - - if (strcmp (key, "unicode") == 0) { - em_junk_bf_unicode = gconf_value_get_bool (value); - } -} - -gboolean -em_junk_bf_check_junk (EPlugin *ep, EMJunkTarget *target) -{ - CamelMimeMessage *msg = target->m; - gint rv; - - const gchar *argv[] = { - em_junk_bf_binary, - NULL, - NULL - }; - - if (!is_installed) - return FALSE; - - d(fprintf (stderr, "em_junk_bf_check_junk\n")); - - if (em_junk_bf_unicode) { - argv[1] = "--unicode=yes"; - } - - rv = pipe_to_bogofilter (msg, argv, NULL, &target->error); - - d(fprintf (stderr, "em_junk_bf_check_junk rv = %d\n", rv)); - - return (rv == 0); -} - -void -em_junk_bf_report_junk (EPlugin *ep, EMJunkTarget *target) -{ - CamelMimeMessage *msg = target->m; - - const gchar *argv[] = { - em_junk_bf_binary, - "-s", - NULL, - NULL - }; - - if (!is_installed) - return; - - d(fprintf (stderr, "em_junk_bf_report_junk\n")); - - if (em_junk_bf_unicode) { - argv[2] = "--unicode=yes"; - } - - pipe_to_bogofilter (msg, argv, NULL, &target->error); -} - -void -em_junk_bf_report_non_junk (EPlugin *ep, EMJunkTarget *target) -{ - CamelMimeMessage *msg = target->m; - - const gchar *argv[] = { - em_junk_bf_binary, - "-n", - NULL, - NULL - }; - - if (!is_installed) - return; - - d(fprintf (stderr, "em_junk_bf_report_non_junk\n")); - - if (em_junk_bf_unicode) { - argv[2] = "--unicode=yes"; - } - - pipe_to_bogofilter (msg, argv, NULL, &target->error); -} - -void -em_junk_bf_commit_reports (EPlugin *ep, EMJunkTarget *target) -{ - if (!is_installed) - return; -} - -gpointer -em_junk_bf_validate_binary (EPlugin *ep, EMJunkTarget *target) -{ - gpointer res = g_file_test (em_junk_bf_binary, G_FILE_TEST_EXISTS) ? (gpointer) "1" : NULL; - - if (res != NULL) - is_installed = TRUE; - - return res; -} - -gint -e_plugin_lib_enable (EPlugin *ep, gint enable) -{ - static gboolean first = TRUE; - GConfClient *gconf; - - is_installed = enable != 0; - - if (!first) - return 0; - - first = FALSE; - gconf = gconf_client_get_default (); - - gconf_client_add_dir (gconf, - em_junk_bf_gconf_dir, - GCONF_CLIENT_PRELOAD_ONELEVEL, - NULL); - - gconf_client_notify_add (gconf, - em_junk_bf_gconf_dir, - em_junk_bf_setting_notify, - NULL, NULL, NULL); - - em_junk_bf_unicode = gconf_client_get_bool (gconf, - EM_JUNK_BF_GCONF_DIR "/unicode", NULL); - - g_object_unref (gconf); - - return 0; -} - -static void -convert_unicode_cb (GtkWidget *widget, gpointer data) -{ - - gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - GConfClient *gconf = gconf_client_get_default (); - - gconf_client_set_bool (gconf, data, active, NULL); - - g_object_unref (gconf); -} - -GtkWidget * -org_gnome_bogo_convert_unicode (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data) -{ - EShell *shell; - GtkWidget *check; - guint n_rows; - - g_object_get (data->parent, "n-rows", &n_rows, NULL); - - if (data->old) - return data->old; - - check = gtk_check_button_new_with_mnemonic (_("Convert message text to _Unicode")); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), em_junk_bf_unicode); - g_signal_connect (GTK_TOGGLE_BUTTON (check), "toggled", G_CALLBACK (convert_unicode_cb), (gpointer) "/apps/evolution/mail/junk/bogofilter/unicode"); - gtk_table_attach ( - GTK_TABLE (data->parent), check, - 0, 1, n_rows, n_rows+1, 0, 0, 0, 0); - - shell = e_shell_get_default (); - if (e_shell_get_express_mode (shell)) - gtk_widget_hide (check); - else - gtk_widget_show (check); - - return check; -} - diff --git a/plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in b/plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in deleted file mode 100644 index d4bfbb5b70..0000000000 --- a/plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in +++ /dev/null @@ -1,18 +0,0 @@ - - - - /schemas/apps/evolution/mail/junk/bogofilter/unicode - /apps/evolution/mail/junk/bogofilter/unicode - bf-eplugin - bool - true - - Convert mail messages to Unicode - - Convert message text to Unicode UTF-8 to unify spam/ham tokens - coming from different character sets. - - - - - diff --git a/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml b/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml deleted file mode 100644 index 1317b988d9..0000000000 --- a/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - <_description>Filter junk messages using Bogofilter. - - - - - - - - - - - - - - diff --git a/plugins/sa-junk-plugin/Makefile.am b/plugins/sa-junk-plugin/Makefile.am deleted file mode 100644 index 0452fcd6ec..0000000000 --- a/plugins/sa-junk-plugin/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-sa-junk-plugin.eplug - -plugin_LTLIBRARIES = liborg-gnome-sa-junk-plugin.la - -liborg_gnome_sa_junk_plugin_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - $(GNOME_PLATFORM_CFLAGS) \ - $(EVOLUTION_MAIL_CFLAGS) - -liborg_gnome_sa_junk_plugin_la_SOURCES = em-junk-filter.c - -liborg_gnome_sa_junk_plugin_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_sa_junk_plugin_la_LIBADD = \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/shell/libeshell.la \ - $(EVOLUTION_MAIL_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -BUILT_SOURCES = $(plugin_DATA) $(error_DATA) - -CLEANFILES = $(BUILT_SOURCES) - -EXTRA_DIST = org-gnome-sa-junk-plugin.eplug.xml - --include $(top_srcdir)/git.mk diff --git a/plugins/sa-junk-plugin/em-junk-filter.c b/plugins/sa-junk-plugin/em-junk-filter.c deleted file mode 100644 index 635e1192c4..0000000000 --- a/plugins/sa-junk-plugin/em-junk-filter.c +++ /dev/null @@ -1,966 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see - * - * - * Authors: - * Radek Doulik - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include "mail/em-config.h" -#include "shell/e-shell.h" - -#include - -#define d(x) (camel_debug("junk")?(x):0) - -G_LOCK_DEFINE_STATIC (init); -G_LOCK_DEFINE_STATIC (report); -G_LOCK_DEFINE_STATIC (socket_path); -G_LOCK_DEFINE_STATIC (spamd_restart); - -gint e_plugin_lib_enable (EPlugin *ep, gint enable); -gboolean em_junk_sa_check_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_sa_report_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_sa_report_non_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_sa_commit_reports (EPlugin *ep); -gpointer em_junk_sa_validate_binary (EPlugin *ep); -GtkWidget *org_gnome_sa_use_remote_tests (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data); - -static void em_junk_sa_init (void); -static void em_junk_sa_finalize (void); -static void em_junk_sa_kill_spamd (void); - -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 gboolean em_junk_sa_system_spamd_available = FALSE; -static gboolean em_junk_sa_new_daemon_started = FALSE; -static gboolean em_junk_sa_checked_spamassassin_version = FALSE; -static guint em_junk_sa_spamassassin_version = 0; -static gchar *em_junk_sa_socket_path = NULL; -static gchar *em_junk_sa_spamd_pidfile = NULL; -static const gchar *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 gchar * em_junk_sa_preferred_socket_path; - -static const gchar *em_junk_sa_spamc_binaries [4] = {"spamc", "/usr/bin/spamc", "/usr/sbin/spamc", NULL}; -static const gchar *em_junk_sa_spamd_binaries [4] = {"spamd", "/usr/bin/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 gint em_junk_sa_spamd_restarts_count = 0; - -/* Variables to indicate whether spamd is running with --allow-tell */ -static gint no_allow_tell; -static gboolean em_junk_sa_allow_tell_tested = FALSE; -static gboolean is_installed = FALSE; - -gchar *em_junk_sa_spamc_gconf_binary = NULL; -gchar *em_junk_sa_spamd_gconf_binary = NULL; - -static gint -pipe_to_sa_full (CamelMimeMessage *msg, - const gchar *in, - const gchar **argv, - gint rv_err, - gint wait_for_termination, - GByteArray *output_buffer, - GCancellable *cancellable, - GError **error) -{ - gint result, status, errnosav, fds[2], out_fds[2]; - CamelStream *stream; - gchar *program; - pid_t pid; - - if (camel_debug_start ("junk")) { - gint i; - - printf ("pipe_to_sa "); - for (i = 0; argv[i]; i++) - printf ("%s ", argv[i]); - printf ("\n"); - camel_debug_end (); - } - - program = g_find_program_in_path (argv[0]); - if (program == NULL) { - d(printf ("program not found, returning %d\n", rv_err)); - g_set_error (error, EM_JUNK_ERROR, rv_err, _("SpamAssassin not found, code: %d"), rv_err); - return rv_err; - } - g_free (program); - - if (pipe (fds) == -1) { - errnosav = errno; - d(printf ("failed to create a pipe (for use with SpamAssassin: %s\n", g_strerror (errno))); - g_set_error (error, EM_JUNK_ERROR, errnosav, _("Failed to create pipe: %s"), g_strerror (errnosav)); - errno = errnosav; - 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", g_strerror (errno))); - g_set_error (error, EM_JUNK_ERROR, errnosav, _("Failed to create pipe: %s"), g_strerror (errnosav)); - close (fds[0]); - close (fds[1]); - errno = errnosav; - return rv_err; - } - - if (!(pid = fork ())) { - /* child process */ - gint maxfd, fd, nullfd; - - nullfd = open ("/dev/null", O_WRONLY); - - if (dup2 (fds[0], STDIN_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); - for (fd = 3; fd < maxfd; fd++) - fcntl (fd, F_SETFD, FD_CLOEXEC); - - execvp (argv[0], (gchar * const *) argv); - _exit (rv_err & 0377); - } else if (pid < 0) { - errnosav = errno; - close (fds[0]); - close (fds[1]); - if (output_buffer) { - close (out_fds[0]); - close (out_fds[1]); - } - if (errnosav != 0 && errnosav != -1) - g_set_error (error, EM_JUNK_ERROR, errnosav, _("Error after fork: %s"), g_strerror (errnosav)); - errno = errnosav; - return rv_err; - } - - /* parent process */ - close (fds[0]); - if (output_buffer) - close (out_fds[1]); - - if (msg) { - stream = camel_stream_fs_new_with_fd (fds[1]); - - camel_data_wrapper_write_to_stream_sync ( - CAMEL_DATA_WRAPPER (msg), stream, cancellable, NULL); - camel_stream_flush (stream, cancellable, NULL); - camel_stream_close (stream, cancellable, NULL); - g_object_unref (stream); - } else if (in) { - camel_write (fds[1], in, strlen (in), cancellable, NULL); - close (fds[1]); - } - - if (output_buffer) { - CamelStream *memstream; - - stream = camel_stream_fs_new_with_fd (out_fds[0]); - - memstream = camel_stream_mem_new (); - camel_stream_mem_set_byte_array ( - CAMEL_STREAM_MEM (memstream), output_buffer); - - camel_stream_write_to_stream ( - stream, memstream, cancellable, NULL); - g_object_unref (stream); - g_byte_array_append (output_buffer, (guchar *)"", 1); - - d(printf ("child process output: %s len: %d\n", output_buffer->data, output_buffer->len)); - } - - if (wait_for_termination) { - gint res; - - d(printf ("wait for child %d termination\n", pid)); - result = waitpid (pid, &status, 0); - - 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); - g_set_error (error, EM_JUNK_ERROR, -2, _("SpamAssassin child process does not respond, killing...")); - } else - g_set_error (error, EM_JUNK_ERROR, -3, _("Wait for SpamAssassin child process interrupted, terminating...")); - } - - if (result != -1 && WIFEXITED (status)) - res = WEXITSTATUS (status); - else - res = rv_err; - - if (res >= 64) - g_set_error (error, EM_JUNK_ERROR, res, _("Pipe to SpamAssassin failed, error code: %d"), res); - - return res; - } else - return 0; -} - -static gint -pipe_to_sa (CamelMimeMessage *msg, - const gchar *in, - const gchar **argv, - GCancellable *cancellable, - GError **error) -{ - return pipe_to_sa_full (msg, in, argv, -1, 1, NULL, cancellable, error); -} - -static gchar * -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 (const gchar *binary, gboolean system) -{ - const gchar *argv[5]; - gint i = 0; - gboolean rv; - - G_LOCK (socket_path); - - 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 (!system) { - argv[i++] = "-U"; - argv[i++] = em_junk_sa_get_socket_path (); - } - - argv[i] = NULL; - - rv = pipe_to_sa (NULL, "From test@127.0.0.1", argv, NULL, NULL) == 0; - - d(fprintf (stderr, "result: %d (%s)\n", rv, rv ? "success" : "failed")); - - G_UNLOCK (socket_path); - - return rv; -} - -/* - One time test to see if spamd is running with --allow-tell. The call - to spamc should return 0 if it is. (Thanks to Karsten Bräckelmann - for the idea). -*/ -static void -em_junk_sa_test_allow_tell (void) -{ - const gchar *argv[4] = { - "spamc", - "-L", - "forget", - NULL - }; - - no_allow_tell = pipe_to_sa (NULL, "\n" , argv, NULL, NULL); - em_junk_sa_allow_tell_tested = TRUE; -} - -static void -em_junk_sa_test_spamassassin (void) -{ - const gchar *argv[3] = { - "spamassassin", - "--version", - NULL, - }; - - if (pipe_to_sa (NULL, NULL, argv, NULL, NULL) != 0) - em_junk_sa_available = FALSE; - else - em_junk_sa_available = TRUE; - - em_junk_sa_tested = TRUE; -} - -#define MAX_SPAMD_PORTS 1 - -static gboolean -em_junk_sa_run_spamd (const gchar *binary) -{ - const gchar *argv[8]; - gint i; - gboolean rv = FALSE; - - G_LOCK (socket_path); - - d(fprintf (stderr, "looks like spamd is not running\n")); - - i = 0; - argv[i++] = binary; - argv[i++] = "--socketpath"; - argv[i++] = em_junk_sa_get_socket_path (); - - if (em_junk_sa_local_only) - argv[i++] = "--local"; - - /* See bug #268852*/ - argv[i++] = "--max-children=1"; - /*argv[i++] = "--daemonize";*/ - argv[i++] = "--pidfile"; - argv[i++] = em_junk_sa_spamd_pidfile; - argv[i] = NULL; - - d(fprintf (stderr, "trying to run %s with socket path %s\n", binary, em_junk_sa_get_socket_path ())); - - if (!pipe_to_sa_full (NULL, NULL, argv, -1, 0, NULL, NULL, NULL)) { - 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; - } - - G_UNLOCK (socket_path); - - return rv; -} - -static void -em_junk_sa_start_own_daemon () -{ - gint 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; - } - } -} - -static void -em_junk_sa_find_spamc () -{ - if (em_junk_sa_use_spamc && em_junk_sa_new_daemon_started) { - gint 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 -em_junk_sa_test_spamd (void) -{ - const gchar *argv[4]; - gint i, b; - gboolean try_system_spamd = TRUE; - - if (em_junk_sa_spamc_gconf_binary) { - em_junk_sa_spamc_binaries[0] = em_junk_sa_spamc_gconf_binary; - em_junk_sa_spamc_binaries[1] = NULL; - } - - if (em_junk_sa_spamd_gconf_binary) { - em_junk_sa_spamd_binaries[0] = em_junk_sa_spamd_gconf_binary; - em_junk_sa_spamd_binaries[1] = NULL; - try_system_spamd = FALSE; - } - - em_junk_sa_use_spamc = FALSE; - - if (em_junk_sa_local_only && try_system_spamd) { - i = 0; - argv [i++] = "/bin/sh"; - argv [i++] = "-c"; - argv [i++] = "ps ax|grep -v grep|grep -E 'spamd.*(\\-L|\\-\\-local)'|grep -E -v '\\ \\-p\\ |\\ \\-\\-port\\ '"; - argv[i] = NULL; - - if (pipe_to_sa (NULL, NULL, argv, NULL, NULL) != 0) { - try_system_spamd = FALSE; - d(fprintf (stderr, "there's no system spamd with -L/--local parameter running\n")); - } - } - - /* try to use sytem spamd first */ - if (try_system_spamd) { - 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_system_spamd_available = TRUE; - 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) - em_junk_sa_start_own_daemon (); - - /* new daemon started => let find spamc binary */ - em_junk_sa_find_spamc (); - - d(fprintf (stderr, "use spamd: %s\n", em_junk_sa_use_spamc ? "yes" : "no")); - - em_junk_sa_spamd_tested = TRUE; -} - -static gboolean -em_junk_sa_is_available (GError **error) -{ - G_LOCK (init); - - if (!em_junk_sa_tested) - em_junk_sa_test_spamassassin (); - - if (em_junk_sa_available && !em_junk_sa_spamd_tested && em_junk_sa_use_daemon) - em_junk_sa_test_spamd (); - - if (!em_junk_sa_available && error) { - if (is_installed) - g_set_error (error, EM_JUNK_ERROR, 1, _("SpamAssassin is not available. Please install it first.")); - - is_installed = FALSE; - } - - /* While we're at it, see if spamd is running with --allow-tell */ - if (!em_junk_sa_allow_tell_tested) - em_junk_sa_test_allow_tell (); - - G_UNLOCK (init); - - return em_junk_sa_available; -} - -static gboolean -em_junk_sa_check_respawn_too_fast () -{ - time_t time_now = time (NULL); - gboolean rv; - - G_LOCK (spamd_restart); - - 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++; - - G_UNLOCK (spamd_restart); - - 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; -} - -gboolean -em_junk_sa_check_junk (EPlugin *ep, EMJunkTarget *target) -{ - GByteArray *out = NULL; - const gchar *argv[7]; - gchar *to_free = NULL; - gint i = 0, socket_i; - gboolean rv; - CamelMimeMessage *msg = target->m; - - if (!is_installed) - return FALSE; - - d(fprintf (stderr, "em_junk_sa_check_junk\n")); - - if (!em_junk_sa_is_available (&target->error)) { - 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"; - argv[i++] = "-t"; - argv[i++] = "60"; - if (!em_junk_sa_system_spamd_available) { - argv[i++] = "-U"; - - G_LOCK (socket_path); - socket_i = i; - argv[i++] = to_free = g_strdup (em_junk_sa_get_socket_path ()); - G_UNLOCK (socket_path); - } - } else { - argv [i++] = "spamassassin"; - argv [i++] = "--exit-code"; - if (em_junk_sa_local_only) - argv [i++] = "--local"; - } - - argv[i] = NULL; - - rv = pipe_to_sa_full (msg, NULL, argv, 0, 1, out, NULL, &target->error) != 0; - - if (!rv && out && out->data && !strcmp ((const gchar *)out->data, "0/0\n")) { - /* an error occurred */ - if (em_junk_sa_respawn_spamd ()) { - g_byte_array_set_size (out, 0); - - G_LOCK (socket_path); - g_free (to_free); - argv[socket_i] = to_free = g_strdup (em_junk_sa_get_socket_path ()); - G_UNLOCK (socket_path); - - rv = pipe_to_sa_full (msg, NULL, argv, 0, 1, out, NULL, &target->error) != 0; - } else if (!em_junk_sa_use_spamc) - /* in case respawning were too fast we fallback to spamassassin */ - rv = em_junk_sa_check_junk (ep, target); - } - - 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 guint -get_spamassassin_version () -{ - GByteArray *out = NULL; - gint i; - - const gchar *argv[3] = { - "sa-learn", - "--version", - NULL - }; - - if (!em_junk_sa_checked_spamassassin_version) { - out = g_byte_array_new (); - - if (pipe_to_sa_full (NULL, NULL, argv, -1, 1, out, NULL, NULL) != 0) { - if (out) - g_byte_array_free (out, TRUE); - return em_junk_sa_spamassassin_version; - } - - if (out->len > 0) { - for (i = 0; i < out->len; i++) { - if (g_ascii_isdigit (out->data[i])) { - em_junk_sa_spamassassin_version = (out->data[i] - '0'); - em_junk_sa_checked_spamassassin_version = TRUE; - break; - } - } - } - - if (out) - g_byte_array_free (out, TRUE); - } - - return em_junk_sa_spamassassin_version; -} - -void -em_junk_sa_report_junk (EPlugin *ep, EMJunkTarget *target) -{ - const gchar *sync_op = - (get_spamassassin_version () >= 3) - ? "--no-sync": "--no-rebuild"; - const gchar *argv[6] = { - "sa-learn", - sync_op, - "--spam", - "--single", - NULL, - NULL - }; - /* Call setup for spamc */ - const gchar *argv2[4] = { - "spamc", - "-L", - "spam", - NULL - }; - CamelMimeMessage *msg = target->m; - - if (!is_installed) - return; - - d(fprintf (stderr, "em_junk_sa_report_junk\n")); - if (em_junk_sa_is_available (&target->error)) { - if (no_allow_tell && em_junk_sa_local_only) - argv[4] = "--local"; - - G_LOCK (report); - pipe_to_sa (msg, NULL, - (no_allow_tell ? argv : argv2), - NULL, &target->error); - G_UNLOCK (report); - } -} - -void -em_junk_sa_report_non_junk (EPlugin *ep, EMJunkTarget *target) -{ - const gchar *sync_op = - (get_spamassassin_version () >= 3) - ? "--no-sync": "--no-rebuild"; - const gchar *argv[6] = { - "sa-learn", - sync_op, - "--ham", - "--single", - NULL, - NULL - }; - /* Setup for spamc */ - const gchar *argv2[4] = { - "spamc", - "-L", - "ham", - NULL - }; - CamelMimeMessage *msg = target->m; - - if (!is_installed) - return; - - d(fprintf (stderr, "em_junk_sa_report_notjunk\n")); - - if (em_junk_sa_is_available (&target->error)) { - - if (no_allow_tell && em_junk_sa_local_only) - argv[4] = "--local"; - G_LOCK (report); - pipe_to_sa (msg, NULL, - (no_allow_tell ? argv : argv2), - NULL, &target->error); - G_UNLOCK (report); - } -} - -void -em_junk_sa_commit_reports (EPlugin *ep) -{ - const gchar *sync_op = - (get_spamassassin_version () >= 3) ? "--sync": "--rebuild"; - const gchar *argv[4] = { - "sa-learn", - sync_op, - NULL, - NULL - }; - - /* Only meaningful if we're using sa-learn */ - if (!no_allow_tell || !is_installed) - return; - - d(fprintf (stderr, "em_junk_sa_commit_reports\n")); - - if (em_junk_sa_is_available (NULL)) { - if (em_junk_sa_local_only) - argv[2] = "--local"; - - G_LOCK (report); - pipe_to_sa (NULL, NULL, argv, NULL, NULL); - G_UNLOCK (report); - } -} - -gpointer -em_junk_sa_validate_binary (EPlugin *ep) -{ - gpointer res = em_junk_sa_is_available (NULL) ? (gpointer) "1" : NULL; - - if (res != NULL) - is_installed = TRUE; - - return res; -} - -static void -em_junk_sa_setting_notify (GConfClient *gconf, guint cnxn_id, GConfEntry *entry, gpointer data) -{ - GConfValue *value; - gchar *tkey; - - g_return_if_fail (gconf_entry_get_key (entry) != NULL); - - if (!(value = gconf_entry_get_value (entry))) - return; - - tkey = strrchr (entry->key, '/'); - g_return_if_fail (tkey != NULL); - - if (!strcmp(tkey, "local_only")) - 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, "socket_path")) { - G_LOCK (socket_path); - g_free (em_junk_sa_preferred_socket_path); - em_junk_sa_preferred_socket_path = g_strdup (gconf_value_get_string (value)); - G_UNLOCK (socket_path); - } -} - -gint -e_plugin_lib_enable (EPlugin *ep, gint enable) -{ - is_installed = enable != 0; - - if (is_installed) - em_junk_sa_tested = FALSE; - - em_junk_sa_init (); - - return 0; -} - -static void -em_junk_sa_init (void) -{ - G_LOCK (init); - - 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); - - G_LOCK (socket_path); - g_free (em_junk_sa_preferred_socket_path); - em_junk_sa_preferred_socket_path = gconf_client_get_string (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/socket_path", NULL); - G_UNLOCK (socket_path); - - gconf_client_notify_add(em_junk_sa_gconf, "/apps/evolution/mail/junk/sa", - (GConfClientNotifyFunc) em_junk_sa_setting_notify, - NULL, NULL, NULL); - - em_junk_sa_spamc_gconf_binary = gconf_client_get_string (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/spamc_binary", NULL); - em_junk_sa_spamd_gconf_binary = gconf_client_get_string (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/spamd_binary", NULL); - - atexit (em_junk_sa_finalize); - } - - G_UNLOCK (init); -} - -static void -em_junk_sa_kill_spamd (void) -{ - G_LOCK (socket_path); - g_free (em_junk_sa_preferred_socket_path); - em_junk_sa_preferred_socket_path = NULL; - G_UNLOCK (socket_path); - - if (em_junk_sa_new_daemon_started) { - gint fd = open (em_junk_sa_spamd_pidfile, O_RDONLY); - - if (fd != -1) { - gchar pid_str[16]; - gint bytes; - - bytes = read (fd, pid_str, 15); - if (bytes > 0) { - gint 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")); - - g_object_unref (em_junk_sa_gconf); - em_junk_sa_kill_spamd (); -} - -static void -use_remote_tests_cb (GtkWidget *widget, gpointer data) -{ - gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - gconf_client_set_bool (em_junk_sa_gconf, data, !active, NULL); -} - -GtkWidget * -org_gnome_sa_use_remote_tests (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data) -{ - EShell *shell; - GtkWidget *check, *vbox, *label; - gchar *text = g_strdup_printf (" %s", _("This will make SpamAssassin more reliable, but slower")); - guint n_rows; - - g_object_get (data->parent, "n-rows", &n_rows, NULL); - - if (data->old) - return data->old; - - check = gtk_check_button_new_with_mnemonic (_("I_nclude remote tests")); - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), text); - g_free (text); - vbox = gtk_vbox_new (FALSE, 2); - gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (check), FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (label), FALSE, FALSE, 0); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), !em_junk_sa_local_only); - g_signal_connect (GTK_TOGGLE_BUTTON (check), "toggled", G_CALLBACK (use_remote_tests_cb), (gpointer) "/apps/evolution/mail/junk/sa/local_only"); - gtk_table_attach ( - GTK_TABLE (data->parent), vbox, - 0, 1, n_rows, n_rows+1, 0, 0, 0, 0); - - shell = e_shell_get_default (); - if (e_shell_get_express_mode (shell)) - gtk_widget_hide (vbox); - else - gtk_widget_show_all (vbox); - - return vbox; -} - diff --git a/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml b/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml deleted file mode 100644 index 83ed170c74..0000000000 --- a/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - <_description>Filter junk messages using SpamAssassin. - - - - - - - - - - - - - -- cgit