6f417690a738f19187eded1de3aab333d64dad6f
[gnus] / lisp / nnmail.el
1 ;;; nnmail.el --- mail support functions for the Gnus mail backends
2 ;; Copyright (C) 1995,96 Free Software Foundation, Inc.
3
4 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
5 ;; Keywords: news, mail
6
7 ;; This file is part of GNU Emacs.
8
9 ;; GNU Emacs is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24 ;;; Commentary:
25
26 ;;; Code:
27
28 (require 'nnheader)
29 (require 'rmail)
30 (require 'timezone)
31 (require 'sendmail)
32 (eval-when-compile (require 'cl))
33
34 (defvar nnmail-split-methods
35   '(("mail.misc" ""))
36   "*Incoming mail will be split according to this variable.
37
38 If you'd like, for instance, one mail group for mail from the
39 \"4ad-l\" mailing list, one group for junk mail and one for everything
40 else, you could do something like this:
41
42  (setq nnmail-split-methods
43        '((\"mail.4ad\" \"From:.*4ad\")
44          (\"mail.junk\" \"From:.*Lars\\\\|Subject:.*buy\")
45          (\"mail.misc\" \"\")))
46
47 As you can see, this variable is a list of lists, where the first
48 element in each \"rule\" is the name of the group (which, by the way,
49 does not have to be called anything beginning with \"mail\",
50 \"yonka.zow\" is a fine, fine name), and the second is a regexp that
51 nnmail will try to match on the header to find a fit.
52
53 The second element can also be a function.  In that case, it will be
54 called narrowed to the headers with the first element of the rule as
55 the argument.  It should return a non-nil value if it thinks that the
56 mail belongs in that group.
57
58 The last element should always have \"\" as the regexp.
59
60 This variable can also have a function as its value.")
61
62 ;; Suggested by Erik Selberg <speed@cs.washington.edu>.
63 (defvar nnmail-crosspost t
64   "*If non-nil, do crossposting if several split methods match the mail.
65 If nil, the first match found will be used.")
66
67 ;; Added by gord@enci.ucalgary.ca (Gordon Matzigkeit).
68 (defvar nnmail-keep-last-article nil
69   "*If non-nil, nnmail will never delete the last expired article in a directory.  
70 You may need to set this variable if other programs are putting
71 new mail into folder numbers that Gnus has marked as expired.")
72
73 (defvar nnmail-use-long-file-names nil
74   "*If non-nil the mail backends will use long file and directory names.
75 If nil, groups like \"mail.misc\" will end up in directories like
76 \"mail/misc/\".")
77
78 (defvar nnmail-expiry-wait 7
79   "*Expirable articles that are older than this will be expired.
80 This variable can either be a number (which will be interpreted as a
81 number of days) -- this doesn't have to be an integer.  This variable
82 can also be `immediate' and `never'.")
83
84 (defvar nnmail-expiry-wait-function nil
85   "*Variable that holds function to specify how old articles should be before they are expired.
86   The function will be called with the name of the group that the
87 expiry is to be performed in, and it should return an integer that
88 says how many days an article can be stored before it is considered
89 \"old\".  It can also return the values `never' and `immediate'.
90
91 Eg.:
92
93 (setq nnmail-expiry-wait-function
94       (lambda (newsgroup)
95         (cond ((string-match \"private\" newsgroup) 31)
96               ((string-match \"junk\" newsgroup) 1)
97               ((string-match \"important\" 'never))
98               (t 7))))")
99
100 (defvar nnmail-spool-file 
101   (or (getenv "MAIL")
102       (concat "/usr/spool/mail/" (user-login-name)))
103   "Where the mail backends will look for incoming mail.
104 This variable is \"/usr/spool/mail/$user\" by default.
105 If this variable is nil, no mail backends will read incoming mail.
106 If this variable is a list, all files mentioned in this list will be
107 used as incoming mailboxes.")
108
109 (defvar nnmail-crash-box "~/.gnus-crash-box"
110   "*File where Gnus will store mail while processing it.")
111
112 (defvar nnmail-use-procmail nil
113   "*If non-nil, the mail backends will look in `nnmail-procmail-directory' for spool files.
114 The file(s) in `nnmail-spool-file' will also be read.")
115
116 (defvar nnmail-procmail-directory "~/incoming/"
117   "*When using procmail (and the like), incoming mail is put in this directory.
118 The Gnus mail backends will read the mail from this directory.")
119
120 (defvar nnmail-procmail-suffix "\\.spool"
121   "*Suffix of files created by procmail (and the like).
122 This variable might be a suffix-regexp to match the suffixes of
123 several files - eg. \".spool[0-9]*\".")
124
125 (defvar nnmail-resplit-incoming nil
126   "*If non-nil, re-split incoming procmail sorted mail.")
127
128 (defvar nnmail-delete-file-function 'delete-file
129   "Function called to delete files in some mail backends.")
130
131 (defvar nnmail-crosspost-link-function 'add-name-to-file
132   "Function called to create a copy of a file.
133 This is `add-name-to-file' by default, which means that crossposts
134 will use hard links.  If your file system doesn't allow hard
135 links, you could set this variable to `copy-file' instead.")
136
137 (defvar nnmail-movemail-program "movemail"
138   "*A command to be executed to move mail from the inbox.
139 The default is \"movemail\".")
140
141 (defvar nnmail-read-incoming-hook nil
142   "*Hook that will be run after the incoming mail has been transferred.
143 The incoming mail is moved from `nnmail-spool-file' (which normally is
144 something like \"/usr/spool/mail/$user\") to the user's home
145 directory. This hook is called after the incoming mail box has been
146 emptied, and can be used to call any mail box programs you have
147 running (\"xwatch\", etc.)
148
149 Eg.
150
151 \(add-hook 'nnmail-read-incoming-hook 
152            (lambda () 
153              (start-process \"mailsend\" nil 
154                             \"/local/bin/mailsend\" \"read\" \"mbox\")))
155
156 If you have xwatch running, this will alert it that mail has been
157 read.  
158
159 If you use `display-time', you could use something like this:
160
161 \(add-hook 'nnmail-read-incoming-hook
162           (lambda ()
163             ;; Update the displayed time, since that will clear out
164             ;; the flag that says you have mail.
165             (if (eq (process-status \"display-time\") 'run)
166                 (display-time-filter display-time-process \"\"))))") 
167
168 ;; Suggested by Erik Selberg <speed@cs.washington.edu>.
169 (defvar nnmail-prepare-incoming-hook nil
170   "*Hook called before treating incoming mail.
171 The hook is run in a buffer with all the new, incoming mail.")
172
173 (defvar nnmail-pre-get-new-mail-hook nil
174   "Hook called just before starting to handle new incoming mail.")
175
176 (defvar nnmail-post-get-new-mail-hook nil
177   "Hook called just after finishing handling new incoming mail.")
178
179 ;; Suggested by Mejia Pablo J <pjm9806@usl.edu>.
180 (defvar nnmail-tmp-directory nil
181   "*If non-nil, use this directory for temporary storage when reading incoming mail.")
182
183 (defvar nnmail-large-newsgroup 50
184   "*The number of the articles which indicates a large newsgroup.
185 If the number of the articles is greater than the value, verbose
186 messages will be shown to indicate the current status.")
187
188 (defvar nnmail-split-fancy "mail.misc"
189   "*Incoming mail can be split according to this fancy variable.
190 To enable this, set `nnmail-split-methods' to `nnmail-split-fancy'.
191
192 The format is this variable is SPLIT, where SPLIT can be one of
193 the following:
194
195 GROUP: Mail will be stored in GROUP (a string).
196
197 \(FIELD VALUE SPLIT): If the message field FIELD (a regexp) contains
198   VALUE (a regexp), store the messages as specified by SPLIT.
199
200 \(| SPLIT...): Process each SPLIT expression until one of them matches.
201   A SPLIT expression is said to match if it will cause the mail
202   message to be stored in one or more groups.  
203
204 \(& SPLIT...): Process each SPLIT expression.
205
206 FIELD must match a complete field name.  VALUE must match a complete
207 word according to the `nnmail-split-fancy-syntax-table' syntax table.
208 You can use .* in the regexps to match partial field names or words.
209
210 FIELD and VALUE can also be lisp symbols, in that case they are expanded
211 as specified in `nnmail-split-abbrev-alist'.
212
213 Example:
214
215 \(setq nnmail-split-methods 'nnmail-split-fancy
216       nnmail-split-fancy
217       ;; Messages from the mailer deamon are not crossposted to any of
218       ;; the ordinary groups.  Warnings are put in a separate group
219       ;; from real errors.
220       '(| (\"from\" mail (| (\"subject\" \"warn.*\" \"mail.warning\")
221                           \"mail.misc\"))
222           ;; Non-error messages are crossposted to all relevant
223           ;; groups, but we don't crosspost between the group for the
224           ;; (ding) list and the group for other (ding) related mail.
225           (& (| (any \"ding@ifi\\\\.uio\\\\.no\" \"ding.list\")
226                 (\"subject\" \"ding\" \"ding.misc\"))
227              ;; Other mailing lists...
228              (any \"procmail@informatik\\\\.rwth-aachen\\\\.de\" \"procmail.list\")
229              (any \"SmartList@informatik\\\\.rwth-aachen\\\\.de\" \"SmartList.list\")
230              ;; People...
231              (any \"larsi@ifi\\\\.uio\\\\.no\" \"people.Lars Magne Ingebrigtsen\"))
232           ;; Unmatched mail goes to the catch all group.
233           \"misc.misc\"))")
234
235 (defvar nnmail-split-abbrev-alist
236   '((any . "from\\|to\\|cc\\|sender\\|apparently-to")
237     (mail . "mailer-daemon\\|postmaster"))
238   "*Alist of abbreviations allowed in `nnmail-split-fancy'.")
239
240 (defvar nnmail-delete-incoming nil
241   "*If non-nil, the mail backends will delete incoming files after splitting.")
242
243 (defvar nnmail-message-id-cache-length 1000
244   "*The approximate number of Message-IDs nnmail will keep in its cache.
245 If this variable is nil, no checking on duplicate messages will be
246 performed.")
247
248 (defvar nnmail-message-id-cache-file "~/.nnmail-cache"
249   "*The file name of the nnmail Message-ID cache.")
250
251 (defvar nnmail-treat-duplicates 'warn
252   "*If non-nil, nnmail keep a cache of Message-IDs to discover mail duplicates.
253 Three values are legal: nil, which means that nnmail is not to keep a
254 Message-ID cache; `warn', which means that nnmail should insert extra
255 headers to warn the user about the duplication (this is the default);
256 and `delete', which means that nnmail will delete duplicated mails.
257
258 This variable can also be a function.  It will be called from a buffer
259 narrowed to the article in question with the Message-ID as a
260 parameter.  It should return nil, `warn' or `delete'.")
261
262 ;;; Internal variables.
263
264 (defvar nnmail-split-fancy-syntax-table
265   (copy-syntax-table (standard-syntax-table))
266   "Syntax table used by `nnmail-split-fancy'.")
267
268 \f
269
270 (defconst nnmail-version "nnmail 1.0"
271   "nnmail version.")
272
273 \f