*** pub/sgnus/lisp/gnus.el	Fri May 24 01:39:53 1996
--- sgnus/lisp/gnus.el	Fri May 24 23:44:51 1996
***************
*** 1259,1265 ****
  ;  "*Face used for mouse highlighting in Gnus.
  ;No mouse highlights will be done if `gnus-visual' is nil.")
  
! (defvar gnus-summary-mark-below nil
    "*Mark all articles with a score below this variable as read.
  This variable is local to each summary buffer and usually set by the
  score file.")
--- 1259,1265 ----
  ;  "*Face used for mouse highlighting in Gnus.
  ;No mouse highlights will be done if `gnus-visual' is nil.")
  
! (defvar gnus-summary-mark-below 0
    "*Mark all articles with a score below this variable as read.
  This variable is local to each summary buffer and usually set by the
  score file.")
***************
*** 1722,1728 ****
    "gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls + Boys)"
    "The mail address of the Gnus maintainers.")
  
! (defconst gnus-version "September Gnus v0.93"
    "Version number for this version of Gnus.")
  
  (defvar gnus-info-nodes
--- 1722,1728 ----
    "gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls + Boys)"
    "The mail address of the Gnus maintainers.")
  
! (defconst gnus-version "September Gnus v0.94"
    "Version number for this version of Gnus.")
  
  (defvar gnus-info-nodes
***************
*** 1930,1936 ****
      gnus-newsgroup-scored gnus-newsgroup-kill-headers
      gnus-newsgroup-async gnus-thread-expunge-below
      gnus-score-alist gnus-current-score-file gnus-summary-expunge-below
!     gnus-summary-mark-below gnus-newsgroup-active gnus-scores-exclude-files
      gnus-newsgroup-history gnus-newsgroup-ancient
      gnus-newsgroup-sparse
      (gnus-newsgroup-adaptive . gnus-use-adaptive-scoring)
--- 1930,1937 ----
      gnus-newsgroup-scored gnus-newsgroup-kill-headers
      gnus-newsgroup-async gnus-thread-expunge-below
      gnus-score-alist gnus-current-score-file gnus-summary-expunge-below
!     (gnus-summary-mark-below . 0)
!     gnus-newsgroup-active gnus-scores-exclude-files
      gnus-newsgroup-history gnus-newsgroup-ancient
      gnus-newsgroup-sparse
      (gnus-newsgroup-adaptive . gnus-use-adaptive-scoring)
***************
*** 7609,7615 ****
  	    1)
  	   ((memq (mail-header-number (car thread)) gnus-newsgroup-limit)
  	    1)
! 	   (t 1))))
      (when (and level (zerop level) gnus-tmp-new-adopts)
        (incf number
  	    (apply '+ (mapcar
--- 7610,7616 ----
  	    1)
  	   ((memq (mail-header-number (car thread)) gnus-newsgroup-limit)
  	    1)
! 	   (t 0))))
      (when (and level (zerop level) gnus-tmp-new-adopts)
        (incf number
  	    (apply '+ (mapcar
***************
*** 14158,14176 ****
  	(narrow-to-region
  	 (funcall (intern "mime::preview-content-info/point-min") pcinfo)
  	 (point-max))
! 	t)
!     (goto-char (point-max))
!     (when (re-search-backward gnus-signature-separator nil t)
!       (forward-line 1)
!       (when (or (null gnus-signature-limit)
! 		(and (numberp gnus-signature-limit)
! 		     (< (- (point-max) (point)) gnus-signature-limit))
! 		(and (gnus-functionp gnus-signature-limit)
! 		     (funcall gnus-signature-limit))
! 		(and (stringp gnus-signature-limit)
! 		     (not (re-search-forward gnus-signature-limit nil t))))
! 	(narrow-to-region (point) (point-max))
! 	t))))
  
  (defun gnus-article-check-hidden-text (type arg)
    "Return nil if hiding is necessary."
--- 14159,14177 ----
  	(narrow-to-region
  	 (funcall (intern "mime::preview-content-info/point-min") pcinfo)
  	 (point-max))
! 	t))
!   (goto-char (point-max))
!   (when (re-search-backward gnus-signature-separator nil t)
!     (forward-line 1)
!     (when (or (null gnus-signature-limit)
! 	      (and (numberp gnus-signature-limit)
! 		   (< (- (point-max) (point)) gnus-signature-limit))
! 	      (and (gnus-functionp gnus-signature-limit)
! 		   (funcall gnus-signature-limit))
! 	      (and (stringp gnus-signature-limit)
! 		   (not (re-search-forward gnus-signature-limit nil t))))
!       (narrow-to-region (point) (point-max))
!       t)))
  
  (defun gnus-article-check-hidden-text (type arg)
    "Return nil if hiding is necessary."
*** pub/sgnus/lisp/message.el	Fri May 24 01:39:55 1996
--- sgnus/lisp/message.el	Fri May 24 23:07:15 1996
***************
*** 724,729 ****
--- 724,730 ----
      ;;  ["Insert Signature"         news-reply-signature     t]
      ["Caesar (rot13) Message" message-caesar-buffer-body t]
      ["Rename buffer" message-rename-buffer t]
+     ["Spellcheck" ispell-message t]
      "----"
      ["Send Message" message-send-and-exit t]
      ["Abort Message" message-dont-send t]))
***************
*** 1194,1199 ****
--- 1195,1201 ----
  	      (y-or-n-p "No changes in the buffer; really send? ")))
      ;; Make it possible to undo the coming changes.
      (undo-boundary)
+     (message-fix-before-sending)
      (run-hooks 'message-send-hook)
      (message "Sending...")
      (when (and (or (not (message-news-p))
***************
*** 1219,1224 ****
--- 1221,1233 ----
        ;; Return success.
        t)))
  
+ (defun message-fix-before-sending ()
+   "Do various things to make the message nice before sending it."
+   ;; Make sure there's a newline at the end of the message.
+   (goto-char (point-max))
+   (unless (bolp)
+     (insert "\n")))
+ 
  (defun message-add-action (action &rest types)
    "Add ACTION to be performed when doing an exit of type TYPES."
    (let (var)
***************
*** 1491,1520 ****
  		(message 
  		 "The subject field is empty or missing.  Posting is denied.")
  		nil)))))
  	;; Check the From header.
! 	(or (message-check-element 'from)
! 	    (save-excursion
! 	      (let* ((case-fold-search t)
! 		     (from (message-fetch-field "from")))
! 		(cond
! 		 ((not from)
! 		  (message "There is no From line.  Posting is denied.")
! 		  nil)
! 		 ((not (string-match "@[^\\.]*\\." from))
! 		  (message
! 		   "Denied posting -- the From looks strange: \"%s\"." from)
! 		  nil)
! 		 ((string-match "@[^@]*@" from)
! 		  (message 
! 		   "Denied posting -- two \"@\"'s in the From header: %s."
! 		   from)
! 		  nil)
! 		 ((string-match "(.*).*(.*)" from)
! 		  (message
! 		   "Denied posting -- the From header looks strange: \"%s\"." 
! 		   from)
! 		  nil)
! 		 (t t))))))))
     ;; Check for long lines.
     (or (message-check-element 'long-lines)
         (save-excursion
--- 1500,1581 ----
  		(message 
  		 "The subject field is empty or missing.  Posting is denied.")
  		nil)))))
+ 	;; Check the Newsgroups & Followup-To headers.
+ 	(or
+ 	 (message-check-element 'existing-newsgroups)
+ 	 (let* ((case-fold-search t)
+ 		(newsgroups (message-fetch-field "newsgroups"))
+ 		(followup-to (message-fetch-field "followup-to"))
+ 		(groups (message-tokenize-header
+ 			 (if followup-to
+ 			     (concat newsgroups "," followup-to)
+ 			   newsgroups)))
+ 		(hashtb (and (boundp 'gnus-active-hashtb)
+ 			     gnus-active-hashtb))
+ 		errors)
+ 	   (if (not hashtb)
+ 	       t
+ 	     (while groups
+ 	       (unless (boundp (intern (car groups) hashtb))
+ 		 (push (car groups) errors))
+ 	       (pop groups))
+ 	     (if (not errors)
+ 		 t
+ 	       (y-or-n-p
+ 		(format
+ 		 "Really post to %s unknown group%s: %s "
+ 		 (if (= (length errors) 1) "this" "these")
+ 		 (if (= (length errors) 1) "" "s")
+ 		 (mapconcat 'identity errors ", ")))))))
+ 	;; Check the Newsgroups & Followup-To headers for syntax errors.
+ 	(or
+ 	 (message-check-element 'valid-newsgroups)
+ 	 (let ((case-fold-search t)
+ 	       (headers '("Newsgroups" "Followup-To"))
+ 	       header error)
+ 	   (while (and headers (not error))
+ 	     (when (setq header (mail-fetch-field (car headers)))
+ 	       (if (or
+ 		    (not (string-match
+ 			  "\\`\\([-.a-zA-Z0-9]+\\)?\\(,[-.a-zA-Z0-9]+\\)*\\'"
+ 			  header))
+ 		    (memq 
+ 		     nil (mapcar 
+ 			  (lambda (g)
+ 			    (not (string-match "\\.\\'\\|\\.\\." g)))
+ 			  (message-tokenize-header header ","))))
+ 		   (setq error t)))
+ 	     (unless error
+ 	       (pop headers)))
+ 	   (if (not error)
+ 	       t
+ 	     (y-or-n-p
+ 	      (format "The %s header looks odd: \"%s\".  Really post? "
+ 		      (car headers) header)))))
  	;; Check the From header.
! 	(or 
! 	 (message-check-element 'from)
! 	 (save-excursion
! 	   (let* ((case-fold-search t)
! 		  (from (message-fetch-field "from")))
! 	     (cond
! 	      ((not from)
! 	       (message "There is no From line.  Posting is denied.")
! 	       nil)
! 	      ((not (string-match "@[^\\.]*\\." from))
! 	       (message
! 		"Denied posting -- the From looks strange: \"%s\"." from)
! 	       nil)
! 	      ((string-match "@[^@]*@" from)
! 	       (message 
! 		"Denied posting -- two \"@\"'s in the From header: %s." from)
! 	       nil)
! 	      ((string-match "(.*).*(.*)" from)
! 	       (message
! 		"Denied posting -- the From header looks strange: \"%s\"." 
! 		from)
! 	       nil)
! 	      (t t))))))))
     ;; Check for long lines.
     (or (message-check-element 'long-lines)
         (save-excursion
*** pub/sgnus/lisp/nntp.el	Fri May 24 01:39:59 1996
--- sgnus/lisp/nntp.el	Fri May 24 23:03:05 1996
***************
*** 831,837 ****
        ;; Save status message.
        (end-of-line)
        (setq nntp-status-string
! 	    (buffer-substring (point-min) (point)))
        (when status
  	(setq wait t)
  	(while wait
--- 831,838 ----
        ;; Save status message.
        (end-of-line)
        (setq nntp-status-string
! 	    (nnheader-replace-chars-in-string 
! 	     (buffer-substring (point-min) (point)) ?\r ? ))
        (when status
  	(setq wait t)
  	(while wait
*** pub/sgnus/lisp/nnvirtual.el	Fri May 24 01:39:59 1996
--- sgnus/lisp/nnvirtual.el	Fri May 24 23:43:58 1996
***************
*** 193,206 ****
      (let ((newsrc (cdr gnus-newsrc-alist))
  	  group)
        (while (setq group (car (pop newsrc)))
! 	(and (string-match nnvirtual-component-regexp group) ; Match
! 	     ;; Add this group to the list of component groups.
! 	     (setq nnvirtual-component-groups
! 		   (cons group 
! 			 (delete group nnvirtual-component-groups)))))
!       (setq nnvirtual-component-groups
! 	    (delete (nnvirtual-current-group)
! 		    nnvirtual-component-groups)))
      (if (not nnvirtual-component-groups)
  	(nnheader-report 'nnvirtual "No component groups: %s" server)
        t)))
--- 193,202 ----
      (let ((newsrc (cdr gnus-newsrc-alist))
  	  group)
        (while (setq group (car (pop newsrc)))
! 	(when (string-match nnvirtual-component-regexp group) ; Match
! 	  ;; Add this group to the list of component groups.
! 	  (setq nnvirtual-component-groups
! 		(cons group (delete group nnvirtual-component-groups))))))
      (if (not nnvirtual-component-groups)
  	(nnheader-report 'nnvirtual "No component groups: %s" server)
        t)))
***************
*** 213,218 ****
--- 209,216 ----
      (nnheader-report 'nnvirtual "No component groups in %s" group))
     (t
      (unless dont-check
+       (setq nnvirtual-component-groups
+ 	    (delete (nnvirtual-current-group) nnvirtual-component-groups))
        (nnvirtual-create-mapping))
      (setq nnvirtual-current-group group)
      (let ((len (length nnvirtual-mapping)))
*** pub/sgnus/lisp/ChangeLog	Fri May 24 01:40:12 1996
--- sgnus/lisp/ChangeLog	Fri May 24 23:44:46 1996
***************
*** 1,4 ****
--- 1,28 ----
+ Fri May 24 21:27:49 1996  Lars Magne Ingebrigtsen  <larsi@eistla.ifi.uio.no>
+ 
+ 	* nnvirtual.el (nnvirtual-request-group): Don't include itself in
+ 	its component groups.
+ 
+ 	* gnus.el (gnus-summary-mark-below): Changed default.
+ 
+ Fri May 24 19:29:17 1996  Lars Magne Ingebrigtsen  <larsi@aegir.ifi.uio.no>
+ 
+ 	* message.el (message-check-news-syntax): Check invalid Newsgroups
+ 	syntax. 
+ 	(message-mode-menu): Added spellcheck.
+ 
+ 	* nntp.el (nntp-wait-for-response): Peel off ^Ms.
+ 
+ 	* message.el (message-fix-before-sending): New function.
+ 	(message-send): Use it.
+ 	(message-check-news-syntax): Check for invalid group names.
+ 
+ 	* gnus.el (gnus-summary-number-of-articles-in-thread): Return 0 if
+ 	not included.
+ 
  Thu May 23 23:32:43 1996  Lars Magne Ingebrigtsen  <larsi@hler.ifi.uio.no>
+ 
+ 	* gnus.el: September Gnus v0.93 is released.
  
  	* nnbabyl.el (nnbabyl-read-mbox): Would bogously increase the
   	number in groups.
*** pub/sgnus/texi/Makefile	Fri May 24 01:40:15 1996
--- sgnus/texi/Makefile	Fri May 24 23:44:01 1996
***************
*** 2,8 ****
  EMACS=emacs
  MAKEINFO=$(EMACS) -batch -q -no-site-file
  INFOSWI=-l texinfmt -f texinfo-every-node-update -f texinfo-format-buffer -f save-buffer
- # MAKEINFO=makeinfo -o gnus.info gnus.texi
  LATEX=latex
  DVIPS=dvips
  PERL=perl
--- 2,7 ----
***************
*** 31,36 ****
--- 30,36 ----
  
  makeinfo: 
  	makeinfo -o gnus.info gnus.texi	
+ 	makeinfo -o message.info message.texi	
  
  texi2latexi.elc:
  	$(EMACS) -batch -l bytecomp -f batch-byte-recompile-directory
*** pub/sgnus/texi/message.texi	Fri May 24 01:40:15 1996
--- sgnus/texi/message.texi	Fri May 24 23:03:04 1996
***************
*** 783,788 ****
--- 783,794 ----
  Check whether the article is empty.
  @item empty-headers
  Check whether any of the headers are empty.
+ @item existing-newsgroups
+ Check whether the newsgroups mentioned in the Newsgroups and 
+ Followup-To headers exist.
+ @item valid-newsgroups
+ Check whether the @code{Newsgroups} and @code{Followup-To} headers
+ are valid syntactially.
  @end table
  
  All these conditions are checked by default.
