;;; nnmail.el --- mail support functions for the Gnus mail backends
-;; Copyright (C) 1995,96,97 Free Software Foundation, Inc.
+;; Copyright (C) 1995,96,97,98,99 Free Software Foundation, Inc.
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Keywords: news, mail
;; This file is part of GNU Emacs.
;;; Code:
+(eval-when-compile (require 'cl))
+
(require 'nnheader)
-(require 'timezone)
(require 'message)
-(eval-when-compile (require 'cl))
(require 'custom)
+(require 'gnus-util)
+(require 'mail-source)
+(require 'mm-util)
+
+(eval-and-compile
+ (autoload 'gnus-error "gnus-util")
+ (autoload 'gnus-buffer-live-p "gnus-util"))
(defgroup nnmail nil
"Reading mail with Gnus."
(defcustom nnmail-split-methods
'(("mail.misc" ""))
- "Incoming mail will be split according to this variable.
+ "*Incoming mail will be split according to this variable.
If you'd like, for instance, one mail group for mail from the
\"4ad-l\" mailing list, one group for junk mail and one for everything
;; Added by gord@enci.ucalgary.ca (Gordon Matzigkeit).
(defcustom nnmail-keep-last-article nil
- "If non-nil, nnmail will never delete the last expired article in a directory.
+ "If non-nil, nnmail will never delete/move a group's last article.
+It can be marked expirable, so it will be deleted when it is no longer last.
+
You may need to set this variable if other programs are putting
new mail into folder numbers that Gnus has marked as expired."
:group 'nnmail-procmail
:type '(choice (const :tag "nnmail-expiry-wait" nil)
(function :format "%v" nnmail-)))
-(defcustom nnmail-spool-file
- (or (getenv "MAIL")
- (concat "/usr/spool/mail/" (user-login-name)))
- "Where the mail backends will look for incoming mail.
-This variable is \"/usr/spool/mail/$user\" by default.
-If this variable is nil, no mail backends will read incoming mail.
-If this variable is a list, all files mentioned in this list will be
-used as incoming mailboxes.
-If this variable is a directory (i. e., it's name ends with a \"/\"),
-treat all files in that directory as incoming spool files."
- :group 'nnmail-files
- :type 'file)
-
-(defcustom nnmail-crash-box "~/.gnus-crash-box"
- "File where Gnus will store mail while processing it."
- :group 'nnmail-files
- :type 'file)
-
-(defcustom nnmail-use-procmail nil
- "*If non-nil, the mail backends will look in `nnmail-procmail-directory' for spool files.
-The file(s) in `nnmail-spool-file' will also be read."
- :group 'nnmail-procmail
+(defcustom nnmail-cache-accepted-message-ids nil
+ "If non-nil, put Message-IDs of Gcc'd articles into the duplicate cache."
+ :group 'nnmail
:type 'boolean)
-(defcustom nnmail-procmail-directory "~/incoming/"
- "*When using procmail (and the like), incoming mail is put in this directory.
-The Gnus mail backends will read the mail from this directory."
- :group 'nnmail-procmail
- :type 'directory)
-
-(defcustom nnmail-procmail-suffix "\\.spool"
- "*Suffix of files created by procmail (and the like).
-This variable might be a suffix-regexp to match the suffixes of
-several files - eg. \".spool[0-9]*\"."
- :group 'nnmail-procmail
- :type 'regexp)
+(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)
(defcustom nnmail-resplit-incoming nil
"*If non-nil, re-split incoming procmail sorted mail."
:group 'nnmail-files
:type 'function)
-(defcustom nnmail-crosspost-link-function 'add-name-to-file
- "Function called to create a copy of a file.
+(defcustom nnmail-crosspost-link-function
+ (if (string-match "windows-nt\\|emx" (symbol-name system-type))
+ 'copy-file
+ 'add-name-to-file)
+ "*Function called to create a copy of a file.
This is `add-name-to-file' by default, which means that crossposts
will use hard links. If your file system doesn't allow hard
links, you could set this variable to `copy-file' instead."
(function-item copy-file)
(function :tag "Other")))
-(defcustom nnmail-movemail-program "movemail"
- "*A command to be executed to move mail from the inbox.
-The default is \"movemail\".
-
-This can also be a function. In that case, the function will be
-called with two parameters -- the name of the INBOX file, and the file
-to be moved to."
- :group 'nnmail-files
- :group 'nnmail-retrieve
- :type 'string)
-
-(defcustom nnmail-pop-password-required nil
- "*Non-nil if a password is required when reading mail using POP."
- :group 'nnmail-retrieve
- :type 'boolean)
-
-(defcustom nnmail-read-incoming-hook
+(defcustom nnmail-read-incoming-hook
(if (eq system-type 'windows-nt)
'(nnheader-ms-strip-cr)
nil)
- "Hook that will be run after the incoming mail has been transferred.
+ "*Hook that will be run after the incoming mail has been transferred.
The incoming mail is moved from `nnmail-spool-file' (which normally is
something like \"/usr/spool/mail/$user\") to the user's home
directory. This hook is called after the incoming mail box has been
Eg.
-\(add-hook 'nnmail-read-incoming-hook
+\(add-hook 'nnmail-read-incoming-hook
(lambda ()
- (start-process \"mailsend\" nil
+ (start-process \"mailsend\" nil
\"/local/bin/mailsend\" \"read\" \"mbox\")))
If you have xwatch running, this will alert it that mail has been
-read.
+read.
If you use `display-time', you could use something like this:
:group 'nnmail-prepare
:type 'hook)
-;; Suggested by Erik Selberg <speed@cs.washington.edu>.
(defcustom nnmail-prepare-incoming-hook nil
"Hook called before treating incoming mail.
The hook is run in a buffer with all the new, incoming mail."
This can also be a list of regexps."
:group 'nnmail-prepare
:type '(choice (const :tag "none" nil)
- regexp
- (repeat regexp)))
+ (regexp :value ".*")
+ (repeat :value (".*") regexp)))
(defcustom nnmail-pre-get-new-mail-hook nil
"Hook called just before starting to handle new incoming mail."
:group 'nnmail-split
:type 'hook)
-;; Suggested by Mejia Pablo J <pjm9806@usl.edu>.
-(defcustom nnmail-tmp-directory nil
- "*If non-nil, use this directory for temporary storage.
-Used when reading incoming mail."
- :group 'nnmail-files
- :group 'nnmail-retrieve
- :type '(choice (const :tag "default" nil)
- (directory :format "%v")))
-
(defcustom nnmail-large-newsgroup 50
"*The number of the articles which indicates a large newsgroup.
If the number of the articles is greater than the value, verbose
"Incoming mail can be split according to this fancy variable.
To enable this, set `nnmail-split-methods' to `nnmail-split-fancy'.
-The format is this variable is SPLIT, where SPLIT can be one of
+The format of this variable is SPLIT, where SPLIT can be one of
the following:
-GROUP: Mail will be stored in GROUP (a string).
+GROUP: Mail will be stored in GROUP (a string).
-\(FIELD VALUE SPLIT): If the message field FIELD (a regexp) contains
- VALUE (a regexp), store the messages as specified by SPLIT.
+\(FIELD VALUE [- RESTRICT [- RESTRICT [...]]] SPLIT): If the message
+ field FIELD (a regexp) contains VALUE (a regexp), store the messages
+ as specified by SPLIT. If RESTRICT (a regexp) matches some string
+ after FIELD and before the end of the matched VALUE, return NIL,
+ otherwise process SPLIT. Multiple RESTRICTs add up, further
+ restricting the possibility of processing SPLIT.
\(| SPLIT...): Process each SPLIT expression until one of them matches.
A SPLIT expression is said to match if it will cause the mail
- message to be stored in one or more groups.
+ message to be stored in one or more groups.
\(& SPLIT...): Process each SPLIT expression.
the buffer containing the message headers. The return value FUNCTION
should be a split, which is then recursively processed.
+\(! FUNCTION SPLIT): Call FUNCTION with the result of SPLIT. The
+ return value FUNCTION should be a split, which is then recursively
+ processed.
+
FIELD must match a complete field name. VALUE must match a complete
word according to the `nnmail-split-fancy-syntax-table' syntax table.
-You can use .* in the regexps to match partial field names or words.
+You can use \".*\" in the regexps to match partial field names or words.
FIELD and VALUE can also be lisp symbols, in that case they are expanded
as specified in `nnmail-split-abbrev-alist'.
;; Other mailing lists...
(any \"procmail@informatik\\\\.rwth-aachen\\\\.de\" \"procmail.list\")
(any \"SmartList@informatik\\\\.rwth-aachen\\\\.de\" \"SmartList.list\")
+ ;; Both lists below have the same suffix, so prevent
+ ;; cross-posting to mkpkg.list of messages posted only to
+ ;; the bugs- list, but allow cross-posting when the
+ ;; message was really cross-posted.
+ (any \"bugs-mypackage@somewhere\" \"mypkg.bugs\")
+ (any \"mypackage@somewhere\" - \"bugs-mypackage\" \"mypkg.list\")
+ ;;
;; People...
(any \"larsi@ifi\\\\.uio\\\\.no\" \"people.Lars Magne Ingebrigtsen\"))
;; Unmatched mail goes to the catch all group.
(defcustom nnmail-split-abbrev-alist
'((any . "from\\|to\\|cc\\|sender\\|apparently-to\\|resent-from\\|resent-to\\|resent-cc")
- (mail . "mailer-daemon\\|postmaster\\|uucp"))
- "Alist of abbreviations allowed in `nnmail-split-fancy'."
+ (mail . "mailer-daemon\\|postmaster\\|uucp")
+ (to . "to\\|cc\\|apparently-to\\|resent-to\\|resent-cc")
+ (from . "from\\|sender\\|resent-from")
+ (nato . "to\\|cc\\|resent-to\\|resent-cc")
+ (naany . "from\\|to\\|cc\\|sender\\|resent-from\\|resent-to\\|resent-cc"))
+ "*Alist of abbreviations allowed in `nnmail-split-fancy'."
:group 'nnmail-split
:type '(repeat (cons :format "%v" symbol regexp)))
-(defcustom nnmail-delete-incoming t
- "*If non-nil, the mail backends will delete incoming files after
-splitting."
- :group 'nnmail-retrieve
- :type 'boolean)
-
(defcustom nnmail-message-id-cache-length 1000
"*The approximate number of Message-IDs nnmail will keep in its cache.
If this variable is nil, no checking on duplicate messages will be
(defcustom nnmail-treat-duplicates 'warn
"*If non-nil, nnmail keep a cache of Message-IDs to discover mail duplicates.
-Three values are legal: nil, which means that nnmail is not to keep a
+Three values are valid: nil, which means that nnmail is not to keep a
Message-ID cache; `warn', which means that nnmail should insert extra
headers to warn the user about the duplication (this is the default);
and `delete', which means that nnmail will delete duplicated mails.
(const warn)
(const delete)))
+(defcustom nnmail-extra-headers nil
+ "*Extra headers to parse."