comparison lisp/gnus/nnmail.el @ 108:360340f9fd5f r20-1b6

Import from CVS: tag r20-1b6
author cvs
date Mon, 13 Aug 2007 09:18:39 +0200
parents cf808b4c4290
children fe104dbd9147
comparison
equal deleted inserted replaced
107:523141596bda 108:360340f9fd5f
26 ;;; Code: 26 ;;; Code:
27 27
28 (require 'nnheader) 28 (require 'nnheader)
29 (require 'timezone) 29 (require 'timezone)
30 (require 'message) 30 (require 'message)
31 (eval-when-compile (require 'cl)) 31 (require 'cl)
32 (require 'custom) 32 (require 'custom)
33
34 (eval-and-compile
35 (autoload 'gnus-error "gnus-util"))
33 36
34 (defgroup nnmail nil 37 (defgroup nnmail nil
35 "Reading mail with Gnus." 38 "Reading mail with Gnus."
36 :group 'gnus) 39 :group 'gnus)
37 40
107 :group 'nnmail-split 110 :group 'nnmail-split
108 :type 'boolean) 111 :type 'boolean)
109 112
110 ;; Added by gord@enci.ucalgary.ca (Gordon Matzigkeit). 113 ;; Added by gord@enci.ucalgary.ca (Gordon Matzigkeit).
111 (defcustom nnmail-keep-last-article nil 114 (defcustom nnmail-keep-last-article nil
112 "If non-nil, nnmail will never delete the last expired article in a directory. 115 "If non-nil, nnmail will never delete the last expired article in a directory.
113 You may need to set this variable if other programs are putting 116 You may need to set this variable if other programs are putting
114 new mail into folder numbers that Gnus has marked as expired." 117 new mail into folder numbers that Gnus has marked as expired."
115 :group 'nnmail-procmail 118 :group 'nnmail-procmail
116 :group 'nnmail-various 119 :group 'nnmail-various
117 :type 'boolean) 120 :type 'boolean)
155 (t 7))))" 158 (t 7))))"
156 :group 'nnmail-expire 159 :group 'nnmail-expire
157 :type '(choice (const :tag "nnmail-expiry-wait" nil) 160 :type '(choice (const :tag "nnmail-expiry-wait" nil)
158 (function :format "%v" nnmail-))) 161 (function :format "%v" nnmail-)))
159 162
160 (defcustom nnmail-spool-file 163 (defcustom nnmail-spool-file
161 (or (getenv "MAIL") 164 (or (getenv "MAIL")
162 (concat "/usr/spool/mail/" (user-login-name))) 165 (concat "/usr/spool/mail/" (user-login-name)))
163 "Where the mail backends will look for incoming mail. 166 "Where the mail backends will look for incoming mail.
164 This variable is \"/usr/spool/mail/$user\" by default. 167 This variable is \"/usr/spool/mail/$user\" by default.
165 If this variable is nil, no mail backends will read incoming mail. 168 If this variable is nil, no mail backends will read incoming mail.
228 (defcustom nnmail-pop-password-required nil 231 (defcustom nnmail-pop-password-required nil
229 "*Non-nil if a password is required when reading mail using POP." 232 "*Non-nil if a password is required when reading mail using POP."
230 :group 'nnmail-retrieve 233 :group 'nnmail-retrieve
231 :type 'boolean) 234 :type 'boolean)
232 235
233 (defcustom nnmail-read-incoming-hook 236 (defcustom nnmail-read-incoming-hook
234 (if (eq system-type 'windows-nt) 237 (if (eq system-type 'windows-nt)
235 '(nnheader-ms-strip-cr) 238 '(nnheader-ms-strip-cr)
236 nil) 239 nil)
237 "Hook that will be run after the incoming mail has been transferred. 240 "Hook that will be run after the incoming mail has been transferred.
238 The incoming mail is moved from `nnmail-spool-file' (which normally is 241 The incoming mail is moved from `nnmail-spool-file' (which normally is
241 emptied, and can be used to call any mail box programs you have 244 emptied, and can be used to call any mail box programs you have
242 running (\"xwatch\", etc.) 245 running (\"xwatch\", etc.)
243 246
244 Eg. 247 Eg.
245 248
246 \(add-hook 'nnmail-read-incoming-hook 249 \(add-hook 'nnmail-read-incoming-hook
247 (lambda () 250 (lambda ()
248 (start-process \"mailsend\" nil 251 (start-process \"mailsend\" nil
249 \"/local/bin/mailsend\" \"read\" \"mbox\"))) 252 \"/local/bin/mailsend\" \"read\" \"mbox\")))
250 253
251 If you have xwatch running, this will alert it that mail has been 254 If you have xwatch running, this will alert it that mail has been
252 read. 255 read.
253 256
254 If you use `display-time', you could use something like this: 257 If you use `display-time', you could use something like this:
255 258
256 \(add-hook 'nnmail-read-incoming-hook 259 \(add-hook 'nnmail-read-incoming-hook
257 (lambda () 260 (lambda ()
328 To enable this, set `nnmail-split-methods' to `nnmail-split-fancy'. 331 To enable this, set `nnmail-split-methods' to `nnmail-split-fancy'.
329 332
330 The format is this variable is SPLIT, where SPLIT can be one of 333 The format is this variable is SPLIT, where SPLIT can be one of
331 the following: 334 the following:
332 335
333 GROUP: Mail will be stored in GROUP (a string). 336 GROUP: Mail will be stored in GROUP (a string).
334 337
335 \(FIELD VALUE SPLIT): If the message field FIELD (a regexp) contains 338 \(FIELD VALUE SPLIT): If the message field FIELD (a regexp) contains
336 VALUE (a regexp), store the messages as specified by SPLIT. 339 VALUE (a regexp), store the messages as specified by SPLIT.
337 340
338 \(| SPLIT...): Process each SPLIT expression until one of them matches. 341 \(| SPLIT...): Process each SPLIT expression until one of them matches.
339 A SPLIT expression is said to match if it will cause the mail 342 A SPLIT expression is said to match if it will cause the mail
340 message to be stored in one or more groups. 343 message to be stored in one or more groups.
341 344
342 \(& SPLIT...): Process each SPLIT expression. 345 \(& SPLIT...): Process each SPLIT expression.
343 346
344 \(: FUNCTION optional args): Call FUNCTION with the optional args, in 347 \(: FUNCTION optional args): Call FUNCTION with the optional args, in
345 the buffer containing the message headers. The return value FUNCTION 348 the buffer containing the message headers. The return value FUNCTION
346 should be a split, which is then recursively processed. 349 should be a split, which is then recursively processed.
347 350
348 FIELD must match a complete field name. VALUE must match a complete 351 FIELD must match a complete field name. VALUE must match a complete
349 word according to the `nnmail-split-fancy-syntax-table' syntax table. 352 word according to the `nnmail-split-fancy-syntax-table' syntax table.
350 You can use .* in the regexps to match partial field names or words. 353 You can use \".*\" in the regexps to match partial field names or words.
351 354
352 FIELD and VALUE can also be lisp symbols, in that case they are expanded 355 FIELD and VALUE can also be lisp symbols, in that case they are expanded
353 as specified in `nnmail-split-abbrev-alist'. 356 as specified in `nnmail-split-abbrev-alist'.
354 357
355 GROUP can contain \\& and \\N which will substitute from matching 358 GROUP can contain \\& and \\N which will substitute from matching
469 (defun nnmail-group-pathname (group dir &optional file) 472 (defun nnmail-group-pathname (group dir &optional file)
470 "Make pathname for GROUP." 473 "Make pathname for GROUP."
471 (concat 474 (concat
472 (let ((dir (file-name-as-directory (expand-file-name dir)))) 475 (let ((dir (file-name-as-directory (expand-file-name dir))))
473 ;; If this directory exists, we use it directly. 476 ;; If this directory exists, we use it directly.
474 (if (or nnmail-use-long-file-names 477 (if (or nnmail-use-long-file-names
475 (file-directory-p (concat dir group))) 478 (file-directory-p (concat dir group)))
476 (concat dir group "/") 479 (concat dir group "/")
477 ;; If not, we translate dots into slashes. 480 ;; If not, we translate dots into slashes.
478 (concat dir (nnheader-replace-chars-in-string group ?. ?/) "/"))) 481 (concat dir (nnheader-replace-chars-in-string group ?. ?/) "/")))
479 (or file ""))) 482 (or file "")))
561 (and (file-exists-p inbox) 564 (and (file-exists-p inbox)
562 (/= 0 (nnheader-file-size inbox)))) 565 (/= 0 (nnheader-file-size inbox))))
563 (message "Getting mail from %s..." inbox))) 566 (message "Getting mail from %s..." inbox)))
564 ;; Set TOFILE if have not already done so, and 567 ;; Set TOFILE if have not already done so, and
565 ;; rename or copy the file INBOX to TOFILE if and as appropriate. 568 ;; rename or copy the file INBOX to TOFILE if and as appropriate.
566 (cond 569 (cond
567 ((file-exists-p tofile) 570 ((file-exists-p tofile)
568 ;; The crash box exists already. 571 ;; The crash box exists already.
569 t) 572 t)
570 ((and (not popmail) 573 ((and (not popmail)
571 (not (file-exists-p inbox))) 574 (not (file-exists-p inbox)))
579 (save-excursion 582 (save-excursion
580 (setq errors (generate-new-buffer " *nnmail loss*")) 583 (setq errors (generate-new-buffer " *nnmail loss*"))
581 (buffer-disable-undo errors) 584 (buffer-disable-undo errors)
582 (let ((default-directory "/")) 585 (let ((default-directory "/"))
583 (if (nnheader-functionp nnmail-movemail-program) 586 (if (nnheader-functionp nnmail-movemail-program)
584 (funcall nnmail-movemail-program inbox tofile) 587 (condition-case err
588 (progn
589 (funcall nnmail-movemail-program inbox tofile)
590 (setq result 0))
591 (error
592 (save-excursion
593 (set-buffer errors)
594 (insert (prin1-to-string err))
595 (setq result 255))))
585 (setq result 596 (setq result
586 (apply 597 (apply
587 'call-process 598 'call-process
588 (append 599 (append
589 (list 600 (list
590 (expand-file-name 601 (expand-file-name
591 nnmail-movemail-program exec-directory) 602 nnmail-movemail-program exec-directory)
592 nil errors nil inbox tofile) 603 nil errors nil inbox tofile)
593 (when nnmail-internal-password 604 (when nnmail-internal-password
594 (list nnmail-internal-password))))))) 605 (list nnmail-internal-password)))))))
595 (if (and (not (buffer-modified-p errors)) 606 (if (and (not (buffer-modified-p errors))
635 (let (group-assoc) 646 (let (group-assoc)
636 ;; Go through all groups from the active list. 647 ;; Go through all groups from the active list.
637 (save-excursion 648 (save-excursion
638 (set-buffer nntp-server-buffer) 649 (set-buffer nntp-server-buffer)
639 (goto-char (point-min)) 650 (goto-char (point-min))
640 (while (re-search-forward 651 (while (re-search-forward
641 "^\\([^ \t]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)" nil t) 652 "^\\([^ \t]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)" nil t)
642 ;; We create an alist with `(GROUP (LOW . HIGH))' elements. 653 ;; We create an alist with `(GROUP (LOW . HIGH))' elements.
643 (push (list (match-string 1) 654 (push (list (match-string 1)
644 (cons (string-to-int (match-string 3)) 655 (cons (string-to-int (match-string 3))
645 (string-to-int (match-string 2)))) 656 (string-to-int (match-string 2))))
674 "\\([^/]*\\)" nnmail-procmail-suffix "$") 685 "\\([^/]*\\)" nnmail-procmail-suffix "$")
675 (expand-file-name file)) 686 (expand-file-name file))
676 (let ((procmail-group (substring (expand-file-name file) 687 (let ((procmail-group (substring (expand-file-name file)
677 (match-beginning 1) 688 (match-beginning 1)
678 (match-end 1)))) 689 (match-end 1))))
679 (if group 690 (if group
680 (if (string-equal group procmail-group) 691 (if (string-equal group procmail-group)
681 group 692 group
682 nil) 693 nil)
683 procmail-group)) 694 procmail-group))
684 nil) 695 nil)
721 (forward-line -1) 732 (forward-line -1)
722 (insert "Message-ID: " (setq message-id (nnmail-message-id)) 733 (insert "Message-ID: " (setq message-id (nnmail-message-id))
723 "\n"))) 734 "\n")))
724 ;; Look for a Content-Length header. 735 ;; Look for a Content-Length header.
725 (if (not (save-excursion 736 (if (not (save-excursion
726 (and (re-search-backward 737 (and (re-search-backward
727 "^Content-Length:[ \t]*\\([0-9]+\\)" start t) 738 "^Content-Length:[ \t]*\\([0-9]+\\)" start t)
728 (setq content-length (string-to-int 739 (setq content-length (string-to-int
729 (buffer-substring 740 (buffer-substring
730 (match-beginning 1) 741 (match-beginning 1)
731 (match-end 1)))) 742 (match-end 1))))
732 ;; We destroy the header, since none of 743 ;; We destroy the header, since none of
733 ;; the backends ever use it, and we do not 744 ;; the backends ever use it, and we do not
734 ;; want to confuse other mailers by having 745 ;; want to confuse other mailers by having
744 (goto-char (+ (point) content-length)) 755 (goto-char (+ (point) content-length))
745 (setq do-search nil)) 756 (setq do-search nil))
746 (setq do-search t))) 757 (setq do-search t)))
747 (widen) 758 (widen)
748 ;; Go to the beginning of the next article - or to the end 759 ;; Go to the beginning of the next article - or to the end
749 ;; of the buffer. 760 ;; of the buffer.
750 (when do-search 761 (when do-search
751 (if (re-search-forward "^" nil t) 762 (if (re-search-forward "^" nil t)
752 (goto-char (match-beginning 0)) 763 (goto-char (match-beginning 0))
753 (goto-char (1- (point-max))))) 764 (goto-char (1- (point-max)))))
754 (delete-char 1) ; delete ^_ 765 (delete-char 1) ; delete ^_
830 (while (not (eobp)) 841 (while (not (eobp))
831 (setq start (point) 842 (setq start (point)
832 end nil) 843 end nil)
833 ;; Find the end of the head. 844 ;; Find the end of the head.
834 (narrow-to-region 845 (narrow-to-region
835 start 846 start
836 (if (search-forward "\n\n" nil t) 847 (if (search-forward "\n\n" nil t)
837 (1- (point)) 848 (1- (point))
838 ;; This will never happen, but just to be on the safe side -- 849 ;; This will never happen, but just to be on the safe side --
839 ;; if there is no head-body delimiter, we search a bit manually. 850 ;; if there is no head-body delimiter, we search a bit manually.
840 (while (and (looking-at "From \\|[^ \t]+:") 851 (while (and (looking-at "From \\|[^ \t]+:")
856 (goto-char (point-min)) 867 (goto-char (point-min))
857 (if (not (re-search-forward 868 (if (not (re-search-forward
858 "^Content-Length:[ \t]*\\([0-9]+\\)" nil t)) 869 "^Content-Length:[ \t]*\\([0-9]+\\)" nil t))
859 (setq content-length nil) 870 (setq content-length nil)
860 (setq content-length (string-to-int (match-string 1))) 871 (setq content-length (string-to-int (match-string 1)))
861 ;; We destroy the header, since none of the backends ever 872 ;; We destroy the header, since none of the backends ever
862 ;; use it, and we do not want to confuse other mailers by 873 ;; use it, and we do not want to confuse other mailers by
863 ;; having a (possibly) faulty header. 874 ;; having a (possibly) faulty header.
864 (beginning-of-line) 875 (beginning-of-line)
865 (insert "X-")) 876 (insert "X-"))
866 (run-hooks 'nnmail-prepare-incoming-header-hook) 877 (run-hooks 'nnmail-prepare-incoming-header-hook)
886 ((looking-at "[ \t]*\n\\(From \\)") 897 ((looking-at "[ \t]*\n\\(From \\)")
887 (setq end (match-beginning 1))) 898 (setq end (match-beginning 1)))
888 (t (setq end nil)))) 899 (t (setq end nil))))
889 (if end 900 (if end
890 (goto-char end) 901 (goto-char end)
891 ;; No Content-Length, so we find the beginning of the next 902 ;; No Content-Length, so we find the beginning of the next
892 ;; article or the end of the buffer. 903 ;; article or the end of the buffer.
893 (goto-char head-end) 904 (goto-char head-end)
894 (or (nnmail-search-unix-mail-delim) 905 (or (nnmail-search-unix-mail-delim)
895 (goto-char (point-max)))) 906 (goto-char (point-max))))
896 ;; Allow the backend to save the article. 907 ;; Allow the backend to save the article.
914 ;; Carry on until the bitter end. 925 ;; Carry on until the bitter end.
915 (while (not (eobp)) 926 (while (not (eobp))
916 (setq start (point)) 927 (setq start (point))
917 ;; Find the end of the head. 928 ;; Find the end of the head.
918 (narrow-to-region 929 (narrow-to-region
919 start 930 start
920 (if (search-forward "\n\n" nil t) 931 (if (search-forward "\n\n" nil t)
921 (1- (point)) 932 (1- (point))
922 ;; This will never happen, but just to be on the safe side -- 933 ;; This will never happen, but just to be on the safe side --
923 ;; if there is no head-body delimiter, we search a bit manually. 934 ;; if there is no head-body delimiter, we search a bit manually.
924 (while (and (looking-at "From \\|[^ \t]+:") 935 (while (and (looking-at "From \\|[^ \t]+:")
986 (nnmail-process-unix-mail-format func artnum-func)))) 997 (nnmail-process-unix-mail-format func artnum-func))))
987 (when exit-func 998 (when exit-func
988 (funcall exit-func)) 999 (funcall exit-func))
989 (kill-buffer (current-buffer))))) 1000 (kill-buffer (current-buffer)))))
990 1001
991 ;; Mail crossposts suggested by Brian Edmonds <edmonds@cs.ubc.ca>. 1002 ;; Mail crossposts suggested by Brian Edmonds <edmonds@cs.ubc.ca>.
992 (defun nnmail-article-group (func) 1003 (defun nnmail-article-group (func)
993 "Look at the headers and return an alist of groups that match. 1004 "Look at the headers and return an alist of groups that match.
994 FUNC will be called with the group name to determine the article number." 1005 FUNC will be called with the group name to determine the article number."
995 (let ((methods nnmail-split-methods) 1006 (let ((methods nnmail-split-methods)
996 (obuf (current-buffer)) 1007 (obuf (current-buffer))
1021 (let ((split 1032 (let ((split
1022 (condition-case nil 1033 (condition-case nil
1023 (or (funcall nnmail-split-methods) 1034 (or (funcall nnmail-split-methods)
1024 '("bogus")) 1035 '("bogus"))
1025 (error 1036 (error
1026 (message 1037 (message
1027 "Error in `nnmail-split-methods'; using `bogus' mail group") 1038 "Error in `nnmail-split-methods'; using `bogus' mail group")
1028 (sit-for 1) 1039 (sit-for 1)
1029 '("bogus"))))) 1040 '("bogus")))))
1030 (unless (equal split '(junk)) 1041 (unless (equal split '(junk))
1031 ;; `nnmail-split-methods' is a function, so we just call 1042 ;; `nnmail-split-methods' is a function, so we just call
1032 ;; this function here and use the result. 1043 ;; this function here and use the result.
1033 (setq group-art 1044 (setq group-art
1034 (mapcar 1045 (mapcar
1035 (lambda (group) (cons group (funcall func group))) 1046 (lambda (group) (cons group (funcall func group)))
1036 split)))) 1047 split))))
1044 (ignore-errors 1055 (ignore-errors
1045 (if (stringp (nth 1 method)) 1056 (if (stringp (nth 1 method))
1046 (re-search-backward (cadr method) nil t) 1057 (re-search-backward (cadr method) nil t)
1047 ;; Function to say whether this is a match. 1058 ;; Function to say whether this is a match.
1048 (funcall (nth 1 method) (car method)))) 1059 (funcall (nth 1 method) (car method))))
1049 ;; Don't enter the article into the same 1060 ;; Don't enter the article into the same
1050 ;; group twice. 1061 ;; group twice.
1051 (not (assoc (car method) group-art))) 1062 (not (assoc (car method) group-art)))
1052 (push (cons (car method) (funcall func (car method))) 1063 (push (cons (car method) (funcall func (car method)))
1053 group-art)) 1064 group-art))
1054 ;; This is the final group, which is used as a 1065 ;; This is the final group, which is used as a
1055 ;; catch-all. 1066 ;; catch-all.
1056 (unless group-art 1067 (unless group-art
1057 (setq group-art 1068 (setq group-art
1058 (list (cons (car method) 1069 (list (cons (car method)
1059 (funcall func (car method))))))))) 1070 (funcall func (car method)))))))))
1060 ;; See whether the split methods returned `junk'. 1071 ;; See whether the split methods returned `junk'.
1061 (if (equal group-art '(junk)) 1072 (if (equal group-art '(junk))
1062 nil 1073 nil
1257 ;; Get a list of spool files to read. 1268 ;; Get a list of spool files to read.
1258 (defun nnmail-get-spool-files (&optional group) 1269 (defun nnmail-get-spool-files (&optional group)
1259 (if (null nnmail-spool-file) 1270 (if (null nnmail-spool-file)
1260 ;; No spool file whatsoever. 1271 ;; No spool file whatsoever.
1261 nil 1272 nil
1262 (let* ((procmails 1273 (let* ((procmails
1263 ;; If procmail is used to get incoming mail, the files 1274 ;; If procmail is used to get incoming mail, the files
1264 ;; are stored in this directory. 1275 ;; are stored in this directory.
1265 (and (file-exists-p nnmail-procmail-directory) 1276 (and (file-exists-p nnmail-procmail-directory)
1266 (or (eq nnmail-spool-file 'procmail) 1277 (or (eq nnmail-spool-file 'procmail)
1267 nnmail-use-procmail) 1278 nnmail-use-procmail)
1268 (directory-files 1279 (directory-files
1269 nnmail-procmail-directory 1280 nnmail-procmail-directory
1270 t (concat (if group (concat "^" group) "") 1281 t (concat (if group (concat "^" group) "")
1271 nnmail-procmail-suffix "$")))) 1282 nnmail-procmail-suffix "$"))))
1272 (p procmails) 1283 (p procmails)
1273 (crash (when (and (file-exists-p nnmail-crash-box) 1284 (crash (when (and (file-exists-p nnmail-crash-box)
1274 (> (nnheader-file-size 1285 (> (nnheader-file-size
1275 (file-truename nnmail-crash-box)) 1286 (file-truename nnmail-crash-box))
1276 0)) 1287 0))
1277 (list nnmail-crash-box)))) 1288 (list nnmail-crash-box))))
1278 ;; Remove any directories that inadvertently match the procmail 1289 ;; Remove any directories that inadvertently match the procmail
1279 ;; suffix, which might happen if the suffix is "". 1290 ;; suffix, which might happen if the suffix is "".
1280 (while p 1291 (while p
1281 (when (file-directory-p (car p)) 1292 (when (file-directory-p (car p))
1282 (setq procmails (delete (car p) procmails))) 1293 (setq procmails (delete (car p) procmails)))
1283 (setq p (cdr p))) 1294 (setq p (cdr p)))
1284 ;; Return the list of spools. 1295 ;; Return the list of spools.
1285 (append 1296 (append
1286 crash 1297 crash
1287 (cond ((and group 1298 (cond ((and group
1288 (or (eq nnmail-spool-file 'procmail) 1299 (or (eq nnmail-spool-file 'procmail)
1289 nnmail-use-procmail) 1300 nnmail-use-procmail)
1290 procmails) 1301 procmails)
1292 ((and group 1303 ((and group
1293 (eq nnmail-spool-file 'procmail)) 1304 (eq nnmail-spool-file 'procmail))
1294 nil) 1305 nil)
1295 ((listp nnmail-spool-file) 1306 ((listp nnmail-spool-file)
1296 (nconc 1307 (nconc
1297 (apply 1308 (apply
1298 'nconc 1309 'nconc
1299 (mapcar 1310 (mapcar
1300 (lambda (file) 1311 (lambda (file)
1301 (if (and (not (string-match "^po:" file)) 1312 (if (and (not (string-match "^po:" file))
1302 (file-directory-p file)) 1313 (file-directory-p file))
1303 (nnheader-directory-regular-files file) 1314 (nnheader-directory-regular-files file)
1304 (list file))) 1315 (list file)))
1305 nnmail-spool-file)) 1316 nnmail-spool-file))
1306 procmails)) 1317 procmails))
1307 ((stringp nnmail-spool-file) 1318 ((stringp nnmail-spool-file)
1308 (if (and (not (string-match "^po:" nnmail-spool-file)) 1319 (if (and (not (string-match "^po:" nnmail-spool-file))
1309 (file-directory-p nnmail-spool-file)) 1320 (file-directory-p nnmail-spool-file))
1310 (nconc 1321 (nconc
1311 (nnheader-directory-regular-files nnmail-spool-file) 1322 (nnheader-directory-regular-files nnmail-spool-file)
1312 procmails) 1323 procmails)
1313 (cons nnmail-spool-file procmails))) 1324 (cons nnmail-spool-file procmails)))
1314 ((eq nnmail-spool-file 'pop) 1325 ((eq nnmail-spool-file 'pop)
1315 (cons (format "po:%s" (user-login-name)) procmails)) 1326 (cons (format "po:%s" (user-login-name)) procmails))
1316 (t 1327 (t
1317 procmails)))))) 1328 procmails))))))
1318 1329
1319 ;; Activate a backend only if it isn't already activated. 1330 ;; Activate a backend only if it isn't already activated.
1320 ;; If FORCE, re-read the active file even if the backend is 1331 ;; If FORCE, re-read the active file even if the backend is
1321 ;; already activated. 1332 ;; already activated.
1322 (defun nnmail-activate (backend &optional force) 1333 (defun nnmail-activate (backend &optional force)
1323 (let (file timestamp file-time) 1334 (let (file timestamp file-time)
1324 (if (or (not (symbol-value (intern (format "%s-group-alist" backend)))) 1335 (if (or (not (symbol-value (intern (format "%s-group-alist" backend))))
1325 force 1336 force
1326 (and (setq file (ignore-errors 1337 (and (setq file (ignore-errors
1327 (symbol-value (intern (format "%s-active-file" 1338 (symbol-value (intern (format "%s-active-file"
1328 backend))))) 1339 backend)))))
1329 (setq file-time (nth 5 (file-attributes file))) 1340 (setq file-time (nth 5 (file-attributes file)))
1330 (or (not 1341 (or (not
1331 (setq timestamp 1342 (setq timestamp
1332 (condition-case () 1343 (condition-case ()
1333 (symbol-value (intern 1344 (symbol-value (intern
1334 (format "%s-active-timestamp" 1345 (format "%s-active-timestamp"
1335 backend))) 1346 backend)))
1336 (error 'none)))) 1347 (error 'none))))
1337 (not (consp timestamp)) 1348 (not (consp timestamp))
1338 (equal timestamp '(0 0)) 1349 (equal timestamp '(0 0))
1339 (> (nth 0 file-time) (nth 0 timestamp)) 1350 (> (nth 0 file-time) (nth 0 timestamp))
1340 (and (= (nth 0 file-time) (nth 0 timestamp)) 1351 (and (= (nth 0 file-time) (nth 0 timestamp))
1341 (> (nth 1 file-time) (nth 1 timestamp)))))) 1352 (> (nth 1 file-time) (nth 1 timestamp))))))
1342 (save-excursion 1353 (save-excursion
1343 (or (eq timestamp 'none) 1354 (or (eq timestamp 'none)
1344 (set (intern (format "%s-active-timestamp" backend)) 1355 (set (intern (format "%s-active-timestamp" backend))
1345 ;;; dmoore@ucsd.edu 25.10.96 1356 file-time))
1346 ;;; it's not always the case that current-time 1357 (funcall (intern (format "%s-request-list" backend)))))
1347 ;;; does correspond to changes in the file's time. So just compare
1348 ;;; the file's new time against its own previous time.
1349 ;;; (current-time)
1350 file-time
1351 ))
1352 (funcall (intern (format "%s-request-list" backend)))
1353 ;;; dmoore@ucsd.edu 25.10.96
1354 ;;; BACKEND-request-list already does this itself!
1355 ;;; (set (intern (format "%s-group-alist" backend))
1356 ;;; (nnmail-get-active))
1357 ))
1358 t)) 1358 t))
1359 1359
1360 (defun nnmail-message-id () 1360 (defun nnmail-message-id ()
1361 (concat "<" (message-unique-id) "@totally-fudged-out-message-id>")) 1361 (concat "<" (message-unique-id) "@totally-fudged-out-message-id>"))
1362 1362
1370 (if (or (not nnmail-treat-duplicates) 1370 (if (or (not nnmail-treat-duplicates)
1371 (and nnmail-cache-buffer 1371 (and nnmail-cache-buffer
1372 (buffer-name nnmail-cache-buffer))) 1372 (buffer-name nnmail-cache-buffer)))
1373 () ; The buffer is open. 1373 () ; The buffer is open.
1374 (save-excursion 1374 (save-excursion
1375 (set-buffer 1375 (set-buffer
1376 (setq nnmail-cache-buffer 1376 (setq nnmail-cache-buffer
1377 (get-buffer-create " *nnmail message-id cache*"))) 1377 (get-buffer-create " *nnmail message-id cache*")))
1378 (buffer-disable-undo (current-buffer)) 1378 (buffer-disable-undo (current-buffer))
1379 (when (file-exists-p nnmail-message-id-cache-file) 1379 (when (file-exists-p nnmail-message-id-cache-file)
1380 (nnheader-insert-file-contents nnmail-message-id-cache-file)) 1380 (nnheader-insert-file-contents nnmail-message-id-cache-file))
1381 (set-buffer-modified-p nil) 1381 (set-buffer-modified-p nil)
1400 t)) 1400 t))
1401 (nnmail-write-region (point-min) (point-max) 1401 (nnmail-write-region (point-min) (point-max)
1402 nnmail-message-id-cache-file nil 'silent) 1402 nnmail-message-id-cache-file nil 'silent)
1403 (set-buffer-modified-p nil) 1403 (set-buffer-modified-p nil)
1404 (setq nnmail-cache-buffer nil) 1404 (setq nnmail-cache-buffer nil)
1405 ;;(kill-buffer (current-buffer)) 1405 (kill-buffer (current-buffer)))))
1406 )))
1407 1406
1408 (defun nnmail-cache-insert (id) 1407 (defun nnmail-cache-insert (id)
1409 (when nnmail-treat-duplicates 1408 (when nnmail-treat-duplicates
1409 (unless (gnus-buffer-live-p nnmail-cache-buffer)
1410 (nnmail-cache-open))
1410 (save-excursion 1411 (save-excursion
1411 (set-buffer nnmail-cache-buffer) 1412 (set-buffer nnmail-cache-buffer)
1412 (goto-char (point-max)) 1413 (goto-char (point-max))
1413 (insert id "\n")))) 1414 (insert id "\n"))))
1414 1415
1416 (when nnmail-treat-duplicates 1417 (when nnmail-treat-duplicates
1417 (save-excursion 1418 (save-excursion
1418 (set-buffer nnmail-cache-buffer) 1419 (set-buffer nnmail-cache-buffer)
1419 (goto-char (point-max)) 1420 (goto-char (point-max))
1420 (search-backward id nil t)))) 1421 (search-backward id nil t))))
1422
1423 (defun nnmail-fetch-field (header)
1424 (save-excursion
1425 (save-restriction
1426 (message-narrow-to-head)
1427 (message-fetch-field header))))
1421 1428
1422 (defun nnmail-check-duplication (message-id func artnum-func) 1429 (defun nnmail-check-duplication (message-id func artnum-func)
1423 (run-hooks 'nnmail-prepare-incoming-message-hook) 1430 (run-hooks 'nnmail-prepare-incoming-message-hook)
1424 ;; If this is a duplicate message, then we do not save it. 1431 ;; If this is a duplicate message, then we do not save it.
1425 (let* ((duplication (nnmail-cache-id-exists-p message-id)) 1432 (let* ((duplication (nnmail-cache-id-exists-p message-id))
1441 (nreverse (nnmail-article-group artnum-func))))) 1448 (nreverse (nnmail-article-group artnum-func)))))
1442 ((eq action 'delete) 1449 ((eq action 'delete)
1443 (setq group-art nil)) 1450 (setq group-art nil))
1444 ((eq action 'warn) 1451 ((eq action 'warn)
1445 ;; We insert a warning. 1452 ;; We insert a warning.
1446 (let ((case-fold-search t) 1453 (let ((case-fold-search t))
1447 (newid (nnmail-message-id)))
1448 (goto-char (point-min)) 1454 (goto-char (point-min))
1449 (when (re-search-forward "^message-id[ \t]*:" nil t) 1455 (re-search-forward "^message-id[ \t]*:" nil t)
1450 (beginning-of-line)
1451 (insert "Original-"))
1452 (beginning-of-line) 1456 (beginning-of-line)
1453 (insert 1457 (insert
1454 "Message-ID: " newid "\n"
1455 "Gnus-Warning: This is a duplicate of message " message-id "\n") 1458 "Gnus-Warning: This is a duplicate of message " message-id "\n")
1456 (nnmail-cache-insert newid)
1457 (funcall func (setq group-art 1459 (funcall func (setq group-art
1458 (nreverse (nnmail-article-group artnum-func)))))) 1460 (nreverse (nnmail-article-group artnum-func))))))
1459 (t 1461 (t
1460 (funcall func (setq group-art 1462 (funcall func (setq group-art
1461 (nreverse (nnmail-article-group artnum-func)))))) 1463 (nreverse (nnmail-article-group artnum-func))))))
1503 (file-exists-p nnmail-crash-box)) 1505 (file-exists-p nnmail-crash-box))
1504 ;; There is new mail. We first find out if all this mail 1506 ;; There is new mail. We first find out if all this mail
1505 ;; is supposed to go to some specific group. 1507 ;; is supposed to go to some specific group.
1506 (setq group (nnmail-get-split-group spool group-in)) 1508 (setq group (nnmail-get-split-group spool group-in))
1507 ;; We split the mail 1509 ;; We split the mail
1508 (nnmail-split-incoming 1510 (nnmail-split-incoming
1509 nnmail-crash-box (intern (format "%s-save-mail" method)) 1511 nnmail-crash-box (intern (format "%s-save-mail" method))
1510 spool-func group (intern (format "%s-active-number" method))) 1512 spool-func group (intern (format "%s-active-number" method)))
1511 ;; Check whether the inbox is to be moved to the special tmp dir. 1513 ;; Check whether the inbox is to be moved to the special tmp dir.
1512 (setq incoming 1514 (setq incoming
1513 (nnmail-make-complex-temp-name 1515 (nnmail-make-complex-temp-name
1514 (expand-file-name 1516 (expand-file-name
1515 (if nnmail-tmp-directory 1517 (if nnmail-tmp-directory
1516 (concat 1518 (concat
1517 (file-name-as-directory nnmail-tmp-directory) 1519 (file-name-as-directory nnmail-tmp-directory)
1518 (file-name-nondirectory 1520 (file-name-nondirectory
1519 (concat (file-name-as-directory temp) "Incoming"))) 1521 (concat (file-name-as-directory temp) "Incoming")))
1520 (concat (file-name-as-directory temp) "Incoming"))))) 1522 (concat (file-name-as-directory temp) "Incoming")))))
1521 (rename-file nnmail-crash-box incoming t) 1523 (rename-file nnmail-crash-box incoming t)
1522 (push incoming incomings)))) 1524 (push incoming incomings))))
1523 ;; If we did indeed read any incoming spools, we save all info. 1525 ;; If we did indeed read any incoming spools, we save all info.
1524 (when incomings 1526 (when incomings
1525 (nnmail-save-active 1527 (nnmail-save-active
1526 (nnmail-get-value "%s-group-alist" method) 1528 (nnmail-get-value "%s-group-alist" method)
1527 (nnmail-get-value "%s-active-file" method)) 1529 (nnmail-get-value "%s-active-file" method))
1528 (when exit-func 1530 (when exit-func
1529 (funcall exit-func)) 1531 (funcall exit-func))
1530 (run-hooks 'nnmail-read-incoming-hook) 1532 (run-hooks 'nnmail-read-incoming-hook)
1675 (when (assoc group (pop his)) 1677 (when (assoc group (pop his))
1676 (setq found t 1678 (setq found t
1677 his nil))) 1679 his nil)))
1678 found)) 1680 found))
1679 1681
1682 (eval-and-compile
1683 (autoload 'pop3-movemail "pop3"))
1684
1680 (defun nnmail-pop3-movemail (inbox crashbox) 1685 (defun nnmail-pop3-movemail (inbox crashbox)
1681 "Function to move mail from INBOX on a pop3 server to file CRASHBOX." 1686 "Function to move mail from INBOX on a pop3 server to file CRASHBOX."
1682 (require 'pop3)
1683 (let ((pop3-maildrop 1687 (let ((pop3-maildrop
1684 (substring inbox (match-end (string-match "^po:" inbox))))) 1688 (substring inbox (match-end (string-match "^po:" inbox)))))
1685 (pop3-movemail crashbox))) 1689 (pop3-movemail crashbox)))
1686 1690
1687 (run-hooks 'nnmail-load-hook) 1691 (run-hooks 'nnmail-load-hook)
1688 1692
1689 (provide 'nnmail) 1693 (provide 'nnmail)
1690 1694
1691 ;;; nnmail.el ends here 1695 ;;; nnmail.el ends here