gnus-registry.el: Correct function argument order.
[gnus] / lisp / nnml.el
index 7744f04..8275e19 100644 (file)
@@ -1,16 +1,19 @@
 ;;; nnml.el --- mail spool access for Gnus
-;; Copyright (C) 1995,96,97 Free Software Foundation, Inc.
 
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
-;;     Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
+;; Copyright (C) 1995-2015 Free Software Foundation, Inc.
+
+;; Authors: Didier Verna <didier@xemacs.org> (adding compaction)
+;;     Simon Josefsson <simon@josefsson.org>
+;;     Lars Magne Ingebrigtsen <larsi@gnus.org>
+;;     Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;; Keywords: news, mail
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 ;; Based on nnspool.el by Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>.
 ;; For an overview of what the interface functions do, please see the
-;; Gnus sources.  
+;; Gnus sources.
 
 ;;; Code:
 
+(require 'gnus)
 (require 'nnheader)
 (require 'nnmail)
 (require 'nnoo)
-(require 'cl)
+(eval-when-compile (require 'cl))
+
+;; FIXME first is unused in this file.
+(autoload 'gnus-article-unpropagatable-p "gnus-sum")
+(autoload 'gnus-backlog-remove-article "gnus-bcklg")
 
 (nnoo-declare nnml)
 
 (defvoo nnml-directory message-directory
-  "Mail spool directory.")
+  "Spool directory for the nnml mail backend.")
 
-(defvoo nnml-active-file 
-  (concat (file-name-as-directory nnml-directory) "active")
+(defvoo nnml-active-file
+    (expand-file-name "active" nnml-directory)
   "Mail active file.")
 
-(defvoo nnml-newsgroups-file 
-  (concat (file-name-as-directory nnml-directory) "newsgroups")
+(defvoo nnml-newsgroups-file
+    (expand-file-name "newsgroups" nnml-directory)
   "Mail newsgroups description file.")
 
 (defvoo nnml-get-new-mail t
   "If non-nil, nnml will check the incoming mail file and split the mail.")
 
 (defvoo nnml-nov-is-evil nil
-  "If non-nil, Gnus will never generate and use nov databases for mail groups.
+  "If non-nil, Gnus will never generate and use nov databases for mail spools.
 Using nov databases will speed up header fetching considerably.
 This variable shouldn't be flipped much.  If you have, for some reason,
 set this to t, and want to set it to nil again, you should always run
@@ -66,6 +72,19 @@ all.  This may very well take some time.")
 (defvoo nnml-inhibit-expiry nil
   "If non-nil, inhibit expiry.")
 
+(defvoo nnml-use-compressed-files nil
+  "If non-nil, allow using compressed message files.
+
+If it is a string, use it as the file extension which specifies
+the compression program.  You can set it to \".bz2\" if your Emacs
+supports auto-compression using the bzip2 program.  A value of t
+is equivalent to \".gz\".")
+
+(defvoo nnml-compressed-files-size-threshold 1000
+  "Default size threshold for compressed message files.
+Message files with bodies larger than that many characters will
+be automatically compressed if `nnml-use-compressed-files' is
+non-nil.")
 
 \f
 
@@ -84,21 +103,55 @@ all.  This may very well take some time.")
 
 (defvoo nnml-generate-active-function 'nnml-generate-active-info)
 
-\f
+(defvar nnml-nov-buffer-file-name nil)
+
+(defvoo nnml-file-coding-system nnmail-file-coding-system)
 
+\f
 ;;; Interface functions.
 
 (nnoo-define-basics nnml)
 
+(eval-when-compile
+  (defsubst nnml-group-name-charset (group server-or-method)
+    (gnus-group-name-charset
+     (if (stringp server-or-method)
+        (gnus-server-to-method
+         (if (string-match "\\+" server-or-method)
+             (concat (substring server-or-method 0 (match-beginning 0))
+                     ":" (substring server-or-method (match-end 0)))
+           (concat "nnml:" server-or-method)))
+       (or server-or-method gnus-command-method '(nnml "")))
+     group)))
+
+(defun nnml-decoded-group-name (group &optional server-or-method)
+  "Return a decoded group name of GROUP on SERVER-OR-METHOD."
+  (if nnmail-group-names-not-encoded-p
+      group
+    (mm-decode-coding-string
+     group
+     (nnml-group-name-charset group server-or-method))))
+
+(defun nnml-encoded-group-name (group &optional server-or-method)
+  "Return an encoded group name of GROUP on SERVER-OR-METHOD."
+  (mm-encode-coding-string
+   group
+   (nnml-group-name-charset group server-or-method)))
+
+(defun nnml-group-pathname (group &optional file server)
+  "Return an absolute file name of FILE for GROUP on SERVER."
+  (nnmail-group-pathname (inline (nnml-decoded-group-name group server))
+                        nnml-directory file))
+
 (deffoo nnml-retrieve-headers (sequence &optional group server fetch-old)
   (when (nnml-possibly-change-directory group server)
-    (save-excursion
-      (set-buffer nntp-server-buffer)
+    (with-current-buffer nntp-server-buffer
       (erase-buffer)
-      (let ((file nil)
-           (number (length sequence))
-           (count 0)
-           beg article)
+      (let* ((file nil)
+            (number (length sequence))
+            (count 0)
+            (file-name-coding-system nnmail-pathname-coding-system)
+            beg article)
        (if (stringp (car sequence))
            'headers
          (if (nnml-retrieve-headers-with-nov sequence fetch-old)
@@ -106,13 +159,14 @@ all.  This may very well take some time.")
            (while sequence
              (setq article (car sequence))
              (setq file (nnml-article-to-file article))
-             (when (and (file-exists-p file)
+             (when (and file
+                        (file-exists-p file)
                         (not (file-directory-p file)))
                (insert (format "221 %d Article retrieved.\n" article))
                (setq beg (point))
                (nnheader-insert-head file)
                (goto-char beg)
-               (if (search-forward "\n\n" nil t)
+               (if (re-search-forward "\n\r?\n" nil t)
                    (forward-char -1)
                  (goto-char (point-max))
                  (insert "\n\n"))
@@ -136,10 +190,8 @@ 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)))
-  (cond 
+    (ignore-errors (make-directory nnml-directory t)))
+  (cond
    ((not (file-exists-p nnml-directory))
     (nnml-close-server)
     (nnheader-report 'nnml "Couldn't create directory: %s" nnml-directory))
@@ -151,91 +203,112 @@ 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))
+        (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))
+       (when (and (setq group-num (nnml-find-group-number id server))
                   (cdr
                    (assq (cdr group-num)
                          (nnheader-article-to-file-alist
-                          (setq gpath
-                                (nnmail-group-pathname
-                                 (car group-num)
-                                 nnml-directory))))))
-         (setq path (concat gpath (int-to-string (cdr group-num)))))
+                          (setq gpath (nnml-group-pathname (car group-num)
+                                                           nil server))))))
+         (nnml-update-file-alist)
+         (setq path (concat gpath (if nnml-use-compressed-files
+                                      (cdr (assq (cdr group-num)
+                                                 nnml-article-file-alist))
+                                    (number-to-string (cdr group-num))))))
       (setq path (nnml-article-to-file id)))
-    (cond 
+    (cond
      ((not path)
       (nnheader-report 'nnml "No such article: %s" id))
      ((not (file-exists-p path))
       (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
+              &n