timer vs. itimer
[gnus] / lisp / gnus-agent.el
index b4c1d47..3d69b5b 100644 (file)
@@ -1,5 +1,5 @@
 ;;; gnus-agent.el --- unplugged support for Gnus
-;; Copyright (C) 1997,98,99 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; This file is part of GNU Emacs.
@@ -28,6 +28,9 @@
 (require 'nnvirtual)
 (require 'gnus-sum)
 (eval-when-compile
+  (if (featurep 'xemacs)
+      (require 'itimer)
+    (require 'timer))
   (require 'cl)
   (require 'gnus-score))
 
@@ -433,7 +436,7 @@ Currently sends flag setting requests, if any."
       (when (file-exists-p (gnus-agent-lib-file "flags"))
        (set-buffer (get-buffer-create " *Gnus Agent flag synchronize*"))
        (erase-buffer)
-       (insert-file-contents (gnus-agent-lib-file "flags"))
+       (nnheader-insert-file-contents (gnus-agent-lib-file "flags"))
        (if (null (gnus-check-server gnus-command-method))
            (message "Couldn't open server %s" (nth 1 gnus-command-method))
          (while (not (eobp))
@@ -443,7 +446,8 @@ Currently sends flag setting requests, if any."
              (write-file (gnus-agent-lib-file "flags"))
              (error "Couldn't set flags from file %s"
                     (gnus-agent-lib-file "flags"))))
-         (write-file (gnus-agent-lib-file "flags")))))))
+         (write-file (gnus-agent-lib-file "flags")))
+        (kill-buffer nil)))))
 
 ;;;
 ;;; Server mode commands
@@ -483,8 +487,10 @@ Currently sends flag setting requests, if any."
 (defun gnus-agent-write-servers ()
   "Write the alist of covered servers."
   (gnus-make-directory (nnheader-concat gnus-agent-directory "lib"))
-  (with-temp-file (nnheader-concat gnus-agent-directory "lib/servers")
-    (prin1 gnus-agent-covered-methods (current-buffer))))
+  (let ((coding-system-for-write nnheader-file-coding-system)
+       (file-name-coding-system nnmail-pathname-coding-system))
+    (with-temp-file (nnheader-concat gnus-agent-directory "lib/servers")
+      (prin1 gnus-agent-covered-methods (current-buffer)))))
 
 ;;;
 ;;; Summary commands
@@ -591,7 +597,7 @@ the actual number of articles toggled is returned."
       (funcall function nil new)
       (gnus-agent-write-active file new)
       (erase-buffer)
-      (insert-file-contents-literally file))))
+      (nnheader-insert-file-contents file))))
 
 (defun gnus-agent-write-active (file new)
   (let ((orig (gnus-make-hashtable (count-lines (point-min) (point-max))))
@@ -599,7 +605,7 @@ the actual number of articles toggled is returned."
        elem osym)
     (when (file-exists-p file)
       (with-temp-buffer
-       (insert-file-contents file)
+       (nnheader-insert-file-contents file)
        (gnus-active-to-gnus-format nil orig))
       (mapatoms
        (lambda (sym)
@@ -611,7 +617,9 @@ the actual number of articles toggled is returned."
        new))
     (gnus-make-directory (file-name-directory file))
     (let ((coding-system-for-write gnus-agent-file-coding-system))
-      (gnus-write-active-file file orig))))
+      ;; The hashtable contains real names of groups,  no more prefix
+      ;; removing, so set `full' to `t'.
+      (gnus-write-active-file file orig t))))
 
 (defun gnus-agent-save-groups (method)
   (gnus-agent-save-active-1 method 'gnus-groups-to-gnus-format))
@@ -619,17 +627,30 @@ the actual number of articles toggled is returned."
 (defun gnus-agent-save-group-info (method group active)
   (when (gnus-agent-method-p method)
     (let* ((gnus-command-method method)
-          (file (gnus-agent-lib-file "active")))
+          (coding-system-for-write nnheader-file-coding-system)
+          (file-name-coding-system nnmail-pathname-coding-system)
+          (file (gnus-agent-lib-file "active"))
+          oactive)
       (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) 
        (when (file-exists-p file)
          (nnheader-insert-file-contents file))
        (goto-char (point-min))
        (when (re-search-forward
               (concat "^" (regexp-quote group) " ") nil t)
+         (save-excursion
+           (save-restriction
+             (narrow-to-region (match-beginning 0)
+                               (progn
+                                 (forward-line 1)
+                                 (point)))
+             (setq oactive (car (nnmail-parse-active)))))
          (gnus-delete-line))
-       (insert (format "%S %d %d y\n" (intern group) (cdr active)
-                       (car active)))
+       (insert (format "%S %d %d y\n" (intern group)
+                       (cdr active)
+                       (or (car oactive) (car active))))
        (goto-char (point-max))
        (while (search-backward "\\." nil t)
          (delete-char 1))))))
@@ -673,11 +694,12 @@ the actual number of articles toggled is returned."
                             (format " *Gnus agent %s history*"
                                     (gnus-agent-method)))))
          gnus-agent-history-buffers)
+    (mm-disable-multibyte) ;; everything is binary
     (erase-buffer)
     (insert "\n")
     (let ((file (gnus-agent-lib-file "history")))
       (when (file-exists-p file)
-       (insert-file file))
+       (nnheader-insert-file-contents file))
       (set (make-local-variable 'gnus-agent-file-name) file))))
 
 (defun gnus-agent-save-history ()
@@ -699,12 +721,15 @@ the actual number of articles toggled is returned."
   (save-excursion
     (set-buffer gnus-agent-current-history)
     (goto-char (point-max))
-    (insert id "\t" (number-to-string date) "\t")
-    (while group-arts
-      (insert (format "%S" (caar group-arts)) 
-             " " (number-to-string (cdr (pop group-arts)))
-             " "))
-    (insert "\n")))
+    (let ((p (point)))
+      (insert id "\t" (number-to-string date) "\t")
+      (while group-arts
+       (insert (format "%S" (intern (caar group-arts)))
+               " " (number-to-string (cdr (pop group-arts)))
+               " "))
+      (insert "\n")
+      (while (search-backward "\\." p t)
+       (delete-char 1)))))
 
 (defun gnus-agent-article-in-history-p (id)
   (save-excursion
@@ -844,16 +869,32 @@ 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
+    ;; Add article with marks to list of article headers we want to fetch.
     (dolist (arts (gnus-info-marks (gnus-get-info group)))
-      (setq articles (union (gnus-uncompress-sequence (cdr arts))
+      (setq articles (gnus-agent-union (gnus-uncompress-sequence (cdr arts))
                            articles)))
     (setq articles (sort articles '<))
-    ;; remove known articles
+    ;; Remove known articles.
     (when (gnus-agent-load-alist group)
       (setq articles (gnus-sorted-intersection
                      articles
@@ -862,7 +903,7 @@ the actual number of articles toggled is returned."
                             (cdr (gnus-active group)))))))
     ;; Fetch them.
     (gnus-make-directory (nnheader-translate-file-chars
-                         (file-name-directory file)))
+                         (file-name-directory file) t))
     (when articles
       (gnus-message 7 "Fetching headers for %s..." group)
       (save-excursion
@@ -942,15 +983,16 @@ the actual number of articles toggled is returned."
 
 (defun gnus-agent-save-alist (group &optional articles state dir)
   "Save the article-state alist for GROUP."
-  (with-temp-file (if dir
-                     (concat dir ".agentview")
-                   (gnus-agent-article-name ".agentview" group))
-    (princ (setq gnus-agent-article-alist
-                (nconc gnus-agent-article-alist
-                       (mapcar (lambda (article) (cons article state))
-                               articles)))
-          (current-buffer))
-    (insert "\n")))
+  (let ((file-name-coding-system nnmail-pathname-coding-system))
+      (with-temp-file (if dir
+                         (concat dir ".agentview")
+                       (gnus-agent-article-name ".agentview" group))
+       (princ (setq gnus-agent-article-alist
+                    (nconc gnus-agent-article-alist
+                           (mapcar (lambda (article) (cons article state))
+                                   articles)))
+              (current-buffer))
+       (insert "\n"))))
 
 (defun gnus-agent-article-name (article group)
   (concat (gnus-agent-directory) (gnus-agent-group-path group) "/"
@@ -1005,7 +1047,13 @@ the actual number of articles toggled is returned."
        gnus-newsgroup-dependencies gnus-newsgroup-headers
        gnus-newsgroup-scored gnus-headers gnus-score
        gnus-use-cache articles arts
-       category predicate info marks score-param)
+       category predicate info marks score-param
+       (gnus-summary-expunge-below gnus-summary-expunge-below)
+       (gnus-summary-mark-below gnus-summary-mark-below)
+       (gnus-orphan-score gnus-orphan-score)
+       ;; Maybe some other gnus-summary local variables should also
+       ;; be put here.
+       )
     (unless (gnus-check-group group)
       (error "Can't open server for %s" group))
     ;; Fetch headers.
@@ -1294,8 +1342,8 @@ The following commands are available:
   (let ((info (assq category gnus-category-alist))
        (buffer-read-only nil))
     (gnus-delete-line)
-    (gnus-category-write)
-    (setq gnus-category-alist (delq info gnus-category-alist))))
+    (setq gnus-category-alist (delq info gnus-category-alist))
+    (gnus-category-write)))
 
 (defun gnus-category-copy (category to)
   "Copy the current category."
@@ -1434,7 +1482,7 @@ The following commands are available:
       (while (setq gnus-command-method (pop methods))
        (when (file-exists-p (gnus-agent-lib-file "active"))
          (with-temp-buffer
-           (insert-file-contents (gnus-agent-lib-file "active"))
+           (nnheader-insert-file-contents (gnus-agent-lib-file "active"))
            (gnus-active-to-gnus-format 
             gnus-command-method
             (setq orig (gnus-make-hashtable
@@ -1454,8 +1502,9 @@ The following commands are available:
                    (forward-line 1)
                  ;; Old article.  Schedule it for possible nuking.
                  (while (not (eolp))
-                   (setq sym (let ((obarray expiry-hashtb))
-                               (read (current-buffer))))
+                   (setq sym (let ((obarray expiry-hashtb) s)
+                               (setq s (read (current-buffer)))
+                               (if (stringp s) (intern s) s)))
                    (if (boundp sym)
                        (set sym (cons (cons (read (current-buffer)) (point))
                                       (symbol-value sym)))