Synch with Oort Gnus.
[elisp/gnus.git-] / lisp / mail-source.el
index 0fb724c..5cf4016 100644 (file)
@@ -1,5 +1,5 @@
 ;;; 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
@@ -264,6 +264,11 @@ If non-nil, this maildrop will be checked periodically for new mail."
   :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 ""
@@ -286,6 +291,9 @@ Common keywords should be listed here.")
        (:path (or (getenv "MAIL")
                  (expand-file-name (user-login-name) rmail-spool-directory))))
       (directory
+       (:prescript)
+       (:prescript-delay)
+       (:postscript)
        (:path)
        (:suffix ".spool")
        (:predicate identity))
@@ -375,7 +383,7 @@ the `mail-source-keyword-map' variable."
      ,@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))
@@ -418,7 +426,7 @@ See `mail-source-bind'."
      ,@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."
@@ -452,21 +460,27 @@ Return the number of files that were found."
              (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 error (%s).  Continue? "
+                                    (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.
@@ -525,7 +539,8 @@ Pass INFO on to CALLBACK."
                       '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))
@@ -624,6 +639,9 @@ If ARGS, PROMPT is used as an argument to `format'."
 (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
@@ -632,6 +650,8 @@ If ARGS, PROMPT is used as an argument to `format'."
                   (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)
@@ -676,15 +696,17 @@ If ARGS, PROMPT is used as an argument to `format'."
                     (or leave
                         (and (boundp 'pop3-leave-mail-on-server)
                              pop3-leave-mail-on-server))))
-               (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)
@@ -735,15 +757,17 @@ If ARGS, PROMPT is used as an argument to `format'."
                    (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))
@@ -913,10 +937,11 @@ This only works when `display-time' is enabled."
                  (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 (if (imap-capability 'IMAP4rev1 buf)
-                                   (imap-fetch uid "BODY.PEEK[]" 'BODYDETAIL
-                                               nil buf)
-                           (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
@@ -932,7 +957,7 @@ This only works when `display-time' is enabled."
               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