comparison lisp/gnus/gnus-start.el @ 31716:9968f55ad26e

Update to emacs-21-branch of the Gnus CVS repository.
author Gerd Moellmann <gerd@gnu.org>
date Tue, 19 Sep 2000 13:37:09 +0000
parents fb6b9c37cdc4
children 65104da03c90
comparison
equal deleted inserted replaced
31715:7c896543d225 31716:9968f55ad26e
1 ;;; gnus-start.el --- startup functions for Gnus 1 ;;; gnus-start.el --- startup functions for Gnus
2 ;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. 2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000
3 ;; Free Software Foundation, Inc.
3 4
4 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 5 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
5 ;; Keywords: news 6 ;; Keywords: news
6 7
7 ;; This file is part of GNU Emacs. 8 ;; This file is part of GNU Emacs.
50 (condition-case nil 51 (condition-case nil
51 (concat (file-name-directory 52 (concat (file-name-directory
52 (directory-file-name installation-directory)) 53 (directory-file-name installation-directory))
53 "site-lisp/gnus-init") 54 "site-lisp/gnus-init")
54 (error nil)) 55 (error nil))
55 "*The site-wide Gnus Emacs-Lisp startup file name, or nil if none. 56 "The site-wide Gnus Emacs-Lisp startup file name, or nil if none.
56 If a file with the `.el' or `.elc' suffixes exists, it will be read instead." 57 If a file with the `.el' or `.elc' suffixes exists, it will be read instead."
57 :group 'gnus-start 58 :group 'gnus-start
58 :type '(choice file (const nil))) 59 :type '(choice file (const nil)))
59 60
60 (defcustom gnus-default-subscribed-newsgroups nil 61 (defcustom gnus-default-subscribed-newsgroups nil
140 :group 'gnus-start-server 141 :group 'gnus-start-server
141 :type '(choice (const nil) 142 :type '(choice (const nil)
142 (const some) 143 (const some)
143 (const t))) 144 (const t)))
144 145
145 (defcustom gnus-level-subscribed 5 146 (defconst gnus-level-subscribed 5
146 "*Groups with levels less than or equal to this variable are subscribed." 147 "Groups with levels less than or equal to this variable are subscribed.")
147 :group 'gnus-group-levels 148
148 :type 'integer) 149 (defconst gnus-level-unsubscribed 7
149 150 "Groups with levels less than or equal to this variable are unsubscribed.
150 (defcustom gnus-level-unsubscribed 7
151 "*Groups with levels less than or equal to this variable are unsubscribed.
152 Groups with levels less than `gnus-level-subscribed', which should be 151 Groups with levels less than `gnus-level-subscribed', which should be
153 less than this variable, are subscribed." 152 less than this variable, are subscribed.")
154 :group 'gnus-group-levels 153
155 :type 'integer) 154 (defconst gnus-level-zombie 8
156 155 "Groups with this level are zombie groups.")
157 (defcustom gnus-level-zombie 8 156
158 "*Groups with this level are zombie groups." 157 (defconst gnus-level-killed 9
159 :group 'gnus-group-levels 158 "Groups with this level are killed.")
160 :type 'integer)
161
162 (defcustom gnus-level-killed 9
163 "*Groups with this level are killed."
164 :group 'gnus-group-levels
165 :type 'integer)
166 159
167 (defcustom gnus-level-default-subscribed 3 160 (defcustom gnus-level-default-subscribed 3
168 "*New subscribed groups will be subscribed at this level." 161 "*New subscribed groups will be subscribed at this level."
169 :group 'gnus-group-levels 162 :group 'gnus-group-levels
170 :type 'integer) 163 :type 'integer)
194 but you won't be told how many unread articles there are in the 187 but you won't be told how many unread articles there are in the
195 groups." 188 groups."
196 :group 'gnus-group-levels 189 :group 'gnus-group-levels
197 :type '(choice integer 190 :type '(choice integer
198 (const :tag "none" nil))) 191 (const :tag "none" nil)))
192
193 (defcustom gnus-read-newsrc-file t
194 "*Non-nil means that Gnus will read the `.newsrc' file.
195 Gnus always reads its own startup file, which is called
196 \".newsrc.eld\". The file called \".newsrc\" is in a format that can
197 be readily understood by other newsreaders. If you don't plan on
198 using other newsreaders, set this variable to nil to save some time on
199 entry."
200 :group 'gnus-newsrc
201 :type 'boolean)
199 202
200 (defcustom gnus-save-newsrc-file t 203 (defcustom gnus-save-newsrc-file t
201 "*Non-nil means that Gnus will save the `.newsrc' file. 204 "*Non-nil means that Gnus will save the `.newsrc' file.
202 Gnus always saves its own startup file, which is called 205 Gnus always saves its own startup file, which is called
203 \".newsrc.eld\". The file called \".newsrc\" is in a format that can 206 \".newsrc.eld\". The file called \".newsrc\" is in a format that can
221 not match this regexp will be removed before saving the list." 224 not match this regexp will be removed before saving the list."
222 :group 'gnus-newsrc 225 :group 'gnus-newsrc
223 :type 'boolean) 226 :type 'boolean)
224 227
225 (defcustom gnus-ignored-newsgroups 228 (defcustom gnus-ignored-newsgroups
226 (purecopy (mapconcat 'identity 229 (mapconcat 'identity
227 '("^to\\." ; not "real" groups 230 '("^to\\." ; not "real" groups
228 "^[0-9. \t]+ " ; all digits in name 231 "^[0-9. \t]+ " ; all digits in name
229 "[][\"#'()]" ; bogus characters 232 "^[\"][]\"[#'()]" ; bogus characters
230 ) 233 )
231 "\\|")) 234 "\\|")
232 "*A regexp to match uninteresting newsgroups in the active file. 235 "*A regexp to match uninteresting newsgroups in the active file.
233 Any lines in the active file matching this regular expression are 236 Any lines in the active file matching this regular expression are
234 removed from the newsgroup list before anything else is done to it, 237 removed from the newsgroup list before anything else is done to it,
235 thus making them effectively non-existent." 238 thus making them effectively non-existent."
236 :group 'gnus-group-new 239 :group 'gnus-group-new
242 inserts new groups at the beginning of the list of groups; 245 inserts new groups at the beginning of the list of groups;
243 `gnus-subscribe-alphabetically' inserts new groups in strict 246 `gnus-subscribe-alphabetically' inserts new groups in strict
244 alphabetic order; `gnus-subscribe-hierarchically' inserts new groups 247 alphabetic order; `gnus-subscribe-hierarchically' inserts new groups
245 in hierarchical newsgroup order; `gnus-subscribe-interactively' asks 248 in hierarchical newsgroup order; `gnus-subscribe-interactively' asks
246 for your decision; `gnus-subscribe-killed' kills all new groups; 249 for your decision; `gnus-subscribe-killed' kills all new groups;
247 `gnus-subscribe-zombies' will make all new groups into zombies." 250 `gnus-subscribe-zombies' will make all new groups into zombies;
251 `gnus-subscribe-topics' will enter groups into the topics that
252 claim them."
248 :group 'gnus-group-new 253 :group 'gnus-group-new
249 :type '(radio (function-item gnus-subscribe-randomly) 254 :type '(radio (function-item gnus-subscribe-randomly)
250 (function-item gnus-subscribe-alphabetically) 255 (function-item gnus-subscribe-alphabetically)
251 (function-item gnus-subscribe-hierarchically) 256 (function-item gnus-subscribe-hierarchically)
252 (function-item gnus-subscribe-interactively) 257 (function-item gnus-subscribe-interactively)
253 (function-item gnus-subscribe-killed) 258 (function-item gnus-subscribe-killed)
254 (function-item gnus-subscribe-zombies) 259 (function-item gnus-subscribe-zombies)
260 (function-item gnus-subscribe-topics)
255 function)) 261 function))
256 262
257 (defcustom gnus-subscribe-options-newsgroup-method 263 (defcustom gnus-subscribe-options-newsgroup-method
258 'gnus-subscribe-alphabetically 264 'gnus-subscribe-alphabetically
259 "*This function is called to subscribe newsgroups mentioned on \"options -n\" lines. 265 "*This function is called to subscribe newsgroups mentioned on \"options -n\" lines.
358 :type 'hook) 364 :type 'hook)
359 365
360 (defcustom gnus-after-getting-new-news-hook 366 (defcustom gnus-after-getting-new-news-hook
361 (when (gnus-boundp 'display-time-timer) 367 (when (gnus-boundp 'display-time-timer)
362 '(display-time-event-handler)) 368 '(display-time-event-handler))
363 "*A hook run after Gnus checks for new news." 369 "*A hook run after Gnus checks for new news when Gnus is already running."
364 :group 'gnus-group-new 370 :group 'gnus-group-new
365 :type 'hook) 371 :type 'hook)
366 372
367 (defcustom gnus-save-newsrc-hook nil 373 (defcustom gnus-save-newsrc-hook nil
368 "A hook called before saving any of the newsrc files." 374 "A hook called before saving any of the newsrc files."
380 Can be used to turn version control on or off." 386 Can be used to turn version control on or off."
381 :group 'gnus-newsrc 387 :group 'gnus-newsrc
382 :type 'hook) 388 :type 'hook)
383 389
384 (defcustom gnus-always-read-dribble-file nil 390 (defcustom gnus-always-read-dribble-file nil
385 "Uncoditionally read the dribble file." 391 "Unconditionally read the dribble file."
386 :group 'gnus-newsrc 392 :group 'gnus-newsrc
387 :type 'boolean) 393 :type 'boolean)
388
389 (defvar gnus-startup-file-coding-system 'binary
390 "*Coding system for startup file.")
391 394
392 (defvar gnus-startup-file-coding-system 'binary 395 (defvar gnus-startup-file-coding-system 'binary
393 "*Coding system for startup file.") 396 "*Coding system for startup file.")
394 397
395 ;;; Internal variables 398 ;;; Internal variables
616 gnus-group-mark-positions nil 619 gnus-group-mark-positions nil
617 gnus-newsgroup-data nil 620 gnus-newsgroup-data nil
618 gnus-newsgroup-unreads nil 621 gnus-newsgroup-unreads nil
619 nnoo-state-alist nil 622 nnoo-state-alist nil
620 gnus-current-select-method nil 623 gnus-current-select-method nil
624 nnmail-split-history nil
621 gnus-ephemeral-servers nil) 625 gnus-ephemeral-servers nil)
622 (gnus-shutdown 'gnus) 626 (gnus-shutdown 'gnus)
623 ;; Kill the startup file. 627 ;; Kill the startup file.
624 (and gnus-current-startup-file 628 (and gnus-current-startup-file
625 (get-file-buffer gnus-current-startup-file) 629 (get-file-buffer gnus-current-startup-file)
727 (gnus-group-set-parameter 731 (gnus-group-set-parameter
728 "nndraft:drafts" 'gnus-dummy '((gnus-draft-mode))))) 732 "nndraft:drafts" 'gnus-dummy '((gnus-draft-mode)))))
729 733
730 ;;;###autoload 734 ;;;###autoload
731 (defun gnus-unload () 735 (defun gnus-unload ()
732 "Unload all Gnus features." 736 "Unload all Gnus features.
737 \(For some value of `all' or `Gnus'.) Currently, features whose names
738 have prefixes `gnus-', `nn', `mm-' or `rfc' are unloaded. Use
739 cautiously -- unloading may cause trouble."
733 (interactive) 740 (interactive)
734 (unless (boundp 'load-history) 741 (dolist (feature features)
735 (error "Sorry, `gnus-unload' is not implemented in this Emacs version")) 742 (if (string-match "^\\(gnus-\\|nn\\|mm-\\|rfc\\)" (symbol-name feature))
736 (let ((history load-history) 743 (unload-feature feature 'force))))
737 feature)
738 (while history
739 (and (string-match "^\\(gnus\\|nn\\)" (caar history))
740 (setq feature (cdr (assq 'provide (car history))))
741 (unload-feature feature 'force))
742 (setq history (cdr history)))))
743 744
744 745
745 ;;; 746 ;;;
746 ;;; Dribble file 747 ;;; Dribble file
747 ;;; 748 ;;;
786 (gnus-get-buffer-create 787 (gnus-get-buffer-create
787 (file-name-nondirectory dribble-file)))) 788 (file-name-nondirectory dribble-file))))
788 (erase-buffer) 789 (erase-buffer)
789 (setq buffer-file-name dribble-file) 790 (setq buffer-file-name dribble-file)
790 (auto-save-mode t) 791 (auto-save-mode t)
791 (buffer-disable-undo (current-buffer)) 792 (buffer-disable-undo)
792 (bury-buffer (current-buffer)) 793 (bury-buffer (current-buffer))
793 (set-buffer-modified-p nil) 794 (set-buffer-modified-p nil)
794 (let ((auto (make-auto-save-file-name)) 795 (let ((auto (make-auto-save-file-name))
795 (gnus-dribble-ignore t) 796 (gnus-dribble-ignore t)
796 modes) 797 modes)
856 857
857 (defun gnus-setup-news (&optional rawfile level dont-connect) 858 (defun gnus-setup-news (&optional rawfile level dont-connect)
858 "Setup news information. 859 "Setup news information.
859 If RAWFILE is non-nil, the .newsrc file will also be read. 860 If RAWFILE is non-nil, the .newsrc file will also be read.
860 If LEVEL is non-nil, the news will be set up at level LEVEL." 861 If LEVEL is non-nil, the news will be set up at level LEVEL."
861 (let ((init (not (and gnus-newsrc-alist gnus-active-hashtb (not rawfile))))) 862 (require 'nnmail)
863 (let ((init (not (and gnus-newsrc-alist gnus-active-hashtb (not rawfile))))
864 ;; Binding this variable will inhibit multiple fetchings
865 ;; of the same mail source.
866 (nnmail-fetched-sources (list t)))
862 867
863 (when init 868 (when init
864 ;; Clear some variables to re-initialize news information. 869 ;; Clear some variables to re-initialize news information.
865 (setq gnus-newsrc-alist nil 870 (setq gnus-newsrc-alist nil
866 gnus-active-hashtb nil) 871 gnus-active-hashtb nil)
940 (gnus-server-opened gnus-select-method)) 945 (gnus-server-opened gnus-select-method))
941 (gnus-check-bogus-newsgroups)))) 946 (gnus-check-bogus-newsgroups))))
942 947
943 (defun gnus-find-new-newsgroups (&optional arg) 948 (defun gnus-find-new-newsgroups (&optional arg)
944 "Search for new newsgroups and add them. 949 "Search for new newsgroups and add them.
945 Each new newsgroup will be treated with `gnus-subscribe-newsgroup-method.' 950 Each new newsgroup will be treated with `gnus-subscribe-newsgroup-method'.
946 The `-n' option line from .newsrc is respected. 951 The `-n' option line from .newsrc is respected.
947 952
948 With 1 C-u, use the `ask-server' method to query the server for new 953 With 1 C-u, use the `ask-server' method to query the server for new
949 groups. 954 groups.
950 With 2 C-u's, use most complete method possible to query the server 955 With 2 C-u's, use most complete method possible to query the server
951 for new groups, and subscribe the new groups as zombies." 956 for new groups, and subscribe the new groups as zombies."
952 (interactive "p") 957 (interactive "p")
953 (let* ((gnus-subscribe-newsgroup-method 958 (let* ((gnus-subscribe-newsgroup-method
954 gnus-subscribe-newsgroup-method) 959 gnus-subscribe-newsgroup-method)
955 (check (cond 960 (check (cond
956 ((or (and (= (or arg 1) 4) 961 ((or (and (= (or arg 1) 4)
957 (not (listp gnus-check-new-newsgroups))) 962 (not (listp gnus-check-new-newsgroups)))
958 (null gnus-read-active-file) 963 (null gnus-read-active-file)
959 (eq gnus-read-active-file 'some)) 964 (eq gnus-read-active-file 'some))
960 'ask-server) 965 'ask-server)
961 ((= (or arg 1) 16) 966 ((= (or arg 1) 16)
962 (setq gnus-subscribe-newsgroup-method 967 (setq gnus-subscribe-newsgroup-method
963 'gnus-subscribe-zombies) 968 'gnus-subscribe-zombies)
964 t) 969 t)
965 (t gnus-check-new-newsgroups)))) 970 (t gnus-check-new-newsgroups))))
966 (unless (gnus-check-first-time-used) 971 (unless (gnus-check-first-time-used)
967 (if (or (consp check) 972 (if (or (consp check)
968 (eq check 'ask-server)) 973 (eq check 'ask-server))
969 ;; Ask the server for new groups. 974 ;; Ask the server for new groups.
970 (gnus-ask-server-for-new-groups) 975 (gnus-ask-server-for-new-groups)
1095 (push group new-newsgroups) 1100 (push group new-newsgroups)
1096 (funcall gnus-subscribe-newsgroup-method group))))))) 1101 (funcall gnus-subscribe-newsgroup-method group)))))))
1097 hashtb)) 1102 hashtb))
1098 (when new-newsgroups 1103 (when new-newsgroups
1099 (gnus-subscribe-hierarchical-interactive new-newsgroups))) 1104 (gnus-subscribe-hierarchical-interactive new-newsgroups)))
1100 (if (> groups 0) 1105 (if (> groups 0)
1101 (gnus-message 5 "%d new newsgroup%s arrived" 1106 (gnus-message 5 "%d new newsgroup%s arrived"
1102 groups (if (> groups 1) "s have" " has")) 1107 groups (if (> groups 1) "s have" " has"))
1103 (gnus-message 5 "No new newsgroups")) 1108 (gnus-message 5 "No new newsgroups"))
1104 (when got-new 1109 (when got-new
1105 (setq gnus-newsrc-last-checked-date new-date)) 1110 (setq gnus-newsrc-last-checked-date new-date))
1106 got-new)) 1111 got-new))
1107 1112
1108 (defun gnus-check-first-time-used () 1113 (defun gnus-check-first-time-used ()
1109 (if (or (> (length gnus-newsrc-alist) 1) 1114 (catch 'ended
1110 (file-exists-p gnus-startup-file) 1115 ;; First check if any of the following files exist. If they do,
1111 (file-exists-p (concat gnus-startup-file ".el")) 1116 ;; it's not the first time the user has used Gnus.
1112 (file-exists-p (concat gnus-startup-file ".eld"))) 1117 (dolist (file (list gnus-current-startup-file
1113 nil 1118 (concat gnus-current-startup-file ".el")
1119 (concat gnus-current-startup-file ".eld")
1120 gnus-startup-file
1121 (concat gnus-startup-file ".el")
1122 (concat gnus-startup-file ".eld")))
1123 (when (file-exists-p file)
1124 (throw 'ended nil)))
1114 (gnus-message 6 "First time user; subscribing you to default groups") 1125 (gnus-message 6 "First time user; subscribing you to default groups")
1115 (unless (gnus-read-active-file-p) 1126 (unless (gnus-read-active-file-p)
1116 (let ((gnus-read-active-file t)) 1127 (let ((gnus-read-active-file t))
1117 (gnus-read-active-file))) 1128 (gnus-read-active-file)))
1118 (setq gnus-newsrc-last-checked-date (current-time-string)) 1129 (setq gnus-newsrc-last-checked-date (current-time-string))
1119 (let ((groups gnus-default-subscribed-newsgroups) 1130 ;; Subscribe to the default newsgroups.
1131 (let ((groups (or gnus-default-subscribed-newsgroups
1132 gnus-backup-default-subscribed-newsgroups))
1120 group) 1133 group)
1121 (if (eq groups t) 1134 (when (eq groups t)
1122 nil 1135 ;; If t, we subscribe (or not) all groups as if they were new.
1123 (setq groups (or groups gnus-backup-default-subscribed-newsgroups))
1124 (mapatoms 1136 (mapatoms
1125 (lambda (sym) 1137 (lambda (sym)
1126 (if (null (setq group (symbol-name sym))) 1138 (when (setq group (symbol-name sym))
1127 ()
1128 (let ((do-sub (gnus-matches-options-n group))) 1139 (let ((do-sub (gnus-matches-options-n group)))
1129 (cond 1140 (cond
1130 ((eq do-sub 'subscribe) 1141 ((eq do-sub 'subscribe)
1131 (gnus-sethash group group gnus-killed-hashtb) 1142 (gnus-sethash group group gnus-killed-hashtb)
1132 (funcall gnus-subscribe-options-newsgroup-method group)) 1143 (funcall gnus-subscribe-options-newsgroup-method group))
1133 ((eq do-sub 'ignore) 1144 ((eq do-sub 'ignore)
1134 nil) 1145 nil)
1135 (t 1146 (t
1136 (push group gnus-killed-list)))))) 1147 (push group gnus-killed-list))))))
1137 gnus-active-hashtb) 1148 gnus-active-hashtb)
1138 (while groups 1149 (dolist (group groups)
1139 (when (gnus-active (car groups)) 1150 ;; Only subscribe the default groups that are activated.
1151 (when (gnus-active group)
1140 (gnus-group-change-level 1152 (gnus-group-change-level
1141 (car groups) gnus-level-default-subscribed gnus-level-killed)) 1153 group gnus-level-default-subscribed gnus-level-killed)))
1142 (setq groups (cdr groups)))
1143 (save-excursion 1154 (save-excursion
1144 (set-buffer gnus-group-buffer) 1155 (set-buffer gnus-group-buffer)
1145 (gnus-group-make-help-group)) 1156 (gnus-group-make-help-group))
1146 (when gnus-novice-user 1157 (when gnus-novice-user
1147 (gnus-message 7 "`A k' to list killed groups")))))) 1158 (gnus-message 7 "`A k' to list killed groups"))))))
1148 1159
1149 (defun gnus-subscribe-group (group previous &optional method) 1160 (defun gnus-subscribe-group (group &optional previous method)
1161 "Subcribe GROUP and put it after PREVIOUS."
1150 (gnus-group-change-level 1162 (gnus-group-change-level
1151 (if method 1163 (if method
1152 (list t group gnus-level-default-subscribed nil nil method) 1164 (list t group gnus-level-default-subscribed nil nil method)
1153 group) 1165 group)
1154 gnus-level-default-subscribed gnus-level-killed previous t)) 1166 gnus-level-default-subscribed gnus-level-killed previous t)
1167 t)
1155 1168
1156 ;; `gnus-group-change-level' is the fundamental function for changing 1169 ;; `gnus-group-change-level' is the fundamental function for changing
1157 ;; subscription levels of newsgroups. This might mean just changing 1170 ;; subscription levels of newsgroups. This might mean just changing
1158 ;; from level 1 to 2, which is pretty trivial, from 2 to 6 or back 1171 ;; from level 1 to 2, which is pretty trivial, from 2 to 6 or back
1159 ;; again, which subscribes/unsubscribes a group, which is equally 1172 ;; again, which subscribes/unsubscribes a group, which is equally
1244 (setq info (cdr entry) 1257 (setq info (cdr entry)
1245 num (car entry)) 1258 num (car entry))
1246 (setq active (gnus-active group)) 1259 (setq active (gnus-active group))
1247 (setq num 1260 (setq num
1248 (if active (- (1+ (cdr active)) (car active)) t)) 1261 (if active (- (1+ (cdr active)) (car active)) t))
1249 ;; Check whether the group is foreign. If so, the 1262 ;; Shorten the select method if possible, if we need to
1250 ;; foreign select method has to be entered into the 1263 ;; store it at all (native groups).
1251 ;; info. 1264 (let ((method (gnus-method-simplify
1252 (let ((method (or gnus-override-subscribe-method 1265 (or gnus-override-subscribe-method
1253 (gnus-group-method group)))) 1266 (gnus-group-method group)))))
1254 (if (eq method gnus-select-method) 1267 (if method
1255 (setq info (list group level nil)) 1268 (setq info (list group level nil nil method))
1256 (setq info (list group level nil nil method))))) 1269 (setq info (list group level nil)))))
1257 (unless previous 1270 (unless previous
1258 (setq previous 1271 (setq previous
1259 (let ((p gnus-newsrc-alist)) 1272 (let ((p gnus-newsrc-alist))
1260 (while (cddr p) 1273 (while (cddr p)
1261 (setq p (cdr p))) 1274 (setq p (cdr p)))
1369 (gnus-check-backend-function 'request-scan (car method)) 1382 (gnus-check-backend-function 'request-scan (car method))
1370 (gnus-request-scan group method)) 1383 (gnus-request-scan group method))
1371 t) 1384 t)
1372 (condition-case () 1385 (condition-case ()
1373 (inline (gnus-request-group group dont-check method)) 1386 (inline (gnus-request-group group dont-check method))
1374 (error nil) 1387 ;;(error nil)
1375 (quit nil)) 1388 (quit nil))
1376 (setq active (gnus-parse-active)) 1389 (setq active (gnus-parse-active))
1377 ;; If there are no articles in the group, the GROUP 1390 ;; If there are no articles in the group, the GROUP
1378 ;; command may have responded with the `(0 . 0)'. We 1391 ;; command may have responded with the `(0 . 0)'. We
1379 ;; ignore this if we already have an active entry 1392 ;; ignore this if we already have an active entry
1441 (< (cdar range) (car active))) 1454 (< (cdar range) (car active)))
1442 (setcdr (car range) (1- (car active)))) 1455 (setcdr (car range) (1- (car active))))
1443 ;; Then we want to peel off any elements that are higher 1456 ;; Then we want to peel off any elements that are higher
1444 ;; than the upper active limit. 1457 ;; than the upper active limit.
1445 (let ((srange range)) 1458 (let ((srange range))
1446 ;; Go past all legal elements. 1459 ;; Go past all valid elements.
1447 (while (and (cdr srange) 1460 (while (and (cdr srange)
1448 (<= (or (and (atom (cadr srange)) 1461 (<= (or (and (atom (cadr srange))
1449 (cadr srange)) 1462 (cadr srange))
1450 (caadr srange)) 1463 (caadr srange))
1451 (cdr active))) 1464 (cdr active)))
1452 (setq srange (cdr srange))) 1465 (setq srange (cdr srange)))
1453 (when (cdr srange) 1466 (when (cdr srange)
1454 ;; Nuke all remaining illegal elements. 1467 ;; Nuke all remaining invalid elements.
1455 (setcdr srange nil)) 1468 (setcdr srange nil))
1456 1469
1457 ;; Adjust the final element. 1470 ;; Adjust the final element.
1458 (when (and (not (atom (car srange))) 1471 (when (and (not (atom (car srange)))
1459 (> (cdar srange) (cdr active))) 1472 (> (cdar srange) (cdr active)))
1483 (1+ gnus-level-subscribed)) 1496 (1+ gnus-level-subscribed))
1484 ((numberp gnus-activate-foreign-newsgroups) 1497 ((numberp gnus-activate-foreign-newsgroups)
1485 gnus-activate-foreign-newsgroups) 1498 gnus-activate-foreign-newsgroups)
1486 (t 0)) 1499 (t 0))
1487 level)) 1500 level))
1488 info group active method) 1501 scanned-methods info group active method retrievegroups)
1489 (gnus-message 5 "Checking new news...") 1502 (gnus-message 5 "Checking new news...")
1490 1503
1491 (while newsrc 1504 (while newsrc
1492 (setq active (gnus-active (setq group (gnus-info-group 1505 (setq active (gnus-active (setq group (gnus-info-group
1493 (setq info (pop newsrc)))))) 1506 (setq info (pop newsrc))))))
1495 ;; Check newsgroups. If the user doesn't want to check them, or 1508 ;; Check newsgroups. If the user doesn't want to check them, or
1496 ;; they can't be checked (for instance, if the news server can't 1509 ;; they can't be checked (for instance, if the news server can't
1497 ;; be reached) we just set the number of unread articles in this 1510 ;; be reached) we just set the number of unread articles in this
1498 ;; newsgroup to t. This means that Gnus thinks that there are 1511 ;; newsgroup to t. This means that Gnus thinks that there are
1499 ;; unread articles, but it has no idea how many. 1512 ;; unread articles, but it has no idea how many.
1513
1514 ;; To be more explicit:
1515 ;; >0 for an active group with messages
1516 ;; 0 for an active group with no unread messages
1517 ;; nil for non-foreign groups that the user has requested not be checked
1518 ;; t for unchecked foreign groups or bogus groups, or groups that can't
1519 ;; be checked, for one reason or other.
1500 (if (and (setq method (gnus-info-method info)) 1520 (if (and (setq method (gnus-info-method info))
1501 (not (inline 1521 (not (inline
1502 (gnus-server-equal 1522 (gnus-server-equal
1503 gnus-select-method 1523 gnus-select-method
1504 (setq method (gnus-server-get-method nil method))))) 1524 (setq method (gnus-server-get-method nil method)))))
1505 (not (gnus-secondary-method-p method))) 1525 (not (gnus-secondary-method-p method)))
1506 ;; These groups are foreign. Check the level. 1526 ;; These groups are foreign. Check the level.
1507 (when (<= (gnus-info-level info) foreign-level) 1527 (when (and (<= (gnus-info-level info) foreign-level)
1508 (setq active (gnus-activate-group group 'scan)) 1528 (setq active (gnus-activate-group group 'scan)))
1509 ;; Let the Gnus agent save the active file. 1529 ;; Let the Gnus agent save the active file.
1510 (when (and gnus-agent gnus-plugged active) 1530 (when (and gnus-agent gnus-plugged active)
1511 (gnus-agent-save-group-info 1531 (gnus-agent-save-group-info
1512 method (gnus-group-real-name group) active)) 1532 method (gnus-group-real-name group) active))
1513 (unless (inline (gnus-virtual-group-p group)) 1533 (unless (inline (gnus-virtual-group-p group))
1514 (inline (gnus-close-group group))) 1534 (inline (gnus-close-group group)))
1515 (when (fboundp (intern (concat (symbol-name (car method)) 1535 (when (fboundp (intern (concat (symbol-name (car method))
1516 "-request-update-info"))) 1536 "-request-update-info")))
1517 (inline (gnus-request-update-info info method)))) 1537 (inline (gnus-request-update-info info method))))
1518 ;; These groups are native or secondary. 1538 ;; These groups are native or secondary.
1519 (when (and (<= (gnus-info-level info) level) 1539 (cond
1520 (not gnus-read-active-file)) 1540 ;; We don't want these groups.
1521 (setq active (gnus-activate-group group 'scan)) 1541 ((> (gnus-info-level info) level)
1522 (inline (gnus-close-group group)))) 1542 (setq active 'ignore))
1543 ;; Activate groups.
1544 ((not gnus-read-active-file)
1545 (if (gnus-check-backend-function 'retrieve-groups group)
1546 ;; if server support gnus-retrieve-groups we push
1547 ;; the group onto retrievegroups for later checking
1548 (if (assoc method retrievegroups)
1549 (setcdr (assoc method retrievegroups)
1550 (cons group (cdr (assoc method retrievegroups))))
1551 (push (list method group) retrievegroups))
1552 ;; hack: `nnmail-get-new-mail' changes the mail-source depending
1553 ;; on the group, so we must perform a scan for every group
1554 ;; if the users has any directory mail sources.
1555 ;; hack: if `nnmail-scan-directory-mail-source-once' is non-nil,
1556 ;; for it scan all spool files even when the groups are
1557 ;; not required.
1558 (if (and
1559 (or nnmail-scan-directory-mail-source-once
1560 (null (assq 'directory
1561 (or mail-sources
1562 (if (listp nnmail-spool-file)
1563 nnmail-spool-file
1564 (list nnmail-spool-file))))))
1565 (member method scanned-methods))
1566 (setq active (gnus-activate-group group))
1567 (setq active (gnus-activate-group group 'scan))
1568 (push method scanned-methods))
1569 (when active
1570 (gnus-close-group group))))))
1523 1571
1524 ;; Get the number of unread articles in the group. 1572 ;; Get the number of unread articles in the group.
1525 (if active 1573 (cond
1526 (inline (gnus-get-unread-articles-in-group info active t)) 1574 ((eq active 'ignore)
1575 ;; Don't do anything.
1576 )
1577 (active
1578 (inline (gnus-get-unread-articles-in-group info active t)))
1579 (t
1527 ;; The group couldn't be reached, so we nix out the number of 1580 ;; The group couldn't be reached, so we nix out the number of
1528 ;; unread articles and stuff. 1581 ;; unread articles and stuff.
1529 (gnus-set-active group nil) 1582 (gnus-set-active group nil)
1530 (setcar (gnus-gethash group gnus-newsrc-hashtb) t))) 1583 (let ((tmp (gnus-gethash group gnus-newsrc-hashtb)))
1584 (if tmp (setcar tmp t))))))
1585
1586 ;; iterate through groups on methods which support gnus-retrieve-groups
1587 ;; and fetch a partial active file and use it to find new news.
1588 (while retrievegroups
1589 (let* ((mg (pop retrievegroups))
1590 (method (or (car mg) gnus-select-method))
1591 (groups (cdr mg)))
1592 (when (gnus-check-server method)
1593 ;; Request that the backend scan its incoming messages.
1594 (when (gnus-check-backend-function 'request-scan (car method))
1595 (gnus-request-scan nil method))
1596 (gnus-read-active-file-2 (mapcar (lambda (group)
1597 (gnus-group-real-name group))
1598 groups) method)
1599 (dolist (group groups)
1600 (cond
1601 ((setq active (gnus-active (gnus-info-group
1602 (setq info (gnus-get-info group)))))
1603 (inline (gnus-get-unread-articles-in-group info active t)))
1604 (t
1605 ;; The group couldn't be reached, so we nix out the number of
1606 ;; unread articles and stuff.
1607 (gnus-set-active group nil)
1608 (setcar (gnus-gethash group gnus-newsrc-hashtb) t)))))))
1531 1609
1532 (gnus-message 5 "Checking new news...done"))) 1610 (gnus-message 5 "Checking new news...done")))
1533 1611
1534 ;; Create a hash table out of the newsrc alist. The `car's of the 1612 ;; Create a hash table out of the newsrc alist. The `car's of the
1535 ;; alist elements are used as keys. 1613 ;; alist elements are used as keys.
1633 1711
1634 ;; Get the active file(s) from the backend(s). 1712 ;; Get the active file(s) from the backend(s).
1635 (defun gnus-read-active-file (&optional force not-native) 1713 (defun gnus-read-active-file (&optional force not-native)
1636 (gnus-group-set-mode-line) 1714 (gnus-group-set-mode-line)
1637 (let ((methods 1715 (let ((methods
1638 (append 1716 (mapcar
1639 (if (and (not not-native) 1717 (lambda (m) (if (stringp m) (gnus-server-get-method nil m) m))
1640 (gnus-check-server gnus-select-method)) 1718 (append
1641 ;; The native server is available. 1719 (if (and (not not-native)
1642 (cons gnus-select-method gnus-secondary-select-methods) 1720 (gnus-check-server gnus-select-method))
1643 ;; The native server is down, so we just do the 1721 ;; The native server is available.
1644 ;; secondary ones. 1722 (cons gnus-select-method gnus-secondary-select-methods)
1645 gnus-secondary-select-methods) 1723 ;; The native server is down, so we just do the
1646 ;; Also read from the archive server. 1724 ;; secondary ones.
1647 (when (gnus-archive-server-wanted-p) 1725 gnus-secondary-select-methods)
1648 (list "archive")))) 1726 ;; Also read from the archive server.
1649 list-type) 1727 (when (gnus-archive-server-wanted-p)
1728 (list "archive")))))
1729 method)
1650 (setq gnus-have-read-active-file nil) 1730 (setq gnus-have-read-active-file nil)
1651 (save-excursion 1731 (save-excursion
1652 (set-buffer nntp-server-buffer) 1732 (set-buffer nntp-server-buffer)
1653 (while methods 1733 (while (setq method (pop methods))
1654 (let* ((method (if (stringp (car methods)) 1734 ;; Only do each method once, in case the methods appear more
1655 (gnus-server-get-method nil (car methods)) 1735 ;; than once in this list.
1656 (car methods))) 1736 (unless (member method methods)
1657 (where (nth 1 method)) 1737 (condition-case ()
1658 (mesg (format "Reading active file%s via %s..." 1738 (gnus-read-active-file-1 method force)
1659 (if (and where (not (zerop (length where)))) 1739 ;; We catch C-g so that we can continue past servers
1660 (concat " from " where) "") 1740 ;; that do not respond.
1661 (car method)))) 1741 (quit nil)))))))
1742
1743 (defun gnus-read-active-file-1 (method force)
1744 (let (where mesg)
1745 (setq where (nth 1 method)
1746 mesg (format "Reading active file%s via %s..."
1747 (if (and where (not (zerop (length where))))
1748 (concat " from " where) "")
1749 (car method)))
1750 (gnus-message 5 mesg)
1751 (when (gnus-check-server method)
1752 ;; Request that the backend scan its incoming messages.
1753 (when (gnus-check-backend-function 'request-scan (car method))
1754 (gnus-request-scan nil method))
1755 (cond
1756 ((and (eq gnus-read-active-file 'some)
1757 (gnus-check-backend-function 'retrieve-groups (car method))
1758 (not force))
1759 (let ((newsrc (cdr gnus-newsrc-alist))
1760 (gmethod (gnus-server-get-method nil method))
1761 groups info)
1762 (while (setq info (pop newsrc))
1763 (when (inline
1764 (gnus-server-equal
1765 (inline
1766 (gnus-find-method-for-group
1767 (gnus-info-group info) info))
1768 gmethod))
1769 (push (gnus-group-real-name (gnus-info-group info))
1770 groups)))
1771 (gnus-read-active-file-2 groups method)))
1772 ((null method)
1773 t)
1774 (t
1775 (if (not (gnus-request-list method))
1776 (unless (equal method gnus-message-archive-method)
1777 (gnus-error 1 "Cannot read active file from %s server"
1778 (car method)))
1662 (gnus-message 5 mesg) 1779 (gnus-message 5 mesg)
1663 (when (gnus-check-server method) 1780 (gnus-active-to-gnus-format method gnus-active-hashtb nil t)
1664 ;; Request that the backend scan its incoming messages. 1781 ;; We mark this active file as read.
1665 (when (gnus-check-backend-function 'request-scan (car method)) 1782 (push method gnus-have-read-active-file)
1666 (gnus-request-scan nil method)) 1783 (gnus-message 5 "%sdone" mesg)))))))
1667 (cond 1784
1668 ((and (eq gnus-read-active-file 'some) 1785 (defun gnus-read-active-file-2 (groups method)
1669 (gnus-check-backend-function 'retrieve-groups (car method)) 1786 "Read an active file for GROUPS in METHOD using gnus-retrieve-groups."
1670 (not force)) 1787 (when groups
1671 (let ((newsrc (cdr gnus-newsrc-alist)) 1788 (save-excursion
1672 (gmethod (gnus-server-get-method nil method)) 1789 (set-buffer nntp-server-buffer)
1673 groups info) 1790 (gnus-check-server method)
1674 (while (setq info (pop newsrc)) 1791 (let ((list-type (gnus-retrieve-groups groups method)))
1675 (when (inline 1792 (cond ((not list-type)
1676 (gnus-server-equal 1793 (gnus-error
1677 (inline 1794 1.2 "Cannot read partial active file from %s server."
1678 (gnus-find-method-for-group 1795 (car method)))
1679 (gnus-info-group info) info)) 1796 ((eq list-type 'active)
1680 gmethod)) 1797 (gnus-active-to-gnus-format method gnus-active-hashtb nil t))
1681 (push (gnus-group-real-name (gnus-info-group info)) 1798 (t
1682 groups))) 1799 (gnus-groups-to-gnus-format method gnus-active-hashtb t)))))))
1683 (when groups
1684 (gnus-check-server method)
1685 (setq list-type (gnus-retrieve-groups groups method))
1686 (cond
1687 ((not list-type)
1688 (gnus-error
1689 1.2 "Cannot read partial active file from %s server."
1690 (car method)))
1691 ((eq list-type 'active)
1692 (gnus-active-to-gnus-format
1693 method gnus-active-hashtb nil t))
1694 (t
1695 (gnus-groups-to-gnus-format
1696 method gnus-active-hashtb t))))))
1697 ((null method)
1698 t)
1699 (t
1700 (if (not (gnus-request-list method))
1701 (unless (equal method gnus-message-archive-method)
1702 (gnus-error 1 "Cannot read active file from %s server"
1703 (car method)))
1704 (gnus-message 5 mesg)
1705 (gnus-active-to-gnus-format method gnus-active-hashtb nil t)
1706 ;; We mark this active file as read.
1707 (push method gnus-have-read-active-file)
1708 (gnus-message 5 "%sdone" mesg))))))
1709 (setq methods (cdr methods))))))
1710
1711
1712 (defun gnus-ignored-newsgroups-has-to-p ()
1713 "Non-nil iff gnus-ignored-newsgroups includes \"^to\\\\.\" as an element."
1714 ;; note this regexp is the same as:
1715 ;; (concat (regexp-quote "^to\\.") "\\($\\|" (regexp-quote "\\|") "\\)")
1716 (string-match "\\^to\\\\\\.\\($\\|\\\\|\\)" gnus-ignored-newsgroups))
1717 1800
1718 ;; Read an active file and place the results in `gnus-active-hashtb'. 1801 ;; Read an active file and place the results in `gnus-active-hashtb'.
1719 (defun gnus-active-to-gnus-format (&optional method hashtb ignore-errors 1802 (defun gnus-active-to-gnus-format (&optional method hashtb ignore-errors
1720 real-active) 1803 real-active)
1721 (unless method 1804 (unless method
1730 (gnus-make-hashtable 1813 (gnus-make-hashtable
1731 (count-lines (point-min) (point-max))) 1814 (count-lines (point-min) (point-max)))
1732 (gnus-make-hashtable 4096))))))) 1815 (gnus-make-hashtable 4096)))))))
1733 ;; Delete unnecessary lines. 1816 ;; Delete unnecessary lines.
1734 (goto-char (point-min)) 1817 (goto-char (point-min))
1735 (cond ((gnus-ignored-newsgroups-has-to-p) 1818 (cond
1736 (delete-matching-lines gnus-ignored-newsgroups)) 1819 ((string= gnus-ignored-newsgroups "")
1737 ((string= gnus-ignored-newsgroups "") 1820 (delete-matching-lines "^to\\."))
1738 (delete-matching-lines "^to\\.")) 1821 (t
1739 (t 1822 (delete-matching-lines (concat "^to\\.\\|" gnus-ignored-newsgroups))))
1740 (delete-matching-lines (concat "^to\\.\\|" 1823
1741 gnus-ignored-newsgroups)))) 1824 (goto-char (point-min))
1742 1825 (unless (re-search-forward "[\\\"]" nil t)
1743 ;; Make the group names readable as a lisp expression even if they 1826 ;; Make the group names readable as a lisp expression even if they
1744 ;; contain special characters. 1827 ;; contain special characters.
1745 (goto-char (point-max)) 1828 (goto-char (point-max))
1746 (while (re-search-backward "[][';?()#]" nil t) 1829 (while (re-search-backward "[][';?()#]" nil t)
1747 (insert ?\\)) 1830 (insert ?\\)))
1748 1831
1749 ;; Let the Gnus agent save the active file. 1832 ;; Let the Gnus agent save the active file.
1750 (when (and gnus-agent real-active) 1833 (when (and gnus-agent real-active gnus-plugged)
1751 (gnus-agent-save-active method)) 1834 (gnus-agent-save-active method))
1752 1835
1753 ;; If these are groups from a foreign select method, we insert the 1836 ;; If these are groups from a foreign select method, we insert the
1754 ;; group prefix in front of the group names. 1837 ;; group prefix in front of the group names.
1755 (when (not (gnus-server-equal 1838 (when (not (gnus-server-equal
1756 (gnus-server-get-method nil method) 1839 (gnus-server-get-method nil method)
1757 (gnus-server-get-method nil gnus-select-method))) 1840 (gnus-server-get-method nil gnus-select-method)))
1758 (let ((prefix (gnus-group-prefixed-name "" method))) 1841 (let ((prefix (gnus-group-prefixed-name "" method)))
1759 (goto-char (point-min)) 1842 (goto-char (point-min))
1760 (while (and (not (eobp)) 1843 (while (and (not (eobp))
1761 (progn (insert prefix) 1844 (progn
1762 (zerop (forward-line 1))))))) 1845 (when (= (following-char) ?\")
1846 (forward-char 1))
1847 (insert prefix)
1848 (zerop (forward-line 1)))))))
1763 ;; Store the active file in a hash table. 1849 ;; Store the active file in a hash table.
1764 (goto-char (point-min)) 1850 (goto-char (point-min))
1765 (let (group max min) 1851 (let (group max min)
1766 (while (not (eobp)) 1852 (while (not (eobp))
1767 (condition-case () 1853 (condition-case err
1768 (progn 1854 (progn
1769 (narrow-to-region (point) (gnus-point-at-eol)) 1855 (narrow-to-region (point) (gnus-point-at-eol))
1770 ;; group gets set to a symbol interned in the hash table 1856 ;; group gets set to a symbol interned in the hash table
1771 ;; (what a hack!!) - jwz 1857 ;; (what a hack!!) - jwz
1772 (setq group (let ((obarray hashtb)) (read cur))) 1858 (setq group (let ((obarray hashtb)) (read cur)))
1859 ;; ### The extended group name scheme makes
1860 ;; the previous optimization strategy sort of pointless...
1861 (when (stringp group)
1862 (setq group (intern group hashtb)))
1773 (if (and (numberp (setq max (read cur))) 1863 (if (and (numberp (setq max (read cur)))
1774 (numberp (setq min (read cur))) 1864 (numberp (setq min (read cur)))
1775 (progn 1865 (progn
1776 (skip-chars-forward " \t") 1866 (skip-chars-forward " \t")
1777 (not 1867 (not
1778 (or (= (following-char) ?=) 1868 (or (eq (char-after) ?=)
1779 (= (following-char) ?x) 1869 (eq (char-after) ?x)
1780 (= (following-char) ?j))))) 1870 (eq (char-after) ?j)))))
1781 (progn 1871 (progn
1782 (set group (cons min max)) 1872 (set group (cons min max))
1783 ;; if group is moderated, stick in moderation table 1873 ;; if group is moderated, stick in moderation table
1784 (when (= (following-char) ?m) 1874 (when (eq (char-after) ?m)
1785 (unless gnus-moderated-hashtb 1875 (unless gnus-moderated-hashtb
1786 (setq gnus-moderated-hashtb (gnus-make-hashtable))) 1876 (setq gnus-moderated-hashtb (gnus-make-hashtable)))
1787 (gnus-sethash (symbol-name group) t 1877 (gnus-sethash (symbol-name group) t
1788 gnus-moderated-hashtb))) 1878 gnus-moderated-hashtb)))
1789 (set group nil))) 1879 (set group nil)))
1790 (error 1880 (error
1791 (and group 1881 (and group
1792 (symbolp group) 1882 (symbolp group)
1793 (set group nil)) 1883 (set group nil))
1794 (unless ignore-errors 1884 (unless ignore-errors
1795 (gnus-message 3 "Warning - illegal active: %s" 1885 (gnus-message 3 "Warning - invalid active: %s"
1796 (buffer-substring 1886 (buffer-substring
1797 (gnus-point-at-bol) (gnus-point-at-eol)))))) 1887 (gnus-point-at-bol) (gnus-point-at-eol))))))
1798 (widen) 1888 (widen)
1799 (forward-line 1))))) 1889 (forward-line 1)))))
1800 1890
1812 (gnus-server-get-method nil method) 1902 (gnus-server-get-method nil method)
1813 (gnus-server-get-method nil gnus-select-method))) 1903 (gnus-server-get-method nil gnus-select-method)))
1814 (gnus-group-prefixed-name "" method)))) 1904 (gnus-group-prefixed-name "" method))))
1815 1905
1816 ;; Let the Gnus agent save the active file. 1906 ;; Let the Gnus agent save the active file.
1817 (when (and gnus-agent real-active) 1907 (if (and gnus-agent
1818 (gnus-agent-save-groups method)) 1908 real-active
1819 1909 gnus-plugged
1820 (goto-char (point-min)) 1910 (gnus-agent-method-p method))
1821 ;; We split this into to separate loops, one with the prefix 1911 (progn
1822 ;; and one without to speed the reading up somewhat. 1912 (gnus-agent-save-groups method)
1823 (if prefix 1913 (gnus-active-to-gnus-format method hashtb nil real-active))
1824 (let (min max opoint group) 1914
1915 (goto-char (point-min))
1916 ;; We split this into to separate loops, one with the prefix
1917 ;; and one without to speed the reading up somewhat.
1918 (if prefix
1919 (let (min max opoint group)
1920 (while (not (eobp))
1921 (condition-case ()
1922 (progn
1923 (read cur) (read cur)
1924 (setq min (read cur)
1925 max (read cur)
1926 opoint (point))
1927 (skip-chars-forward " \t")
1928 (insert prefix)
1929 (goto-char opoint)
1930 (set (let ((obarray hashtb)) (read cur))
1931 (cons min max)))
1932 (error (and group (symbolp group) (set group nil))))
1933 (forward-line 1)))
1934 (let (min max group)
1825 (while (not (eobp)) 1935 (while (not (eobp))
1826 (condition-case () 1936 (condition-case ()
1827 (progn 1937 (when (eq (char-after) ?2)
1828 (read cur) (read cur) 1938 (read cur) (read cur)
1829 (setq min (read cur) 1939 (setq min (read cur)
1830 max (read cur) 1940 max (read cur))
1831 opoint (point)) 1941 (set (setq group (let ((obarray hashtb)) (read cur)))
1832 (skip-chars-forward " \t")
1833 (insert prefix)
1834 (goto-char opoint)
1835 (set (let ((obarray hashtb)) (read cur))
1836 (cons min max))) 1942 (cons min max)))
1837 (error (and group (symbolp group) (set group nil)))) 1943 (error (and group (symbolp group) (set group nil))))
1838 (forward-line 1))) 1944 (forward-line 1)))))))
1839 (let (min max group)
1840 (while (not (eobp))
1841 (condition-case ()
1842 (when (= (following-char) ?2)
1843 (read cur) (read cur)
1844 (setq min (read cur)
1845 max (read cur))
1846 (set (setq group (let ((obarray hashtb)) (read cur)))
1847 (cons min max)))
1848 (error (and group (symbolp group) (set group nil))))
1849 (forward-line 1))))))
1850 1945
1851 (defun gnus-read-newsrc-file (&optional force) 1946 (defun gnus-read-newsrc-file (&optional force)
1852 "Read startup file. 1947 "Read startup file.
1853 If FORCE is non-nil, the .newsrc file is read." 1948 If FORCE is non-nil, the .newsrc file is read."
1854 ;; Reset variables that might be defined in the .newsrc.eld file. 1949 ;; Reset variables that might be defined in the .newsrc.eld file.
1862 ;; We always load the .newsrc.eld file. If always contains 1957 ;; We always load the .newsrc.eld file. If always contains
1863 ;; much information that can not be gotten from the .newsrc 1958 ;; much information that can not be gotten from the .newsrc
1864 ;; file (ticked articles, killed groups, foreign methods, etc.) 1959 ;; file (ticked articles, killed groups, foreign methods, etc.)
1865 (gnus-read-newsrc-el-file quick-file) 1960 (gnus-read-newsrc-el-file quick-file)
1866 1961
1867 (when (and (file-exists-p gnus-current-startup-file) 1962 (when (and gnus-read-newsrc-file
1963 (file-exists-p gnus-current-startup-file)
1868 (or force 1964 (or force
1869 (and (file-newer-than-file-p newsrc-file quick-file) 1965 (and (file-newer-than-file-p newsrc-file quick-file)
1870 (file-newer-than-file-p newsrc-file 1966 (file-newer-than-file-p newsrc-file
1871 (concat quick-file "d"))) 1967 (concat quick-file "d")))
1872 (not gnus-newsrc-alist))) 1968 (not gnus-newsrc-alist)))
1878 ;; i. e., reading the .newsrc file will not trash the data 1974 ;; i. e., reading the .newsrc file will not trash the data
1879 ;; already read (except for read articles). 1975 ;; already read (except for read articles).
1880 (save-excursion 1976 (save-excursion
1881 (gnus-message 5 "Reading %s..." newsrc-file) 1977 (gnus-message 5 "Reading %s..." newsrc-file)
1882 (set-buffer (nnheader-find-file-noselect newsrc-file)) 1978 (set-buffer (nnheader-find-file-noselect newsrc-file))
1883 (buffer-disable-undo (current-buffer)) 1979 (buffer-disable-undo)
1884 (gnus-newsrc-to-gnus-format) 1980 (gnus-newsrc-to-gnus-format)
1885 (kill-buffer (current-buffer)) 1981 (kill-buffer (current-buffer))
1886 (gnus-message 5 "Reading %s...done" newsrc-file))) 1982 (gnus-message 5 "Reading %s...done" newsrc-file)))
1887 1983
1888 ;; Convert old to new. 1984 ;; Convert old to new.
2054 (when (numberp symbol) 2150 (when (numberp symbol)
2055 (setq symbol (intern (int-to-string symbol) gnus-active-hashtb))) 2151 (setq symbol (intern (int-to-string symbol) gnus-active-hashtb)))
2056 (unless (boundp symbol) 2152 (unless (boundp symbol)
2057 (set symbol nil)) 2153 (set symbol nil))
2058 ;; It was a group name. 2154 ;; It was a group name.
2059 (setq subscribed (= (following-char) ?:) 2155 (setq subscribed (eq (char-after) ?:)
2060 group (symbol-name symbol) 2156 group (symbol-name symbol)
2061 reads nil) 2157 reads nil)
2062 (if (eolp) 2158 (if (eolp)
2063 ;; If the line ends here, this is clearly a buggy line, so 2159 ;; If the line ends here, this is clearly a buggy line, so
2064 ;; we put point a the beginning of line and let the cond 2160 ;; we put point a the beginning of line and let the cond
2078 (setq num1 (progn 2174 (setq num1 (progn
2079 (narrow-to-region (match-beginning 0) (match-end 0)) 2175 (narrow-to-region (match-beginning 0) (match-end 0))
2080 (read buf))) 2176 (read buf)))
2081 (widen) 2177 (widen)
2082 ;; If the next character is a dash, then this is a range. 2178 ;; If the next character is a dash, then this is a range.
2083 (if (= (following-char) ?-) 2179 (if (eq (char-after) ?-)
2084 (progn 2180 (progn
2085 ;; We read the upper bound of the range. 2181 ;; We read the upper bound of the range.
2086 (forward-char 1) 2182 (forward-char 1)
2087 (if (not (looking-at "[0-9]+")) 2183 (if (not (looking-at "[0-9]+"))
2088 ;; This is a buggy line, by we pretend that 2184 ;; This is a buggy line, by we pretend that
2100 ;; It was just a simple number, so we add it to the 2196 ;; It was just a simple number, so we add it to the
2101 ;; list of ranges. 2197 ;; list of ranges.
2102 (push num1 reads)) 2198 (push num1 reads))
2103 ;; If the next char in ?\n, then we have reached the end 2199 ;; If the next char in ?\n, then we have reached the end
2104 ;; of the line and return nil. 2200 ;; of the line and return nil.
2105 (/= (following-char) ?\n)) 2201 (not (eq (char-after) ?\n)))
2106 ((= (following-char) ?\n) 2202 ((eq (char-after) ?\n)
2107 ;; End of line, so we end. 2203 ;; End of line, so we end.
2108 nil) 2204 nil)
2109 (t 2205 (t
2110 ;; Not numbers and not eol, so this might be a buggy 2206 ;; Not numbers and not eol, so this might be a buggy
2111 ;; line... 2207 ;; line...
2115 (setq group nil) 2211 (setq group nil)
2116 (gnus-error 3.1 "Mangled line: %s" 2212 (gnus-error 3.1 "Mangled line: %s"
2117 (buffer-substring (gnus-point-at-bol) 2213 (buffer-substring (gnus-point-at-bol)
2118 (gnus-point-at-eol)))) 2214 (gnus-point-at-eol))))
2119 nil)) 2215 nil))
2120 ;; Skip past ", ". Spaces are illegal in these ranges, but 2216 ;; Skip past ", ". Spaces are invalid in these ranges, but
2121 ;; we allow them, because it's a common mistake to put a 2217 ;; we allow them, because it's a common mistake to put a
2122 ;; space after the comma. 2218 ;; space after the comma.
2123 (skip-chars-forward ", ")) 2219 (skip-chars-forward ", "))
2124 2220
2125 ;; We have already read .newsrc.eld, so we gently update the 2221 ;; We have already read .newsrc.eld, so we gently update the
2227 (and (re-search-forward "[ \t]-n" (gnus-point-at-eol) t) 2323 (and (re-search-forward "[ \t]-n" (gnus-point-at-eol) t)
2228 (- (point) 2))) 2324 (- (point) 2)))
2229 (gnus-point-at-eol))) 2325 (gnus-point-at-eol)))
2230 ;; Search for all "words"... 2326 ;; Search for all "words"...
2231 (while (re-search-forward "[^ \t,\n]+" eol t) 2327 (while (re-search-forward "[^ \t,\n]+" eol t)
2232 (if (= (char-after (match-beginning 0)) ?!) 2328 (if (eq (char-after (match-beginning 0)) ?!)
2233 ;; If the word begins with a bang (!), this is a "not" 2329 ;; If the word begins with a bang (!), this is a "not"
2234 ;; spec. We put this spec (minus the bang) and the 2330 ;; spec. We put this spec (minus the bang) and the
2235 ;; symbol `ignore' into the list. 2331 ;; symbol `ignore' into the list.
2236 (push (cons (concat 2332 (push (cons (concat
2237 "^" (buffer-substring 2333 "^" (buffer-substring
2275 (make-local-variable 'version-control) 2371 (make-local-variable 'version-control)
2276 (setq version-control 'never) 2372 (setq version-control 'never)
2277 (setq buffer-file-name 2373 (setq buffer-file-name
2278 (concat gnus-current-startup-file ".eld")) 2374 (concat gnus-current-startup-file ".eld"))
2279 (setq default-directory (file-name-directory buffer-file-name)) 2375 (setq default-directory (file-name-directory buffer-file-name))
2280 (buffer-disable-undo (current-buffer)) 2376 (buffer-disable-undo)
2281 (erase-buffer) 2377 (erase-buffer)
2282 (gnus-message 5 "Saving %s.eld..." gnus-current-startup-file) 2378 (gnus-message 5 "Saving %s.eld..." gnus-current-startup-file)
2283 (gnus-gnus-to-quick-newsrc-format) 2379 (gnus-gnus-to-quick-newsrc-format)
2284 (gnus-run-hooks 'gnus-save-quick-newsrc-hook) 2380 (gnus-run-hooks 'gnus-save-quick-newsrc-hook)
2285 (let ((coding-system-for-write gnus-startup-file-coding-system)) 2381 (let ((coding-system-for-write gnus-startup-file-coding-system))
2292 2388
2293 (defun gnus-gnus-to-quick-newsrc-format () 2389 (defun gnus-gnus-to-quick-newsrc-format ()
2294 "Insert Gnus variables such as gnus-newsrc-alist in lisp format." 2390 "Insert Gnus variables such as gnus-newsrc-alist in lisp format."
2295 (let ((print-quoted t) 2391 (let ((print-quoted t)
2296 (print-escape-newlines t)) 2392 (print-escape-newlines t))
2393
2297 (insert ";; -*- emacs-lisp -*-\n") 2394 (insert ";; -*- emacs-lisp -*-\n")
2298 (insert ";; Gnus startup file.\n") 2395 (insert ";; Gnus startup file.\n")
2299 (insert "\ 2396 (insert "\
2300 ;; Never delete this file -- if you want to force Gnus to read the 2397 ;; Never delete this file -- if you want to force Gnus to read the
2301 ;; .newsrc file (if you have one), touch .newsrc instead.\n") 2398 ;; .newsrc file (if you have one), touch .newsrc instead.\n")
2339 (let ((newsrc (cdr gnus-newsrc-alist)) 2436 (let ((newsrc (cdr gnus-newsrc-alist))
2340 (standard-output (current-buffer)) 2437 (standard-output (current-buffer))
2341 info ranges range method) 2438 info ranges range method)
2342 (setq buffer-file-name gnus-current-startup-file) 2439 (setq buffer-file-name gnus-current-startup-file)
2343 (setq default-directory (file-name-directory buffer-file-name)) 2440 (setq default-directory (file-name-directory buffer-file-name))
2344 (buffer-disable-undo (current-buffer)) 2441 (buffer-disable-undo)
2345 (erase-buffer) 2442 (erase-buffer)
2346 ;; Write options. 2443 ;; Write options.
2347 (when gnus-newsrc-options 2444 (when gnus-newsrc-options
2348 (insert gnus-newsrc-options)) 2445 (insert gnus-newsrc-options))
2349 ;; Write subscribed and unsubscribed. 2446 ;; Write subscribed and unsubscribed.
2402 2499
2403 (defun gnus-slave-save-newsrc () 2500 (defun gnus-slave-save-newsrc ()
2404 (save-excursion 2501 (save-excursion
2405 (set-buffer gnus-dribble-buffer) 2502 (set-buffer gnus-dribble-buffer)
2406 (let ((slave-name 2503 (let ((slave-name
2407 (make-temp-file (concat gnus-current-startup-file "-slave-"))) 2504 (make-temp-name (concat gnus-current-startup-file "-slave-")))
2408 (modes (ignore-errors 2505 (modes (ignore-errors
2409 (file-modes (concat gnus-current-startup-file ".eld"))))) 2506 (file-modes (concat gnus-current-startup-file ".eld")))))
2507 (let ((coding-system-for-write gnus-startup-file-coding-system))
2508 (gnus-write-buffer slave-name))
2410 (when modes 2509 (when modes
2411 (set-file-modes slave-name modes)) 2510 (set-file-modes slave-name modes)))))
2412 (gnus-write-buffer slave-name))))
2413 2511
2414 (defun gnus-master-read-slave-newsrc () 2512 (defun gnus-master-read-slave-newsrc ()
2415 (let ((slave-files 2513 (let ((slave-files
2416 (directory-files 2514 (directory-files
2417 (file-name-directory gnus-current-startup-file) 2515 (file-name-directory gnus-current-startup-file)
2425 (if (not slave-files) 2523 (if (not slave-files)
2426 () ; There are no slave files to read. 2524 () ; There are no slave files to read.
2427 (gnus-message 7 "Reading slave newsrcs...") 2525 (gnus-message 7 "Reading slave newsrcs...")
2428 (save-excursion 2526 (save-excursion
2429 (set-buffer (gnus-get-buffer-create " *gnus slave*")) 2527 (set-buffer (gnus-get-buffer-create " *gnus slave*"))
2430 (buffer-disable-undo (current-buffer))
2431 (setq slave-files 2528 (setq slave-files
2432 (sort (mapcar (lambda (file) 2529 (sort (mapcar (lambda (file)
2433 (list (nth 5 (file-attributes file)) file)) 2530 (list (nth 5 (file-attributes file)) file))
2434 slave-files) 2531 slave-files)
2435 (lambda (f1 f2) 2532 (lambda (f1 f2)
2436 (or (< (caar f1) (caar f2)) 2533 (or (< (caar f1) (caar f2))
2437 (< (nth 1 (car f1)) (nth 1 (car f2))))))) 2534 (< (nth 1 (car f1)) (nth 1 (car f2)))))))
2438 (while slave-files 2535 (while slave-files
2439 (erase-buffer) 2536 (erase-buffer)
2440 (setq file (nth 1 (car slave-files))) 2537 (setq file (nth 1 (car slave-files)))
2441 (insert-file-contents file) 2538 (nnheader-insert-file-contents file)
2442 (when (condition-case () 2539 (when (condition-case ()
2443 (progn 2540 (progn
2444 (eval-buffer (current-buffer)) 2541 (eval-buffer (current-buffer))
2445 t) 2542 t)
2446 (error 2543 (error
2483 (gnus-sethash (gnus-group-prefixed-name "" method) "Has read" 2580 (gnus-sethash (gnus-group-prefixed-name "" method) "Has read"
2484 gnus-description-hashtb) 2581 gnus-description-hashtb)
2485 2582
2486 (gnus-message 5 "Reading descriptions file via %s..." (car method)) 2583 (gnus-message 5 "Reading descriptions file via %s..." (car method))
2487 (cond 2584 (cond
2585 ((null (gnus-get-function method 'request-list-newsgroups t))
2586 t)
2488 ((not (gnus-check-server method)) 2587 ((not (gnus-check-server method))
2489 (gnus-message 1 "Couldn't open server") 2588 (gnus-message 1 "Couldn't open server")
2490 nil) 2589 nil)
2491 ((not (gnus-request-list-newsgroups method)) 2590 ((not (gnus-request-list-newsgroups method))
2492 (gnus-message 1 "Couldn't read newsgroups descriptions") 2591 (gnus-message 1 "Couldn't read newsgroups descriptions")
2527 ;; ... which leads to this line being effectively ignored. 2626 ;; ... which leads to this line being effectively ignored.
2528 (when (symbolp group) 2627 (when (symbolp group)
2529 (let ((str (buffer-substring 2628 (let ((str (buffer-substring
2530 (point) (progn (end-of-line) (point)))) 2629 (point) (progn (end-of-line) (point))))
2531 (coding 2630 (coding
2532 (and (boundp 'enable-multibyte-characters) 2631 (and (or gnus-xemacs
2533 enable-multibyte-characters 2632 (and (boundp 'enable-multibyte-characters)
2633 enable-multibyte-characters))
2534 (fboundp 'gnus-mule-get-coding-system) 2634 (fboundp 'gnus-mule-get-coding-system)
2535 (gnus-mule-get-coding-system (symbol-name group))))) 2635 (gnus-mule-get-coding-system (symbol-name group)))))
2536 (if coding 2636 (when coding
2537 (setq str (gnus-decode-coding-string str (car coding)))) 2637 (setq str (mm-decode-coding-string str (car coding))))
2538 (set group str))) 2638 (set group str)))
2539 (forward-line 1)))) 2639 (forward-line 1))))
2540 (gnus-message 5 "Reading descriptions file...done") 2640 (gnus-message 5 "Reading descriptions file...done")
2541 t)))) 2641 t))))
2542 2642
2552 ;;;###autoload 2652 ;;;###autoload
2553 (defun gnus-declare-backend (name &rest abilities) 2653 (defun gnus-declare-backend (name &rest abilities)
2554 "Declare backend NAME with ABILITIES as a Gnus backend." 2654 "Declare backend NAME with ABILITIES as a Gnus backend."
2555 (setq gnus-valid-select-methods 2655 (setq gnus-valid-select-methods
2556 (nconc gnus-valid-select-methods 2656 (nconc gnus-valid-select-methods
2557 (list (apply 'list name abilities))))) 2657 (list (apply 'list name abilities))))
2658 (gnus-redefine-select-method-widget))
2558 2659
2559 (defun gnus-set-default-directory () 2660 (defun gnus-set-default-directory ()
2560 "Set the default directory in the current buffer to `gnus-default-directory'. 2661 "Set the default directory in the current buffer to `gnus-default-directory'.
2561 If this variable is nil, don't do anything." 2662 If this variable is nil, don't do anything."
2562 (setq default-directory 2663 (setq default-directory