comparison lisp/gnus/gnus-start.el @ 82951:0fde48feb604

Import Gnus 5.10 from the v5_10 branch of the Gnus repository.
author Andreas Schwab <schwab@suse.de>
date Thu, 22 Jul 2004 16:45:51 +0000
parents 695cf19ef79e
children 497f0d2ca551 cce1c0ee76ee
comparison
equal deleted inserted replaced
56503:8bbd2323fbf2 82951:0fde48feb604
1 ;;; gnus-start.el --- startup functions for Gnus 1 ;;; gnus-start.el --- startup functions for Gnus
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 ;; Free Software Foundation, Inc. 3 ;; Free Software Foundation, Inc.
4 4
5 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 5 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
6 ;; Keywords: news 6 ;; Keywords: news
7 7
30 (require 'gnus-win) 30 (require 'gnus-win)
31 (require 'gnus-int) 31 (require 'gnus-int)
32 (require 'gnus-spec) 32 (require 'gnus-spec)
33 (require 'gnus-range) 33 (require 'gnus-range)
34 (require 'gnus-util) 34 (require 'gnus-util)
35 (require 'message) 35 (autoload 'message-make-date "message")
36 (autoload 'gnus-agent-read-servers-validate "gnus-agent")
37 (autoload 'gnus-agent-possibly-alter-active "gnus-agent")
36 (eval-when-compile (require 'cl)) 38 (eval-when-compile (require 'cl))
37 39
38 (defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc") 40 (defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc")
39 "Your `.newsrc' file. 41 "Your `.newsrc' file.
40 `.newsrc-SERVER' will be used instead if that exists." 42 `.newsrc-SERVER' will be used instead if that exists."
41 :group 'gnus-start 43 :group 'gnus-start
42 :type 'file) 44 :type 'file)
45
46 (defcustom gnus-backup-startup-file 'never
47 "Whether to create backup files.
48 This variable takes the same values as the `version-control'
49 variable."
50 :group 'gnus-start
51 :type '(choice (const :tag "Never" never)
52 (const :tag "If existing" nil)
53 (other :tag "Always" t)))
54
55 (defcustom gnus-save-startup-file-via-temp-buffer t
56 "Whether to write the startup file contents to a buffer then save
57 the buffer or write directly to the file. The buffer is faster
58 because all of the contents are written at once. The direct write
59 uses considerably less memory."
60 :group 'gnus-start
61 :type '(choice (const :tag "Write via buffer" t)
62 (const :tag "Write directly to file" nil)))
43 63
44 (defcustom gnus-init-file (nnheader-concat gnus-home-directory ".gnus") 64 (defcustom gnus-init-file (nnheader-concat gnus-home-directory ".gnus")
45 "Your Gnus Emacs-Lisp startup file name. 65 "Your Gnus Emacs-Lisp startup file name.
46 If a file with the `.el' or `.elc' suffixes exists, it will be read instead." 66 If a file with the `.el' or `.elc' suffixes exists, it will be read instead."
47 :group 'gnus-start 67 :group 'gnus-start
222 nil if you set this variable to nil. 242 nil if you set this variable to nil.
223 243
224 This variable can also be a regexp. In that case, all groups that do 244 This variable can also be a regexp. In that case, all groups that do
225 not match this regexp will be removed before saving the list." 245 not match this regexp will be removed before saving the list."
226 :group 'gnus-newsrc 246 :group 'gnus-newsrc
227 :type 'boolean) 247 :type '(radio (sexp :format "Non-nil\n"
248 :match (lambda (widget value)
249 (and value (not (stringp value))))
250 :value t)
251 (const nil)
252 (regexp :format "%t: %v\n" :size 0)))
228 253
229 (defcustom gnus-ignored-newsgroups 254 (defcustom gnus-ignored-newsgroups
230 (mapconcat 'identity 255 (mapconcat 'identity
231 '("^to\\." ; not "real" groups 256 '("^to\\." ; not "real" groups
232 "^[0-9. \t]+ " ; all digits in name 257 "^[0-9. \t]+\\( \\|$\\)" ; all digits in name
233 "^[\"][]\"[#'()]" ; bogus characters 258 "^[\"][]\"[#'()]" ; bogus characters
234 ) 259 )
235 "\\|") 260 "\\|")
236 "*A regexp to match uninteresting newsgroups in the active file. 261 "*A regexp to match uninteresting newsgroups in the active file.
237 Any lines in the active file matching this regular expression are 262 Any lines in the active file matching this regular expression are
239 thus making them effectively non-existent." 264 thus making them effectively non-existent."
240 :group 'gnus-group-new 265 :group 'gnus-group-new
241 :type 'regexp) 266 :type 'regexp)
242 267
243 (defcustom gnus-subscribe-newsgroup-method 'gnus-subscribe-zombies 268 (defcustom gnus-subscribe-newsgroup-method 'gnus-subscribe-zombies
244 "*Function called with a group name when new group is detected. 269 "*Function(s) called with a group name when new group is detected.
245 A few pre-made functions are supplied: `gnus-subscribe-randomly' 270 A few pre-made functions are supplied: `gnus-subscribe-randomly'
246 inserts new groups at the beginning of the list of groups; 271 inserts new groups at the beginning of the list of groups;
247 `gnus-subscribe-alphabetically' inserts new groups in strict 272 `gnus-subscribe-alphabetically' inserts new groups in strict
248 alphabetic order; `gnus-subscribe-hierarchically' inserts new groups 273 alphabetic order; `gnus-subscribe-hierarchically' inserts new groups
249 in hierarchical newsgroup order; `gnus-subscribe-interactively' asks 274 in hierarchical newsgroup order; `gnus-subscribe-interactively' asks
257 (function-item gnus-subscribe-hierarchically) 282 (function-item gnus-subscribe-hierarchically)
258 (function-item gnus-subscribe-interactively) 283 (function-item gnus-subscribe-interactively)
259 (function-item gnus-subscribe-killed) 284 (function-item gnus-subscribe-killed)
260 (function-item gnus-subscribe-zombies) 285 (function-item gnus-subscribe-zombies)
261 (function-item gnus-subscribe-topics) 286 (function-item gnus-subscribe-topics)
262 function)) 287 function
288 (repeat function)))
289
290 (defcustom gnus-subscribe-newsgroup-hooks nil
291 "*Hooks run after you subscribe to a new group.
292 The hooks will be called with new group's name as argument."
293 :group 'gnus-group-new
294 :type 'hook)
263 295
264 (defcustom gnus-subscribe-options-newsgroup-method 296 (defcustom gnus-subscribe-options-newsgroup-method
265 'gnus-subscribe-alphabetically 297 'gnus-subscribe-alphabetically
266 "*This function is called to subscribe newsgroups mentioned on \"options -n\" lines. 298 "*Function(s) called to subscribe newsgroups mentioned on \"options -n\" lines.
267 If, for instance, you want to subscribe to all newsgroups in the 299 If, for instance, you want to subscribe to all newsgroups in the
268 \"no\" and \"alt\" hierarchies, you'd put the following in your 300 \"no\" and \"alt\" hierarchies, you'd put the following in your
269 .newsrc file: 301 .newsrc file:
270 302
271 options -n no.all alt.all 303 options -n no.all alt.all
277 (function-item gnus-subscribe-alphabetically) 309 (function-item gnus-subscribe-alphabetically)
278 (function-item gnus-subscribe-hierarchically) 310 (function-item gnus-subscribe-hierarchically)
279 (function-item gnus-subscribe-interactively) 311 (function-item gnus-subscribe-interactively)
280 (function-item gnus-subscribe-killed) 312 (function-item gnus-subscribe-killed)
281 (function-item gnus-subscribe-zombies) 313 (function-item gnus-subscribe-zombies)
282 function)) 314 (function-item gnus-subscribe-topics)
315 function
316 (repeat function)))
283 317
284 (defcustom gnus-subscribe-hierarchical-interactive nil 318 (defcustom gnus-subscribe-hierarchical-interactive nil
285 "*If non-nil, Gnus will offer to subscribe hierarchically. 319 "*If non-nil, Gnus will offer to subscribe hierarchically.
286 When a new hierarchy appears, Gnus will ask the user: 320 When a new hierarchy appears, Gnus will ask the user:
287 321
292 hierarchy in its entirety." 326 hierarchy in its entirety."
293 :group 'gnus-group-new 327 :group 'gnus-group-new
294 :type 'boolean) 328 :type 'boolean)
295 329
296 (defcustom gnus-auto-subscribed-groups 330 (defcustom gnus-auto-subscribed-groups
297 "nnml\\|^nnfolder\\|^nnmbox\\|^nnmh\\|^nnbabyl" 331 "^nnml\\|^nnfolder\\|^nnmbox\\|^nnmh\\|^nnbabyl\\|^nnmaildir"
298 "*All new groups that match this regexp will be subscribed automatically. 332 "*All new groups that match this regexp will be subscribed automatically.
299 Note that this variable only deals with new groups. It has no effect 333 Note that this variable only deals with new groups. It has no effect
300 whatsoever on old groups. 334 whatsoever on old groups.
301 335
302 New groups that match this regexp will not be handled by 336 New groups that match this regexp will not be handled by
352 (defcustom gnus-started-hook nil 386 (defcustom gnus-started-hook nil
353 "A hook called as the last thing after startup." 387 "A hook called as the last thing after startup."
354 :group 'gnus-start 388 :group 'gnus-start
355 :type 'hook) 389 :type 'hook)
356 390
357 (defcustom gnus-setup-news-hook nil 391 (defcustom gnus-setup-news-hook
392 '(gnus-fixup-nnimap-unread-after-getting-new-news)
358 "A hook after reading the .newsrc file, but before generating the buffer." 393 "A hook after reading the .newsrc file, but before generating the buffer."
359 :group 'gnus-start 394 :group 'gnus-start
395 :type 'hook)
396
397 (defcustom gnus-get-top-new-news-hook nil
398 "A hook run just before Gnus checks for new news globally."
399 :group 'gnus-group-new
360 :type 'hook) 400 :type 'hook)
361 401
362 (defcustom gnus-get-new-news-hook nil 402 (defcustom gnus-get-new-news-hook nil
363 "A hook run just before Gnus checks for new news." 403 "A hook run just before Gnus checks for new news."
364 :group 'gnus-group-new 404 :group 'gnus-group-new
365 :type 'hook) 405 :type 'hook)
366 406
367 (defcustom gnus-after-getting-new-news-hook 407 (defcustom gnus-after-getting-new-news-hook
368 (when (gnus-boundp 'display-time-timer) 408 '(gnus-display-time-event-handler
369 '(display-time-event-handler)) 409 gnus-fixup-nnimap-unread-after-getting-new-news)
370 "*A hook run after Gnus checks for new news when Gnus is already running." 410 "*A hook run after Gnus checks for new news when Gnus is already running."
371 :group 'gnus-group-new 411 :group 'gnus-group-new
412 :type 'hook)
413
414 (defcustom gnus-read-newsrc-el-hook nil
415 "A hook called after reading the newsrc.eld? file."
416 :group 'gnus-newsrc
372 :type 'hook) 417 :type 'hook)
373 418
374 (defcustom gnus-save-newsrc-hook nil 419 (defcustom gnus-save-newsrc-hook nil
375 "A hook called before saving any of the newsrc files." 420 "A hook called before saving any of the newsrc files."
376 :group 'gnus-newsrc 421 :group 'gnus-newsrc
384 429
385 (defcustom gnus-save-standard-newsrc-hook nil 430 (defcustom gnus-save-standard-newsrc-hook nil
386 "A hook called just before saving the standard newsrc file. 431 "A hook called just before saving the standard newsrc file.
387 Can be used to turn version control on or off." 432 Can be used to turn version control on or off."
388 :group 'gnus-newsrc 433 :group 'gnus-newsrc
434 :type 'hook)
435
436 (defcustom gnus-group-mode-hook nil
437 "Hook for Gnus group mode."
438 :group 'gnus-group-various
439 :options '(gnus-topic-mode)
389 :type 'hook) 440 :type 'hook)
390 441
391 (defcustom gnus-always-read-dribble-file nil 442 (defcustom gnus-always-read-dribble-file nil
392 "Unconditionally read the dribble file." 443 "Unconditionally read the dribble file."
393 :group 'gnus-newsrc 444 :group 'gnus-newsrc
430 (if (or debug-on-error debug-on-quit) 481 (if (or debug-on-error debug-on-quit)
431 (load file nil t) 482 (load file nil t)
432 (condition-case var 483 (condition-case var
433 (load file nil t) 484 (load file nil t)
434 (error 485 (error
435 (error "Error in %s: %s" file var))))))))) 486 (error "Error in %s: %s" file (cadr var))))))))))
436 487
437 ;; For subscribing new newsgroup 488 ;; For subscribing new newsgroup
438 489
439 (defun gnus-subscribe-hierarchical-interactive (groups) 490 (defun gnus-subscribe-hierarchical-interactive (groups)
440 (let ((groups (sort groups 'string<)) 491 (let ((groups (sort groups 'string<))
506 (defun gnus-subscribe-randomly (newsgroup) 557 (defun gnus-subscribe-randomly (newsgroup)
507 "Subscribe new NEWSGROUP by making it the first newsgroup." 558 "Subscribe new NEWSGROUP by making it the first newsgroup."
508 (gnus-subscribe-newsgroup newsgroup)) 559 (gnus-subscribe-newsgroup newsgroup))
509 560
510 (defun gnus-subscribe-alphabetically (newgroup) 561 (defun gnus-subscribe-alphabetically (newgroup)
511 "Subscribe new NEWSGROUP and insert it in alphabetical order." 562 "Subscribe new NEWGROUP and insert it in alphabetical order."
512 (let ((groups (cdr gnus-newsrc-alist)) 563 (let ((groups (cdr gnus-newsrc-alist))
513 before) 564 before)
514 (while (and (not before) groups) 565 (while (and (not before) groups)
515 (if (string< newgroup (caar groups)) 566 (if (string< newgroup (caar groups))
516 (setq before (caar groups)) 567 (setq before (caar groups))
517 (setq groups (cdr groups)))) 568 (setq groups (cdr groups))))
518 (gnus-subscribe-newsgroup newgroup before))) 569 (gnus-subscribe-newsgroup newgroup before)))
519 570
520 (defun gnus-subscribe-hierarchically (newgroup) 571 (defun gnus-subscribe-hierarchically (newgroup)
521 "Subscribe new NEWSGROUP and insert it in hierarchical newsgroup order." 572 "Subscribe new NEWGROUP and insert it in hierarchical newsgroup order."
522 ;; Basic ideas by mike-w@cs.aukuni.ac.nz (Mike Williams) 573 ;; Basic ideas by mike-w@cs.aukuni.ac.nz (Mike Williams)
523 (save-excursion 574 (save-excursion
524 (set-buffer (nnheader-find-file-noselect gnus-current-startup-file)) 575 (set-buffer (nnheader-find-file-noselect gnus-current-startup-file))
525 (let ((groupkey newgroup) 576 (prog1
526 before) 577 (let ((groupkey newgroup) before)
527 (while (and (not before) groupkey) 578 (while (and (not before) groupkey)
528 (goto-char (point-min)) 579 (goto-char (point-min))
529 (let ((groupkey-re 580 (let ((groupkey-re
530 (concat "^\\(" (regexp-quote groupkey) ".*\\)[!:]"))) 581 (concat "^\\(" (regexp-quote groupkey) ".*\\)[!:]")))
531 (while (and (re-search-forward groupkey-re nil t) 582 (while (and (re-search-forward groupkey-re nil t)
532 (progn 583 (progn
533 (setq before (match-string 1)) 584 (setq before (match-string 1))
534 (string< before newgroup))))) 585 (string< before newgroup)))))
535 ;; Remove tail of newsgroup name (eg. a.b.c -> a.b) 586 ;; Remove tail of newsgroup name (eg. a.b.c -> a.b)
536 (setq groupkey 587 (setq groupkey
537 (when (string-match "^\\(.*\\)\\.[^.]+$" groupkey) 588 (when (string-match "^\\(.*\\)\\.[^.]+$" groupkey)
538 (substring groupkey (match-beginning 1) (match-end 1))))) 589 (substring groupkey (match-beginning 1) (match-end 1)))))
539 (gnus-subscribe-newsgroup newgroup before)) 590 (gnus-subscribe-newsgroup newgroup before))
540 (kill-buffer (current-buffer)))) 591 (kill-buffer (current-buffer)))))
541 592
542 (defun gnus-subscribe-interactively (group) 593 (defun gnus-subscribe-interactively (group)
543 "Subscribe the new GROUP interactively. 594 "Subscribe the new GROUP interactively.
544 It is inserted in hierarchical newsgroup order if subscribed. If not, 595 It is inserted in hierarchical newsgroup order if subscribed. If not,
545 it is killed." 596 it is killed."
564 ;; We subscribe the group by changing its level to `subscribed'. 615 ;; We subscribe the group by changing its level to `subscribed'.
565 (gnus-group-change-level 616 (gnus-group-change-level
566 newsgroup gnus-level-default-subscribed 617 newsgroup gnus-level-default-subscribed
567 gnus-level-killed (gnus-gethash (or next "dummy.group") 618 gnus-level-killed (gnus-gethash (or next "dummy.group")
568 gnus-newsrc-hashtb)) 619 gnus-newsrc-hashtb))
569 (gnus-message 5 "Subscribe newsgroup: %s" newsgroup))) 620 (gnus-message 5 "Subscribe newsgroup: %s" newsgroup)
621 (run-hook-with-args 'gnus-subscribe-newsgroup-hooks newsgroup)
622 t))
570 623
571 (defun gnus-read-active-file-p () 624 (defun gnus-read-active-file-p ()
572 "Say whether the active file has been read from `gnus-select-method'." 625 "Say whether the active file has been read from `gnus-select-method'."
573 (memq gnus-select-method gnus-have-read-active-file)) 626 (memq gnus-select-method gnus-have-read-active-file))
574 627
575 ;;; General various misc type functions. 628 ;;; General various misc type functions.
576 629
577 ;; Silence byte-compiler. 630 ;; Silence byte-compiler.
578 (defvar gnus-current-headers) 631 (eval-when-compile
579 (defvar gnus-thread-indent-array) 632 (defvar gnus-current-headers)
580 (defvar gnus-newsgroup-name) 633 (defvar gnus-thread-indent-array)
581 (defvar gnus-newsgroup-headers) 634 (defvar gnus-newsgroup-name)
582 (defvar gnus-group-list-mode) 635 (defvar gnus-newsgroup-headers)
583 (defvar gnus-group-mark-positions) 636 (defvar gnus-group-list-mode)
584 (defvar gnus-newsgroup-data) 637 (defvar gnus-group-mark-positions)
585 (defvar gnus-newsgroup-unreads) 638 (defvar gnus-newsgroup-data)
586 (defvar nnoo-state-alist) 639 (defvar gnus-newsgroup-unreads)
587 (defvar gnus-current-select-method) 640 (defvar nnoo-state-alist)
641 (defvar gnus-current-select-method)
642 (defvar mail-sources)
643 (defvar nnmail-scan-directory-mail-source-once)
644 (defvar nnmail-split-history)
645 (defvar nnmail-spool-file))
646
647 (defun gnus-close-all-servers ()
648 "Close all servers."
649 (interactive)
650 (dolist (server gnus-opened-servers)
651 (gnus-close-server (car server))))
588 652
589 (defun gnus-clear-system () 653 (defun gnus-clear-system ()
590 "Clear all variables and buffers." 654 "Clear all variables and buffers."
591 ;; Clear Gnus variables. 655 ;; Clear Gnus variables.
592 (let ((variables gnus-variable-list)) 656 (let ((variables (remove 'gnus-format-specs gnus-variable-list)))
593 (while variables 657 (while variables
594 (set (car variables) nil) 658 (set (car variables) nil)
595 (setq variables (cdr variables)))) 659 (setq variables (cdr variables))))
596 ;; Clear other internal variables. 660 ;; Clear other internal variables.
597 (setq gnus-list-of-killed-groups nil 661 (setq gnus-list-of-killed-groups nil
598 gnus-have-read-active-file nil 662 gnus-have-read-active-file nil
663 gnus-agent-covered-methods nil
664 gnus-server-method-cache nil
599 gnus-newsrc-alist nil 665 gnus-newsrc-alist nil
600 gnus-newsrc-hashtb nil 666 gnus-newsrc-hashtb nil
601 gnus-killed-list nil 667 gnus-killed-list nil
602 gnus-zombie-list nil 668 gnus-zombie-list nil
603 gnus-killed-hashtb nil 669 gnus-killed-hashtb nil
628 ;; Kill global KILL file buffer. 694 ;; Kill global KILL file buffer.
629 (when (get-file-buffer (gnus-newsgroup-kill-file nil)) 695 (when (get-file-buffer (gnus-newsgroup-kill-file nil))
630 (kill-buffer (get-file-buffer (gnus-newsgroup-kill-file nil)))) 696 (kill-buffer (get-file-buffer (gnus-newsgroup-kill-file nil))))
631 (gnus-kill-buffer nntp-server-buffer) 697 (gnus-kill-buffer nntp-server-buffer)
632 ;; Kill Gnus buffers. 698 ;; Kill Gnus buffers.
633 (let ((buffers (gnus-buffers))) 699 (dolist (buffer (gnus-buffers))
634 (when buffers 700 (gnus-kill-buffer buffer))
635 (mapcar 'kill-buffer buffers)))
636 ;; Remove Gnus frames. 701 ;; Remove Gnus frames.
637 (gnus-kill-gnus-frames)) 702 (gnus-kill-gnus-frames))
638 703
639 (defun gnus-no-server-1 (&optional arg slave) 704 (defun gnus-no-server-1 (&optional arg slave)
640 "Read network news. 705 "Read network news.
668 (gnus-splash) 733 (gnus-splash)
669 (gnus-run-hooks 'gnus-before-startup-hook) 734 (gnus-run-hooks 'gnus-before-startup-hook)
670 (nnheader-init-server-buffer) 735 (nnheader-init-server-buffer)
671 (setq gnus-slave slave) 736 (setq gnus-slave slave)
672 (gnus-read-init-file) 737 (gnus-read-init-file)
738 (if gnus-agent
739 (gnus-agentize))
673 740
674 (when gnus-simple-splash 741 (when gnus-simple-splash
675 (setq gnus-simple-splash nil) 742 (setq gnus-simple-splash nil)
676 (cond 743 (cond
677 ((featurep 'xemacs) 744 ((featurep 'xemacs)
705 (when gnus-use-grouplens 772 (when gnus-use-grouplens
706 (bbb-login) 773 (bbb-login)
707 (add-hook 'gnus-summary-mode-hook 'gnus-grouplens-mode)) 774 (add-hook 'gnus-summary-mode-hook 'gnus-grouplens-mode))
708 775
709 ;; Do the actual startup. 776 ;; Do the actual startup.
777 (if gnus-agent
778 (gnus-request-create-group "queue" '(nndraft "")))
779 (gnus-request-create-group "drafts" '(nndraft ""))
710 (gnus-setup-news nil level dont-connect) 780 (gnus-setup-news nil level dont-connect)
711 (gnus-run-hooks 'gnus-setup-news-hook) 781 (gnus-run-hooks 'gnus-setup-news-hook)
712 (gnus-start-draft-setup) 782 (gnus-start-draft-setup)
713 ;; Generate the group buffer. 783 ;; Generate the group buffer.
714 (gnus-group-list-groups level) 784 (gnus-group-list-groups level)
724 (let ((gnus-level-default-subscribed 1)) 794 (let ((gnus-level-default-subscribed 1))
725 (gnus-subscribe-group "nndraft:drafts" nil '(nndraft ""))) 795 (gnus-subscribe-group "nndraft:drafts" nil '(nndraft "")))
726 (gnus-group-set-parameter 796 (gnus-group-set-parameter
727 "nndraft:drafts" 'gnus-dummy '((gnus-draft-mode))))) 797 "nndraft:drafts" 'gnus-dummy '((gnus-draft-mode)))))
728 798
729 ;;;###autoload
730 (defun gnus-unload ()
731 "Unload all Gnus features.
732 \(For some value of `all' or `Gnus'.) Currently, features whose names
733 have prefixes `gnus-', `nn', `mm-' or `rfc' are unloaded. Use
734 cautiously -- unloading may cause trouble."
735 (interactive)
736 (dolist (feature features)
737 (if (string-match "^\\(gnus-\\|nn\\|mm-\\|rfc\\)" (symbol-name feature))
738 (unload-feature feature 'force))))
739
740 799
741 ;;; 800 ;;;
742 ;;; Dribble file 801 ;;; Dribble file
743 ;;; 802 ;;;
744 803
761 (buffer-name gnus-dribble-buffer)) 820 (buffer-name gnus-dribble-buffer))
762 (let ((obuf (current-buffer))) 821 (let ((obuf (current-buffer)))
763 (set-buffer gnus-dribble-buffer) 822 (set-buffer gnus-dribble-buffer)
764 (goto-char (point-max)) 823 (goto-char (point-max))
765 (insert string "\n") 824 (insert string "\n")
766 (set-window-point (get-buffer-window (current-buffer)) (point-max)) 825 ;; This has been commented by Josh Huber <huber@alum.wpi.edu>
826 ;; It causes problems with both XEmacs and Emacs 21, and doesn't
827 ;; seem to be of much value. (FIXME: remove this after we make sure
828 ;; it's not needed).
829 ;; (set-window-point (get-buffer-window (current-buffer)) (point-max))
767 (bury-buffer gnus-dribble-buffer) 830 (bury-buffer gnus-dribble-buffer)
768 (save-excursion 831 (save-excursion
769 (set-buffer gnus-group-buffer) 832 (set-buffer gnus-group-buffer)
770 (gnus-group-set-mode-line)) 833 (gnus-group-set-mode-line))
771 (set-buffer obuf)))) 834 (set-buffer obuf))))
787 (buffer-disable-undo) 850 (buffer-disable-undo)
788 (bury-buffer (current-buffer)) 851 (bury-buffer (current-buffer))
789 (set-buffer-modified-p nil) 852 (set-buffer-modified-p nil)
790 (let ((auto (make-auto-save-file-name)) 853 (let ((auto (make-auto-save-file-name))
791 (gnus-dribble-ignore t) 854 (gnus-dribble-ignore t)
855 (purpose nil)
792 modes) 856 modes)
793 (when (or (file-exists-p auto) (file-exists-p dribble-file)) 857 (when (or (file-exists-p auto) (file-exists-p dribble-file))
794 ;; Load whichever file is newest -- the auto save file 858 ;; Load whichever file is newest -- the auto save file
795 ;; or the "real" file. 859 ;; or the "real" file.
796 (if (file-newer-than-file-p auto dribble-file) 860 (if (file-newer-than-file-p auto dribble-file)
802 (save-buffer) 866 (save-buffer)
803 (when (and (file-exists-p gnus-current-startup-file) 867 (when (and (file-exists-p gnus-current-startup-file)
804 (file-exists-p dribble-file) 868 (file-exists-p dribble-file)
805 (setq modes (file-modes gnus-current-startup-file))) 869 (setq modes (file-modes gnus-current-startup-file)))
806 (set-file-modes dribble-file modes)) 870 (set-file-modes dribble-file modes))
871 (goto-char (point-min))
872 (when (search-forward "Gnus was exited on purpose" nil t)
873 (setq purpose t))
807 ;; Possibly eval the file later. 874 ;; Possibly eval the file later.
808 (when (or gnus-always-read-dribble-file 875 (when (or gnus-always-read-dribble-file
809 (gnus-y-or-n-p 876 (gnus-y-or-n-p
810 "Gnus auto-save file exists. Do you want to read it? ")) 877 (if purpose
878 "Gnus exited on purpose without saving; read auto-save file anyway? "
879 "Gnus auto-save file exists. Do you want to read it? ")))
811 (setq gnus-dribble-eval-file t))))))) 880 (setq gnus-dribble-eval-file t)))))))
812 881
813 (defun gnus-dribble-eval-file () 882 (defun gnus-dribble-eval-file ()
814 (when gnus-dribble-eval-file 883 (when gnus-dribble-eval-file
815 (setq gnus-dribble-eval-file nil) 884 (setq gnus-dribble-eval-file nil)
867 ;; Read the newsrc file and create `gnus-newsrc-hashtb'. 936 ;; Read the newsrc file and create `gnus-newsrc-hashtb'.
868 (gnus-read-newsrc-file rawfile)) 937 (gnus-read-newsrc-file rawfile))
869 938
870 ;; Make sure the archive server is available to all and sundry. 939 ;; Make sure the archive server is available to all and sundry.
871 (when gnus-message-archive-method 940 (when gnus-message-archive-method
872 (setq gnus-server-alist (delq (assoc "archive" gnus-server-alist) 941 (unless (assoc "archive" gnus-server-alist)
873 gnus-server-alist)) 942 (push `("archive"
874 (push (cons "archive" gnus-message-archive-method) 943 nnfolder
875 gnus-server-alist)) 944 "archive"
945 (nnfolder-directory
946 ,(nnheader-concat message-directory "archive"))
947 (nnfolder-active-file
948 ,(nnheader-concat message-directory "archive/active"))
949 (nnfolder-get-new-mail nil)
950 (nnfolder-inhibit-expiry t))
951 gnus-server-alist)))
876 952
877 ;; If we don't read the complete active file, we fill in the 953 ;; If we don't read the complete active file, we fill in the
878 ;; hashtb here. 954 ;; hashtb here.
879 (when (or (null gnus-read-active-file) 955 (when (or (null gnus-read-active-file)
880 (eq gnus-read-active-file 'some)) 956 (eq gnus-read-active-file 'some))
881 (gnus-update-active-hashtb-from-killed)) 957 (gnus-update-active-hashtb-from-killed))
958
959 ;; Validate agent covered methods now that gnus-server-alist has
960 ;; been initialized.
961 ;; NOTE: This is here for one purpose only. By validating the
962 ;; agentized server's, it converts the old 5.10.3, and earlier,
963 ;; format to the current format. That enables the agent code
964 ;; within gnus-read-active-file to function correctly.
965 (if gnus-agent
966 (gnus-agent-read-servers-validate))
882 967
883 ;; Read the active file and create `gnus-active-hashtb'. 968 ;; Read the active file and create `gnus-active-hashtb'.
884 ;; If `gnus-read-active-file' is nil, then we just create an empty 969 ;; If `gnus-read-active-file' is nil, then we just create an empty
885 ;; hash table. The partial filling out of the hash table will be 970 ;; hash table. The partial filling out of the hash table will be
886 ;; done in `gnus-get-unread-articles'. 971 ;; done in `gnus-get-unread-articles'.
906 991
907 (gnus-update-format-specifications) 992 (gnus-update-format-specifications)
908 993
909 ;; See whether we need to read the description file. 994 ;; See whether we need to read the description file.
910 (when (and (boundp 'gnus-group-line-format) 995 (when (and (boundp 'gnus-group-line-format)
996 (stringp gnus-group-line-format)
911 (let ((case-fold-search nil)) 997 (let ((case-fold-search nil))
912 (string-match "%[-,0-9]*D" gnus-group-line-format)) 998 (string-match "%[-,0-9]*D" gnus-group-line-format))
913 (not gnus-description-hashtb) 999 (not gnus-description-hashtb)
914 (not dont-connect) 1000 (not dont-connect)
915 gnus-read-active-file) 1001 gnus-read-active-file)
920 (gnus-check-server gnus-select-method) 1006 (gnus-check-server gnus-select-method)
921 (not gnus-slave) 1007 (not gnus-slave)
922 gnus-plugged) 1008 gnus-plugged)
923 (gnus-find-new-newsgroups)) 1009 (gnus-find-new-newsgroups))
924 1010
1011 ;; Check and remove bogus newsgroups.
1012 (when (and init gnus-check-bogus-newsgroups
1013 gnus-read-active-file (not level)
1014 (gnus-server-opened gnus-select-method))
1015 (gnus-check-bogus-newsgroups))
1016
925 ;; We might read in new NoCeM messages here. 1017 ;; We might read in new NoCeM messages here.
926 (when (and gnus-use-nocem 1018 (when (and gnus-use-nocem
927 (not level) 1019 (not level)
928 (not dont-connect)) 1020 (not dont-connect))
929 (gnus-nocem-scan-groups)) 1021 (gnus-nocem-scan-groups))
931 ;; Read any slave files. 1023 ;; Read any slave files.
932 (gnus-master-read-slave-newsrc) 1024 (gnus-master-read-slave-newsrc)
933 1025
934 ;; Find the number of unread articles in each non-dead group. 1026 ;; Find the number of unread articles in each non-dead group.
935 (let ((gnus-read-active-file (and (not level) gnus-read-active-file))) 1027 (let ((gnus-read-active-file (and (not level) gnus-read-active-file)))
936 (gnus-get-unread-articles level)) 1028 (gnus-get-unread-articles level))))
937 1029
938 (when (and init gnus-check-bogus-newsgroups 1030 (defun gnus-call-subscribe-functions (method group)
939 gnus-read-active-file (not level) 1031 "Call METHOD to subscribe GROUP.
940 (gnus-server-opened gnus-select-method)) 1032 If no function returns `non-nil', call `gnus-subscribe-zombies'."
941 (gnus-check-bogus-newsgroups)))) 1033 (unless (cond
1034 ((functionp method)
1035 (funcall method group))
1036 ((listp method)
1037 (catch 'found
1038 (dolist (func method)
1039 (if (funcall func group)
1040 (throw 'found t)))
1041 nil))
1042 (t nil))
1043 (gnus-subscribe-zombies group)))
942 1044
943 (defun gnus-find-new-newsgroups (&optional arg) 1045 (defun gnus-find-new-newsgroups (&optional arg)
944 "Search for new newsgroups and add them. 1046 "Search for new newsgroups and add them.
945 Each new newsgroup will be treated with `gnus-subscribe-newsgroup-method'. 1047 Each new newsgroup will be treated with `gnus-subscribe-newsgroup-method'.
946 The `-n' option line from .newsrc is respected. 1048 The `-n' option line from .newsrc is respected.
990 (let ((do-sub (gnus-matches-options-n group))) 1092 (let ((do-sub (gnus-matches-options-n group)))
991 (cond 1093 (cond
992 ((eq do-sub 'subscribe) 1094 ((eq do-sub 'subscribe)
993 (setq groups (1+ groups)) 1095 (setq groups (1+ groups))
994 (gnus-sethash group group gnus-killed-hashtb) 1096 (gnus-sethash group group gnus-killed-hashtb)
995 (funcall gnus-subscribe-options-newsgroup-method group)) 1097 (gnus-call-subscribe-functions
1098 gnus-subscribe-options-newsgroup-method group))
996 ((eq do-sub 'ignore) 1099 ((eq do-sub 'ignore)
997 nil) 1100 nil)
998 (t 1101 (t
999 (setq groups (1+ groups)) 1102 (setq groups (1+ groups))
1000 (gnus-sethash group group gnus-killed-hashtb) 1103 (gnus-sethash group group gnus-killed-hashtb)
1001 (if gnus-subscribe-hierarchical-interactive 1104 (if gnus-subscribe-hierarchical-interactive
1002 (push group new-newsgroups) 1105 (push group new-newsgroups)
1003 (funcall gnus-subscribe-newsgroup-method group))))))) 1106 (gnus-call-subscribe-functions
1107 gnus-subscribe-newsgroup-method group)))))))
1004 gnus-active-hashtb) 1108 gnus-active-hashtb)
1005 (when new-newsgroups 1109 (when new-newsgroups
1006 (gnus-subscribe-hierarchical-interactive new-newsgroups)) 1110 (gnus-subscribe-hierarchical-interactive new-newsgroups))
1007 (if (> groups 0) 1111 (if (> groups 0)
1008 (gnus-message 5 "%d new newsgroup%s arrived." 1112 (gnus-message 5 "%d new newsgroup%s arrived."
1083 (let ((do-sub (gnus-matches-options-n group))) 1187 (let ((do-sub (gnus-matches-options-n group)))
1084 (cond 1188 (cond
1085 ((eq do-sub 'subscribe) 1189 ((eq do-sub 'subscribe)
1086 (incf groups) 1190 (incf groups)
1087 (gnus-sethash group group gnus-killed-hashtb) 1191 (gnus-sethash group group gnus-killed-hashtb)
1088 (funcall gnus-subscribe-options-newsgroup-method group)) 1192 (gnus-call-subscribe-functions
1193 gnus-subscribe-options-newsgroup-method group))
1089 ((eq do-sub 'ignore) 1194 ((eq do-sub 'ignore)
1090 nil) 1195 nil)
1091 (t 1196 (t
1092 (incf groups) 1197 (incf groups)
1093 (gnus-sethash group group gnus-killed-hashtb) 1198 (gnus-sethash group group gnus-killed-hashtb)
1094 (if gnus-subscribe-hierarchical-interactive 1199 (if gnus-subscribe-hierarchical-interactive
1095 (push group new-newsgroups) 1200 (push group new-newsgroups)
1096 (funcall gnus-subscribe-newsgroup-method group))))))) 1201 (gnus-call-subscribe-functions
1202 gnus-subscribe-newsgroup-method group)))))))
1097 hashtb)) 1203 hashtb))
1098 (when new-newsgroups 1204 (when new-newsgroups
1099 (gnus-subscribe-hierarchical-interactive new-newsgroups))) 1205 (gnus-subscribe-hierarchical-interactive new-newsgroups)))
1100 (if (> groups 0) 1206 (if (> groups 0)
1101 (gnus-message 5 "%d new newsgroup%s arrived" 1207 (gnus-message 5 "%d new newsgroup%s arrived"
1107 1213
1108 (defun gnus-check-first-time-used () 1214 (defun gnus-check-first-time-used ()
1109 (catch 'ended 1215 (catch 'ended
1110 ;; First check if any of the following files exist. If they do, 1216 ;; First check if any of the following files exist. If they do,
1111 ;; it's not the first time the user has used Gnus. 1217 ;; it's not the first time the user has used Gnus.
1112 (dolist (file (list gnus-current-startup-file 1218 (dolist (file (list (concat gnus-current-startup-file ".el")
1113 (concat gnus-current-startup-file ".el")
1114 (concat gnus-current-startup-file ".eld") 1219 (concat gnus-current-startup-file ".eld")
1115 gnus-startup-file
1116 (concat gnus-startup-file ".el") 1220 (concat gnus-startup-file ".el")
1117 (concat gnus-startup-file ".eld"))) 1221 (concat gnus-startup-file ".eld")))
1118 (when (file-exists-p file) 1222 (when (file-exists-p file)
1119 (throw 'ended nil))) 1223 (throw 'ended nil)))
1120 (gnus-message 6 "First time user; subscribing you to default groups") 1224 (gnus-message 6 "First time user; subscribing you to default groups")
1124 (setq gnus-newsrc-last-checked-date (message-make-date)) 1228 (setq gnus-newsrc-last-checked-date (message-make-date))
1125 ;; Subscribe to the default newsgroups. 1229 ;; Subscribe to the default newsgroups.
1126 (let ((groups (or gnus-default-subscribed-newsgroups 1230 (let ((groups (or gnus-default-subscribed-newsgroups
1127 gnus-backup-default-subscribed-newsgroups)) 1231 gnus-backup-default-subscribed-newsgroups))
1128 group) 1232 group)
1129 (when (eq groups t) 1233 (if (eq groups t)
1130 ;; If t, we subscribe (or not) all groups as if they were new. 1234 ;; If t, we subscribe (or not) all groups as if they were new.
1131 (mapatoms 1235 (mapatoms
1132 (lambda (sym) 1236 (lambda (sym)
1133 (when (setq group (symbol-name sym)) 1237 (when (setq group (symbol-name sym))
1134 (let ((do-sub (gnus-matches-options-n group))) 1238 (let ((do-sub (gnus-matches-options-n group)))
1135 (cond 1239 (cond
1136 ((eq do-sub 'subscribe) 1240 ((eq do-sub 'subscribe)
1137 (gnus-sethash group group gnus-killed-hashtb) 1241 (gnus-sethash group group gnus-killed-hashtb)
1138 (funcall gnus-subscribe-options-newsgroup-method group)) 1242 (gnus-call-subscribe-functions
1139 ((eq do-sub 'ignore) 1243 gnus-subscribe-options-newsgroup-method group))
1140 nil) 1244 ((eq do-sub 'ignore)
1141 (t 1245 nil)
1142 (push group gnus-killed-list)))))) 1246 (t
1143 gnus-active-hashtb) 1247 (push group gnus-killed-list))))))
1248 gnus-active-hashtb)
1144 (dolist (group groups) 1249 (dolist (group groups)
1145 ;; Only subscribe the default groups that are activated. 1250 ;; Only subscribe the default groups that are activated.
1146 (when (gnus-active group) 1251 (when (gnus-active group)
1147 (gnus-group-change-level 1252 (gnus-group-change-level
1148 group gnus-level-default-subscribed gnus-level-killed))) 1253 group gnus-level-default-subscribed gnus-level-killed)))
1149 (save-excursion 1254 (save-excursion
1150 (set-buffer gnus-group-buffer) 1255 (set-buffer gnus-group-buffer)
1151 (gnus-group-make-help-group)) 1256 ;; Don't error if the group already exists. This happens when a
1257 ;; first-time user types 'F'. -- didier
1258 (gnus-group-make-help-group t))
1152 (when gnus-novice-user 1259 (when gnus-novice-user
1153 (gnus-message 7 "`A k' to list killed groups")))))) 1260 (gnus-message 7 "`A k' to list killed groups"))))))
1154 1261
1155 (defun gnus-subscribe-group (group &optional previous method) 1262 (defun gnus-subscribe-group (group &optional previous method)
1156 "Subcribe GROUP and put it after PREVIOUS." 1263 "Subscribe GROUP and put it after PREVIOUS."
1157 (gnus-group-change-level 1264 (gnus-group-change-level
1158 (if method 1265 (if method
1159 (list t group gnus-level-default-subscribed nil nil method) 1266 (list t group gnus-level-default-subscribed nil nil method)
1160 group) 1267 group)
1161 gnus-level-default-subscribed gnus-level-killed previous t) 1268 gnus-level-default-subscribed gnus-level-killed previous t)
1211 ;; If the group was killed, we remove it from the killed or zombie 1318 ;; If the group was killed, we remove it from the killed or zombie
1212 ;; list. If not, and it is in fact going to be killed, we remove 1319 ;; list. If not, and it is in fact going to be killed, we remove
1213 ;; it from the newsrc hash table and assoc. 1320 ;; it from the newsrc hash table and assoc.
1214 (cond 1321 (cond
1215 ((>= oldlevel gnus-level-zombie) 1322 ((>= oldlevel gnus-level-zombie)
1216 (if (= oldlevel gnus-level-zombie) 1323 ;; oldlevel could be wrong.
1217 (setq gnus-zombie-list (delete group gnus-zombie-list)) 1324 (setq gnus-zombie-list (delete group gnus-zombie-list))
1218 (setq gnus-killed-list (delete group gnus-killed-list)))) 1325 (setq gnus-killed-list (delete group gnus-killed-list)))
1219 (t 1326 (t
1220 (when (and (>= level gnus-level-zombie) 1327 (when (and (>= level gnus-level-zombie)
1221 entry) 1328 entry)
1222 (gnus-sethash (car (nth 2 entry)) nil gnus-newsrc-hashtb) 1329 (gnus-sethash (car (nth 2 entry)) nil gnus-newsrc-hashtb)
1223 (when (nth 3 entry) 1330 (when (nth 3 entry)
1236 ;; We do not enter foreign groups into the list of dead 1343 ;; We do not enter foreign groups into the list of dead
1237 ;; groups. 1344 ;; groups.
1238 (unless (gnus-group-foreign-p group) 1345 (unless (gnus-group-foreign-p group)
1239 (if (= level gnus-level-zombie) 1346 (if (= level gnus-level-zombie)
1240 (push group gnus-zombie-list) 1347 (push group gnus-zombie-list)
1241 (push group gnus-killed-list)))) 1348 (if (= oldlevel gnus-level-killed)
1349 ;; Remove from active hashtb.
1350 (unintern group gnus-active-hashtb)
1351 ;; Don't add it into killed-list if it was killed.
1352 (push group gnus-killed-list)))))
1242 (t 1353 (t
1243 ;; If the list is to be entered into the newsrc assoc, and 1354 ;; If the list is to be entered into the newsrc assoc, and
1244 ;; it was killed, we have to create an entry in the newsrc 1355 ;; it was killed, we have to create an entry in the newsrc
1245 ;; hashtb format and fix the pointers in the newsrc assoc. 1356 ;; hashtb format and fix the pointers in the newsrc assoc.
1246 (if (< oldlevel gnus-level-zombie) 1357 (if (< oldlevel gnus-level-zombie)
1304 ;; Find all bogus newsgroup that are subscribed. 1415 ;; Find all bogus newsgroup that are subscribed.
1305 (while newsrc 1416 (while newsrc
1306 (setq info (pop newsrc) 1417 (setq info (pop newsrc)
1307 group (gnus-info-group info)) 1418 group (gnus-info-group info))
1308 (unless (or (gnus-active group) ; Active 1419 (unless (or (gnus-active group) ; Active
1309 (gnus-info-method info)) ; Foreign 1420 (and (gnus-info-method info)
1421 (not (gnus-secondary-method-p
1422 (gnus-info-method info))))) ; Foreign
1310 ;; Found a bogus newsgroup. 1423 ;; Found a bogus newsgroup.
1311 (push group bogus))) 1424 (push group bogus)))
1312 (if confirm 1425 (if confirm
1313 (map-y-or-n-p 1426 (map-y-or-n-p
1314 "Remove bogus group %s? " 1427 "Remove bogus group %s? "
1375 (progn 1488 (progn
1376 (and scan 1489 (and scan
1377 (gnus-check-backend-function 'request-scan (car method)) 1490 (gnus-check-backend-function 'request-scan (car method))
1378 (gnus-request-scan group method)) 1491 (gnus-request-scan group method))
1379 t) 1492 t)
1380 (condition-case () 1493 (if (or debug-on-error debug-on-quit)
1381 (inline (gnus-request-group group dont-check method)) 1494 (inline (gnus-request-group group dont-check method))
1382 ;;(error nil) 1495 (condition-case nil
1383 (quit 1496 (inline (gnus-request-group group dont-check method))
1384 (message "Quit activating %s" group) 1497 ;;(error nil)
1385 nil)) 1498 (quit
1386 (setq active (gnus-parse-active)) 1499 (message "Quit activating %s" group)
1387 ;; If there are no articles in the group, the GROUP 1500 nil)))
1388 ;; command may have responded with the `(0 . 0)'. We 1501 (unless dont-check
1389 ;; ignore this if we already have an active entry 1502 (setq active (gnus-parse-active))
1390 ;; for the group. 1503 ;; If there are no articles in the group, the GROUP
1391 (if (and (zerop (car active)) 1504 ;; command may have responded with the `(0 . 0)'. We
1392 (zerop (cdr active)) 1505 ;; ignore this if we already have an active entry
1393 (gnus-active group)) 1506 ;; for the group.
1394 (gnus-active group) 1507 (if (and (zerop (car active))
1395 (gnus-set-active group active) 1508 (zerop (cdr active))
1396 ;; Return the new active info. 1509 (gnus-active group))
1397 active)))) 1510 (gnus-active group)
1511
1512 (gnus-set-active group active)
1513 ;; Return the new active info.
1514 active)))))
1398 1515
1399 (defun gnus-get-unread-articles-in-group (info active &optional update) 1516 (defun gnus-get-unread-articles-in-group (info active &optional update)
1400 (when active 1517 (when active
1401 ;; Allow the backend to update the info in the group. 1518 ;; Allow the backend to update the info in the group.
1402 (when (and update 1519 (when (and update
1409 (num 0)) 1526 (num 0))
1410 ;; If a cache is present, we may have to alter the active info. 1527 ;; If a cache is present, we may have to alter the active info.
1411 (when (and gnus-use-cache info) 1528 (when (and gnus-use-cache info)
1412 (inline (gnus-cache-possibly-alter-active 1529 (inline (gnus-cache-possibly-alter-active
1413 (gnus-info-group info) active))) 1530 (gnus-info-group info) active)))
1531
1532 ;; If the agent is enabled, we may have to alter the active info.
1533 (when (and gnus-agent info)
1534 (gnus-agent-possibly-alter-active
1535 (gnus-info-group info) active))
1536
1414 ;; Modify the list of read articles according to what articles 1537 ;; Modify the list of read articles according to what articles
1415 ;; are available; then tally the unread articles and add the 1538 ;; are available; then tally the unread articles and add the
1416 ;; number to the group hash table entry. 1539 ;; number to the group hash table entry.
1417 (cond 1540 (cond
1418 ((zerop (cdr active)) 1541 ((zerop (cdr active))
1475 (or (and (atom (car range)) (car range)) 1598 (or (and (atom (car range)) (car range))
1476 (caar range))))) 1599 (caar range)))))
1477 (setq range (cdr range))) 1600 (setq range (cdr range)))
1478 (setq num (max 0 (- (cdr active) num))))) 1601 (setq num (max 0 (- (cdr active) num)))))
1479 ;; Set the number of unread articles. 1602 ;; Set the number of unread articles.
1480 (when info 1603 (when (and info
1604 (gnus-gethash (gnus-info-group info) gnus-newsrc-hashtb))
1481 (setcar (gnus-gethash (gnus-info-group info) gnus-newsrc-hashtb) num)) 1605 (setcar (gnus-gethash (gnus-info-group info) gnus-newsrc-hashtb) num))
1482 num))) 1606 num)))
1483 1607
1484 ;; Go though `gnus-newsrc-alist' and compare with `gnus-active-hashtb' 1608 ;; Go though `gnus-newsrc-alist' and compare with `gnus-active-hashtb'
1485 ;; and compute how many unread articles there are in each group. 1609 ;; and compute how many unread articles there are in each group.
1486 (defun gnus-get-unread-articles (&optional level) 1610 (defun gnus-get-unread-articles (&optional level)
1611 (setq gnus-server-method-cache nil)
1487 (let* ((newsrc (cdr gnus-newsrc-alist)) 1612 (let* ((newsrc (cdr gnus-newsrc-alist))
1488 (level (or level gnus-activate-level (1+ gnus-level-subscribed))) 1613 (level (or level gnus-activate-level (1+ gnus-level-subscribed)))
1489 (foreign-level 1614 (foreign-level
1490 (min 1615 (min
1491 (cond ((and gnus-activate-foreign-newsgroups 1616 (cond ((and gnus-activate-foreign-newsgroups
1493 (1+ gnus-level-subscribed)) 1618 (1+ gnus-level-subscribed))
1494 ((numberp gnus-activate-foreign-newsgroups) 1619 ((numberp gnus-activate-foreign-newsgroups)
1495 gnus-activate-foreign-newsgroups) 1620 gnus-activate-foreign-newsgroups)
1496 (t 0)) 1621 (t 0))
1497 level)) 1622 level))
1498 scanned-methods info group active method retrievegroups) 1623 (methods-cache nil)
1499 (gnus-message 5 "Checking new news...") 1624 (type-cache nil)
1625 scanned-methods info group active method retrieve-groups cmethod
1626 method-type)
1627 (gnus-message 6 "Checking new news...")
1500 1628
1501 (while newsrc 1629 (while newsrc
1502 (setq active (gnus-active (setq group (gnus-info-group 1630 (setq active (gnus-active (setq group (gnus-info-group
1503 (setq info (pop newsrc)))))) 1631 (setq info (pop newsrc))))))
1504 1632
1512 ;; >0 for an active group with messages 1640 ;; >0 for an active group with messages
1513 ;; 0 for an active group with no unread messages 1641 ;; 0 for an active group with no unread messages
1514 ;; nil for non-foreign groups that the user has requested not be checked 1642 ;; nil for non-foreign groups that the user has requested not be checked
1515 ;; t for unchecked foreign groups or bogus groups, or groups that can't 1643 ;; t for unchecked foreign groups or bogus groups, or groups that can't
1516 ;; be checked, for one reason or other. 1644 ;; be checked, for one reason or other.
1517 (if (and (setq method (gnus-info-method info)) 1645 (when (setq method (gnus-info-method info))
1518 (not (inline 1646 (if (setq cmethod (assoc method methods-cache))
1519 (gnus-server-equal 1647 (setq method (cdr cmethod))
1520 gnus-select-method 1648 (setq cmethod (inline (gnus-server-get-method nil method)))
1521 (setq method (gnus-server-get-method nil method))))) 1649 (push (cons method cmethod) methods-cache)
1522 (not (gnus-secondary-method-p method))) 1650 (setq method cmethod)))
1651 (when (and method
1652 (not (setq method-type (cdr (assoc method type-cache)))))
1653 (setq method-type
1654 (cond
1655 ((gnus-secondary-method-p method)
1656 'secondary)
1657 ((inline (gnus-server-equal gnus-select-method method))
1658 'primary)
1659 (t
1660 'foreign)))
1661 (push (cons method method-type) type-cache))
1662 (if (and method
1663 (eq method-type 'foreign))
1523 ;; These groups are foreign. Check the level. 1664 ;; These groups are foreign. Check the level.
1524 (when (and (<= (gnus-info-level info) foreign-level) 1665 (when (and (<= (gnus-info-level info) foreign-level)
1525 (setq active (gnus-activate-group group 'scan))) 1666 (setq active (gnus-activate-group group 'scan)))
1526 ;; Let the Gnus agent save the active file. 1667 ;; Let the Gnus agent save the active file.
1527 (when (and gnus-agent gnus-plugged active) 1668 (when (and gnus-agent active (gnus-online method))
1528 (gnus-agent-save-group-info 1669 (gnus-agent-save-group-info
1529 method (gnus-group-real-name group) active)) 1670 method (gnus-group-real-name group) active))
1530 (unless (inline (gnus-virtual-group-p group)) 1671 (unless (inline (gnus-virtual-group-p group))
1531 (inline (gnus-close-group group))) 1672 (inline (gnus-close-group group)))
1532 (when (fboundp (intern (concat (symbol-name (car method)) 1673 (when (fboundp (intern (concat (symbol-name (car method))
1540 ;; Activate groups. 1681 ;; Activate groups.
1541 ((not gnus-read-active-file) 1682 ((not gnus-read-active-file)
1542 (if (gnus-check-backend-function 'retrieve-groups group) 1683 (if (gnus-check-backend-function 'retrieve-groups group)
1543 ;; if server support gnus-retrieve-groups we push 1684 ;; if server support gnus-retrieve-groups we push
1544 ;; the group onto retrievegroups for later checking 1685 ;; the group onto retrievegroups for later checking
1545 (if (assoc method retrievegroups) 1686 (if (assoc method retrieve-groups)
1546 (setcdr (assoc method retrievegroups) 1687 (setcdr (assoc method retrieve-groups)
1547 (cons group (cdr (assoc method retrievegroups)))) 1688 (cons group (cdr (assoc method retrieve-groups))))
1548 (push (list method group) retrievegroups)) 1689 (push (list method group) retrieve-groups))
1549 ;; hack: `nnmail-get-new-mail' changes the mail-source depending 1690 ;; hack: `nnmail-get-new-mail' changes the mail-source depending
1550 ;; on the group, so we must perform a scan for every group 1691 ;; on the group, so we must perform a scan for every group
1551 ;; if the users has any directory mail sources. 1692 ;; if the users has any directory mail sources.
1552 ;; hack: if `nnmail-scan-directory-mail-source-once' is non-nil, 1693 ;; hack: if `nnmail-scan-directory-mail-source-once' is non-nil,
1553 ;; for it scan all spool files even when the groups are 1694 ;; for it scan all spool files even when the groups are
1561 (list nnmail-spool-file)))))) 1702 (list nnmail-spool-file))))))
1562 (member method scanned-methods)) 1703 (member method scanned-methods))
1563 (setq active (gnus-activate-group group)) 1704 (setq active (gnus-activate-group group))
1564 (setq active (gnus-activate-group group 'scan)) 1705 (setq active (gnus-activate-group group 'scan))
1565 (push method scanned-methods)) 1706 (push method scanned-methods))
1566 (when active 1707 (when active
1567 (gnus-close-group group)))))) 1708 (gnus-close-group group))))))
1568 1709
1569 ;; Get the number of unread articles in the group. 1710 ;; Get the number of unread articles in the group.
1570 (cond 1711 (cond
1571 ((eq active 'ignore) 1712 ((eq active 'ignore)
1572 ;; Don't do anything. 1713 ;; Don't do anything.
1576 (t 1717 (t
1577 ;; The group couldn't be reached, so we nix out the number of 1718 ;; The group couldn't be reached, so we nix out the number of
1578 ;; unread articles and stuff. 1719 ;; unread articles and stuff.
1579 (gnus-set-active group nil) 1720 (gnus-set-active group nil)
1580 (let ((tmp (gnus-gethash group gnus-newsrc-hashtb))) 1721 (let ((tmp (gnus-gethash group gnus-newsrc-hashtb)))
1581 (if tmp (setcar tmp t)))))) 1722 (when tmp
1723 (setcar tmp t))))))
1582 1724
1583 ;; iterate through groups on methods which support gnus-retrieve-groups 1725 ;; iterate through groups on methods which support gnus-retrieve-groups
1584 ;; and fetch a partial active file and use it to find new news. 1726 ;; and fetch a partial active file and use it to find new news.
1585 (while retrievegroups 1727 (dolist (rg retrieve-groups)
1586 (let* ((mg (pop retrievegroups)) 1728 (let ((method (or (car rg) gnus-select-method))
1587 (method (or (car mg) gnus-select-method)) 1729 (groups (cdr rg)))
1588 (groups (cdr mg)))
1589 (when (gnus-check-server method) 1730 (when (gnus-check-server method)
1590 ;; Request that the backend scan its incoming messages. 1731 ;; Request that the backend scan its incoming messages.
1591 (when (gnus-check-backend-function 'request-scan (car method)) 1732 (when (gnus-check-backend-function 'request-scan (car method))
1592 (gnus-request-scan nil method)) 1733 (gnus-request-scan nil method))
1593 (gnus-read-active-file-2 (mapcar (lambda (group) 1734 (gnus-read-active-file-2
1594 (gnus-group-real-name group)) 1735 (mapcar (lambda (group) (gnus-group-real-name group)) groups)
1595 groups) method) 1736 method)
1596 (dolist (group groups) 1737 (dolist (group groups)
1597 (cond 1738 (cond
1598 ((setq active (gnus-active (gnus-info-group 1739 ((setq active (gnus-active (gnus-info-group
1599 (setq info (gnus-get-info group))))) 1740 (setq info (gnus-get-info group)))))
1600 (inline (gnus-get-unread-articles-in-group info active t))) 1741 (inline (gnus-get-unread-articles-in-group info active t)))
1601 (t 1742 (t
1602 ;; The group couldn't be reached, so we nix out the number of 1743 ;; The group couldn't be reached, so we nix out the number of
1603 ;; unread articles and stuff. 1744 ;; unread articles and stuff.
1604 (gnus-set-active group nil) 1745 (gnus-set-active group nil)
1605 (setcar (gnus-gethash group gnus-newsrc-hashtb) t))))))) 1746 (setcar (gnus-gethash group gnus-newsrc-hashtb) t)))))))
1606 1747
1607 (gnus-message 5 "Checking new news...done"))) 1748 (gnus-message 6 "Checking new news...done")))
1608 1749
1609 ;; Create a hash table out of the newsrc alist. The `car's of the 1750 ;; Create a hash table out of the newsrc alist. The `car's of the
1610 ;; alist elements are used as keys. 1751 ;; alist elements are used as keys.
1611 (defun gnus-make-hashtable-from-newsrc-alist () 1752 (defun gnus-make-hashtable-from-newsrc-alist ()
1612 (let ((alist gnus-newsrc-alist) 1753 (let ((alist gnus-newsrc-alist)
1662 (while articles 1803 (while articles
1663 (when (gnus-member-of-range 1804 (when (gnus-member-of-range
1664 (setq article (pop articles)) ranges) 1805 (setq article (pop articles)) ranges)
1665 (push article news))) 1806 (push article news)))
1666 (when news 1807 (when news
1808 ;; Enter this list into the group info.
1667 (gnus-info-set-read 1809 (gnus-info-set-read
1668 info (gnus-remove-from-range (gnus-info-read info) (nreverse news))) 1810 info (gnus-remove-from-range (gnus-info-read info) (nreverse news)))
1811
1812 ;; Set the number of unread articles in gnus-newsrc-hashtb.
1813 (gnus-get-unread-articles-in-group info (gnus-active group))
1814
1815 ;; Insert the change into the group buffer and the dribble file.
1816 (gnus-group-update-group group t))))
1817
1818 (defun gnus-make-ascending-articles-unread (group articles)
1819 "Mark ascending ARTICLES in GROUP as unread."
1820 (let* ((entry (or (gnus-gethash group gnus-newsrc-hashtb)
1821 (gnus-gethash (gnus-group-real-name group)
1822 gnus-newsrc-hashtb)))
1823 (info (nth 2 entry))
1824 (ranges (gnus-info-read info))
1825 (r ranges)
1826 modified)
1827
1828 (while articles
1829 (let ((article (pop articles))) ; get the next article to remove from ranges
1830 (while (let ((range (car ranges))) ; note the current range
1831 (if (atom range) ; single value range
1832 (cond ((not range)
1833 ;; the articles extend past the end of the ranges
1834 ;; OK - I'm done
1835 (setq articles nil))
1836 ((< range article)
1837 ;; this range preceeds the article. Leave the range unmodified.
1838 (pop ranges)
1839 ranges)
1840 ((= range article)
1841 ;; this range exactly matches the article; REMOVE THE RANGE.
1842 ;; NOTE: When the range being removed is the last range, the list is corrupted by inserting null at its end.
1843 (setcar ranges (cadr ranges))
1844 (setcdr ranges (cddr ranges))
1845 (setq modified (if (car ranges) t 'remove-null))
1846 nil))
1847 (let ((min (car range))
1848 (max (cdr range)))
1849 ;; I have a min/max range to consider
1850 (cond ((> min max) ; invalid range introduced by splitter
1851 (setcar ranges (cadr ranges))
1852 (setcdr ranges (cddr ranges))
1853 (setq modified (if (car ranges) t 'remove-null))
1854 ranges)
1855 ((= min max)
1856 ;; replace min/max range with a single-value range
1857 (setcar ranges min)
1858 ranges)
1859 ((< max article)
1860 ;; this range preceeds the article. Leave the range unmodified.
1861 (pop ranges)
1862 ranges)
1863 ((< article min)
1864 ;; this article preceeds the range. Return null to move to the
1865 ;; next article
1866 nil)
1867 (t
1868 ;; this article splits the range into two parts
1869 (setcdr ranges (cons (cons (1+ article) max) (cdr ranges)))
1870 (setcdr range (1- article))
1871 (setq modified t)
1872 ranges))))))))
1873
1874 (when modified
1875 (when (eq modified 'remove-null)
1876 (setq r (delq nil r)))
1877 ;; Enter this list into the group info.
1878 (gnus-info-set-read info r)
1879
1880 ;; Set the number of unread articles in gnus-newsrc-hashtb.
1881 (gnus-get-unread-articles-in-group info (gnus-active group))
1882
1883 ;; Insert the change into the group buffer and the dribble file.
1669 (gnus-group-update-group group t)))) 1884 (gnus-group-update-group group t))))
1670 1885
1671 ;; Enter all dead groups into the hashtb. 1886 ;; Enter all dead groups into the hashtb.
1672 (defun gnus-update-active-hashtb-from-killed () 1887 (defun gnus-update-active-hashtb-from-killed ()
1673 (let ((hashtb (setq gnus-active-hashtb (gnus-make-hashtable 4096))) 1888 (let ((hashtb (setq gnus-active-hashtb (gnus-make-hashtable 4096)))
1729 (set-buffer nntp-server-buffer) 1944 (set-buffer nntp-server-buffer)
1730 (while (setq method (pop methods)) 1945 (while (setq method (pop methods))
1731 ;; Only do each method once, in case the methods appear more 1946 ;; Only do each method once, in case the methods appear more
1732 ;; than once in this list. 1947 ;; than once in this list.
1733 (unless (member method methods) 1948 (unless (member method methods)
1734 (condition-case () 1949 (if (or debug-on-error debug-on-quit)
1735 (gnus-read-active-file-1 method force) 1950 (gnus-read-active-file-1 method force)
1736 ;; We catch C-g so that we can continue past servers 1951 (condition-case ()
1737 ;; that do not respond. 1952 (gnus-read-active-file-1 method force)
1738 (quit 1953 ;; We catch C-g so that we can continue past servers
1739 (message "Quit reading the active file") 1954 ;; that do not respond.
1740 nil))))))) 1955 (quit
1956 (message "Quit reading the active file")
1957 nil))))))))
1741 1958
1742 (defun gnus-read-active-file-1 (method force) 1959 (defun gnus-read-active-file-1 (method force)
1743 (let (where mesg) 1960 (let (where mesg)
1744 (setq where (nth 1 method) 1961 (setq where (nth 1 method)
1745 mesg (format "Reading active file%s via %s..." 1962 mesg (format "Reading active file%s via %s..."
1780 ;; We mark this active file as read. 1997 ;; We mark this active file as read.
1781 (push method gnus-have-read-active-file) 1998 (push method gnus-have-read-active-file)
1782 (gnus-message 5 "%sdone" mesg))))))) 1999 (gnus-message 5 "%sdone" mesg)))))))
1783 2000
1784 (defun gnus-read-active-file-2 (groups method) 2001 (defun gnus-read-active-file-2 (groups method)
1785 "Read an active file for GROUPS in METHOD using gnus-retrieve-groups." 2002 "Read an active file for GROUPS in METHOD using `gnus-retrieve-groups'."
1786 (when groups 2003 (when groups
1787 (save-excursion 2004 (save-excursion
1788 (set-buffer nntp-server-buffer) 2005 (set-buffer nntp-server-buffer)
1789 (gnus-check-server method) 2006 (gnus-check-server method)
1790 (let ((list-type (gnus-retrieve-groups groups method))) 2007 (let ((list-type (gnus-retrieve-groups groups method)))
1827 (goto-char (point-max)) 2044 (goto-char (point-max))
1828 (while (re-search-backward "[][';?()#]" nil t) 2045 (while (re-search-backward "[][';?()#]" nil t)
1829 (insert ?\\))) 2046 (insert ?\\)))
1830 2047
1831 ;; Let the Gnus agent save the active file. 2048 ;; Let the Gnus agent save the active file.
1832 (when (and gnus-agent real-active gnus-plugged) 2049 (when (and gnus-agent real-active (gnus-online method))
1833 (gnus-agent-save-active method)) 2050 (gnus-agent-save-active method))
1834 2051
1835 ;; If these are groups from a foreign select method, we insert the 2052 ;; If these are groups from a foreign select method, we insert the
1836 ;; group prefix in front of the group names. 2053 ;; group prefix in front of the group names.
1837 (when (not (gnus-server-equal 2054 (when (not (gnus-server-equal
1847 (zerop (forward-line 1))))))) 2064 (zerop (forward-line 1)))))))
1848 ;; Store the active file in a hash table. 2065 ;; Store the active file in a hash table.
1849 (goto-char (point-min)) 2066 (goto-char (point-min))
1850 (let (group max min) 2067 (let (group max min)
1851 (while (not (eobp)) 2068 (while (not (eobp))
1852 (condition-case err 2069 (condition-case ()
1853 (progn 2070 (progn
1854 (narrow-to-region (point) (gnus-point-at-eol)) 2071 (narrow-to-region (point) (gnus-point-at-eol))
1855 ;; group gets set to a symbol interned in the hash table 2072 ;; group gets set to a symbol interned in the hash table
1856 ;; (what a hack!!) - jwz 2073 ;; (what a hack!!) - jwz
1857 (setq group (let ((obarray hashtb)) (read cur))) 2074 (setq group (let ((obarray hashtb)) (read cur)))
1903 (gnus-group-prefixed-name "" method)))) 2120 (gnus-group-prefixed-name "" method))))
1904 2121
1905 ;; Let the Gnus agent save the active file. 2122 ;; Let the Gnus agent save the active file.
1906 (if (and gnus-agent 2123 (if (and gnus-agent
1907 real-active 2124 real-active
1908 gnus-plugged 2125 (gnus-online method)
1909 (gnus-agent-method-p method)) 2126 (gnus-agent-method-p method))
1910 (progn 2127 (progn
1911 (gnus-agent-save-groups method) 2128 (gnus-agent-save-groups method)
1912 (gnus-active-to-gnus-format method hashtb nil real-active)) 2129 (gnus-active-to-gnus-format method hashtb nil real-active))
1913 2130
1944 2161
1945 (defun gnus-read-newsrc-file (&optional force) 2162 (defun gnus-read-newsrc-file (&optional force)
1946 "Read startup file. 2163 "Read startup file.
1947 If FORCE is non-nil, the .newsrc file is read." 2164 If FORCE is non-nil, the .newsrc file is read."
1948 ;; Reset variables that might be defined in the .newsrc.eld file. 2165 ;; Reset variables that might be defined in the .newsrc.eld file.
1949 (let ((variables gnus-variable-list)) 2166 (let ((variables (remove 'gnus-format-specs gnus-variable-list)))
1950 (while variables 2167 (while variables
1951 (set (car variables) nil) 2168 (set (car variables) nil)
1952 (setq variables (cdr variables)))) 2169 (setq variables (cdr variables))))
1953 (let* ((newsrc-file gnus-current-startup-file) 2170 (let* ((newsrc-file gnus-current-startup-file)
1954 (quick-file (concat newsrc-file ".el"))) 2171 (quick-file (concat newsrc-file ".el")))
2007 (gnus-add-to-range 2224 (gnus-add-to-range
2008 (gnus-info-read info) 2225 (gnus-info-read info)
2009 (nconc (gnus-uncompress-range dormant) 2226 (nconc (gnus-uncompress-range dormant)
2010 (gnus-uncompress-range ticked))))))))) 2227 (gnus-uncompress-range ticked)))))))))
2011 2228
2229 (defun gnus-load (file)
2230 "Load FILE, but in such a way that read errors can be reported."
2231 (with-temp-buffer
2232 (insert-file-contents file)
2233 (while (not (eobp))
2234 (condition-case type
2235 (let ((form (read (current-buffer))))
2236 (eval form))
2237 (error
2238 (unless (eq (car type) 'end-of-file)
2239 (let ((error (format "Error in %s line %d" file
2240 (count-lines (point-min) (point)))))
2241 (ding)
2242 (unless (gnus-yes-or-no-p (concat error "; continue? "))
2243 (error "%s" error)))))))))
2244
2012 (defun gnus-read-newsrc-el-file (file) 2245 (defun gnus-read-newsrc-el-file (file)
2013 (let ((ding-file (concat file "d"))) 2246 (let ((ding-file (concat file "d")))
2014 ;; We always, always read the .eld file. 2247 (when (file-exists-p ding-file)
2015 (gnus-message 5 "Reading %s..." ding-file) 2248 ;; We always, always read the .eld file.
2016 (let (gnus-newsrc-assoc) 2249 (gnus-message 5 "Reading %s..." ding-file)
2017 (condition-case nil 2250 (let (gnus-newsrc-assoc)
2018 (let ((coding-system-for-read gnus-ding-file-coding-system)) 2251 (let ((coding-system-for-read gnus-ding-file-coding-system))
2019 (load ding-file t t t)) 2252 (gnus-load ding-file))
2020 (error 2253 ;; Older versions of `gnus-format-specs' are no longer valid
2021 (ding) 2254 ;; in Oort Gnus 0.01.
2022 (unless (gnus-yes-or-no-p 2255 (let ((version
2023 (format "Error in %s; continue? " ding-file)) 2256 (and gnus-newsrc-file-version
2024 (error "Error in %s" ding-file)))) 2257 (gnus-continuum-version gnus-newsrc-file-version))))
2025 (when gnus-newsrc-assoc 2258 (when (or (not version)
2026 (setq gnus-newsrc-alist gnus-newsrc-assoc))) 2259 (< version 5.090009))
2260 (setq gnus-format-specs gnus-default-format-specs)))
2261 (when gnus-newsrc-assoc
2262 (setq gnus-newsrc-alist gnus-newsrc-assoc))))
2027 (gnus-make-hashtable-from-newsrc-alist) 2263 (gnus-make-hashtable-from-newsrc-alist)
2028 (when (file-newer-than-file-p file ding-file) 2264 (when (file-newer-than-file-p file ding-file)
2029 ;; Old format quick file 2265 ;; Old format quick file
2030 (gnus-message 5 "Reading %s..." file) 2266 (gnus-message 5 "Reading %s..." file)
2031 ;; The .el file is newer than the .eld file, so we read that one 2267 ;; The .el file is newer than the .eld file, so we read that one
2032 ;; as well. 2268 ;; as well.
2033 (gnus-read-old-newsrc-el-file file)))) 2269 (gnus-read-old-newsrc-el-file file)))
2270 (gnus-run-hooks 'gnus-read-newsrc-el-hook))
2034 2271
2035 ;; Parse the old-style quick startup file 2272 ;; Parse the old-style quick startup file
2036 (defun gnus-read-old-newsrc-el-file (file) 2273 (defun gnus-read-old-newsrc-el-file (file)
2037 (let (newsrc killed marked group m info) 2274 (let (newsrc killed marked group m info)
2038 (prog1 2275 (prog1
2154 (setq subscribed (eq (char-after) ?:) 2391 (setq subscribed (eq (char-after) ?:)
2155 group (symbol-name symbol) 2392 group (symbol-name symbol)
2156 reads nil) 2393 reads nil)
2157 (if (eolp) 2394 (if (eolp)
2158 ;; If the line ends here, this is clearly a buggy line, so 2395 ;; If the line ends here, this is clearly a buggy line, so
2159 ;; we put point at the beginning of line and let the cond 2396 ;; we put point a the beginning of line and let the cond
2160 ;; below do the error handling. 2397 ;; below do the error handling.
2161 (beginning-of-line) 2398 (beginning-of-line)
2162 ;; We skip to the beginning of the ranges. 2399 ;; We skip to the beginning of the ranges.
2163 (skip-chars-forward "!: \t")) 2400 (skip-chars-forward "!: \t"))
2164 ;; We are now at the beginning of the list of read articles. 2401 ;; We are now at the beginning of the list of read articles.
2340 'subscribe) 2577 'subscribe)
2341 out)))) 2578 out))))
2342 2579
2343 (setq gnus-newsrc-options-n out)))) 2580 (setq gnus-newsrc-options-n out))))
2344 2581
2582 (eval-and-compile
2583 (defalias 'gnus-long-file-names
2584 (if (fboundp 'msdos-long-file-names)
2585 'msdos-long-file-names
2586 (lambda () t))))
2587
2345 (defun gnus-save-newsrc-file (&optional force) 2588 (defun gnus-save-newsrc-file (&optional force)
2346 "Save .newsrc file." 2589 "Save .newsrc file."
2347 ;; Note: We cannot save .newsrc file if all newsgroups are removed 2590 ;; Note: We cannot save .newsrc file if all newsgroups are removed
2348 ;; from the variable gnus-newsrc-alist. 2591 ;; from the variable gnus-newsrc-alist.
2349 (when (and (or gnus-newsrc-alist gnus-killed-list) 2592 (when (and (or gnus-newsrc-alist gnus-killed-list)
2366 (gnus-gnus-to-newsrc-format) 2609 (gnus-gnus-to-newsrc-format)
2367 (gnus-message 8 "Saving %s...done" gnus-current-startup-file)) 2610 (gnus-message 8 "Saving %s...done" gnus-current-startup-file))
2368 ;; Save .newsrc.eld. 2611 ;; Save .newsrc.eld.
2369 (set-buffer (gnus-get-buffer-create " *Gnus-newsrc*")) 2612 (set-buffer (gnus-get-buffer-create " *Gnus-newsrc*"))
2370 (make-local-variable 'version-control) 2613 (make-local-variable 'version-control)
2371 (setq version-control 'never) 2614 (setq version-control gnus-backup-startup-file)
2372 (setq buffer-file-name 2615 (setq buffer-file-name
2373 (concat gnus-current-startup-file ".eld")) 2616 (concat gnus-current-startup-file ".eld"))
2374 (setq default-directory (file-name-directory buffer-file-name)) 2617 (setq default-directory (file-name-directory buffer-file-name))
2375 (buffer-disable-undo) 2618 (buffer-disable-undo)
2376 (erase-buffer) 2619 (erase-buffer)
2377 (gnus-message 5 "Saving %s.eld..." gnus-current-startup-file) 2620 (gnus-message 5 "Saving %s.eld..." gnus-current-startup-file)
2378 (gnus-gnus-to-quick-newsrc-format) 2621
2379 (gnus-run-hooks 'gnus-save-quick-newsrc-hook) 2622 (if gnus-save-startup-file-via-temp-buffer
2380 (let ((coding-system-for-write gnus-ding-file-coding-system)) 2623 (let ((coding-system-for-write gnus-ding-file-coding-system)
2381 (save-buffer)) 2624 (standard-output (current-buffer)))
2382 (kill-buffer (current-buffer)) 2625 (gnus-gnus-to-quick-newsrc-format)
2626 (gnus-run-hooks 'gnus-save-quick-newsrc-hook)
2627 (save-buffer))
2628 (let ((coding-system-for-write gnus-ding-file-coding-system)
2629 (version-control gnus-backup-startup-file)
2630 (startup-file (concat gnus-current-startup-file ".eld"))
2631 (working-dir (file-name-directory gnus-current-startup-file))
2632 working-file
2633 (i -1))
2634 ;; Generate the name of a non-existent file.
2635 (while (progn (setq working-file
2636 (format
2637 (if (and (eq system-type 'ms-dos)
2638 (not (gnus-long-file-names)))
2639 "%s#%d.tm#" ; MSDOS limits files to 8+3
2640 (if (memq system-type '(vax-vms axp-vms))
2641 "%s$tmp$%d"
2642 "%s#tmp#%d"))
2643 working-dir (setq i (1+ i))))
2644 (file-exists-p working-file)))
2645
2646 (unwind-protect
2647 (progn
2648 (gnus-with-output-to-file working-file
2649 (gnus-gnus-to-quick-newsrc-format)
2650 (gnus-run-hooks 'gnus-save-quick-newsrc-hook))
2651
2652 ;; These bindings will mislead the current buffer
2653 ;; into thinking that it is visiting the startup
2654 ;; file.
2655 (let ((buffer-backed-up nil)
2656 (buffer-file-name startup-file)
2657 (file-precious-flag t)
2658 (setmodes (file-modes startup-file)))
2659 ;; Backup the current version of the startup file.
2660 (backup-buffer)
2661
2662 ;; Replace the existing startup file with the temp file.
2663 (rename-file working-file startup-file t)
2664 (set-file-modes startup-file setmodes)))
2665 (condition-case nil
2666 (delete-file working-file)
2667 (file-error nil)))))
2668
2669 (gnus-kill-buffer (current-buffer))
2383 (gnus-message 2670 (gnus-message
2384 5 "Saving %s.eld...done" gnus-current-startup-file)) 2671 5 "Saving %s.eld...done" gnus-current-startup-file))
2385 (gnus-dribble-delete-file) 2672 (gnus-dribble-delete-file)
2386 (gnus-group-set-mode-line))))) 2673 (gnus-group-set-mode-line)))))
2387 2674
2388 (defun gnus-gnus-to-quick-newsrc-format () 2675 (defun gnus-gnus-to-quick-newsrc-format (&optional minimal name &rest specific-variables)
2389 "Insert Gnus variables such as gnus-newsrc-alist in lisp format." 2676 "Print Gnus variables such as `gnus-newsrc-alist' in Lisp format."
2390 (let ((print-quoted t) 2677 (princ ";; -*- emacs-lisp -*-\n")
2391 (print-escape-newlines t)) 2678 (if name
2392 2679 (princ (format ";; %s\n" name))
2393 (insert ";; -*- emacs-lisp -*-\n") 2680 (princ ";; Gnus startup file.\n"))
2394 (insert ";; Gnus startup file.\n") 2681
2395 (insert "\ 2682 (unless minimal
2683 (princ "\
2396 ;; Never delete this file -- if you want to force Gnus to read the 2684 ;; Never delete this file -- if you want to force Gnus to read the
2397 ;; .newsrc file (if you have one), touch .newsrc instead.\n") 2685 ;; .newsrc file (if you have one), touch .newsrc instead.\n")
2398 (insert "(setq gnus-newsrc-file-version " 2686 (princ "(setq gnus-newsrc-file-version ")
2399 (prin1-to-string gnus-version) ")\n") 2687 (princ (gnus-prin1-to-string gnus-version))
2400 (let* ((gnus-killed-list 2688 (princ ")\n"))
2689
2690 (let* ((print-quoted t)
2691 (print-readably t)
2692 (print-escape-multibyte nil)
2693 (print-escape-nonascii t)
2694 (print-length nil)
2695 (print-level nil)
2696 (print-escape-newlines t)
2697 (gnus-killed-list
2401 (if (and gnus-save-killed-list 2698 (if (and gnus-save-killed-list
2402 (stringp gnus-save-killed-list)) 2699 (stringp gnus-save-killed-list))
2403 (gnus-strip-killed-list) 2700 (gnus-strip-killed-list)
2404 gnus-killed-list)) 2701 gnus-killed-list))
2405 (variables 2702 (variables
2406 (if gnus-save-killed-list gnus-variable-list 2703 (or specific-variables
2407 ;; Remove the `gnus-killed-list' from the list of variables 2704 (if gnus-save-killed-list gnus-variable-list
2408 ;; to be saved, if required. 2705 ;; Remove the `gnus-killed-list' from the list of variables
2409 (delq 'gnus-killed-list (copy-sequence gnus-variable-list)))) 2706 ;; to be saved, if required.
2707 (delq 'gnus-killed-list (copy-sequence gnus-variable-list)))))
2410 ;; Peel off the "dummy" group. 2708 ;; Peel off the "dummy" group.
2411 (gnus-newsrc-alist (cdr gnus-newsrc-alist)) 2709 (gnus-newsrc-alist (cdr gnus-newsrc-alist))
2412 variable) 2710 variable)
2413 ;; Insert the variables into the file. 2711 ;; Insert the variables into the file.
2414 (while variables 2712 (while variables
2415 (when (and (boundp (setq variable (pop variables))) 2713 (when (and (boundp (setq variable (pop variables)))
2416 (symbol-value variable)) 2714 (symbol-value variable))
2417 (insert "(setq " (symbol-name variable) " '") 2715 (princ "(setq ")
2418 (gnus-prin1 (symbol-value variable)) 2716 (princ (symbol-name variable))
2419 (insert ")\n")))))) 2717 (princ " '")
2718 (prin1 (symbol-value variable))
2719 (princ ")\n")))))
2420 2720
2421 (defun gnus-strip-killed-list () 2721 (defun gnus-strip-killed-list ()
2422 "Return the killed list minus the groups that match `gnus-save-killed-list'." 2722 "Return the killed list minus the groups that match `gnus-save-killed-list'."
2423 (let ((list gnus-killed-list) 2723 (let ((list gnus-killed-list)
2424 olist) 2724 olist)
2622 (read nntp-server-buffer)) 2922 (read nntp-server-buffer))
2623 (error 0))) 2923 (error 0)))
2624 (skip-chars-forward " \t") 2924 (skip-chars-forward " \t")
2625 ;; ... which leads to this line being effectively ignored. 2925 ;; ... which leads to this line being effectively ignored.
2626 (when (symbolp group) 2926 (when (symbolp group)
2627 (let ((str (buffer-substring 2927 (let* ((str (buffer-substring
2628 (point) (progn (end-of-line) (point)))) 2928 (point) (progn (end-of-line) (point))))
2629 (coding 2929 (name (symbol-name group))
2630 (and (or (featurep 'xemacs) 2930 (charset
2631 (and (boundp 'enable-multibyte-characters) 2931 (or (gnus-group-name-charset method name)
2632 enable-multibyte-characters)) 2932 (gnus-parameter-charset name)
2633 (fboundp 'gnus-mule-get-coding-system) 2933 gnus-default-charset)))
2634 (gnus-mule-get-coding-system (symbol-name group))))) 2934 ;; Fixme: Don't decode in unibyte mode.
2635 (when coding 2935 (when (and str charset (featurep 'mule))
2636 (setq str (mm-decode-coding-string str (car coding)))) 2936 (setq str (mm-decode-coding-string str charset)))
2637 (set group str))) 2937 (set group str)))
2638 (forward-line 1)))) 2938 (forward-line 1))))
2639 (gnus-message 5 "Reading descriptions file...done") 2939 (gnus-message 5 "Reading descriptions file...done")
2640 t)))) 2940 t))))
2641 2941
2648 (when (looking-at "[^ \t]+[ \t]+\\(.*\\)") 2948 (when (looking-at "[^ \t]+[ \t]+\\(.*\\)")
2649 (match-string 1))))) 2949 (match-string 1)))))
2650 2950
2651 ;;;###autoload 2951 ;;;###autoload
2652 (defun gnus-declare-backend (name &rest abilities) 2952 (defun gnus-declare-backend (name &rest abilities)
2653 "Declare backend NAME with ABILITIES as a Gnus backend." 2953 "Declare back end NAME with ABILITIES as a Gnus back end."
2654 (setq gnus-valid-select-methods 2954 (setq gnus-valid-select-methods
2655 (nconc gnus-valid-select-methods 2955 (nconc gnus-valid-select-methods
2656 (list (apply 'list name abilities)))) 2956 (list (apply 'list name abilities))))
2657 (gnus-redefine-select-method-widget)) 2957 (gnus-redefine-select-method-widget))
2658 2958
2663 (if (and gnus-default-directory 2963 (if (and gnus-default-directory
2664 (file-exists-p gnus-default-directory)) 2964 (file-exists-p gnus-default-directory))
2665 (file-name-as-directory (expand-file-name gnus-default-directory)) 2965 (file-name-as-directory (expand-file-name gnus-default-directory))
2666 default-directory))) 2966 default-directory)))
2667 2967
2968 (eval-and-compile
2969 (defalias 'gnus-display-time-event-handler
2970 (if (gnus-boundp 'display-time-timer)
2971 'display-time-event-handler
2972 (lambda () "Does nothing as `display-time-timer' is not bound.
2973 Would otherwise be an alias for `display-time-event-handler'." nil))))
2974
2975 ;;;###autoload
2976 (defun gnus-fixup-nnimap-unread-after-getting-new-news ()
2977 (let (server group info)
2978 (mapatoms
2979 (lambda (sym)
2980 (when (and (setq group (symbol-name sym))
2981 (gnus-group-entry group)
2982 (setq info (symbol-value sym)))
2983 (gnus-sethash group (cons (nth 2 info) (cdr (gnus-group-entry group)))
2984 gnus-newsrc-hashtb)))
2985 (if (boundp 'nnimap-mailbox-info)
2986 (symbol-value 'nnimap-mailbox-info)
2987 (make-vector 1 0)))))
2988
2989
2668 (provide 'gnus-start) 2990 (provide 'gnus-start)
2669 2991
2670 ;;; arch-tag: f4584a22-b7b7-4853-abfc-a637329af5d2 2992 ;;; arch-tag: f4584a22-b7b7-4853-abfc-a637329af5d2
2671 ;;; gnus-start.el ends here 2993 ;;; gnus-start.el ends here
2994
2995