*** empty log message ***
[gnus] / lisp / nnml.el
index fd74ec0..ed3e365 100644 (file)
@@ -1,7 +1,7 @@
 ;;; nnml.el --- mail spool access for Gnus
-;; Copyright (C) 1995,96,97 Free Software Foundation, Inc.
+;; Copyright (C) 1995,96,97,98,99 Free Software Foundation, Inc.
 
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;; Keywords: news, mail
 
@@ -84,6 +84,10 @@ all.  This may very well take some time.")
 
 (defvoo nnml-generate-active-function 'nnml-generate-active-info)
 
+(defvar nnml-nov-buffer-file-name nil)
+
+(defvoo nnml-file-coding-system nnmail-file-coding-system-1)
+
 \f
 
 ;;; Interface functions.
@@ -138,9 +142,7 @@ all.  This may very well take some time.")
 (deffoo nnml-open-server (server &optional defs)
   (nnoo-change-server 'nnml server defs)
   (when (not (file-exists-p nnml-directory))
-    (condition-case ()
-       (make-directory nnml-directory t)
-      (error)))
+    (ignore-errors (make-directory nnml-directory t)))
   (cond
    ((not (file-exists-p nnml-directory))
     (nnml-close-server)
@@ -161,8 +163,6 @@ all.  This may very well take some time.")
 (deffoo nnml-request-article (id &optional group server buffer)
   (nnml-possibly-change-directory group server)
   (let* ((nntp-server-buffer (or buffer nntp-server-buffer))
-        ;; 1997/8/12 by MORIOKA Tomohiko
-        ;;     for XEmacs/mule.
         (pathname-coding-system 'binary)
         path gpath group-num)
     (if (stringp id)
@@ -183,7 +183,9 @@ all.  This may very well take some time.")
       (nnheader-report 'nnml "No such file: %s" path))
      ((file-directory-p path)
       (nnheader-report 'nnml "File is a directory: %s" path))
-     ((not (save-excursion (nnmail-find-file path)))
+     ((not (save-excursion (let ((nnmail-file-coding-system
+                                 nnml-file-coding-system))
+                            (nnmail-find-file path))))
       (nnheader-report 'nnml "Couldn't read file: %s" path))
      (t
       (nnheader-report 'nnml "Article %s retrieved" id)
@@ -225,8 +227,16 @@ all.  This may very well take some time.")
   t)
 
 (deffoo nnml-request-create-group (group &optional server args)
+  (nnml-possibly-change-directory nil server)
   (nnmail-activate 'nnml)
-  (unless (assoc group nnml-group-alist)
+  (cond
+   ((assoc group nnml-group-alist)
+    t)
+   ((and (file-exists-p (nnmail-group-pathname group nnml-directory))
+        (not (file-directory-p (nnmail-group-pathname group nnml-directory))))
+    (nnheader-report 'nnml "%s is a file"
+                    (nnmail-group-pathname group nnml-directory)))
+   (t
     (let (active)
       (push (list group (setq active (cons 1 0)))
            nnml-group-alist)
@@ -236,17 +246,14 @@ all.  This may very well take some time.")
        (when articles
          (setcar active (apply 'min articles))
          (setcdr active (apply 'max articles))))
-      (nnmail-save-active nnml-group-alist nnml-active-file)))
-  t)
+      (nnmail-save-active nnml-group-alist nnml-active-file)
+      t))))
 
 (deffoo nnml-request-list (&optional server)
   (save-excursion
-    ;; 1997/8/12 by MORIOKA Tomohiko
-    ;; for XEmacs/mule.
     (let ((nnmail-file-coding-system nnmail-active-file-coding-system)
-         (pathname-coding-system 'binary)) ; for XEmacs/mule
-      (nnmail-find-file nnml-active-file)
-      )
+         (pathname-coding-system 'binary))
+      (nnmail-find-file nnml-active-file))
     (setq nnml-group-alist (nnmail-get-active))
     t))
 
@@ -266,6 +273,11 @@ all.  This may very well take some time.")
        article rest mod-time number)
     (nnmail-activate 'nnml)
 
+    (setq active-articles (sort active-articles '<))
+    ;; Articles not listed in active-articles are already gone,
+    ;; so don't try to expire them.
+    (setq articles (gnus-sorted-intersection articles active-articles))
+
     (while (and articles is-old)
       (when (setq article (nnml-article-to-file (setq number (pop articles))))
        (when (setq mod-time (nth 5 (file-attributes article)))
@@ -354,16 +366,14 @@ all.  This may very well take some time.")
     (let ((chars (nnmail-insert-lines))
          (art (concat (int-to-string article) "\t"))
          headers)
-      (when (condition-case ()
-               (progn
-                 (nnmail-write-region
-                  (point-min) (point-max)
-                  (or (nnml-article-to-file article)
-                      (concat nnml-current-directory
-                              (int-to-string article)))
-                  nil (if (nnheader-be-verbose 5) nil 'nomesg))
-                 t)
-             (error nil))
+      (when (ignore-errors
+             (nnmail-write-region
+              (point-min) (point-max)
+              (or (nnml-article-to-file article)
+                  (concat nnml-current-directory
+                          (int-to-string article)))
+              nil (if (nnheader-be-verbose 5) nil 'nomesg))
+             t)
        (setq headers (nnml-parse-head chars article))
        ;; Replace the NOV line in the NOV file.
        (save-excursion
@@ -404,9 +414,7 @@ all.  This may very well take some time.")
          (nnheader-message 5 "Deleting article %s in %s..." article group)
          (funcall nnmail-delete-file-function article))))
     ;; Try to delete the directory itself.
-    (condition-case ()
-       (delete-directory nnml-current-directory)
-      (error nil)))
+    (ignore-errors (delete-directory nnml-current-directory)))
   ;; Remove the group from all structures.
   (setq nnml-group-alist
        (delq (assoc group nnml-group-alist) nnml-group-alist)
@@ -420,11 +428,9 @@ all.  This may very well take some time.")
   (nnml-possibly-change-directory group server)
   (let ((new-dir (nnmail-group-pathname new-name nnml-directory))
        (old-dir (nnmail-group-pathname group nnml-directory)))
-    (when (condition-case ()
-             (progn
-               (make-directory new-dir t)
-               t)
-           (error nil))
+    (when (ignore-errors
+           (make-directory new-dir t)
+           t)
       ;; We move the articles file by file instead of renaming
       ;; the directory -- there may be subgroups in this group.
       ;; One might be more clever, I guess.
@@ -439,9 +445,7 @@ all.  This may very well take some time.")
        (when (file-exists-p overview)
          (rename-file overview (concat new-dir nnml-nov-file-name))))
       (when (<= (length (directory-files old-dir)) 2)
-       (condition-case ()
-           (delete-directory old-dir)
-         (error nil)))
+       (ignore-errors (delete-directory old-dir)))
       ;; That went ok, so we change the internal structures.
       (let ((entry (assoc group nnml-group-alist)))
        (when entry
@@ -459,7 +463,7 @@ all.  This may very well take some time.")
      ((not (file-exists-p file))
       (nnheader-report 'nnml "File %s does not exist" file))
      (t
-      (nnheader-temp-write file
+      (with-temp-file file
        (nnheader-insert-file-contents file)
        (nnmail-replace-status name value))
       t))))
@@ -475,8 +479,8 @@ all.  This may very well take some time.")
       ;; Just to make sure nothing went wrong when reading over NFS --
       ;; check once more.
       (when (file-exists-p
-            (setq file (concat nnml-current-directory "/"
-                               (number-to-string article))))
+            (setq file (expand-file-name (number-to-string article)
+                                         nnml-current-directory)))
        (nnml-update-file-alist t)
        file))))
 
@@ -493,7 +497,6 @@ all.  This may very well take some time.")
 (defun nnml-find-group-number (id)
   (save-excursion
     (set-buffer (get-buffer-create " *nnml id*"))
-    (buffer-disable-undo (current-buffer))
     (let ((alist nnml-group-alist)
          number)
       ;; We want to look through all .overview files, but we want to
@@ -528,9 +531,7 @@ all.  This may very well take some time.")
          (setq found t)
          ;; We return the article number.
          (setq number
-               (condition-case ()
-                   (read (current-buffer))
-                 (error nil)))))
+               (ignore-errors (read (current-buffer))))))
       number)))
 
 (defun nnml-retrieve-headers-with-nov (articles &optional fetch-old)
@@ -566,15 +567,10 @@ all.  This may very well take some time.")
       (file-exists-p nnml-current-directory))))
 
 (defun nnml-possibly-create-directory (group)
-  (let (dir dirs)
-    (setq dir (nnmail-group-pathname group nnml-directory))
-    (while (not (file-directory-p dir))
-      (push dir dirs)
-      (setq dir (file-name-directory (directory-file-name dir))))
-    (while dirs
-      (make-directory (directory-file-name (car dirs)))
-      (nnheader-message 5 "Creating mail directory %s" (car dirs))
-      (setq dirs (cdr dirs)))))
+  (let ((dir (nnmail-group-pathname group nnml-directory)))
+    (unless (file-exists-p dir)
+      (make-directory (directory-file-name dir) t)
+      (nnheader-message 5 "Creating mail directory %s" dir))))
 
 (defun nnml-save-mail (group-art)
   "Called narrowed to an article."
@@ -657,10 +653,10 @@ all.  This may very well take some time.")
   "Parse the head of the current buffer."
   (save-excursion
     (save-restriction
-      (goto-char (point-min))
-      (narrow-to-region
-       (point)
-       (1- (or (search-forward "\n\n" nil t) (point-max))))
+      (unless (zerop (buffer-size))
+       (narrow-to-region
+        (goto-char (point-min))
+        (if (search-forward "\n\n" nil t) (1- (point)) (point-max))))
       ;; Fold continuation lines.
       (goto-char (point-min))
       (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
@@ -674,12 +670,15 @@ all.  This may very well take some time.")
 
 (defun nnml-open-nov (group)
   (or (cdr (assoc group nnml-nov-buffer-alist))
-      (let ((buffer (nnheader-find-file-noselect
-                    (concat (nnmail-group-pathname group nnml-directory)
-                            nnml-nov-file-name))))
+      (let ((buffer (get-buffer-create (format " *nnml overview %s*" group))))
        (save-excursion
          (set-buffer buffer)
-         (buffer-disable-undo (current-buffer)))
+         (set (make-local-variable 'nnml-nov-buffer-file-name)
+              (concat (nnmail-group-pathname group nnml-directory)
+                      nnml-nov-file-name))
+         (erase-buffer)
+         (when (file-exists-p nnml-nov-buffer-file-name)
+           (nnheader-insert-file-contents nnml-nov-buffer-file-name)))
        (push (cons group buffer) nnml-nov-buffer-alist)
        buffer)))
 
@@ -689,7 +688,8 @@ all.  This may very well take some time.")
       (when (buffer-name (cdar nnml-nov-buffer-alist))
        (set-buffer (cdar nnml-nov-buffer-alist))
        (when (buffer-modified-p)
-         (nnmail-write-region 1 (point-max) (buffer-file-name) nil 'nomesg))
+         (nnmail-write-region 1 (point-max) nnml-nov-buffer-file-name
+                              nil 'nomesg))
        (set-buffer-modified-p nil)
        (kill-buffer (current-buffer)))
       (setq nnml-nov-buffer-alist (cdr nnml-nov-buffer-alist)))))
@@ -719,13 +719,18 @@ all.  This may very well take some time.")
     (let ((dirs (directory-files dir t nil t))
          dir)
       (while (setq dir (pop dirs))
-       (when (and (not (member (file-name-nondirectory dir) '("." "..")))
+       (when (and (not (string-match "^\\." (file-name-nondirectory dir)))
                   (file-directory-p dir))
          (nnml-generate-nov-databases-1 dir seen))))
     ;; Do this directory.
     (let ((files (sort (nnheader-article-to-file-alist dir)
                       'car-less-than-car)))
-      (when files
+      (if (not files)
+         (let* ((group (nnheader-file-to-group
+                        (directory-file-name dir) nnml-directory))
+                (info (cadr (assoc group nnml-group-alist))))
+           (when info
+             (setcar info (1+ (cdr info)))))
        (funcall nnml-generate-active-function dir)
        ;; Generate the nov file.
        (nnml-generate-nov-file dir files)
@@ -754,7 +759,7 @@ all.  This may very well take some time.")
     (save-excursion
       ;; Init the nov buffer.
       (set-buffer nov-buffer)
-      (buffer-disable-undo (current-buffer))
+      (buffer-disable-undo)
       (erase-buffer)
       (set-buffer nntp-server-buffer)
       ;; Delete the old NOV file.