This commit was generated by cvs2svn to compensate for changes in r3968,
[elisp/gnus.git-] / lisp / nnmail.el
index 5f43048..8e8359e 100644 (file)
 (eval-when-compile (require 'cl))
 
 (require 'nnheader)
+(require 'timezone)
 (require 'message)
 (require 'custom)
 (require 'gnus-util)
 
 (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."
@@ -241,13 +243,6 @@ to be moved to."
   :group 'nnmail-retrieve
   :type 'string)
 
-(defcustom nnmail-movemail-args nil
-  "*Extra arguments to give to `nnmail-movemail-program'  to move mail from the inbox.
-The default is nil"
-  :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
@@ -414,7 +409,7 @@ Example:
   :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
@@ -449,11 +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))
-
 ;;; Internal variables.
 
 (defvar nnmail-split-history nil
@@ -493,20 +483,19 @@ 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.")
 
 (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))))
 
@@ -525,12 +514,55 @@ 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'."
@@ -609,9 +641,7 @@ parameter.  It should return nil, `warn' or `delete'."
                              nnmail-movemail-program exec-directory)
                             nil errors nil inbox tofile)
                            (when nnmail-internal-password
-                             (list nnmail-internal-password))
-                           (when nnmail-movemail-args
-                             nnmail-movemail-args))))))
+                             (list nnmail-internal-password)))))))
                (push inbox nnmail-moved-inboxes)
                (if (and (not (buffer-modified-p errors))
                         (zerop result))
@@ -676,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)
@@ -808,7 +838,7 @@ is a spool.  If not using procmail, return GROUP."
          (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 ")
@@ -837,7 +867,7 @@ is a spool.  If not using procmail, return GROUP."
          (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 ")
@@ -1001,6 +1031,7 @@ FUNC will be called with the buffer narrowed to each mail."
     (save-excursion
       ;; Insert the incoming file.
       (set-buffer (get-buffer-create " *nnmail incoming*"))
+      (buffer-disable-undo (current-buffer))
       (erase-buffer)
       (nnheader-insert-file-contents incoming)
       (unless (zerop (buffer-size))
@@ -1171,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"))))
@@ -1454,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)
@@ -1521,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)
@@ -1640,9 +1671,9 @@ 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.
-            (time-less-p days (time-since time)))))))
+            (nnmail-time-less days (nnmail-time-since time)))))))
 
 (defvar nnmail-read-passwd nil)
 (defun nnmail-read-passwd (prompt &rest args)
@@ -1653,11 +1684,13 @@ If ARGS, PROMPT is used as an argument to `format'."
             (apply 'format prompt args)
           prompt)))
     (unless nnmail-read-passwd
-      (if (load "passwd" t)
+      (if (functionp 'read-passwd)
          (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)))
+       (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 ()
@@ -1670,9 +1703,9 @@ 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."
-  (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)))
 
 ;;;
@@ -1707,11 +1740,11 @@ If ARGS, PROMPT is used as an argument to `format'."
        (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")