*** empty log message ***
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 01:54:41 +0000 (01:54 +0000)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 01:54:41 +0000 (01:54 +0000)
lisp/ChangeLog
lisp/gnus.el
lisp/nnbabyl.el
lisp/nnmbox.el
lisp/nnml.el
lisp/nntp.el
texi/gnus.texi

index cbd7ea3..bd4298c 100644 (file)
@@ -1,3 +1,31 @@
+Thu Apr 20 06:36:33 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.el (gnus-setup-news): Read .newsrc.eld before reading the
+       active file.
+       (gnus-group-edit-group-parameters): New command and keystroke.
+
+       * nntp.el (nntp-server-list-active-group): Improperly initialised. 
+
+       * gnus.el (gnus-retrieve-groups): New function.
+       (gnus-groups-to-gnus-format): New function.
+       (gnus-read-active-file): New semantics: `some'.
+       (gnus-level-subscribed, gnus-level-unsubscribed,
+       gnus-level-zombie, gnus-level-killed): New variables.
+       (gnus-inews-check-post): Many of the checks didn't actually check
+       anything. 
+       (gnus-check-before-posting): New variable.
+       (gnus-group-edit-group-method): New command and keystroke.
+       (gnus-group-mode-map): Change in keymap for edit-group.
+       (gnus-server-extend-method): Didn{t properly recognise native
+       groups. 
+
+       * gnus.el: Changes throughout to use the level variables instead
+       of the hard-coded level numbers.
+
+Thu Apr 20 04:23:34 1995  Lars Magne Ingebrigtsen  <larsi@gjalp.ifi.uio.no>
+
+        * gnus.el: 0.53 is released.
+
 Thu Apr 20 01:56:59 1995  Lars Magne Ingebrigtsen  <larsi@gjalp.ifi.uio.no>
 
        * gnus-uu.el (gnus-uu-part-number): New function.
index 5b9c9de..5e7506a 100644 (file)
                  (system-name)))
   "*Default method for selecting a newsgroup.
 This variable should be a list, where the first element is how the
-news is to be fetched, the second is the address.  An optional third
-element can be included to specify a port number if nntp is used.
+news is to be fetched, the second is the address. 
 
 For instance, if you want to get your news via NNTP from
-\"flab.flab.edu\" on port 23, you could say:
+\"flab.flab.edu\", you could say:
 
-(setq gnus-select-method '(nntp \"flab.flab.edu\" 23))
+(setq gnus-select-method '(nntp \"flab.flab.edu\"))
 
 If you want to use your local spool, say:
 
 (setq gnus-select-method (list 'nnspool (system-name)))
 
-If you use this variable, you must set `gnus-nntp-server' to nil.")
+If you use this variable, you must set `gnus-nntp-server' to nil.
+
+There is a lot more to know about select methods and virtual servers -
+see the manual for details.")
 
 ;; Added by Sudish Joseph <joseph@cis.ohio-state.edu>.
 (defvar gnus-post-method nil
@@ -110,7 +112,7 @@ This is an obsolete variable, which is scarcely used. If you use an
 nntp server for your newsgroup and want to change the port number
 used to 899, you would say something along these lines:
 
- (setq gnus-select-method '(nntp \"my.nntp.server\" 899))")
+ (setq gnus-select-method '(nntp \"my.nntp.server\" (nntp-port-number 899)))")
 
 (defvar gnus-startup-file "~/.newsrc"
   "*Your `.newsrc' file.
@@ -413,17 +415,43 @@ check for bogus newsgroups with \\<gnus-group-mode-map>\\[gnus-group-check-bogus
 If this variable is nil, Gnus will only know about the groups in your
 `.newsrc' file.
 
-If you set this variable to nil, you probably still want to be told
-about new newsgroups that arrive.  To do that, set
+If this variable is `some', Gnus will try to only read the relevant
+parts of the active file from the server.  Not all servers support
+this, and it might be quite slow with other servers, but this should
+generally be faster than both the t and nil value.
+
+If you set this variable to nil or `some', you probably still want to
+be told about new newsgroups that arrive.  To do that, set
 `gnus-check-new-newsgroups' to `ask-server'.  This may not work
-properly with all servers.") 
+properly with all servers.")
+
+(defvar gnus-level-subscribed 5
+  "*Groups with levels less than or equal to this variable are subscribed.")
+
+(defvar gnus-level-unsubscribed 7
+  "*Groups with levels less than or equal to this variable are unsubscribed.
+Groups with levels less than `gnus-level-subscribed', which should be
+less than thiss variable, are subscribed.")
+
+(defvar gnus-level-zombie 8
+  "*Groups with this level are zombie groups.")
+
+(defvar gnus-level-killed 9
+  "*Groups with this level are killed.")
+
+(defvar gnus-level-default-subscribed 3
+  "*New subscribed groups will be subscribed at this level.")
+
+(defvar gnus-level-default-unsubscribed 
+  "*New unsubscribed groups will be unsubscribed at this level.")
 
 (defvar gnus-activate-foreign-newsgroups nil
   "*If nil, Gnus will not check foreign newsgroups at startup.
 If it is non-nil, it should be a number between one and nine. Foreign
 newsgroups that have a level lower or equal to this number will be
 activated on startup. For instance, if you want to active all
-subscribed newsgroups, but not the rest, you'd set this variable to 5.
+subscribed newsgroups, but not the rest, you'd set this variable to 
+`gnus-level-subscribed'.
 
 If you subscribe to lots of newsgroups from different servers, startup
 might take a while. By setting this variable to nil, you'll save time,
@@ -493,10 +521,10 @@ score files in the \"/ftp.some-where:/pub/score\" directory.
   "*Default article score level.
 If this variable is nil, scoring will be disabled.")
 
-(defvar gnus-group-default-list-level 5
+(defvar gnus-group-default-list-level gnus-level-subscribed
   "*Default listing level.")
 
-(defvar gnus-group-always-list-unread 5
+(defvar gnus-group-always-list-unread gnus-level-subscribed
   "*Always list groups less than this variable with unread articles. 
 If nil, use parameter to specify.")
 
@@ -585,6 +613,9 @@ If it is non-nil, headers that match the regular expressions will
 be placed first in the article buffer in the sequence specified by
 this list.")
 
+(defvar gnus-check-before-posting t
+  "In non-nil, Gnus will attempt to run some checks on outgoing posts.")
+
 (defvar gnus-required-headers
   '(From Date Newsgroups Subject Message-ID Organization Lines X-Newsreader)
   "*Headers to be generated or prompted for when posting an article.
@@ -777,7 +808,7 @@ with some simple extensions.
 
 %M    Only marked articles (character, \"*\" or \" \")
 %S    Whether the group is subscribed (character, \"U\", \"K\", \"Z\" or \" \")
-%L    Level of subscribedness (integer, 1-9)
+%L    Level of subscribedness (integer)
 %N    Number of unread articles (integer)
 %I    Number of dormant articles (integer)
 %i    Number of ticked and dormant (integer)
@@ -1221,9 +1252,6 @@ of the last succesful match.")
 
 (defvar gnus-newsgroup-dependencies nil)
 (defconst gnus-group-edit-buffer "*Gnus edit newsgroup*")
-(defvar gnus-default-subscribe-level 2)
-(defvar gnus-default-unsubscribe-level 6)
-(defvar gnus-default-kill-level 9)
 
 (defconst gnus-group-line-format-alist
   (list (list ?M 'marked ?c)
@@ -1303,7 +1331,7 @@ variable (string, integer, character, etc).")
 (defconst gnus-maintainer "Lars Magne Ingebrigtsen <larsi@ifi.uio.no>"
   "The mail address of the Gnus maintainer.")
 
-(defconst gnus-version "(ding) Gnus v0.53"
+(defconst gnus-version "(ding) Gnus v0.54"
   "Version number for this version of Gnus.")
 
 (defvar gnus-info-nodes
@@ -2015,9 +2043,10 @@ it is killed."
   "Subscribe new NEWSGROUP.
 If NEXT is non-nil, it is inserted before NEXT. Otherwise it is made
 the first newsgroup."
-  ;; We subscribe the group by changing its level to 3.
+  ;; We subscribe the group by changing its level to `subscribed'.
   (gnus-group-change-level 
-   newsgroup 3 9 (gnus-gethash (or next "dummy.group") gnus-newsrc-hashtb))
+   newsgroup gnus-level-default-subscribed
+   gnus-level-killed (gnus-gethash (or next "dummy.group") gnus-newsrc-hashtb))
   (message "Subscribe newsgroup: %s" newsgroup))
 
 ;; For directories
@@ -2805,7 +2834,7 @@ Note: LIST has to be sorted over `<'."
   (define-key gnus-group-mode-map "\M-f" 'gnus-group-fetch-faq)
   (define-key gnus-group-mode-map "?" 'gnus-group-describe-briefly)
   (define-key gnus-group-mode-map "\C-c\C-i" 'gnus-info-find-node)
-  (define-key gnus-group-mode-map "\M-e" 'gnus-group-edit-group)
+  (define-key gnus-group-mode-map "\M-e" 'gnus-group-edit-group-method)
   (define-key gnus-group-mode-map "^" 'gnus-group-enter-server-mode)
   (define-key gnus-group-mode-map
     (if gnus-xemacs [button2] [mouse-2]) 'gnus-mouse-pick-group)
@@ -2819,7 +2848,9 @@ Note: LIST has to be sorted over `<'."
   (define-key gnus-group-make-map "a" 'gnus-group-make-archive-group)
   (define-key gnus-group-make-map "k" 'gnus-group-make-kiboze-group)
   (define-key gnus-group-make-map "m" 'gnus-group-make-group)
-  (define-key gnus-group-make-map "e" 'gnus-group-edit-group)
+  (define-key gnus-group-make-map "E" 'gnus-group-edit-group)
+  (define-key gnus-group-make-map "e" 'gnus-group-edit-group-method)
+  (define-key gnus-group-make-map "p" 'gnus-group-edit-group-parameters)
 
   (define-prefix-command 'gnus-group-list-map)
   (define-key gnus-group-mode-map "G" 'gnus-group-list-map)
@@ -2891,7 +2922,7 @@ If ARG is non-nil and not a positive number, Gnus will
 prompt the user for the name of an NNTP server to use.
 As opposed to `gnus', this command will not connect to the local server."
   (interactive "P")
-  (gnus (or arg 2) t))
+  (gnus (or arg (1- gnus-level-default-subscribed)) t))
 
 (defalias '\(ding\) 'gnus)
 
@@ -2973,10 +3004,10 @@ prompt the user for the name of an NNTP server to use."
 
 (defun gnus-group-list-groups (level &optional unread)
   "List newsgroups with level LEVEL or lower that have unread alticles.
-Default is 5, which lists all subscribed groups.
+Default is all subscribed groups.
 If argument UNREAD is non-nil, groups with no unread articles are also listed."
   (interactive "P")
-  (setq level (or level gnus-group-default-list-level 5))
+  (setq level (or level gnus-group-default-list-level gnus-level-subscribed))
   (gnus-group-setup-buffer)    ;May call from out of group buffer
   (let ((case-fold-search nil)
        (group (gnus-group-group-name)))
@@ -3017,7 +3048,7 @@ If REGEXP, only list groups matching REGEXP."
        (lowest (or lowest 1))
        info clevel unread group)
     (erase-buffer)
-    (if (< lowest 8)
+    (if (< lowest gnus-level-zombie)
        ;; List living groups.
        (while newsrc
          (setq info (car newsrc)
@@ -3037,14 +3068,15 @@ If REGEXP, only list groups matching REGEXP."
                nil group (car (cdr info)) (nth 3 info) unread (nth 4 info)))))
 
     ;; List dead groups.
-    (and (>= level 8) (<= lowest 8)
+    (and (>= level gnus-level-zombie) (<= lowest gnus-level-zombie)
         (gnus-group-prepare-flat-list-dead 
-         (setq gnus-zombie-list (sort gnus-zombie-list 'string<)) 8 ?Z
+         (setq gnus-zombie-list (sort gnus-zombie-list 'string<)) 
+         gnus-level-zombie ?Z
          regexp))
-    (and (>= level 9) (<= lowest 9)
+    (and (>= level gnus-level-killed) (<= lowest gnus-level-killed)
         (gnus-group-prepare-flat-list-dead 
-         (setq gnus-killed-list (sort gnus-killed-list 'string<)) 9 ?K
-         regexp))
+         (setq gnus-killed-list (sort gnus-killed-list 'string<)) 
+         gnus-level-killed ?K regexp))
 
     (gnus-group-set-mode-line)
     (setq gnus-have-all-newsgroups all)
@@ -3105,8 +3137,26 @@ If REGEXP, only list groups matching REGEXP."
   "Return nil if GROUP is native, non-nil if it is foreign."
   (string-match ":" group))
 
-(defun gnus-group-set-info (info)
-  (let ((entry (gnus-gethash (car info) gnus-newsrc-hashtb)))
+(defun gnus-group-set-info (info &optional method-only-group part)
+  (let* ((entry (gnus-gethash
+                (or method-only-group (car info)) gnus-newsrc-hashtb))
+        (part-info info)
+        (info (if method-only-group (nth 2 entry) info)))
+    (if (not method-only-group)
+       ()
+      (or entry
+         (error "Trying to change non-existant group %s" method-only-group))
+      ;; We have recevied parts of the actual group info - either the
+      ;; select method or the group parameters.  We first check
+      ;; whether we have to extend the info, and if so, do that.
+      (let ((len (length info))
+           (total (if (eq part 'method) 5 6)))
+       (and (< len total)
+            (setcdr (nthcdr (1- len) info)
+                    (make-list (- total len) nil)))
+       ;; Then we enter the new info.
+       (setcar (nthcdr (1- total) info) part-info)))
+    ;; We uncompress some lists of marked articles.
     (let (marked)
       (if (not (setq marked (nth 3 info)))
          ()
@@ -3119,13 +3169,16 @@ If REGEXP, only list groups matching REGEXP."
          (setq marked (cdr marked)))))
     (if entry
        ()
+      ;; This is a new group, so we just create it.
       (save-excursion
        (set-buffer gnus-group-buffer)
        (if (nth 4 info)
+           ;; It's a foreign group...
            (gnus-group-make-group 
             (gnus-group-real-name (car info))
             (prin1-to-string (car (nth 4 info)))
             (nth 1 (nth 4 info)))
+         ;; It's a native group.
          (gnus-group-make-group
           (car info)
           (prin1-to-string (car gnus-select-method))
@@ -3136,6 +3189,8 @@ If REGEXP, only list groups matching REGEXP."
                             (gnus-group-real-name (car info))
                             (or (nth 4 info) gnus-select-method))
                            gnus-newsrc-hashtb))))
+    ;; Whether it was a new group or not, we now have the entry, so we
+    ;; can do the update.
     (if entry
        (progn
          (setcar (nthcdr 2 entry) info)
@@ -3149,6 +3204,12 @@ If REGEXP, only list groups matching REGEXP."
                                  (length (cdr (assq 'dormant marked)))))))))
       (error "No such group: %s" (car info)))))
 
+(defun gnus-group-set-method-info (group select-method)
+  (gnus-group-set-info select-method group 'method))
+
+(defun gnus-group-set-params-info (group params)
+  (gnus-group-set-info params group 'params))
+
 (defun gnus-group-update-group-line ()
   "This function updates the current line in the newsgroup buffer and
 moves the point to the colon."
@@ -3175,7 +3236,8 @@ moves the point to the colon."
           nil group (nth 1 info) (nth 3 info) (car entry) (nth 4 info)))
       (setq active (gnus-gethash group gnus-active-hashtb))
       (gnus-group-insert-group-line 
-       nil group (if (member group gnus-zombie-list) 8 9)
+       nil group (if (member group gnus-zombie-list) gnus-level-zombie
+                  gnus-level-killed)
        nil (if active (- (1+ (cdr active)) (car active)) 0) nil))))
 
 (defun gnus-group-insert-group-line (gformat group level marked number method)
@@ -3193,9 +3255,9 @@ moves the point to the colon."
          (if (numberp number)
              (max 0 (- number-total number))
            "*"))
-        (subscribed (cond ((< level 6) ? )
-                          ((< level 8) ?U)
-                          ((= level 8) ?Z)
+        (subscribed (cond ((<= level gnus-level-subscribed) ? )
+                          ((<= level gnus-level-unsubscribed) ?U)
+                          ((= level gnus-level-zombie) ?Z)
                           (t ?K)))
         (qualified-group (gnus-group-real-name group))
         (newsgroup-description 
@@ -3325,8 +3387,11 @@ If FIRST-TOO, the current line is also eligeble as a target."
                            (let ((unread 
                                   (get-text-property (point) 'gnus-unread)))
                              (or (eq unread t) (and unread (> unread 0))))
-                           (let ((lev (get-text-property (point) 'gnus-level)))
-                             (and lev (< (get-text-property (point) 'gnus-level) 6)))))
+                           (let ((lev (get-text-property
+                                       (point) 'gnus-level)))
+                             (and lev (<= (get-text-property 
+                                          (point) 'gnus-level)
+                                          gnus-level-subscribed)))))
                       (or (not level)
                           (let ((lev (get-text-property (point) 'gnus-level)))
                             (if (and lev (<= lev level))
@@ -3516,8 +3581,9 @@ ADDRESS."
     (and (gnus-gethash nname gnus-active-hashtb)
         (error "Group %s already exists" nname))
     (gnus-group-change-level 
-     (setq info (list t nname 3 nil nil meth))
-     3 9 (gnus-gethash (or (gnus-group-group-name) "dummy.group")
+     (setq info (list t nname gnus-level-default-subscribed nil nil meth))
+     gnus-level-default-subscribed gnus-level-killed 
+     (gnus-gethash (or (gnus-group-group-name) "dummy.group")
                       gnus-newsrc-hashtb) t)
     (gnus-sethash nname '(0 . 0) gnus-active-hashtb)
     (gnus-dribble-enter 
@@ -3527,7 +3593,7 @@ ADDRESS."
     (and (gnus-check-backend-function 'request-create-group nname)
         (gnus-request-create-group nname))))
 
-(defun gnus-group-edit-group (group)
+(defun gnus-group-edit-group (group &optional part)
   "Edit the group on the current line."
   (interactive (list (gnus-group-group-name)))
   (let (info)
@@ -3553,8 +3619,27 @@ ADDRESS."
              (setcdr (car marked) 
                      (gnus-compress-sequence (sort (cdr (car marked)) '<) t)))
          (setq marked (cdr marked))))
-      (insert (pp-to-string (list 'gnus-group-set-info
-                                 (list 'quote cinfo)))))))
+      (cond ((eq part 'method)
+            (insert 
+             "(gnus-group-set-method-info \"" group "\"\n  "
+             (pp-to-string (list 'quote (or (nth 4 info) "native"))) ")\n"))
+           ((eq part 'params)
+            (insert 
+             "(gnus-group-set-params-info \"" group "\"\n  "
+             (pp-to-string (list 'quote (nth 5 info))) ")\n"))
+           (t
+            (insert (pp-to-string 
+                     (list 'gnus-group-set-info (list 'quote cinfo)))))))))
+
+(defun gnus-group-edit-group-method (group)
+  "Edit the select method of GROUP."
+  (interactive (list (gnus-group-group-name)))
+  (gnus-group-edit-group group 'method))
+
+(defun gnus-group-edit-group-parameters (group)
+  "Edit the group parameters of GROUP."
+  (interactive (list (gnus-group-group-name)))
+  (gnus-group-edit-group group 'params))
 
 (defun gnus-group-edit-group-done ()
   (interactive)
@@ -3650,7 +3735,7 @@ score file entries for articles to include in the group."
   (setq gnus-newsrc-assoc 
        (sort (cdr gnus-newsrc-assoc) gnus-group-sort-function))
   (gnus-make-hashtable-from-newsrc-alist)
-  (gnus-get-unread-articles 6)
+  (gnus-get-unread-articles (1+ gnus-level-subscribed))
   (gnus-group-list-groups nil))
 
 (defun gnus-group-sort-by-alphabet (info1 info2)
@@ -3936,11 +4021,12 @@ specify which levels you are interested in re-scanning."
   (if (and gnus-read-active-file (not arg))
       (progn
        (gnus-read-active-file)
-       (gnus-get-unread-articles (or arg 6)))
+       (gnus-get-unread-articles (or arg (1+ gnus-level-subscribed))))
     (let ((gnus-read-active-file nil))
-      (gnus-get-unread-articles (or arg 6))))
+      (gnus-get-unread-articles (or arg (1+ gnus-level-subscribed)))))
   (gnus-group-list-groups 
-   (or gnus-group-always-list-unread arg 5) gnus-have-all-newsgroups))
+   (or gnus-group-always-list-unread arg gnus-level-subscribed)
+   gnus-have-all-newsgroups))
 
 (defun gnus-group-get-new-news-this-group (n)
   "Check for newly arrived news in the current group (and the N-1 next groups).
@@ -4020,7 +4106,8 @@ If N is negative, this group and the N-1 previous groups will be checked."
                       (symbol-value group)))
        (add-text-properties 
        b (1+ b) (list 'gnus-group group
-                      'gnus-unread t 'gnus-marked nil 'gnus-level 6)))
+                      'gnus-unread t 'gnus-marked nil
+                      'gnus-level (1+ gnus-level-subscribed))))
      gnus-description-hashtb)
     (goto-char (point-min))
     (gnus-group-position-cursor)))
@@ -4083,7 +4170,8 @@ level to cut off listing groups.
 If ALL, also list groups with no unread articles.
 If LOWEST, don't list groups with level lower than LOWEST."
   (interactive "P\nsList newsgroups matching: ")
-  (gnus-group-prepare-flat (or level 5) all (or lowest 1) regexp)
+  (gnus-group-prepare-flat (or level gnus-level-subscribed)
+                          all (or lowest 1) regexp)
   (goto-char (point-min))
   (gnus-group-position-cursor))
 
@@ -4093,7 +4181,7 @@ If the prefix LEVEL is non-nil, it should be a number that says which
 level to cut off listing groups. 
 If LOWEST, don't list groups with level lower than LOWEST."
   (interactive "P\nsList newsgroups matching: ")
-  (gnus-group-list-matching (or level 9) regexp t lowest))
+  (gnus-group-list-matching (or level gnus-level-killed) regexp t lowest))
 
 ;; Suggested by Jack Vinson <vinson@unagi.cis.upenn.edu>.
 (defun gnus-group-save-newsrc ()
@@ -4381,11 +4469,14 @@ and the second element is the address."
       (if sub
          (progn
            (gnus-group-change-level 
-            (list t group 3 nil nil gnus-browse-current-method) 3 9 
+            (list t group gnus-level-default-subscribed
+                  nil nil gnus-browse-current-method) 
+            gnus-level-default-subscribed gnus-level-killed
             (gnus-gethash (car (nth 1 gnus-newsrc-assoc)) gnus-newsrc-hashtb)
             t)
            (insert ? ))
-       (gnus-group-change-level group 9 3)
+       (gnus-group-change-level 
+        group gnus-level-killed gnus-level-default-subscribed)
        (insert ?K)))
     t))
 
@@ -5638,7 +5729,7 @@ If READ-ALL is non-nil, all articles in the group are selected."
       (setq gnus-newsgroup-auto-expire
            (or (and (stringp gnus-auto-expirable-newsgroups)
                     (string-match gnus-auto-expirable-newsgroups group))
-               (memq 'auto-expire gnus-current-select-method)))
+               (memq 'auto-expire (nth 5 info))))
       ;; First and last article in this newsgroup.
       (and gnus-newsgroup-headers
           (setq gnus-newsgroup-begin 
@@ -5944,7 +6035,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
                            virtual
                            ;; Only do cross-references on subscribed
                            ;; groups, if that is what is wanted.  
-                           (<= (nth 1 info) 5)))
+                           (<= (nth 1 info) gnus-level-subscribed)))
                   (progn
                     (setq num 0)
                     ;; Set the new list of read articles in this group.
@@ -7212,7 +7303,7 @@ NOTE: This command only works with newsgroup that use NNTP."
     (set-buffer gnus-group-buffer)
     (gnus-sethash 
      name 
-     (list t nil (list name 3 nil nil 
+     (list t nil (list name gnus-level-default-subscribed nil nil 
                       (list 'nndigest gnus-article-buffer
                             (cons 'quit-buffer buf))))
      gnus-newsrc-hashtb)
@@ -10046,7 +10137,7 @@ score the alt hierarchy, you'd say \"!alt.all\"."
     (while newsrc
       (setq group (car (car newsrc)))
       (setq entry (gnus-gethash group gnus-newsrc-hashtb))
-      (if (and (<= (nth 1 (car newsrc)) 5)
+      (if (and (<= (nth 1 (car newsrc)) gnus-level-subscribed)
               (and (car entry)
                    (or (eq (car entry) t)
                        (not (zerop (car entry)))))
@@ -11200,7 +11291,8 @@ Type \\[describe-mode] in the buffer to get a list of commands."
                           (format "%s" (car (gnus-find-method-for-group 
                                              gnus-newsgroup-name)))
                           gnus-valid-select-methods))))
-         (assq 'to-address (gnus-find-method-for-group gnus-newsgroup-name))
+         (assq 'to-address (nth 5 (nth 2 (gnus-gethash gnus-newsgroup-name
+                                                       gnus-newsrc-hashtb))))
          (gnus-y-or-n-p "Are you sure you want to post to all of USENET? "))
       (let ((sumart (if (not post)
                        (save-excursion
@@ -11441,107 +11533,99 @@ will attempt to use the foreign server to post the article."
 
 (defun gnus-inews-check-post ()
   "Check whether the post looks ok."
-  (and 
-   ;; Check excessive size.
-   (if (> (buffer-size) 60000)
-       (gnus-y-or-n-p (format "The article is %d octets long. Really post? "
-                             (buffer-size)))
-     t)
-   ;; Check for commands in Subject.
-   (save-excursion
-     (save-restriction
-       (goto-char (point-min))
-       (narrow-to-region 
-       (point) 
-       (re-search-forward 
-        (concat "^" (regexp-quote mail-header-separator) "$")))
-       (if (string-match "^cmsg " (mail-fetch-field "subject"))
-          (gnus-y-or-n-p
-           "The control code \"cmsg \" is in the subject. Really post? ")
-        t)))
-   ;; Check for control characters.
-   (save-excursion
-     (if (re-search-forward "[\000-\007\013\015-\037\200-\237]" nil t)
-        (gnus-y-or-n-p 
-         "The article contains control characters. Really post? ")
-       t))
-   ;; Check for multiple identical headers.
-   (let (found)
-     (save-excursion
-       (save-restriction
-        (goto-char (point-min))
-        (narrow-to-region
-         (point) 
-         (re-search-forward 
-          (concat "^" (regexp-quote mail-header-separator) "$")))
-        (goto-char (point-min))
-        (while (and (not found) (re-search-forward "^[^ \t:]+: " nil t))
-          (save-excursion
-            (or (re-search-forward 
-                 (concat "^" (setq found
-                                   (buffer-substring (match-beginning 0) 
-                                                     (match-end 0))))
-                 nil t)
-                (setq found nil))))
-        (if found
-            (gnus-y-or-n-p 
-             (format "Multiple %s headers. Really post? " found))
-          t))))
-   ;; Check for version and sendsys.
-   (save-excursion
-     (save-restriction
-       (goto-char (point-min))
-       (narrow-to-region
-       (point) 
-       (re-search-forward 
-        (concat "^" (regexp-quote mail-header-separator) "$")))
-       (if (re-search-backward "^Sendsys:\\|^Version:" nil t)
-          (gnus-yes-or-no-p
-           (format "The article contains a %s command. Really post? "
-                   (buffer-substring (match-beginning 0) (match-end 0))))
-        t)))
-   ;; Check the From header.
-   (save-excursion
-     (save-restriction
-       (goto-char (point-min))
-       (narrow-to-region
-       (point)
-       (re-search-forward
-        (concat "^" (regexp-quote mail-header-separator) "$")))
-       (let* ((case-fold-search t)
-             (from (mail-fetch-field "from")))
-        (if (and from
-                 (string-match "@" from)
-                 (not (string-match "@[^\\.]*\\." from)))
-            (gnus-yes-or-no-p
-             (format "The domain looks strange: \"%s\". Really post? "
-                     from))
-          t))))
-   ;; Check for long lines.
-   (save-excursion
-     (save-restriction
-       (goto-char (point-min))
-       (narrow-to-region
-       (point)
-       (re-search-forward
-        (concat "^" (regexp-quote mail-header-separator) "$")))
-       (while 
-          (and
-           (progn
-             (end-of-line)
-             (< (current-column) 80))
-           (zerop (forward-line 1))))
-       (or (eobp)
-          (gnus-yes-or-no-p
-           (format
-            "You have lines longer than 79 characters.  Really post? ")))))
-   ;; Use the (size . checksum) variable to see whether the
-   ;; article is empty or has only quoted text.
-   (if (and (= (buffer-size) (car gnus-article-check-size))
-           (= (gnus-article-checksum) (cdr gnus-article-check-size)))
-       (gnus-yes-or-no-p
-       "It looks like there's no new text in your article. Really post? ")
-     t)))
+  (or
+   (not gnus-check-before-posting)
+   (and 
+    ;; We narrow to the headers and check them first.
+    (save-excursion
+      (save-restriction
+       (goto-char (point-min))
+       (narrow-to-region 
+        (point) 
+        (re-search-forward 
+         (concat "^" (regexp-quote mail-header-separator) "$")))
+       (goto-char (point-min))
+       (and 
+        ;; Check for commands in Subject.
+        (save-excursion
+          (if (string-match "^cmsg " (mail-fetch-field "subject"))
+              (gnus-y-or-n-p
+               "The control code \"cmsg \" is in the subject. Really post? ")
+            t))
+        ;; Check for multiple identical headers.
+        (save-excursion
+          (let (found)
+            (while (and (not found) (re-search-forward "^[^ \t:]+: " nil t))
+              (save-excursion
+                (or (re-search-forward 
+                     (concat "^" (setq found
+                                       (buffer-substring 
+                                        (match-beginning 0) 
+                                        (- (match-end 0) 2))))
+                     nil t)
+                    (setq found nil))))
+            (if found
+                (gnus-y-or-n-p 
+                 (format "Multiple %s headers. Really post? " found))
+              t)))
+        ;; Check for version and sendsys.
+        (save-excursion
+          (if (re-search-forward "^Sendsys:\\|^Version:" nil t)
+              (gnus-yes-or-no-p
+               (format "The article contains a %s command. Really post? "
+                       (buffer-substring (match-beginning 0) 
+                                         (1- (match-end 0)))))
+            t))
+        ;; Check the Message-Id header.
+        (save-excursion
+          (let* ((case-fold-search t)
+                 (message-id (mail-fetch-field "message-id")))
+            (or (and (string-match "@" message-id)
+                     (string-match "@[^\\.]*\\." message-id))
+                (gnus-yes-or-no-p
+                 (format "The Message-ID looks strange: \"%s\". Really post? "
+                         message-id)))))
+        ;; Check the From header.
+        (save-excursion
+          (let* ((case-fold-search t)
+                 (from (mail-fetch-field "from")))
+            (or (and (string-match "@" from)
+                     (string-match "@[^\\.]*\\." from))
+                (gnus-yes-or-no-p
+                 (format "The From looks strange: \"%s\". Really post? "
+                         from))))))))
+    ;; Check for long lines.
+    (save-excursion
+      (goto-char (point-min))
+      (re-search-forward
+       (concat "^" (regexp-quote mail-header-separator) "$"))
+      (while (and
+             (progn
+               (end-of-line)
+               (< (current-column) 80))
+             (zerop (forward-line 1))))
+      (or (bolp)
+         (gnus-yes-or-no-p
+          (format
+           "You have lines longer than 79 characters.  Really post? "))))
+    ;; Check for control characters.
+    (save-excursion
+      (if (re-search-forward "[\000-\007\013\015-\037\200-\237]" nil t)
+         (gnus-y-or-n-p 
+          "The article contains control characters. Really post? ")
+       t))
+    ;; Check excessive size.
+    (if (> (buffer-size) 60000)
+       (gnus-y-or-n-p (format "The article is %d octets long. Really post? "
+                              (buffer-size)))
+      t)
+    ;; Use the (size . checksum) variable to see whether the
+    ;; article is empty or has only quoted text.
+    (if (and (= (buffer-size) (car gnus-article-check-size))
+            (= (gnus-article-checksum) (cdr gnus-article-check-size)))
+       (gnus-yes-or-no-p
+        "It looks like there's no new text in your article. Really post? ")
+      t))))
 
 (defun gnus-article-checksum ()
   (let ((sum 0))
@@ -11792,7 +11876,7 @@ nil."
                 (not
                  (gnus-y-or-n-p
                   (format
-                   "Your .sig is %d lines; it should be max 4. Really post? "
+                   "Your .sig is %d lines; it should be max 4.  Really post? "
                    b)))
                 (if (file-exists-p signature)
                     (error (format "Edit %s." signature))
@@ -12352,6 +12436,13 @@ mailer."
 ;; Should return a status string (not in the nntp buffer, but as the
 ;; result of the function).
 ;;
+;; `choke-retrieve-groups GROUPS &optional SERVER'
+;; Optional function for retrieving active file info on all groups in
+;; GROUPS.  Two return formats are supported: The normal active file
+;; format, and a list of GROUP lines.  This function should return (as
+;; a function value) either `active' or `group', depending on what
+;; format it returns.
+;;
 ;; The following functions are optional and apply only to backends
 ;; that are able to control the contents of their groups totally
 ;; (ie. mail backends.)  Backends that aren't able to do that
@@ -12555,6 +12646,9 @@ is returned insted of the status string."
     (funcall (gnus-get-function method 'retrieve-headers) 
             articles (gnus-group-real-name group) (nth 1 method))))
 
+(defun gnus-retrieve-groups (groups method)
+  (funcall (gnus-get-function method 'retrieve-groups) groups (nth 1 method)))
+
 (defun gnus-request-article (article group &optional buffer)
   (let ((method (gnus-find-method-for-group group)))
     (funcall (gnus-get-function method 'request-article) 
@@ -12625,11 +12719,11 @@ is returned insted of the status string."
     (funcall (gnus-get-function method 'request-create-group) 
             (gnus-group-real-name group) (nth 1 method))))
 
-(defun gnus-find-method-for-group (group)
+(defun gnus-find-method-for-group (group &optional info)
   (or gnus-override-method
       (and (not group)
           gnus-select-method)
-      (let ((info (nth 2 (gnus-gethash group gnus-newsrc-hashtb)))
+      (let ((info (or info (nth 2 (gnus-gethash group gnus-newsrc-hashtb))))
            method)
        (if (or (not info)
                (not (setq method (nth 4 info))))
@@ -12641,18 +12735,7 @@ is returned insted of the status string."
                       (gnus-server-extend-method group method))
                      (t
                       method))))
-       (let ((method-name (symbol-name (car method))))
-         (if (and (memq 'address (assoc method-name 
-                                        gnus-valid-select-methods))
-                  (not (assq (intern (concat method-name "-address"))
-                             method)))
-             (setq method 
-                   (append method 
-                           (list (list (intern (concat 
-                                                method-name "-address"))
-                                       (nth 1 method)))))))
-       method)))
-
+       (gnus-server-add-address method))))
 
 (defun gnus-check-backend-function (func group)
   (let ((method (if (stringp group) (car (gnus-find-method-for-group group))
@@ -12710,6 +12793,10 @@ If LEVEL is non-nil, the news will be set up at level LEVEL."
   (let ((init (not (and gnus-newsrc-assoc gnus-active-hashtb (not rawfile)))))
     ;; Clear some variables to re-initialize news information.
     (if init (setq gnus-newsrc-assoc nil gnus-active-hashtb nil))
+
+    ;; Read the newsrc file and create `gnus-newsrc-hashtb'.
+    (if init (gnus-read-newsrc-file rawfile))
+
     ;; 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
@@ -12720,10 +12807,8 @@ If LEVEL is non-nil, the news will be set up at level LEVEL."
        (gnus-read-active-file)
       (setq gnus-active-hashtb (make-vector 4095 0)))
 
-    ;; Read the newsrc file and create `gnus-newsrc-hashtb'.
-    (if init (gnus-read-newsrc-file rawfile))
     ;; Find the number of unread articles in each non-dead group.
-    (gnus-get-unread-articles (or level 6))
+    (gnus-get-unread-articles (or level (1+ gnus-level-subscribed)))
     ;; Find new newsgroups and treat them.
     (if (and init gnus-check-new-newsgroups gnus-read-active-file (not level)
             (gnus-server-opened gnus-select-method))
@@ -12886,7 +12971,8 @@ The `-n' option line from .newsrc is respected."
         gnus-active-hashtb)
        (while groups
          (if (gnus-gethash (car groups) gnus-active-hashtb)
-             (gnus-group-change-level (car groups) 3 9))
+             (gnus-group-change-level 
+              (car groups) gnus-level-default-subscribed gnus-level-killed))
          (setq groups (cdr groups)))
        (gnus-group-make-help-group)
        (and gnus-novice-user
@@ -12919,7 +13005,7 @@ The `-n' option line from .newsrc is respected."
       (setq group entry))
     (if (and (stringp entry)
             oldlevel 
-            (< oldlevel 8))
+            (< oldlevel gnus-level-zombie))
        (setq entry (gnus-gethash entry gnus-newsrc-hashtb)))
     (if (and (not oldlevel)
             (listp entry))
@@ -12935,12 +13021,12 @@ The `-n' option line from .newsrc is respected."
     ;; If the group was killed, we remove it from the killed or zombie
     ;; list. If not, and it is in fact going to be killed, we remove
     ;; it from the newsrc hash table and assoc.
-    (cond ((>= oldlevel 8)
-          (if (= oldlevel 8)
+    (cond ((>= oldlevel gnus-level-zombie)
+          (if (= oldlevel gnus-level-zombie)
               (setq gnus-zombie-list (delete group gnus-zombie-list))
             (setq gnus-killed-list (delete group gnus-killed-list))))
          (t
-          (if (>= level 8)
+          (if (>= level gnus-level-zombie)
               (progn
                 (gnus-sethash (car (nth 2 entry))
                               nil gnus-newsrc-hashtb)
@@ -12953,16 +13039,16 @@ The `-n' option line from .newsrc is respected."
     ;; Finally we enter (if needed) the list where it is supposed to
     ;; go, and change the subscription level. If it is to be killed,
     ;; we enter it into the killed or zombie list.
-    (cond ((>= level 8)
+    (cond ((>= level gnus-level-zombie)
           (and (string= group (gnus-group-real-name group))
-               (if (= level 8)
+               (if (= level gnus-level-zombie)
                    (setq gnus-zombie-list (cons group gnus-zombie-list))
                  (setq gnus-killed-list (cons group gnus-killed-list)))))
          (t
           ;; If the list is to be entered into the newsrc assoc, and
           ;; it was killed, we have to create an entry in the newsrc
           ;; hashtb format and fix the pointers in the newsrc assoc.
-          (if (>= oldlevel 8)
+          (if (>= oldlevel gnus-level-zombie)
               (progn
                 (if (listp entry)
                     (progn
@@ -12995,7 +13081,8 @@ The `-n' option line from .newsrc is respected."
 
 (defun gnus-kill-newsgroup (newsgroup)
   "Obsolete function. Kills a newsgroup."
-  (gnus-group-change-level (gnus-gethash newsgroup gnus-newsrc-hashtb) 9))
+  (gnus-group-change-level
+   (gnus-gethash newsgroup gnus-newsrc-hashtb) gnus-level-killed))
 
 (defun gnus-check-bogus-newsgroups (&optional confirm)
   "Remove bogus newsgroups.
@@ -13022,7 +13109,7 @@ newsgroup."
     ;; then removing them from the list of killed groups.
     (while bogus
       (gnus-group-change-level 
-       (gnus-gethash (car bogus) gnus-newsrc-hashtb) 9)
+       (gnus-gethash (car bogus) gnus-newsrc-hashtb) gnus-level-killed)
       (setq gnus-killed-list (delete (car bogus) gnus-killed-list))
       (setq bogus (cdr bogus)))
     ;; Then we remove all bogus groups from the list of killed and
@@ -13054,7 +13141,7 @@ newsgroup."
 ;; and compute how many unread articles there are in each group.
 (defun gnus-get-unread-articles (&optional level)
   (let ((newsrc (cdr gnus-newsrc-assoc))
-       (level (or level 6))
+       (level (or level (1+ gnus-level-subscribed)))
        info group active virtuals)
     (message "Checking new news...")
     (while newsrc
@@ -13301,27 +13388,56 @@ Returns whether the updating was successful."
 (defun gnus-read-active-file ()
   "Get active file from NNTP server."
   (gnus-group-set-mode-line)
-  (let ((methods (cons gnus-select-method gnus-secondary-select-methods)))
+  (let ((methods (cons gnus-select-method gnus-secondary-select-methods))
+       list-type)
     (setq gnus-have-read-active-file nil)
-    (while methods
-      (let* ((where (nth 1 (car methods)))
-            (mesg (format "Reading active file%s via %s..."
-                          (if (and where (not (zerop (length where))))
-                              (concat " from " where) "")
-                          (car (car methods)))))
-       (message mesg)
-       (gnus-check-news-server (car methods))
-       (if (gnus-request-list (car methods)) ; Get active 
-           (save-excursion
-             (set-buffer nntp-server-buffer)
+    (save-excursion
+      (set-buffer nntp-server-buffer)
+      (while methods
+       (let* ((where (nth 1 (car methods)))
+              (mesg (format "Reading active file%s via %s..."
+                            (if (and where (not (zerop (length where))))
+                                (concat " from " where) "")
+                            (car (car methods)))))
+         (message mesg)
+         (gnus-check-news-server (car methods))
+         (cond 
+          ((and (eq gnus-read-active-file 'some)
+                (gnus-check-backend-function
+                 'retrieve-groups (car (car methods))))
+           (let ((newsrc (cdr gnus-newsrc-assoc))
+                 groups)
+             (while newsrc
+               (and (gnus-server-equal 
+                     (gnus-find-method-for-group
+                      (car (car newsrc)) (car newsrc))
+                     (gnus-server-get-method nil (car methods)))
+                    (setq groups (cons (car (car newsrc)) groups)))
+               (setq newsrc (cdr newsrc)))
+             (setq list-type (gnus-retrieve-groups groups (car methods)))
+             (cond ((not list-type)
+                    (message "Cannot read partial active file from %s server." 
+                             (car (car methods)))
+                    (ding))
+                   ((eq list-type 'active)
+                    (gnus-active-to-gnus-format 
+                     (and gnus-have-read-active-file (car methods)))
+                    (setq gnus-have-read-active-file t))
+                   (t
+                    (gnus-groups-to-gnus-format
+                     (and gnus-have-read-active-file (car methods)))
+                    (setq gnus-have-read-active-file t)))))
+          (t
+           (if (not (gnus-request-list (car methods)))
+               (progn
+                 (message "Cannot read active file from %s server." 
+                          (car (car methods)))
+                 (ding))
              (gnus-active-to-gnus-format 
               (and gnus-have-read-active-file (car methods)))
              (setq gnus-have-read-active-file t)
-             (message "%s...done" mesg))
-         (message "Cannot read active file from %s server." 
-                  (car (car methods)))
-         (ding)))
-      (setq methods (cdr methods)))))
+             (message "%s...done" mesg)))))
+       (setq methods (cdr methods))))))
 
 ;; rewritten by jwz based on ideas from Rick Sladkey <jrs@world.std.com>
 ;; Further rewrites by lmi.
@@ -13388,6 +13504,46 @@ Lines matching `gnus-ignored-newsgroups' are ignored."
          (error 
           (progn (ding) (message "Possible error in active file."))))))))
 
+(defun gnus-groups-to-gnus-format (method &optional hashtb)
+  ;; Parse a "groups" active file.
+  (let ((cur (current-buffer))
+       (hashtb (or hashtb 
+                   (if method
+                       gnus-active-hashtb
+                     (setq gnus-active-hashtb
+                           (gnus-make-hashtable 
+                            (count-lines (point-min) (point-max)))))))
+       (prefix (and method (not (eq method gnus-select-method))
+                    (gnus-group-prefixed-name "" method))))
+
+    (goto-char (point-min))
+    (condition-case ()
+       ;; We split this into to separate loops, one with the prefix
+       ;; and one without to speed the reading up somewhat.
+       (if prefix
+           (let (min max opoint)
+             (while (not (eobp))
+               (read cur) (read cur)
+               (setq min (read cur)
+                     max (read cur)
+                     opoint (point))
+               (skip-chars-forward " \t")
+               (insert prefix)
+               (goto-char opoint)
+               (set (let ((obarray hashtb)) (read cur)) 
+                    (cons min max))
+               (forward-line 1)))
+         (let (min max opoint)
+           (while (not (eobp))
+             (read cur) (read cur)
+             (setq min (read cur)
+                   max (read cur))
+             (set (let ((obarray hashtb)) (read cur)) 
+                  (cons min max))
+             (forward-line 1))))
+      (error 
+       (progn (ding) (message "Possible error in active file."))))))
+
 (defun gnus-read-newsrc-file (&optional force)
   "Read startup file.
 If FORCE is non-nil, the .newsrc file is read."
@@ -13462,13 +13618,17 @@ If FORCE is non-nil, the .newsrc file is read."
          (if info
              (progn
                (setcar (nthcdr 2 info) (cdr (cdr group)))
-               (setcar (cdr info) (if (nth 1 group) 3 6))
+               (setcar (cdr info)
+                       (if (nth 1 group) gnus-level-default-subscribed 
+                         gnus-level-default-unsubscribed))
                (setq gnus-newsrc-assoc (cons info gnus-newsrc-assoc)))
            (setq gnus-newsrc-assoc
                  (cons 
                   (setq info
                         (list (car group)
-                              (if (nth 1 group) 3 6) (cdr (cdr group))))
+                              (if (nth 1 group) gnus-level-default-subscribed
+                                gnus-level-default-unsubscribed) 
+                              (cdr (cdr group))))
                   gnus-newsrc-assoc)))
          (if (setq m (assoc (car group) marked))
            (setcdr (cdr (cdr info)) (cons (list (cons 'tick (cdr m))) nil))))
@@ -13683,13 +13843,19 @@ If FORCE is non-nil, the .newsrc file is read."
                  ;; only change it if there's been a status change
                  ;; from subscribed to unsubscribed, or vice versa.
                  (setq level (nth 1 info))
-                 (cond ((and (<= level 5) (not subscribe))
-                        (setq level (if read-list 6 7)))
-                       ((and (> level 5) subscribe)
-                        (setq level 3)))
+                 (cond ((and (<= level gnus-level-subscribed) (not subscribe))
+                        (setq level (if read-list 
+                                        gnus-level-default-unsubscribed 
+                                      (1+ gnus-level-default-unsubscribed))))
+                       ((and (> level gnus-level-subscribed) subscribe)
+                        (setq level gnus-level-default-subscribed)))
                  (setcar (cdr info) level))
              (setq gnus-newsrc-assoc
-                   (cons (list newsgroup (if subscribe 3 (if read-list 6 7))
+                   (cons (list newsgroup 
+                               (if subscribe
+                                   gnus-level-default-subscribed 
+                                 (if read-list gnus-level-default-subscribed
+                                   (1+ gnus-level-default-subscribed)))
                                (nreverse read-list))
                          gnus-newsrc-assoc))))))
        (setq line (1+ line))
@@ -13801,7 +13967,8 @@ If FORCE is non-nil, the .newsrc file is read."
        (setq info (car newsrc))
        (if (not (nth 4 info))          ;Don't write foreign groups to .newsrc.
            (progn
-             (insert (car info) (if (>= (nth 1 info) 6) "!" ":"))
+             (insert (car info) (if (> (nth 1 info) gnus-level-subscribed)
+                                    "!" ":"))
              (if (setq ranges (nth 2 info))
                  (progn
                    (insert " ")
@@ -14004,6 +14171,7 @@ The following commands are available:
          (gnus-server-position-cursor))))))
 
 (defun gnus-server-set-info (info)
+  ;; Enter a select method into the virtual server alist.
   (gnus-dribble-enter 
    (concat "(gnus-server-set-info '"
           (prin1-to-string info) ")"))
@@ -14014,21 +14182,46 @@ The following commands are available:
            (nconc gnus-server-alist (list (cons server info)))))))
 
 (defun gnus-server-to-method (server)
+  ;; Map virtual server names to select methods.
   (cdr (assoc server gnus-server-alist)))
 
 (defun gnus-server-extend-method (group method)
+  ;; This function "extends" a virtual server.  If the server is
+  ;; "hello", and the select method is ("hello" (my-var "something")) 
+  ;; in the group "alt.alt", this will result in a new virtual server
+  ;; called "helly+alt.alt".
   (let ((entry
-        (gnus-copy-sequence (cdr (assoc (car method) gnus-server-alist)))))
+        (gnus-copy-sequence 
+         (if (equal (car method) "native") gnus-select-method
+             (cdr (assoc (car method) gnus-server-alist))))))
     (setcar (cdr entry) (concat (nth 1 entry) "+" group))
     (nconc entry (cdr method))))
 
 (defun gnus-server-get-method (group method)
+  ;; Input either a server name, and extended server name, or a
+  ;; select method, and return a select method. 
   (cond ((stringp method)
         (gnus-server-to-method method))
        ((stringp (car method))
         (gnus-server-extend-method group method))
        (t
-        method)))
+        (gnus-server-add-address method))))
+
+(defun gnus-server-add-address (method)
+  (let ((method-name (symbol-name (car method))))
+    (if (and (memq 'address (assoc method-name gnus-valid-select-methods))
+            (not (assq (intern (concat method-name "-address")) method)))
+       (append method (list (list (intern (concat method-name "-address"))
+                                  (nth 1 method))))
+      method)))
+
+(defun gnus-server-equal (s1 s2)
+  (or (equal s1 s2)
+      (and (= (length s1) (length s2))
+          (progn
+            (while (and s1 (member (car s1) s2))
+              (setq s1 (cdr s1)))
+            (null s1)))))
 
 ;;; Interactive server functions.
 
index 803282e..1f14598 100644 (file)
 (require 'nnmail)
 
 (defvar nnbabyl-mbox-file (expand-file-name "~/RMAIL")
-  "The name of the mail box file in the users home directory.")
+  "The name of the rmail box file in the users home directory.")
 
 (defvar nnbabyl-active-file (expand-file-name "~/.rmail-active")
-  "The name of the active file for the mail box.")
+  "The name of the active file for the rmail box.")
 
 (defvar nnbabyl-get-new-mail t
   "If non-nil, nnbabyl will check the incoming mail file and split the mail.")
index 3eb7657..822edfb 100644 (file)
 (require 'nnmail)
 
 (defvar nnmbox-mbox-file (expand-file-name "~/mbox")
-  "The name of the mail box file in the users home directory.")
+  "The name of the mail box file in the user's home directory.")
 
 (defvar nnmbox-active-file (expand-file-name "~/.mbox-active")
   "The name of the active file for the mail box.")
 
 (defvar nnmbox-get-new-mail t
-  "If non-nil, nnml will check the incoming mail file and split the mail.")
+  "If non-nil, nnmbox will check the incoming mail file and split the mail.")
 
 \f
 
index b071017..3640352 100644 (file)
@@ -33,7 +33,7 @@
 (require 'nnmail)
 
 (defvar nnml-directory "~/Mail/"
-  "Mail directory.")
+  "Mail spool directory.")
 
 (defvar nnml-active-file (concat nnml-directory "active")
   "Mail active file.")
@@ -58,13 +58,11 @@ all. This may very well take some time.")
 (defconst nnml-version "nnml 0.2"
   "nnml version.")
 
-(defvar nnml-current-directory nil
-  "Current news group directory.")
+(defvar nnml-nov-file-name ".overview")
 
+(defvar nnml-current-directory nil)
 (defvar nnml-status-string "")
-
 (defvar nnml-nov-buffer-alist nil)
-
 (defvar nnml-group-alist nil)
 (defvar nnml-active-timestamp nil)
 
@@ -81,6 +79,7 @@ all. This may very well take some time.")
    (list 'nnml-newsgroups-file nnml-newsgroups-file)
    (list 'nnml-get-new-mail nnml-get-new-mail)
    (list 'nnml-nov-is-evil nnml-nov-is-evil)
+   (list 'nnml-nov-file-name nnml-nov-file-name)
    '(nnml-current-directory nil)
    '(nnml-status-string "")
    '(nnml-nov-buffer-alist nil)
@@ -372,7 +371,7 @@ all. This may very well take some time.")
     (let ((first (car articles))
          (last (progn (while (cdr articles) (setq articles (cdr articles)))
                       (car articles)))
-         (nov (concat nnml-current-directory ".nov")))
+         (nov (concat nnml-current-directory nnml-nov-file-name)))
       (if (file-exists-p nov)
          (save-excursion
            (set-buffer nntp-server-buffer)
@@ -562,7 +561,7 @@ all. This may very well take some time.")
   (or (cdr (assoc group nnml-nov-buffer-alist))
       (let ((buffer (find-file-noselect 
                     (concat (nnmail-article-pathname 
-                             group nnml-directory) ".nov"))))
+                             group nnml-directory) nnml-nov-file-name))))
        (save-excursion
          (set-buffer buffer)
          (buffer-disable-undo (current-buffer)))
@@ -605,7 +604,7 @@ all. This may very well take some time.")
                    (string-to-int name)))
                 (directory-files dir nil "^[0-9]+$" t))
                (function <)))
-       (nov (concat dir "/.nov"))
+       (nov (concat dir "/" nnml-nov-file-name))
        (nov-buffer (get-buffer-create "*nov*"))
        nov-line chars)
     (if files
index a14cd9c..9c595d9 100644 (file)
@@ -146,7 +146,7 @@ instead use `nntp-server-buffer'.")
 You'd better not use this variable in NNTP front-end program but
 instead call function `nntp-status-message' to get status message.")
 
-(defvar nntp-server-xover t)
+(defvar nntp-server-xover 'try)
 (defvar nntp-server-list-active-group 'try)
 (defvar nntp-current-group "")
 
@@ -170,8 +170,8 @@ instead call function `nntp-status-message' to get status message.")
    (list 'nntp-prepare-server-hook nntp-prepare-server-hook) 
    '(nntp-server-process nil)
    '(nntp-status-string nil)
-   '(nntp-server-xover t)
-   '(nntp-server-list-active-group 'try)
+   '(nntp-server-xover try)
+   '(nntp-server-list-active-group try)
    '(nntp-current-group "")))
 
 \f
@@ -255,7 +255,7 @@ instead call function `nntp-status-message' to get status message.")
          (command (if nntp-server-list-active-group
                       "LIST ACTIVE" "GROUP")))
        (while groups
-         (nntp-send-strings-to-server "HEAD" (car groups))
+         (nntp-send-strings-to-server command (car groups))
          (setq groups (cdr groups))
          (setq count (1+ count))
          ;; Every 400 requests we have to read the stream in
@@ -272,14 +272,17 @@ instead call function `nntp-status-message' to get status message.")
                         (setq last-point (point))
                         (< received count))
                  (nntp-accept-response)))))
+
        ;; Wait for the reply from the final command.
-       (goto-char (point-max))
-       (re-search-backward "^[0-9]" nil t)
-       (if (looking-at "^[23]")
-           (while (progn
-                    (goto-char (- (point-max) 3))
-                    (not (looking-at "^\\.\r$")))
-             (nntp-accept-response)))
+       (if nntp-server-list-active-group
+           (progn
+             (goto-char (point-max))
+             (re-search-backward "^[0-9]" nil t)
+             (if (looking-at "^[23]")
+                 (while (progn
+                          (goto-char (- (point-max) 3))
+                          (not (looking-at "^\\.\r$")))
+                   (nntp-accept-response)))))
 
        ;; Now all replies are received. We remove CRs.
        (goto-char (point-min))
@@ -513,7 +516,7 @@ SUBJECT.  HEADER is a Gnus header vector.  ARTICLE-BUFFER contains the
 article being followed up.  INFO is a Gnus info list.  If FOLLOW-TO,
 post to this group instead.  If RESPECT-POSTER, heed the special
 \"poster\" value of the Followup-to header."
-  (if (assq 'to-address (nth 4 info))
+  (if (assq 'to-address (nth 5 info))
       (nnmail-request-post-buffer 
        post group subject header article-buffer info follow-to respect-poster)
     (let ((mail-default-headers 
@@ -765,8 +768,7 @@ It will prompt for a password."
          (if (stringp nntp-server-xover)
              (nntp-send-command "^\\.\r$" nntp-server-xover range)
            (let ((commands nntp-xover-commands))
-             (while (and commands
-                         (eq t nntp-server-xover))
+             (while (and commands (eq nntp-server-xover 'try))
                (nntp-send-command "^\\.\r$" (car commands) range)
                (save-excursion
                  (set-buffer nntp-server-buffer)
@@ -774,10 +776,12 @@ It will prompt for a password."
                  (if (looking-at "[23]") 
                      (setq nntp-server-xover (car commands))))
                (setq commands (cdr commands)))
-             (if (eq t nntp-server-xover)
+             (if (eq nntp-server-xover 'try)
                  (setq nntp-server-xover nil))
              nntp-server-xover))
-       (if nntp-server-xover (nntp-decode-text) (erase-buffer))))))
+       (if nntp-server-xover
+           (nntp-decode-text)
+         (erase-buffer))))))
 
 (defun nntp-send-strings-to-server (&rest strings)
   "Send list of STRINGS to news server as command and its arguments."
@@ -883,8 +887,6 @@ If SERVICE, this this as the port number."
            (setq nntp-server-process proc)
            ;; Suggested by Hallvard B Furuseth <h.b.furuseth@usit.uio.no>.
            (process-kill-without-query proc)
-           (setq nntp-server-xover t)
-           (setq nntp-server-list-active-group t)
            (setq nntp-address server)
            ;; It is possible to change kanji-fileio-code in this hook.
            (run-hooks 'nntp-server-hook)
index 5460751..06cea04 100644 (file)
@@ -1,7 +1,7 @@
 \input texinfo                  @c -*-texinfo-*-
 @comment %**start of header (This is for running Texinfo on a region.)
 @setfilename gnus
-@settitle Gnus 0.51 Manual
+@settitle Gnus 0.54 Manual
 @synindex fn cp
 @synindex vr cp
 @synindex pg cp
@@ -753,14 +753,24 @@ that you actually subscribe to.
 Note that if you subscribe to lots and lots of groups, setting this
 variable to @code{nil} will probabaly make Gnus slower, not faster.  At
 present, having this variable @code{nil} will slow Gnus down
-considerably, unless you read news over a 2400 baud modem.  Gnus does
-the group info fetching in total lock-step, so if you have this variable
-@code{nil}, you should kill all groups that you aren't interested in to
-speed things up.
+considerably, unless you read news over a 2400 baud modem.  
 
-There are plans for doing lots of Gnus stuff asynchronously, which
-should make this option more useful, but that's probably some ways off
-in the future.
+This variable can also have the value @code{some}.  Gnus will then
+attempt to read active info only on the subscribed groups.  On some
+servers this is quite fast (on sparkling, brand new INN servers that
+support the @samp{LIST ACTIVE group} command), on others this is not
+fast at all.  In any case, @code{some} should be faster than @code{nil},
+and is certainly faster than @code{t} over slow lines.
+
+If this variable is @code{nil}, Gnus will as for group info in total
+lock-step, which isn't very fast.  If it is @code{some} and you use an
+NNTP server, Gnus will pump out commands as fast as it can, and read all
+the replies in one swoop.  This will normally result in better
+performance, but if the server does not support the aforementioned
+@samp{LIST ACTIVE group} command, this isn't very nice to the server. 
+
+In any case, if you use @code{some} or @code{nil}, you should kill all
+groups that you aren't interested in.
 
 @node Startup Variables
 @section Startup Variables
@@ -799,6 +809,7 @@ long as Gnus is active.
 * Group Subscribing::      Unsubscribing, killing, subscribing.
 * Group Levels::           Levels? What are those, then?
 * Foreign Groups::         How to create foreign groups.
+* Group Parameters::       Each group may have different parameters set.
 * Listing Groups::         Gnus can list various subsets of the groups.
 * Group Maintenance::      Maintaining a tidy @file{.newsrc} file.
 * Browse Foreign Server::  You can browse a server.  See what if has to offer.
@@ -1120,18 +1131,34 @@ group to three (@code{gnus-group-set-current-level}).  If no numeric
 prefix is given, this command will prompt the user for a level.
 @end table
 
-Gnus considers groups on levels 1-5 to be subscribed, 6-7 to be
-unsubscribed, 8 to be zombies (walking dead) and 9 to be killed,
-completely dead.  Gnus treats subscribed and unsubscribed groups exactly
-the same, but zombie and killed groups have no information on what
-articles you have read, etc, stored.  This distinction between dead and
-living groups isn't done because it is nice or clever, it is done purely
-for reasons of efficiency.  On the other hand, if you would like a finer
-granularity to the levels - you're out of luck.  The nine levels are
-hardcoded into the source.  Sorry.
-
-It is recommended that you keep all regular groups on level 3 or higher,
-and keep your mail groups (if any) on level 1 or 2.
+@vindex gnus-level-killed
+@vindex gnus-level-zombie
+@vindex gnus-level-unsubscribed
+@vindex gnus-level-subscribed
+Gnus considers groups on between levels 1 and
+@code{gnus-level-subscribed} (inclusive) to be subscribed,
+@code{gnus-level-subscribed} (ecxlusive) and
+@code{gnus-level-unsubscribed} (inclusive) to be unsubscribed,
+@code{gnus-level-zombie} to be zombies (walking dead) and
+@code{gnus-level-killed} to be killed, completely dead.  Gnus treats
+subscribed and unsubscribed groups exactly the same, but zombie and
+killed groups have no information on what articles you have read, etc,
+stored.  This distinction between dead and living groups isn't done
+because it is nice or clever, it is done purely for reasons of
+efficiency. 
+
+It is recommended that you keep all your mail groups (if any) on quite
+low levels (eg. 1 or 2).
+
+If you want to play with the level variables, you should show some care.
+Set them once, and don't touch them ever again.  
+
+@vindex gnus-level-default-unsubscribed
+@vindex gnus-level-default-subscribed
+Two closely related variables are @code{gnus-level-default-subscribed}
+and @code{gnus-level-default-unsubscribed}, which are the leves that new
+groups will be put on if they are (un)subscribed.  These two variables
+should, of course, be inside the relevant legal ranges.
 
 @vindex gnus-keep-same-level
 If @code{gnus-keep-same-level} is non-@code{nil}, some movement commands
@@ -1158,10 +1185,12 @@ personal mail group.
 A foreign group (or any group, really) is specified by a @dfn{name} and
 a @dfn{select method}.  To take the latter first, a select method is a
 list where the first element says what backend to use (eg. nntp,
-nnspool, nnml) and the second element is the @dfn{address}, in some
-meaning of the word.  There may be additional elements in the select
-method, where the value may have special meaning for the backend in
-question.
+nnspool, nnml) and the second element is the @dfn{server name}.  There
+may be additional elements in the select method, where the value may
+have special meaning for the backend in question.
+
+One could say that a select method defines a @dfn{virtual server} - so
+we do just that (@pxref{The Server Buffer}).
 
 The @dfn{name} of the group is the name the backend will recognize the
 group as.
@@ -1184,9 +1213,19 @@ for a name, a method and possibly an @dfn{address}.  For an easier way
 to subscribe to @sc{nntp} groups, @xref{Browse Foreign Server}.
 @item M e
 @kindex M e (Group)
+@findex gnus-group-edit-group-method
+Enter a buffer where you can edit the select method of the current
+group (@code{gnus-group-edit-group-method}).
+@item M p
+@kindex M p (Group)
+@findex gnus-group-edit-group-parameters
+Enter a buffer where you can edit the group parameters
+(@code{gnus-group-edit-group-parameters}). 
+@item M E
+@kindex M E (Group)
 @findex gnus-group-edit-group
-Edit a group entry.  Gnus will pop up a new buffer where you can edit
-the entry (@code{gnus-group-edit-group}).
+Enter a buffer where you can edit the group info
+(@code{gnus-group-edit-group}).
 @item M d
 @kindex M d (Group)
 @findex gnus-group-make-directory-group
@@ -1234,46 +1273,6 @@ these groups.  How many unread articles there are will be determined
 when, or if, you decide to enter them.  You can also activate any group
 with @kbd{M-g} to see how many unread articles there are.
 
-@cindex to-address
-If the select method contains an element that looks like
-@samp{(to-address .  "some@@where.com")}, that address will be used by
-the backend when doing followups and posts.  This is primarily useful in
-mail groups that represent mailing lists.  You just set this address to
-whatever the list address is.
-
-This trick will actually work whether the group is foreign or not.
-Let's say there's a group on the server that is called @samp{fa.4ad-l}.
-This is a real newsgroup, but the server has gotten the articles from a
-mail-to-news gateway.  Posting directly to this group is therefore
-impossible - you have to send mail to the mailing list address instead.
-
-To achieve this, go to the group in question in the group buffer and
-type @kbd{M e} to edit the group entry.  You'll then be put in a buffer
-where you can edit the group entry.
-
-@lisp
-(gnus-group-set-info
- '("ifi.fritt-forum" 3
-   ((1 . 3321)
-    (3325 . 3325))
-   ((score
-     (3322 . 1000)
-     (3324 . 1000)))))
-@end lisp
-
-A fifth entry has to be added. (In case there isn't a fourth one, you
-have to add a fourth one yourself - @code{nil}.)  The fifth entry should
-look like this:
-
-@lisp
-(nntp "your.host" (to-address . "4ad-l@@jhuvm.hcf.jhu.edu"))
-@end lisp
-
-The two first entries in this method should, of course, be the same as
-@code{gnus-select-method}. 
-
-Quite simple, eh? <duck> @strong{Ouch}.
-
 @node nntp
 @subsection nntp
 @cindex @sc{nntp}
@@ -1291,11 +1290,16 @@ The name of the foreign group can be the same as a native group.  In
 fact, you can subscribe to the same group from as many different servers
 you feel like.  There will be no name collisions.
 
+The following variables can be used to create a virtual @code{nntp}
+server: 
+
+@table @code
+@item nntp-server-opened-hook
+@vindex nntp-server-opened-hook
 @cindex @sc{mode reader}
 @cindex authinfo
 @findex nntp-send-authinfo
 @findex nntp-send-mode-reader
-@vindex nntp-server-opened-hook
 @code{nntp-server-opened-hook} is run after a connection has been made.
 It can be used to send commands to the @sc{nntp} server after it has
 been contacted.  By default is sends the command @samp{MODE READER} to
@@ -1303,6 +1307,7 @@ the server with the @code{nntp-send-mode-reader} function.  Another
 popular function is @code{nntp-send-authinfo}, which will prompt you for
 an @sc{nntp} password and stuff.
 
+@item nntp-maximum-request
 @vindex nntp-maximum-request
 If the @sc{nntp} server doesn't support @sc{nov} headers, this backend
 will collect headers by sending a series of @code{head} commands.  To
@@ -1311,14 +1316,73 @@ waiting for reply, and then reads all the replies.  This is controlled
 by the @code{nntp-maximum-request} variable, and is 400 by default.  If
 your network is buggy, you should set this to 1.
 
+@item nntp-connection-timeout
 @vindex nntp-connection-timeout
-If you have lots of foreign nntp groups that you connect to regularly,
-you're sure to have problems with nntp servers not responding properly,
-or being too loaded to reply within reasonable time.  This is can lead
-to awkward problems, which can be helped somewhat by setting
-@code{nntp-connection-timeout}.  This is an integer that says how many
-seconds the nntp backend should wait for a connection before giving up.
-If it is @code{nil}, which is the default, no timeouts are done.
+If you have lots of foreign @code{nntp} groups that you connect to
+regularly, you're sure to have problems with @sc{nntp} servers not
+responding properly, or being too loaded to reply within reasonable
+time.  This is can lead to awkward problems, which can be helped
+somewhat by setting @code{nntp-connection-timeout}.  This is an integer
+that says how many seconds the @code{nntp} backend should wait for a
+connection before giving up.  If it is @code{nil}, which is the default,
+no timeouts are done.
+
+@item nntp-server-hook
+@vindex nntp-server-hook
+This hook is run as the last step when connecting to an @sc{nntp}
+server.
+
+@findex nntp-open-rlogin
+@findex nntp-open-network-stream
+@item nntp-open-server-function
+@vindex nntp-open-server-function
+This function is used to connect to the remote system.  Two pre-made
+functions are @code{nntp-open-network-stream}, which is the default, and
+simply connects to some port or other on the remote system.  The other
+is @code{nntp-open-rlogin}, which does an rlogin on the remote system,
+and then does a telnet to the @sc{nntp} server available there.
+
+@item nntp-rlogin-parameters
+@vindex nntp-rlogin-parameters
+If you use @code{nntp-open-rlogin} as the
+@code{nntp-open-server-function}, this list will be used as the
+parameter list given to @code{rsh}.
+
+@item nntp-rlogin-user-name
+@vindex nntp-rlogin-user-name
+User name on the remote system when using the @code{rlogin} connect
+function. 
+
+@item nntp-address
+@vindex nntp-address
+The address of the remote system running the @sc{nntp} server.
+
+@item nntp-port-number
+@vindex nntp-port-number
+Port number to connect to when using the @code{nntp-open-network-stream}
+connect function.
+
+@item nntp-buggy-select
+@vindex nntp-buggy-select
+Set this to non-@code{nil} if your select routine is buggy.
+
+@item nntp-nov-is-evil 
+@vindex nntp-nov-is-evil 
+If the @sc{nntp} server does not support @sc{nov}, you could set this
+variable to @code{t}, but @code{nntp} usually checks whether @sc{nov}
+can be used automatically.
+
+@item nntp-xover-commands
+@vindex nntp-xover-commands
+List of strings that are used as commands to fetch @sc{nov} lines from a
+server.  The default value of this variable is @code{("XOVER"
+"XOVERVIEW")}. 
+
+@item nntp-prepare-server-hook
+@vindex nntp-prepare-server-hook
+A hook run before attempting to connect to an @sc{nntp} server.
+
+@end table
 
 @node nnspool
 @subsection nnspool
@@ -1337,15 +1401,47 @@ native select method (@pxref{Finding the News}).
 
 @table @code
 @item nnspool-inews-program
+@vindex nnspool-inews-program
 Program used to post an article.
+
+@item nnspool-inews-switches
+@vindex nnspool-inews-switches
+Parameters given to the inews program when posting an article. 
+
 @item nnspool-spool-directory
+@vindex nnspool-spool-directory
 Where nnspool looks for the articles.  This is normally
 @file{/usr/spool/news/}.
+
 @item nnspool-nov-directory 
+@vindex nnspool-nov-directory 
 Where nnspool will look for @sc{nov} files.  This is normally
 @file{/usr/spool/news/over.view/}.
+
 @item nnspool-lib-dir
+@vindex nnspool-lib-dir
 Where the news lib dir is (@file{/usr/lib/news/} by default).
+
+@item nnspool-active-file
+@vindex nnspool-active-file
+The path of the active file.
+
+@item nnspool-newsgroups-file
+@vindex nnspool-newsgroups-file
+The path of the group description file.
+
+@item nnspool-history-file
+@vindex nnspool-history-file
+The path of the news history file.
+
+@item nnspool-active-times-file
+@vindex nnspool-active-times-file
+The path of the active date file.
+
+@item nnspool-nov-is-evil
+@vindex nnspool-nov-is-evil
+If non-@code{nil}, @code{nnspool} won't try to use any @sc{nov} files
+that it finds.
 @end table
 
 @node nnvirtual
@@ -1741,13 +1837,23 @@ the @code{nnbabyl} mail reading, you just set
 @vindex nnmbox-active-file
 @vindex nnmbox-mbox-file
 The @dfn{nnmbox} backend will use the standard Un*x mbox file to store
-mail.  The path of the mbox file is given by the @code{nnmbox-mbox-file}
-variable.  In addition, Gnus needs to store information about active
-articles.  The file specified by @code{nnmbox-active-file} will be used
-for that.
+mail.  @code{nnmbox} will add extra headers to each mail article to say
+which group it belongs in.
 
-nnmbox will add extra headers to each mail article to say which
-group it belongs in.
+@table @code
+@item nnmbox-mbox-file
+@vindex nnmbox-mbox-file
+The name of the mail box in the user's home directory. 
+
+@item nnmbox-active-file
+@vindex nnmbox-active-file
+The name of the active file for the mail box.
+
+@item nnmbox-get-new-mail
+@vindex nnmbox-get-new-mail
+If non-@code{nil}, @code{nnmbox} will read incoming mail and split it
+into groups.
+@end table
 
 @node nnbabyl
 @subsubsection nnbabyl
@@ -1756,15 +1862,24 @@ group it belongs in.
 
 @vindex nnbabyl-active-file
 @vindex nnbabyl-mbox-file
-The @dfn{nnbabyl} backend will use a babyl mail box to store mail.  The
-path of the rmail mail box file is given by the @code{nnbabyl-mbox-file}
-variable.  In addition, Gnus needs to store information about active
-articles.  The file specified by @code{nnbabyl-active-file} will be used
-for that.
-
-nnbabyl will add extra headers to each mail article to say which
+The @dfn{nnbabyl} backend will use a babyl mail box to store mail.
+@code{nnbabyl} will add extra headers to each mail article to say which
 group it belongs in.
 
+@table @code
+@item nnbabyl-mbox-file
+@vindex nnbabyl-mbox-file
+The name of the rmail mbox file.
+
+@item nnbabyl-active-file
+@vindex nnbabyl-active-file
+The name of the active file for the rmail box.
+
+@item nnbabyl-get-new-mail
+@vindex nnbabyl-get-new-mail
+If non-@code{nil}, @code{nnbabyl} will read incoming mail. 
+@end table
+
 @node nnml
 @subsubsection nnml
 @cindex nnml
@@ -1796,6 +1911,33 @@ splitting.  It has to create lots of files, and it also generates
 @sc{nov} databases for the incoming mails.  This makes is the fastest
 backend when it comes to reading mail.
 
+@table @code
+@item nnml-directory
+@vindex nnml-directory
+All @code{nnml} directories will be placed under this directory. 
+
+@item nnml-active-file
+@vindex nnml-active-file
+The active file for the @code{nnml} server.
+
+@item nnml-newsgroups-file
+@vindex nnml-newsgroups-file
+The @code{nnml} group description file.
+
+@item nnml-get-new-mail
+@vindex nnml-get-new-mail
+If non-@code{nil}, @code{nnml} will read incoming mail.
+
+@item nnml-nov-is-evil
+@vindex nnml-nov-is-evil
+If non-@code{nil}, this backend will ignore any @sc{nov} files.  
+
+@item nnml-nov-file-name
+@vindex nnml-nov-file-name
+The name of the @sc{nov} files.  The default is @file{.overview}. 
+
+@end table
+
 @findex nnml-generate-nov-databases
 If your @code{nnml} groups and @sc{nov} files get totally out of whack,
 you can do a complete update by typing @kbd{M-x
@@ -1813,6 +1955,14 @@ might take a while to complete.
 @code{nnmh} a @emph{much} slower backend than @code{nnml}, but it also
 makes it easier to write procmail scripts for.
 
+@table @code
+@item nnml-directory
+All @code{nnmh} directories will be located under this directory.
+
+@item nnmh-get-new-mail
+If non-@code{nil}, @code{nnml} will read incoming mail.
+@end table
+
 @node nnfolder
 @subsubsection nnfolder
 @cindex nnfolder
@@ -1823,11 +1973,75 @@ file.  Each file is in the standard Un*x mbox format.  @code{nnfolder}
 will add extra headers to keep track of article numbers and arrival
 dates.
 
-@vindex nnfolder-active-file
-@vindex nnfolder-directory
-@code{nnfolder-directory} says where to store these files, and
-@code{nnfolder-active-file} says where to store the @dfn{active}
-information.
+@table @code
+@item nnfolder-directory
+All the @code{nnfolder} mail boxes will be stored under this directory. 
+
+@item nnfolder-active-file
+The name of the active file.
+
+@item nnfolder-newsgroups-file
+The name of the group description file.
+
+@item nnfolder-get-new-mail
+If non-@code{nil}, @code{nnfolder} will read incoming mail.
+@end table
+
+@node Group Parameters
+@section Group Parameters
+@cindex group parameters
+
+Gnus stores all information on a group in a list that is usually known
+as the @dfn{group info}.  This list has from three to six elements.
+Here's an example info.
+
+@lisp
+("nnml:mail.ding" 3 ((1 . 232) 244 (256 . 270)) ((tick 246 249))
+                  (nnml "private") ((to-address . "ding@@ifi.uio.no")))
+@end lisp
+
+The first element is the @dfn{group name}, as Gnus knows the group,
+anyway.  The second element is the @dfn{subscription level}, which
+normally is a small integer.  The third element is a list of ranges of
+read articles.  The fourth element is a list of lists of article marks
+of various kinds.  The fifth element is the select method (or virtual
+server, if you like).  The sixth element is a list of @dfn{group
+parameters}, which is what this section is about.
+
+Any of the last three elements may be missing if they are not required.
+In fact, the vast majority of groups will normally only have the first
+three elements, which saves quite a lot of cons cells.
+
+At present, there's not much you can put in the group parameters list: 
+
+@table @code
+@item to-address
+@cindex to-address
+If the group parameter list contains an element that looks like
+@samp{(to-address .  "some@@where.com")}, that address will be used by
+the backend when doing followups and posts.  This is primarily useful in
+mail groups that represent mailing lists.  You just set this address to
+whatever the list address is.
+
+This trick will actually work whether the group is foreign or not.
+Let's say there's a group on the server that is called @samp{fa.4ad-l}.
+This is a real newsgroup, but the server has gotten the articles from a
+mail-to-news gateway.  Posting directly to this group is therefore
+impossible - you have to send mail to the mailing list address instead.
+
+@item auto-expire
+@cindex auto-expire
+If this symbol is present in the group parameter list, all articles that
+are read will be marked as expirable.  For an alternative approach,
+@xref{Expiring Old Mail Articles}.
+@end table
+
+If you want to change the group parameters (or anything else of the
+group info) you can use the @kbd{M E} to edit enter a buffer where you
+can edit the group info.
+
+You usually don't want to edit the entire group info, so you'd be better
+off using the @kbd{M p} command to just edit the group parameters.
 
 @node Listing Groups
 @section Listing Groups
@@ -2020,6 +2234,13 @@ level ARG and lower (@code{gnus-group-get-new-news}).
 @findex gnus-group-get-new-news-this-group
 Check whether new articles have arrived in the current group
 (@code{gnus-group-get-new-news-this-group}).
+
+@item ^
+@kindex ^ (Group)
+@findex gnus-group-enter-server-mode
+Enter the server buffer (@code{gnus-group-enter-server-mode}). @xref{The
+Server Buffer}.
+
 @item M-f
 @kindex M-f (Group)
 @findex gnus-group-fetch-faq
@@ -2760,6 +2981,12 @@ This hook is called after inserting the required headers in an article
 to be posted.  The hook is called from the @code{*post-news*} buffer,
 narrowed to the head, and is intended for people who would like to
 insert additional headers, or just change headers in some way or other.
+
+@item gnus-check-before-posting
+@vindex gnus-check-before-posting
+If non-@code{nil}, Gnus will attempt to check the legality of the
+headers, as well as some other stuff, before posting.
+
 @end table
 
 
@@ -3945,6 +4172,9 @@ the pseudo-articles into the summary buffer, but view them
 immediately.  If this variable is @code{not-confirm}, the user won't even
 be asked for a confirmation before viewing is done.
 
+So; there you are, reading your @emph{pseduo-articles} in your
+@emph{virtual newsgroup} from the @emph{virtual server}; and you think:
+Why isn't anything real anymore? How did we get here?
 
 @node Various Article Stuff 
 @section Various Article Stuff