X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/3a35cf56e7c9951f6d99f54c65d7109654c854f0..6b4093c022450f5fd3bac9010b48602461b6956a:/lisp/mh-e/mh-junk.el diff --git a/lisp/mh-e/mh-junk.el b/lisp/mh-e/mh-junk.el index a20117d858..e3ca8ad24e 100644 --- a/lisp/mh-e/mh-junk.el +++ b/lisp/mh-e/mh-junk.el @@ -1,6 +1,6 @@ -;;; mh-junk.el --- Interface to anti-spam measures +;;; mh-junk.el --- MH-E interface to anti-spam measures -;; Copyright (C) 2003, 2004 Free Software Foundation, Inc. +;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. ;; Author: Satyaki Das , ;; Bill Wohler @@ -9,10 +9,10 @@ ;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -20,9 +20,7 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: @@ -32,20 +30,23 @@ ;;; Code: -(eval-when-compile (require 'mh-acros)) -(mh-require-cl) (require 'mh-e) +(require 'mh-scan) +(mh-require-cl) -;; Interactive functions callable from the folder buffer ;;;###mh-autoload (defun mh-junk-blacklist (range) "Blacklist RANGE as spam. -This command trains the spam program in use (see the `mh-junk-program' option) -with the content of the range (see `mh-interactive-range') and then handles -the message(s) as specified by the `mh-junk-disposition' option. +This command trains the spam program in use (see the option +`mh-junk-program') with the content of RANGE and then handles the +message(s) as specified by the option `mh-junk-disposition'. + +Check the documentation of `mh-interactive-range' to see how RANGE is +read in interactive use. -For more information about using your particular spam fighting program, see: +For more information about using your particular spam fighting +program, see: - `mh-spamassassin-blacklist' - `mh-bogofilter-blacklist' @@ -63,9 +64,9 @@ For more information about using your particular spam fighting program, see: (substring mh-junk-disposition 1))) (t (concat "+" mh-junk-disposition))))) (mh-iterate-on-range msg range - (message (format "Blacklisting message %d..." msg)) + (message "Blacklisting message %d..." msg) (funcall (symbol-function blacklist-func) msg) - (message (format "Blacklisting message %d...done" msg)) + (message "Blacklisting message %d...done" msg) (if (not (memq msg mh-seen-list)) (setq mh-seen-list (cons msg mh-seen-list))) (if dest @@ -77,19 +78,20 @@ For more information about using your particular spam fighting program, see: (defun mh-junk-whitelist (range) "Whitelist RANGE as ham. -This command reclassifies a range of messages (see `mh-interactive-range') as -ham if it were incorrectly classified as spam. It then refiles the message -into the `+inbox' folder. +This command reclassifies the RANGE as ham if it were incorrectly +classified as spam (see the option `mh-junk-program'). It then +refiles the message into the \"+inbox\" folder. -The `mh-junk-program' option specifies the spam program in use." +Check the documentation of `mh-interactive-range' to see how +RANGE is read in interactive use." (interactive (list (mh-interactive-range "Whitelist"))) (let ((whitelist-func (nth 2 (assoc mh-junk-choice mh-junk-function-alist)))) (unless whitelist-func (error "Customize `mh-junk-program' appropriately")) (mh-iterate-on-range msg range - (message (format "Whitelisting message %d..." msg)) + (message "Whitelisting message %d..." msg) (funcall (symbol-function whitelist-func) msg) - (message (format "Whitelisting message %d...done" msg)) + (message "Whitelisting message %d...done" msg) (mh-refile-a-msg nil (intern mh-inbox))) (mh-next-msg))) @@ -100,14 +102,18 @@ The `mh-junk-program' option specifies the spam program in use." (defvar mh-spamassassin-executable (executable-find "spamassassin")) (defvar mh-sa-learn-executable (executable-find "sa-learn")) +;;;###mh-autoload (defun mh-spamassassin-blacklist (msg) "Blacklist MSG with SpamAssassin. -SpamAssassin is one of the more popular spam filtering programs. Get it from -your local distribution or from http://spamassassin.org/. +SpamAssassin is one of the more popular spam filtering programs. +Get it from your local distribution or from +http://spamassassin.org/. -To use SpamAssassin, add the following recipes to `.procmailrc': +To use SpamAssassin, add the following recipes to +\".procmailrc\": + PATH=$PATH:/usr/bin/mh MAILDIR=$HOME/`mhparam Path` # Fight spam with SpamAssassin. @@ -123,92 +129,103 @@ To use SpamAssassin, add the following recipes to `.procmailrc': * ^X-Spam-Status: Yes spam/. -If you don't use `spamc', use `spamassassin -P -a'. - -Note that one of the recipes above throws away messages with a score greater -than or equal to 10. Here's how you can determine a value that works best for -you. - -First, run `spamassassin -t' on every mail message in your archive and use -Gnumeric to verify that the average plus the standard deviation of good mail -is under 5, the SpamAssassin default for \"spam\". - -Using Gnumeric, sort the messages by score and view the messages with the -highest score. Determine the score which encompasses all of your interesting -messages and add a couple of points to be conservative. Add that many dots to -the `X-Spam-Level:' header field above to send messages with that score down -the drain. - -In the example above, messages with a score of 5-9 are set aside in the -`+spam' folder for later review. The major weakness of rules-based filters is -a plethora of false positives so it is worthwhile to check. - -If SpamAssassin classifies a message incorrectly, or is unsure, you can use -the MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist]. - -The \\[mh-junk-blacklist] command adds a `blacklist_from' entry to -`~/spamassassin/user_prefs', deletes the message, and sends the message to the -Razor, so that others might not see this spam. If the `sa-learn' command is -available, the message is also recategorized as spam. - -The \\[mh-junk-whitelist] command adds a `whitelist_from' rule to the -`~/.spamassassin/user_prefs' file. If the `sa-learn' command is available, the -message is also recategorized as ham. - -Over time, you'll observe that the same host or domain occurs repeatedly in -the `blacklist_from' entries, so you might think that you could avoid future -spam by blacklisting all mail from a particular domain. The utility function -`mh-spamassassin-identify-spammers' helps you do precisely that. This function -displays a frequency count of the hosts and domains in the `blacklist_from' -entries from the last blank line in `~/.spamassassin/user_prefs' to the end of -the file. This information can be used so that you can replace multiple -`blacklist_from' entries with a single wildcard entry such as: +If you don't use \"spamc\", use \"spamassassin -P -a\". + +Note that one of the recipes above throws away messages with a +score greater than or equal to 10. Here's how you can determine a +value that works best for you. + +First, run \"spamassassin -t\" on every mail message in your +archive and use Gnumeric to verify that the average plus the +standard deviation of good mail is under 5, the SpamAssassin +default for \"spam\". + +Using Gnumeric, sort the messages by score and view the messages +with the highest score. Determine the score which encompasses all +of your interesting messages and add a couple of points to be +conservative. Add that many dots to the \"X-Spam-Level:\" header +field above to send messages with that score down the drain. + +In the example above, messages with a score of 5-9 are set aside +in the \"+spam\" folder for later review. The major weakness of +rules-based filters is a plethora of false positives so it is +worthwhile to check. + +If SpamAssassin classifies a message incorrectly, or is unsure, +you can use the MH-E commands \\[mh-junk-blacklist] and +\\[mh-junk-whitelist]. + +The command \\[mh-junk-blacklist] adds a \"blacklist_from\" entry +to \"~/spamassassin/user_prefs\", deletes the message, and sends +the message to the Razor, so that others might not see this spam. +If the \"sa-learn\" command is available, the message is also +recategorized as spam. + +The command \\[mh-junk-whitelist] adds a \"whitelist_from\" rule +to the \"~/.spamassassin/user_prefs\" file. If the \"sa-learn\" +command is available, the message is also recategorized as ham. + +Over time, you'll observe that the same host or domain occurs +repeatedly in the \"blacklist_from\" entries, so you might think +that you could avoid future spam by blacklisting all mail from a +particular domain. The utility function +`mh-spamassassin-identify-spammers' helps you do precisely that. +This function displays a frequency count of the hosts and domains +in the \"blacklist_from\" entries from the last blank line in +\"~/.spamassassin/user_prefs\" to the end of the file. This +information can be used so that you can replace multiple +\"blacklist_from\" entries with a single wildcard entry such as: blacklist_from *@*amazingoffersdirect2u.com -In versions of SpamAssassin (2.50 and on) that support a Bayesian classifier, -\\[mh-junk-blacklist] uses the `sa-learn' program to recategorize the message -as spam. Neither MH-E, nor SpamAssassin, rebuilds the database after adding -words, so you will need to run `sa-learn --rebuild' periodically. This can be +In versions of SpamAssassin (2.50 and on) that support a Bayesian +classifier, \\[mh-junk-blacklist] uses the program \"sa-learn\" +to recategorize the message as spam. Neither MH-E, nor +SpamAssassin, rebuilds the database after adding words, so you +will need to run \"sa-learn --rebuild\" periodically. This can be done by adding the following to your crontab: - 0 * * * * sa-learn --rebuild > /dev/null 2>&1" + 0 * * * * sa-learn --rebuild > /dev/null 2>&1" (unless mh-spamassassin-executable (error "Unable to find the spamassassin executable")) (let ((current-folder mh-current-folder) (msg-file (mh-msg-filename msg mh-current-folder)) (sender)) - (save-excursion - (message (format "Reporting message %d..." msg)) - (mh-truncate-log-buffer) - (call-process mh-spamassassin-executable msg-file mh-log-buffer nil + (message "Reporting message %d..." msg) + (mh-truncate-log-buffer) + ;; Put call-process output in log buffer if we are saving it + ;; (this happens if mh-junk-background is t). + (with-current-buffer mh-log-buffer + (call-process mh-spamassassin-executable msg-file mh-junk-background nil ;;"--report" "--remove-from-whitelist" "-r" "-R") ; spamassassin V2.20 - (when mh-sa-learn-executable - (message "Recategorizing this message as spam...") - (call-process mh-sa-learn-executable msg-file mh-log-buffer nil - "--single" "--spam" "--local" "--no-rebuild")) - (message (format "Blacklisting message %d..." msg)) - (set-buffer (get-buffer-create mh-temp-buffer)) + (when mh-sa-learn-executable + (message "Recategorizing message %d as spam..." msg) + (mh-truncate-log-buffer) + (call-process mh-sa-learn-executable msg-file mh-junk-background nil + "--single" "--spam" "--local" "--no-rebuild"))) + (message "Blacklisting sender of message %d..." msg) + (with-current-buffer (get-buffer-create mh-temp-buffer) (erase-buffer) (call-process (expand-file-name mh-scan-prog mh-progs) - nil mh-junk-background nil - (format "%s" msg) current-folder + nil t nil + (format "%d" msg) current-folder "-format" "%<(mymbox{from})%|%(addr{from})%>") (goto-char (point-min)) (if (search-forward-regexp "^\\(.+\\)$" nil t) (progn (setq sender (match-string 0)) (mh-spamassassin-add-rule "blacklist_from" sender) - (message (format "Blacklisting message %d...done" msg))) - (message (format "Blacklisting message %d...not done (from my address)" msg)))))) + (message "Blacklisting sender of message %d...done" msg)) + (message "Blacklisting sender of message %d...not done (from my address)" msg))))) +;;;###mh-autoload (defun mh-spamassassin-whitelist (msg) "Whitelist MSG with SpamAssassin. -The \\[mh-junk-whitelist] command adds a `whitelist_from' rule to the -`~/.spamassassin/user_prefs' file. If the `sa-learn' command is available, the -message is also recategorized as ham. +The \\[mh-junk-whitelist] command adds a \"whitelist_from\" rule to +the \"~/.spamassassin/user_prefs\" file. If the \"sa-learn\" command +is available, the message is also recategorized as ham. See `mh-spamassassin-blacklist' for more information." (unless mh-spamassassin-executable @@ -216,31 +233,34 @@ See `mh-spamassassin-blacklist' for more information." (let ((msg-file (mh-msg-filename msg mh-current-folder)) (show-buffer (get-buffer mh-show-buffer)) from) - (save-excursion - (set-buffer (get-buffer-create mh-temp-buffer)) + (with-current-buffer (get-buffer-create mh-temp-buffer) (erase-buffer) - (message "Removing spamassassin markup from message...") - (call-process mh-spamassassin-executable msg-file mh-temp-buffer nil + (message "Removing spamassassin markup from message %d..." msg) + (call-process mh-spamassassin-executable msg-file t nil ;; "--remove-markup" "-d") ; spamassassin V2.20 (if show-buffer (kill-buffer show-buffer)) (write-file msg-file) (when mh-sa-learn-executable - (message "Recategorizing this message as ham...") - (call-process mh-sa-learn-executable msg-file mh-temp-buffer nil - "--single" "--ham" "--local --no-rebuild")) - (message (format "Whitelisting message %d..." msg)) + (message "Recategorizing message %d as ham..." msg) + (mh-truncate-log-buffer) + ;; Put call-process output in log buffer if we are saving it + ;; (this happens if mh-junk-background is t). + (with-current-buffer mh-log-buffer + (call-process mh-sa-learn-executable msg-file mh-junk-background nil + "--single" "--ham" "--local" "--no-rebuild"))) + (message "Whitelisting sender of message %d..." msg) (setq from (car (mh-funcall-if-exists ietf-drums-parse-address (mh-get-header-field "From:")))) (kill-buffer nil) (unless (or (null from) (equal from "")) (mh-spamassassin-add-rule "whitelist_from" from)) - (message (format "Whitelisting message %d...done" msg))))) + (message "Whitelisting sender of message %d...done" msg)))) (defun mh-spamassassin-add-rule (rule body) - "Add a new rule to `~/.spamassassin/user_prefs'. + "Add a new rule to \"~/.spamassassin/user_prefs\". The name of the rule is RULE and its body is BODY." (save-window-excursion (let* ((line (format "%s\t%s\n" rule body)) @@ -256,14 +276,15 @@ The name of the rule is RULE and its body is BODY." (if (not buffer-exists) (kill-buffer nil))))) +;;;###mh-autoload (defun mh-spamassassin-identify-spammers () "Identify spammers who are repeat offenders. -This function displays a frequency count of the hosts and domains in the -`blacklist_from' entries from the last blank line in -`~/.spamassassin/user_prefs' to the end of the file. This information can be -used so that you can replace multiple `blacklist_from' entries with a single -wildcard entry such as: +This function displays a frequency count of the hosts and domains +in the \"blacklist_from\" entries from the last blank line in +\"~/.spamassassin/user_prefs\" to the end of the file. This +information can be used so that you can replace multiple +\"blacklist_from\" entries with a single wildcard entry such as: blacklist_from *@*amazingoffersdirect2u.com" (interactive) @@ -305,11 +326,12 @@ wildcard entry such as: (defvar mh-bogofilter-executable (executable-find "bogofilter")) +;;;###mh-autoload (defun mh-bogofilter-blacklist (msg) - "Blacklist MSG with Bogofilter. + "Blacklist MSG with bogofilter. -Bogofilter is a Bayesian spam filtering program. Get it from your local -distribution or from http://bogofilter.sourceforge.net/. +Bogofilter is a Bayesian spam filtering program. Get it from your +local distribution or from http://bogofilter.sourceforge.net/. Bogofilter is taught by running: @@ -320,15 +342,16 @@ on every good message, and bogofilter -s < spam-message on every spam message. This is called a full training; three other -training methods are described in the FAQ that is distributed with bogofilter. -Note that most Bayesian filters need 1000 to 5000 of each type of message to -start doing a good job. +training methods are described in the FAQ that is distributed with +bogofilter. Note that most Bayesian filters need 1000 to 5000 of each +type of message to start doing a good job. -To use Bogofilter, add the following recipes to `.procmailrc': +To use bogofilter, add the following recipes to \".procmailrc\": + PATH=$PATH:/usr/bin/mh MAILDIR=$HOME/`mhparam Path` - # Fight spam with Bogofilter. + # Fight spam with bogofilter. :0fw | bogofilter -3 -e -p @@ -340,9 +363,9 @@ To use Bogofilter, add the following recipes to `.procmailrc': * ^X-Bogosity: Unsure, tests=bogofilter spam/unsure/. -If Bogofilter classifies a message incorrectly, or is unsure, you can use the -MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist] to update -Bogofilter's training. +If bogofilter classifies a message incorrectly, or is unsure, you can +use the MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist] +to update bogofilter's training. The \"Bogofilter FAQ\" suggests that you run the following occasionally to shrink the database: @@ -355,18 +378,27 @@ The \"Bogofilter tuning HOWTO\" describes how you can fine-tune Bogofilter." (unless mh-bogofilter-executable (error "Unable to find the bogofilter executable")) (let ((msg-file (mh-msg-filename msg mh-current-folder))) - (call-process mh-bogofilter-executable msg-file mh-junk-background - nil "-s"))) + (mh-truncate-log-buffer) + ;; Put call-process output in log buffer if we are saving it + ;; (this happens if mh-junk-background is t). + (with-current-buffer mh-log-buffer + (call-process mh-bogofilter-executable msg-file mh-junk-background + nil "-s")))) +;;;###mh-autoload (defun mh-bogofilter-whitelist (msg) - "Whitelist MSG with Bogofilter. + "Whitelist MSG with bogofilter. See `mh-bogofilter-blacklist' for more information." (unless mh-bogofilter-executable (error "Unable to find the bogofilter executable")) (let ((msg-file (mh-msg-filename msg mh-current-folder))) - (call-process mh-bogofilter-executable msg-file mh-junk-background - nil "-n"))) + (mh-truncate-log-buffer) + ;; Put call-process output in log buffer if we are saving it + ;; (this happens if mh-junk-background is t). + (with-current-buffer mh-log-buffer + (call-process mh-bogofilter-executable msg-file mh-junk-background + nil "-n")))) @@ -374,14 +406,16 @@ See `mh-bogofilter-blacklist' for more information." (defvar mh-spamprobe-executable (executable-find "spamprobe")) +;;;###mh-autoload (defun mh-spamprobe-blacklist (msg) "Blacklist MSG with SpamProbe. SpamProbe is a Bayesian spam filtering program. Get it from your local distribution or from http://spamprobe.sourceforge.net. -To use SpamProbe, add the following recipes to `.procmailrc': +To use SpamProbe, add the following recipes to \".procmailrc\": + PATH=$PATH:/usr/bin/mh MAILDIR=$HOME/`mhparam Path` # Fight spam with SpamProbe. @@ -395,15 +429,20 @@ To use SpamProbe, add the following recipes to `.procmailrc': *^X-SpamProbe: SPAM spam/. -If SpamProbe classifies a message incorrectly, you can use the MH-E commands -\\[mh-junk-blacklist] and \\[mh-junk-whitelist] to update SpamProbe's -training." +If SpamProbe classifies a message incorrectly, you can use the +MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist] to +update SpamProbe's training." (unless mh-spamprobe-executable (error "Unable to find the spamprobe executable")) (let ((msg-file (mh-msg-filename msg mh-current-folder))) - (call-process mh-spamprobe-executable msg-file mh-junk-background - nil "spam"))) + (mh-truncate-log-buffer) + ;; Put call-process output in log buffer if we are saving it + ;; (this happens if mh-junk-background is t). + (with-current-buffer mh-log-buffer + (call-process mh-spamprobe-executable msg-file mh-junk-background + nil "spam")))) +;;;###mh-autoload (defun mh-spamprobe-whitelist (msg) "Whitelist MSG with SpamProbe. @@ -411,15 +450,19 @@ See `mh-spamprobe-blacklist' for more information." (unless mh-spamprobe-executable (error "Unable to find the spamprobe executable")) (let ((msg-file (mh-msg-filename msg mh-current-folder))) - (call-process mh-spamprobe-executable msg-file mh-junk-background - nil "good"))) + (mh-truncate-log-buffer) + ;; Put call-process output in log buffer if we are saving it + ;; (this happens if mh-junk-background is t). + (with-current-buffer mh-log-buffer + (call-process mh-spamprobe-executable msg-file mh-junk-background + nil "good")))) (provide 'mh-junk) -;;; Local Variables: -;;; indent-tabs-mode: nil -;;; sentence-end-double-space: nil -;;; End: +;; Local Variables: +;; indent-tabs-mode: nil +;; sentence-end-double-space: nil +;; End: -;;; arch-tag: 603335f1-77ff-4306-8828-5d3dad51abe1 +;; arch-tag: 603335f1-77ff-4306-8828-5d3dad51abe1 ;;; mh-junk.el ends here