Synch to Gnus 200311282213.
authoryamaoka <yamaoka>
Sat, 29 Nov 2003 04:15:58 +0000 (04:15 +0000)
committeryamaoka <yamaoka>
Sat, 29 Nov 2003 04:15:58 +0000 (04:15 +0000)
contrib/ChangeLog
contrib/starttls.el
lisp/ChangeLog
lisp/message.el

index f0abd9d..999d5d9 100644 (file)
@@ -1,3 +1,7 @@
+2003-11-15  Simon Josefsson  <jas@extundo.com>
+
+       * starttls.el: Sync with recent gnu.emacs.sources post.
+
 2003-10-24  Steve Youngs  <sryoungs@bigpond.net.au>
 
        * nnir.el: Autoload `read-kbd-macro' at compile time.
index 229daf1..ff5efc4 100644 (file)
 ;;; Commentary:
 
 ;; This package implements a simple wrapper around the GNU TLS command
-;; line application "gnutls-cli" to make Emacs support STARTTLS.
+;; line application "gnutls-cli" to make Emacs support STARTTLS.  It
+;; is backwards compatible (same API functions) with the "starttls.el"
+;; that is part of Emacs 21 (that version used an external program
+;; "starttls" that isn't widely installed, and was based on OpenSSL).
+
+;; This package require GNUTLS 0.9.90 (released 2003-10-08) or later.
+
+;; Usage is similar to `open-network-stream'.  Evaluating the following:
 ;;
-;; This package require GNUTLS 0.9.8 (released 2003-10-02) or later.
+;; (progn
+;;   (setq tmp (open-starttls-stream "test" (current-buffer) "mail.example.com" 143))
+;;   (process-send-string tmp ". starttls\n")
+;;   (sit-for 4)
+;;   (message "STARTTLS output:\n%s" (negotiate-starttls tmp))
+;;   (process-send-string tmp ". capability\n"))
 ;;
-;; Usage is similar to `open-network-stream', i.e.:
+;; in, e.g., the *scratch* buffer, yields the following output:
 ;;
-;; (setq tmp (open-starttls-stream "test" (current-buffer) "cyrus.andrew.cmu.edu" 143))
-;; #<process test<9>>
-;; (process-send-string tmp ". starttls\n")
+;; * OK imap.example.com Cyrus IMAP4 v2.1.15 server ready\r
+;; . OK Begin TLS negotiation now\r
+;; * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA ...
+;; . OK Completed\r
 ;; nil
-;; (negotiate-starttls tmp)
-;; "*** Starting TLS handshake
+;;
+;; And the message buffer contains:
+;;
+;; STARTTLS output:
+;; *** Starting TLS handshake
+;; - Server's trusted authorities:
+;;    [0]: O=Sendmail,OU=Sendmail Server,CN=imap.example.com,EMAIL=admin@imap.example.com
 ;; - Certificate type: X.509
-;;  - Certificate info:
-;;  # Certificate is valid since: Thu Jun 26 19:00:00 CEST 2003
-;;  # Certificate expires: Sat Jun 26 19:00:00 CEST 2004
-;;  # Certificate fingerprint: 8d 59 d6 e1 c9 91 dc 5a bb 38 47 8c ec 85 1b 99
-;;  # Certificate serial number: 3e fb 52 ce
-;;  # Certificate version: #3
-;;  # Certificate public key algorithm: RSA
+;;  - Got a certificate list of 1 certificates.
+;;
+;;  - Certificate[0] info:
+;;  # The hostname in the certificate matches 'imap.example.com'.
+;;  # valid since: Wed Aug 28 12:47:00 CEST 2002
+;;  # expires at: Thu Aug 28 12:47:00 CEST 2003
+;;  # serial number: 00
+;;  # fingerprint: 06 3f 25 cb 44 aa 5c 1e 79 d7 63 86 f8 b1 9a cf
+;;  # version: #3
+;;  # public key algorithm: RSA
 ;;  #   Modulus: 1024 bits
-;;  # CN=cyrus.andrew.cmu.edu,OU=Computing Services,O=Carnegie Mellon University,L=Pittsburgh,ST=Pennsylvania,C=US
-;;  # Certificate Issuer's info:
-;;  # CN=CMU CA mail 1,OU=Computing Services,O=Carnegie Mellon University,L=Pittsburgh,ST=Pennsylvania,C=US
+;;  # Subject's DN: O=Sendmail,OU=Sendmail Server,CN=imap.example.com,EMAIL=admin@imap.example.com
+;;  # Issuer's DN: O=Sendmail,OU=Sendmail Server,CN=imap.example.com,EMAIL=admin@imap.example.com
 ;;
+;;
+;; - Peer's certificate issuer is unknown
 ;; - Peer's certificate is NOT trusted
 ;; - Version: TLS 1.0
 ;; - Key Exchange: RSA
 ;; - Cipher: ARCFOUR 128
 ;; - MAC: SHA
 ;; - Compression: NULL
-;; "
-;; (process-send-string tmp ". capability\n")
-;; nil
-;; (process-send-string tmp ". logout\n")
-;; nil
-;;
-;; Resolving 'cyrus.andrew.cmu.edu'...
-;; Connecting to '128.2.10.174:143'...
-;;
-;; - Simple Client Mode:
-;;
-;; * OK mail-fe4.andrew.cmu.edu Cyrus IMAP4 Murder v2.1.15-077 server ready\r
-;; . OK Begin TLS negotiation now\r
-;; * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS NAMESPACE UIDPLUS ID NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND SORT THREAD=ORDEREDSUBJECT THREAD=REFERENCES AUTH=PLAIN AUTH=KERBEROS_V4 AUTH=GSSAPI AUTH=ANONYMOUS ANNOTATEMORE\r
-;; . OK Completed\r
-;; * BYE LOGOUT received\r
-;; . OK Completed\r
-;; *** Received corrupted data(-9) - server has terminated the connection abnormally
+
+;; Revision history:
 ;;
-;; Process test<9> finished
+;; 2003-11-15: cleanup, and posted to gnu.emacs.sources.
 
 ;;; Code:
 
-(eval-and-compile
-  (autoload 'format-spec "format-spec")
-  (autoload 'format-spec-make "format-spec"))
-
 (defgroup starttls nil
   "Negotiated Transport Layer Security (STARTTLS) parameters."
   :group 'comm)
 
-(defcustom starttls-program "gnutls-cli"
-  "The program to run in a subprocess to open an STARTTLS connection.
-The program should read input on stdin and write output to
-stdout.  Also see `starttls-connect' and `starttls-success' for
-what the program should output after initial connection and
-successful negotiation respectively."
+(defcustom starttls-file-name "gnutls-cli"
+  "Name of the program to run in a subprocess to open an STARTTLS connection.
+The program should read input on stdin, write output to stdout,
+and initiate TLS negotiation when receiving the SIGALRM signal.
+Also see `starttls-connect', `starttls-failure', and
+`starttls-success' for what the program should output after
+initial connection and successful negotiation respectively."
   :type 'string
   :group 'starttls)
 
-(defcustom starttls-extra-args nil
-  "List of extra arguments to `starttls-program'.
+(defcustom starttls-extra-arguments nil
+  "List of extra arguments to `starttls-file-name'.
 E.g., (\"--protocols\" \"ssl3\")."
   :type '(repeat string)
   :group 'starttls)
@@ -110,26 +113,27 @@ E.g., (\"--protocols\" \"ssl3\")."
 (defcustom starttls-connect "- Simple Client Mode:\n\n"
   "*Regular expression indicating successful connection.
 The default is what GNUTLS's \"gnutls-cli\" outputs."
-  ;; cli.c:main() print this string when it is starting to run in the
-  ;; application read/write phase.  If the logic, or the string
-  ;; itself, is modified, this have to be updated.
+  ;; GNUTLS cli.c:main() print this string when it is starting to run
+  ;; in the application read/write phase.  If the logic, or the string
+  ;; itself, is modified, this must be updated.
   :type 'regexp
   :group 'starttls)
 
 (defcustom starttls-failure "*** Handshake has failed"
   "*Regular expression indicating failed TLS handshake.
 The default is what GNUTLS's \"gnutls-cli\" outputs."
-  ;; cli.c:do_handshake() print this string on failure.  If the logic,
-  ;; or the string itself, is modified, this have to be updated.
+  ;; GNUTLS cli.c:do_handshake() print this string on failure.  If the
+  ;; logic, or the string itself, is modified, this must be updated.
   :type 'regexp
   :group 'starttls)
 
 (defcustom starttls-success "- Compression: "
   "*Regular expression indicating completed TLS handshakes.
 The default is what GNUTLS's \"gnutls-cli\" outputs."
-  ;; cli.c:do_handshake() calls, on success, common.c:print_info(),
-  ;; that unconditionally print this string last.  If that logic, or
-  ;; the string itself, is modified, this have to be updated.
+  ;; GNUTLS cli.c:do_handshake() calls, on success,
+  ;; common.c:print_info(), that unconditionally print this string
+  ;; last.  If that logic, or the string itself, is modified, this
+  ;; must be updated.
   :type 'regexp
   :group 'starttls)
 
@@ -140,29 +144,26 @@ multi-line informational message with information about the
 handshake, or NIL on failure."
   (let (buffer info old-max done-ok done-bad)
     (if (null (setq buffer (process-buffer process)))
-       ;; XXX how to remove/extract the TLS negotiation junk?
+       ;; XXX How to remove/extract the TLS negotiation junk?
        (signal-process (process-id process) 'SIGALRM)
       (with-current-buffer buffer
        (save-excursion
-         (goto-char (point-max))
-         (setq old-max (point))
+         (setq old-max (goto-char (point-max)))
          (signal-process (process-id process) 'SIGALRM)
-         (while (and process
-                     (memq (process-status process) '(open run))
+         (while (and (processp process)
+                     (eq (process-status process) 'run)
                      (save-excursion
-                       (set-buffer buffer) ;; XXX "blue moon" nntp.el bug
                        (goto-char old-max)
-                       (progn
-                         (setq
-                          done-ok (re-search-forward starttls-success nil t)
-                          done-bad (re-search-forward starttls-failure nil t))
-                         (not (or done-ok done-bad)))))
+                       (not (or (setq done-ok (re-search-forward
+                                               starttls-success nil t))
+                                (setq done-bad (re-search-forward
+                                                starttls-failure nil t))))))
            (accept-process-output process 1 100)
            (sit-for 0.1))
          (setq info (buffer-substring-no-properties old-max (point-max)))
          (delete-region old-max (point-max))
          (if (or (and done-ok (not done-bad))
-                 ;; prevent mitm that fake success msg after failure msg.
+                 ;; Prevent mitm that fake success msg after failure msg.
                  (and done-ok done-bad (< done-ok done-bad)))
              info
            (message "STARTTLS negotiation failed: %s" info)
@@ -185,32 +186,35 @@ specifying a port number to connect to."
         (old-max (with-current-buffer buffer (point-max)))
         (process-connection-type starttls-process-connection-type)
         (process (apply #'start-process name buffer
-                        starttls-program "-s" host
+                        starttls-file-name "-s" host
                         "-p" (if (integerp service)
                                  (int-to-string service)
                                service)
-                        starttls-extra-args)))
+                        starttls-extra-arguments)))
     (process-kill-without-query process)
-    (while (and process
-               (memq (process-status process) '(open run))
+    (while (and (processp process)
+               (eq (process-status process) 'run)
                (save-excursion
-                 (set-buffer buffer) ;; XXX "blue moon" nntp.el bug
-                 (goto-char (point-min))
+                 (set-buffer buffer)
+                 (goto-char old-max)
                  (not (setq done (re-search-forward
                                   starttls-connect nil t)))))
       (accept-process-output process 0 100)
       (sit-for 0.1))
     (if done
-       (progn
-         (with-current-buffer buffer
-           (delete-region old-max done))
-         (setq done process))
-      (delete-process process))
+       (with-current-buffer buffer
+         (delete-region old-max done))
+      (delete-process process)
+      (setq process nil))
     (message "Opening STARTTLS connection to `%s'...%s"
             host (if done "done" "failed"))
-    done))
+    process))
 
 ;; Compatibility with starttls.el by Daiki Ueno <ueno@unixuser.org>:
+(defvaralias 'starttls-program 'starttls-file-name)
+(make-obsolete-variable 'starttls-program 'starttls-file-name)
+(defvaralias 'starttls-extra-args 'starttls-extra-arguments)
+(make-obsolete-variable 'starttls-extra-args 'starttls-extra-arguments)
 (defalias 'starttls-open-stream 'open-starttls-stream)
 (defalias 'starttls-negotiate 'negotiate-starttls)
 
index 0f30867..d5fe3a8 100644 (file)
@@ -1,3 +1,9 @@
+2003-11-28  Reiner Steib  <Reiner.Steib@gmx.de>
+
+       * message.el: Added custom-manual links to all variables that have
+       an index entry in the message manual.
+       (message-generate-headers-first): Fixed doc-string.
+
 2003-11-27  Katsumi Yamaoka  <yamaoka@jpl.org>
 
        * gnus-msg.el (gnus-summary-yank-message): Don't bind
@@ -26,7 +32,7 @@
        exits processors
        (spam-group-processor-p): support old-style and new-style spam/ham
        exit processors
-       (spam-group-processor-multiple-p): handle new-style spam/hamn exit
+       (spam-group-processor-multiple-p): handle new-style spam/ham exit
        processors
        (spam-summary-prepare): use spam-old-{ham,spam}-articles; change
        logic to iterate over list of processors instead of manual
index fed9efc..afdaadc 100644 (file)
@@ -195,7 +195,6 @@ If this variable is nil, no such courtesy message will be added."
 ;;; Start of variables adopted from `message-utils.el'.
 
 (defcustom message-subject-trailing-was-query 'ask
-  ;; should it default to nil or ask?
   "*What to do with trailing \"(was: <old subject>)\" in subject lines.
 If nil, leave the subject unchanged.  If it is the symbol `ask', query
 the user what do do.  In this case, the subject is matched against
@@ -206,6 +205,7 @@ used."
   :type '(choice (const :tag "never" nil)
                 (const :tag "always strip" t)
                  (const ask))
+  :link '(custom-manual "(message)Message Headers")
   :group 'message-various)
 
 (defcustom message-subject-trailing-was-ask-regexp
@@ -219,6 +219,7 @@ the variable is t instead of `ask', use
 
 It is okay to create some false positives here, as the user is asked."
   :group 'message-various
+  :link '(custom-manual "(message)Message Headers")
   :type 'regexp)
 
 (defcustom message-subject-trailing-was-regexp
@@ -230,6 +231,7 @@ matched against `message-subject-trailing-was-regexp' in
 `message-strip-subject-trailing-was'.  You should use a regexp creating very
 few false positives here."
   :group 'message-various
+  :link '(custom-manual "(message)Message Headers")
   :type 'regexp)
 
 ;; Fixme: Why are all these things autoloaded?
@@ -241,6 +243,7 @@ few false positives here."
   "--8<---------------cut here---------------start------------->8---\n"
   "How to mark the beginning of some inserted text."
   :type 'string
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-various)
 
 ;;;###autoload
@@ -248,6 +251,7 @@ few false positives here."
   "--8<---------------cut here---------------end--------------->8---\n"
   "How to mark the end of some inserted text."
   :type 'string
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-various)
 
 ;;;###autoload
@@ -256,6 +260,7 @@ few false positives here."
   "Header to insert when you don't want your article to be archived.
 Archives \(such as groups.google.com\) respect this header."
   :type 'string
+  :link '(custom-manual "(message)Header Commands")
   :group 'message-various)
 
 ;;;###autoload
@@ -265,6 +270,7 @@ Archives \(such as groups.google.com\) respect this header."
 If nil, don't insert any text in the body."
   :type '(radio (string :format "%t: %v\n" :size 0)
                (const nil))
+  :link '(custom-manual "(message)Header Commands")
   :group 'message-various)
 
 ;;; Crossposts and Followups
@@ -362,12 +368,14 @@ Also see `message-required-news-headers' and
 `message-required-mail-headers'."
   :group 'message-news
   :group 'message-headers
+  :link '(custom-manual "(message)Message Headers")
   :type '(repeat sexp))
 
 (defcustom message-draft-headers '(References From)
   "*Headers to be generated when saving a draft message."
   :group 'message-news
   :group 'message-headers
+  :link '(custom-manual "(message)Message Headers")
   :type '(repeat sexp))
 
 (defcustom message-required-news-headers
@@ -381,6 +389,7 @@ User-Agent are optional.  If don't you want message to insert some
 header, remove it from this list."
   :group 'message-news
   :group 'message-headers
+  :link '(custom-manual "(message)Message Headers")
   :type '(repeat sexp))
 
 (defcustom message-required-mail-headers
@@ -391,11 +400,13 @@ It is recommended that From, Date, To, Subject and Message-ID be
 included.  Organization and User-Agent are optional."
   :group 'message-mail
   :group 'message-headers
+  :link '(custom-manual "(message)Message Headers")
   :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."
   :group 'message-headers
+  :link '(custom-manual "(message)Message Headers")
   :type 'sexp)
 
 (defcustom message-ignored-news-headers
@@ -403,6 +414,7 @@ included.  Organization and User-Agent are optional."
   "*Regexp of headers to be removed unconditionally before posting."
   :group 'message-news
   :group 'message-headers
+  :link '(custom-manual "(message)Message Headers")
   :type 'regexp)
 
 (defcustom message-ignored-mail-headers
@@ -410,6 +422,7 @@ included.  Organization and User-Agent are optional."
   "*Regexp of headers to be removed unconditionally before mailing."
   :group 'message-mail
   :group 'message-headers
+  :link '(custom-manual "(message)Mail Headers")
   :type 'regexp)
 
 (defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-Complaints-To:\\|Return-Path:\\|^Supersedes:\\|^NNTP-Posting-Date:\\|^X-Trace:\\|^X-Complaints-To:\\|^Cancel-Lock:\\|^Cancel-Key:\\|^X-Hashcash:\\|^X-Payment:"
@@ -417,6 +430,7 @@ included.  Organization and User-Agent are optional."
 It's best to delete old Path and Date headers before posting to avoid
 any confusion."
   :group 'message-interface
+  :link '(custom-manual "(message)Superseding")
   :type 'regexp)
 
 (defcustom message-supersede-setup-function
@@ -429,6 +443,7 @@ any confusion."
   "^[ \t]*\\([Rr][Ee]\\(\\[[0-9]*\\]\\)*:[ \t]*\\)*[ \t]*"
   "*Regexp matching \"Re: \" in the subject line."
   :group 'message-various
+  :link '(custom-manual "(message)Message Headers")
   :type 'regexp)
 
 ;;; Some sender agents encode the whole subject including leading "Re: ".
@@ -461,6 +476,7 @@ any confusion."
 Unlike `message-subject-re-regexp', this regexp matches \"Re: \" within
 an encoded-word."
   :group 'message-various
+  :link '(custom-manual "(message)Message Headers")
   :type 'regexp)
 
 (defcustom message-use-subject-re t
@@ -476,6 +492,7 @@ is the symbol `guess', try to detect \"Re: \" within an encoded-word."
 (defcustom message-signature-separator "^-- *$"
   "Regexp matching the signature separator."
   :type 'regexp
+  :link '(custom-manual "(message)Various Message Variables")
   :group 'message-various)
 
 (defcustom message-signature-separator-for-insertion "-- \n"
@@ -488,6 +505,7 @@ value may go against RFC-1036 and draft-ietf-usefor-article-05.txt. "
 (defcustom message-elide-ellipsis "\n[...]\n\n"
   "*The string which is inserted for elided text."
   :type 'string
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-various)
 
 (defcustom message-interactive t
@@ -495,6 +513,7 @@ value may go against RFC-1036 and draft-ietf-usefor-article-05.txt. "
 nil means let mailer mail back a message to report errors."
   :group 'message-sending
   :group 'message-mail
+  :link '(custom-manual "(message)Sending Variables")
   :type 'boolean)
 
 (defcustom message-generate-new-buffers 'unique
@@ -503,6 +522,7 @@ If this is a function, call that function with three parameters:  The type,
 the to address and the group name.  (Any of these may be nil.)  The function
 should return the new buffer name."
   :group 'message-buffers
+  :link '(custom-manual "(message)Message Buffers")
   :type '(choice (const :tag "off" nil)
                 (const :tag "unique" unique)
                 (const :tag "unsent" unsent)
@@ -511,6 +531,7 @@ should return the new buffer name."
 (defcustom message-kill-buffer-on-exit nil
   "*Non-nil means that the message buffer will be killed after sending a message."
   :group 'message-buffers
+  :link '(custom-manual "(message)Message Buffers")
   :type 'boolean)
 
 (defcustom message-kill-buffer-query-function 'yes-or-no-p
@@ -547,6 +568,7 @@ If t, use `message-user-organization-file'."
 (defcustom message-user-organization-file "/usr/lib/news/organization"
   "*Local news organization file."
   :type 'file
+  :link '(custom-manual "(message)News Headers")
   :group 'message-headers)
 
 (defcustom message-forward-start-separator
@@ -582,6 +604,7 @@ The provided functions are:
 * `message-forward-subject-fwd' Subject of article with 'Fwd:' prepended
       to it."
   :group 'message-forwarding
+  :link '(custom-manual "(message)Forwarding")
   :type '(radio (function-item message-forward-subject-author-subject)
                (function-item message-forward-subject-fwd)
                (function-item message-forward-subject-name-subject)
@@ -592,6 +615,7 @@ The provided functions are:
 Otherwise, directly inline the old message in the forwarded message."
   :version "21.1"
   :group 'message-forwarding
+  :link '(custom-manual "(message)Forwarding")
   :type 'boolean)
 
 (defcustom message-forward-show-mml 'best
@@ -617,11 +641,13 @@ digital signature."
   "*Non-nil means try to remove as much cruft as possible from the subject.
 Done before generating the new subject of a forward."
   :group 'message-forwarding
+  :link '(custom-manual "(message)Forwarding")
   :type 'boolean)
 
 (defcustom message-ignored-resent-headers "^Return-receipt\\|^X-Gnus\\|^Gnus-Warning:\\|^>?From "
   "*All headers that match this regexp will be deleted when resending a message."
   :group 'message-interface
+  :link '(custom-manual "(message)Resending")
   :type 'regexp)
 
 (defcustom message-forward-ignored-headers "^Content-Transfer-Encoding:\\|^X-Gnus"
@@ -634,6 +660,7 @@ Done before generating the new subject of a forward."
 (defcustom message-ignored-cited-headers "."
   "*Delete these headers from the messages you yank."
   :group 'message-insertion
+  :link '(custom-manual "(message)Insertion Variables")
   :type 'regexp)
 
 (defcustom message-cite-prefix-regexp
@@ -656,11 +683,13 @@ Done before generating the new subject of a forward."
                "]\\)+>+\\|[ \t]*[]>|}+]\\)+"))))
   "*Regexp matching the longest possible citation prefix on a line."
   :group 'message-insertion
+  :link '(custom-manual "(message)Insertion Variables")
   :type 'regexp)
 
 (defcustom message-cancel-message "I am canceling my own article.\n"
   "Message to be inserted in the cancel message."
   :group 'message-interface
+  :link '(custom-manual "(message)Canceling News")
   :type 'string)
 
 ;; Useful to set in site-init.el
@@ -685,6 +714,7 @@ See also `send-mail-function'."
                (function-item feedmail-send-it)
                (function :tag "Other"))
   :group 'message-sending
+  :link '(custom-manual "(message)Mail Variables")
   :group 'message-mail)
 
 ;; 1997-09-29 by MORIOKA Tomohiko
@@ -694,6 +724,7 @@ The headers should be delimited by a line whose contents match the
 variable `mail-header-separator'."
   :group 'message-sending
   :group 'message-news
+  :link '(custom-manual "(message)News Variables")
   :type 'function)
 
 (defcustom message-reply-to-function nil
@@ -701,6 +732,7 @@ variable `mail-header-separator'."
 This function should pick out addresses from the To, Cc, and From headers
 and respond with new To and Cc headers."
   :group 'message-interface
+  :link '(custom-manual "(message)Reply")
   :type '(choice function (const nil)))
 
 (defcustom message-wide-reply-to-function nil
@@ -708,6 +740,7 @@ and respond with new To and Cc 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
+  :link '(custom-manual "(message)Wide Reply")
   :type '(choice function (const nil)))
 
 (defcustom message-followup-to-function nil
@@ -715,6 +748,7 @@ and respond with new To and Cc 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
+  :link '(custom-manual "(message)Followup")
   :type '(choice function (const nil)))
 
 (defcustom message-use-followup-to 'ask
@@ -724,6 +758,7 @@ query before using the \"poster\" value.  If it is the symbol `ask',
 always query the user whether to use the value.  If it is the symbol
 `use', always use the value."
   :group 'message-interface
+  :link '(custom-manual "(message)Followup")
   :type '(choice (const :tag "ignore" nil)
                 (const :tag "use & query" t)
                 (const :tag "maybe" t)
@@ -737,6 +772,7 @@ query before using the value other than \"always\" or \"never\".
 If it is the symbol `ask', always query the user whether to use
 the value.  If it is the symbol `use', always use the value."
   :group 'message-interface
+  :link '(custom-manual "(message)Mailing Lists")
   :type '(choice (const :tag "ignore" nil)
                 (const :tag "maybe" t)
                 (const :tag "always" use)
@@ -774,6 +810,7 @@ regular expressions to match lists.  These functions can be used in
 conjunction with `message-subscribed-regexps' and
 `message-subscribed-addresses'."
   :group 'message-interface
+  :link '(custom-manual "(message)Mailing Lists")
   :type '(repeat sexp))
 
 (defcustom message-subscribed-address-file nil
@@ -781,6 +818,7 @@ conjunction with `message-subscribed-regexps' and
 If nil, do not look at any files to determine list subscriptions.  If
 non-nil, each line of this file should be a mailing list address."
   :group 'message-interface
+  :link '(custom-manual "(message)Mailing Lists")
   :type '(radio (file :format "%t: %v\n" :size 0)
                (const nil)))
 
@@ -790,6 +828,7 @@ If nil, do not use any predefined list subscriptions.  This list of
 addresses can be used in conjunction with
 `message-subscribed-address-functions' and `message-subscribed-regexps'."
   :group 'message-interface
+  :link '(custom-manual "(message)Mailing Lists")
   :type '(repeat string))
 
 (defcustom message-subscribed-regexps nil
@@ -798,6 +837,7 @@ If nil, do not use any predefined list subscriptions.  This list of
 regular expressions can be used in conjunction with
 `message-subscribed-address-functions' and `message-subscribed-addresses'."
   :group 'message-interface
+  :link '(custom-manual "(message)Mailing Lists")
   :type '(repeat regexp))
 
 (defcustom message-allow-no-recipients 'ask
@@ -806,6 +846,7 @@ If it is the symbol `always', the posting is allowed.  If it is the
 symbol `never', the posting is not allowed.  If it is the symbol
 `ask', you are prompted."
   :group 'message-interface
+  :link '(custom-manual "(message)Message Headers")
   :type '(choice (const always)
                 (const never)
                 (const ask)))
@@ -814,6 +855,7 @@ symbol `never', the posting is not allowed.  If it is the symbol
   "*Non-nil means don't add \"-f username\" to the sendmail command line.
 Doing so would be even more evil than leaving it out."
   :group 'message-sending
+  :link '(custom-manual "(message)Mail Variables")
   :type 'boolean)
 
 (defcustom message-sendmail-envelope-from nil
@@ -823,12 +865,14 @@ If this is nil, use `user-mail-address'.  If it is the symbol
   :type '(choice (string :tag "From name")
                 (const :tag "Use From: header from message" header)
                 (const :tag "Use `user-mail-address'" nil))
+  :link '(custom-manual "(message)Mail Variables")
   :group 'message-sending)
 
 ;; qmail-related stuff
 (defcustom message-qmail-inject-program "/var/qmail/bin/qmail-inject"
   "Location of the qmail-inject program."
   :group 'message-sending
+  :link '(custom-manual "(message)Mail Variables")
   :type 'file)
 
 (defcustom message-qmail-inject-args nil
@@ -840,6 +884,7 @@ For e.g., if you wish to set the envelope sender address so that bounces
 go to the right place or to deal with listserv's usage of that address, you
 might set this variable to '(\"-f\" \"you@some.where\")."
   :group 'message-sending
+  :link '(custom-manual "(message)Mail Variables")
   :type '(choice (function)
                 (repeat string)))
 
@@ -873,16 +918,16 @@ variable isn't used."
 ;; will *not* have a `References:' header if `message-generate-headers-first'
 ;; is nil.  See: http://article.gmane.org/gmane.emacs.gnus.general/51138
 (defcustom message-generate-headers-first '(references)
-  "*If non-nil, generate all required headers before composing.
-The variables `message-required-news-headers' and
+  "Which headers should be generated before starting to compose a message.
+If `t', generate all required headers.  This can also be a list of headers to
+generate.  The variables `message-required-news-headers' and
 `message-required-mail-headers' specify which headers to generate.
-This can also be a list of headers that should be generated before
-composing.
 
 Note that the variable `message-deletable-headers' specifies headers which
 are to be deleted and then re-generated before sending, so this variable
 will not have a visible effect for those headers."
   :group 'message-headers
+  :link '(custom-manual "(message)Message Headers")
   :type '(choice (const :tag "None" nil)
                  (const :tag "References" '(references))
                  (const :tag "All" t)
@@ -892,11 +937,13 @@ will not have a visible effect for those headers."
   "Normal hook, run each time a new outgoing message is initialized.
 The function `message-setup' runs this hook."
   :group 'message-various
+  :link '(custom-manual "(message)Various Message Variables")
   :type 'hook)
 
 (defcustom message-cancel-hook nil
   "Hook run when cancelling articles."
   :group 'message-various
+  :link '(custom-manual "(message)Various Message Variables")
   :type 'hook)
 
 (defcustom message-signature-setup-hook nil
@@ -904,6 +951,7 @@ The function `message-setup' runs this hook."
 It is run after the headers have been inserted and before
 the signature is inserted."
   :group 'message-various
+  :link '(custom-manual "(message)Various Message Variables")
   :type 'hook)
 
 (defcustom message-bounce-setup-hook nil
@@ -931,6 +979,7 @@ The function `message-supersede' runs this hook."
 (defcustom message-header-setup-hook nil
   "Hook called narrowed to the headers when setting up a message buffer."
   :group 'message-various
+  :link '(custom-manual "(message)Various Message Variables")
   :type 'hook)
 
 (defcustom message-minibuffer-local-map
@@ -948,6 +997,7 @@ Note that Gnus provides a feature where the reader can click on
 people who read your message will have to change their Gnus
 configuration.  See the variable `gnus-cite-attribution-suffix'."
   :type 'function
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-insertion)
 
 ;;;###autoload
@@ -956,6 +1006,7 @@ configuration.  See the variable `gnus-cite-attribution-suffix'."
 Fix `message-cite-prefix-regexp' if it is set to an abnormal value.
 See also `message-yank-cited-prefix'."
   :type 'string
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-insertion)
 
 (defcustom message-yank-add-new-references t
@@ -981,12 +1032,14 @@ an article is yanked by the command `message-yank-original' interactively."
 Fix `message-cite-prefix-regexp' if it is set to an abnormal value.
 See also `message-yank-prefix'."
   :type 'string
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-insertion)
 
 (defcustom message-indentation-spaces 3
   "*Number of spaces to insert at the beginning of each cited line.
 Used by `message-yank-original' via `message-yank-cite'."
   :group 'message-insertion
+  :link '(custom-manual "(message)Insertion Variables")
   :type 'integer)
 
 ;;;###autoload
@@ -1000,6 +1053,7 @@ Note that `message-cite-original' uses `mail-citation-hook' if that is non-nil."
                (function-item mu-cite-original)
                (function-item sc-cite-original)
                (function :tag "Other"))
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-insertion)
 
 ;;;###autoload
@@ -1020,6 +1074,7 @@ This can also be a list of functions.  Each function can find the
 citation between (point) and (mark t).  And each function should leave
 point and mark around the citation text as modified."
   :type 'function
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-insertion)
 
 ;;;###autoload
@@ -1029,6 +1084,7 @@ If t, the `message-signature-file' file will be inserted instead.
 If a function, the result from the function will be used instead.
 If a form, the result from the form will be used instead."
   :type 'sexp
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-insertion)
 
 ;;;###autoload
@@ -1037,18 +1093,21 @@ If a form, the result from the form will be used instead."
 Ignored if the named file doesn't exist.
 If nil, don't insert a signature."
   :type '(choice file (const :tags "None" nil))
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-insertion)
 
 ;;;###autoload
 (defcustom message-signature-insert-empty-line t
   "*If non-nil, insert an empty line before the signature separator."
   :type 'boolean
+  :link '(custom-manual "(message)Insertion Variables")
   :group 'message-insertion)
 
 (defcustom message-distribution-function nil
   "*Function called to return a Distribution header."
   :group 'message-news
   :group 'message-headers
+  :link '(custom-manual "(message)News Headers")
   :type '(choice function (const nil)))
 
 (defcustom message-expires 14
@@ -1098,18 +1157,21 @@ It is a vector of the following headers:
 It is inserted before you edit the message, so you can edit or delete
 these lines."
   :group 'message-headers
+  :link '(custom-manual "(message)Message Headers")
   :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
+  :link '(custom-manual "(message)Mail Headers")
   :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
+  :link '(custom-manual "(message)News Headers")
   :type 'message-header-lines)
 
 ;; Note: could use /usr/ucb/mail instead of sendmail;
@@ -1137,6 +1199,7 @@ these lines."
 The value should be an expression to test whether the problem will
 actually occur."
   :group 'message-sending
+  :link '(custom-manual "(message)Mail Variables")
   :type 'sexp)
 
 ;;; XXX: This symbol is overloaded!  See below.
@@ -1182,6 +1245,7 @@ mail aliases off."
   "*Directory where Message auto-saves buffers if Gnus isn't running.
 If nil, Message won't auto-save."
   :group 'message-buffers
+  :link '(custom-manual "(message)Various Message Variables")
   :type '(choice directory (const :tag "Don't auto-save" nil)))
 
 (defcustom message-default-charset
@@ -1189,6 +1253,7 @@ If nil, Message won't auto-save."
   "Default charset used in non-MULE XEmacsen."
   :version "21.1"
   :group 'message
+  :link '(custom-manual "(message)Various Message Variables")
   :type 'symbol)
 
 (defcustom message-dont-reply-to-names
@@ -1197,6 +1262,7 @@ If nil, Message won't auto-save."
 A value of nil means exclude your own user name only."
   :version "21.1"
   :group 'message
+  :link '(custom-manual "(message)Wide Reply")
   :type '(choice (const :tag "Yourself" nil)
                 regexp))
 
@@ -1221,6 +1287,7 @@ candidates:
 This can also be a list of regexps to match headers.  Or a list
 starting with `not' and followed by regexps."
   :group 'message
+  :link '(custom-manual "(message)Message Headers")
   :type '(repeat regexp))
 
 ;;; Internal variables.
@@ -1434,6 +1501,7 @@ The cdr of each entry is a function for applying the face to a region.")
 This hook is run quite early when sending."
   :group 'message-various
   :options '(ispell-message)
+  :link '(custom-manual "(message)Various Message Variables")
   :type 'hook)
 
 (defcustom message-send-mail-hook nil
@@ -1441,6 +1509,7 @@ This hook is run quite early when sending."
 This hook is run very late -- just before the message is sent as
 mail."
   :group 'message-various
+  :link '(custom-manual "(message)Various Message Variables")
   :type 'hook)
 
 (defcustom message-send-news-hook nil
@@ -1448,6 +1517,7 @@ mail."
 This hook is run very late -- just before the message is sent as
 news."
   :group 'message-various
+  :link '(custom-manual "(message)Various Message Variables")
   :type 'hook)
 
 (defcustom message-sent-hook nil
@@ -1480,6 +1550,7 @@ The lower bound of message size in characters, beyond which the message
 should be sent in several parts.  If it is nil, the size is unlimited."
   :version "21.1"
   :group 'message-buffers
+  :link '(custom-manual "(message)Mail Variables")
   :type '(choice (const :tag "unlimited" nil)
                 (integer 1000000)))
 
@@ -1487,6 +1558,7 @@ should be sent in several parts.  If it is nil, the size is unlimited."
   "A regexp to match the alternative email addresses.
 The first matched address (not primary one) is used in the From field."
   :group 'message-headers
+  :link '(custom-manual "(message)Message Headers")
   :type '(choice (const :tag "Always use primary" nil)
                 regexp))
 
@@ -1532,6 +1604,7 @@ answers yes, reply to all recipients as usual.  If the user answers
 no, only reply back to the author."
   :version "21.3"
   :group 'message-headers
+  :link '(custom-manual "(message)Wide Reply")
   :type 'boolean)
 
 (defcustom message-user-fqdn nil
@@ -1548,6 +1621,7 @@ no, only reply back to the author."
                                 'ask)
   "Whether to encode non-ASCII in domain names into ASCII according to IDNA."
   :group 'message-headers
+  :link '(custom-manual "(message)IDNA")
   :type '(choice (const :tag "Ask" ask)
                 (const :tag "Never" nil)
                 (const :tag "Always" t)))
@@ -2505,6 +2579,7 @@ packages requires these properties to be present in order to work.
 If you use one of these packages, turn this option off, and hope the
 message composition doesn't break too bad."
   :group 'message-various
+  :link '(custom-manual "(message)Various Message Variables")
   :type 'boolean)
 
 (defconst message-forbidden-properties
@@ -5789,6 +5864,7 @@ than 988 characters long, and if they are not, trim them until they are."
   "Whether \\<message-mode-map>\\[message-beginning-of-line]\
  goes to beginning of header values."
   :group 'message-buffers
+  :link '(custom-manual "(message)Movement")
   :type 'boolean)
 
 (defun message-beginning-of-line (&optional n)
@@ -7224,6 +7300,7 @@ which specify the range to operate on."
   "*Function to execute when `message-tab' (TAB) is executed in the body.
 If nil, the function bound in `text-mode-map' or `global-map' is executed."
   :group 'message
+  :link '(custom-manual "(message)Various Commands")
   :type 'function)
 
 (defun message-tab ()