*** empty log message ***
[gnus] / lisp / nnfolder.el
index 337c139..3f8811f 100644 (file)
@@ -1,10 +1,10 @@
 ;;; nnfolder.el --- mail folder access for Gnus
-;; Copyright (C) 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc.
 
 ;; Author: Scott Byer <byer@mv.us.adobe.com>
 ;;     Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
 ;;     Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
-;; Keywords: news, mail
+;; Keywords: mail
 
 ;; This file is part of GNU Emacs.
 
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
 
 ;;; Commentary:
 
-;; For an overview of what the interface functions do, please see the
-;; Gnus sources.  
-
-;; Various enhancements by byer@mv.us.adobe.com (Scott Byer).
-
 ;;; Code:
 
 (require 'nnheader)
-(require 'rmail)
+(require 'message)
 (require 'nnmail)
+(require 'nnoo)
+(require 'cl)
+(require 'gnus-util)
+
+(nnoo-declare nnfolder)
 
-(defvar nnfolder-directory (expand-file-name "~/Mail/")
-  "The name of the mail box file in the users home directory.")
+(defvoo nnfolder-directory (expand-file-name message-directory)
+  "The name of the nnfolder directory.")
 
-(defvar nnfolder-active-file 
-  (concat (file-name-as-directory nnfolder-directory) "active")
+(defvoo nnfolder-active-file
+  (nnheader-concat nnfolder-directory "active")
   "The name of the active file.")
 
-;; I renamed this variable to somehting more in keeping with the general GNU
+;; I renamed this variable to something more in keeping with the general GNU
 ;; style. -SLB
 
-(defvar nnfolder-ignore-active-file nil
-  "If non-nil, causes nnfolder to do some extra work in order to determine the true active ranges of an mbox file.  
-Note that the active file is still saved, but it's values are not
-used.  This costs some extra time when scanning an mbox when opening
-it.")
-
-;; Note that this variable may not be completely implemented yet. -SLB
-
-(defvar nnfolder-always-close nil
-  "If non-nil, nnfolder attempts to only ever have one mbox open at a time.  
-This is a straight space/performance trade off, as the mboxes will have to 
-be scanned every time they are read in.  If nil (default), nnfolder will
-attempt to keep the buffers around (saving the nnfolder's buffer upon group 
-close, but not killing it), speeding some things up tremendously, especially
-such things as moving mail.  All buffers always get killed upon server close.")
-
-(defvar nnfolder-newsgroups-file 
-  (concat (file-name-as-directory  nnfolder-directory) "newsgroups")
+(defvoo nnfolder-ignore-active-file nil
+  "If non-nil, causes nnfolder to do some extra work in order to determine
+the true active ranges of an mbox file.  Note that the active file is still
+saved, but it's values are not used.  This costs some extra time when
+scanning an mbox when opening it.")
+
+(defvoo nnfolder-distrust-mbox nil
+  "If non-nil, causes nnfolder to not trust the user with respect to
+inserting unaccounted for mail in the middle of an mbox file.  This can greatly
+slow down scans, which now must scan the entire file for unmarked messages.
+When nil, scans occur forward from the last marked message, a huge
+time saver for large mailboxes.")
+
+(defvoo nnfolder-newsgroups-file
+  (concat (file-name-as-directory nnfolder-directory) "newsgroups")
   "Mail newsgroups description file.")
 
-(defvar nnfolder-get-new-mail t
-  "If non-nil, nnml will check the incoming mail file and split the mail.")
+(defvoo nnfolder-get-new-mail t
+  "If non-nil, nnfolder will check the incoming mail file and split the mail.")
 
-(defvar nnfolder-prepare-save-mail-hook nil
+(defvoo nnfolder-prepare-save-mail-hook nil
   "Hook run narrowed to an article before saving.")
 
+(defvoo nnfolder-save-buffer-hook nil
+  "Hook run before saving the nnfolder mbox buffer.")
+
+(defvoo nnfolder-inhibit-expiry nil
+  "If non-nil, inhibit expiry.")
+
 \f
 
-(defconst nnfolder-version "nnfolder 0.2"
+(defconst nnfolder-version "nnfolder 1.0"
   "nnfolder version.")
 
 (defconst nnfolder-article-marker "X-Gnus-Article-Number: "
   "String used to demarcate what the article number for a message is.")
 
-(defvar nnfolder-current-group nil)
-(defvar nnfolder-current-buffer nil)
-(defvar nnfolder-status-string "")
-(defvar nnfolder-group-alist nil)
-(defvar nnfolder-buffer-alist nil)
-
-(defmacro nnfolder-article-string (article)
-  (` (concat "\n" nnfolder-article-marker (int-to-string (, article)) " ")))
-
-\f
-
-(defvar nnfolder-current-server nil)
-(defvar nnfolder-server-alist nil)
-(defvar nnfolder-server-variables 
-  (list 
-   (list 'nnfolder-directory nnfolder-directory)
-   (list 'nnfolder-active-file nnfolder-active-file)
-   (list 'nnfolder-newsgroups-file nnfolder-newsgroups-file)
-   (list 'nnfolder-get-new-mail nnfolder-get-new-mail)
-   '(nnfolder-current-group nil)
-   '(nnfolder-current-buffer nil)
-   '(nnfolder-status-string "")
-   '(nnfolder-group-alist nil)
-   '(nnfolder-buffer-alist nil)))
+(defvoo nnfolder-current-group nil)
+(defvoo nnfolder-current-buffer nil)
+(defvoo nnfolder-status-string "")
+(defvoo nnfolder-group-alist nil)
+(defvoo nnfolder-buffer-alist nil)
+(defvoo nnfolder-scantime-alist nil)
+(defvoo nnfolder-active-timestamp nil)
 
 \f
 
 ;;; Interface functions
 
-(defun nnfolder-retrieve-headers (sequence &optional newsgroup server)
+(nnoo-define-basics nnfolder)
+
+(deffoo nnfolder-retrieve-headers (articles &optional group server fetch-old)
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
-    (let ((delim-string (concat "^" rmail-unix-mail-delimiter))
-         article art-string start stop)
-      (nnfolder-possibly-change-group newsgroup)
-      (set-buffer nnfolder-current-buffer)
-      (goto-char (point-min))
-      (if (stringp (car sequence))
-         'headers
-       (while sequence
-         (setq article (car sequence))
-         (setq art-string (nnfolder-article-string article))
-         (set-buffer nnfolder-current-buffer)
-         (if (or (search-forward art-string nil t)
-                 ;; Don't search the whole file twice!  Also, articles
-                 ;; probably have some locality by number, so searching
-                 ;; backwards will be faster.  Especially if we're at the
-                 ;; beginning of the buffer :-). -SLB
-                 (search-backward art-string nil t))
-             (progn
-               (setq start (or (re-search-backward delim-string nil t)
-                               (point)))
-               (search-forward "\n\n" nil t)
-               (setq stop (1- (point)))
-               (set-buffer nntp-server-buffer)
-               (insert (format "221 %d Article retrieved.\n" article))
-               (insert-buffer-substring nnfolder-current-buffer start stop)
-               (goto-char (point-max))
-               (insert ".\n")))
-         (setq sequence (cdr sequence)))
-
-       ;; Fold continuation lines.
-       (set-buffer nntp-server-buffer)
+    (let (article start stop)
+      (nnfolder-possibly-change-group group server)
+      (when nnfolder-current-buffer
+       (set-buffer nnfolder-current-buffer)
        (goto-char (point-min))
-       (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
-         (replace-match " " t t))
-       'headers))))
-
-(defun nnfolder-open-server (server &optional defs)
-  (nnheader-init-server-buffer)
-  (if (equal server nnfolder-current-server)
-      t
-    (if nnfolder-current-server
-       (setq nnfolder-server-alist 
-             (cons (list nnfolder-current-server
-                         (nnheader-save-variables nnfolder-server-variables))
-                   nnfolder-server-alist)))
-    (let ((state (assoc server nnfolder-server-alist)))
-      (if state 
-         (progn
-           (nnheader-restore-variables (nth 1 state))
-           (setq nnfolder-server-alist (delq state nnfolder-server-alist)))
-       (nnheader-set-init-variables nnfolder-server-variables defs)))
-    (setq nnfolder-current-server server)))
-
-(defun nnfolder-close-server (&optional server)
-  t)
-
-(defun nnfolder-server-opened (&optional server)
-  (and (equal server nnfolder-current-server)
-       nntp-server-buffer
-       (buffer-name nntp-server-buffer)))
-
-(defun nnfolder-request-close ()
+       (if (stringp (car articles))
+           'headers
+         (while (setq article (pop articles))
+           (set-buffer nnfolder-current-buffer)
+           (when (nnfolder-goto-article article)
+             (setq start (point))
+             (search-forward "\n\n" nil t)
+             (setq stop (1- (point)))
+             (set-buffer nntp-server-buffer)
+             (insert (format "221 %d Article retrieved.\n" article))
+             (insert-buffer-substring nnfolder-current-buffer start stop)
+             (goto-char (point-max))
+             (insert ".\n")))
+
+         (set-buffer nntp-server-buffer)
+         (nnheader-fold-continuation-lines)
+         'headers)))))
+
+(deffoo nnfolder-open-server (server &optional defs)
+  (nnoo-change-server 'nnfolder server defs)
+  (nnmail-activate 'nnfolder t)
+  (gnus-make-directory nnfolder-directory)
+  (cond
+   ((not (file-exists-p nnfolder-directory))
+    (nnfolder-close-server)
+    (nnheader-report 'nnfolder "Couldn't create directory: %s"
+                    nnfolder-directory))
+   ((not (file-directory-p (file-truename nnfolder-directory)))
+    (nnfolder-close-server)
+    (nnheader-report 'nnfolder "Not a directory: %s" nnfolder-directory))
+   (t
+    (nnmail-activate 'nnfolder)
+    (nnheader-report 'nnfolder "Opened server %s using directory %s"
+                    server nnfolder-directory)
+    t)))
+
+(deffoo nnfolder-request-close ()
   (let ((alist nnfolder-buffer-alist))
     (while alist
-      (nnfolder-close-group (car (car alist)) nil t)
+      (nnfolder-close-group (caar alist) nil t)
       (setq alist (cdr alist))))
+  (nnoo-close-server 'nnfolder)
   (setq nnfolder-buffer-alist nil
        nnfolder-group-alist nil))
 
-(defun nnfolder-status-message (&optional server)
-  nnfolder-status-string)
-
-(defun nnfolder-request-article (article &optional newsgroup server buffer)
-  (nnfolder-possibly-change-group newsgroup)
-  (if (stringp article)
-      nil
-    (save-excursion
-      (set-buffer nnfolder-current-buffer)
-      (goto-char (point-min))
-      (if (search-forward (nnfolder-article-string article) nil t)
-         (let (start stop)
-           (re-search-backward (concat "^" rmail-unix-mail-delimiter) nil t)
-           (setq start (point))
-           (forward-line 1)
-           (or (and (re-search-forward 
-                     (concat "^" rmail-unix-mail-delimiter) nil t)
+(deffoo nnfolder-request-article (article &optional group server buffer)
+  (nnfolder-possibly-change-group group server)
+  (save-excursion
+    (set-buffer nnfolder-current-buffer)
+    (goto-char (point-min))
+    (when (nnfolder-goto-article article)
+      (let (start stop)
+       (setq start (point))
+       (forward-line 1)
+       (unless (and (nnmail-search-unix-mail-delim)
                     (forward-line -1))
-               (goto-char (point-max)))
-           (setq stop (point))
-           (let ((nntp-server-buffer (or buffer nntp-server-buffer)))
-             (set-buffer nntp-server-buffer)
-             (erase-buffer)
-             (insert-buffer-substring nnfolder-current-buffer start stop)
-             (goto-char (point-min))
-             (while (looking-at "From ")
-               (delete-char 5)
-               (insert "X-From-Line: ")
-               (forward-line 1))
-             t))))))
-
-(defun nnfolder-request-group (group &optional server dont-check)
+         (goto-char (point-max)))
+       (setq stop (point))
+       (let ((nntp-server-buffer (or buffer nntp-server-buffer)))
+         (set-buffer nntp-server-buffer)
+         (erase-buffer)
+         (insert-buffer-substring nnfolder-current-buffer start stop)
+         (goto-char (point-min))
+         (while (looking-at "From ")
+           (delete-char 5)
+           (insert "X-From-Line: ")
+           (forward-line 1))
+         (if (numberp article)
+             (cons nnfolder-current-group article)
+           (goto-char (point-min))
+           (search-forward (concat "\n" nnfolder-article-marker))
+           (cons nnfolder-current-group
+                 (string-to-int
+                  (buffer-substring
+                   (point) (progn (end-of-line) (point)))))))))))
+
+(deffoo nnfolder-request-group (group &optional server dont-check)
+  (nnfolder-possibly-change-group group server t)
   (save-excursion
-    (nnfolder-possibly-change-group group)
-    (and (assoc group nnfolder-group-alist)
-        (progn
-          (if dont-check
-              t
-            (nnfolder-get-new-mail group))
-          (let* ((active (assoc group nnfolder-group-alist))
-                 (group (car active))
-                 (range (car (cdr active)))
-                 (minactive (car range))
-                 (maxactive (cdr range)))
-            ;; I've been getting stray 211 lines in my nnfolder active
-            ;; file.  So, let's make sure that doesn't happen. -SLB
-            (set-buffer nntp-server-buffer)
-            (erase-buffer)
-            (insert (format "211 %d %d %d %s\n" 
-                            (1+ (- maxactive minactive))
-                            minactive maxactive group))
-            t)))))
+    (if (not (assoc group nnfolder-group-alist))
+       (nnheader-report 'nnfolder "No such group: %s" group)
+      (if dont-check
+         (progn
+           (nnheader-report 'nnfolder "Selected group %s" group)
+           t)
+       (let* ((active (assoc group nnfolder-group-alist))
+              (group (car active))
+              (range (cadr active)))
+         (cond
+          ((null active)
+           (nnheader-report 'nnfolder "No such group: %s" group))
+          ((null nnfolder-current-group)
+           (nnheader-report 'nnfolder "Empty group: %s" group))
+          (t
+           (nnheader-report 'nnfolder "Selected group %s" group)
+           (nnheader-insert "211 %d %d %d %s\n"
+                            (1+ (- (cdr range) (car range)))
+                            (car range) (cdr range) group))))))))
+
+(deffoo nnfolder-request-scan (&optional group server)
+  (nnfolder-possibly-change-group nil server)
+  (when nnfolder-get-new-mail
+    (nnfolder-possibly-change-group group server)
+    (nnmail-get-new-mail
+     'nnfolder
+     (lambda ()
+       (let ((bufs nnfolder-buffer-alist))
+        (save-excursion
+          (while bufs
+            (if (not (gnus-buffer-live-p (nth 1 (car bufs))))
+                (setq nnfolder-buffer-alist
+                      (delq (car bufs) nnfolder-buffer-alist))
+              (set-buffer (nth 1 (car bufs)))
+              (nnfolder-save-buffer)
+              (kill-buffer (current-buffer)))
+            (setq bufs (cdr bufs))))))
+     nnfolder-directory
+     group)))
 
 ;; Don't close the buffer if we're not shutting down the server.  This way,
 ;; we can keep the buffer in the group buffer cache, and not have to grovel
 ;; over the buffer again unless we add new mail to it or modify it in some
 ;; way.
 
-(defun nnfolder-close-group (group &optional server force)
+(deffoo nnfolder-close-group (group &optional server force)
   ;; Make sure we _had_ the group open.
-  (if (or (assoc group nnfolder-buffer-alist)
-         (equal group nnfolder-current-group))
-      (progn
-       (nnfolder-possibly-change-group group)
-       (save-excursion
-         (set-buffer nnfolder-current-buffer)
-         ;; If the buffer was modified, write the file out now.
-         (and (buffer-modified-p) (save-buffer))
-         (if (or force
-                 nnfolder-always-close)
-             ;; If we're shutting the server down, we need to kill the
-             ;; buffer and remove it from the open buffer list.  Or, of
-             ;; course, if we're trying to minimize our space impact.
-             (progn
-               (kill-buffer (current-buffer))
-               (setq nnfolder-buffer-alist (delq (assoc group 
-                                                        nnfolder-buffer-alist)
-                                                 nnfolder-buffer-alist)))))))
+  (when (or (assoc group nnfolder-buffer-alist)
+           (equal group nnfolder-current-group))
+    (let ((inf (assoc group nnfolder-buffer-alist)))
+      (when inf
+       (when (and nnfolder-current-group
+                  nnfolder-current-buffer)
+         (push (list nnfolder-current-group nnfolder-current-buffer)
+               nnfolder-buffer-alist))
+       (setq nnfolder-buffer-alist
+             (delq inf nnfolder-buffer-alist))
+       (setq nnfolder-current-buffer (cadr inf)
+             nnfolder-current-group (car inf))))
+    (when (and nnfolder-current-buffer
+              (buffer-name nnfolder-current-buffer))
+      (save-excursion
+       (set-buffer nnfolder-current-buffer)
+       ;; If the buffer was modified, write the file out now.
+       (nnfolder-save-buffer)
+       ;; If we're shutting the server down, we need to kill the
+       ;; buffer and remove it from the open buffer list.  Or, of
+       ;; course, if we're trying to minimize our space impact.
+       (kill-buffer (current-buffer))
+       (setq nnfolder-buffer-alist (delq (assoc group nnfolder-buffer-alist)
+                                         nnfolder-buffer-alist)))))
   (setq nnfolder-current-group nil
        nnfolder-current-buffer nil)
   t)
 
-(defun nnfolder-request-create-group (group &optional server) 
-  (nnfolder-request-list)
-  (setq nnfolder-group-alist (nnmail-get-active))
-  (or (assoc group nnfolder-group-alist)
-      (progn
-       (setq nnfolder-group-alist 
-             (cons (list group (cons 0 0)) nnfolder-group-alist))
-       (nnmail-save-active nnfolder-group-alist nnfolder-active-file)))
+(deffoo nnfolder-request-create-group (group &optional server args)
+  (nnfolder-possibly-change-group nil server)
+  (nnmail-activate 'nnfolder)
+  (when group
+    (unless (assoc group nnfolder-group-alist)
+      (push (list group (cons 1 0)) nnfolder-group-alist)
+      (nnmail-save-active nnfolder-group-alist nnfolder-active-file)
+      (nnfolder-read-folder group)))
   t)
 
-(defun nnfolder-request-list (&optional server)
-  (if server (nnfolder-get-new-mail))
+(deffoo nnfolder-request-list (&optional server)
+  (nnfolder-possibly-change-group nil server)
   (save-excursion
-    (or nnfolder-group-alist
-       (nnmail-find-file nnfolder-active-file)
-       (progn
-         (setq nnfolder-group-alist (nnmail-get-active))
-         (nnmail-save-active nnfolder-group-alist nnfolder-active-file)
-         (nnmail-find-file nnfolder-active-file)))))
-
-(defun nnfolder-request-newgroups (date &optional server)
+    (let ((nnmail-file-coding-system nnmail-active-file-coding-system)
+         (pathname-coding-system 'binary))
+      (nnmail-find-file nnfolder-active-file)
+      (setq nnfolder-group-alist (nnmail-get-active)))
+    t))
+
+(deffoo nnfolder-request-newgroups (date &optional server)
+  (nnfolder-possibly-change-group nil server)
   (nnfolder-request-list server))
 
-(defun nnfolder-request-list-newsgroups (&optional server)
+(deffoo nnfolder-request-list-newsgroups (&optional server)
+  (nnfolder-possibly-change-group nil server)
   (save-excursion
     (nnmail-find-file nnfolder-newsgroups-file)))
 
-(defun nnfolder-request-post (&optional server)
-  (mail-send-and-exit nil))
-
-(defalias 'nnfolder-request-post-buffer 'nnmail-request-post-buffer)
-
-(defun nnfolder-request-expire-articles 
+(deffoo nnfolder-request-expire-articles
   (articles newsgroup &optional server force)
-  (nnfolder-possibly-change-group newsgroup)
-  (let* ((days (or (and nnmail-expiry-wait-function
-                       (funcall nnmail-expiry-wait-function newsgroup))
-                  nnmail-expiry-wait))
-        (is-old t)
+  (nnfolder-possibly-change-group newsgroup server)
+  (let* ((is-old t)
         rest)
-    (save-excursion 
+    (nnmail-activate 'nnfolder)
+
+    (save-excursion
       (set-buffer nnfolder-current-buffer)
-      (while articles
+      (while (and articles is-old)
        (goto-char (point-min))
-       (if (search-forward (nnfolder-article-string (car articles)) nil t)
-           (if (or force
-                   (setq is-old
-                         (> (nnmail-days-between 
-                             (current-time-string)
-                             (buffer-substring 
-                              (point) (progn (end-of-line) (point))))
-                            days)))
-               (progn
-                 (and gnus-verbose-backends
-                      (message "Deleting: %s" (car articles)))
-                 (nnfolder-delete-mail))
-             (setq rest (cons (car articles) rest))))
+       (when (nnfolder-goto-article (car articles))
+         (if (setq is-old
+                   (nnmail-expired-article-p
+                    newsgroup
+                    (buffer-substring
+                     (point) (progn (end-of-line) (point)))
+                    force nnfolder-inhibit-expiry))
+             (progn
+               (nnheader-message 5 "Deleting article %d..."
+                                 (car articles) newsgroup)
+               (nnfolder-delete-mail))
+           (push (car articles) rest)))
        (setq articles (cdr articles)))
-      (and (buffer-modified-p) (save-buffer))
-      ;; Find the lowest active article in this group.
-      (let* ((active (car (cdr (assoc newsgroup nnfolder-group-alist))))
-            (marker (concat "\n" nnfolder-article-marker))
-            (number "[0-9]+")
-            (activemin (cdr active)))
-       (goto-char (point-min))
-       (while (and (search-forward marker nil t)
-                   (re-search-forward number nil t))
-         (setq activemin (min activemin
-                              (string-to-number (buffer-substring
-                                                 (match-beginning 0)
-                                                 (match-end 0))))))
-       (setcar active activemin))
+      (unless nnfolder-inhibit-expiry
+       (nnheader-message 5 "Deleting articles...done"))
+      (nnfolder-save-buffer)
+      (nnfolder-adjust-min-active newsgroup)
       (nnmail-save-active nnfolder-group-alist nnfolder-active-file)
       (nconc rest articles))))
 
-(defun nnfolder-request-move-article
-  (article group server accept-form &optional last)
-  (nnfolder-possibly-change-group group)
-  (let ((buf (get-buffer-create " *nnfolder move*"))
-       result)
-    (and 
-     (nnfolder-request-article article group server)
-     (save-excursion
-       (set-buffer buf)
-       (buffer-disable-undo (current-buffer))
-       (erase-buffer)
-       (insert-buffer-substring nntp-server-buffer)
-       (goto-char (point-min))
-       (while (re-search-forward 
-              "^X-Gnus-Newsgroup:" 
-              (save-excursion (search-forward "\n\n" nil t) (point)) t)
-        (delete-region (progn (beginning-of-line) (point))
-                       (progn (forward-line 1) (point))))
-       (setq result (eval accept-form))
-       (kill-buffer buf)
-       result)
-     (save-excursion
-       (nnfolder-possibly-change-group group)
-       (set-buffer nnfolder-current-buffer)
-       (goto-char (point-min))
-       (if (search-forward (nnfolder-article-string article) nil t)
+(deffoo nnfolder-request-move-article (article group server
+                                              accept-form &optional last)
+  (save-excursion
+    (let ((buf (get-buffer-create " *nnfolder move*"))
+         result)
+      (and
+       (nnfolder-request-article article group server)
+       (save-excursion
+        (set-buffer buf)
+        (buffer-disable-undo (current-buffer))
+        (erase-buffer)
+        (insert-buffer-substring nntp-server-buffer)
+        (goto-char (point-min))
+        (while (re-search-forward
+                (concat "^" nnfolder-article-marker)
+                (save-excursion (search-forward "\n\n" nil t) (point)) t)
+          (delete-region (progn (beginning-of-line) (point))
+                         (progn (forward-line 1) (point))))
+        (setq result (eval accept-form))
+        (kill-buffer buf)
+        result)
+       (save-excursion
+        (nnfolder-possibly-change-group group server)
+        (set-buffer nnfolder-current-buffer)
+        (goto-char (point-min))
+        (when (nnfolder-goto-article article)
           (nnfolder-delete-mail))
-       (and last 
-           (buffer-modified-p)
-           (save-buffer))))
-    result))
+        (when last
+          (nnfolder-save-buffer)
+          (nnfolder-adjust-min-active group)
+          (nnmail-save-active nnfolder-group-alist nnfolder-active-file))))
+      result)))
 
-(defun nnfolder-request-accept-article (group &optional last)
-  (nnfolder-possibly-change-group group)
-  (let ((buf (current-buffer))
-       result)
-    (goto-char (point-min))
-    (if (looking-at "X-From-Line: ")
-       (replace-match "From ")
-      (insert "From nobody " (current-time-string) "\n"))
-    (and 
-     (nnfolder-request-list)
-     (save-excursion
-       (set-buffer buf)
-       (goto-char (point-min))
-       (search-forward "\n\n" nil t)
-       (forward-line -1)
-       (while (re-search-backward "^X-Gnus-Newsgroup: " nil t)
-        (delete-region (point) (progn (forward-line 1) (point))))
-       (setq result (car (nnfolder-save-mail (and (stringp group) group)))))
-     (save-excursion
-       (set-buffer nnfolder-current-buffer)
-       (and last (buffer-modified-p) (save-buffer))))
-    (nnmail-save-active nnfolder-group-alist nnfolder-active-file)
-    result))
+(deffoo nnfolder-request-accept-article (group &optional server last)
+  (save-excursion
+    (nnfolder-possibly-change-gr