X-Git-Url: http://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Fnnmail.el;h=8bf0cbf5de10fc0aebd2dca0d9efb593d6671215;hb=2ba7cc1331afa29de3a313db91033903dbebfda6;hp=1d94460ed37d07ec3fea032c2cf47b8d1a2f6a1b;hpb=b09a5bb4fbe14ae9769670d1131ab3b204dda4c9;p=gnus diff --git a/lisp/nnmail.el b/lisp/nnmail.el index 1d94460ed..8bf0cbf5d 100644 --- a/lisp/nnmail.el +++ b/lisp/nnmail.el @@ -1,16 +1,17 @@ ;;; nnmail.el --- mail support functions for the Gnus mail backends -;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 -;; Free Software Foundation, Inc. + +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, +;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news, mail ;; 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 @@ -18,14 +19,16 @@ ;; 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. +;; along with GNU Emacs. If not, see . ;;; Commentary: ;;; Code: +;; For Emacs < 22.2. +(eval-and-compile + (unless (fboundp 'declare-function) (defmacro declare-function (&rest r)))) + (eval-when-compile (require 'cl)) (require 'gnus) ; for macro gnus-kill-buffer, at least @@ -34,10 +37,10 @@ (require 'gnus-util) (require 'mail-source) (require 'mm-util) +(require 'gnus-int) -(eval-and-compile - (autoload 'gnus-add-buffer "gnus") - (autoload 'gnus-kill-buffer "gnus")) +(autoload 'gnus-add-buffer "gnus") +(autoload 'gnus-kill-buffer "gnus") (defgroup nnmail nil "Reading mail with Gnus." @@ -48,7 +51,7 @@ :group 'nnmail) (defgroup nnmail-prepare nil - "Preparing (or mangling) new mail after retrival." + "Preparing (or mangling) new mail after retrieval." :group 'nnmail) (defgroup nnmail-duplicate nil @@ -196,7 +199,7 @@ The return value should be `delete' or a group name (a string)." :version "21.1" :group 'nnmail-expire :type '(choice (const delete) - (function :format "%v" nnmail-) + function string)) (defcustom nnmail-fancy-expiry-targets nil @@ -239,12 +242,10 @@ If non-nil, also update the cache when copy or move articles." :group 'nnmail :type 'boolean) -(defcustom nnmail-spool-file '((file)) - "*Where the mail backends will look for incoming mail. -This variable is a list of mail source specifiers. -This variable is obsolete; `mail-sources' should be used instead." - :group 'nnmail-files - :type 'sexp) +(make-obsolete-variable 'nnmail-spool-file 'mail-sources + "Gnus 5.9 (Emacs 22.1)") +;; revision 5.29 / p0-85 / Gnus 5.9 +;; Variable removed in No Gnus v0.7 (defcustom nnmail-resplit-incoming nil "*If non-nil, re-split incoming procmail sorted mail." @@ -292,7 +293,10 @@ Eg. \(add-hook 'nnmail-read-incoming-hook (lambda () (call-process \"/local/bin/mailsend\" nil nil nil - \"read\" nnmail-spool-file))) + \"read\" + ;; The incoming mail box file. + (expand-file-name (user-login-name) + rmail-spool-directory)))) If you have xwatch running, this will alert it that mail has been read. @@ -526,8 +530,9 @@ performed." :type '(choice (const :tag "disable" nil) (integer :format "%v"))) -(defcustom nnmail-message-id-cache-file "~/.nnmail-cache" - "*The file name of the nnmail Message-ID cache." +(defcustom nnmail-message-id-cache-file + (nnheader-concat gnus-home-directory ".nnmail-cache") + "The file name of the nnmail Message-ID cache." :group 'nnmail-duplicate :group 'nnmail-files :type 'file) @@ -622,7 +627,14 @@ using different case (i.e. mailing-list@domain vs Mailing-List@Domain)." mm-text-coding-system "Coding system used in reading inbox") -(defvar nnmail-pathname-coding-system nil +(defvar nnmail-pathname-coding-system + ;; This causes Emacs 22.2 and 22.3 to issue a useless warning. + ;;(if (and (featurep 'xemacs) (featurep 'file-coding)) + (if (featurep 'xemacs) + (if (featurep 'file-coding) + ;; Work around a bug in many XEmacs 21.5 betas. + ;; Cf. http://thread.gmane.org/gmane.emacs.gnus.general/68134 + (setq file-name-coding-system (coding-system-aliasee 'file-name)))) "*Coding system for file name.") (defun nnmail-find-file (file) @@ -654,9 +666,7 @@ using different case (i.e. mailing-list@domain vs Mailing-List@Domain)." (expand-file-name group dir) ;; If not, we translate dots into slashes. (expand-file-name - (mm-encode-coding-string - (nnheader-replace-chars-in-string group ?. ?/) - nnmail-pathname-coding-system) + (nnheader-replace-chars-in-string group ?. ?/) dir)))) (or file ""))) @@ -687,7 +697,7 @@ nn*-request-list should have been called before calling this function." (setq group (symbol-name group))) (if (and (numberp (setq max (read buffer))) (numberp (setq min (read buffer)))) - (push (list group (cons min max)) + (push (list (mm-string-as-unibyte group) (cons min max)) group-assoc))) (error nil)) (widen) @@ -702,6 +712,7 @@ nn*-request-list should have been called before calling this function." (let ((coding-system-for-write nnmail-active-file-coding-system)) (when file-name (with-temp-file file-name + (mm-disable-multibyte) (nnmail-generate-active group-assoc))))) (defun nnmail-generate-active (alist) @@ -1041,6 +1052,9 @@ If SOURCE is a directory spec, try to return the group name component." (nnmail-check-duplication message-id func artnum-func)) 1)) +(defvar nnmail-group-names-not-encoded-p nil + "Non-nil means group names are not encoded.") + (defun nnmail-split-incoming (incoming func &optional exit-func group artnum-func) "Go through the entire INCOMING file and pick out each individual mail. @@ -1050,7 +1064,8 @@ FUNC will be called with the buffer narrowed to each mail." (nnmail-split-methods (if (and group (not nnmail-resplit-incoming)) (list (list group "")) - nnmail-split-methods))) + nnmail-split-methods)) + (nnmail-group-names-not-encoded-p t)) (save-excursion ;; Insert the incoming file. (set-buffer (get-buffer-create nnmail-article-buffer)) @@ -1129,7 +1144,7 @@ FUNC will be called with the group name to determine the article number." (if (and (symbolp nnmail-split-methods) (fboundp nnmail-split-methods)) (let ((split - (condition-case nil + (condition-case error-info ;; `nnmail-split-methods' is a function, so we ;; just call this function here and use the ;; result. @@ -1137,10 +1152,10 @@ FUNC will be called with the group name to determine the article number." '("bogus")) (error (nnheader-message - 5 "Error in `nnmail-split-methods'; using `bogus' mail group") + 5 "Error in `nnmail-split-methods'; using `bogus' mail group: %S" error-info) (sit-for 1) '("bogus"))))) - (setq split (gnus-remove-duplicates split)) + (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 ;; see anything else to do... @@ -1241,11 +1256,11 @@ Return the number of characters in the body." (progn (forward-line 1) (point)))) (insert (format "Xref: %s" (system-name))) (while group-alist - (insert (format " %s:%d" - (mm-encode-coding-string - (caar group-alist) - nnmail-pathname-coding-system) - (cdar group-alist))) + (insert (if (mm-multibyte-p) + (mm-string-as-multibyte + (format " %s:%d" (caar group-alist) (cdar group-alist))) + (mm-string-as-unibyte + (format " %s:%d" (caar group-alist) (cdar group-alist))))) (setq group-alist (cdr group-alist))) (insert "\n"))) @@ -1279,10 +1294,20 @@ Return the number of characters in the body." "Translate TAB characters into SPACE characters." (subst-char-in-region (point-min) (point-max) ?\t ? t)) -(defun nnmail-fix-eudora-headers () - "Eudora has a broken References line, but an OK In-Reply-To." +(defcustom nnmail-broken-references-mailers + "^X-Mailer:.*\\(Eudora\\|Pegasus\\)" + "Header line matching mailer producing bogus References lines. +See `nnmail-ignore-broken-references'." + :group 'nnmail-prepare + :version "23.1" ;; No Gnus + :type 'regexp) + +(defun nnmail-ignore-broken-references () + "Ignore the References line and use In-Reply-To + +Eudora has a broken References line, but an OK In-Reply-To." (goto-char (point-min)) - (when (re-search-forward "^X-Mailer:.*Eudora" nil t) + (when (re-search-forward nnmail-broken-references-mailers nil t) (goto-char (point-min)) (when (re-search-forward "^References:" nil t) (beginning-of-line) @@ -1291,11 +1316,17 @@ Return the number of characters in the body." (when (re-search-forward "^\\(In-Reply-To:[^\n]+\\)\n[ \t]+" nil t) (replace-match "\\1" t)))) +(defalias 'nnmail-fix-eudora-headers 'nnmail-ignore-broken-references) +(make-obsolete 'nnmail-fix-eudora-headers 'nnmail-ignore-broken-references "Emacs 23.1") + (custom-add-option 'nnmail-prepare-incoming-header-hook - 'nnmail-fix-eudora-headers) + 'nnmail-ignore-broken-references) ;;; Utility functions +(declare-function gnus-activate-group "gnus-start" + (group &optional scan dont-check method)) + (defun nnmail-do-request-post (accept-func &optional server) "Utility function to directly post a message to an nnmail-derived group. Calls ACCEPT-FUNC (which should be `nnchoke-request-accept-article') @@ -1419,11 +1450,12 @@ See the documentation for the variable `nnmail-split-fancy' for details." ;; Not in cache, compute a regexp for the field/value pair. (t - (let* ((field (nth 0 split)) - (value (nth 1 split)) - partial-front - partial-rear - regexp) + (let ((field (nth 0 split)) + (value (nth 1 split)) + (split-rest (cddr split)) + partial-front + partial-rear + regexp) (if (symbolp value) (setq value (cdr (assq value nnmail-split-abbrev-alist)))) (if (and (>= (length value) 2) @@ -1435,7 +1467,13 @@ See the documentation for the variable `nnmail-split-fancy' for details." (string= ".*" (substring value -2))) (setq value (substring value 0 -2) partial-rear "")) - (when nnmail-split-fancy-match-partial-words + ;; Invert the match-partial-words behavior if the optional + ;; last element is specified. + (while (eq (car split-rest) '-) + (setq split-rest (cddr split-rest))) + (when (if (cadr split-rest) + (not nnmail-split-fancy-match-partial-words) + nnmail-split-fancy-match-partial-words) (setq partial-front "" partial-rear "")) (setq regexp (concat "^\\(\\(" @@ -1450,7 +1488,7 @@ See the documentation for the variable `nnmail-split-fancy' for details." (or partial-rear "\\>"))) (push (cons split regexp) nnmail-split-cache) ;; Now that it's in the cache, just call nnmail-split-it again - ;; on the same split, which will find it immediately in the cache. + ;; on the same split, which will find it immediately in the cache. (nnmail-split-it split)))))) (defun nnmail-expand-newtext (newtext) @@ -1655,12 +1693,11 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (setq references (nreverse (gnus-split-references refstr))) (unless (gnus-buffer-live-p nnmail-cache-buffer) (nnmail-cache-open)) - (mapcar (lambda (x) - (setq res (or (nnmail-cache-fetch-group x) res)) - (when (or (member res '("delayed" "drafts" "queue")) - (and regexp res (string-match regexp res))) - (setq res nil))) - references) + (dolist (x references) + (setq res (or (nnmail-cache-fetch-group x) res)) + (when (or (member res '("delayed" "drafts" "queue")) + (and regexp res (string-match regexp res))) + (setq res nil))) res))) (defun nnmail-cache-id-exists-p (id) @@ -1733,13 +1770,14 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (symbol-value sym)))) (defun nnmail-get-new-mail (method exit-func temp - &optional group spool-func) + &optional group spool-func) "Read new incoming mail." - (let* ((sources (or mail-sources - (if (listp nnmail-spool-file) nnmail-spool-file - (list nnmail-spool-file)))) + (nnmail-get-new-mail-1 method exit-func temp group nil spool-func)) + +(defun nnmail-get-new-mail-1 (method exit-func temp + group in-group spool-func) + (let* ((sources mail-sources) fetching-sources - (group-in group) (i 0) (new 0) (total 0) @@ -1747,20 +1785,16 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (when (and (nnmail-get-value "%s-get-new-mail" method) sources) (while (setq source (pop sources)) - ;; Be compatible with old values. - (cond - ((stringp source) - (setq source - (cond - ((string-match "^po:" source) - (list 'pop :user (substring source (match-end 0)))) - ((file-directory-p source) - (list 'directory :path source)) - (t - (list 'file :path source))))) - ((eq source 'procmail) - (message "Invalid value for nnmail-spool-file: `procmail'") - nil)) + ;; Use group's parameter + (when (eq (car source) 'group) + (let ((mail-sources + (list + (gnus-group-find-parameter + (concat (symbol-name method) ":" group) + 'mail-source t)))) + (nnmail-get-new-mail-1 method exit-func temp + group group spool-func)) + (setq source nil)) ;; Hack to only fetch the contents of a single group's spool file. (when (and (eq (car source) 'directory) (null nnmail-scan-directory-mail-source-once) @@ -1799,9 +1833,10 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (nnmail-split-incoming file ',(intern (format "%s-save-mail" method)) ',spool-func - (if (equal file orig-file) - nil - (nnmail-get-split-group orig-file ',source)) + (or in-group + (if (equal file orig-file) + nil + (nnmail-get-split-group orig-file ',source))) ',(intern (format "%s-active-number" method))))))) (incf total new) (incf i))) @@ -1845,6 +1880,8 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." ;; Compare the time with the current time. (ignore-errors (time-less-p days (time-since time)))))))) +(declare-function gnus-group-mark-article-read "gnus-group" (group article)) + (defun nnmail-expiry-target-group (target group) ;; Do not invoke this from nntp-server-buffer! At least nnfolder clears ;; that buffer if the nnfolder group isn't selected. @@ -1866,9 +1903,15 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (case-fold-search nil) (from (or (message-fetch-field "from") "")) (to (or (message-fetch-field "to") "")) - (date (date-to-time - (or (message-fetch-field "date") (current-time-string)))) + (date (message-fetch-field "date")) (target 'delete)) + (setq date (if date + (condition-case err + (date-to-time date) + (error + (message "%s" (error-message-string err)) + (current-time))) + (current-time))) (dolist (regexp-target-pair (reverse nnmail-fancy-expiry-targets) target) (setq header (car regexp-target-pair)) (cond @@ -1876,8 +1919,10 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." ;; To or From header ((and (equal header 'to-from) (or (string-match (cadr regexp-target-pair) from) - (and (string-match message-dont-reply-to-names from) - (string-match (cadr regexp-target-pair) to)))) + (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) ""))))) (setq target (format-time-string (caddr regexp-target-pair) date))) ((and (not (equal header 'to-from)) (string-match (cadr regexp-target-pair) @@ -2007,5 +2052,5 @@ Doesn't change point." (provide 'nnmail) -;;; arch-tag: fe8f671a-50db-428a-bb5d-f00462f72ed7 +;; arch-tag: fe8f671a-50db-428a-bb5d-f00462f72ed7 ;;; nnmail.el ends here