X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=lisp%2Fnnmail.el;h=8e8359e94a2492e8449e9cdc4c8bbe3128a5a00a;hb=ed341c45e5e97c823e86a642b7136a140f2af6f3;hp=5304d32f7406b18774065b586af03fca1c5fe0a6;hpb=8cfa576451fc393ec8ad0de58a89a0afd4343fbf;p=elisp%2Fgnus.git- diff --git a/lisp/nnmail.el b/lisp/nnmail.el index 5304d32..8e8359e 100644 --- a/lisp/nnmail.el +++ b/lisp/nnmail.el @@ -1,5 +1,5 @@ ;;; nnmail.el --- mail support functions for the Gnus mail backends -;; Copyright (C) 1995,96,97,98,99 Free Software Foundation, Inc. +;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news, mail @@ -28,14 +28,15 @@ (eval-when-compile (require 'cl)) (require 'nnheader) +(require 'timezone) (require 'message) (require 'custom) (require 'gnus-util) -(require 'mail-source) (eval-and-compile (autoload 'gnus-error "gnus-util") - (autoload 'gnus-buffer-live-p "gnus-util")) + (autoload 'gnus-buffer-live-p "gnus-util") + (autoload 'gnus-encode-coding-string "gnus-ems")) (defgroup nnmail nil "Reading mail with Gnus." @@ -170,12 +171,43 @@ Eg.: :group 'nnmail :type 'boolean) -(defcustom nnmail-spool-file '((file)) +(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 a list of mail source specifiers. -If this variable is nil, no mail backends will read 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 'sexp) + :type '(choice (file :tag "File") + (repeat :tag "Files" 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 + :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-resplit-incoming nil "*If non-nil, re-split incoming procmail sorted mail." @@ -200,6 +232,22 @@ 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 (if (eq system-type 'windows-nt) '(nnheader-ms-strip-cr) @@ -232,6 +280,7 @@ If you use `display-time', you could use something like this: :group 'nnmail-prepare :type 'hook) +;; Suggested by Erik Selberg . (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." @@ -276,6 +325,15 @@ discarded after running the split process." :group 'nnmail-split :type 'hook) +;; Suggested by Mejia Pablo J . +(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 @@ -351,6 +409,12 @@ Example: :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 @@ -367,7 +431,7 @@ performed." (defcustom nnmail-treat-duplicates 'warn "*If non-nil, nnmail keep a cache of Message-IDs to discover mail duplicates. -Three values are valid: nil, which means that nnmail is not to keep a +Three values are legal: 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. @@ -380,16 +444,6 @@ parameter. It should return nil, `warn' or `delete'." (const warn) (const delete))) -(defcustom nnmail-extra-headers nil - "*Extra headers to parse." - :group 'nnmail - :type '(repeat symbol)) - -(defcustom nnmail-split-header-length-limit 512 - "Header lines longer than this limit are excluded from the split function." - :group 'nnmail - :type 'integer) - ;;; Internal variables. (defvar nnmail-split-history nil @@ -397,6 +451,9 @@ parameter. It should return nil, `warn' or `delete'." (defvar nnmail-current-spool nil) +(defvar nnmail-pop-password nil + "*Password to use when reading mail from a POP server, if required.") + (defvar nnmail-split-fancy-syntax-table nil "Syntax table used by `nnmail-split-fancy'.") (unless (syntax-table-p nnmail-split-fancy-syntax-table) @@ -408,6 +465,11 @@ parameter. It should return nil, `warn' or `delete'." (defvar nnmail-prepare-save-mail-hook nil "Hook called before saving mail.") +(defvar nnmail-moved-inboxes nil + "List of inboxes that have been moved.") + +(defvar nnmail-internal-password nil) + (defvar nnmail-split-tracing nil) (defvar nnmail-split-trace nil) @@ -421,33 +483,24 @@ parameter. It should return nil, `warn' or `delete'." (defun nnmail-request-post (&optional server) (mail-send-and-exit nil)) -(defvar nnmail-file-coding-system 'binary +(defvar nnmail-file-coding-system 'raw-text "Coding system used in nnmail.") -(defvar nnmail-file-coding-system-1 - (if (string-match "nt" system-configuration) - 'raw-text-dos 'binary) - "Another coding system used in nnmail.") - -(defvar nnmail-incoming-coding-system - mm-text-coding-system - "Coding system used in reading inbox") - (defun nnmail-find-file (file) "Insert FILE in server buffer safely." (set-buffer nntp-server-buffer) - (delete-region (point-min) (point-max)) + (erase-buffer) (let ((format-alist nil) (after-insert-file-functions nil)) (condition-case () - (let ((coding-system-for-read nnmail-file-coding-system) - (auto-mode-alist (nnheader-auto-mode-alist)) - (pathname-coding-system nnmail-file-coding-system)) - (insert-file-contents file) + (let ((pathname-coding-system 'binary)) + (insert-file-contents-as-coding-system + nnmail-file-coding-system file) t) (file-error nil)))) -(defvar nnmail-pathname-coding-system 'binary +(defvar nnmail-pathname-coding-system + 'iso-8859-1 "*Coding system for pathname.") (defun nnmail-group-pathname (group dir &optional file) @@ -461,12 +514,174 @@ parameter. It should return nil, `warn' or `delete'." (concat dir group "/") ;; If not, we translate dots into slashes. (concat dir - (mm-encode-coding-string + (gnus-encode-coding-string (nnheader-replace-chars-in-string group ?. ?/) nnmail-pathname-coding-system) "/"))) (or file ""))) +(defun nnmail-date-to-time (date) + "Convert DATE into time." + (condition-case () + (let* ((d1 (timezone-parse-date date)) + (t1 (timezone-parse-time (aref d1 3)))) + (apply 'encode-time + (mapcar (lambda (el) + (and el (string-to-number el))) + (list + (aref t1 2) (aref t1 1) (aref t1 0) + (aref d1 2) (aref d1 1) (aref d1 0) + (number-to-string + (* 60 (timezone-zone-to-minute + (or (aref d1 4) (current-time-zone))))))))) + ;; If we get an error, then we just return a 0 time. + (error (list 0 0)))) + +(defun nnmail-time-less (t1 t2) + "Say whether time T1 is less than time T2." + (or (< (car t1) (car t2)) + (and (= (car t1) (car t2)) + (< (nth 1 t1) (nth 1 t2))))) + +(defun nnmail-days-to-time (days) + "Convert DAYS into time." + (let* ((seconds (* 1.0 days 60 60 24)) + (rest (expt 2 16)) + (ms (condition-case nil (floor (/ seconds rest)) + (range-error (expt 2 16))))) + (list ms (condition-case nil (round (- seconds (* ms rest))) + (range-error (expt 2 16)))))) + +(defun nnmail-time-since (time) + "Return the time since TIME, which is either an internal time or a date." + (when (stringp time) + ;; Convert date strings to internal time. + (setq time (nnmail-date-to-time time))) + (let* ((current (current-time)) + (rest (when (< (nth 1 current) (nth 1 time)) + (expt 2 16)))) + (list (- (+ (car current) (if rest -1 0)) (car time)) + (- (+ (or rest 0) (nth 1 current)) (nth 1 time))))) + +;; Function rewritten from rmail.el. +(defun nnmail-move-inbox (inbox) + "Move INBOX to `nnmail-crash-box'." + (if (not (file-writable-p nnmail-crash-box)) + (gnus-error 1 "Can't write to crash box %s. Not moving mail" + nnmail-crash-box) + ;; If the crash box exists and is empty, we delete it. + (when (and (file-exists-p nnmail-crash-box) + (zerop (nnheader-file-size (file-truename nnmail-crash-box)))) + (delete-file nnmail-crash-box)) + (let ((tofile (file-truename (expand-file-name nnmail-crash-box))) + (popmail (string-match "^po:" inbox)) + movemail errors result) + (unless popmail + (setq inbox (file-truename (expand-file-name inbox))) + (setq movemail t) + ;; On some systems, /usr/spool/mail/foo is a directory + ;; and the actual inbox is /usr/spool/mail/foo/foo. + (when (file-directory-p inbox) + (setq inbox (expand-file-name (user-login-name) inbox)))) + (if (member inbox nnmail-moved-inboxes) + ;; We don't try to move an already moved inbox. + nil + (if popmail + (progn + (when (and nnmail-pop-password + (not nnmail-internal-password)) + (setq nnmail-internal-password nnmail-pop-password)) + (when (and nnmail-pop-password-required + (not nnmail-internal-password)) + (setq nnmail-internal-password + (nnmail-read-passwd + (format "Password for %s: " + (substring inbox (+ popmail 3)))))) + (nnheader-message 5 "Getting mail from the post office...")) + (when (or (and (file-exists-p tofile) + (/= 0 (nnheader-file-size tofile))) + (and (file-exists-p inbox) + (/= 0 (nnheader-file-size inbox)))) + (nnheader-message 5 "Getting mail from %s..." inbox))) + ;; Set TOFILE if have not already done so, and + ;; rename or copy the file INBOX to TOFILE if and as appropriate. + (cond + ((file-exists-p tofile) + ;; The crash box exists already. + t) + ((and (not popmail) + (not (file-exists-p inbox))) + ;; There is no inbox. + (setq tofile nil)) + (t + ;; If getting from mail spool directory, use movemail to move + ;; rather than just renaming, so as to interlock with the + ;; mailer. + (unwind-protect + (save-excursion + (setq errors (generate-new-buffer " *nnmail loss*")) + (buffer-disable-undo errors) + (if (nnheader-functionp nnmail-movemail-program) + (condition-case err + (progn + (funcall nnmail-movemail-program inbox tofile) + (setq result 0)) + (error + (save-excursion + (set-buffer errors) + (insert (prin1-to-string err)) + (setq result 255)))) + (let ((default-directory "/")) + (setq result + (apply + 'call-process + (append + (list + (expand-file-name + nnmail-movemail-program exec-directory) + nil errors nil inbox tofile) + (when nnmail-internal-password + (list nnmail-internal-password))))))) + (push inbox nnmail-moved-inboxes) + (if (and (not (buffer-modified-p errors)) + (zerop result)) + ;; No output => movemail won + (progn + (unless popmail + (when (file-exists-p tofile) + (set-file-modes tofile nnmail-default-file-modes)))) + (set-buffer errors) + ;; There may be a warning about older revisions. We + ;; ignore those. + (goto-char (point-min)) + (if (search-forward "older revision" nil t) + (progn + (unless popmail + (when (file-exists-p tofile) + (set-file-modes + tofile nnmail-default-file-modes)))) + ;; Probably a real error. + ;; We nix out the password in case the error + ;; was because of a wrong password being given. + (setq nnmail-internal-password nil) + (subst-char-in-region (point-min) (point-max) ?\n ?\ ) + (goto-char (point-max)) + (skip-chars-backward " \t") + (delete-region (point) (point-max)) + (goto-char (point-min)) + (when (looking-at "movemail: ") + (delete-region (point-min) (match-end 0))) + (unless (yes-or-no-p + (format "movemail: %s (%d return). Continue? " + (buffer-string) result)) + (error "%s" (buffer-string))) + (setq tofile nil))))))) + (nnheader-message 5 "Getting mail from %s...done" inbox) + (and errors + (buffer-name errors) + (kill-buffer errors)) + tofile)))) + (defun nnmail-get-active () "Returns an assoc of group names and active ranges. nn*-request-list should have been called before calling this function." @@ -491,7 +706,7 @@ nn*-request-list should have been called before calling this function." "Save GROUP-ASSOC in ACTIVE-FILE." (let ((coding-system-for-write nnmail-active-file-coding-system)) (when file-name - (with-temp-file file-name + (nnheader-temp-write file-name (nnmail-generate-active group-assoc))))) (defun nnmail-generate-active (alist) @@ -502,16 +717,31 @@ nn*-request-list should have been called before calling this function." (insert (format "%s %d %d y\n" (car group) (cdadr group) (caadr group)))))) -(defun nnmail-get-split-group (file source) +(defun nnmail-get-split-group (file group) "Find out whether this FILE is to be split into GROUP only. -If SOURCE is a directory spec, try to return the group name component." - (if (eq (car source) 'directory) - (let ((file (file-name-nondirectory file))) - (mail-source-bind directory source - (if (string-match (concat (regexp-quote suffix "$") file)) - (substring file 0 (match-beginning 0)) - nil))) - nil)) +If GROUP is non-nil and we are using procmail, return the group name +only when the file is the correct procmail file. When GROUP is nil, +return nil if FILE is a spool file or the procmail group for which it +is a spool. If not using procmail, return GROUP." + (if (or (eq nnmail-spool-file 'procmail) + nnmail-use-procmail) + (if (string-match (concat "^" (regexp-quote + (expand-file-name + (file-name-as-directory + nnmail-procmail-directory))) + "\\([^/]*\\)" + nnmail-procmail-suffix "$") + (expand-file-name file)) + (let ((procmail-group (substring (expand-file-name file) + (match-beginning 1) + (match-end 1)))) + (if group + (if (string-equal group procmail-group) + group + nil) + procmail-group)) + nil) + group)) (defun nnmail-process-babyl-mail-format (func artnum-func) (let ((case-fold-search t) @@ -608,7 +838,7 @@ If SOURCE is a directory spec, try to return the group name component." (when (and (or (bobp) (save-excursion (forward-line -1) - (eq (char-after) ?\n))) + (= (following-char) ?\n))) (save-excursion (forward-line 1) (while (looking-at ">From \\|From ") @@ -637,7 +867,7 @@ If SOURCE is a directory spec, try to return the group name component." (when (and (or (bobp) (save-excursion (forward-line -1) - (eq (char-after) ?\n))) + (= (following-char) ?\n))) (save-excursion (forward-line 1) (while (looking-at ">From \\|From ") @@ -793,15 +1023,17 @@ FUNC will be called with the buffer narrowed to each mail." (let (;; If this is a group-specific split, we bind the split ;; methods to just this group. (nnmail-split-methods (if (and group + (or (eq nnmail-spool-file 'procmail) + nnmail-use-procmail) (not nnmail-resplit-incoming)) (list (list group "")) nnmail-split-methods))) (save-excursion ;; Insert the incoming file. (set-buffer (get-buffer-create " *nnmail incoming*")) + (buffer-disable-undo (current-buffer)) (erase-buffer) - (let ((nnheader-file-coding-system nnmail-incoming-coding-system)) - (nnheader-insert-file-contents incoming)) + (nnheader-insert-file-contents incoming) (unless (zerop (buffer-size)) (goto-char (point-min)) (save-excursion (run-hooks 'nnmail-prepare-incoming-hook)) @@ -851,10 +1083,10 @@ FUNC will be called with the group name to determine the article number." ;; existence to process. (goto-char (point-min)) (while (not (eobp)) - (unless (< (move-to-column nnmail-split-header-length-limit) - nnmail-split-header-length-limit) - (delete-region (point) (progn (end-of-line) (point)))) - (forward-line 1)) + (end-of-line) + (if (> (current-column) 1024) + (gnus-delete-line) + (forward-line 1))) ;; Allow washing. (goto-char (point-min)) (run-hooks 'nnmail-split-hook) @@ -970,9 +1202,8 @@ Return the number of characters in the body." (insert (format "Xref: %s" (system-name))) (while group-alist (insert (format " %s:%d" - (mm-encode-coding-string - (caar group-alist) - nnmail-pathname-coding-system) + (gnus-encode-coding-string (caar group-alist) + nnmail-pathname-coding-system) (cdar group-alist))) (setq group-alist (cdr group-alist))) (insert "\n")))) @@ -1002,6 +1233,16 @@ Return the number of characters in the body." ;;; Utility functions +(defun nnmail-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)) + +;; Written by Per Abrahamsen . + (defun nnmail-split-fancy () "Fancy splitting method. See the documentation for the variable `nnmail-split-fancy' for documentation." @@ -1132,6 +1373,68 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (apply 'concat (nreverse expanded)) newtext))) +;; Get a list of spool files to read. +(defun nnmail-get-spool-files (&optional group) + (if (null nnmail-spool-file) + ;; No spool file whatsoever. + nil + (let* ((procmails + ;; If procmail is used to get incoming mail, the files + ;; are stored in this directory. + (and (file-exists-p nnmail-procmail-directory) + (or (eq nnmail-spool-file 'procmail) + nnmail-use-procmail) + (directory-files + nnmail-procmail-directory + t (concat (if group (concat "^" (regexp-quote group)) "") + nnmail-procmail-suffix "$")))) + (p procmails) + (crash (when (and (file-exists-p nnmail-crash-box) + (> (nnheader-file-size + (file-truename nnmail-crash-box)) + 0)) + (list nnmail-crash-box)))) + ;; Remove any directories that inadvertently match the procmail + ;; suffix, which might happen if the suffix is "". + (while p + (when (file-directory-p (car p)) + (setq procmails (delete (car p) procmails))) + (setq p (cdr p))) + ;; Return the list of spools. + (append + crash + (cond ((and group + (or (eq nnmail-spool-file 'procmail) + nnmail-use-procmail) + procmails) + procmails) + ((and group + (eq nnmail-spool-file 'procmail)) + nil) + ((listp nnmail-spool-file) + (nconc + (apply + 'nconc + (mapcar + (lambda (file) + (if (and (not (string-match "^po:" file)) + (file-directory-p file)) + (nnheader-directory-regular-files file) + (list file))) + nnmail-spool-file)) + procmails)) + ((stringp nnmail-spool-file) + (if (and (not (string-match "^po:" nnmail-spool-file)) + (file-directory-p nnmail-spool-file)) + (nconc + (nnheader-directory-regular-files nnmail-spool-file) + procmails) + (cons nnmail-spool-file procmails))) + ((eq nnmail-spool-file 'pop) + (cons (format "po:%s" (user-login-name)) procmails)) + (t + procmails)))))) + ;; Activate a backend only if it isn't already activated. ;; If FORCE, re-read the active file even if the backend is ;; already activated. @@ -1181,6 +1484,7 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (set-buffer (setq nnmail-cache-buffer (get-buffer-create " *nnmail message-id cache*"))) + (buffer-disable-undo (current-buffer)) (when (file-exists-p nnmail-message-id-cache-file) (nnheader-insert-file-contents nnmail-message-id-cache-file)) (set-buffer-modified-p nil) @@ -1248,9 +1552,9 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." ;; Let the backend save the article (or not). (cond ((not duplication) + (nnmail-cache-insert message-id) (funcall func (setq group-art - (nreverse (nnmail-article-group artnum-func)))) - (nnmail-cache-insert message-id)) + (nreverse (nnmail-article-group artnum-func))))) ((eq action 'delete) (setq group-art nil)) ((eq action 'warn) @@ -1281,11 +1585,9 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (defun nnmail-get-new-mail (method exit-func temp &optional group spool-func) "Read new incoming mail." - (let* ((sources (if (listp nnmail-spool-file) nnmail-spool-file - (list nnmail-spool-file))) + (let* ((spools (nnmail-get-spool-files group)) (group-in group) - (i 0) - nnmail-current-spool incoming incomings source) + nnmail-current-spool incoming incomings spool) (when (and (nnmail-get-value "%s-get-new-mail" method) nnmail-spool-file) ;; We first activate all the groups. @@ -1294,30 +1596,43 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (run-hooks 'nnmail-pre-get-new-mail-hook) ;; Open the message-id cache. (nnmail-cache-open) - ;; The we go through all the existing mail source specification - ;; and fetch the mail from each. - (while (setq source (pop sources)) - ;; Be compatible with old values. - (when (stringp source) - (setq source - (cond - ((string-match "^po:" source) - (list 'pop :user (substring source (match-end 0)))) - ((file-directory-p source) - (list 'directory :path source)) - (t - (list 'file :path source))))) - (nnheader-message 3 "%s: Reading incoming mail %S..." method source) - (when (mail-source-fetch - source - `(lambda (file orig-file) - (nnmail-split-incoming - file ',(intern (format "%s-save-mail" method)) - ',spool-func (nnmail-get-split-group orig-file source) - ',(intern (format "%s-active-number" method))))) - (incf i))) + ;; The we go through all the existing spool files and split the + ;; mail from each. + (while spools + (setq spool (pop spools)) + ;; We read each spool file if either the spool is a POP-mail + ;; spool, or the file exists. We can't check for the + ;; existence of POPped mail. + (when (or (string-match "^po:" spool) + (and (file-exists-p (file-truename spool)) + (> (nnheader-file-size (file-truename spool)) 0))) + (nnheader-message 3 "%s: Reading incoming mail..." method) + (when (and (nnmail-move-inbox spool) + (file-exists-p nnmail-crash-box)) + (setq nnmail-current-spool spool) + ;; There is new mail. We first find out if all this mail + ;; is supposed to go to some specific group. + (setq group (nnmail-get-split-group spool group-in)) + ;; We split the mail + (nnmail-split-incoming + nnmail-crash-box (intern (format "%s-save-mail" method)) + spool-func group (intern (format "%s-active-number" method))) + ;; Check whether the inbox is to be moved to the special tmp dir. + (setq incoming + (nnmail-make-complex-temp-name + (expand-file-name + (if nnmail-tmp-directory + (concat + (file-name-as-directory nnmail-tmp-directory) + (file-name-nondirectory + (concat (file-name-as-directory temp) "Incoming"))) + (concat (file-name-as-directory temp) "Incoming"))))) + (unless (file-exists-p (file-name-directory incoming)) + (make-directory (file-name-directory incoming) t)) + (rename-file nnmail-crash-box incoming t) + (push incoming incomings)))) ;; If we did indeed read any incoming spools, we save all info. - (unless (zerop i) + (when incomings (nnmail-save-active (nnmail-get-value "%s-group-alist" method) (nnmail-get-value "%s-active-file" method)) @@ -1328,7 +1643,14 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." ;; Close the message-id cache. (nnmail-cache-close) ;; Allow the user to hook. - (run-hooks 'nnmail-post-get-new-mail-hook)))) + (run-hooks 'nnmail-post-get-new-mail-hook) + ;; Delete all the temporary files. + (while incomings + (setq incoming (pop incomings)) + (and nnmail-delete-incoming + (file-exists-p incoming) + (file-writable-p incoming) + (delete-file incoming)))))) (defun nnmail-expired-article-p (group time force &optional inhibit) "Say whether an article that is TIME old in GROUP should be expired." @@ -1349,11 +1671,27 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." ;; This is an ange-ftp group, and we don't have any dates. nil) ((numberp days) - (setq days (days-to-time days)) + (setq days (nnmail-days-to-time days)) ;; Compare the time with the current time. - (condition-case () - (time-less-p days (time-since time)) - (error nil))))))) + (nnmail-time-less days (nnmail-time-since time))))))) + +(defvar nnmail-read-passwd nil) +(defun nnmail-read-passwd (prompt &rest args) + "Read a password using PROMPT. +If ARGS, PROMPT is used as an argument to `format'." + (let ((prompt + (if args + (apply 'format prompt args) + prompt))) + (unless nnmail-read-passwd + (if (functionp 'read-passwd) + (setq nnmail-read-passwd 'read-passwd) + (if (load "passwd" t) + (setq nnmail-read-passwd 'read-passwd) + (unless (fboundp 'ange-ftp-read-passwd) + (autoload 'ange-ftp-read-passwd "ange-ftp")) + (setq nnmail-read-passwd 'ange-ftp-read-passwd)))) + (funcall nnmail-read-passwd prompt))) (defun nnmail-check-syntax () "Check (and modify) the syntax of the message in the current buffer." @@ -1365,9 +1703,9 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (defun nnmail-write-region (start end filename &optional append visit lockname) "Do a `write-region', and then set the file modes." - (let ((coding-system-for-write nnmail-file-coding-system) - (pathname-coding-system 'binary)) - (write-region start end filename append visit lockname) + (let ((pathname-coding-system 'binary)) + (write-region-as-coding-system + nnmail-file-coding-system start end filename append visit lockname) (set-file-modes filename nnmail-default-file-modes))) ;;; @@ -1402,11 +1740,11 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (goto-char (point-min)) (while (re-search-forward "[^ \t=]+" nil t) (setq name (match-string 0)) - (if (not (eq (char-after) ?=)) + (if (not (= (following-char) ?=)) ;; Implied "yes". (setq value "yes") (forward-char 1) - (if (not (eq (char-after) ?\")) + (if (not (= (following-char) ?\")) (if (not (looking-at "[^ \t]")) ;; Implied "no". (setq value "no") @@ -1463,6 +1801,15 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." his nil))) found)) +(eval-and-compile + (autoload 'pop3-movemail "pop3")) + +(defun nnmail-pop3-movemail (inbox crashbox) + "Function to move mail from INBOX on a pop3 server to file CRASHBOX." + (let ((pop3-maildrop + (substring inbox (match-end (string-match "^po:" inbox))))) + (pop3-movemail crashbox))) + (defun nnmail-within-headers-p () "Check to see if point is within the headers of a unix mail message. Doesn't change point."