*** empty log message ***
[gnus] / lisp / message.el
index 96b7c93..3ea01e9 100644 (file)
@@ -1,5 +1,5 @@
 ;;; message.el --- composing mail and news messages
-;; Copyright (C) 1996,97 Free Software Foundation, Inc.
+;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
 ;; Keywords: mail, news
@@ -32,7 +32,6 @@
 (eval-when-compile (require 'cl))
 
 (require 'mailheader)
-(require 'rmail)
 (require 'nnheader)
 (require 'timezone)
 (require 'easymenu)
   :type 'integer)
 
 (defcustom message-send-rename-function nil
-  "Function called to rename the buffer after sending it."
+  "*Function called to rename the buffer after sending it."
   :group 'message-buffers
   :type 'function)
 
@@ -158,7 +157,7 @@ Otherwise, most addresses look like `angles', but they look like
 
 (defcustom message-syntax-checks nil
   ;; Guess this one shouldn't be easy to customize...
-  "Controls what syntax checks should not be performed on outgoing posts.
+  "*Controls what syntax checks should not be performed on outgoing posts.
 To disable checking of long signatures, for instance, add
  `(signature . disabled)' to this list.
 
@@ -167,14 +166,14 @@ Don't touch this variable unless you really know what you're doing.
 Checks include subject-cmsg multiple-headers sendsys message-id from
 long-lines control-chars size new-text redirected-followup signature
 approved sender empty empty-headers message-id from subject
-shorten-followup-to existing-newsgroups."
+shorten-followup-to existing-newsgroups buffer-file-name unchanged."
   :group 'message-news)
 
 (defcustom message-required-news-headers
   '(From Newsgroups Subject Date Message-ID
         (optional . Organization) Lines
         (optional . X-Newsreader))
-  "Headers to be generated or prompted for when posting an article.
+  "*Headers to be generated or prompted for when posting an article.
 RFC977 and RFC1036 require From, Date, Newsgroups, Subject,
 Message-ID.  Organization, Lines, In-Reply-To, Expires, and
 X-Newsreader are optional.  If don't you want message to insert some
@@ -186,7 +185,7 @@ header, remove it from this list."
 (defcustom message-required-mail-headers
   '(From Subject Date (optional . In-Reply-To) Message-ID Lines
         (optional . X-Mailer))
-  "Headers to be generated or prompted for when mailing a message.
+  "*Headers to be generated or prompted for when mailing a message.
 RFC822 required that From, Date, To, Subject and Message-ID be
 included.  Organization, Lines and X-Mailer are optional."
   :group 'message-mail
@@ -194,24 +193,24 @@ included.  Organization, Lines and X-Mailer are optional."
   :type '(repeat sexp))
 
 (defcustom message-deletable-headers '(Message-ID Date Lines)
-  "Headers to be deleted if they already exist and were generated by message previously."
+  "*Headers to be deleted if they already exist and were generated by message previously."
   :group 'message-headers
   :type 'sexp)
 
 (defcustom message-ignored-news-headers
-  "^NNTP-Posting-Host:\\|^Xref:\\|^Bcc:\\|^Gcc:\\|^Fcc:\\|^Resent-Fcc:"
+  "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:"
   "*Regexp of headers to be removed unconditionally before posting."
   :group 'message-news
   :group 'message-headers
   :type 'regexp)
 
-(defcustom message-ignored-mail-headers "^Gcc:\\|^Fcc:\\|^Resent-Fcc:"
+(defcustom message-ignored-mail-headers "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:"
   "*Regexp of headers to be removed unconditionally before mailing."
   :group 'message-mail
   :group 'message-headers
   :type 'regexp)
 
-(defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|Return-Path:\\|^Supersedes:"
+(defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|X-Trace:\\|X-Complaints-To:\\|Return-Path:\\|^Supersedes:"
   "*Header lines matching this regexp will be deleted before posting.
 It's best to delete old Path and Date headers before posting to avoid
 any confusion."
@@ -220,7 +219,7 @@ any confusion."
 
 ;;;###autoload
 (defcustom message-signature-separator "^-- *$"
-  "Regexp matching the signature separator."
+  "*Regexp matching the signature separator."
   :type 'regexp
   :group 'message-various)
 
@@ -228,7 +227,7 @@ any confusion."
   "*The string which is inserted for elided text.")
 
 (defcustom message-interactive nil
-  "Non-nil means when sending a message wait for and display errors.
+  "*Non-nil means when sending a message wait for and display errors.
 nil means let mailer mail back a message to report errors."
   :group 'message-sending
   :group 'message-mail
@@ -293,7 +292,7 @@ If nil, Message won't autosave."
   :type 'boolean)
 
 (defcustom message-included-forward-headers
-  "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-\\|^Message-ID:\\|^References:"
+  "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-\\|^Message-ID:\\|^References:\\|^Content-Transfer-Encoding:\\|^Content-Type:\\|^Mime-Version:"
   "*Regexp matching headers to be included in forwarded messages."
   :group 'message-forwarding
   :type 'regexp)
@@ -309,28 +308,30 @@ If nil, Message won't autosave."
   :type 'regexp)
 
 (defcustom message-cancel-message "I am canceling my own article."
-  "Message to be inserted in the cancel message."
+  "*Message to be inserted in the cancel message."
   :group 'message-interface
   :type 'string)
 
 ;; Useful to set in site-init.el
 ;;;###autoload
 (defcustom message-send-mail-function 'message-send-mail-with-sendmail
-  "Function to call to send the current buffer as mail.
+  "*Function to call to send the current buffer as mail.
 The headers should be delimited by a line whose contents match the
 variable `mail-header-separator'.
 
 Legal values include `message-send-mail-with-sendmail' (the default),
-`message-send-mail-with-mh' and `message-send-mail-with-qmail'."
+`message-send-mail-with-mh', `message-send-mail-with-qmail' and
+`smtpmail-send-it'."
   :type '(radio (function-item message-send-mail-with-sendmail)
                (function-item message-send-mail-with-mh)
                (function-item message-send-mail-with-qmail)
+               (function-item smtpmail-send-it)
                (function :tag "Other"))
   :group 'message-sending
   :group 'message-mail)
 
 (defcustom message-send-news-function 'message-send-news
-  "Function to call to send the current buffer as news.
+  "*Function to call to send the current buffer as news.
 The headers should be delimited by a line whose contents match the
 variable `mail-header-separator'."
   :group 'message-sending
@@ -338,21 +339,21 @@ variable `mail-header-separator'."
   :type 'function)
 
 (defcustom message-reply-to-function nil
-  "Function that should return a list of headers.
+  "*Function that should return a list of headers.
 This function should pick out addresses from the To, Cc, and From headers
 and respond with new To and Cc headers."
   :group 'message-interface
   :type 'function)
 
 (defcustom message-wide-reply-to-function nil
-  "Function that should return a list of headers.
+  "*Function that should return a list of headers.
 This function should pick out addresses from the To, Cc, and From headers
 and respond with new To and Cc headers."
   :group 'message-interface
   :type 'function)
 
 (defcustom message-followup-to-function nil
-  "Function that should return a list of headers.
+  "*Function that should return a list of headers.
 This function should pick out addresses from the To, Cc, and From headers
 and respond with new To and Cc headers."
   :group 'message-interface
@@ -378,12 +379,12 @@ command line, because it is even more evil than leaving it out."
 
 ;; qmail-related stuff
 (defcustom message-qmail-inject-program "/var/qmail/bin/qmail-inject"
-  "Location of the qmail-inject program."
+  "*Location of the qmail-inject program."
   :group 'message-sending
   :type 'file)
 
 (defcustom message-qmail-inject-args nil
-  "Arguments passed to qmail-inject programs.
+  "*Arguments passed to qmail-inject programs.
 This should be a list of strings, one string for each argument.
 
 For e.g., if you wish to set the envelope sender address so that bounces
@@ -401,7 +402,7 @@ might set this variable to '(\"-f\" \"you@some.where\")."
        ((boundp 'gnus-select-method)
         gnus-select-method)
        (t '(nnspool "")))
-  "Method used to post news."
+  "*Method used to post news."
   :group 'message-news
   :group 'message-sending
   ;; This should be the `gnus-select-method' widget, but that might
@@ -414,30 +415,30 @@ might set this variable to '(\"-f\" \"you@some.where\")."
   :type 'boolean)
 
 (defcustom message-setup-hook nil
-  "Normal hook, run each time a new outgoing message is initialized.
+  "*Normal hook, run each time a new outgoing message is initialized.
 The function `message-setup' runs this hook."
   :group 'message-various
   :type 'hook)
 
 (defcustom message-signature-setup-hook nil
-  "Normal hook, run each time a new outgoing message is initialized.
+  "*Normal hook, run each time a new outgoing message is initialized.
 It is run after the headers have been inserted and before
 the signature is inserted."
   :group 'message-various
   :type 'hook)
 
 (defcustom message-mode-hook nil
-  "Hook run in message mode buffers."
+  "*Hook run in message mode buffers."
   :group 'message-various
   :type 'hook)
 
 (defcustom message-header-hook nil
-  "Hook run in a message mode buffer narrowed to the headers."
+  "*Hook run in a message mode buffer narrowed to the headers."
   :group 'message-various
   :type 'hook)
 
 (defcustom message-header-setup-hook nil
-  "Hook called narrowed to the headers when setting up a message
+  "*Hook called narrowed to the headers when setting up a message
 buffer."
   :group 'message-various
   :type 'hook)
@@ -467,8 +468,11 @@ Used by `message-yank-original' via `message-yank-cite'."
           mail-citation-hook)
       mail-citation-hook
     'message-cite-original)
-  "*Function for citing an original message."
+  "*Function for citing an original message.
+Pre-defined functions include `message-cite-original' and
+`message-cite-original-without-signature'."
   :type '(radio (function-item message-cite-original)
+               (function-item message-cite-original-without-signature)
                (function-item sc-cite-original)
                (function :tag "Other"))
   :group 'message-insertion)
@@ -506,14 +510,14 @@ If a form, the result from the form will be used instead."
   :type 'function)
 
 (defcustom message-expires 14
-  "Number of days before your article expires."
+  "*Number of days before your article expires."
   :group 'message-news
   :group 'message-headers
   :link '(custom-manual "(message)News Headers")
   :type 'integer)
 
 (defcustom message-user-path nil
-  "If nil, use the NNTP server name in the Path header.
+  "*If nil, use the NNTP server name in the Path header.
 If stringp, use this; if non-nil, use no host name (user name only)."
   :group 'message-news
   :group 'message-headers
@@ -537,25 +541,30 @@ If stringp, use this; if non-nil, use no host name (user name only)."
 (defvar message-postpone-actions nil
   "A list of actions to be performed after postponing a message.")
 
+(define-widget 'message-header-lines 'text
+  "All header lines must be LFD terminated."
+  :valid-regexp "^\\'"
+  :error "All header lines must be newline terminated")
+
 (defcustom message-default-headers ""
   "*A string containing header lines to be inserted in outgoing messages.
 It is inserted before you edit the message, so you can edit or delete
 these lines."
   :group 'message-headers
-  :type 'string)
+  :type 'message-header-lines)
 
 (defcustom message-default-mail-headers ""
   "*A string of header lines to be inserted in outgoing mails."
   :group 'message-headers
   :group 'message-mail
-  :type 'string)
+  :type 'message-header-lines)
 
 (defcustom message-default-news-headers ""
   "*A string of header lines to be inserted in outgoing news
 articles."
   :group 'message-headers
   :group 'message-news
-  :type 'string)
+  :type 'message-header-lines)
 
 ;; Note: could use /usr/ucb/mail instead of sendmail;
 ;; options -t, and -v if not interactive.
@@ -577,7 +586,7 @@ articles."
       ;; 33 and 126, except colon)", i. e., any chars except ctl chars,
       ;; space, or colon.
       '(looking-at "[ \t]\\|[][!\"#$%&'()*+,-./0-9;<=>?@A-Z\\\\^_`a-z{|}~]+:"))
-  "Set this non-nil if the system's mailer runs the header and body together.
+  "*Set this non-nil if the system's mailer runs the header and body together.
 \(This problem exists on Sunos 4 when sendmail is run in remote mode.)
 The value should be an expression to test whether the problem will
 actually occur."
@@ -683,7 +692,7 @@ Defaults to `text-mode-abbrev-table'.")
 (defface message-header-other-face
   '((((class color)
       (background dark))
-     (:foreground "red4"))
+     (:foreground "#b00000"))
     (((class color)
       (background light))
      (:foreground "steel blue"))
@@ -719,7 +728,7 @@ Defaults to `text-mode-abbrev-table'.")
 (defface message-separator-face
   '((((class color)
       (background dark))
-     (:foreground "blue4"))
+     (:foreground "blue3"))
     (((class color)
       (background light))
      (:foreground "brown"))
@@ -766,10 +775,14 @@ Defaults to `text-mode-abbrev-table'.")
        1 'message-separator-face)
       (,(concat "^[ \t]*"
                "\\([" cite-prefix "]+[" cite-suffix "]*\\)?"
-               "[>|}].*")
+               "[:>|}].*")
        (0 'message-cited-text-face))))
   "Additional expressions to highlight in Message mode.")
 
+;; XEmacs does it like this.  For Emacs, we have to set the
+;; `font-lock-defaults' buffer-local variable.
+(put 'message-mode 'font-lock-defaults '(message-font-lock-keywords t))
+
 (defvar message-face-alist
   '((bold . bold-region)
     (underline . underline-region)
@@ -780,23 +793,23 @@ Defaults to `text-mode-abbrev-table'.")
 The cdr of ech entry is a function for applying the face to a region.")
 
 (defcustom message-send-hook nil
-  "Hook run before sending messages."
+  "*Hook run before sending messages."
   :group 'message-various
   :options '(ispell-message)
   :type 'hook)
 
 (defcustom message-send-mail-hook nil
-  "Hook run before sending mail messages."
+  "*Hook run before sending mail messages."
   :group 'message-various
   :type 'hook)
 
 (defcustom message-send-news-hook nil
-  "Hook run before sending news messages."
+  "*Hook run before sending news messages."
   :group 'message-various
   :type 'hook)
 
 (defcustom message-sent-hook nil
-  "Hook run after sending messages."
+  "*Hook run after sending messages."
   :group 'message-various
   :type 'hook)
 
@@ -890,19 +903,22 @@ The cdr of ech entry is a function for applying the face to a region.")
     (Lines)
     (Expires)
     (Message-ID)
-    (References)
+    (References . message-fill-header)
     (X-Mailer)
     (X-Newsreader))
   "Alist used for formatting headers.")
 
 (eval-and-compile
   (autoload 'message-setup-toolbar "messagexmas")
+  (autoload 'mh-new-draft-name "mh-comp")
   (autoload 'mh-send-letter "mh-comp")
   (autoload 'gnus-point-at-eol "gnus-util")
   (autoload 'gnus-point-at-bol "gnus-util")
   (autoload 'gnus-output-to-mail "gnus-util")
   (autoload 'gnus-output-to-rmail "gnus-util")
-  (autoload 'mail-abbrev-in-expansion-header-p "mailabbrev"))
+  (autoload 'mail-abbrev-in-expansion-header-p "mailabbrev")
+  (autoload 'nndraft-request-associate-buffer "nndraft")
+  (autoload 'nndraft-request-expire-articles "nndraft"))
 
 \f
 
@@ -1003,7 +1019,7 @@ The cdr of ech entry is a function for applying the face to a region.")
   "Return non-nil if FORM is funcallable."
   (or (and (symbolp form) (fboundp form))
       (and (listp form) (eq (car form) 'lambda))
-      (compiled-function-p form)))
+      (byte-code-function-p form)))
 
 (defun message-strip-subject-re (subject)
   "Remove \"Re:\" from subject lines."
@@ -1072,7 +1088,8 @@ Return the number of headers removed."
       (save-excursion
        (save-restriction
          (message-narrow-to-headers)
-         (message-fetch-field "newsgroups")))))
+         (and (message-fetch-field "newsgroups")
+              (not (message-fetch-field "posted-to")))))))
 
 (defun message-mail-p ()
   "Say whether the current buffer contains a mail message."
@@ -1171,6 +1188,8 @@ Return the number of headers removed."
 
   (define-key message-mode-map "\C-c\C-e" 'message-elide-region)
   (define-key message-mode-map "\C-c\C-v" 'message-delete-not-region)
+  (define-key message-mode-map "\C-c\C-z" 'message-kill-to-signature)
+  (define-key message-mode-map "\M-\r" 'message-newline-and-reformat)
 
   (define-key message-mode-map "\t" 'message-tab))
 
@@ -1185,6 +1204,8 @@ Return the number of headers removed."
    ["Caesar (rot13) Region" message-caesar-region (mark t)]
    ["Elide Region" message-elide-region (mark t)]
    ["Delete Outside Region" message-delete-not-region (mark t)]
+   ["Kill To Signature" message-kill-to-signature t]
+   ["Newline and Reformat" message-newline-and-reformat t]
    ["Rename buffer" message-rename-buffer t]
    ["Spellcheck" ispell-message t]
    "----"
@@ -1249,8 +1270,6 @@ C-c C-r  message-caesar-buffer-body (rot13 the message body)."
   (setq major-mode 'message-mode)
   (setq mode-name "Message")
   (setq buffer-offer-save t)
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults '(message-font-lock-keywords t))
   (make-local-variable 'facemenu-add-face-function)
   (make-local-variable 'facemenu-remove-face-function)
   (setq facemenu-add-face-function
@@ -1263,14 +1282,19 @@ C-c C-r  message-caesar-buffer-body (rot13 the message body)."
        facemenu-remove-face-function t)
   (make-local-variable 'paragraph-separate)
   (make-local-variable 'paragraph-start)
-  (setq paragraph-start (concat (regexp-quote mail-header-separator)
-                               "$\\|[ \t]*[-_][-_][-_]+$\\|"
-                               "-- $\\|"
-                               paragraph-start))
-  (setq paragraph-separate (concat (regexp-quote mail-header-separator)
-                                  "$\\|[ \t]*[-_][-_][-_]+$\\|"
-                                  "-- $\\|"
-                                  paragraph-separate))
+  (setq paragraph-start
+       (concat (regexp-quote mail-header-separator)
+               "$\\|[ \t]*[-_][-_][-_]+$\\|"
+               "-- $\\|"
+               ;;!!! Uhm... shurely this can't be right.
+               "[> " (regexp-quote message-yank-prefix) "]+$\\|"
+               paragraph-start))
+  (setq paragraph-separate
+       (concat (regexp-quote mail-header-separator)
+               "$\\|[ \t]*[-_][-_][-_]+$\\|"
+               "-- $\\|"
+               "[> " (regexp-quote message-yank-prefix) "]+$\\|"
+               paragraph-separate))
   (make-local-variable 'message-reply-headers)
   (setq message-reply-headers nil)
   (make-local-variable 'message-newsreader)
@@ -1292,7 +1316,10 @@ C-c C-r  message-caesar-buffer-body (rot13 the message body)."
        (mail-abbrevs-setup)
       (funcall (intern "mail-aliases-setup"))))
   (message-set-auto-save-file-name)
-  (run-hooks 'text-mode-hook 'message-mode-hook))
+  (gnus-run-hooks 'text-mode-hook 'message-mode-hook)
+  (unless (string-match "XEmacs" emacs-version)
+    (set (make-local-variable 'font-lock-defaults)
+        '(message-font-lock-keywords t))))
 
 \f
 
@@ -1421,6 +1448,31 @@ With the prefix argument FORCE, insert the header anyway."
   (message-goto-signature)
   (forward-line -2))
 
+(defun message-kill-to-signature ()
+  "Deletes all text up to the signature."
+  (interactive)
+  (let ((point (point)))
+    (message-goto-signature)
+    (forward-line -2)
+    (kill-region point (point))
+    (unless (bolp)
+      (insert "\n"))))
+
+(defun message-newline-and-reformat ()
+  "Insert four newlines, and then reformat if inside quoted text."
+  (interactive)
+  (let ((point (point))
+       quoted)
+    (save-excursion
+      (beginning-of-line)
+      (setq quoted (looking-at (regexp-quote message-yank-prefix))))
+    (insert "\n\n\n\n")
+    (when quoted
+      (insert message-yank-prefix))
+    (fill-paragraph nil)
+    (goto-char point)
+    (forward-line 2)))
+
 (defun message-insert-signature (&optional force)
   "Insert a signature.  See documentation for the `message-signature' variable."
   (interactive (list 0))
@@ -1512,7 +1564,7 @@ message-elide-elipsis) will be inserted where the text was killed."
 
 (defun message-caesar-buffer-body (&optional rotnum)
   "Caesar rotates all letters in the current buffer by 13 places.
-Used to encode/decode possibly offensive messages (commonly in net.jokes).
+Used to encode/decode possiblyun offensive messages (commonly in net.jokes).
 With prefix arg, specifies the number of places to rotate each letter forward.
 Mail and USENET news headers are not rotated."
   (interactive (if current-prefix-arg
@@ -1559,7 +1611,9 @@ name, rather than giving an automatic name."
                       (read-string "New buffer name: " name-default)
                     name-default))
             (default-directory
-              (file-name-as-directory message-autosave-directory)))
+              (if message-autosave-directory
+                  (file-name-as-directory message-autosave-directory)
+                default-directory)))
        (rename-buffer name t)))))
 
 (defun message-fill-yanked-message (&optional justifyp)
@@ -1641,6 +1695,26 @@ prefix, and don't delete any headers."
       (unless modified
        (setq message-checksum (cons (message-checksum) (buffer-size)))))))
 
+(defun message-cite-original-without-signature ()
+  "Cite function in the standard Message manner."
+  (let ((start (point))
+       (end (mark t))
+       (functions
+        (when message-indent-citation-function
+          (if (listp message-indent-citation-function)
+              message-indent-citation-function
+            (list message-indent-citation-function)))))
+    (goto-char end)
+    (when (re-search-backward "^-- $" start t)
+      (delete-region (point) end))
+    (goto-char start)
+    (while functions
+      (funcall (pop functions)))
+    (when message-citation-line-function
+      (unless (bolp)
+       (insert "\n"))
+      (funcall message-citation-line-function))))
+
 (defun message-cite-original ()
   "Cite function in the standard Message manner."
   (let ((start (point))
@@ -1735,6 +1809,7 @@ The text will also be indented the normal way."
 (defun message-dont-send ()
   "Don't send the message you have been editing."
   (interactive)
+  (save-buffer)
   (let ((actions message-postpone-actions))
     (message-bury (current-buffer))
     (message-do-actions actions)))
@@ -1767,19 +1842,15 @@ Otherwise any failure is reported in a message back to
 the user from the mailer."
   (interactive "P")
   ;; Disabled test.
-  (when (if (and nil buffer-file-name)
-           (y-or-n-p (format "Send buffer contents as %s message? "
-                             (if (message-mail-p)
-                                 (if (message-news-p) "mail and news" "mail")
-                               "news")))
-         (or (buffer-modified-p)
-             (y-or-n-p "No changes in the buffer; really send? ")))
+  (when (or (buffer-modified-p)
+           (message-check-element 'unchanged)
+           (y-or-n-p "No changes in the buffer; really send? "))
     ;; Make it possible to undo the coming changes.
     (undo-boundary)
     (let ((inhibit-read-only t))
       (put-text-property (point-min) (point-max) 'read-only nil))
     (message-fix-before-sending)
-    (run-hooks 'message-send-hook)
+    (gnus-run-hooks 'message-send-hook)
     (message "Sending...")
     (let ((alist message-send-method-alist)
          (success t)
@@ -1799,7 +1870,7 @@ the user from the mailer."
        (message-do-fcc)
        ;;(when (fboundp 'mail-hist-put-headers-into-history)
        ;; (mail-hist-put-headers-into-history))
-       (run-hooks 'message-sent-hook)
+       (gnus-run-hooks 'message-sent-hook)
        (message "Sending...done")
        ;; Mark the buffer as unmodified and delete autosave.
        (set-buffer-modified-p nil)
@@ -1860,7 +1931,7 @@ the user from the mailer."
             (if news nil message-deletable-headers)))
        (message-generate-headers message-required-mail-headers))
       ;; Let the user do all of the above.
-      (run-hooks 'message-header-hook))
+      (gnus-run-hooks 'message-header-hook))
     (unwind-protect
        (save-excursion
          (set-buffer tembuf)
@@ -1905,7 +1976,7 @@ the user from the mailer."
       (replace-match "\n")
       (backward-char 1)
       (setq delimline (point-marker))
-      (run-hooks 'message-send-mail-hook)
+      (gnus-run-hooks 'message-send-mail-hook)
       ;; Insert an extra newline if we need it to work around
       ;; Sun's bug that swallows newlines.
       (goto-char (1+ delimline))
@@ -1915,7 +1986,8 @@ the user from the mailer."
        (save-excursion
          (set-buffer errbuf)
          (erase-buffer))))
-    (let ((default-directory "/"))
+    (let ((default-directory "/")
+         (coding-system-for-write 'binary))
       (apply 'call-process-region
             (append (list (point-min) (point-max)
                           (if (boundp 'sendmail-program)
@@ -1960,30 +2032,31 @@ to find out how to use this."
   (re-search-forward
    (concat "^" (regexp-quote mail-header-separator) "\n"))
   (replace-match "\n")
-  (run-hooks 'message-send-mail-hook)
+  (gnus-run-hooks 'message-send-mail-hook)
   ;; send the message
   (case
-      (apply
-       'call-process-region 1 (point-max) message-qmail-inject-program
-       nil nil nil
-       ;; qmail-inject's default behaviour is to look for addresses on the
-       ;; command line; if there're none, it scans the headers.
-       ;; yes, it does The Right Thing w.r.t. Resent-To and it's kin.
-       ;;
-       ;; in general, ALL of qmail-inject's defaults are perfect for simply
-       ;; reading a formatted (i. e., at least a To: or Resent-To header)
-       ;; message from stdin.
-       ;;
-       ;; qmail also has the advantage of not having been raped by
-       ;; various vendors, so we don't have to allow for that, either --
-       ;; compare this with message-send-mail-with-sendmail and weep
-       ;; for sendmail's lost innocence.
-       ;;
-       ;; all this is way cool coz it lets us keep the arguments entirely
-       ;; free for -inject-arguments -- a big win for the user and for us
-       ;; since we don't have to play that double-guessing game and the user
-       ;; gets full control (no gestapo'ish -f's, for instance).  --sj
-       message-qmail-inject-args)
+      (let ((coding-system-for-write 'binary))
+       (apply
+        'call-process-region 1 (point-max) message-qmail-inject-program
+        nil nil nil
+        ;; qmail-inject's default behaviour is to look for addresses on the
+        ;; command line; if there're none, it scans the headers.
+        ;; yes, it does The Right Thing w.r.t. Resent-To and it's kin.
+        ;;
+        ;; in general, ALL of qmail-inject's defaults are perfect for simply
+        ;; reading a formatted (i. e., at least a To: or Resent-To header)
+        ;; message from stdin.
+        ;;
+        ;; qmail also has the advantage of not having been raped by
+        ;; various vendors, so we don't have to allow for that, either --
+        ;; compare this with message-send-mail-with-sendmail and weep
+        ;; for sendmail's lost innocence.
+        ;;
+        ;; all this is way cool coz it lets us keep the arguments entirely
+        ;; free for -inject-arguments -- a big win for the user and for us
+        ;; since we don't have to play that double-guessing game and the user
+        ;; gets full control (no gestapo'ish -f's, for instance).  --sj
+        message-qmail-inject-args))
     ;; qmail-inject doesn't say anything on it's stdout/stderr,
     ;; we have to look at the retval instead
     (0 nil)
@@ -1995,10 +2068,7 @@ to find out how to use this."
 (defun message-send-mail-with-mh ()
   "Send the prepared message buffer with mh."
   (let ((mh-previous-window-config nil)
-       (name (make-temp-name
-              (concat (file-name-as-directory
-                       (expand-file-name message-autosave-directory))
-                      "msg."))))
+       (name (mh-new-draft-name)))
     (setq buffer-file-name name)
     ;; MH wants to generate these headers itself.
     (when message-mh-deletable-headers
@@ -2009,7 +2079,7 @@ to find out how to use this."
                (concat "^" (symbol-name (car headers)) ": *") nil t)
               (message-delete-line))
          (pop headers))))
-    (run-hooks 'message-send-mail-hook)
+    (gnus-run-hooks 'message-send-mail-hook)
     ;; Pass it on to mh.
     (mh-send-letter)))
 
@@ -2031,7 +2101,7 @@ to find out how to use this."
       ;; Insert some headers.
       (message-generate-headers message-required-news-headers)
       ;; Let the user do all of the above.
-      (run-hooks 'message-header-hook))
+      (gnus-run-hooks 'message-header-hook))
     (message-cleanup-headers)
     (if (not (message-check-news-syntax))
        (progn
@@ -2063,7 +2133,7 @@ to find out how to use this."
               (concat "^" (regexp-quote mail-header-separator) "\n"))
              (replace-match "\n")
              (backward-char 1))
-           (run-hooks 'message-send-news-hook)
+           (gnus-run-hooks 'message-send-news-hook)
            ;;(require (car method))
            ;;(funcall (intern (format "%s-open-server" (car method)))
            ;;(cadr method) (cddr method))
@@ -2195,8 +2265,12 @@ to find out how to use this."
      (let* ((case-fold-search t)
            (message-id (message-fetch-field "message-id" t)))
        (or (not message-id)
+          ;; Is there an @ in the ID?
           (and (string-match "@" message-id)
-               (string-match "@[^\\.]*\\." message-id))
+               ;; Is there a dot in the ID?
+               (string-match "@[^.]*\\." message-id)
+               ;; Does the ID end with a dot?
+               (not (string-match "\\.>" message-id)))
           (y-or-n-p
            (format "The Message-ID looks strange: \"%s\".  Really post? "
                    message-id)))))
@@ -2516,11 +2590,10 @@ to find out how to use this."
 (defun message-make-organization ()
   "Make an Organization header."
   (let* ((organization
-         (or (getenv "ORGANIZATION")
-             (when message-user-organization
+         (when message-user-organization
                (if (message-functionp message-user-organization)
                    (funcall message-user-organization)
-                 message-user-organization)))))
+                 message-user-organization))))
     (save-excursion
       (message-set-work-buffer)
       (cond ((stringp organization)
@@ -2679,7 +2752,8 @@ give as trustworthy answer as possible."
           (string-match "\\." mail-host-address))
       mail-host-address)
      ;; We try `user-mail-address' as a backup.
-     ((and (string-match "\\." user-mail)
+     ((and user-mail
+          (string-match "\\." user-mail)
           (string-match "@\\(.*\\)\\'" user-mail))
       (match-string 1 user-mail))
      ;; Default to this bogus thing.
@@ -2876,7 +2950,7 @@ Headers already prepared in the buffer are not modified."
 
 (defun message-fill-header (header value)
   (let ((begin (point))
-       (fill-column 78)
+       (fill-column 990)
        (fill-prefix "\t"))
     (insert (capitalize (symbol-name header))
            ": "
@@ -2998,7 +3072,8 @@ Headers already prepared in the buffer are not modified."
    headers)
   (delete-region (point) (progn (forward-line -1) (point)))
   (when message-default-headers
-    (insert message-default-headers))
+    (insert message-default-headers)
+    (or (bolp) (insert ?\n)))
   (put-text-property
    (point)
    (progn
@@ -3008,7 +3083,8 @@ Headers already prepared in the buffer are not modified."
   (forward-line -1)
   (when (message-news-p)
     (when message-default-news-headers
-      (insert message-default-news-headers))
+      (insert message-default-news-headers)
+      (or (bolp) (insert ?\n)))
     (when message-generate-headers-first
       (message-generate-headers
        (delq 'Lines
@@ -3016,57 +3092,35 @@ Headers already prepared in the buffer are not modified."
                   (copy-sequence message-required-news-headers))))))
   (when (message-mail-p)
     (when message-default-mail-headers
-      (insert message-default-mail-headers))
+      (insert message-default-mail-headers)
+      (or (bolp) (insert ?\n)))
     (when message-generate-headers-first
       (message-generate-headers
        (delq 'Lines
             (delq 'Subject
                   (copy-sequence message-required-mail-headers))))))
-  (run-hooks 'message-signature-setup-hook)
+  (gnus-run-hooks 'message-signature-setup-hook)
   (message-insert-signature)
   (save-restriction
     (message-narrow-to-headers)
-    (run-hooks 'message-header-setup-hook))
+    (gnus-run-hooks 'message-header-setup-hook))
   (set-buffer-modified-p nil)
   (setq buffer-undo-list nil)
-  (run-hooks 'message-setup-hook)
+  (gnus-run-hooks 'message-setup-hook)
   (message-position-point)
   (undo-boundary))
 
 (defun message-set-auto-save-file-name ()
   "Associate the message buffer with a file in the drafts directory."
   (when message-autosave-directory
-    (cond
-     ((fboundp 'nndraft-request-associate-buffer)
-      (setq message-draft-article (nndraft-request-associate-buffer "drafts"))
-      (clear-visited-file-modtime))
-     (t (unless (file-exists-p message-autosave-directory)
-         (make-directory message-autosave-directory t))
-       (let ((name (make-temp-name
-                    (expand-file-name
-                     (concat (file-name-as-directory
-                              message-autosave-directory)
-                             "msg."
-                             (message-replace-chars-in-string
-                              (message-replace-chars-in-string
-                               (buffer-name) ?* ?.)
-                              ?/ ?-))))))
-         (setq buffer-auto-save-file-name
-               (save-excursion
-                 (prog1
-                     (progn
-                       (set-buffer (get-buffer-create " *draft tmp*"))
-                       (setq buffer-file-name name)
-                       (make-auto-save-file-name))
-                   (kill-buffer (current-buffer)))))
-         (clear-visited-file-modtime))))))
+    (setq message-draft-article (nndraft-request-associate-buffer "drafts"))
+    (clear-visited-file-modtime)))
 
 (defun message-disassociate-draft ()
   "Disassociate the message buffer from the drafts directory."
   (when message-draft-article
-    (if (fboundp 'nndraft-request-expire-articles)
-       (nndraft-request-expire-articles
-         (list message-draft-article) "drafts" nil t))))
+    (nndraft-request-expire-articles
+     (list message-draft-article) "drafts" nil t)))
 
 \f
 
@@ -3148,7 +3202,10 @@ Headers already prepared in the buffer are not modified."
       (unless follow-to
        (if (or (not wide)
                to-address)
-           (setq follow-to (list (cons 'To (or to-address reply-to from))))
+           (progn
+             (setq follow-to (list (cons 'To (or to-address reply-to from))))
+             (when (and wide mct)
+               (push (cons 'Cc mct) follow-to)))
          (let (ccalist)
            (save-excursion
              (message-set-work-buffer)
@@ -3653,7 +3710,7 @@ Do a `tab-to-tab-stop' if not in those headers."
 
 (defvar gnus-active-hashtb)
 (defun message-expand-group ()
-  (let* ((b (save-excursion
+  "Expand the group name under point."  (let* ((b (save-excursion
              (save-restriction
                (narrow-to-region
                 (save-excursion