* nnmaildir.el (nnmaildir-request-set-mark): Handle the "too many
[gnus] / lisp / gnus-start.el
index 34b77f6..cd1154f 100644 (file)
 (require 'gnus-spec)
 (require 'gnus-range)
 (require 'gnus-util)
-(require 'message)
-(eval-when-compile (require 'cl))
+(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)
+
+  (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.
@@ -242,7 +251,12 @@ nil if you set this variable to nil.
 This variable can also be a regexp.  In that case, all groups that do
 not match this regexp will be removed before saving the list."
   :group 'gnus-newsrc
-  :type 'boolean)
+  :type '(radio (sexp :format "Non-nil\n"
+                     :match (lambda (widget value)
+                              (and value (not (stringp value))))
+                     :value t)
+               (const nil)
+               (regexp :format "%t: %v\n" :size 0)))
 
 (defcustom gnus-ignored-newsgroups
   (mapconcat 'identity
@@ -281,8 +295,8 @@ claim them."
                (repeat function)))
 
 (defcustom gnus-subscribe-newsgroup-hooks nil
-  "*Hooks run after you subscribe to a new group. The hooks will be called
-with new group's name as argument."
+  "*Hooks run after you subscribe to a new group.
+The hooks will be called with new group's name as argument."
   :group 'gnus-group-new
   :type 'hook)
 
@@ -381,7 +395,7 @@ This hook is called as the first thing when Gnus is started."
   :group 'gnus-start
   :type 'hook)
 
-(defcustom gnus-setup-news-hook 
+(defcustom gnus-setup-news-hook
   '(gnus-fixup-nnimap-unread-after-getting-new-news)
   "A hook after reading the .newsrc file, but before generating the buffer."
   :group 'gnus-start
@@ -398,7 +412,7 @@ This hook is called as the first thing when Gnus is started."
   :type 'hook)
 
 (defcustom gnus-after-getting-new-news-hook
-  '(gnus-display-time-event-handler 
+  '(gnus-display-time-event-handler
     gnus-fixup-nnimap-unread-after-getting-new-news)
   "*A hook run after Gnus checks for new news when Gnus is already running."
   :group 'gnus-group-new
@@ -552,7 +566,7 @@ Can be used to turn version control on or off."
   (gnus-subscribe-newsgroup newsgroup))
 
 (defun gnus-subscribe-alphabetically (newgroup)
-  "Subscribe new NEWSGROUP and insert it in alphabetical order."
+  "Subscribe new NEWGROUP and insert it in alphabetical order."
   (let ((groups (cdr gnus-newsrc-alist))
        before)
     (while (and (not before) groups)
@@ -562,7 +576,7 @@ Can be used to turn version control on or off."
     (gnus-subscribe-newsgroup newgroup before)))
 
 (defun gnus-subscribe-hierarchically (newgroup)
-  "Subscribe new NEWSGROUP and insert it in hierarchical newsgroup order."
+  "Subscribe new NEWGROUP and insert it in hierarchical newsgroup order."
   ;; Basic ideas by mike-w@cs.aukuni.ac.nz (Mike Williams)
   (save-excursion
     (set-buffer (nnheader-find-file-noselect gnus-current-startup-file))
@@ -608,8 +622,7 @@ the first newsgroup."
     ;; We subscribe the group by changing its level to `subscribed'.
     (gnus-group-change-level
      newsgroup gnus-level-default-subscribed
-     gnus-level-killed (gnus-gethash (or next "dummy.group")
-                                    gnus-newsrc-hashtb))
+     gnus-level-killed (gnus-group-entry (or next "dummy.group")))
     (gnus-message 5 "Subscribe newsgroup: %s" newsgroup)
     (run-hook-with-args 'gnus-subscribe-newsgroup-hooks newsgroup)
     t))
@@ -653,6 +666,10 @@ the first newsgroup."
   ;; Clear other internal variables.
   (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
        gnus-killed-list nil
@@ -759,11 +776,6 @@ prompt the user for the name of an NNTP server to use."
          (when (or gnus-slave gnus-use-dribble-file)
            (gnus-dribble-read-file))
 
-         ;; Allow using GroupLens predictions.
-         (when gnus-use-grouplens
-           (bbb-login)
-           (add-hook 'gnus-summary-mode-hook 'gnus-grouplens-mode))
-
          ;; Do the actual startup.
          (if gnus-agent
              (gnus-request-create-group "queue" '(nndraft "")))
@@ -781,7 +793,7 @@ prompt the user for the name of an NNTP server to use."
 (defun gnus-start-draft-setup ()
   "Make sure the draft group exists."
   (gnus-request-create-group "drafts" '(nndraft ""))
-  (unless (gnus-gethash "nndraft:drafts" gnus-newsrc-hashtb)
+  (unless (gnus-group-entry "nndraft:drafts")
     (let ((gnus-level-default-subscribed 1))
       (gnus-subscribe-group "nndraft:drafts" nil '(nndraft "")))
     (gnus-group-set-parameter
@@ -947,6 +959,15 @@ If LEVEL is non-nil, the news will be set up at level LEVEL."
              (eq gnus-read-active-file 'some))
       (gnus-update-active-hashtb-from-killed))
 
+    ;; Validate agent covered methods now that gnus-server-alist has
+    ;; been initialized.
+    ;; NOTE: This is here for one purpose only.  By validating the
+    ;; agentized server's, it converts the old 5.10.3, and earlier,
+    ;; format to the current format.  That enables the agent code
+    ;; within gnus-read-active-file to function correctly.
+    (if gnus-agent
+        (gnus-agent-read-servers-validate))
+
     ;; Read the active file and create `gnus-active-hashtb'.
     ;; If `gnus-read-active-file' is nil, then we just create an empty
     ;; hash table.  The partial filling out of the hash table will be
@@ -1013,7 +1034,7 @@ If LEVEL is non-nil, the news will be set up at level LEVEL."
   "Call METHOD to subscribe GROUP.
 If no function returns `non-nil', call `gnus-subscribe-zombies'."
   (unless (cond
-          ((gnus-functionp method)
+          ((functionp method)
            (funcall method group))
           ((listp method)
            (catch 'found
@@ -1242,7 +1263,7 @@ for new groups, and subscribe the new groups as zombies."
          (gnus-message 7 "`A k' to list killed groups"))))))
 
 (defun gnus-subscribe-group (group &optional previous method)
-  "Subcribe GROUP and put it after PREVIOUS."
+  "Subscribe GROUP and put it after PREVIOUS."
   (gnus-group-change-level
    (if method
        (list t group gnus-level-default-subscribed nil nil method)
@@ -1277,16 +1298,16 @@ for new groups, and subscribe the new groups as zombies."
     (when (and (stringp entry)
               oldlevel
               (< oldlevel gnus-level-zombie))
-      (setq entry (gnus-gethash entry gnus-newsrc-hashtb)))
+      (setq entry (gnus-group-entry entry)))
     (if (and (not oldlevel)
             (consp entry))
        (setq oldlevel (gnus-info-level (nth 2 entry)))
       (setq oldlevel (or oldlevel gnus-level-killed)))
     (when (stringp previous)
-      (setq previous (gnus-gethash previous gnus-newsrc-hashtb)))
+      (setq previous (gnus-group-entry previous)))
 
     (if (and (>= oldlevel gnus-level-zombie)
-            (gnus-gethash group gnus-newsrc-hashtb))
+            (gnus-group-entry group))
        ;; We are trying to subscribe a group that is already
        ;; subscribed.
        ()                              ; Do nothing.
@@ -1310,8 +1331,7 @@ for new groups, and subscribe the new groups as zombies."
                   entry)
          (gnus-sethash (car (nth 2 entry)) nil gnus-newsrc-hashtb)
          (when (nth 3 entry)
-           (setcdr (gnus-gethash (car (nth 3 entry))
-                                 gnus-newsrc-hashtb)
+           (setcdr (gnus-group-entry (car (nth 3 entry)))
                    (cdr entry)))
          (setcdr (cdr entry) (cdddr entry)))))
 
@@ -1371,7 +1391,7 @@ for new groups, and subscribe the new groups as zombies."
            (gnus-sethash group (cons num previous)
                          gnus-newsrc-hashtb))
          (when (cdr entry)
-           (setcdr (gnus-gethash (caadr entry) gnus-newsrc-hashtb) entry))
+           (setcdr (gnus-group-entry (caadr entry)) entry))
          (gnus-dribble-enter
           (format
            "(gnus-group-set-info '%S)" info)))))
@@ -1382,7 +1402,7 @@ for new groups, and subscribe the new groups as zombies."
 (defun gnus-kill-newsgroup (newsgroup)
   "Obsolete function.  Kills a newsgroup."
   (gnus-group-change-level
-   (gnus-gethash newsgroup gnus-newsrc-hashtb) gnus-level-killed))
+   (gnus-group-entry newsgroup) gnus-level-killed))
 
 (defun gnus-check-bogus-newsgroups (&optional confirm)
   "Remove bogus newsgroups.
@@ -1410,14 +1430,14 @@ newsgroup."
           (lambda (group)
             ;; Remove all bogus subscribed groups by first killing them, and
             ;; then removing them from the list of killed groups.
-            (when (setq entry (gnus-gethash group gnus-newsrc-hashtb))
+            (when (setq entry (gnus-group-entry group))
               (gnus-group-change-level entry gnus-level-killed)
               (setq gnus-killed-list (delete group gnus-killed-list))))
           bogus '("group" "groups" "remove"))
        (while (setq group (pop bogus))
          ;; Remove all bogus subscribed groups by first killing them, and
          ;; then removing them from the list of killed groups.
-         (when (setq entry (gnus-gethash group gnus-newsrc-hashtb))
+         (when (setq entry (gnus-group-entry group))
            (gnus-group-change-level entry gnus-level-killed)
            (setq gnus-killed-list (delete group gnus-killed-list)))))
       ;; Then we remove all bogus groups from the list of killed and
@@ -1490,6 +1510,16 @@ newsgroup."
                    (zerop (cdr active))
                    (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)))))
@@ -1505,10 +1535,19 @@ newsgroup."
 
     (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
                 (gnus-info-group info) active)))
+
+      ;; 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 info))
+
       ;; Modify the list of read articles according to what articles
       ;; are available; then tally the unread articles and add the
       ;; number to the group hash table entry.
@@ -1576,8 +1615,8 @@ newsgroup."
        (setq num (max 0 (- (cdr active) num)))))
       ;; Set the number of unread articles.
       (when (and info
-                (gnus-gethash (gnus-info-group info) gnus-newsrc-hashtb))
-       (setcar (gnus-gethash (gnus-info-group info) gnus-newsrc-hashtb) num))
+                (gnus-group-entry (gnus-info-group info)))
+       (setcar (gnus-group-entry (gnus-info-group info)) num))
       num)))
 
 ;; Go though `gnus-newsrc-alist' and compare with `gnus-active-hashtb'
@@ -1595,7 +1634,10 @@ newsgroup."
                  gnus-activate-foreign-newsgroups)
                 (t 0))
           level))
-        scanned-methods info group active method retrieve-groups)
+        (methods-cache nil)
+        (type-cache nil)
+        scanned-methods info group active method retrieve-groups cmethod
+        method-type)
     (gnus-message 6 "Checking new news...")
 
     (while newsrc
@@ -1614,12 +1656,25 @@ newsgroup."
       ;; nil for non-foreign groups that the user has requested not be checked
       ;; t for unchecked foreign groups or bogus groups, or groups that can't
       ;;   be checked, for one reason or other.
-      (if (and (setq method (gnus-info-method info))
-              (not (inline
-                     (gnus-server-equal
-                      gnus-select-method
-                      (setq method (gnus-server-get-method nil method)))))
-              (not (gnus-secondary-method-p method)))
+      (when (setq method (gnus-info-method info))
+       (if (setq cmethod (assoc method methods-cache))
+           (setq method (cdr cmethod))
+         (setq cmethod (inline (gnus-server-get-method nil method)))
+         (push (cons method cmethod) methods-cache)
+         (setq method cmethod)))
+      (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)))
+       (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)))
@@ -1677,7 +1732,7 @@ newsgroup."
        ;; The group couldn't be reached, so we nix out the number of
        ;; unread articles and stuff.
        (gnus-set-active group nil)
-       (let ((tmp (gnus-gethash group gnus-newsrc-hashtb)))
+       (let ((tmp (gnus-group-entry group)))
          (when tmp
            (setcar tmp t))))))
 
@@ -1702,7 +1757,7 @@ newsgroup."
              ;; The group couldn't be reached, so we nix out the number of
              ;; unread articles and stuff.
              (gnus-set-active group nil)
-             (setcar (gnus-gethash group gnus-newsrc-hashtb) t)))))))
+             (setcar (gnus-group-entry group) t)))))))
 
     (gnus-message 6 "Checking new news...done")))
 
@@ -1754,9 +1809,9 @@ newsgroup."
 
 (defun gnus-make-articles-unread (group articles)
   "Mark ARTICLES in GROUP as unread."
-  (let* ((info (nth 2 (or (gnus-gethash group gnus-newsrc-hashtb)
-                         (gnus-gethash (gnus-group-real-name group)
-                                       gnus-newsrc-hashtb))))
+  (let* ((info (nth 2 (or (gnus-group-entry group)
+                         (gnus-group-entry
+                          (gnus-group-real-name group)))))
         (ranges (gnus-info-read info))
         news article)
     (while articles
@@ -1776,9 +1831,8 @@ newsgroup."
 
 (defun gnus-make-ascending-articles-unread (group articles)
   "Mark ascending ARTICLES in GROUP as unread."
-  (let* ((entry (or (gnus-gethash group gnus-newsrc-hashtb)
-                    (gnus-gethash (gnus-group-real-name group)
-                                  gnus-newsrc-hashtb)))
+  (let* ((entry (or (gnus-group-entry group)
+                    (gnus-group-entry (gnus-group-real-name group))))
          (info (nth 2 entry))
         (ranges (gnus-info-read info))
          (r ranges)
@@ -1958,7 +2012,7 @@ newsgroup."
          (gnus-message 5 "%sdone" mesg)))))))
 
 (defun gnus-read-active-file-2 (groups method)
-  "Read an active file for GROUPS in METHOD using gnus-retrieve-groups."
+  "Read an active file for GROUPS in METHOD using `gnus-retrieve-groups'."
   (when groups
     (save-excursion
       (set-buffer nntp-server-buffer)
@@ -2027,7 +2081,7 @@ newsgroup."
       (while (not (eobp))
        (condition-case ()
            (progn
-             (narrow-to-region (point) (gnus-point-at-eol))
+             (narrow-to-region (point) (point-at-eol))
              ;; group gets set to a symbol interned in the hash table
              ;; (what a hack!!) - jwz
              (setq group (let ((obarray hashtb)) (read cur)))
@@ -2059,7 +2113,7 @@ newsgroup."
           (unless ignore-errors
             (gnus-message 3 "Warning - invalid active: %s"
                           (buffer-substring
-                           (gnus-point-at-bol) (gnus-point-at-eol))))))
+                           (point-at-bol) (point-at-eol))))))
        (widen)
        (forward-line 1)))))
 
@@ -2084,7 +2138,7 @@ newsgroup."
             (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))
@@ -2160,17 +2214,68 @@ If FORCE is non-nil, the .newsrc file is read."
       (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)))))
-
-(defun gnus-convert-old-ticks ()
+    (when fcv
+      ;; A .newsrc.eld file was loaded.
+      (let ((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)))
+              #'car-less-than-car)))
+        ;; Skip converters older than the file version
+        (while (and converters (>= fcv (caar converters)))
+          (pop converters))
+
+        ;; Perform converters to bring older version up to date.
+        (when (and converters 
+                   (< fcv (caar converters)))
+          (while (let (c
+                       (cursor-in-echo-area t)
+                       (echo-keystrokes 0))
+                   (message "Convert newsrc 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 using old (unconverted) newsrc"))
+                         ((or (eq c ?y) (eq c ?Y))
+                          nil)
+                         ((eq c ?\?)
+                          (message "This conversion is irreversible. \
+ You should backup your files before proceeding.")
+                          (sit-for 5)
+                          t)
+                         (t
+                          (gnus-message 3 "Ignoring unexpected input")
+                          (sit-for 3)
+                          t))))
+          (while (and converters (< fcv (caar converters)))
+            (let* ((converter  (pop converters))
+                   (convert-to (nth 1 converter))
+                   (load-from  (nth 2 converter))
+                   (func       (nth 3 converter)))
+              (when (and load-from
+                         (not (fboundp func)))
+                (load load-from t))
+              (funcall func convert-to)))
+          (gnus-dribble-enter 
+           (format ";Converted newsrc from version '%s' to '%s'? (n/y/?)"
+                   gnus-newsrc-file-version gnus-version)))))))
+
+(defun gnus-convert-old-ticks (converting-to)
   (let ((newsrc (cdr gnus-newsrc-alist))
        marks info dormant ticked)
     (while (setq info (pop newsrc))
@@ -2334,7 +2439,7 @@ If FORCE is non-nil, the .newsrc file is read."
              ;; don't give a damn, frankly, my dear.
              (concat gnus-newsrc-options
                      (buffer-substring
-                      (gnus-point-at-bol)
+                      (point-at-bol)
                       ;; Options may continue on the next line.
                       (or (and (re-search-forward "^[^ \t]" nil 'move)
                                (progn (beginning-of-line) (point)))
@@ -2405,8 +2510,8 @@ If FORCE is non-nil, the .newsrc file is read."
                ;; The line was buggy.
                (setq group nil)
                (gnus-error 3.1 "Mangled line: %s"
-                           (buffer-substring (gnus-point-at-bol)
-                                             (gnus-point-at-eol))))
+                           (buffer-substring (point-at-bol)
+                                             (point-at-eol))))
              nil))
          ;; Skip past ", ".  Spaces are invalid in these ranges, but
          ;; we allow them, because it's a common mistake to put a
@@ -2515,9 +2620,9 @@ If FORCE is non-nil, the .newsrc file is read."
       (while (re-search-forward "[ \t]-n" nil t)
        (setq eol
              (or (save-excursion
-                   (and (re-search-forward "[ \t]-n" (gnus-point-at-eol) t)
+                   (and (re-search-forward "[ \t]-n" (point-at-eol) t)
                         (- (point) 2)))
-                 (gnus-point-at-eol)))
+                 (point-at-eol)))
        ;; Search for all "words"...
        (while (re-search-forward "[^ \t,\n]+" eol t)
          (if (eq (char-after (match-beginning 0)) ?!)
@@ -2550,6 +2655,10 @@ If FORCE is non-nil, the .newsrc file is read."
   ;; 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)
@@ -2567,6 +2676,7 @@ If FORCE is non-nil, the .newsrc file is read."
            (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)
@@ -2631,19 +2741,25 @@ If FORCE is non-nil, the .newsrc file is read."
        (gnus-dribble-delete-file)
        (gnus-group-set-mode-line)))))
 
-(defun gnus-gnus-to-quick-newsrc-format ()
-  "Print Gnus variables such as gnus-newsrc-alist in lisp format."
+(defun gnus-gnus-to-quick-newsrc-format (&optional minimal name &rest specific-variables)
+  "Print Gnus variables such as `gnus-newsrc-alist' in Lisp format."
     (princ ";; -*- emacs-lisp -*-\n")
-    (princ ";; Gnus startup file.\n")
-    (princ "\
+    (if name
+       (princ (format ";; %s\n" name))
+      (princ ";; Gnus startup file.\n"))
+
+    (unless minimal
+      (princ "\
 ;; Never delete this file -- if you want to force Gnus to read the
 ;; .newsrc file (if you have one), touch .newsrc instead.\n")
-    (princ "(setq gnus-newsrc-file-version ")
-    (princ (gnus-prin1-to-string gnus-version))
-    (princ ")\n")
+      (princ "(setq gnus-newsrc-file-version ")
+      (princ (gnus-prin1-to-string gnus-version))
+      (princ ")\n"))
+
     (let* ((print-quoted t)
            (print-readably t)
            (print-escape-multibyte nil)
+           (print-escape-nonascii t)
            (print-length nil)
            (print-level nil)
            (print-escape-newlines t)
@@ -2653,10 +2769,11 @@ If FORCE is non-nil, the .newsrc file is read."
                (gnus-strip-killed-list)
              gnus-killed-list))
           (variables
-           (if gnus-save-killed-list gnus-variable-list
-             ;; Remove the `gnus-killed-list' from the list of variables
-             ;; to be saved, if required.
-             (delq 'gnus-killed-list (copy-sequence gnus-variable-list))))
+           (or specific-variables
+               (if gnus-save-killed-list gnus-variable-list
+                 ;; Remove the `gnus-killed-list' from the list of variables
+                 ;; to be saved, if required.
+                 (delq 'gnus-killed-list (copy-sequence gnus-variable-list)))))
           ;; Peel off the "dummy" group.
           (gnus-newsrc-alist (cdr gnus-newsrc-alist))
           variable)
@@ -2745,7 +2862,7 @@ If FORCE is non-nil, the .newsrc file is read."
 
 (defun gnus-slave-mode ()
   "Minor mode for slave Gnusae."
-  (gnus-add-minor-mode 'gnus-slave-mode " Slave" (make-sparse-keymap))
+  (add-minor-mode 'gnus-slave-mode " Slave" (make-sparse-keymap))
   (gnus-run-hooks 'gnus-slave-mode-hook))
 
 (defun gnus-slave-save-newsrc ()
@@ -2883,6 +3000,7 @@ If FORCE is non-nil, the .newsrc file is read."
                      (or (gnus-group-name-charset method name)
                          (gnus-parameter-charset name)
                          gnus-default-charset)))
+               ;; Fixme: Don't decode in unibyte mode.
                (when (and str charset (featurep 'mule))
                  (setq str (mm-decode-coding-string str charset)))
                (set group str)))
@@ -2901,7 +3019,7 @@ If FORCE is non-nil, the .newsrc file is read."
 
 ;;;###autoload
 (defun gnus-declare-backend (name &rest abilities)
-  "Declare backend NAME with ABILITIES as a Gnus backend."
+  "Declare back end NAME with ABILITIES as a Gnus back end."
   (setq gnus-valid-select-methods
        (nconc gnus-valid-select-methods
               (list (apply 'list name abilities))))
@@ -2917,7 +3035,7 @@ If this variable is nil, don't do anything."
          default-directory)))
 
 (eval-and-compile
-(defalias 'gnus-display-time-event-handler 
+(defalias 'gnus-display-time-event-handler
   (if (gnus-boundp 'display-time-timer)
       'display-time-event-handler
     (lambda () "Does nothing as `display-time-timer' is not bound.