This commit was manufactured by cvs2svn to create tag 'gnus-6_7_7-ichikawa'.
[elisp/gnus.git-] / lisp / nnmail.el
index 3e9cd0f..516e8b1 100644 (file)
@@ -1,7 +1,7 @@
 ;;; nnmail.el --- mail support functions for the Gnus mail backends
-;; Copyright (C) 1995,96,97 Free Software Foundation, Inc.
+;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc.
 
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news, mail
 
 ;; This file is part of GNU Emacs.
@@ -33,7 +33,9 @@
 (require 'custom)
 
 (eval-and-compile
-  (autoload 'gnus-error "gnus-util"))
+  (autoload 'gnus-error "gnus-util")
+  (autoload 'gnus-buffer-live-p "gnus-util")
+  (autoload 'gnus-encode-coding-string "gnus-ems"))
 
 (defgroup nnmail nil
   "Reading mail with Gnus."
@@ -74,7 +76,7 @@
 
 (defcustom nnmail-split-methods
   '(("mail.misc" ""))
-  "Incoming mail will be split according to this variable.
+  "*Incoming mail will be split according to this variable.
 
 If you'd like, for instance, one mail group for mail from the
 \"4ad-l\" mailing list, one group for junk mail and one for everything
@@ -171,7 +173,7 @@ Eg.:
 (defcustom nnmail-spool-file
   (or (getenv "MAIL")
       (concat "/usr/spool/mail/" (user-login-name)))
-  "Where the mail backends will look for incoming mail.
+  "*Where the mail backends will look for 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
@@ -216,10 +218,10 @@ several files - eg. \".spool[0-9]*\"."
   :type 'function)
 
 (defcustom nnmail-crosspost-link-function
-  (if (string-match "windows-nt\\|emx" (format "%s" system-type))
+  (if (string-match "windows-nt\\|emx" (symbol-name system-type))
       'copy-file
     'add-name-to-file)
-  "Function called to create a copy of a file.
+  "*Function called to create a copy of a file.
 This is `add-name-to-file' by default, which means that crossposts
 will use hard links.  If your file system doesn't allow hard
 links, you could set this variable to `copy-file' instead."
@@ -248,7 +250,7 @@ to be moved to."
   (if (eq system-type 'windows-nt)
       '(nnheader-ms-strip-cr)
     nil)
-  "Hook that will be run after the incoming mail has been transferred.
+  "*Hook that will be run after the incoming mail has been transferred.
 The incoming mail is moved from `nnmail-spool-file' (which normally is
 something like \"/usr/spool/mail/$user\") to the user's home
 directory.  This hook is called after the incoming mail box has been
@@ -341,7 +343,7 @@ messages will be shown to indicate the current status."
   "Incoming mail can be split according to this fancy variable.
 To enable this, set `nnmail-split-methods' to `nnmail-split-fancy'.
 
-The format is this variable is SPLIT, where SPLIT can be one of
+The format of this variable is SPLIT, where SPLIT can be one of
 the following:
 
 GROUP: Mail will be stored in GROUP (a string).
@@ -401,11 +403,11 @@ Example:
     (from . "from\\|sender\\|resent-from")
     (nato . "to\\|cc\\|resent-to\\|resent-cc")
     (naany . "from\\|to\\|cc\\|sender\\|resent-from\\|resent-to\\|resent-cc"))
-  "Alist of abbreviations allowed in `nnmail-split-fancy'."
+  "*Alist of abbreviations allowed in `nnmail-split-fancy'."
   :group 'nnmail-split
   :type '(repeat (cons :format "%v" symbol regexp)))
 
-(defcustom nnmail-delete-incoming nil
+(defcustom nnmail-delete-incoming t
   "*If non-nil, the mail backends will delete incoming files after
 splitting."
   :group 'nnmail-retrieve
@@ -476,7 +478,6 @@ parameter.  It should return nil, `warn' or `delete'."
 (defun nnmail-request-post (&optional server)
   (mail-send-and-exit nil))
 
-;; 1997/5/4 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
 (defvar nnmail-file-coding-system 'raw-text
   "Coding system used in nnmail.")
 
@@ -487,16 +488,12 @@ parameter.  It should return nil, `warn' or `delete'."
   (let ((format-alist nil)
         (after-insert-file-functions nil))
     (condition-case ()
-       ;; 1997/5/4 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
        (let ((coding-system-for-read nnmail-file-coding-system)
-             ;; 1997/8/12 by MORIOKA Tomohiko
-             ;;        for XEmacs/mule.
              (pathname-coding-system 'binary))
          (insert-file-contents file)
          t)
       (file-error nil))))
 
-;; 1997/8/10 by MORIOKA Tomohiko
 (defvar nnmail-pathname-coding-system
   'iso-8859-1
   "*Coding system for pathname.")
@@ -544,7 +541,7 @@ parameter.  It should return nil, `warn' or `delete'."
   "Convert DAYS into time."
   (let* ((seconds (* 1.0 days 60 60 24))
         (rest (expt 2 16))
-        (ms (condition-case nil (round (/ seconds rest))
+        (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))))))
@@ -594,12 +591,12 @@ parameter.  It should return nil, `warn' or `delete'."
                      (nnmail-read-passwd
                       (format "Password for %s: "
                               (substring inbox (+ popmail 3))))))
-             (message "Getting mail from the post office..."))
+             (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))))
-           (message "Getting mail from %s..." 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
@@ -639,14 +636,14 @@ parameter.  It should return nil, `warn' or `delete'."
                             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)))
-                     (push inbox nnmail-moved-inboxes))
+                         (set-file-modes tofile nnmail-default-file-modes))))
                  (set-buffer errors)
                  ;; There may be a warning about older revisions.  We
                  ;; ignore those.
@@ -655,8 +652,8 @@ parameter.  It should return nil, `warn' or `delete'."
                      (progn
                        (unless popmail
                          (when (file-exists-p tofile)
-                           (set-file-modes tofile nnmail-default-file-modes)))
-                       (push inbox nnmail-moved-inboxes))
+                           (set-file-modes
+                            tofile nnmail-default-file-modes))))
                    ;; Probably a real error.
                    (subst-char-in-region (point-min) (point-max) ?\n ?\  )
                    (goto-char (point-max))
@@ -670,7 +667,7 @@ parameter.  It should return nil, `warn' or `delete'."
                                     (buffer-string) result))
                      (error "%s" (buffer-string)))
                    (setq tofile nil)))))))
-       (message "Getting mail from %s...done" inbox)
+       (nnheader-message 5 "Getting mail from %s...done" inbox)
        (and errors
             (buffer-name errors)
             (kill-buffer errors))
@@ -693,7 +690,6 @@ nn*-request-list should have been called before calling this function."
              group-assoc)))
     group-assoc))
 
-;; 1997/8/12 by MORIOKA Tomohiko
 (defvar nnmail-active-file-coding-system
   'iso-8859-1
   "*Coding system for active file.")
@@ -721,10 +717,12 @@ 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 "^" (expand-file-name
-                                    (file-name-as-directory
-                                     nnmail-procmail-directory))
-                               "\\([^/]*\\)" nnmail-procmail-suffix "$")
+      (if (string-match (concat "^" (regexp-quote
+                                    (expand-file-name
+                                     (file-name-as-directory
+                                      nnmail-procmail-directory)))
+                               "\\([^/]*\\)"
+                               (regexp-quote nnmail-procmail-suffix) "$")
                        (expand-file-name file))
          (let ((procmail-group (substring (expand-file-name file)
                                           (match-beginning 1)
@@ -740,8 +738,8 @@ is a spool.  If not using procmail, return GROUP."
 (defun nnmail-process-babyl-mail-format (func artnum-func)
   (let ((case-fold-search t)
        start message-id content-length do-search end)
-    (goto-char (point-min))
     (while (not (eobp))
+      (goto-char (point-min))
       (re-search-forward
        "\f\n0, *unseen,+\n\\(\\*\\*\\* EOOH \\*\\*\\*\n\\)?" nil t)
       (goto-char (match-end 0))
@@ -879,7 +877,7 @@ is a spool.  If not using procmail, return GROUP."
                  (goto-char (match-beginning 0))))
        ;; Possibly wrong format?
        (progn
-         (pop-to-buffer (find-file-noselect nnmail-current-spool))
+         (pop-to-buffer (nnheader-find-file-noselect nnmail-current-spool))
          (error "Error, unknown mail format! (Possibly corrupted.)"))
       ;; Carry on until the bitter end.
       (while (not (eobp))
@@ -966,7 +964,7 @@ is a spool.  If not using procmail, return GROUP."
                  (forward-line 1)))
        ;; Possibly wrong format?
        (progn
-         (pop-to-buffer (find-file-noselect nnmail-current-spool))
+         (pop-to-buffer (nnheader-find-file-noselect nnmail-current-spool))
          (error "Error, unknown mail format! (Possibly corrupted.)"))
       ;; Carry on until the bitter end.
       (while (not (eobp))
@@ -1052,7 +1050,8 @@ FUNC will be called with the group name to determine the article number."
        (obuf (current-buffer))
        (beg (point-min))
        end group-art method regrepp)
-    (if (and (sequencep methods) (= (length methods) 1))
+    (if (and (sequencep methods)
+            (= (length methods) 1))
        ;; If there is only just one group to put everything in, we
        ;; just return a list with just this one method in.
        (setq group-art
@@ -1082,10 +1081,11 @@ FUNC will be called with the group name to determine the article number."
                       (or (funcall nnmail-split-methods)
                           '("bogus"))
                     (error
-                     (message
+                     (nnheader-message 5
                       "Error in `nnmail-split-methods'; using `bogus' mail group")
                      (sit-for 1)
                      '("bogus")))))
+             (setq split (remove-duplicates split :test 'equal))
              ;; The article may be "cross-posted" to `junk'.  What
              ;; to do?  Just remove the `junk' spec.  Don't really
              ;; see anything else to do...
@@ -1547,9 +1547,6 @@ 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."
-  ;; Nix out the previous split history.
-  (unless group
-    (setq nnmail-split-history nil))
   (let* ((spools (nnmail-get-spool-files group))
         (group-in group)
         nnmail-current-spool incoming incomings spool)
@@ -1666,10 +1663,7 @@ If ARGS, PROMPT is used as an argument to `format'."
 
 (defun nnmail-write-region (start end filename &optional append visit lockname)
   "Do a `write-region', and then set the file modes."
-  ;; 1997/5/4 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
   (let ((coding-system-for-write nnmail-file-coding-system)
-       ;; 1997/8/12 by MORIOKA Tomohiko
-       ;;      for XEmacs/mule.
        (pathname-coding-system 'binary))
     (write-region start end filename append visit lockname)
     (set-file-modes filename nnmail-default-file-modes)))
@@ -1748,6 +1742,16 @@ If ARGS, PROMPT is used as an argument to `format'."
                          ", "))
        (princ "\n")))))
 
+(defun nnmail-purge-split-history (group)
+  "Remove all instances of GROUP from `nnmail-split-history'."
+  (let ((history nnmail-split-history)
+       prev)
+    (while history
+      (setcar history (delete-if (lambda (e) (string= (car e) group))
+                                (car history)))
+      (pop history))
+    (setq nnmail-split-history (delq nil nnmail-split-history))))
+
 (defun nnmail-new-mail-p (group)
   "Say whether GROUP has new mail."
   (let ((his nnmail-split-history)
@@ -1767,6 +1771,14 @@ If ARGS, PROMPT is used as an argument to `format'."
          (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."
+  (let ((pos (point)))
+    (save-excursion
+      (and (nnmail-search-unix-mail-delim-backward)
+          (not (search-forward "\n\n" pos t))))))
+
 (run-hooks 'nnmail-load-hook)
 
 (provide 'nnmail)