;;; rmail-spam-filter.el --- spam filter for Rmail, the Emacs mail reader
-;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-;; Free Software Foundation, Inc.
+;; Copyright (C) 2002-2015 Free Software Foundation, Inc.
;; Keywords: email, spam, filter, rmail
;; Author: Eli Tziperman <eli AT deas.harvard.edu>
+;; Package: rmail
;; This file is part of GNU Emacs.
;; 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: (FIXME ?)
+ ;; won't be displayed for this message: (FIXME ?)
(if (and (car maybe-spam) (cdr maybe-spam))
(setq exit-while-loop t)
;; Else, spam was not yet found, proceed to next element
;; Else the prompt to write a new file leaves the raw
;; mbox buffer visible.
(and newfile
- (rmail-show-message (rmail-first-unseen-message) 1))
+ (rmail-show-message (rmail-first-unseen-message) t))
(rmail-output rsf-file)
;; Swap back, else rmail-get-new-mail-1 gets confused.
(when newfile
(setq return-value t)))
return-value))
+(defun rmail-get-new-mail-filter-spam (nnew)
+ "Check the most NNEW recent messages for spam.
+This is called at the end of `rmail-get-new-mail-1' if there is new mail."
+ (let* ((nold (- rmail-total-messages nnew))
+ (nspam 0)
+ (nscan (1+ nold))
+ ;; Save the original deleted state of all the messages.
+ (rdv-old rmail-deleted-vector)
+ errflag)
+ ;; Set all messages undeleted so that the expunge only affects spam.
+ (setq rmail-deleted-vector (make-string (1+ rmail-total-messages) ?\s))
+ (while (and (not errflag) (<= nscan rmail-total-messages))
+ (condition-case nil
+ (or (rmail-spam-filter nscan)
+ (setq nspam (1+ nspam)))
+ (error (setq errflag nscan)))
+ (setq nscan (1+ nscan)))
+ (unwind-protect
+ (if errflag
+ (progn
+ (setq rmail-use-spam-filter nil)
+ (if rsf-beep (ding t))
+ (message "Spam filter error for new message %d, disabled" errflag)
+ (sleep-for rsf-sleep-after-message))
+ (when (> nspam 0)
+ ;; Otherwise sleep or expunge prompt leaves raw mbox buffer showing.
+ (rmail-show-message (or (rmail-first-unseen-message) 1) t)
+ (unwind-protect
+ (progn
+ (if rsf-beep (ding t))
+ (message "Rmail spam-filter detected and deleted %d spam \
+message%s"
+ nspam (if (= 1 nspam) "" "s"))
+ (sleep-for rsf-sleep-after-message)
+ (if (rmail-expunge-confirmed) (rmail-only-expunge t)))
+ ;; Swap back, else get-new-mail-1 gets confused.
+ (rmail-swap-buffers-maybe)
+ (widen))))
+ ;; Restore the original deleted state. Character N refers to message N.
+ (setq rmail-deleted-vector
+ (concat (substring rdv-old 0 (1+ nold))
+ ;; This still works if we deleted all the new mail.
+ (substring rmail-deleted-vector (1+ nold)))))
+ ;; Return a message based on the number of spam messages found.
+ (cond
+ (errflag ", error in spam filter")
+ ((zerop nspam) "")
+ ((= 1 nnew) ", and it appears to be spam")
+ ((= nspam nnew) ", and all appear to be spam")
+ (t (format ", and %d appear%s to be spam" nspam
+ (if (= 1 nspam) "s" ""))))))
+
;; define functions for interactively adding sender/subject of a
;; specific message to the spam definitions while reading it, using
;; the menubar:
;; to make sure message-subject is actually evaluated and its value
;; substituted.
(add-to-list 'rsf-definitions-alist
- ;; Note that an empty elment is treated the same as
+ ;; Note that an empty element is treated the same as
;; an absent one, so why does it bother to add them?
(list '(from . "")
'(to . "")
(provide 'rmail-spam-filter)
-;; arch-tag: 03e1d45d-b72f-4dd7-8f04-e7fd78249746
-;;; rmail-spam-fitler ends here
+;;; rmail-spam-filter ends here