Synch to No Gnus 200405202205.
authoryamaoka <yamaoka>
Thu, 20 May 2004 22:17:42 +0000 (22:17 +0000)
committeryamaoka <yamaoka>
Thu, 20 May 2004 22:17:42 +0000 (22:17 +0000)
lisp/ChangeLog
lisp/dns.el
lisp/gnus-art.el
lisp/gnus.el
lisp/spam-report.el
lisp/spam.el

index 179bbbd..bc7357f 100644 (file)
@@ -1,3 +1,55 @@
+2004-05-21  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-art.el (gnus-picon-databases): Add /usr/share/picons.
+
+2004-05-20  Magnus Henoch  <mange@freemail.hu>
+
+       * dns.el (dns-read-type): Add support for SVR.  (small patch)
+
+2004-05-20  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * spam.el (spam-use-crm114, spam-crm114, spam-crm114-program)
+       (spam-crm114-header, spam-crm114-spam-switch)
+       (spam-crm114-spam-strong-switch, spam-crm114-ham-strong-switch)
+       (spam-crm114-positive-spam-header)
+       (spam-crm114-database-directory, spam-list-of-processors)
+       (spam-group-spam-processor-crm114-p)
+       (spam-group-ham-processor-crm114-p, spam-extra-header-to-number)
+       (spam-generic-score, spam-list-of-checks)
+       (spam-list-of-statistical-checks, spam-registration-functions)
+       (spam-check-crm114-headers, spam-crm114-score)
+       (spam-check-crm114, spam-crm114-register-with-crm114)
+       (spam-crm114-register-spam-routine)
+       (spam-crm114-unregister-spam-routine)
+       (spam-crm114-register-ham-routine)
+       (spam-crm114-unregister-ham-routine): add CRM114 support.  From
+       asjo@koldfront.dk (Adam Sj\e,Ax\e(Bgren).
+
+       * gnus.el: added spam-use-crm114
+
+       * spam.el (spam-list-of-processors, spam-registration-functions):
+       add spam-use-resend
+       (spam-group-spam-processor-report-resend-p): utility wrapper
+       (spam-report-articles-gmane): doc fix
+       (spam-report-articles-resend,
+       spam-report-resend-register-routine): wrappers around
+       spam-report-resend-to
+
+       * spam-report.el (spam-report-resend-to, spam-report-resend):
+       support for resending spam
+       (spam-report-gmane): line length >80 fix
+
+       * gnus.el (spam-process): add spam-use-resend
+
+2004-05-20  TSUCHIYA Masatoshi  <tsuchiya@namazu.org>
+
+       * spam.el (spam-mark-spam-as-expired-and-move-routine): Return the
+       number of processed spam messages.
+       (spam-ham-copy-or-move-routine): Return the number of processed
+       ham messages.
+       (spam-summary-prepare-exit): Use the above values to decide
+       whether status messages shouled be displayed.
+
 2004-05-20  Katsumi Yamaoka  <yamaoka@jpl.org>
 
        * rfc2047.el (rfc2047-encode-function-alist): Renamed from
        * gnus-group.el (gnus-group-make-kiboze-group)
        (gnus-group-browse-foreign-server): do.
 
-2004-04-22  Teodor Zlatanov  <tzz@bwh.harvard.edu>
+2004-04-22  Teodor Zlatanov  <tzz@lifelogs.com>
 
+       From Dan Christensen <jdc@uwo.ca>, asjo@koldfront.dk (Adam
+       Sj\e,Ax\e(Bgren), Wes Hardaker <wes@hardakers.net>, and Michael Shields
+       <shields@msrl.com>:
+       
        * spam.el (spam-necessary-extra-headers): get the extra headers we
        may need for spam sorting and scoring
        (spam-user-format-function-S): a user format function suitable for
index 19ab3ba..4855b24 100644 (file)
@@ -56,6 +56,7 @@ If nil, /etc/resolv.conf will be consulted.")
     (MX 15)
     (TXT 16)
     (AAAA 28) ; RFC3596
+    (SRV 33) ; RFC2782
     (AXFR 252)
     (MAILB 253)
     (MAILA 254)
@@ -284,6 +285,11 @@ If TCP-P, the first two bytes of the package with be the length field."
                  (list 'retry (dns-read-int32))
                  (list 'expire (dns-read-int32))
                  (list 'minimum (dns-read-int32))))
+          ((eq type 'SRV)
+           (list (list 'priority (dns-read-bytes 2))
+                 (list 'weight (dns-read-bytes 2))
+                 (list 'port (dns-read-bytes 2))
+                 (list 'target (dns-read-name buffer))))
           ((eq type 'MX)
            (cons (dns-read-bytes 2) (dns-read-name buffer)))
           ((or (eq type 'CNAME) (eq type 'NS) (eq type 'PTR))
index 018c846..ddb00ba 100644 (file)
@@ -822,7 +822,8 @@ be controlled by `gnus-treat-body-boundary'."
   :type '(choice (item :tag "None" :value nil)
                 string))
 
-(defcustom gnus-picon-databases '("/usr/lib/picon" "/usr/local/faces")
+(defcustom gnus-picon-databases '("/usr/lib/picon" "/usr/local/faces"
+                                 "/usr/share/picons")
   "Defines the location of the faces database.
 For information on obtaining this database of pretty pictures, please
 see http://www.cs.indiana.edu/picons/ftp/index.html"
index b68ae98..3dedd3c 100644 (file)
@@ -1934,10 +1934,12 @@ Only applicable to non-spam (unclassified and ham) groups.")
            (const :tag "Spam: Blacklist"     (spam spam-use-blacklist))
            (const :tag "Spam: Bsfilter"      (spam spam-use-bsfilter))
            (const :tag "Spam: Gmane Report"  (spam spam-use-gmane))
+           (const :tag "Spam: Resend Message"(spam spam-use-resend))
            (const :tag "Spam: ifile"         (spam spam-use-ifile))
            (const :tag "Spam: Spam Oracle"   (spam spam-use-spamoracle))
            (const :tag "Spam: Spam-stat"     (spam spam-use-stat))
            (const :tag "Spam: SpamAssassin"  (spam spam-use-spamassassin))
+           (const :tag "Spam: CRM114"        (spam spam-use-crm114))
            (const :tag "Ham: BBDB"           (ham spam-use-BBDB))
            (const :tag "Ham: Bogofilter"     (ham spam-use-bogofilter))
            (const :tag "Ham: Bsfilter"       (ham spam-use-bsfilter))
@@ -1946,6 +1948,7 @@ Only applicable to non-spam (unclassified and ham) groups.")
            (const :tag "Ham: Spam Oracle"    (ham spam-use-spamoracle))
            (const :tag "Ham: Spam-stat"      (ham spam-use-stat))
            (const :tag "Ham: SpamAssassin"   (ham spam-use-spamassassin))
+           (const :tag "Ham: CRM114"         (ham spam-use-crm114))
            (const :tag "Ham: Whitelist"      (ham spam-use-whitelist)))))
    :function-document
    "Which spam or ham processors will be applied when the summary is exited."
@@ -1984,6 +1987,7 @@ spam processing, associated with the appropriate processor."
                   (const :tag "Spam: Spam-stat"     (spam spam-use-stat))
                   (const :tag "Spam: Spam Oracle"   (spam spam-use-spamoracle))
                   (const :tag "Spam: SpamAssassin"  (spam spam-use-spamassassin))
+                  (const :tag "Spam: CRM114"        (spam spam-use-crm114))
                   (const :tag "Ham: BBDB"           (ham spam-use-BBDB))
                   (const :tag "Ham: Bogofilter"     (ham spam-use-bogofilter))
                   (const :tag "Ham: Bsfilter"       (ham spam-use-bsfilter))
@@ -1992,6 +1996,7 @@ spam processing, associated with the appropriate processor."
                   (const :tag "Ham: Spam-stat"      (ham spam-use-stat))
                   (const :tag "Ham: Spam Oracle"    (ham spam-use-spamoracle))
                   (const :tag "Ham: SpamAssassin"   (ham spam-use-spamassassin))
+                  (const :tag "Ham: CRM114"         (ham spam-use-crm114))
                   (const :tag "Ham: Whitelist"      (ham spam-use-whitelist)))))
 
    :parameter-document
@@ -2038,6 +2043,7 @@ spam-autodetect-recheck-messages is set.")
          (variable-item spam-use-BBDB)
          (variable-item spam-use-ifile)
          (variable-item spam-use-spamoracle)
+         (variable-item spam-use-crm114)
          (variable-item spam-use-spamassassin)
          (variable-item spam-use-spamassassin-headers)
          (variable-item spam-use-bsfilter)
@@ -2074,6 +2080,7 @@ set."
        (variable-item spam-use-BBDB)
        (variable-item spam-use-ifile)
        (variable-item spam-use-spamoracle)
+       (variable-item spam-use-crm114)
        (variable-item spam-use-stat)
        (variable-item spam-use-blackholes)
        (variable-item spam-use-hashcash)
index 6527817..7a60538 100644 (file)
@@ -79,12 +79,36 @@ The function must accept the arguments `host' and `report'."
   :type 'file
   :group 'spam-report)
 
+(defcustom spam-report-resend-to (or 
+                                 (when (length user-mail-address) 
+                                   user-mail-address)
+                                 "nonexistent-user-please-fix@invalid.domain")
+  "Email address that spam articles are resent to when reporting."
+  :type 'string
+  :group 'spam-report)
+
 (defvar spam-report-url-ping-temp-agent-function nil
   "Internal variable for `spam-report-agentize' and `spam-report-deagentize'.
 This variable will store the value of `spam-report-url-ping-function' from
 before `spam-report-agentize' was run, so that `spam-report-deagentize' can
 undo that change.")
 
+(defun spam-report-resend (&rest articles)
+  "Report an article as spam by resending via email."
+  (dolist (article articles)
+    (gnus-message 6 
+                 "Reporting spam article %d to <%s>..." 
+                 article spam-report-resend-to)
+    ;; This is ganked from the `gnus-summary-resend-message' function.
+    ;; It involves rendering the SPAM, which is undesirable, but there does
+    ;; not seem to be a nicer way to achieve this.
+    ;; select this particular article
+    (gnus-summary-select-article nil nil nil article)
+    ;; resend it to the destination address
+    (save-excursion
+      (set-buffer gnus-original-article-buffer)
+      (message-resend spam-report-resend-to))))
+
 (defun spam-report-gmane (&rest articles)
   "Report an article as spam through Gmane"
   (dolist (article articles)
@@ -93,10 +117,11 @@ undo that change.")
                   (string-match spam-report-gmane-regex gnus-newsgroup-name)))
       (gnus-message 6 "Reporting spam article %d to spam.gmane.org..." article)
       (if spam-report-gmane-use-article-number
-         (spam-report-url-ping "spam.gmane.org"
-                               (format "/%s:%d"
-                                       (gnus-group-real-name gnus-newsgroup-name)
-                                       article))
+         (spam-report-url-ping 
+          "spam.gmane.org"
+          (format "/%s:%d"
+                  (gnus-group-real-name gnus-newsgroup-name)
+                  article))
        (with-current-buffer nntp-server-buffer
          (gnus-request-head article gnus-newsgroup-name)
          (goto-char (point-min))
index adb83c7..8bfb881 100644 (file)
@@ -55,7 +55,8 @@
 
 ;; autoload spam-report
 (eval-and-compile
-  (autoload 'spam-report-gmane "spam-report"))
+  (autoload 'spam-report-gmane "spam-report")
+  (autoload 'spam-report-resend "spam-report"))
 
 ;; autoload gnus-registry
 (eval-and-compile
@@ -275,6 +276,11 @@ them."
   :type 'boolean
   :group 'spam)
 
+(defcustom spam-use-crm114 nil
+  "Whether the CRM114 Mailfilter should be used by `spam-split'."
+  :type 'boolean
+  :group 'spam)
+
 (defcustom spam-install-hooks (or
                               spam-use-dig
                               spam-use-gmane-xref
@@ -295,7 +301,8 @@ them."
                               spam-use-BBDB-exclusive
                               spam-use-ifile
                               spam-use-stat
-                              spam-use-spamoracle)
+                              spam-use-spamoracle
+                              spam-use-crm114)
   "Whether the spam hooks should be installed.
 Default to t if one of the spam-use-* variables is set."
   :group 'spam
@@ -576,6 +583,53 @@ order for SpamAssassin to recognize the new registered spam."
   :type 'string
   :group 'spam-spamassassin)
 
+(defgroup spam-crm114 nil
+  "Spam CRM114 Mailfilter configuration."
+  :group 'spam)
+
+(defcustom spam-crm114-program (executable-find "mailfilter.crm")
+  "File path of the CRM114 Mailfilter executable program."
+  :type '(choice (file :tag "Location of CRM114 Mailfilter")
+        (const :tag "CRM114 Mailfilter is not installed"))
+  :group 'spam-crm114)
+
+(defcustom spam-crm114-header "X-CRM114-Status"
+  "The header that CRM114 Mailfilter inserts in messages."
+  :type 'string
+  :group 'spam-crm114)
+
+(defcustom spam-crm114-spam-switch "--learnspam"
+  "The switch that CRM114 Mailfilter uses to register spam messages."
+  :type 'string
+  :group 'spam-crm114)
+
+(defcustom spam-crm114-ham-switch "--learnnonspam"
+  "The switch that CRM114 Mailfilter uses to register ham messages."
+  :type 'string
+  :group 'spam-crm114)
+
+(defcustom spam-crm114-spam-strong-switch "--UNKNOWN"
+  "The switch that CRM114 Mailfilter uses to unregister ham messages."
+  :type 'string
+  :group 'spam-crm114)
+
+(defcustom spam-crm114-ham-strong-switch "--UNKNOWN"
+  "The switch that CRM114 Mailfilter uses to unregister spam messages."
+  :type 'string
+  :group 'spam-crm114)
+
+(defcustom spam-crm114-positive-spam-header "^SPAM"
+  "The regex on `spam-crm114-header' for positive spam identification."
+  :type 'regexp
+  :group 'spam-crm114)
+
+(defcustom spam-crm114-database-directory nil
+  "Directory path of the CRM114 Mailfilter databases."
+  :type '(choice (directory
+         :tag "Location of the CRM114 Mailfilter database directory")
+        (const :tag "Use the default"))
+  :group 'spam-crm114)
+
 ;;; Key bindings for spam control.
 
 (gnus-define-keys gnus-summary-mode-map
@@ -659,13 +713,16 @@ finds ham or spam.")
     nil))
 
 (defvar spam-list-of-processors
+  ;; note the CRM114, resend and gmane processors are not defined in gnus.el
   '((gnus-group-spam-exit-processor-report-gmane spam spam-use-gmane)
+    (gnus-group-spam-exit-processor-report-resend spam spam-use-resend)
     (gnus-group-spam-exit-processor-bogofilter   spam spam-use-bogofilter)
     (gnus-group-spam-exit-processor-bsfilter    spam spam-use-bsfilter)
     (gnus-group-spam-exit-processor-blacklist    spam spam-use-blacklist)
     (gnus-group-spam-exit-processor-ifile        spam spam-use-ifile)
     (gnus-group-spam-exit-processor-stat         spam spam-use-stat)
     (gnus-group-spam-exit-processor-spamoracle   spam spam-use-spamoracle)
+    (gnus-group-spam-exit-processor-crm114       spam spam-use-crm114)
     (gnus-group-spam-exit-processor-spamassassin spam spam-use-spamassassin)
     (gnus-group-ham-exit-processor-ifile         ham spam-use-ifile)
     (gnus-group-ham-exit-processor-bogofilter    ham spam-use-bogofilter)
@@ -675,7 +732,8 @@ finds ham or spam.")
     (gnus-group-ham-exit-processor-BBDB          ham spam-use-BBDB)
     (gnus-group-ham-exit-processor-copy          ham spam-use-ham-copy)
     (gnus-group-ham-exit-processor-spamassassin  ham spam-use-spamassassin)
-    (gnus-group-ham-exit-processor-spamoracle    ham spam-use-spamoracle))
+    (gnus-group-ham-exit-processor-spamoracle    ham spam-use-spamoracle)
+    (gnus-group-ham-exit-processor-crm114        ham spam-use-crm114))
   "The `spam-list-of-processors' list.
 This list contains pairs associating a ham/spam exit processor
 variable with a classification and a spam-use-* variable.")
@@ -705,6 +763,9 @@ variable with a classification and a spam-use-* variable.")
 (defun spam-group-spam-processor-report-gmane-p (group)
   (spam-group-processor-p group 'gnus-group-spam-exit-processor-report-gmane))
 
+(defun spam-group-spam-processor-report-resend-p (group)
+  (spam-group-processor-p group 'gnus-group-spam-exit-processor-report-resend))
+
 (defun spam-group-spam-processor-bogofilter-p (group)
   (spam-group-processor-p group 'gnus-group-spam-exit-processor-bogofilter))
 
@@ -720,6 +781,9 @@ variable with a classification and a spam-use-* variable.")
 (defun spam-group-spam-processor-spamoracle-p (group)
   (spam-group-processor-p group 'gnus-group-spam-exit-processor-spamoracle))
 
+(defun spam-group-spam-processor-crm114-p (group)
+  (spam-group-processor-p group 'gnus-group-spam-exit-processor-crm114))
+
 (defun spam-group-ham-processor-bogofilter-p (group)
   (spam-group-processor-p group 'gnus-group-ham-exit-processor-bogofilter))
 
@@ -741,14 +805,27 @@ variable with a classification and a spam-use-* variable.")
 (defun spam-group-ham-processor-spamoracle-p (group)
   (spam-group-processor-p group 'gnus-group-ham-exit-processor-spamoracle))
 
+(defun spam-group-ham-processor-crm114-p (group)
+  (spam-group-processor-p group 'gnus-group-ham-exit-processor-crm114))
+
 (defun spam-report-articles-gmane (n)
-  "Report the current message as spam.
+  "Report the current message as spam via Gmane.
 Respects the process/prefix convention."
   (interactive "P")
   (dolist (article (gnus-summary-work-articles n))
     (gnus-summary-remove-process-mark article)
     (spam-report-gmane article)))
 
+(defun spam-report-articles-resend (n)
+  "Report the current message as spam by resending it.
+Respects the process/prefix convention.  Also see
+`spam-report-resend-to'."
+  (interactive "P")
+  (let ((articles (gnus-summary-work-articles n)))
+    (spam-report-resend articles)
+    (dolist (article articles)
+      (gnus-summary-remove-process-mark article))))
+
 (defun spam-necessary-extra-headers ()
   "Return the extra headers spam.el thinks are necessary."
   (let (list)
@@ -781,6 +858,9 @@ Respects the process/prefix convention."
        (string-to-number (gnus-replace-in-string
                           (gnus-extra-header header headers)
                           ".*hits=" "")))
+       ;; for CRM checking, it's probably faster to just do the string match
+       ((and spam-use-crm114 (string-match "( pR: \\([0-9.-]+\\)" header))
+       (match-string 1 header))
        (t nil))
     nil))
 
@@ -807,6 +887,8 @@ Will not return a nil score."
     (spam-spamassassin-score recheck))
    ((or spam-use-bsfilter spam-use-bsfilter-headers)
     (spam-bsfilter-score recheck))
+   (spam-use-crm114
+    (spam-crm114-score))
    (t (spam-bogofilter-score recheck))))
 
 ;;; Summary entry and exit processing.
@@ -847,7 +929,7 @@ Will not return a nil score."
            ;; call spam-register-routine with specific articles to unregister,
            ;; when there are articles to unregister and the check is enabled
            (when (and unregister-list (symbol-value check))
-             (spam-register-routine 
+             (spam-register-routine
               classification check t unregister-list))))))
 
     ;; find all the spam processors applicable to this group
@@ -861,22 +943,21 @@ Will not return a nil score."
 
     (unless (and spam-move-spam-nonspam-groups-only
                 (spam-group-spam-contents-p gnus-newsgroup-name))
-      (when (< 0 (length (spam-list-articles
-                         gnus-newsgroup-articles
-                         'spam)))
-       (gnus-message 6 "Marking spam as expired and moving it to %s"
-                     (gnus-parameter-spam-process-destination 
-                      gnus-newsgroup-name))
-       (spam-mark-spam-as-expired-and-move-routine
-        (gnus-parameter-spam-process-destination gnus-newsgroup-name))))
+      (let* ((group (gnus-parameter-spam-process-destination
+                    gnus-newsgroup-name))
+            (num (spam-mark-spam-as-expired-and-move-routine group)))
+       (when (> num 0)
+         (gnus-message 6
+                       "%d spam messages are marked as expired and moved it to %s"
+                       num group))))
 
     ;; now we redo spam-mark-spam-as-expired-and-move-routine to only
     ;; expire spam, in case the above did not expire them
-    (when (< 0 (length (spam-list-articles
-                       gnus-newsgroup-articles
-                       'spam)))
-      (gnus-message 6 "Marking spam as expired without moving it")
-      (spam-mark-spam-as-expired-and-move-routine nil))
+    (let ((num (spam-mark-spam-as-expired-and-move-routine nil)))
+      (when (> num 0)
+       (gnus-message 6
+                     "%d spam messages are markd as expired without moving it"
+                     num)))
 
     (when (or (spam-group-ham-contents-p gnus-newsgroup-name)
              (and (spam-group-spam-contents-p gnus-newsgroup-name)
@@ -891,19 +972,20 @@ Will not return a nil score."
                     (spam-group-processor-p gnus-newsgroup-name processor))
            (spam-register-routine classification check)))))
 
-    (when (< 0 (length (spam-list-articles
-                       gnus-newsgroup-articles
-                       'ham)))
-      (when (spam-group-ham-processor-copy-p gnus-newsgroup-name)
-       (gnus-message 6 "Copying ham")
-       (spam-ham-copy-routine
-        (gnus-parameter-ham-process-destination gnus-newsgroup-name)))
-
-      ;; now move all ham articles out of spam groups
-      (when (spam-group-spam-contents-p gnus-newsgroup-name)
-       (gnus-message 6 "Moving ham messages from spam group")
-       (spam-ham-move-routine
-        (gnus-parameter-ham-process-destination gnus-newsgroup-name)))))
+    (when (spam-group-ham-processor-copy-p gnus-newsgroup-name)
+      (let ((num
+            (spam-ham-copy-routine
+             (gnus-parameter-ham-process-destination gnus-newsgroup-name))))
+       (when (> num 0)
+         (gnus-message 6 "%d ham messages are copied" num))))
+
+    ;; now move all ham articles out of spam groups
+    (when (spam-group-spam-contents-p gnus-newsgroup-name)
+      (let ((num
+            (spam-ham-move-routine
+             (gnus-parameter-ham-process-destination gnus-newsgroup-name))))
+       (when (> num 0)
+         (gnus-message 6 "%d ham messages are moved from spam group" num)))))
 
   (setq spam-old-ham-articles nil)
   (setq spam-old-spam-articles nil))
@@ -973,7 +1055,8 @@ When either list is nil, the other is returned."
          (let ((gnus-novice-user nil)) ; don't ask me if I'm sure
            (gnus-summary-delete-article nil))))
 
-      (gnus-summary-yank-process-mark))))
+      (gnus-summary-yank-process-mark)
+      (length tomove))))
 
 (defun spam-ham-copy-or-move-routine (copy groups)
   (gnus-summary-kill-process-mark)
@@ -1017,9 +1100,10 @@ When either list is nil, the other is returned."
          (gnus-summary-set-process-mark article))
        (when todo
          (let ((gnus-novice-user nil)) ; don't ask me if I'm sure
-           (gnus-summary-delete-article nil))))))
+           (gnus-summary-delete-article nil)))))
 
-  (gnus-summary-yank-process-mark))
+    (gnus-summary-yank-process-mark)
+    (length todo)))
 
 (defun spam-ham-copy-routine (&rest groups)
   (if (and (car-safe groups) (listp (car-safe groups)))
@@ -1132,7 +1216,8 @@ When either list is nil, the other is returned."
     (spam-use-bogofilter-headers       .       spam-check-bogofilter-headers)
     (spam-use-bogofilter               .       spam-check-bogofilter)
     (spam-use-bsfilter-headers         .       spam-check-bsfilter-headers)
-    (spam-use-bsfilter                 .       spam-check-bsfilter))
+    (spam-use-bsfilter                 .       spam-check-bsfilter)
+    (spam-use-crm114                   .       spam-check-crm114))
   "The spam-list-of-checks list contains pairs associating a
 parameter variable with a spam checking function.  If the
 parameter variable is true, then the checking function is called,
@@ -1155,7 +1240,8 @@ definitely a spam.")
     spam-use-bsfilter
     spam-use-blackholes
     spam-use-spamassassin
-    spam-use-spamoracle)
+    spam-use-spamoracle
+    spam-use-crm114)
   "The spam-list-of-statistical-checks list contains all the mail
 splitters that need to have the full message body available.
 Note that you should fetch extra headers if you don't like this,
@@ -1323,12 +1409,16 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
                         spam-stat-register-spam-routine
                         spam-stat-unregister-ham-routine
                         spam-stat-unregister-spam-routine)
-    ;; note that spam-use-gmane is not a legitimate check
+    ;; note that spam-use-gmane and spam-use-resend are not legitimate checks
     (spam-use-gmane      nil
                         spam-report-gmane-register-routine
                         ;; does Gmane support unregistration?
                         nil
                         nil)
+    (spam-use-resend     nil
+                        spam-report-resend-register-routine
+                        nil
+                        nil)
     (spam-use-spamassassin spam-spamassassin-register-ham-routine
                           spam-spamassassin-register-spam-routine
                           spam-spamassassin-unregister-ham-routine
@@ -1340,7 +1430,12 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
     (spam-use-bsfilter  spam-bsfilter-register-ham-routine
                         spam-bsfilter-register-spam-routine
                         spam-bsfilter-unregister-ham-routine
-                        spam-bsfilter-unregister-spam-routine))
+                        spam-bsfilter-unregister-spam-routine)
+    (spam-use-crm114 spam-crm114-register-ham-routine
+                    spam-crm114-register-spam-routine
+                    ;; does CRM114 Mailfilter support unregistration?
+                    nil
+                    nil))
   "The spam-registration-functions list contains pairs
 associating a parameter variable with the ham and spam
 registration functions, and the ham and spam unregistration
@@ -2056,6 +2151,9 @@ REMOVE not nil, remove the ADDRESSES."
   (when articles
     (apply 'spam-report-gmane articles)))
 
+(defun spam-report-resend-register-routine (articles)
+  (spam-report-resend articles))
+
 \f
 ;;;; Bogofilter
 (defun spam-check-bogofilter-headers (&optional score)
@@ -2383,6 +2481,89 @@ REMOVE not nil, remove the ADDRESSES."
   (spam-bsfilter-register-ham-routine articles t))
 
 \f
+;;;; CRM114 Mailfilter
+(defun spam-check-crm114-headers (&optional score)
+  (let ((header (message-fetch-field spam-crm114-header))
+       (spam-split-group (if spam-split-symbolic-return
+                             'spam
+                           spam-split-group)))
+    (when header                       ; return nil when no header
+      (if score                                ; scoring mode
+         (if (string-match "( pR: \\([0-9.-]+\\)" header)
+             (match-string 1 header)
+           "0")
+       ;; spam detection mode
+       (when (string-match spam-crm114-positive-spam-header
+                           header)
+         spam-split-group)))))
+
+;; return something sensible if the score can't be determined
+(defun spam-crm114-score ()
+  "Get the CRM114 Mailfilter pR"
+  (interactive)
+  (save-window-excursion
+    (gnus-summary-show-article t)
+    (set-buffer gnus-article-buffer)
+    (let ((score (or (spam-check-crm114-headers t)
+                    (spam-check-crm114 t))))
+      (gnus-summary-show-article)
+      (message "pR: %s" score)
+      (or score "0"))))
+
+(defun spam-check-crm114 (&optional score)
+  "Check the CRM114 Mailfilter backend for the classification of this message"
+  (let ((article-buffer-name (buffer-name))
+       (db spam-crm114-database-directory)
+       return)
+    (with-temp-buffer
+      (let ((temp-buffer-name (buffer-name)))
+       (save-excursion
+         (set-buffer article-buffer-name)
+         (apply 'call-process-region
+                (point-min) (point-max)
+                spam-crm114-program
+                nil temp-buffer-name nil
+                 (when db (list (concat "--fileprefix=" db)))))
+       (setq return (spam-check-crm114-headers score))))
+    return))
+
+(defun spam-crm114-register-with-crm114 (articles
+                                        spam
+                                        &optional unregister)
+  "Register an article, given as a string, as spam or non-spam."
+  (dolist (article articles)
+    (let ((article-string (spam-get-article-as-string article))
+         (db spam-crm114-database-directory)
+         (switch (if unregister
+                     (if spam
+                         spam-crm114-spam-strong-switch
+                       spam-crm114-ham-strong-switch)
+                   (if spam
+                       spam-crm114-spam-switch
+                     spam-crm114-ham-switch))))
+      (when (stringp article-string)
+       (with-temp-buffer
+         (insert article-string)
+
+         (apply 'call-process-region
+                (point-min) (point-max)
+                spam-crm114-program
+                nil nil nil
+                 (when db (list switch (concat "--fileprefix=" db)))))))))
+
+(defun spam-crm114-register-spam-routine (articles &optional unregister)
+  (spam-crm114-register-with-crm114 articles t unregister))
+
+(defun spam-crm114-unregister-spam-routine (articles)
+  (spam-crm114-register-spam-routine articles t))
+
+(defun spam-crm114-register-ham-routine (articles &optional unregister)
+  (spam-crm114-register-with-crm114 articles nil unregister))
+
+(defun spam-crm114-unregister-ham-routine (articles)
+  (spam-crm114-register-ham-routine articles t))
+
+\f
 ;;;; Hooks
 
 ;;;###autoload