(datadir): Set this variable, like in the other
[gnus] / lisp / gnus-agent.el
index 88fd025..d5c9017 100644 (file)
@@ -1,5 +1,6 @@
 ;;; gnus-agent.el --- unplugged support for Gnus
-;; Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 1998, 1999, 2000, 2001
+;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; This file is part of GNU Emacs.
@@ -34,6 +35,9 @@
     (require 'timer))
   (require 'cl))
 
+(eval-and-compile
+  (autoload 'gnus-server-update-server "gnus-srvr"))
+
 (defcustom gnus-agent-directory (nnheader-concat gnus-directory "agent/")
   "Where the Gnus agent will store its files."
   :group 'gnus-agent
@@ -70,24 +74,38 @@ If nil, only read articles will be expired."
   :group 'gnus-agent
   :type 'hook)
 
+;; Extracted from gnus-xmas-redefine in order to preserve user settings
+(when (featurep 'xemacs)
+  (add-hook 'gnus-agent-group-mode-hook 'gnus-xmas-agent-group-menu-add))
+
 (defcustom gnus-agent-summary-mode-hook nil
   "Hook run in Agent summary minor modes."
   :group 'gnus-agent
   :type 'hook)
 
+;; Extracted from gnus-xmas-redefine in order to preserve user settings
+(when (featurep 'xemacs)
+  (add-hook 'gnus-agent-summary-mode-hook 'gnus-xmas-agent-summary-menu-add))
+
 (defcustom gnus-agent-server-mode-hook nil
   "Hook run in Agent summary minor modes."
   :group 'gnus-agent
   :type 'hook)
 
+;; Extracted from gnus-xmas-redefine in order to preserve user settings
+(when (featurep 'xemacs)
+  (add-hook 'gnus-agent-server-mode-hook 'gnus-xmas-agent-server-menu-add))
+
 (defcustom gnus-agent-confirmation-function 'y-or-n-p
   "Function to confirm when error happens."
+  :version "21.1"
   :group 'gnus-agent
   :type 'function)
 
 (defcustom gnus-agent-synchronize-flags 'ask
   "Indicate if flags are synchronized when you plug in.
 If this is `ask' the hook will query the user."
+  :version "21.1"
   :type '(choice (const :tag "Always" t)
                 (const :tag "Never" nil)
                 (const :tag "Ask" ask))
@@ -170,7 +188,9 @@ If this is `ask' the hook will query the user."
 
 (defun gnus-agent-lib-file (file)
   "The full path of the Gnus agent library FILE."
-  (concat (gnus-agent-directory) "agent.lib/" file))
+  (expand-file-name file
+                   (file-name-as-directory
+                    (expand-file-name "agent.lib" (gnus-agent-directory)))))
 
 ;;; Fetching setup functions.
 
@@ -192,7 +212,7 @@ If this is `ask' the hook will query the user."
 (defmacro gnus-agent-with-fetch (&rest forms)
   "Do FORMS safely."
   `(unwind-protect
-       (progn
+       (let ((gnus-agent-fetching t))
         (gnus-agent-start-fetch)
         ,@forms)
      (gnus-agent-stop-fetch)))
@@ -333,9 +353,9 @@ last form in your `.gnus.el' file:
 
 \(gnus-agentize)
 
-This will modify the `gnus-before-startup-hook', `gnus-post-method',
-and `message-send-mail-function' variables, and install the Gnus
-agent minor mode in all Gnus buffers."
+This will modify the `gnus-setup-news-hook', and
+`message-send-mail-function' variables, and install the Gnus agent
+minor mode in all Gnus buffers."
   (interactive)
   (gnus-open-agent)
   (add-hook 'gnus-setup-news-hook 'gnus-agent-queue-setup)
@@ -366,7 +386,7 @@ agent minor mode in all Gnus buffers."
 
 (defun gnus-agent-insert-meta-information (type &optional method)
   "Insert meta-information into the message that says how it's to be posted.
-TYPE can be either `mail' or `news'.  If the latter METHOD can
+TYPE can be either `mail' or `news'.  If the latter, then METHOD can
 be a select method."
   (save-excursion
     (message-remove-header gnus-agent-meta-information-header)
@@ -389,10 +409,10 @@ be a select method."
   (save-restriction
     (message-narrow-to-headers)
     (let* ((gcc (mail-fetch-field "gcc" nil t))
-          (methods (and gcc 
+          (methods (and gcc
                         (mapcar 'gnus-inews-group-method
                                 (message-unquote-tokens
-                                 (message-tokenize-header 
+                                 (message-tokenize-header
                                   gcc " ,")))))
           covered)
       (while (and (not covered) methods)
@@ -509,7 +529,7 @@ be a select method."
   (when (or (and gnus-agent-synchronize-flags
                 (not (eq gnus-agent-synchronize-flags 'ask)))
            (and (eq gnus-agent-synchronize-flags 'ask)
-                (gnus-y-or-n-p (format "Synchronize flags on server `%s'? " 
+                (gnus-y-or-n-p (format "Synchronize flags on server `%s'? "
                                        (cadr method)))))
     (gnus-agent-synchronize-flags-server method)))
 
@@ -526,6 +546,7 @@ be a select method."
     (when (member method gnus-agent-covered-methods)
       (error "Server already in the agent program"))
     (push method gnus-agent-covered-methods)
+    (gnus-server-update-server server)
     (gnus-agent-write-servers)
     (message "Entered %s into the Agent" server)))
 
@@ -539,6 +560,7 @@ be a select method."
       (error "Server not in the agent program"))
     (setq gnus-agent-covered-methods
          (delete method gnus-agent-covered-methods))
+    (gnus-server-update-server server)
     (gnus-agent-write-servers)
     (message "Removed %s from the agent" server)))
 
@@ -619,23 +641,18 @@ the actual number of articles toggled is returned."
               (gnus-agent-method-p gnus-command-method))
       (gnus-agent-load-alist gnus-newsgroup-name)
       ;; First mark all undownloaded articles as undownloaded.
-      (let ((articles (append gnus-newsgroup-unreads
-                             gnus-newsgroup-marked
-                             gnus-newsgroup-dormant))
-           article)
-       (while (setq article (pop articles))
-         (unless (or (cdr (assq article gnus-agent-article-alist))
-                     (memq article gnus-newsgroup-downloadable)
-                     (memq article gnus-newsgroup-cached))
-           (push article gnus-newsgroup-undownloaded))))
+      (dolist (article (mapcar (lambda (header) (mail-header-number header))
+                              gnus-newsgroup-headers))
+       (unless (or (cdr (assq article gnus-agent-article-alist))
+                   (memq article gnus-newsgroup-downloadable)
+                   (memq article gnus-newsgroup-cached))
+         (push article gnus-newsgroup-undownloaded)))
       ;; Then mark downloaded downloadable as not-downloadable,
       ;; if you get my drift.
-      (let ((articles gnus-newsgroup-downloadable)
-           article)
-       (while (setq article (pop articles))
-         (when (cdr (assq article gnus-agent-article-alist))
-           (setq gnus-newsgroup-downloadable
-                 (delq article gnus-newsgroup-downloadable))))))))
+      (dolist (article gnus-newsgroup-downloadable)
+       (when (cdr (assq article gnus-agent-article-alist))
+         (setq gnus-newsgroup-downloadable
+               (delq article gnus-newsgroup-downloadable)))))))
 
 (defun gnus-agent-catchup ()
   "Mark all undownloaded articles as read."
@@ -698,7 +715,7 @@ the actual number of articles toggled is returned."
       (gnus-make-directory (file-name-directory file))
       (with-temp-file file
        ;; Emacs got problem to match non-ASCII group in multibyte buffer.
-       (mm-disable-multibyte) 
+       (mm-disable-multibyte)
        (when (file-exists-p file)
          (nnheader-insert-file-contents file))
        (goto-char (point-min))
@@ -726,7 +743,7 @@ the actual number of articles toggled is returned."
     (nnheader-translate-file-chars
      (nnheader-replace-chars-in-string
       (nnheader-replace-duplicate-chars-in-string
-       (nnheader-replace-chars-in-string 
+       (nnheader-replace-chars-in-string
        (gnus-group-real-name group)
        ?/ ?_)
        ?. ?_)
@@ -843,8 +860,8 @@ the actual number of articles toggled is returned."
          (with-temp-buffer
            (let (article)
              (while (setq article (pop articles))
-               (when (or 
-                      (gnus-backlog-request-article group article 
+               (when (or
+                      (gnus-backlog-request-article group article
                                                     nntp-server-buffer)
                       (gnus-request-article article group))
                  (goto-char (point-max))
@@ -933,29 +950,13 @@ the actual number of articles toggled is returned."
        (insert "\n"))
       (pop gnus-agent-group-alist))))
 
-(if (fboundp 'union)
-    (defalias 'gnus-agent-union 'union)
-  (defun gnus-agent-union (l1 l2)
-    "Set union of lists L1 and L2."
-    (cond ((null l1) l2)
-         ((null l2) l1)
-         ((equal l1 l2) l1)
-         (t
-          (or (>= (length l1) (length l2))
-              (setq l1 (prog1 l2 (setq l2 l1))))
-          (while l2
-            (or (memq (car l2) l1)
-                (push (car l2) l1))
-            (pop l2))
-          l1))))
-
 (defun gnus-agent-fetch-headers (group &optional force)
   (let ((articles (gnus-list-of-unread-articles group))
        (gnus-decode-encoded-word-function 'identity)
        (file (gnus-agent-article-name ".overview" group)))
     ;; Add article with marks to list of article headers we want to fetch.
     (dolist (arts (gnus-info-marks (gnus-get-info group)))
-      (setq articles (gnus-agent-union (gnus-uncompress-sequence (cdr arts))
+      (setq articles (gnus-union (gnus-uncompress-sequence (cdr arts))
                            articles)))
     (setq articles (sort articles '<))
     ;; Remove known articles.
@@ -1042,14 +1043,14 @@ the actual number of articles toggled is returned."
   (setq gnus-agent-article-alist
        (gnus-agent-read-file
         (if dir
-            (concat dir ".agentview")
+            (expand-file-name ".agentview" dir)
           (gnus-agent-article-name ".agentview" group)))))
 
 (defun gnus-agent-save-alist (group &optional articles state dir)
   "Save the article-state alist for GROUP."
   (let ((file-name-coding-system nnmail-pathname-coding-system))
       (with-temp-file (if dir
-                         (concat dir ".agentview")
+                         (expand-file-name ".agentview" dir)
                        (gnus-agent-article-name ".agentview" group))
        (princ (setq gnus-agent-article-alist
                     (nconc gnus-agent-article-alist
@@ -1059,8 +1060,10 @@ the actual number of articles toggled is returned."
        (insert "\n"))))
 
 (defun gnus-agent-article-name (article group)
-  (concat (gnus-agent-directory) (gnus-agent-group-path group) "/"
-         (if (stringp article) article (string-to-number article))))
+  (expand-file-name (if (stringp article) article (string-to-number article))
+                   (file-name-as-directory
+                    (expand-file-name (gnus-agent-group-path group)
+                                      (gnus-agent-directory)))))
 
 (defun gnus-agent-batch-confirmation (msg)
   "Show error message and return t."
@@ -1097,10 +1100,15 @@ the actual number of articles toggled is returned."
                  (while (setq group (pop groups))
                    (when (<= (gnus-group-level group) gnus-agent-handle-level)
                      (gnus-agent-fetch-group-1 group gnus-command-method))))))
-         (error 
+         (error
           (unless (funcall gnus-agent-confirmation-function
                            (format "Error (%s).  Continue? " err))
-            (error "Cannot fetch articles into the Gnus agent."))))
+            (error "Cannot fetch articles into the Gnus agent.")))
+         (quit
+          (unless (funcall gnus-agent-confirmation-function
+                           (format "Quit fetching session (%s).  Continue? "
+                                   err))
+            (signal 'quit "Cannot fetch articles into the Gnus agent."))))
        (pop methods))
       (gnus-message 6 "Finished fetching articles into the Gnus agent"))))
 
@@ -1128,7 +1136,7 @@ the actual number of articles toggled is returned."
                 (setq gnus-newsgroup-dependencies
                       (make-vector (length articles) 0))
                 (setq gnus-newsgroup-headers
-                      (gnus-get-newsgroup-headers-xover articles nil nil 
+                      (gnus-get-newsgroup-headers-xover articles nil nil
                                                         group))
                 ;; `gnus-agent-overview-buffer' may be killed for
                 ;; timeout reason.  If so, recreate it.
@@ -1522,7 +1530,7 @@ The following commands are available:
        (when (file-exists-p (gnus-agent-lib-file "active"))
          (with-temp-buffer
            (nnheader-insert-file-contents (gnus-agent-lib-file "active"))
-           (gnus-active-to-gnus-format 
+           (gnus-active-to-gnus-format
             gnus-command-method
             (setq orig (gnus-make-hashtable
                         (count-lines (point-min) (point-max))))))
@@ -1536,7 +1544,17 @@ The following commands are available:
              (goto-char (point-min))
              (while (not (eobp))
                (skip-chars-forward "^\t")
-               (if (> (read (current-buffer)) day)
+               (if (let ((fetch-date (read (current-buffer))))
+                     (if (numberp fetch-date)
+                         (>  fetch-date day)
+                       ;; History file is corrupted.
+                       (gnus-message
+                        5
+                        (format "File %s is corrupted!"
+                                (gnus-agent-lib-file "history")))
+                       (sit-for 1)
+                       ;; Ignore it
+                       t))
                    ;; New article; we don't expire it.
                    (forward-line 1)
                  ;; Old article.  Schedule it for possible nuking.
@@ -1588,7 +1606,7 @@ The following commands are available:
                                 (or (not (numberp
                                           (setq art (read (current-buffer)))))
                                     (< art article)))
-                      (if (and (numberp art) 
+                      (if (and (numberp art)
                                (file-exists-p
                                 (gnus-agent-article-name
                                  (number-to-string art) group)))