2001-07-24 09:00:00 ShengHuo ZHU <zsh@cs.rochester.edu>
[gnus] / lisp / nnml.el
index d4a2a58..080dd76 100644 (file)
@@ -1,5 +1,6 @@
 ;;; nnml.el --- mail spool access for Gnus
-;; Copyright (C) 1995,96,97,98,99 Free Software Foundation, Inc.
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
+;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
   "Spool directory for the nnml mail backend.")
 
 (defvoo nnml-active-file
-  (concat (file-name-as-directory nnml-directory) "active")
+    (expand-file-name "active" nnml-directory)
   "Mail active file.")
 
 (defvoo nnml-newsgroups-file
-  (concat (file-name-as-directory nnml-directory) "newsgroups")
+    (expand-file-name "newsgroups" nnml-directory)
   "Mail newsgroups description file.")
 
 (defvoo nnml-get-new-mail t
@@ -85,8 +86,11 @@ all.  This may very well take some time.")
 (defvoo nnml-generate-active-function 'nnml-generate-active-info)
 
 (defvar nnml-nov-buffer-file-name nil)
+(defvar nnml-check-directory-twice t
+  "If t, to make sure nothing went wrong when reading over NFS --
+check twice.")
 
-(defvoo nnml-file-coding-system nnmail-file-coding-system-1)
+(defvoo nnml-file-coding-system nnmail-file-coding-system)
 
 \f
 
@@ -99,11 +103,16 @@ all.  This may very well take some time.")
     (save-excursion
       (set-buffer nntp-server-buffer)
       (erase-buffer)
-      (let ((file nil)
-           (number (length sequence))
-           (count 0)
-           (pathname-coding-system 'binary)
-           beg article)
+      (let* ((file nil)
+             (number (length sequence))
+             (count 0)
+             (file-name-coding-system nnmail-pathname-coding-system)
+             beg article
+             (nnml-check-directory-twice 
+              (and nnml-check-directory-twice 
+                   ;; To speed up, disable it in some case.
+                   (or (not (numberp nnmail-large-newsgroup))
+                       (<= number nnmail-large-newsgroup)))))
        (if (stringp (car sequence))
            'headers
          (if (nnml-retrieve-headers-with-nov sequence fetch-old)
@@ -155,15 +164,15 @@ all.  This may very well take some time.")
                     server nnml-directory)
     t)))
 
-(defun nnml-request-regenerate (server)
+(deffoo nnml-request-regenerate (server)
   (nnml-possibly-change-directory nil server)
-  (nnml-generate-nov-databases)
+  (nnml-generate-nov-databases server)
   t)
 
 (deffoo nnml-request-article (id &optional group server buffer)
   (nnml-possibly-change-directory group server)
   (let* ((nntp-server-buffer (or buffer nntp-server-buffer))
-        (pathname-coding-system 'binary)
+        (file-name-coding-system nnmail-pathname-coding-system)
         path gpath group-num)
     (if (stringp id)
        (when (and (setq group-num (nnml-find-group-number id))
@@ -194,7 +203,7 @@ all.  This may very well take some time.")
            (string-to-int (file-name-nondirectory path)))))))
 
 (deffoo nnml-request-group (group &optional server dont-check)
-  (let ((pathname-coding-system 'binary))
+  (let ((file-name-coding-system nnmail-pathname-coding-system))
     (cond
      ((not (nnml-possibly-change-directory group server))
       (nnheader-report 'nnml "Invalid group (no such directory)"))
@@ -252,7 +261,7 @@ all.  This may very well take some time.")
 (deffoo nnml-request-list (&optional server)
   (save-excursion
     (let ((nnmail-file-coding-system nnmail-active-file-coding-system)
-         (pathname-coding-system 'binary))
+         (file-name-coding-system nnmail-pathname-coding-system))
       (nnmail-find-file nnml-active-file))
     (setq nnml-group-alist (nnmail-get-active))
     t))
@@ -264,8 +273,7 @@ all.  This may very well take some time.")
   (save-excursion
     (nnmail-find-file nnml-newsgroups-file)))
 
-(deffoo nnml-request-expire-articles (articles group
-                                              &optional server force)
+(deffoo nnml-request-expire-articles (articles group &optional server force)
   (nnml-possibly-change-directory group server)
   (let ((active-articles
         (nnheader-directory-articles nnml-current-directory))
@@ -286,8 +294,16 @@ all.  This may very well take some time.")
                         (nnmail-expired-article-p group mod-time force
                                                   nnml-inhibit-expiry)))
              (progn
+               ;; Allow a special target group.
+               (unless (eq nnmail-expiry-target 'delete)
+                 (with-temp-buffer
+                   (nnml-request-article number group server
+                                         (current-buffer))
+                   (let ((nnml-current-directory nil))
+                     (nnmail-expiry-target-group
+                      nnmail-expiry-target group))))
                (nnheader-message 5 "Deleting article %s in %s"
-                                 article group)
+                                 number group)
                (condition-case ()
                    (funcall nnmail-delete-file-function article)
                  (file-error
@@ -305,7 +321,7 @@ all.  This may very well take some time.")
     (nconc rest articles)))
 
 (deffoo nnml-request-move-article
-  (article group server accept-form &optional last)
+    (article group server accept-form &optional last)
   (let ((buf (get-buffer-create " *nnml move*"))
        result)
     (nnml-possibly-change-directory group server)
@@ -313,12 +329,15 @@ all.  This may very well take some time.")
     (and
      (nnml-deletable-article-p group article)
      (nnml-request-article article group server)
-     (save-excursion
-       (set-buffer buf)
-       (insert-buffer-substring nntp-server-buffer)
-       (setq result (eval accept-form))
-       (kill-buffer (current-buffer))
-       result)
+     (let (nnml-current-directory 
+          nnml-current-group 
+          nnml-article-file-alist)
+       (save-excursion
+        (set-buffer buf)
+        (insert-buffer-substring nntp-server-buffer)
+        (setq result (eval accept-form))
+        (kill-buffer (current-buffer))
+        result))
      (progn
        (nnml-possibly-change-directory group server)
        (condition-case ()
@@ -358,6 +377,9 @@ all.  This may very well take some time.")
         (nnml-save-nov))))
     result))
 
+(deffoo nnml-request-post (&optional server)
+  (nnmail-do-request-post 'nnml-request-accept-article server))
+
 (deffoo nnml-request-replace-article (article group buffer)
   (nnml-possibly-change-directory group)
   (save-excursion
@@ -370,8 +392,8 @@ all.  This may very well take some time.")
              (nnmail-write-region
               (point-min) (point-max)
               (or (nnml-article-to-file article)
-                  (concat nnml-current-directory
-                          (int-to-string article)))
+                  (expand-file-name (int-to-string article)
+                                    nnml-current-directory))
               nil (if (nnheader-be-verbose 5) nil 'nomesg))
              t)
        (setq headers (nnml-parse-head chars article))
@@ -475,14 +497,15 @@ all.  This may very well take some time.")
   (nnml-update-file-alist)
   (let (file)
     (if (setq file (cdr (assq article nnml-article-file-alist)))
-       (concat nnml-current-directory file)
-      ;; Just to make sure nothing went wrong when reading over NFS --
-      ;; check once more.
-      (when (file-exists-p
-            (setq file (expand-file-name (number-to-string article)
-                                         nnml-current-directory)))
-       (nnml-update-file-alist t)
-       file))))
+       (expand-file-name file nnml-current-directory)
+      (if nnml-check-directory-twice
+          ;; Just to make sure nothing went wrong when reading over NFS --
+          ;; check once more.
+          (when (file-exists-p
+                 (setq file (expand-file-name (number-to-string article)
+                                              nnml-current-directory)))
+            (nnml-update-file-alist t)
+            file)))))
 
 (defun nnml-deletable-article-p (group article)
   "Say whether ARTICLE in GROUP can be deleted."
@@ -516,8 +539,8 @@ all.  This may very well take some time.")
 
 (defun nnml-find-id (group id)
   (erase-buffer)
-  (let ((nov (concat (nnmail-group-pathname group nnml-directory)
-                    nnml-nov-file-name))
+  (let ((nov (expand-file-name nnml-nov-file-name
+                              (nnmail-group-pathname group nnml-directory)))
        number found)
     (when (file-exists-p nov)
       (nnheader-insert-file-contents nov)
@@ -537,7 +560,7 @@ all.  This may very well take some time.")
 (defun nnml-retrieve-headers-with-nov (articles &optional fetch-old)
   (if (or gnus-nov-is-evil nnml-nov-is-evil)
       nil
-    (let ((nov (concat nnml-current-directory nnml-nov-file-name)))
+    (let ((nov (expand-file-name nnml-nov-file-name nnml-current-directory)))
       (when (file-exists-p nov)
        (save-excursion
          (set-buffer nntp-server-buffer)
@@ -559,7 +582,7 @@ all.  This may very well take some time.")
   (if (not group)
       t
     (let ((pathname (nnmail-group-pathname group nnml-directory))
-         (pathname-coding-system 'binary))
+         (file-name-coding-system nnmail-pathname-coding-system))
       (when (not (equal pathname nnml-current-directory))
        (setq nnml-current-directory pathname
              nnml-current-group group
@@ -591,7 +614,7 @@ all.  This may very well take some time.")
        (let ((file (concat (nnmail-group-pathname
                             (caar ga) nnml-directory)
                            (int-to-string (cdar ga)))))
-z        (if first
+         (if first
              ;; It was already saved, so we just make a hard link.
              (funcall nnmail-crosspost-link-function first file t)
            ;; Save the article.
@@ -633,8 +656,8 @@ z     (if first
       (push (list group active) nnml-group-alist))
     (setcdr active (1+ (cdr active)))
     (while (file-exists-p
-           (concat (nnmail-group-pathname group nnml-directory)
-                   (int-to-string (cdr active))))
+           (expand-file-name (int-to-string (cdr active))
+                             (nnmail-group-pathname group nnml-directory)))
       (setcdr active (1+ (cdr active))))
     (cdr active)))
 
@@ -674,8 +697,9 @@ z     (if first
        (save-excursion
          (set-buffer buffer)
          (set (make-local-variable 'nnml-nov-buffer-file-name)
-              (concat (nnmail-group-pathname group nnml-directory)
-                      nnml-nov-file-name))
+              (expand-file-name
+               nnml-nov-file-name
+               (nnmail-group-pathname group nnml-directory)))
          (erase-buffer)
          (when (file-exists-p nnml-nov-buffer-file-name)
            (nnheader-insert-file-contents nnml-nov-buffer-file-name)))
@@ -695,13 +719,14 @@ z   (if first
       (setq nnml-nov-buffer-alist (cdr nnml-nov-buffer-alist)))))
 
 ;;;###autoload
-(defun nnml-generate-nov-databases ()
+(defun nnml-generate-nov-databases (&optional server)
   "Generate NOV databases in all nnml directories."
-  (interactive)
+  (interactive (list (or (nnoo-current-server 'nnml) "")))
   ;; Read the active file to make sure we don't re-use articles
   ;; numbers in empty groups.
   (nnmail-activate 'nnml)
-  (nnml-open-server (or (nnoo-current-server 'nnml) ""))
+  (unless (nnml-server-opened server)
+    (nnml-open-server server))
   (setq nnml-directory (expand-file-name nnml-directory))
   ;; Recurse down the directories.
   (nnml-generate-nov-databases-1 nnml-directory nil t)
@@ -737,18 +762,21 @@ z   (if first
        (unless no-active
          (nnmail-save-active nnml-group-alist nnml-active-file))))))
 
-(defvar files)
+(eval-when-compile (defvar files))
 (defun nnml-generate-active-info (dir)
   ;; Update the active info for this group.
-  (let ((group (nnheader-file-to-group
-               (directory-file-name dir) nnml-directory)))
-    (setq nnml-group-alist
-         (delq (assoc group nnml-group-alist) nnml-group-alist))
+  (let* ((group (nnheader-file-to-group
+                (directory-file-name dir) nnml-directory))
+        (entry (assoc group nnml-group-alist))
+        (last (or (caadr entry) 0)))
+    (setq nnml-group-alist (delq entry nnml-group-alist))
     (push (list group
-               (cons (caar files)
-                     (let ((f files))
-                       (while (cdr f) (setq f (cdr f)))
-                       (caar f))))
+               (cons (or (caar files) (1+ last))
+                     (max last
+                          (or (let ((f files))
+                                (while (cdr f) (setq f (cdr f)))
+                                (caar f))
+                              0))))
          nnml-group-alist)))
 
 (defun nnml-generate-nov-file (dir files)