* gnus-srvr.el (gnus-tmp-how, gnus-tmp-name, gnus-tmp-where)
[gnus] / lisp / nnfolder.el
index 36e0571..a403f39 100644 (file)
@@ -1,9 +1,8 @@
 ;;; nnfolder.el --- mail folder access for Gnus
 
-;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1995-2014 Free Software Foundation, Inc.
 
-;; Author: Simon Josefsson <simon@josefsson.org> (adding MARKS)
+;; Author: Simon Josefsson <simon@josefsson.org>
 ;;      ShengHuo Zhu <zsh@cs.rochester.edu> (adding NOV)
 ;;      Scott Byer <byer@mv.us.adobe.com>
 ;;     Lars Magne Ingebrigtsen <larsi@gnus.org>
 
 ;;; Code:
 
-;; For Emacs < 22.2.
-(eval-and-compile
-  (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
-
 (require 'nnheader)
 (require 'message)
 (require 'nnmail)
   "The name of the nnfolder NOV directory.
 If nil, `nnfolder-directory' is used.")
 
-(defvoo nnfolder-marks-directory nil
-  "The name of the nnfolder MARKS directory.
-If nil, `nnfolder-directory' is used.")
-
 (defvoo nnfolder-active-file
     (nnheader-concat nnfolder-directory "active")
   "The name of the active file.")
@@ -135,21 +126,6 @@ all.  This may very well take some time.")
 
 (defvar nnfolder-nov-buffer-file-name nil)
 
-(defvoo nnfolder-marks-is-evil nil
-  "If non-nil, Gnus will never generate and use marks file for mail groups.
-Using marks files makes it possible to backup and restore mail groups
-separately from `.newsrc.eld'.  If you have, for some reason, set
-this to t, and want to set it to nil again, you should always remove
-the corresponding marks file (usually base nnfolder file name
-concatenated with `.mrk', but see `nnfolder-marks-file-suffix') for
-the group.  Then the marks file will be regenerated properly by Gnus.")
-
-(defvoo nnfolder-marks nil)
-
-(defvoo nnfolder-marks-file-suffix ".mrk")
-
-(defvar nnfolder-marks-modtime (gnus-make-hashtable))
-
 \f
 
 ;;; Interface functions
@@ -157,8 +133,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
 (nnoo-define-basics nnfolder)
 
 (deffoo nnfolder-retrieve-headers (articles &optional group server fetch-old)
-  (save-excursion
-    (set-buffer nntp-server-buffer)
+  (with-current-buffer nntp-server-buffer
     (erase-buffer)
     (let (article start stop num)
       (nnfolder-possibly-change-group group server)
@@ -233,9 +208,6 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
   (unless (or gnus-nov-is-evil nnfolder-nov-is-evil)
     (and nnfolder-nov-directory
         (gnus-make-directory nnfolder-nov-directory)))
-  (unless nnfolder-marks-is-evil
-    (and nnfolder-marks-directory
-        (gnus-make-directory nnfolder-marks-directory)))
   (cond
    ((not (file-exists-p nnfolder-directory))
     (nnfolder-close-server)
@@ -261,8 +233,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
 
 (deffoo nnfolder-request-article (article &optional group server buffer)
   (nnfolder-possibly-change-group group server)
-  (save-excursion
-    (set-buffer nnfolder-current-buffer)
+  (with-current-buffer nnfolder-current-buffer
     (goto-char (point-min))
     (when (nnfolder-goto-article article)
       (let (start stop)
@@ -291,7 +262,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
                                      (point) (point-at-eol)))
                    -1))))))))
 
-(deffoo nnfolder-request-group (group &optional server dont-check)
+(deffoo nnfolder-request-group (group &optional server dont-check info)
   (nnfolder-possibly-change-group group server t)
   (save-excursion
     (cond ((not (assoc group nnfolder-group-alist))
@@ -324,20 +295,20 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
   (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)))
+     'nnfolder 'nnfolder-save-all-buffers
+     nnfolder-directory group)))
+
+(defun nnfolder-save-all-buffers ()
+  (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))))))
 
 ;; 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
@@ -360,8 +331,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
              nnfolder-current-group (car inf))))
     (when (and nnfolder-current-buffer
               (buffer-name nnfolder-current-buffer))
-      (save-excursion
-       (set-buffer nnfolder-current-buffer)
+      (with-current-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
@@ -447,8 +417,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
        target)
     (nnmail-activate 'nnfolder)
 
-    (save-excursion
-      (set-buffer nnfolder-current-buffer)
+    (with-current-buffer nnfolder-current-buffer
       ;; Since messages are sorted in arrival order and expired in the
       ;; same order, we can stop as soon as we find a message that is
       ;; too old.
@@ -472,11 +441,11 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
                (let ((nnfolder-current-directory nil))
                  (when (functionp target)
                    (setq target (funcall target newsgroup)))
-                 (if (and target
-                          (or (gnus-request-group target)
-                              (gnus-request-create-group target)))
-                     (nnmail-expiry-target-group target newsgroup)
-                   (setq target nil))))
+                 (when (and target (not (eq target 'delete)))
+                   (if (or (gnus-request-group target)
+                           (gnus-request-create-group target))
+                       (nnmail-expiry-target-group target newsgroup)
+                     (setq target nil)))))
              (nnfolder-possibly-change-group newsgroup server))
            (when target
              (nnheader-message 5 "Deleting article %d in %s..."
@@ -492,17 +461,17 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
       (nnfolder-save-buffer)
       (nnfolder-adjust-min-active newsgroup)
       (nnfolder-save-active nnfolder-group-alist nnfolder-active-file)
+      (nnfolder-save-all-buffers)
       (gnus-sorted-difference articles (nreverse deleted-articles)))))
 
-(deffoo nnfolder-request-move-article (article group server accept-form 
+(deffoo nnfolder-request-move-article (article group server accept-form
                                               &optional last move-is-internal)
   (save-excursion
     (let ((buf (get-buffer-create " *nnfolder move*"))
          result)
       (and
        (nnfolder-request-article article group server)
-       (save-excursion
-        (set-buffer buf)
+       (with-current-buffer buf
         (erase-buffer)
         (insert-buffer-substring nntp-server-buffer)
         (goto-char (point-min))
@@ -552,7 +521,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
        (while (re-search-backward (concat "^" nnfolder-article-marker) nil t)
          (delete-region (point) (progn (forward-line 1) (point))))
        (when nnmail-cache-accepted-message-ids
-         (nnmail-cache-insert (nnmail-fetch-field "message-id") 
+         (nnmail-cache-insert (nnmail-fetch-field "message-id")
                               group
                               (nnmail-fetch-field "subject")
                               (nnmail-fetch-field "from")))
@@ -578,8 +547,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
 
 (deffoo nnfolder-request-replace-article (article group buffer)
   (nnfolder-possibly-change-group group)
-  (save-excursion
-    (set-buffer buffer)
+  (with-current-buffer buffer
     (goto-char (point-min))
     (if (not (looking-at "X-From-Line: "))
        (insert "From nobody " (current-time-string) "\n")
@@ -596,8 +564,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
       (nnfolder-delete-mail)
       (insert-buffer-substring buffer)
       (unless (or gnus-nov-is-evil nnfolder-nov-is-evil)
-       (save-excursion
-         (set-buffer buffer)
+       (with-current-buffer buffer
          (let ((headers (nnfolder-parse-head article
                                              (point-min) (point-max))))
            (with-current-buffer (nnfolder-open-nov group)
@@ -614,11 +581,9 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
       ()                               ; Don't delete the articles.
     ;; Delete the file that holds the group.
     (let ((data (nnfolder-group-pathname group))
-         (nov (nnfolder-group-nov-pathname group))
-         (mrk (nnfolder-group-marks-pathname group)))
+         (nov (nnfolder-group-nov-pathname group)))
       (ignore-errors (delete-file data))
-      (ignore-errors (delete-file nov))
-      (ignore-errors (delete-file mrk))))
+      (ignore-errors (delete-file nov))))
   ;; Remove the group from all structures.
   (setq nnfolder-group-alist
        (delq (assoc group nnfolder-group-alist) nnfolder-group-alist)
@@ -630,8 +595,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
 
 (deffoo nnfolder-request-rename-group (group new-name &optional server)
   (nnfolder-possibly-change-group group server)
-  (save-excursion
-    (set-buffer nnfolder-current-buffer)
+  (with-current-buffer nnfolder-current-buffer
     (and (file-writable-p buffer-file-name)
         (ignore-errors
           (let ((new-file (nnfolder-group-pathname new-name)))
@@ -640,11 +604,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
             (when (file-exists-p (nnfolder-group-nov-pathname group))
               (setq new-file (nnfolder-group-nov-pathname new-name))
               (gnus-make-directory (file-name-directory new-file))
-              (rename-file (nnfolder-group-nov-pathname group) new-file))
-            (when (file-exists-p (nnfolder-group-marks-pathname group))
-              (setq new-file (nnfolder-group-marks-pathname new-name))
-              (gnus-make-directory (file-name-directory new-file))
-              (rename-file (nnfolder-group-marks-pathname group) new-file)))
+              (rename-file (nnfolder-group-nov-pathname group) new-file)))
           t)
         ;; That went ok, so we change the internal structures.
         (let ((entry (assoc group nnfolder-group-alist)))
@@ -671,8 +631,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
         (marker (concat "\n" nnfolder-article-marker))
         (number "[0-9]+")
         (activemin (cdr active)))
-    (save-excursion
-      (set-buffer nnfolder-current-buffer)
+    (with-current-buffer nnfolder-current-buffer
       (goto-char (point-min))
       (while (and (search-forward marker nil t)
                  (re-search-forward number nil t))
@@ -925,7 +884,9 @@ deleted.  Point is left where the deleted region was."
              (active (or (cadr (assoc group nnfolder-group-alist))
                          (cons 1 0)))
              (scantime (assoc group nnfolder-scantime-alist))
-             (minid (lsh -1 -1))
+             (minid (or (and (boundp 'most-positive-fixnum)
+                             most-positive-fixnum)
+                        (lsh -1 -1)))
              maxid start end newscantime
              novbuf articles newnum
              buffer-read-only)
@@ -1039,6 +1000,28 @@ deleted.  Point is left where the deleted region was."
            (nnfolder-save-nov))
          (current-buffer))))))
 
+(defun nnfolder-recursive-directory-files (dir prefix)
+  (let ((files nil))
+    (dolist (file (directory-files dir))
+      (cond
+       ((or (file-symlink-p (expand-file-name file dir))
+           (member file '("." "..")))
+       ;; Ignore
+       )
+       ((file-directory-p (expand-file-name file dir))
+       (setq files (nconc (nnfolder-recursive-directory-files
+                           (expand-file-name file dir)
+                           (if prefix
+                               (concat prefix "." (directory-file-name file))
+                             (file-name-nondirectory file)))
+                          files)))
+       ((file-regular-p (expand-file-name file dir))
+       (push (if prefix