* eww.el (eww-tag-form): Protect against degenerate forms.
[gnus] / lisp / nnmail.el
index 23cb604..5be449e 100644 (file)
@@ -1,7 +1,6 @@
 ;;; nnmail.el --- mail support functions for the Gnus mail backends
 
 ;;; nnmail.el --- mail support functions for the Gnus mail backends
 
-;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-;;   2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 1995-2013 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news, mail
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news, mail
@@ -25,7 +24,7 @@
 
 ;;; Code:
 
 
 ;;; Code:
 
-;; For Emacs < 22.2.
+;; For Emacs <22.2 and XEmacs.
 (eval-and-compile
   (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
 
 (eval-and-compile
   (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
 
@@ -41,6 +40,8 @@
 
 (autoload 'gnus-add-buffer "gnus")
 (autoload 'gnus-kill-buffer "gnus")
 
 (autoload 'gnus-add-buffer "gnus")
 (autoload 'gnus-kill-buffer "gnus")
+(eval-when-compile
+  (autoload 'mail-send-and-exit "sendmail" nil t))
 
 (defgroup nnmail nil
   "Reading mail with Gnus."
 
 (defgroup nnmail nil
   "Reading mail with Gnus."
@@ -104,7 +105,9 @@ mail belongs in that group.
 
 The last element should always have \"\" as the regexp.
 
 
 The last element should always have \"\" as the regexp.
 
-This variable can also have a function as its value."
+This variable can also have a function as its value, and it can
+also have a fancy split method as its value.  See
+`nnmail-split-fancy' for an explanation of that syntax."
   :group 'nnmail-split
   :type '(choice (repeat :tag "Alist" (group (string :tag "Name")
                                             (choice regexp function)))
   :group 'nnmail-split
   :type '(choice (repeat :tag "Alist" (group (string :tag "Name")
                                             (choice regexp function)))
@@ -176,7 +179,7 @@ is to be performed in, and it should return an integer that says how
 many days an article can be stored before it is considered \"old\".
 It can also return the values `never' and `immediate'.
 
 many days an article can be stored before it is considered \"old\".
 It can also return the values `never' and `immediate'.
 
-Eg.:
+E.g.:
 
 \(setq nnmail-expiry-wait-function
       (lambda (newsgroup)
 
 \(setq nnmail-expiry-wait-function
       (lambda (newsgroup)
@@ -288,7 +291,7 @@ directory.  This hook is called after the incoming mail box has been
 emptied, and can be used to call any mail box programs you have
 running (\"xwatch\", etc.)
 
 emptied, and can be used to call any mail box programs you have
 running (\"xwatch\", etc.)
 
-Eg.
+E.g.:
 
 \(add-hook 'nnmail-read-incoming-hook
          (lambda ()
 
 \(add-hook 'nnmail-read-incoming-hook
          (lambda ()
@@ -552,9 +555,11 @@ parameter.  It should return nil, `warn' or `delete'."
                 (const warn)
                 (const delete)))
 
                 (const warn)
                 (const delete)))
 
-(defcustom nnmail-extra-headers '(To Newsgroups)
-  "*Extra headers to parse."
-  :version "21.1"
+(defcustom nnmail-extra-headers '(To Newsgroups Cc)
+  "Extra headers to parse.
+In addition to the standard headers, these extra headers will be
+included in NOV headers (and the like) when backends parse headers."
+  :version "24.3"
   :group 'nnmail
   :type '(repeat symbol))
 
   :group 'nnmail
   :type '(repeat symbol))
 
@@ -1145,21 +1150,34 @@ FUNC will be called with the group name to determine the article number."
        (run-hooks 'nnmail-split-hook)
        (when (setq nnmail-split-tracing trace)
          (setq nnmail-split-trace nil))
        (run-hooks 'nnmail-split-hook)
        (when (setq nnmail-split-tracing trace)
          (setq nnmail-split-trace nil))
-       (if (and (symbolp nnmail-split-methods)
-                (fboundp nnmail-split-methods))
-           (let ((split
-                  (condition-case error-info
-                      ;; `nnmail-split-methods' is a function, so we
-                      ;; just call this function here and use the
-                      ;; result.
-                      (or (funcall nnmail-split-methods)
-                          (and (not nnmail-inhibit-default-split-group)
-                               '("bogus")))
-                    (error
-                     (nnheader-message
-                      5 "Error in `nnmail-split-methods'; using `bogus' mail group: %S" error-info)
-                     (sit-for 1)
-                     '("bogus")))))
+       (if (or (and (symbolp nnmail-split-methods)
+                    (fboundp nnmail-split-methods))
+               (not (consp (car-safe nnmail-split-methods)))
+               (and (listp nnmail-split-methods)
+                    ;; Not a regular split method, so it has to be a
+                    ;; fancy one.
+                    (not (let ((top-element (car-safe nnmail-split-methods)))
+                           (and (= 2 (length top-element))
+                                (stringp (nth 0 top-element))
+                                (stringp (nth 1 top-element)))))))
+           (let* ((method-function
+                   (if (and (symbolp nnmail-split-methods)
+                            (fboundp nnmail-split-methods))
+                       nnmail-split-methods
+                     'nnmail-split-fancy))
+                  (split
+                   (condition-case error-info
+                       ;; `nnmail-split-methods' is a function, so we
+                       ;; just call this function here and use the
+                       ;; result.
+                       (or (funcall method-function)
+                           (and (not nnmail-inhibit-default-split-group)
+                                '("bogus")))
+                     (error
+                      (nnheader-message
+                       5 "Error in `nnmail-split-methods'; using `bogus' mail group: %S" error-info)
+                      (sit-for 1)
+                      '("bogus")))))
              (setq split (mm-delete-duplicates split))
              ;; The article may be "cross-posted" to `junk'.  What
              ;; to do?  Just remove the `junk' spec.  Don't really
              (setq split (mm-delete-duplicates split))
              ;; The article may be "cross-posted" to `junk'.  What
              ;; to do?  Just remove the `junk' spec.  Don't really
@@ -1201,7 +1219,8 @@ FUNC will be called with the group name to determine the article number."
              ;; This is the final group, which is used as a
              ;; catch-all.
              (when (and (not group-art)
              ;; This is the final group, which is used as a
              ;; catch-all.
              (when (and (not group-art)
-                        (not nnmail-inhibit-default-split-group))
+                        (or (equal "" (nth 1 method))
+                            (not nnmail-inhibit-default-split-group)))
                (setq group-art
                      (list (cons (car method)
                                  (funcall func (car method))))))))
                (setq group-art
                      (list (cons (car method)
                                  (funcall func (car method))))))))
@@ -1333,7 +1352,7 @@ Eudora has a broken References line, but an OK In-Reply-To."
 ;;; Utility functions
 
 (declare-function gnus-activate-group "gnus-start"
 ;;; Utility functions
 
 (declare-function gnus-activate-group "gnus-start"
-                  (group &optional scan dont-check method))
+                  (group &optional scan dont-check method dont-sub-check))
 
 (defun nnmail-do-request-post (accept-func &optional server)
   "Utility function to directly post a message to an nnmail-derived group.
 
 (defun nnmail-do-request-post (accept-func &optional server)
   "Utility function to directly post a message to an nnmail-derived group.
@@ -1782,7 +1801,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
         (i 0)
         (new 0)
         (total 0)
         (i 0)
         (new 0)
         (total 0)
-        incoming incomings source)
+        source)
     (when (and (nnmail-get-value "%s-get-new-mail" method)
               sources)
       (while (setq source (pop sources))
     (when (and (nnmail-get-value "%s-get-new-mail" method)
               sources)
       (while (setq source (pop sources))
@@ -1825,18 +1844,23 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
       ;; and fetch the mail from each.
       (while (setq source (pop fetching-sources))
        (when (setq new
       ;; and fetch the mail from each.
       (while (setq source (pop fetching-sources))
        (when (setq new
-                   (mail-source-fetch
-                    source
-                    (gnus-byte-compile
-                     `(lambda (file orig-file)
-                        (nnmail-split-incoming
-                         file ',(intern (format "%s-save-mail" method))
-                         ',spool-func
-                         (or in-group
-                             (if (equal file orig-file)
-                                 nil
-                               (nnmail-get-split-group orig-file ',source)))
-                         ',(intern (format "%s-active-number" method)))))))
+                   (condition-case cond
+                       (mail-source-fetch
+                        source
+                        (gnus-byte-compile
+                         `(lambda (file orig-file)
+                            (nnmail-split-incoming
+                             file ',(intern (format "%s-save-mail" method))
+                             ',spool-func
+                             (or in-group
+                                 (if (equal file orig-file)
+                                     nil
+                                   (nnmail-get-split-group orig-file
+                                                           ',source)))
+                             ',(intern (format "%s-active-number" method))))))
+                     ((error quit)
+                      (message "Mail source %s failed: %s" source cond)
+                      0)))
          (incf total new)
          (incf i)))
       ;; If we did indeed read any incoming spools, we save all info.
          (incf total new)
          (incf i)))
       ;; If we did indeed read any incoming spools, we save all info.
@@ -1901,7 +1925,8 @@ If TIME is nil, then return the cutoff time for oldness instead."
       (when (or (gnus-request-group target)
                (gnus-request-create-group target))
        (let ((group-art (gnus-request-accept-article target nil nil t)))
       (when (or (gnus-request-group target)
                (gnus-request-create-group target))
        (let ((group-art (gnus-request-accept-article target nil nil t)))
-         (when (consp group-art)
+         (when (and (consp group-art)
+                    (cdr group-art))
            (gnus-group-mark-article-read target (cdr group-art))))))))
 
 (defun nnmail-fancy-expiry-target (group)
            (gnus-group-mark-article-read target (cdr group-art))))))))
 
 (defun nnmail-fancy-expiry-target (group)
@@ -1927,9 +1952,13 @@ If TIME is nil, then return the cutoff time for oldness instead."
        ((and (equal header 'to-from)
             (or (string-match (cadr regexp-target-pair) from)
                 (and (string-match (cadr regexp-target-pair) to)
        ((and (equal header 'to-from)
             (or (string-match (cadr regexp-target-pair) from)
                 (and (string-match (cadr regexp-target-pair) to)
-                     (let ((rmail-dont-reply-to-names
-                            (message-dont-reply-to-names)))
-                       (equal (rmail-dont-reply-to from) "")))))
+                     (let* ((mail-dont-reply-to-names
+                             (message-dont-reply-to-names))
+                            (rmail-dont-reply-to-names ; obsolete since 24.1
+                             mail-dont-reply-to-names))
+                       (equal (if (fboundp 'rmail-dont-reply-to)
+                                  (rmail-dont-reply-to from)
+                                (mail-dont-reply-to from)) "")))))
        (setq target (format-time-string (caddr regexp-target-pair) date)))
        ((and (not (equal header 'to-from))
             (string-match (cadr regexp-target-pair)
        (setq target (format-time-string (caddr regexp-target-pair) date)))
        ((and (not (equal header 'to-from))
             (string-match (cadr regexp-target-pair)