(defun article-make-date-line (date type)
"Return a DATE line of TYPE."
- (let ((time (condition-case ()
- (date-to-time date)
- (error '(0 0)))))
- (cond
- ;; Convert to the local timezone. We have to slap a
- ;; `condition-case' round the calls to the timezone
- ;; functions since they aren't particularly resistant to
- ;; buggy dates.
- ((eq type 'local)
- (let ((tz (car (current-time-zone time))))
- (format "Date: %s %s%02d%02d" (current-time-string time)
- (if (> tz 0) "+" "-") (/ (abs tz) 3600)
- (/ (% (abs tz) 3600) 60))))
- ;; Convert to Universal Time.
- ((eq type 'ut)
- (concat "Date: "
- (current-time-string
- (let* ((e (parse-time-string date))
- (tm (apply 'encode-time e))
- (ms (car tm))
- (ls (- (cadr tm) (car (current-time-zone time)))))
- (cond ((< ls 0) (list (1- ms) (+ ls 65536)))
- ((> ls 65535) (list (1+ ms) (- ls 65536)))
- (t (list ms ls)))))
- " UT"))
- ;; Get the original date from the article.
- ((eq type 'original)
- (concat "Date: " (if (string-match "\n+$" date)
- (substring date 0 (match-beginning 0))
- date)))
- ;; Let the user define the format.
- ((eq type 'user)
- (if (gnus-functionp gnus-article-time-format)
- (funcall gnus-article-time-format time)
- (concat
- "Date: "
- (format-time-string gnus-article-time-format time))))
- ;; ISO 8601.
- ((eq type 'iso8601)
- (let ((tz (car (current-time-zone time))))
- (concat
- "Date: "
- (format-time-string "%Y%m%dT%H%M%S" time)
- (format "%s%02d%02d"
- (if (> tz 0) "+" "-") (/ (abs tz) 3600)
- (/ (% (abs tz) 3600) 60)))))
- ;; Do an X-Sent lapsed format.
- ((eq type 'lapsed)
- ;; If the date is seriously mangled, the timezone functions are
- ;; liable to bug out, so we ignore all errors.
- (let* ((now (current-time))
- (real-time (subtract-time now time))
- (real-sec (and real-time
- (+ (* (float (car real-time)) 65536)
- (cadr real-time))))
- (sec (and real-time (abs real-sec)))
- num prev)
+ (unless (memq type '(local ut original user iso8601 lapsed english))
+ (error "Unknown conversion type: %s" type))
+ (condition-case ()
+ (let ((time (date-to-time date)))
(cond
- ((null real-time)
- "X-Sent: Unknown")
- ((zerop sec)
- "X-Sent: Now")
- (t
- (concat
- "X-Sent: "
- ;; This is a bit convoluted, but basically we go
- ;; through the time units for years, weeks, etc,
- ;; and divide things to see whether that results
- ;; in positive answers.
- (mapconcat
- (lambda (unit)
- (if (zerop (setq num (ffloor (/ sec (cdr unit)))))
- ;; The (remaining) seconds are too few to
- ;; be divided into this time unit.
- ""
- ;; It's big enough, so we output it.
- (setq sec (- sec (* num (cdr unit))))
- (prog1
- (concat (if prev ", " "") (int-to-string
- (floor num))
- " " (symbol-name (car unit))
- (if (> num 1) "s" ""))
- (setq prev t))))
- article-time-units "")
- ;; If dates are odd, then it might appear like the
- ;; article was sent in the future.
- (if (> real-sec 0)
- " ago"
- " in the future"))))))
- ;; Display the date in proper English
- ((eq type 'english)
- (let ((dtime (decode-time time)))
- (concat
- "Date: the "
- (number-to-string (nth 3 dtime))
- (let ((digit (% (nth 3 dtime) 10)))
- (cond
- ((memq (nth 3 dtime) '(11 12 13)) "th")
- ((= digit 1) "st")
- ((= digit 2) "nd")
- ((= digit 3) "rd")
- (t "th")))
- " of "
- (nth (1- (nth 4 dtime)) gnus-english-month-names)
- " "
- (number-to-string (nth 5 dtime))
- " at "
- (format "%02d" (nth 2 dtime))
- ":"
- (format "%02d" (nth 1 dtime)))))
- (t
- (error "Unknown conversion type: %s" type)))))
+ ;; Convert to the local timezone.
+ ((eq type 'local)
+ (let ((tz (car (current-time-zone time))))
+ (format "Date: %s %s%02d%02d" (current-time-string time)
+ (if (> tz 0) "+" "-") (/ (abs tz) 3600)
+ (/ (% (abs tz) 3600) 60))))
+ ;; Convert to Universal Time.
+ ((eq type 'ut)
+ (concat "Date: "
+ (current-time-string
+ (let* ((e (parse-time-string date))
+ (tm (apply 'encode-time e))
+ (ms (car tm))
+ (ls (- (cadr tm) (car (current-time-zone time)))))
+ (cond ((< ls 0) (list (1- ms) (+ ls 65536)))
+ ((> ls 65535) (list (1+ ms) (- ls 65536)))
+ (t (list ms ls)))))
+ " UT"))
+ ;; Get the original date from the article.
+ ((eq type 'original)
+ (concat "Date: " (if (string-match "\n+$" date)
+ (substring date 0 (match-beginning 0))
+ date)))
+ ;; Let the user define the format.
+ ((eq type 'user)
+ (if (gnus-functionp gnus-article-time-format)
+ (funcall gnus-article-time-format time)
+ (concat
+ "Date: "
+ (format-time-string gnus-article-time-format time))))
+ ;; ISO 8601.
+ ((eq type 'iso8601)
+ (let ((tz (car (current-time-zone time))))
+ (concat
+ "Date: "
+ (format-time-string "%Y%m%dT%H%M%S" time)
+ (format "%s%02d%02d"
+ (if (> tz 0) "+" "-") (/ (abs tz) 3600)
+ (/ (% (abs tz) 3600) 60)))))
+ ;; Do an X-Sent lapsed format.
+ ((eq type 'lapsed)
+ ;; If the date is seriously mangled, the timezone functions are
+ ;; liable to bug out, so we ignore all errors.
+ (let* ((now (current-time))
+ (real-time (subtract-time now time))
+ (real-sec (and real-time
+ (+ (* (float (car real-time)) 65536)
+ (cadr real-time))))
+ (sec (and real-time (abs real-sec)))
+ num prev)
+ (cond
+ ((null real-time)
+ "X-Sent: Unknown")
+ ((zerop sec)
+ "X-Sent: Now")
+ (t
+ (concat
+ "X-Sent: "
+ ;; This is a bit convoluted, but basically we go
+ ;; through the time units for years, weeks, etc,
+ ;; and divide things to see whether that results
+ ;; in positive answers.
+ (mapconcat
+ (lambda (unit)
+ (if (zerop (setq num (ffloor (/ sec (cdr unit)))))
+ ;; The (remaining) seconds are too few to
+ ;; be divided into this time unit.
+ ""
+ ;; It's big enough, so we output it.
+ (setq sec (- sec (* num (cdr unit))))
+ (prog1
+ (concat (if prev ", " "") (int-to-string
+ (floor num))
+ " " (symbol-name (car unit))
+ (if (> num 1) "s" ""))
+ (setq prev t))))
+ article-time-units "")
+ ;; If dates are odd, then it might appear like the
+ ;; article was sent in the future.
+ (if (> real-sec 0)
+ " ago"
+ " in the future"))))))
+ ;; Display the date in proper English
+ ((eq type 'english)
+ (let ((dtime (decode-time time)))
+ (concat
+ "Date: the "
+ (number-to-string (nth 3 dtime))
+ (let ((digit (% (nth 3 dtime) 10)))
+ (cond
+ ((memq (nth 3 dtime) '(11 12 13)) "th")
+ ((= digit 1) "st")
+ ((= digit 2) "nd")
+ ((= digit 3) "rd")
+ (t "th")))
+ " of "
+ (nth (1- (nth 4 dtime)) gnus-english-month-names)
+ " "
+ (number-to-string (nth 5 dtime))
+ " at "
+ (format "%02d" (nth 2 dtime))
+ ":"
+ (format "%02d" (nth 1 dtime)))))))
+ (error
+ (format "Date: %s (from Oort)" date))))
(defun article-date-local (&optional highlight)
"Convert the current article date to the local timezone."
\e$B$?$a$N8z2LE*$JJ}K!$G$9!#\e(B
@c FIXTGNUS We should provide MIME manual.
-@c @node MIME
-@c @section MIME
-@c @cindex MML
-@c @cindex MIME
-@c @cindex multipart
-@c @cindex attachment
-
-@c Message is a @sc{mime}-compliant posting agent. The user generally
-@c doesn't have to do anything to make the @sc{mime} happen---Message will
-@c automatically add the @code{Content-Type} and
-@c @code{Content-Transfer-Encoding} headers.
-
-@c The most typical thing users want to use the multipart things in
-@c @sc{mime} for is to add ``attachments'' to mail they send out. This can
-@c be done with the @code{C-c C-a} command, which will prompt for a file
-@c name and a @sc{mime} type.
-
-@c You can also create arbitrarily complex multiparts using the MML
-@c language (@pxref{Composing, , Composing, emacs-mime, The Emacs MIME
-@c Manual}).
-
-@c @node Security
-@c @section Security
-@c @cindex Security
-@c @cindex S/MIME
-@c @cindex PGP/MIME
-@c @cindex sign
-@c @cindex encrypt
-
-@c Using the MML language, Message is able to create digitally signed and
-@c digitally encrypted messages. Message (or rather MML) currently support
-@c PGP/MIME and S/MIME. Instructing MML to perform security operations on
-@c a MIME part is done using the @code{C-c C-m s} key map for signing and the
-@c @code{C-c C-m c} key map for encryption, as follows.
-
-@c @table @kbd
-
-@c @item C-c C-m s s
-@c @kindex C-c C-m s s
-@c @findex mml-secure-sign-smime
-
-@c Digitally sign current MIME part using S/MIME.
+@ignore
+@node MIME
+@section MIME
+@cindex MML
+@cindex MIME
+@cindex multipart
+@cindex attachment
+
+Message is a @sc{mime}-compliant posting agent. The user generally
+doesn't have to do anything to make the @sc{mime} happen---Message will
+automatically add the @code{Content-Type} and
+@code{Content-Transfer-Encoding} headers.
+
+The most typical thing users want to use the multipart things in
+@sc{mime} for is to add ``attachments'' to mail they send out. This can
+be done with the @code{C-c C-a} command, which will prompt for a file
+name and a @sc{mime} type.
+
+You can also create arbitrarily complex multiparts using the MML
+language (@pxref{Composing, , Composing, emacs-mime, The Emacs MIME
+Manual}).
+
+@node Security
+@section Security
+@cindex Security
+@cindex S/MIME
+@cindex PGP/MIME
+@cindex sign
+@cindex encrypt
+
+Using the MML language, Message is able to create digitally signed and
+digitally encrypted messages. Message (or rather MML) currently support
+PGP/MIME and S/MIME. Instructing MML to perform security operations on
+a MIME part is done using the @code{C-c C-m s} key map for signing and the
+@code{C-c C-m c} key map for encryption, as follows.
+
+@table @kbd
+
+@item C-c C-m s s
+@kindex C-c C-m s s
+@findex mml-secure-sign-smime
+
+Digitally sign current MIME part using S/MIME.
@item C-c C-m s p
@kindex C-c C-m s p
-@c @findex mml-secure-sign-pgp
+@findex mml-secure-sign-pgp
-@c Digitally sign current MIME part using PGP/MIME.
+Digitally sign current MIME part using PGP/MIME.
@item C-c C-m c s
@kindex C-c C-m c s
-@c @findex mml-secure-encrypt-smime
+@findex mml-secure-encrypt-smime
-@c Digitally encrypt current MIME part using S/MIME.
+Digitally encrypt current MIME part using S/MIME.
@item C-c C-m c p
@kindex C-c C-m c p
-@c @findex mml-secure-encrypt-pgpmime
-
-@c Digitally encrypt current MIME part using PGP/MIME.
-
-@c @end table
-
-@c These commands do not immediately sign or encrypt the message, they
-@c merely insert proper MML tags to instruct the MML engine to perform that
-@c operation when the message is actually sent. They may perform other
-@c operations too, such as locating and retrieving a S/MIME certificate of
-@c the person you wish to send encrypted mail to.
-
-@c Since signing and especially encryption often is used when sensitive
-@c information is sent, you may want to have some way to ensure that your
-@c mail is actually signed or encrypted. After invoking the above
-@c sign/encrypt commands, it is possible to preview the raw article by
-@c using @code{C-u C-m P} (@code{mml-preview}). Then you can verify that
-@c your long rant about what your ex-significant other or whomever actually
-@c did with that funny looking person at that strange party the other
-@c night, actually will be sent encrypted.
-
-@c @emph{Note!} Neither PGP/MIME nor S/MIME encrypt/signs RFC822 headers.
-@c They only operate on the MIME object. Keep this in mind before sending
-@c mail with a sensitive Subject line.
-
-@c Actually using the security commands above is not very difficult. At
-@c least not compared with making sure all involved programs talk with each
-@c other properly. Thus, we now describe what external libraries or
-@c programs are required to make things work, and some small general hints.
-
-@c @subsection Using S/MIME
-
-@c @emph{Note!} This section assume you have a basic familiarity with
-@c modern cryptography, S/MIME, various PKCS standards, OpenSSL and so on.
-
-@c The S/MIME support in Message (and MML) require OpenSSL. OpenSSL
-@c perform the actual S/MIME sign/encrypt operations. OpenSSL can be found
-@c at @code{http://www.openssl.org/}. OpenSSL 0.9.6 and later should work.
-@c Version 0.9.5a cannot extract mail addresses from certificates, and it
-@c insert a spurious CR character into MIME separators so you may wish to
-@c avoid it if you would like to avoid being regarded as someone who send
-@c strange mail. (Although by sending S/MIME messages you've probably
-@c already lost that contest.)
-
-@c To be able to send encrypted mail, a personal certificate is not
-@c required. Message (MML) need a certificate for the person to whom you
-@c wish to communicate with though. You're asked for this when you type
-@c @code{C-c C-m c s}. Currently there are two ways to retrieve this
-@c certificate, from a local file or from DNS. If you chose a local file,
-@c it need to contain a X.509 certificate in PEM format. If you chose DNS,
-@c you're asked for the domain name where the certificate is stored, the
-@c default is a good guess. To my belief, Message (MML) is the first mail
-@c agent in the world to support retrieving S/MIME certificates from DNS,
-@c so you're not likely to find very many certificates out there. At least
-@c there should be one, stored at the domain @code{simon.josefsson.org}.
-@c LDAP is a more popular method of distributing certificates, support for
-@c it is planned. (Meanwhile, you can use @code{ldapsearch} from the
-@c command line to retrieve a certificate into a file and use it.)
-
-@c As for signing messages, OpenSSL can't perform signing operations
-@c without some kind of configuration. Especially, you need to tell it
-@c where your private key and your certificate is stored. MML uses an
-@c Emacs interface to OpenSSL, aptly named @code{smime.el}, and it contain
-@c a @code{custom} group used for this configuration. So, try @code{M-x
-@c customize-group RET smime RET} and look around.
-
-@c Currently there is no support for talking to a CA (or RA) to create your
-@c own certificate. None is planned either. You need to do this manually
-@c with OpenSSL or using some other program. I used Netscape and got a
-@c free S/MIME certificate from one of the big CA's on the net. Netscape
-@c is able to export your private key and certificate in PKCS #12 format.
-@c Use OpenSSL to convert this into a plain X.509 certificate in PEM format
-@c as follows.
-
-@c @example
-@c $ openssl pkcs12 -in ns.p12 -clcerts -nodes > key+cert.pem
-@c @end example
-
-@c The @code{key+cert.pem} file should be pointed to from the
-@c @code{smime-keys} variable. You should now be able to send signed mail.
-
-@c @emph{Note!} Your private key is store unencrypted in the file, so take
-@c care in handling it.
-
-@c @subsection Using PGP/MIME
-
-@c PGP/MIME require an external OpenPGP implementation, such as GNU Privacy
-@c Guard (@code{http://www.gnupg.org/}. It also require a Emacs interface
-@c to it, such as Mailcrypt (available from
-@c @code{http://www.nb.net/~lbudney/linux/software/mailcrypt.html}) or
-@c Florian Weimer's @code{gpg.el}.
-
-@c Creating your own OpenPGP key is described in detail in the
-@c documentation of your OpenPGP implementation, so we refer to it.
+@findex mml-secure-encrypt-pgpmime
+
+Digitally encrypt current MIME part using PGP/MIME.
+
+@end table
+
+These commands do not immediately sign or encrypt the message, they
+merely insert proper MML tags to instruct the MML engine to perform that
+operation when the message is actually sent. They may perform other
+operations too, such as locating and retrieving a S/MIME certificate of
+the person you wish to send encrypted mail to.
+
+Since signing and especially encryption often is used when sensitive
+information is sent, you may want to have some way to ensure that your
+mail is actually signed or encrypted. After invoking the above
+sign/encrypt commands, it is possible to preview the raw article by
+using @code{C-u C-m P} (@code{mml-preview}). Then you can verify that
+your long rant about what your ex-significant other or whomever actually
+did with that funny looking person at that strange party the other
+night, actually will be sent encrypted.
+
+@emph{Note!} Neither PGP/MIME nor S/MIME encrypt/signs RFC822 headers.
+They only operate on the MIME object. Keep this in mind before sending
+mail with a sensitive Subject line.
+
+Actually using the security commands above is not very difficult. At
+least not compared with making sure all involved programs talk with each
+other properly. Thus, we now describe what external libraries or
+programs are required to make things work, and some small general hints.
+
+@subsection Using S/MIME
+
+@emph{Note!} This section assume you have a basic familiarity with
+modern cryptography, S/MIME, various PKCS standards, OpenSSL and so on.
+
+The S/MIME support in Message (and MML) require OpenSSL. OpenSSL
+perform the actual S/MIME sign/encrypt operations. OpenSSL can be found
+at @code{http://www.openssl.org/}. OpenSSL 0.9.6 and later should work.
+Version 0.9.5a cannot extract mail addresses from certificates, and it
+insert a spurious CR character into MIME separators so you may wish to
+avoid it if you would like to avoid being regarded as someone who send
+strange mail. (Although by sending S/MIME messages you've probably
+already lost that contest.)
+
+To be able to send encrypted mail, a personal certificate is not
+required. Message (MML) need a certificate for the person to whom you
+wish to communicate with though. You're asked for this when you type
+@code{C-c C-m c s}. Currently there are two ways to retrieve this
+certificate, from a local file or from DNS. If you chose a local file,
+it need to contain a X.509 certificate in PEM format. If you chose DNS,
+you're asked for the domain name where the certificate is stored, the
+default is a good guess. To my belief, Message (MML) is the first mail
+agent in the world to support retrieving S/MIME certificates from DNS,
+so you're not likely to find very many certificates out there. At least
+there should be one, stored at the domain @code{simon.josefsson.org}.
+LDAP is a more popular method of distributing certificates, support for
+it is planned. (Meanwhile, you can use @code{ldapsearch} from the
+command line to retrieve a certificate into a file and use it.)
+
+As for signing messages, OpenSSL can't perform signing operations
+without some kind of configuration. Especially, you need to tell it
+where your private key and your certificate is stored. MML uses an
+Emacs interface to OpenSSL, aptly named @code{smime.el}, and it contain
+a @code{custom} group used for this configuration. So, try @code{M-x
+customize-group RET smime RET} and look around.
+
+Currently there is no support for talking to a CA (or RA) to create your
+own certificate. None is planned either. You need to do this manually
+with OpenSSL or using some other program. I used Netscape and got a
+free S/MIME certificate from one of the big CA's on the net. Netscape
+is able to export your private key and certificate in PKCS #12 format.
+Use OpenSSL to convert this into a plain X.509 certificate in PEM format
+as follows.
+
+@example
+$ openssl pkcs12 -in ns.p12 -clcerts -nodes > key+cert.pem
+@end example
+
+The @code{key+cert.pem} file should be pointed to from the
+@code{smime-keys} variable. You should now be able to send signed mail.
+
+@emph{Note!} Your private key is store unencrypted in the file, so take
+care in handling it.
+
+@subsection Using PGP/MIME
+PGP/MIME require an external OpenPGP implementation, such as GNU Privacy
+Guard (@code{http://www.gnupg.org/}. It also require a Emacs interface
+to it, such as Mailcrypt (available from
+@code{http://www.nb.net/~lbudney/linux/software/mailcrypt.html}) or
+Florian Weimer's @code{gpg.el}.
+
+Creating your own OpenPGP key is described in detail in the
+documentation of your OpenPGP implementation, so we refer to it.
+
+@end ignore
@node Various Commands
@section \e$B$$$m$$$m$JL?Na\e(B
@item message-generate-headers-first
@vindex message-generate-headers-first
-@code{nil} \e$B$G$J$1$l$P!"%a%C%;!<%8$N:n@.$r;O$a$kA0$KA4$F$N%X%C%@!<$r:n@.\e(B
-\e$B$7$^$9!#\e(B
+@code{nil} \e$B$G$J$1$l$P!"%a%C%;!<%8$N:n@.$r;O$a$kA0$KA4$F$NI,MW$J%X%C%@!<\e(B
+\e$B$r:n@.$7$^$9!#\e(B
+
+\e$BJQ?t\e(B @code{message-required-mail-headers} \e$B$H\e(B @code{message-required-news-headers} \e$B$G!"\e(B
+\e$B$I$N%X%C%@!<$,I,MW$+$r;XDj$7$^$9!#\e(B
@item message-from-style
@vindex message-from-style