;;; mail-source.el --- functions for fetching mail
-;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Keywords: news, mail
This variable is a list of mail source specifiers.
See Info node `(gnus)Mail Source Specifiers'."
:group 'mail-source
+ :link '(custom-manual "(gnus)Mail Source Specifiers")
:type `(repeat
(choice :format "%[Value Menu%] %v"
:value (file)
(function :tag "Predicate"))
(group :inline t
(const :format "" :value :prescript)
- (string :tag "Prescript"))
+ (choice :tag "Prescript"
+ :value nil
+ (string :format "%v")
+ (function :format "%v")))
(group :inline t
(const :format "" :value :postscript)
- (string :tag "Postscript"))
+ (choice :tag "Postscript"
+ :value nil
+ (string :format "%v")
+ (function :format "%v")))
(group :inline t
(const :format "" :value :plugged)
(boolean :tag "Plugged"))))
(string :tag "Program"))
(group :inline t
(const :format "" :value :prescript)
- (string :tag "Prescript"))
+ (choice :tag "Prescript"
+ :value nil
+ (string :format "%v")
+ (function :format "%v")))
(group :inline t
(const :format "" :value :postscript)
- (string :tag "Postscript"))
+ (choice :tag "Postscript"
+ :value nil
+ (string :format "%v")
+ (function :format "%v")))
(group :inline t
(const :format "" :value :function)
(function :tag "Function"))
:group 'mail-source
:type 'number)
+(defcustom mail-source-movemail-program nil
+ "If non-nil, name of program for fetching new mail."
+ :group 'mail-source
+ :type '(choice (const nil) string))
+
;;; Internal variables.
(defvar mail-source-string ""
(:path (or (getenv "MAIL")
(expand-file-name (user-login-name) rmail-spool-directory))))
(directory
+ (:prescript)
+ (:prescript-delay)
+ (:postscript)
(:path)
(:suffix ".spool")
(:predicate identity))
,@body))
(put 'mail-source-bind 'lisp-indent-function 1)
-(put 'mail-source-bind 'edebug-form-spec '(form body))
+(put 'mail-source-bind 'edebug-form-spec '(sexp body))
(defun mail-source-set-1 (source)
(let* ((type (pop source))
,@body))
(put 'mail-source-bind-common 'lisp-indent-function 1)
-(put 'mail-source-bind-common 'edebug-form-spec '(form body))
+(put 'mail-source-bind-common 'edebug-form-spec '(sexp body))
(defun mail-source-value (value)
"Return the value of VALUE."
(setq found (mail-source-callback
callback mail-source-crash-box)))
(+ found
- (condition-case err
+ (if (or debug-on-quit debug-on-error)
(funcall function source callback)
- (error
- (unless (yes-or-no-p
- (format "Mail source error (%s). Continue? " err))
- (error "Cannot get new mail"))
- 0))))))))
-
-(defun mail-source-make-complex-temp-name (prefix)
- (let ((newname (make-temp-name prefix))
- (newprefix prefix))
- (while (file-exists-p newname)
- (setq newprefix (concat newprefix "x"))
- (setq newname (make-temp-name newprefix)))
- newname))
+ (condition-case err
+ (funcall function source callback)
+ (error
+ (unless (yes-or-no-p
+ (format "Mail source %s error (%s). Continue? "
+ (if (memq ':password source)
+ (let ((s (copy-sequence source)))
+ (setcar (cdr (memq ':password s))
+ "********")
+ s)
+ source)
+ (cadr err)))
+ (error "Cannot get new mail"))
+ 0)))))))))
+
+(eval-and-compile
+ (if (fboundp 'make-temp-file)
+ (defalias 'mail-source-make-complex-temp-name 'make-temp-file)
+ (defun mail-source-make-complex-temp-name (prefix)
+ (let ((newname (make-temp-name prefix))
+ (newprefix prefix))
+ (while (file-exists-p newname)
+ (setq newprefix (concat newprefix "x"))
+ (setq newname (make-temp-name newprefix)))
+ newname))))
(defun mail-source-callback (callback info)
"Call CALLBACK on the mail file, and then remove the mail file.
'call-process
(append
(list
- (expand-file-name "movemail" exec-directory)
+ (or mail-source-movemail-program
+ (expand-file-name "movemail" exec-directory))
nil errors nil from to)))))
(when (file-exists-p to)
(set-file-modes to mail-source-default-file-modes))
(defun mail-source-fetch-with-program (program)
(zerop (call-process shell-file-name nil nil nil
- shell-command-switch program)))
+ shell-command-switch program)))
(defun mail-source-run-script (script spec &optional delay)
(when script
- (if (and (symbolp script) (fboundp script))
+ (if (functionp script)
(funcall script)
(mail-source-call-script
(format-spec script spec))))
(defun mail-source-fetch-directory (source callback)
"Fetcher for directory sources."
(mail-source-bind (directory source)
+ (mail-source-run-script
+ prescript (format-spec-make ?t path)
+ prescript-delay)
(let ((found 0)
(mail-source-string (format "directory:%s" path)))
(dolist (file (directory-files
(funcall predicate file)
(mail-source-movemail file mail-source-crash-box))
(incf found (mail-source-callback callback file))))
+ (mail-source-run-script
+ postscript (format-spec-make ?t path))
found)))
(defun mail-source-fetch-pop (source callback)
(pop3-port port)
(pop3-authentication-scheme
(if (eq authentication 'apop) 'apop 'pass)))
- (condition-case err
+ (if (or debug-on-quit debug-on-error)
(save-excursion (pop3-movemail mail-source-crash-box))
- (error
- ;; We nix out the password in case the error
- ;; was because of a wrong password being given.
- (setq mail-source-password-cache
- (delq (assoc from mail-source-password-cache)
- mail-source-password-cache))
- (signal (car err) (cdr err))))))))
+ (condition-case err
+ (save-excursion (pop3-movemail mail-source-crash-box))
+ (error
+ ;; We nix out the password in case the error
+ ;; was because of a wrong password being given.
+ (setq mail-source-password-cache
+ (delq (assoc from mail-source-password-cache)
+ mail-source-password-cache))
+ (signal (car err) (cdr err)))))))))
(if result
(progn
(when (eq authentication 'password)
(pop3-port port)
(pop3-authentication-scheme
(if (eq authentication 'apop) 'apop 'pass)))
- (condition-case err
+ (if (or debug-on-quit debug-on-error)
(save-excursion (pop3-get-message-count))
- (error
- ;; We nix out the password in case the error
- ;; was because of a wrong password being given.
- (setq mail-source-password-cache
- (delq (assoc from mail-source-password-cache)
- mail-source-password-cache))
- (signal (car err) (cdr err))))))))
+ (condition-case err
+ (save-excursion (pop3-get-message-count))
+ (error
+ ;; We nix out the password in case the error
+ ;; was because of a wrong password being given.
+ (setq mail-source-password-cache
+ (delq (assoc from mail-source-password-cache)
+ mail-source-password-cache))
+ (signal (car err) (cdr err)))))))))
(if result
;; Inform display-time that we have new mail.
(setq mail-source-new-mail-available (> result 0))
mail-source-password-cache)))
result)))
+(defun mail-source-touch-pop ()
+ "Open and close a POP connection shortly.
+POP server should be defined in `mail-source-primary-source' (which is
+preferred) or `mail-sources'. You may use it for the POP-before-SMTP
+authentication. To do that, you need to set the option
+`message-send-mail-function' to `message-smtpmail-send-it' and put the
+following line in .gnus file:
+
+\(add-hook 'message-send-mail-hook 'mail-source-touch-pop)
+"
+ (let ((sources (if mail-source-primary-source
+ (list mail-source-primary-source)
+ mail-sources)))
+ (while sources
+ (if (eq 'pop (car (car sources)))
+ (mail-source-check-pop (car sources)))
+ (setq sources (cdr sources)))))
+
(defun mail-source-new-mail-p ()
"Handler for `display-time' to indicate when new mail is available."
;; Flash (ie. ring the visible bell) if mail is available.
(with-temp-file mail-source-crash-box
(insert-file-contents file)
(goto-char (point-min))
-;;; ;; Unix mail format
-;;; (unless (looking-at "\n*From ")
-;;; (insert "From maildir "
-;;; (current-time-string) "\n"))
-;;; (while (re-search-forward "^From " nil t)
-;;; (replace-match ">From "))
-;;; (goto-char (point-max))
+;;; ;; Unix mail format
+;;; (unless (looking-at "\n*From ")
+;;; (insert "From maildir "
+;;; (current-time-string) "\n"))
+;;; (while (re-search-forward "^From " nil t)
+;;; (replace-match ">From "))
+;;; (goto-char (point-max))
;;; (insert "\n\n")
;; MMDF mail format
(insert "\001\001\001\001\n"))
(push (cons from imap-password) mail-source-password-cache)))
;; if predicate is nil, use all uids
(dolist (uid (imap-search (or predicate "1:*") buf))
- (when (setq str (imap-fetch uid "RFC822.PEEK" 'RFC822 nil buf))
+ (when (setq str
+ (if (imap-capability 'IMAP4rev1 buf)
+ (caddar (imap-fetch uid "BODY.PEEK[]"
+ 'BODYDETAIL nil buf))
+ (imap-fetch uid "RFC822.PEEK" 'RFC822 nil buf)))
(push uid remove)
(insert "From imap " (current-time-string) "\n")
(save-excursion
fetchflag nil buf))
(if dontexpunge
(imap-mailbox-unselect buf)
- (imap-mailbox-close buf))
+ (imap-mailbox-close nil buf))
(imap-close buf))
(imap-close buf)
;; We nix out the password in case the error