diff lisp/gnus/gnus-start.el @ 57617:7fdc1df35f39

Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-628 Merge from gnus--rel--5.10 Patches applied: * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-55 Update from CVS 2004-10-19 Katsumi Yamaoka <yamaoka@jpl.org> * lisp/gnus/gnus-sum.el (gnus-update-summary-mark-positions): Search for dummy marks in the right way. 2004-10-18 Kevin Greiner <kgreiner@compsol.cc> * lisp/gnus/nnagent.el (nnagent-request-type): Bind gnus-agent to nil to avoid infinite recursion via gnus-get-function. 2004-10-18 Kevin Greiner <kgreiner@compsol.cc> * lisp/gnus/gnus-agent.el (gnus-agent-synchronize-group-flags): When necessary, pass full group name to gnus-request-set-marks. (gnus-agent-synchronize-group-flags): Added support for sync'ing tick marks. (gnus-agent-synchronize-flags-server): Be silent when writing file. 2004-10-18 Kevin Greiner <kgreiner@compsol.cc> * lisp/gnus/gnus-agent.el (gnus-agent-synchronize-group-flags): Replaced gnus-request-update-info with explicit code to sync the in-memory info read flags with the marks being sync'd to the backend. 2004-10-18 Kevin Greiner <kgreiner@compsol.cc> * lisp/gnus/gnus-agent.el (gnus-agent-possibly-synchronize-flags): Ignore servers that are offline. Avoids having gnus-agent-toggle-plugged first ask if you want to open a server and then, even when you responded with no, asking if you want to synchronize the server's flags. (gnus-agent-synchronize-flags-server): Rewrote read loop to handle multi-line expressions. (gnus-agent-synchronize-group-flags): New internal function. Updates marks in memory (in the info structure) AND in the backend. (gnus-agent-check-overview-buffer): Fixed range of deletion to remove entire duplicate line. Fixes merged article number bug. * lisp/gnus/gnus-util.el (gnus-remassoc): Fixed typo in documentation. * lisp/gnus/nnagent.el (nnagent-request-set-mark): Use gnus-agent-synchronize-group-flags, not backend's request-set-mark method, to ensure that synchronization updates marks in the backend and in the info (in memory) structure. 2004-10-18 Kevin Greiner <kgreiner@compsol.cc> * lisp/gnus/gnus-agent.el (gnus-agent-synchronize-flags-server): Do nothing unless plugged. Disable the agent so that an open failure causes an error. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Reiner Steib <Reiner.Steib@gmx.de> * lisp/gnus/gnus-agent.el (gnus-agent-fetched-hook): Add :version. (gnus-agent-go-online): Change :version. (gnus-agent-expire-unagentized-dirs) (gnus-agent-auto-agentize-methods): Add :version. 2004-10-18 Kevin Greiner <kgreiner@compsol.cc> * lisp/gnus/legacy-gnus-agent.el (gnus-agent-convert-to-compressed-agentview-prompt): New function. Used internally to only display 'gnus converting files' message when actually necessary. * lisp/gnus/gnus-sum.el (): Removed (require 'gnus-agent) as required methods now autoloaded. * lisp/gnus/gnus-int.el (gnus-request-move-article): Use gnus-agent-unfetch-articles in place of gnus-agent-expire to improve performance. 2004-10-18 Kevin Greiner <kgreiner@compsol.cc> * lisp/gnus/gnus-agent.el (gnus-agent-cat-groups): rewrote avoiding defsetf to avoid run-time CL dependencies. (gnus-agent-unfetch-articles): New function. (gnus-agent-fetch-headers): Use gnus-agent-braid-nov to validate article numbers even when local .overview file is missing. (gnus-agent-read-article-number): New function. Only accepts 27-bit article numbers. (gnus-agent-copy-nov-line, gnus-agent-uncached-articles): Use gnus-agent-read-article-number. (gnus-agent-braid-nov): Rewrote to validate article numbers coming from backend while recognizing that article numbers in .overview must be valid. * lisp/gnus/gnus-start.el (gnus-convert-old-newsrc): Changed message text as some users confused by references to .newsrc when they only have a .newsrc.eld file. (gnus-convert-mark-converter-prompt, gnus-convert-converter-needs-prompt): Fixed use of property list. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Katsumi Yamaoka <yamaoka@jpl.org> * lisp/gnus/gnus-agent.el (gnus-agent-restore-gcc): Use ^ and regexp-quote. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Lars Magne Ingebrigtsen <larsi@gnus.org> * lisp/gnus/gnus-start.el (gnus-get-unread-articles-in-group): Don't do stuff for non-living groups. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Lars Magne Ingebrigtsen <larsi@gnus.org> * lisp/gnus/gnus-agent.el (gnus-agent-synchronize-flags): Default to nil. (gnus-agent-regenerate-group): Using nil messages aren't valid. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Lars Magne Ingebrigtsen <larsi@gnus.org> * lisp/gnus/gnus-agent.el (gnus-agent-read-agentview): Inline gnus-uncompress-range. 2004-10-18 Kevin Greiner <kgreiner@xpediantsolutions.com> * lisp/gnus/legacy-gnus-agent.el (gnus-agent-convert-to-compressed-agentview): Fixed typos with help from Florian Weimer <fw@deneb.enyo.de> * lisp/gnus/gnus-agent.el (gnus-agentize): gnus-agent-send-mail-real-function no longer set to current value of message-send-mail-function but rather a lambda that calls message-send-mail-function. The change makes the agent real-time responsive to user changes to message-send-mail-function. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Reiner Steib <Reiner.Steib@gmx.de> * lisp/gnus/gnus-start.el (gnus-get-unread-articles): Fix last commit. 2004-10-18 Kevin Greiner <kgreiner@xpediantsolutions.com> * lisp/gnus/gnus-cache.el (gnus-cache-rename-group): New function. (gnus-cache-delete-group): New function. * lisp/gnus/gnus-agent.el (gnus-agent-rename-group): New function. (gnus-agent-delete-group): New function. (gnus-agent-save-group-info): Use gnus-command-method when `method' parameter is nil. Don't write nil entries into the active file. (gnus-agent-get-group-info): New function. (gnus-agent-get-local): Added optional parameters to avoid calling gnus-group-real-name and gnus-find-method-for-group. (gnus-agent-set-local): Delete stored entry if either min, or max, are nil. (gnus-agent-fetch-session): Reworded error/quit messages. On quit, use gnus-agent-regenerate-group to record existance of any articles fetched to disk before the quit occurred. * lisp/gnus/gnus-int.el (gnus-request-delete-group): Use gnus-cache-delete-group and gnus-agent-delete-group to keep the local disk in sync with the server. (gnus-request-rename-group): Use gnus-cache-rename-group and gnus-agent-rename-group to keep the local disk in sync with the server. * lisp/gnus/gnus-start.el (gnus-get-unread-articles): Cosmetic simplification to logic. * lisp/gnus/gnus-group.el (): (gnus-group-delete-group): No longer update gnus-cache-active-altered as gnus-request-delete-group now keeps the cache in sync. (gnus-group-list-active): Let the agent store a server's active list if currently plugged. * lisp/gnus/gnus-util.el (gnus-rename-file): New function. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Katsumi Yamaoka <yamaoka@jpl.org> * lisp/gnus/gnus-agent.el (gnus-agent-regenerate-group): Activate the group when the group's active is not available. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Katsumi Yamaoka <yamaoka@jpl.org> * lisp/gnus/gnus-agent.el (gnus-agent-read-agentview): Add a missing arg to error. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> * lisp/gnus/gnus-start.el (gnus-convert-old-newsrc): Only write the conversion message to newsrc-dribble when an actual conversion is performed. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> * lisp/gnus/gnus-agent.el (gnus-agent-read-local): Bind nnheader-file-coding-system to gnus-agent-file-coding-system to avoid the implicit assumption that they will always be equal. (gnus-agent-save-local): Bind buffer-file-coding-system, not coding-system-for-write, as the with-temp-file macro first prints to a buffer then saves the buffer. 2004-10-18 Kevin Greiner <kgreiner@xpediantsolutions.com> * lisp/gnus/legacy-gnus-agent.el (): New. Provides converters that are only loaded when gnus-convert-old-newsrc needs to call them. * lisp/gnus/gnus-agent.el (gnus-agent-read-agentview): Removed support for old file versions. (gnus-group-prepare-hook): Removed function that converted list form of gnus-agent-expire-days to group properties. * lisp/gnus/gnus-start.el (gnus-convert-old-newsrc): Registered new converters to handle old agent file formats. Added logic for a "backup before upgrading warning". (gnus-convert-mark-converter-prompt): Developers can mark functions as needing (default), or not needing, gnus-convert-old-newsrc's "backup before upgrading warning". (gnus-convert-converter-needs-prompt): Tests whether the user should be protected from potentially irreversable changes by the function. 2004-10-18 Kevin Greiner <kgreiner@xpediantsolutions.com> * lisp/gnus/gnus-int.el (gnus-request-accept-article): Inform the agent that articles are being added to a group. (gnus-request-replace-article): Inform the agent that articles need to be uncached as the cached contents are no longer valid. * lisp/gnus/gnus-agent.el (gnus-agent-file-header-cache): Removed. (gnus-agent-possibly-alter-active): Avoid null in numeric comparison. (gnus-agent-set-local): Refuse to save null in local object table. (gnus-agent-regenerate-group): The REREAD parameter can now be a list of articles that will be marked as unread. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> * lisp/gnus/gnus-range.el (gnus-sorted-range-intersection): Now accepts single-interval range of the form (min . max). Previously the range had to look like ((min . max)). Likewise, return (min . max) rather than ((min . max)). (gnus-range-map): Use gnus-range-normalize to accept single-interval range. * lisp/gnus/gnus-sum.el (gnus-summary-highlight-line): Articles stored in the cache, but not the agent, now appear with their usual face. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> * lisp/gnus/gnus-sum.el (gnus-adjust-marks): Now correctly handles a list of marks consisting of a single range {for example, (3 . 5)} rather than a list of a single range { ((3 . 5)) }. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> * lisp/gnus/gnus-sum.el (gnus-adjust-marks): Avoid splicing null INTO the uncompressed list. 2004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> * lisp/gnus/gnus-draft.el (gnus-group-send-queue): Pass the group name "nndraft:queue" along to gnus-draft-send. Use gnus-agent-prompt-send-queue. (gnus-draft-send): Rebind gnus-agent-queue-mail to nil when group is "nndraft:queue". Suggested by Gaute Strokkenes <gs234@srcf.ucam.org> * lisp/gnus/gnus-group.el (gnus-group-catchup): Use new gnus-sequence-of-unread-articles, not gnus-list-of-unread-articles, to avoid exhausting memory with huge numbers of articles. Use gnus-range-map to avoid having to uncompress the unread list. (gnus-group-archive-directory, gnus-group-recent-archive-directory): Fixed invalid ange-ftp reference. * lisp/gnus/gnus-range.el (gnus-range-map): Iterate over list or sequence. (gnus-sorted-range-intersection): Intersection of two ranges without requiring that they first be uncompressed. * lisp/gnus/gnus-start.el (gnus-activate-group): Unless blocked by the caller, possibly expand the active range to include both cached and agentized articles. (gnus-convert-old-newsrc): Rewrote in anticipation of having multiple version-dependent converters. (gnus-groups-to-gnus-format): Replaced gnus-agent-save-groups with gnus-agent-save-active. (gnus-save-newsrc-file): Save dirty agent range limits. * lisp/gnus/gnus-sum.el (gnus-select-newgroup): Replaced inline code with gnus-agent-possibly-alter-active. (gnus-adjust-marked-articles): Faster handling of simple lists 2004-10-18 David Edmondson <dme@dme.org> * lisp/gnus/mm-view.el (mm-w3m-cid-retrieve-1): Don't use recursive call excessively.
author Miles Bader <miles@gnu.org>
date Tue, 19 Oct 2004 22:38:28 +0000
parents 645f020dcc8a
children c660fc46d193
line wrap: on
line diff
--- a/lisp/gnus/gnus-start.el	Tue Oct 19 21:39:28 2004 +0000
+++ b/lisp/gnus/gnus-start.el	Tue Oct 19 22:38:28 2004 +0000
@@ -1,5 +1,5 @@
 ;;; gnus-start.el --- startup functions for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
@@ -34,8 +34,15 @@
 (require 'gnus-util)
 (autoload 'message-make-date "message")
 (autoload 'gnus-agent-read-servers-validate "gnus-agent")
+(autoload 'gnus-agent-save-local "gnus-agent")
 (autoload 'gnus-agent-possibly-alter-active "gnus-agent")
-(eval-when-compile (require 'cl))
+
+(eval-when-compile 
+  (require 'cl)
+
+  (defvar gnus-agent-covered-methods nil)
+  (defvar gnus-agent-file-loading-local nil)
+  (defvar gnus-agent-file-loading-cache nil))
 
 (defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc")
   "Your `.newsrc' file.
@@ -663,6 +670,8 @@
   (setq gnus-list-of-killed-groups nil
 	gnus-have-read-active-file nil
         gnus-agent-covered-methods nil
+        gnus-agent-file-loading-local nil
+        gnus-agent-file-loading-cache nil
         gnus-server-method-cache nil
 	gnus-newsrc-alist nil
 	gnus-newsrc-hashtb nil
@@ -1511,12 +1520,21 @@
 		    (gnus-active group))
 	       (gnus-active group)
 
+             ;; If a cache is present, we may have to alter the active info.
+             (when gnus-use-cache
+               (inline (gnus-cache-possibly-alter-active
+                        group active)))
+
+             ;; If the agent is enabled, we may have to alter the active info.
+             (when gnus-agent
+               (gnus-agent-possibly-alter-active group active))
+
 	     (gnus-set-active group active)
 	     ;; Return the new active info.
 	     active)))))
 
 (defun gnus-get-unread-articles-in-group (info active &optional update)
-  (when active
+  (when (and info active)
     ;; Allow the backend to update the info in the group.
     (when (and update
 	       (gnus-request-update-info
@@ -1526,6 +1544,10 @@
 
     (let* ((range (gnus-info-read info))
 	   (num 0))
+
+      ;; These checks are present in gnus-activate-group but skipped
+      ;; due to setting dont-check in the preceeding call.
+
       ;; If a cache is present, we may have to alter the active info.
       (when (and gnus-use-cache info)
 	(inline (gnus-cache-possibly-alter-active
@@ -1533,8 +1555,7 @@
 
       ;; If the agent is enabled, we may have to alter the active info.
       (when (and gnus-agent info)
-	(gnus-agent-possibly-alter-active
-	 (gnus-info-group info) active))
+	(gnus-agent-possibly-alter-active (gnus-info-group info) active info))
 
       ;; Modify the list of read articles according to what articles
       ;; are available; then tally the unread articles and add the
@@ -1630,7 +1651,7 @@
 
     (while newsrc
       (setq active (gnus-active (setq group (gnus-info-group
-					     (setq info (pop newsrc))))))
+						  (setq info (pop newsrc))))))
 
       ;; Check newsgroups.  If the user doesn't want to check them, or
       ;; they can't be checked (for instance, if the news server can't
@@ -1653,61 +1674,60 @@
       (when (and method
 		 (not (setq method-type (cdr (assoc method type-cache)))))
 	(setq method-type
-	      (cond
-	       ((gnus-secondary-method-p method)
-		'secondary)
-	       ((inline (gnus-server-equal gnus-select-method method))
-		'primary)
-	       (t
-		'foreign)))
+		   (cond
+		    ((gnus-secondary-method-p method)
+		     'secondary)
+		    ((inline (gnus-server-equal gnus-select-method method))
+		     'primary)
+		    (t
+		     'foreign)))
 	(push (cons method method-type) type-cache))
-      (if (and method
-	       (eq method-type 'foreign))
-	  ;; These groups are foreign.  Check the level.
-	  (when (and (<= (gnus-info-level info) foreign-level)
-		     (setq active (gnus-activate-group group 'scan)))
-	    ;; Let the Gnus agent save the active file.
-	    (when (and gnus-agent active (gnus-online method))
-	      (gnus-agent-save-group-info
-	       method (gnus-group-real-name group) active))
-	    (unless (inline (gnus-virtual-group-p group))
-	      (inline (gnus-close-group group)))
-	    (when (fboundp (intern (concat (symbol-name (car method))
-					   "-request-update-info")))
-	      (inline (gnus-request-update-info info method))))
-	;; These groups are native or secondary.
-	(cond
-	 ;; We don't want these groups.
-	 ((> (gnus-info-level info) level)
-	  (setq active 'ignore))
-	 ;; Activate groups.
-	 ((not gnus-read-active-file)
-	  (if (gnus-check-backend-function 'retrieve-groups group)
-	      ;; if server support gnus-retrieve-groups we push
-	      ;; the group onto retrievegroups for later checking
-	      (if (assoc method retrieve-groups)
-		  (setcdr (assoc method retrieve-groups)
-			  (cons group (cdr (assoc method retrieve-groups))))
-		(push (list method group) retrieve-groups))
-	    ;; hack: `nnmail-get-new-mail' changes the mail-source depending
-	    ;; on the group, so we must perform a scan for every group
-	    ;; if the users has any directory mail sources.
-	    ;; hack: if `nnmail-scan-directory-mail-source-once' is non-nil,
-	    ;; for it scan all spool files even when the groups are
-	    ;; not required.
-	    (if (and
-		 (or nnmail-scan-directory-mail-source-once
-		     (null (assq 'directory
-				 (or mail-sources
-				     (if (listp nnmail-spool-file)
-					 nnmail-spool-file
-				       (list nnmail-spool-file))))))
-		 (member method scanned-methods))
-		(setq active (gnus-activate-group group))
-	      (setq active (gnus-activate-group group 'scan))
-	      (push method scanned-methods))
-	    (when active
-	      (gnus-close-group group))))))
+
+      (cond ((and method (eq method-type 'foreign))
+	     ;; These groups are foreign.  Check the level.
+	     (when (and (<= (gnus-info-level info) foreign-level)
+			(setq active (gnus-activate-group group 'scan)))
+	       ;; Let the Gnus agent save the active file.
+	       (when (and gnus-agent active (gnus-online method))
+		 (gnus-agent-save-group-info
+		  method (gnus-group-real-name group) active))
+	       (unless (inline (gnus-virtual-group-p group))
+		 (inline (gnus-close-group group)))
+	       (when (fboundp (intern (concat (symbol-name (car method))
+					      "-request-update-info")))
+		 (inline (gnus-request-update-info info method)))))
+	    ;; These groups are native or secondary.
+	    ((> (gnus-info-level info) level)
+	     ;; We don't want these groups.
+	     (setq active 'ignore))
+	    ;; Activate groups.
+	    ((not gnus-read-active-file)
+	     (if (gnus-check-backend-function 'retrieve-groups group)
+		 ;; if server support gnus-retrieve-groups we push
+		 ;; the group onto retrievegroups for later checking
+		 (if (assoc method retrieve-groups)
+		     (setcdr (assoc method retrieve-groups)
+			     (cons group (cdr (assoc method retrieve-groups))))
+		   (push (list method group) retrieve-groups))
+	       ;; hack: `nnmail-get-new-mail' changes the mail-source depending
+	       ;; on the group, so we must perform a scan for every group
+	       ;; if the users has any directory mail sources.
+	       ;; hack: if `nnmail-scan-directory-mail-source-once' is non-nil,
+	       ;; for it scan all spool files even when the groups are
+	       ;; not required.
+	       (if (and
+		    (or nnmail-scan-directory-mail-source-once
+			(null (assq 'directory
+				    (or mail-sources
+					(if (listp nnmail-spool-file)
+					    nnmail-spool-file
+					  (list nnmail-spool-file))))))
+		    (member method scanned-methods))
+		   (setq active (gnus-activate-group group))
+		 (setq active (gnus-activate-group group 'scan))
+		 (push method scanned-methods))
+	       (when active
+		 (gnus-close-group group)))))
 
       ;; Get the number of unread articles in the group.
       (cond
@@ -1734,8 +1754,8 @@
 	  (when (gnus-check-backend-function 'request-scan (car method))
 	    (gnus-request-scan nil method))
 	  (gnus-read-active-file-2
-	   (mapcar (lambda (group) (gnus-group-real-name group)) groups)
-	   method)
+		(mapcar (lambda (group) (gnus-group-real-name group)) groups)
+		method)
 	  (dolist (group groups)
 	    (cond
 	     ((setq active (gnus-active (gnus-info-group
@@ -1980,10 +2000,10 @@
 	  (while (setq info (pop newsrc))
 	    (when (inline
 		    (gnus-server-equal
-		     (inline
-		       (gnus-find-method-for-group
-			(gnus-info-group info) info))
-		     gmethod))
+			  (inline
+			    (gnus-find-method-for-group
+				  (gnus-info-group info) info))
+			  gmethod))
 	      (push (gnus-group-real-name (gnus-info-group info))
 		    groups)))
 	  (gnus-read-active-file-2 groups method)))
@@ -2127,7 +2147,7 @@
 	     (gnus-online method)
 	     (gnus-agent-method-p method))
 	(progn
-	  (gnus-agent-save-groups method)
+	  (gnus-agent-save-active method)
 	  (gnus-active-to-gnus-format method hashtb nil real-active))
 
       (goto-char (point-min))
@@ -2203,17 +2223,93 @@
       (gnus-convert-old-newsrc))))
 
 (defun gnus-convert-old-newsrc ()
-  "Convert old newsrc into the new format, if needed."
+  "Convert old newsrc formats into the current format, if needed."
   (let ((fcv (and gnus-newsrc-file-version
 		  (gnus-continuum-version gnus-newsrc-file-version))))
-    (cond
-     ;; No .newsrc.eld file was loaded.
-     ((null fcv) nil)
-     ;; Gnus 5 .newsrc.eld was loaded.
-     ((< fcv (gnus-continuum-version "September Gnus v0.1"))
-      (gnus-convert-old-ticks)))))
+    (when fcv
+      ;; A newsrc file was loaded.
+      (let (prompt-displayed
+            (converters
+             (sort
+              (mapcar (lambda (date-func)
+                        (cons (gnus-continuum-version (car date-func))
+                              date-func))
+                      ;; This is a list of converters that must be run
+                      ;; to bring the newsrc file up to the current
+                      ;; version.  If you create an incompatibility
+                      ;; with older versions, you should create an
+                      ;; entry here.  The entry should consist of the
+                      ;; current gnus version (hardcoded so that it
+                      ;; doesn't change with each release) and the
+                      ;; function that must be applied to convert the
+                      ;; previous version into the current version.
+                      '(("September Gnus v0.1" nil 
+                         gnus-convert-old-ticks)
+                        ("Oort Gnus v0.08"     "legacy-gnus-agent"
+                         gnus-agent-convert-to-compressed-agentview)
+                        ("No Gnus v0.2"        "legacy-gnus-agent"
+                         gnus-agent-unlist-expire-days)
+                        ("No Gnus v0.2"        "legacy-gnus-agent" 
+                         gnus-agent-unhook-expire-days)))
+              #'car-less-than-car)))
+        ;; Skip converters older than the file version
+        (while (and converters (>= fcv (caar converters)))
+          (pop converters))
 
-(defun gnus-convert-old-ticks ()
+        ;; Perform converters to bring older version up to date.
+	(when (and converters (< fcv (caar converters)))
+	  (while (and converters (< fcv (caar converters)))
+            (let* ((converter-spec  (pop converters))
+                   (convert-to      (nth 1 converter-spec))
+                   (load-from       (nth 2 converter-spec))
+                   (func            (nth 3 converter-spec)))
+              (when (and load-from
+                         (not (fboundp func)))
+                (load load-from t))
+              
+              (or prompt-displayed
+                  (not (gnus-convert-converter-needs-prompt func))
+                  (while (let (c
+                               (cursor-in-echo-area t)
+                               (echo-keystrokes 0))
+                           (message "Convert gnus from version '%s' to '%s'? (n/y/?)"
+                                    gnus-newsrc-file-version gnus-version)
+                           (setq c (read-char-exclusive))
+
+                           (cond ((or (eq c ?n) (eq c ?N))
+                                  (error "Can not start gnus without converting"))
+                                 ((or (eq c ?y) (eq c ?Y))
+                                  (setq prompt-displayed t)
+                                  nil)
+                                 ((eq c ?\?)
+                                  (message "This conversion is irreversible. \
+ To be safe, you should backup your files before proceeding.")
+                                  (sit-for 5)
+                                  t)
+                                 (t
+                                  (gnus-message 3 "Ignoring unexpected input")
+                                  (sit-for 3)
+                                  t)))))
+
+              (funcall func convert-to)))
+          (gnus-dribble-enter 
+           (format ";Converted gnus from version '%s' to '%s'."
+                   gnus-newsrc-file-version gnus-version)))))))
+
+(defun gnus-convert-mark-converter-prompt (converter no-prompt)
+  "Indicate whether CONVERTER requires gnus-convert-old-newsrc to
+  display the conversion prompt.  NO-PROMPT may be nil (prompt),
+  t (no prompt), or any form that can be called as a function.
+  The form should return either t or nil."
+  (put converter 'gnus-convert-no-prompt no-prompt))
+
+(defun gnus-convert-converter-needs-prompt (converter)
+  (let ((no-prompt (get converter 'gnus-convert-no-prompt)))
+    (not (if (memq no-prompt '(t nil))
+	     no-prompt
+	   (funcall no-prompt)))))
+
+(defun gnus-convert-old-ticks (converting-to)
   (let ((newsrc (cdr gnus-newsrc-alist))
 	marks info dormant ticked)
     (while (setq info (pop newsrc))
@@ -2593,6 +2689,10 @@
   ;; from the variable gnus-newsrc-alist.
   (when (and (or gnus-newsrc-alist gnus-killed-list)
 	     gnus-current-startup-file)
+    ;; Save agent range limits for the currently active method.
+    (when gnus-agent
+      (gnus-agent-save-local force))
+
     (save-excursion
       (if (and (or gnus-use-dribble-file gnus-slave)
 	       (not force)
@@ -2610,6 +2710,7 @@
 	    (gnus-message 8 "Saving %s..." gnus-current-startup-file)
 	    (gnus-gnus-to-newsrc-format)
 	    (gnus-message 8 "Saving %s...done" gnus-current-startup-file))
+
 	  ;; Save .newsrc.eld.
 	  (set-buffer (gnus-get-buffer-create " *Gnus-newsrc*"))
 	  (make-local-variable 'version-control)