# HG changeset patch # User Paul Reilly # Date 1045593680 0 # Node ID cb307edb1d27be745a0addbfd147ebce993dc7a8 # Parent 31edc813b710a941d9cf40efd475be005cb2eeb0 Initial commit. diff -r 31edc813b710 -r cb307edb1d27 lisp/mail/rmail-spam-filter.el --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/mail/rmail-spam-filter.el Tue Feb 18 18:41:20 2003 +0000 @@ -0,0 +1,632 @@ +;;; rmail-spam-filter.el --- spam filter for rmail, the emacs mail reader. + +;; Copyright (C) 2002 +;; Free Software Foundation, Inc. +;; Keywords: email, spam, filter, rmail +;; Author: Eli Tziperman + +;; This file is part of GNU Emacs. + +;; 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. + +;; GNU Emacs 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 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., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: +;;; ----------- + +;;; Automatically recognize and delete junk email before it is +;;; displayed in rmail/rmail-summary. Spam emails are defined by +;;; specifying one or more of the sender, subject and contents. +;;; URL: http://www.weizmann.ac.il/~eli/Downloads/rmail-spam-filter/ + +;;; Usage: +;;; ------ + +;;; put in your .emacs: + +;;; (load "rmail-spam-filter.el") + +;;; and use customize (in rmail-spam-filter group) to: + +;;; (*) turn on the variable rmail-use-spam-filter, + +;;; (*) specify in variable rmail-spam-definitions-alist what sender, +;;; subject and contents make an email be considered spam. + +;;; in addition, you may: + +;;; (*) Block future mail with the subject or sender of a message +;;; while reading it in RMAIL: just click on the "Spam" item on the +;;; menubar, and add the subject or sender to the list of spam +;;; definitions using the mouse and the appropriate menu item. Â  You +;;; need to later also save the list of spam definitions using the +;;; same menu item, or alternatively, see variable +;;; `rmail-spam-filter-autosave-newly-added-spam-definitions'. + +;;; (*) specify if blind-cc'ed mail (no "To:" header field) is to be +;;; treated as spam (variable rmail-spam-no-blind-cc; Thanks to Ethan +;;; Brown for this). + +;;; (*) specify if rmail-spam-filter should ignore case of spam +;;; definitions (variable rmail-spam-filter-ignore-case; Thanks to +;;; Ethan Brown for the suggestion). + +;;; (*) Specify a "white-list" of trusted senders. If any +;;; rmail-spam-white-list string matches a substring of the "From" +;;; header, the message is flagged as a valid, non-spam message (Ethan +;;; Brown ). + +;;; (*) rmail spam filter also works with bbdb to prevent spam senders +;;; from entering into the .bbdb file. See variable +;;; "rmail-spam-filter-auto-delete-spam-bbdb-entries". This is done +;;; in two ways: (a) bbdb is made not to auto-create entries for +;;; messages that are deleted by the rmail-spam-filter, (b) when a +;;; message is deleted in rmail, the user is offered to delete the +;;; sender's bbdb entry as well _if_ it was created at the same day. + +(require 'rmail) + +;; For find-if and other cool common lisp functions we may want to use. (EDB) +(require 'cl) + +(defgroup rmail-spam-filter nil + "Spam filter for RMAIL, the mail reader for Emacs." + :group 'rmail) + +(defcustom rmail-use-spam-filter nil + "*Non-nil to activate the rmail spam filter. +Specify `rmail-spam-definitions-alist' to define what you consider spam +emails." + :type 'boolean + :group 'rmail-spam-filter ) + +(defcustom rmail-spam-file "~/XRMAIL-SPAM" + "*Name of rmail file for optionally saving some of the spam. +Spam may be either just deleted, or saved in a separate spam file to +be looked at at a later time. Whether the spam is just deleted or +also saved in a separete spam file is specified for each definition of +spam, as one of the fields of `rmail-spam-definitions-alist'" + :type 'string + :group 'rmail-spam-filter ) + +(defcustom rmail-spam-no-blind-cc nil + "*Non-nil to treat blind CC (no To: header) as spam." + :type 'boolean + :group 'rmail-spam-filter ) + +(defcustom rmail-spam-filter-ignore-case nil + "*Non-nil to ignore case in `rmail-spam-definitions-alist'." + :type 'boolean + :group 'rmail-spam-filter ) + +(defcustom rmail-spam-filter-beep nil + "*Non-nil to beep if spam is found." + :type 'boolean + :group 'rmail-spam-filter ) + +(defcustom rmail-spam-sleep-after-message 2.0 + "*Seconds to wait after display of message that spam was found." + :type 'number + :group 'rmail-spam-filter ) + +(defcustom rmail-spam-filter-auto-delete-spam-bbdb-entries nil + "*Non-nil to make sure no entries are made in bbdb for spam emails. +This is done in two ways: (1) bbdb is made not to auto-create entries +for messages that are deleted by the `rmail-spam-filter', (2) when a +message is deleted in rmail, the user is offered to delete the +sender's bbdb entry as well if it was created at the same day. Note +that Emacs needs to be restarted after setting this option for it to +take an effect." + :type 'boolean + :group 'rmail-spam-filter ) + +(defcustom rmail-spam-filter-autosave-newly-added-spam-definitions nil + "*Non-nil to auto save new spam entries. +New entries entered via the spam menu bar item are then saved to +customization file immediately after being added via the menu bar, and +do not require explicitly saving the file after adding the new +entries." + :type 'boolean + :group 'rmail-spam-filter ) + +(defcustom rmail-spam-white-list nil + "*List of strings to identify valid senders. +If any rmail-spam-white-list string matches a substring of the 'From' +header, the message is flagged as a valid, non-spam message. Example: +If your domain is emacs.com then including 'emacs.com' in your +rmail-spam-white-list would flag all mail from your colleagues as +valid." + :type '(repeat string) + :group 'rmail-spam-filter ) + +(defcustom rmail-spam-definitions-alist nil + "*Alist matching strings defining what messages are considered spam. +Each definition may contain specifications of one or more of the +elements {subject, sender, recipients or contents}, as well as a +definition of what to do with the spam (action item). A spam e-mail +is defined as one that fits all of the specified elements of any one +of the spam definitions. The strings that specify spam subject, +sender, etc, may be regexp. For example, to specify that the subject +may be either 'this is spam' or 'another spam', use the regexp: 'this +is spam\|another spam' (without the single quotes)." + :type '(repeat + (list :format "%v" + (cons :format "%v" :value (from . "") + (const :format "" from) + (string :tag "From" "")) + (cons :format "%v" :value (to . "") + (const :format "" to) + (string :tag "To" "")) + (cons :format "%v" :value (subject . "") + (const :format "" subject) + (string :tag "Subject" "")) + (cons :format "%v" :value (contents . "") + (const :format "" contents) + (string :tag "Contents" "")) + (cons :format "%v" :value (action . output-and-delete) + (const :format "" action) + (choice :tag "Action selection" + (const :tag "output to spam folder and delete" output-and-delete) + (const :tag "delete spam" delete-spam) + )) + )) + :group 'rmail-spam-filter) + +(defvar rmail-spam-filter-scanning-messages-now nil + "Non nil when rmail-spam-filter scans messages, +for interaction with `rmail-bbdb-auto-delete-spam-entries'") + +(defun rmail-spam-filter (msg) + "Return nil if msg is spam based on rmail-spam-definitions-alist. +If spam, optionally output msg to a file `rmail-spam-file' and delete +it from rmail file. Called for each new message retrieved by +`rmail-get-new-mail'." + + (let ((old-message) + (return-value) + (this-is-a-spam-email) + (maybe-spam) + (message-sender) + (message-recipients) + (message-subject) + (num-spam-definition-elements) + (num-element 0) + (exit-while-loop nil) + (saved-case-fold-search case-fold-search) + (save-current-msg) + (rmail-spam-filter-saved-bbdb/mail_auto_create_p nil) + ) + + ;; make sure bbdb does not create entries for messages while spam + ;; filter is scanning the rmail file: + (setq rmail-spam-filter-saved-bbdb/mail_auto_create_p 'bbdb/mail_auto_create_p) + (setq bbdb/mail_auto_create_p nil) + ;; let `rmail-bbdb-auto-delete-spam-entries' know that rmail spam + ;; filter is running, so that deletion of rmail messages should be + ;; ignored for now: + (setq rmail-spam-filter-scanning-messages-now t) + (save-excursion + (save-restriction + (setq this-is-a-spam-email nil) + ;; Narrow buffer to header of message and get Sender and + ;; Subject fields to be used below: + (save-restriction + (goto-char (rmail-msgbeg msg)) + (narrow-to-region (point) (progn (search-forward "\n\n") (point))) + (setq message-sender (mail-fetch-field "From")) + (setq message-recipients (mail-fetch-field "To")) + (setq message-subject (mail-fetch-field "Subject")) + ) + ;; Find number of spam-definition elements in the list + ;; rmail-spam-definitions-alist specified by user: + (setq num-spam-definition-elements (safe-length + rmail-spam-definitions-alist)) + + ;;; do we want to ignore case in spam definitions: + (setq case-fold-search rmail-spam-filter-ignore-case) + + ;; Check for blind CC condition. Set vars such that while + ;; loop will be bypassed and spam condition will trigger (EDB) + (if (and rmail-spam-no-blind-cc + (null message-recipients)) + (progn + (setq exit-while-loop t) + (setq maybe-spam t) + (setq this-is-a-spam-email t))) + + ;; Check white list, and likewise cause while loop + ;; bypass. (EDB) + (if (find-if '(lambda (white-str) + (string-match white-str message-sender)) + rmail-spam-white-list) + (progn + (setq exit-while-loop t) + (setq maybe-spam nil) + (setq this-is-a-spam-email nil))) + + ;; scan all elements of the list rmail-spam-definitions-alist + (while (and + (< num-element num-spam-definition-elements) + (not exit-while-loop)) + (progn + ;; Initialize maybe-spam which is set to t in one of two + ;; cases: (1) unspecified definition-elements are found in + ;; rmail-spam-definitions-alist, (2) empty field is found + ;; in the message being scanned (e.g. empty subject, + ;; sender, recipients, etc). The variable is set to nil + ;; if a non empty field of the scanned message does not + ;; match a specified field in + ;; rmail-spam-definitions-alist. + (setq maybe-spam t) + ;; initialize this-is-a-spam-email to nil. This variable + ;; is set to t if one of the spam definitions matches a + ;; field in the scanned message. + (setq this-is-a-spam-email nil) + + ;; start scanning incoming message: + ;;--------------------------------- + + ;; if sender field is not specified in message being + ;; scanned, AND if "from" field does not appear in spam + ;; definitions for this element, this may still be spam + ;; due to another element... + (if (and (not message-sender) + (string-match + (cdr (assoc 'from (nth num-element + rmail-spam-definitions-alist))) "")) + (setq maybe-spam t) + ;; ... else, if message-sender does appear in the + ;; message, and it also appears in the spam definition + ;; list, it is potentially spam: + (if (and message-sender + (string-match + (cdr (assoc 'from (nth num-element + rmail-spam-definitions-alist))) + message-sender) + ) + (setq this-is-a-spam-email t) + (setq maybe-spam nil) + ) + ) + ;; next, if spam was not ruled out already, check recipients: + (if maybe-spam + ;; if To field does not exist AND is not specified, + ;; this may still be spam due to another element... + (if (and (not message-recipients) + (string-match + (cdr (assoc 'to + (nth num-element + rmail-spam-definitions-alist))) "")) + (setq maybe-spam t) + ;; ... else, if To field does appear in the message, + ;; and it also appears in spam definition list, this + ;; is potentially a spam: + (if (and message-recipients + (string-match + (cdr (assoc 'to (nth num-element + rmail-spam-definitions-alist))) + message-recipients) + ) + (setq this-is-a-spam-email t) + (setq maybe-spam nil) + ) + ) + ) + ;; next, if spam was not ruled out already, check subject: + (if maybe-spam + ;; if subject field does not exist AND is not + ;; specified, this may still be spam due to another + ;; element... + (if (and (not message-subject) + (string-match + (cdr (assoc 'subject + (nth num-element + rmail-spam-definitions-alist))) + "")) + (setq maybe-spam t) + ;; ... else, if subject field does appear in the + ;; message, and it also appears in the spam + ;; definition list, this is potentially a spam: + (if (and message-subject + (string-match + (cdr (assoc 'subject (nth num-element + rmail-spam-definitions-alist))) + message-subject) + ) + (setq this-is-a-spam-email t) + (setq maybe-spam nil) + ) + ) + ) + ;; next, if spam was not ruled out already, check + ;; contents: if contents field is not specified, this may + ;; still be spam due to another element... + (if maybe-spam + (if (string-match + (cdr (assoc 'contents + (nth num-element + rmail-spam-definitions-alist))) "") + (setq maybe-spam t) + ;; ... else, check to see if it appears in spam + ;; definition: + (if (string-match + (cdr (assoc 'contents + (nth num-element + rmail-spam-definitions-alist))) + (buffer-substring + (rmail-msgbeg msg) (rmail-msgend msg))) + (setq this-is-a-spam-email t) + (setq maybe-spam nil))) + ) + ;; if the search in rmail-spam-definitions-alist found + ;; that this email is spam, output the email to the spam + ;; rmail file, mark the email for deletion, leave the + ;; while loop and return nil so that an rmail summary line + ;; wont be displayed for this message: + (if (and this-is-a-spam-email maybe-spam) + ;; found that this is spam, no need to look at the + ;; rest of the rmail-spam-definitions-alist, exit + ;; loop: + (setq exit-while-loop t) + ;; else, spam was not yet found, increment number of + ;; element in rmail-spam-definitions-alist and proceed + ;; to next element: + (setq num-element (+ num-element 1))) + ) + ) + (if (and this-is-a-spam-email maybe-spam) + (progn + ;;(message "Found spam!") + ;;(ding 1) (sleep-for 2) + + ;; temprarily set rmail-current-message in order to + ;; output and delete the spam msg if needed: + (setq save-current-msg rmail-current-message) + (setq rmail-current-message msg) + ;; check action item and rmail-spam-definitions-alist + ;; and do it: + (cond + ((equal (cdr (assoc 'action + (nth num-element rmail-spam-definitions-alist))) + 'output-and-delete) + (progn + (rmail-output-to-rmail-file rmail-spam-file) + (rmail-delete-message) + )) + ((equal (cdr (assoc 'action + (nth num-element rmail-spam-definitions-alist))) + 'delete-spam) + (progn + (rmail-delete-message) + )) + ) + (setq rmail-current-message save-current-msg) + (setq bbdb/mail_auto_create_p 'rmail-spam-filter-saved-bbdb/mail_auto_create_p) + ;; set return value. These lines must be last in the + ;; function, so that they will determine the value + ;; returned by rmail-spam-filter: + (setq return-value nil)) + (setq return-value t)))) + (setq case-fold-search saved-case-fold-search) + (setq rmail-spam-filter-scanning-messages-now nil) + return-value)) + + +;; define functions for interactively adding sender/subject of a +;; specific message to the spam definitions while reading it, using +;; the menubar: +(defun rmail-spam-filter-add-subject-to-spam-list () + (interactive) + (set-buffer rmail-buffer) + (let ((message-subject)) + (setq message-subject (mail-fetch-field "Subject")) + ;; note the use of a backquote and comma on the subject line here, + ;; to make sure message-subject is actually evaluated and its value + ;; substituted: + (add-to-list 'rmail-spam-definitions-alist + (list '(from . "") + '(to . "") + `(subject . ,message-subject) + '(contents . "") + '(action . output-and-delete)) + t) + (customize-mark-to-save 'rmail-spam-definitions-alist) + (if rmail-spam-filter-autosave-newly-added-spam-definitions + (progn + (custom-save-all) + (message (concat "added subject \n <<< \n" message-subject + " \n >>> \n to list of spam definitions. \n" + "and saved the spam definitions to file."))) + (message (concat "added subject \n <<< \n" message-subject + " \n >>> \n to list of spam definitions. \n" + "Don't forget to save the spam definitions to file using the spam menu")) + ))) + +(defun rmail-spam-filter-add-sender-to-spam-list () + (interactive) + (set-buffer rmail-buffer) + (let ((message-sender)) + (setq message-sender (mail-fetch-field "From")) + ;; note the use of a backquote and comma on the "from" line here, + ;; to make sure message-sender is actually evaluated and its value + ;; substituted: + (add-to-list 'rmail-spam-definitions-alist + (list `(from . ,message-sender) + '(to . "") + '(subject . "") + '(contents . "") + '(action . output-and-delete)) + t) + (customize-mark-to-save 'rmail-spam-definitions-alist) + (if rmail-spam-filter-autosave-newly-added-spam-definitions + (progn + (custom-save-all) + (message (concat "added sender \n <<< \n" message-sender + " \n >>> \n to list of spam definitions. \n" + "and saved the spam definitions to file."))) + (message (concat "added sender \n <<< \n " message-sender + " \n >>> \n to list of spam definitions." + "Don't forget to save the spam definitions to file using the spam menu")) + ))) + + +(defun rmail-spam-filter-add-region-to-spam-list () + "Add the region makred by user in the rmail buffer to the list of + spam definitions as a contents field." + (interactive) + (set-buffer rmail-buffer) + (let ((region-to-spam-list)) + ;; check if region is inactive or has zero size: + (if (not (and mark-active (not (= (region-beginning) (region-end))))) + ;; if inactive, print error message: + (message "you need to first highlight some text in the rmail buffer") + ;; if active, add to list of spam definisions: + (progn + (setq region-to-spam-list (buffer-substring (region-beginning) (region-end))) + ;; note the use of a backquote and comma on the "from" line here, + ;; to make sure message-sender is actually evaluated and its value + ;; substituted: + (add-to-list 'rmail-spam-definitions-alist + (list '(from . "") + '(to . "") + '(subject . "") + `(contents . ,region-to-spam-list) + '(action . output-and-delete)) + t) + (customize-mark-to-save 'rmail-spam-definitions-alist) + (if rmail-spam-filter-autosave-newly-added-spam-definitions + (progn + (custom-save-all) + (message (concat "added highlighted text \n <<< \n" region-to-spam-list + " \n >>> \n to list of spam definitions. \n" + "and saved the spam definitions to file."))) + (message (concat "added highlighted text \n <<< \n " region-to-spam-list + " \n >>> \n to list of spam definitions." + "Don't forget to save the spam definitions to file using the spam menu")) + ))))) + + +(defun rmail-spam-filter-customize-spam-definitions () + (interactive) + (customize-variable (quote rmail-spam-definitions-alist))) + +(defun rmail-spam-filter-customize-group () + (interactive) + (customize-group (quote rmail-spam-filter))) + +(defun rmail-spam-custom-save-all () + (interactive) + (custom-save-all)) + +;; add the actual menu items and keyboard shortcuts to both rmail and +;; rmail-summary menu-bars:: +(define-key rmail-summary-mode-map [menu-bar spam] + (cons "Spam" (make-sparse-keymap "Spam"))) +(define-key rmail-mode-map [menu-bar spam] + (cons "Spam" (make-sparse-keymap "Spam"))) + +(define-key rmail-summary-mode-map [menu-bar spam customize-group] + '("Browse customizations of rmail spam filter" . rmail-spam-filter-customize-group)) +(define-key rmail-mode-map [menu-bar spam customize-group] + '("Browse customizations of rmail spam filter" . rmail-spam-filter-customize-group)) +(define-key rmail-summary-mode-map "\C-cSg" 'rmail-spam-filter-customize-group) +(define-key rmail-mode-map "\C-cSg" 'rmail-spam-filter-customize-group) + +(define-key rmail-summary-mode-map [menu-bar spam customize-spam-list] + '("Customize list of spam definitions" . rmail-spam-filter-customize-spam-definitions)) +(define-key rmail-mode-map [menu-bar spam customize-spam-list] + '("Customize list of spam definitions" . rmail-spam-filter-customize-spam-definitions)) +(define-key rmail-summary-mode-map "\C-cSd" 'rmail-spam-filter-customize-spam-definitions) +(define-key rmail-mode-map "\C-cSd" 'rmail-spam-filter-customize-spam-definitions) + +(define-key rmail-summary-mode-map [menu-bar spam lambda] '("----")) +(define-key rmail-mode-map [menu-bar spam lambda] '("----")) + +(define-key rmail-summary-mode-map [menu-bar spam my-custom-save-all] + '("save newly added spam definitions to customization file" . rmail-spam-custom-save-all)) +(define-key rmail-mode-map [menu-bar spam my-custom-save-all] + '("save newly added spam definitions to customization file" . rmail-spam-custom-save-all)) +(define-key rmail-summary-mode-map "\C-cSa" 'rmail-spam-custom-save-all) +(define-key rmail-mode-map "\C-cSa" 'rmail-spam-custom-save-all) + +(define-key rmail-summary-mode-map [menu-bar spam add-region-to-spam-list] + '("add region to spam list" . rmail-spam-filter-add-region-to-spam-list)) +(define-key rmail-mode-map [menu-bar spam add-region-to-spam-list] + '("add region to spam list" . rmail-spam-filter-add-region-to-spam-list)) +(define-key rmail-summary-mode-map "\C-cSn" 'rmail-spam-filter-add-region-to-spam-list) +(define-key rmail-mode-map "\C-cSn" 'rmail-spam-filter-add-region-to-spam-list) + +(define-key rmail-summary-mode-map [menu-bar spam add-sender-to-spam-list] + '("add sender to spam list" . rmail-spam-filter-add-sender-to-spam-list)) +(define-key rmail-mode-map [menu-bar spam add-sender-to-spam-list] + '("add sender to spam list" . rmail-spam-filter-add-sender-to-spam-list)) +(define-key rmail-summary-mode-map "\C-cSr" 'rmail-spam-filter-add-sender-to-spam-list) +(define-key rmail-mode-map "\C-cSr" 'rmail-spam-filter-add-sender-to-spam-list) + +(define-key rmail-summary-mode-map [menu-bar spam add-subject-to-spam-list] + '("add subject to spam list" . rmail-spam-filter-add-subject-to-spam-list)) +(define-key rmail-mode-map [menu-bar spam add-subject-to-spam-list] + '("add subject to spam list" . rmail-spam-filter-add-subject-to-spam-list)) +(define-key rmail-summary-mode-map "\C-cSt" 'rmail-spam-filter-add-subject-to-spam-list) +(define-key rmail-mode-map "\C-cSt" 'rmail-spam-filter-add-subject-to-spam-list) + + +(defun rmail-bbdb-auto-delete-spam-entries () + "When deleting a message in RMAIL, check to see if the bbdb entry +was created today, and if it was, prompt to delete it too. This function +needs to be called via the `rmail-delete-message-hook' like this: +\(add-hook 'rmail-delete-message-hook 'rmail-bbdb-auto-delete-spam-entries)" + (interactive) + (require 'bbdb-hooks) + (if (not rmail-spam-filter-scanning-messages-now) + (if (get-buffer "*BBDB*") + (save-excursion + (set-buffer (get-buffer "*BBDB*")) + (if (bbdb-current-record) + (if (equal + (format-time-string bbdb-time-internal-format (current-time)) + (bbdb-record-getprop (bbdb-current-record) 'creation-date)) + (bbdb-delete-current-record (bbdb-current-record)))))))) + +(defun rmail-spam-filter-bbdb-dont-create-entries-for-spam () + "Make sure senderes of rmail messages marked as deleted are not added to bbdb. +Need to add this as a hook like this: +\(setq bbdb/mail-auto-create-p 'rmail-spam-filter-bbdb-dont-create-entries-for-spam) +and this is also used in conjunction with rmail-bbdb-auto-delete-spam-entries. +More doc: rmail-bbdb-auto-delete-spam-entries will delete newly created bbdb +entries of mail that is deleted. However, if one scrolls back to the deleted +messages, then the sender is again added to the bbdb. This function +prevents this. Also, don't create entries for messages in the `rmail-spam-file'." + (interactive) + (not + ;; don't create a bbdb entry if one of the following conditions is satisfied: + (or + ;; 1) looking at a deleted message: + (rmail-message-deleted-p rmail-current-message) + ;; 2) looking at messages in rmail-spam-file: + (string-match + (expand-file-name rmail-spam-file) + (expand-file-name (buffer-file-name rmail-buffer))) + ))) + +;; activate bbdb-anti-spam measures: +(if rmail-spam-filter-auto-delete-spam-bbdb-entries + (progn + (add-hook 'rmail-delete-message-hook 'rmail-bbdb-auto-delete-spam-entries) + (setq bbdb/mail-auto-create-p 'rmail-spam-filter-bbdb-dont-create-entries-for-spam) + )) + +(provide 'rmail-spam-filter) + +;;; rmail-spam-filter ends here