T-gnus 6.15.7 revision 00. t-gnus-6_15_7-00
authoryamaoka <yamaoka>
Tue, 6 Aug 2002 13:45:57 +0000 (13:45 +0000)
committeryamaoka <yamaoka>
Tue, 6 Aug 2002 13:45:57 +0000 (13:45 +0000)
67 files changed:
ChangeLog
GNUS-NEWS
README.T-gnus
contrib/ChangeLog
contrib/hashcash.el [new file with mode: 0644]
lisp/ChangeLog
lisp/dns.el
lisp/flow-fill.el
lisp/gnus-agent.el
lisp/gnus-art.el
lisp/gnus-cache.el
lisp/gnus-cite.el
lisp/gnus-delay.el
lisp/gnus-ems.el
lisp/gnus-fun.el
lisp/gnus-group.el
lisp/gnus-int.el
lisp/gnus-logic.el
lisp/gnus-msg.el
lisp/gnus-namazu.el
lisp/gnus-salt.el
lisp/gnus-sieve.el
lisp/gnus-start.el
lisp/gnus-sum.el
lisp/gnus-topic.el
lisp/gnus-vers.el
lisp/gnus.el
lisp/mail-source.el
lisp/message.el
lisp/mm-decode.el
lisp/mm-encode.el
lisp/mm-url.el
lisp/mm-util.el
lisp/mm-view.el
lisp/mml-sec.el
lisp/mml.el
lisp/mml1991.el
lisp/mml2015.el
lisp/nnbabyl.el
lisp/nndiary.el
lisp/nndoc.el
lisp/nnfolder.el
lisp/nnheader.el
lisp/nnimap.el
lisp/nnmail.el
lisp/nnmaildir.el
lisp/nnmbox.el
lisp/nnmh.el
lisp/nnml.el
lisp/nnrss.el
lisp/nnslashdot.el
lisp/nnsoup.el
lisp/nntp.el
lisp/nnweb.el
lisp/sieve-manage.el
lisp/sieve-mode.el
lisp/sieve.el
lisp/spam.el
lisp/starttls.el
texi/ChangeLog
texi/Makefile.in
texi/emacs-mime.texi
texi/gnus-ja.texi
texi/gnus.texi
texi/message-ja.texi
texi/message.texi
texi/sieve.texi

index bd21efb..dca2ee2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,85 @@
+2002-08-06  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * lisp/gnus-vers.el: T-gnus 6.15.7 revision 00.
+
+2002-08-06  TSUCHIYA Masatoshi  <tsuchiya@namazu.org>
+
+       * lisp/gnus-namazu.el (gnus-namazu-update-index): Handle error
+       messages printed by Namazu.
+       (gnus-namazu/update-sentinel): Likewise.
+       (gnus-namazu-need-path-normalization): Change its default value.
+       (gnus-namazu/normalize-results): Remove `file://' prefix.
+
+       * texi/gnus-ja.texi (Namazu Groups): Update documents.
+
+       * lisp/gnus-namazu.el (gnus-namazu/update-p): Print error
+       messages.
+       (gnus-namazu-update-index): Small clean up.
+       (gnus-namazu-update-all-indices): Ditto.
+
+2002-08-05  TSUCHIYA Masatoshi  <tsuchiya@namazu.org>
+
+       * lisp/gnus-namazu.el: Bug fix of updating multiple indices.
+       (gnus-namazu/setup): Call `gnus-namazu-update-all-indices' without
+       arguments.
+       (gnus-namazu-create-index): Clean temporary files even if an
+       indexer is killed.
+       (gnus-namazu/update-p): New function.
+       (gnus-namazu-update-all-indices): Reimplemented.
+       (gnus-namazu-update-index): Call `gnus-namazu/update-p' to decide
+       whether the specified index will be updated.
+       (gnus-namazu/update-sentinel): Follow the change of
+       `gnus-namazu-update-all-indices'.
+
+2002-08-05  TSUCHIYA Masatoshi  <tsuchiya@namazu.org>
+
+       * lisp/gnus.el (toplevel): Add autoloads for
+       `gnus-namazu-create-index', and `gnus-namazu-update-all-indices'
+       and `gnus-namazu-update-index'.
+
+       * lisp/gnus-namazu.el: Support automatically updating multiple
+       indices.
+       (gnus-namazu-make-index-interval): Abolished.
+       (gnus-namazu-index-update-interval): New option.
+       (gnus-namazu/setup): Call `gnus-namazu-update-all-indices' instead
+       of `gnus-namazu-make-index'.
+       (gnus-namazu/mknmz-process): Abolished.
+       (gnus-namazu/status-file-name): New macro.
+       (gnus-namazu-make-index, gnus-namazu-make-index-stop,
+       gnus-namazu/mknmz-sentinel): Removed.
+       (gnus-namazu/mknmz-cleanup, gnus-namazu/index-old-p): New function.
+       (gnus-namazu-create-index, gnus-namazu-update-all-indices,
+       gnus-namazu-update-index, gnus-namazu-stop-update): New command.
+       (gnus-namazu/update-directories, gnus-namazu/update-process): New
+       internal variable.
+
+2002-07-31  TSUCHIYA Masatoshi  <tsuchiya@namazu.org>
+
+       * lisp/gnus-namazu.el: Support automatically updating index.
+       (gnus-namazu-default-index-directory): New constant.
+       (gnus-namazu-make-index-interval, gnus-namazu-make-index-command,
+       gnus-namazu-make-index-arguments): New options.
+       (gnus-namazu/setup): Call `gnus-namazu-make-index'.
+       (gnus-namazu/real-group-name): Renamed from
+       `gnus-namazu/check-cache-group'.
+       (gnus-namazu/cache-group-candidates): Renamed from
+       `gnus-namazu/cache-group-candidates'.
+       (gnus-namazu/search): Experimental support of articles covered by
+       agent.
+       (gnus-namazu/default-index-directory, gnus-namazu/lapse-seconds,
+       gnus-namazu/mknmz-sentinel): New internal functions.
+       (gnus-namazu/mknmz-process): New internal variable.
+       (gnus-namazu/lock-file-name, gnus-namazu/index-file-name): New
+       macros.
+       (gnus-namazu-make-index, gnus-namazu-make-index-stop): New
+       commands.
+
+2002-07-30  TSUCHIYA Masatoshi  <tsuchiya@namazu.org>
+
+       * lisp/gnus-namazu.el (gnus-namazu/request-list): Removed.
+       (gnus-namazu/get-current-to): New function.
+       (gnus-namazu/complete-query): Call the above.
+
 2002-07-19  Katsumi Yamaoka  <yamaoka@jpl.org>
 
        * lisp/pop3.el: Don't autoload "ssl".
        * lisp/gnus-namazu.el (gnus-namazu/truncate-article-list): Remove
        a redundancy.
 
-2002-06-25  TSUCHIYA Masatoshi  <tsuchiya@namazu.org>
+2002-07-11  TSUCHIYA Masatoshi  <tsuchiya@namazu.org>
 
-       * lisp/gnus-namazu.el (gnus-namazu/truncate-article-list): When
-       `gnus-large-newsgroup' is equal to nil, no confirmation is
-       required.
+       * texi/gnus-ja.texi (Web Newspaper): Update the url of w3m.
+
+2002-07-05  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * lisp/gnus-sum.el (gnus-summary-mode-map): Replace
+       `gnus-article-toggle-headers' with `gnus-summary-toggle-header'.
+       (gnus-summary-wash-map): Ditto.
+       (gnus-summary-wash-hide-map): Replace
+       `gnus-article-toggle-headers' with `gnus-article-hide-headers'.
+       (gnus-summary-article-menu): Ditto.
+
+       * lisp/gnus.el: Remove autoload for `gnus-article-toggle-headers'.
+
+       * lisp/gnus-art.el (article-toggle-headers): Abolished.
 
 2002-07-04  Katsumi Yamaoka  <yamaoka@jpl.org>
 
        workaround I installed on 1999-12-28, i.e. also call
        `as-binary-process' in windows-nt.
 
+2002-06-26  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * contrib/hashcash.el: Require `cl' when compiling.
+       (hashcash-strip-quoted-names): Replace `subseq' with `substring'.
+       (mail-add-payment): Allow no `mail-header-separator' in the buffer;
+       don't use `mapc'.
+
+2002-06-25  TSUCHIYA Masatoshi  <tsuchiya@namazu.org>
+
+       * lisp/gnus-namazu.el (gnus-namazu/truncate-article-list): When
+       `gnus-large-newsgroup' is equal to nil, no confirmation is
+       required.
+
 2002-06-23  Tetsuo Tsukamoto  <czkmt@remus.dti.ne.jp>
 
        * lisp/pop3.el (pop3-open-ssl-stream): Do away with w32-related
        workaround I installed on 1999-12-27, i.e. also call
        `as-binary-process' in windows-nt.
 
+2002-06-12  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * lisp/message.el (message-send): Kill `message-encoding-buffer'
+       even if sending failed.
+
 2002-06-11  Katsumi Yamaoka  <yamaoka@jpl.org>
 
        * lisp/gnus-vers.el (gnus-revision-number): Increment to 02.
        `gnus-message-setup-hook'.
        (gnus-summary-resend-bounced-mail): Ditto.
 
+       * lisp/dns.el (dns-make-network-process): Bind
+       `default-process-coding-system' to `(binary . binary)'; bind
+       `program-coding-system-alist' to nil.
+
+       * lisp/gnus-fun.el (gnus-convert-gray-x-face-to-xpm): Bind
+       `input-coding-system' and `output-coding-system' to `binary'.
+
+       * lisp/gnus-namazu.el (gnus-namazu/call-namazu): Bind
+       `input-coding-system' and `output-coding-system' to the velue of
+       `gnus-namazu-coding-system'.
+
+       * lisp/imap.el (imap-ssl-open): Don't bind the values for
+       `input-coding-system' and `output-coding-system'.
+
+       * lisp/nnmaildir.el (nnmaildir-request-scan): Bind
+       `output-coding-system' to the value of
+       `nnheader-file-coding-system'; bind `file-coding-system' to nil.
+       (nnmaildir-request-rename-group): Ditto.
+       (nnmaildir-request-replace-article): Ditto.
+       (nnmaildir-request-accept-article): Ditto.
+       (nnmaildir-request-set-mark): Ditto.
+
+       * lisp/nnmbox.el (nnmbox-save-buffer): Simplify the source code.
+
+       * lisp/nnrss.el (nnrss-read-server-data): Bind
+       `input-coding-system' to `binary'.
+       (nnrss-save-server-data): Bind `output-coding-system' to `binary'.
+       (nnrss-read-group-data): Bind `input-coding-system' to `binary'.
+       (nnrss-save-group-data): Bind `output-coding-system' to `binary'.
+
 2002-06-07  Katsumi Yamaoka  <yamaoka@jpl.org>
 
        * lisp/pop3.el: Add a comment for the use of `ssl' or `tls'
 
        * contrib/gpg-ring.el: Remove RCS magic cookie.
        * lisp/nnir.el: Ditto.
-       * lisp/sieve-manage.el: Ditto.
-       * lisp/sieve-mode.el: Ditto.
 
        * texi/ptexinfmt.el (texinfo-discard-command-and-arg): New
        function.
        2.3.  Support @., @:, @-.
        (texinfo-format-inforef): New function.
 
+2002-05-30  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * lisp/nnheader.el (nnheader-unfold-fws): New function copied from
+       `ietf-drums-unfold-fws'.
+       (ietf-drums-unfold-fws): Alias to `nnheader-unfold-fws'.
+
 2002-04-30  Daiki Ueno  <ueno@unixuser.org>
 
        * lisp/message.el (message-expand-name-function): New user option.
index 83e5448..ea07a21 100644 (file)
--- a/GNUS-NEWS
+++ b/GNUS-NEWS
@@ -8,6 +8,16 @@ For older news, see Gnus info node "New Features".
 \f
 * Changes in Oort Gnus
 
+** gnus-agent
+
+The Gnus Agent is now enabled by default.  This means that, e.g.,
+headers are not downloaded from agentized servers by default (agentize
+servers by using `J a' in the server buffer).  Gnus will not start to
+download articles unless you instruct it to do so, though, by using
+e.g. J u or J s from the group buffer.  Revert to the old behaviour
+with `(setq gnus-agent nil)'.  Note that putting (gnus-agentize) in
+~/.gnus is not needed any more.
+
 ** gnus-summary-line-format
 
 The default value changed to "%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n".
@@ -173,8 +183,8 @@ variables should change those regexps accordingly. For example:
 
    ("^han\\>" euc-kr) -> ("\\(^\\|:\\)han\\>" euc-kr)
 
-** Gnus supports PGP (RFC 1991/2440), PGP-MIME (RFC 2015/3156) and
-SMIME.
+** Gnus supports PGP (RFC 1991/2440), PGP/MIME (RFC 2015/3156) and
+S/MIME (RFC 2630-2633).
 
 ** Gnus inlines external parts (message/external).
 
index de5137f..9a7b903 100644 (file)
@@ -33,6 +33,6 @@ NEWS:
 
 * T-gnus 6.15 - this is based on Oort Gnus.
 
-  The latest T-gnus is T-gnus 6.15.6 (based on Oort Gnus 0.06).  It
+  The latest T-gnus is T-gnus 6.15.7 (based on Oort Gnus 0.07).  It
   requires SEMI/WEMI (1.13.5 or later), FLIM (1.13.1 or later), and
   APEL (10.0 or later).
index f894e17..124ce41 100644 (file)
@@ -1,3 +1,21 @@
+2002-06-22  Simon Josefsson  <jas@extundo.com>
+
+       * hashcash.el: New file.
+       (hashcash-default-payment, hashcash-payment-alist, hashcash):
+       Defcustom.
+       (hashcash-generate-payment): Update to recent hashcode command
+       line syntax.
+       (hashcash-insert-payment): Use X-Hashcode:.
+       (mail-add-payment): Also look at Newsgroups.
+       (top-level): Add provide and EOF comment.
+       (mail-add-payment): Autoload.
+       (hashcash-insert-payment): s/Hashcode/Hashcash/
+       (mail-add-payment): Doc fix.
+
+2002-05-20  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-mdrtn.el (gnus-moderated-groups): Removed (require 'gnus-load).
+
 2002-04-24  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * ucs-tables.el (featurep): Barf on XEmacs.
diff --git a/contrib/hashcash.el b/contrib/hashcash.el
new file mode 100644 (file)
index 0000000..ccdd314
--- /dev/null
@@ -0,0 +1,120 @@
+;;; hashcash.el --- Add hashcash payments to email
+
+;; $Revision: 1.1.4.1 $
+;; Copyright (C) 1997,2001 Paul E. Foley
+
+;; Maintainer: Paul Foley <mycroft@actrix.gen.nz>
+;; Keywords: mail, hashcash
+
+;; Released under the GNU General Public License
+
+;;; Commentary:
+
+;; The hashcash binary is at http://www.cypherspace.org/hashcash/
+;;
+;; Call mail-add-payment to add a hashcash payment to a mail message
+;; in the current buffer.
+;;
+;; To automatically add payments to all outgoing mail:
+;;    (add-hook 'message-send-hook 'mail-add-payment)
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+(defcustom hashcash-default-payment 0
+  "*The default number of bits to pay to unknown users.
+If this is zero, no payment header will be generated.
+See `hashcash-payment-alist'."
+  :type 'integer)
+
+(defcustom hashcash-payment-alist nil
+  "*An association list mapping email addresses to payment amounts.
+Elements may consist of (ADDR AMOUNT) or (ADDR STRING AMOUNT), where
+ADDR is the email address of the intended recipient and AMOUNT is
+the value of hashcash payment to be made to that user.  STRING, if
+present, is the string to be hashed; if not present ADDR will be used.")
+
+(defcustom hashcash "hashcash"
+  "*The path to the hashcash binary.")
+
+(require 'mail-utils)
+
+(defun hashcash-strip-quoted-names (addr)
+  (setq addr (mail-strip-quoted-names addr))
+  (if (and addr (string-match "^[^+@]+\\(\\+[^@]*\\)@" addr))
+      (concat (substring addr 0 (match-beginning 1))
+             (substring addr (match-end 1)))
+    addr))
+
+(defun hashcash-payment-required (addr)
+  "Return the hashcash payment value required for the given address."
+  (let ((val (assoc addr hashcash-payment-alist)))
+    (if val
+       (if (cddr val)
+           (caddr val)
+         (cadr val))
+      hashcash-default-payment)))
+
+(defun hashcash-payment-to (addr)
+  "Return the string with which hashcash payments should collide."
+  (let ((val (assoc addr hashcash-payment-alist)))
+    (if val
+       (if (cddr val)
+           (cadr val)
+         (car val))
+      addr)))
+
+(defun hashcash-generate-payment (str val)
+  "Generate a hashcash payment by finding a VAL-bit collison on STR."
+  (if (> val 0)
+      (save-excursion
+       (set-buffer (get-buffer-create " *hashcash*"))
+       (erase-buffer)
+       (call-process hashcash nil t nil (concat "-b " (number-to-string val))
+                     str)
+       (goto-char (point-min))
+       (buffer-substring (point-at-bol) (point-at-eol)))
+    nil))
+
+(defun hashcash-insert-payment (arg)
+  "Insert an X-Hashcash header with a payment for ARG"
+  (interactive "sPay to: ")
+  (let ((pay (hashcash-generate-payment (hashcash-payment-to arg)
+                                       (hashcash-payment-required arg))))
+    (when pay
+      (insert-before-markers "X-Hashcash: " pay "\n"))))
+
+;;;###autoload
+(defun mail-add-payment (&optional arg)
+  "Add an X-Hashcash: header with a hashcash payment for each recipient address
+Prefix arg sets default payment temporarily."
+  (interactive "P")
+  (let ((hashcash-default-payment (if arg (prefix-numeric-value arg)
+                                   hashcash-default-payment))
+       (addrlist nil))
+    (save-excursion
+      (save-restriction
+       (goto-char (point-min))
+       (re-search-forward (concat "^\\("
+                                  (regexp-quote mail-header-separator)
+                                  "\\)?$"))
+       (beginning-of-line)
+       (narrow-to-region (point-min) (point))
+       (let ((to (hashcash-strip-quoted-names (mail-fetch-field "To" nil t)))
+             (cc (hashcash-strip-quoted-names (mail-fetch-field "Cc" nil t)))
+             (ng (hashcash-strip-quoted-names
+                  (mail-fetch-field "Newsgroups" nil t))))
+         (when to
+           (setq addrlist (split-string to ",[ \t\n]*")))
+         (when cc
+           (setq addrlist (nconc addrlist (split-string cc ",[ \t\n]*"))))
+         (when ng
+           (setq addrlist (nconc addrlist (split-string ng ",[ \t\n]*")))))
+       (while addrlist
+         (hashcash-insert-payment (pop addrlist))))))
+  t)
+
+(provide 'hashcash)
+
+;;; hashcash.el ends here
index 452beb9..ec6c07f 100644 (file)
@@ -1,3 +1,536 @@
+2002-08-04 01:48:57 Lars Magne Ingebrigtsen <lars@ingebrigtsen.no>
+
+       * gnus.el: Oort Gnus v0.07 is released.
+
+2002-08-04  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-sum.el (gnus-thread-sort-functions): Doc fix.
+       (gnus-article-sort-functions): Doc fix.
+       (t): New keystroke.
+       (gnus-article-sort-by-random): New function.
+       (gnus-thread-sort-by-random): New function.
+
+2002-08-02  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-logic.el (gnus-advanced-integer): Swap arguments in
+       funcall.  From Scott A Crosby <scrosby@cs.rice.edu>.
+
+2002-07-31  Danny Siu  <dsiu@adobe.com>
+
+       * nnimap.el (nnimap-split-articles): do not call nnmail-fetch-field 
+       when splitting malformed messages without message-id
+
+2002-07-28  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+       From Niklas Morberg <niklas.morberg@axis.com>.
+
+       * nnweb.el (nnweb-type, nnweb-type-definition)
+       (nnweb-gmane-create-mapping, nnweb-gmane-wash-article)
+       (nnweb-gmane-search, nnweb-gmane-identity): Added gmane
+       functionality.
+       * nnweb.el: Removed old non-functioning search engines.
+
+2002-07-27  Simon Josefsson  <jas@extundo.com>
+
+       * message.el (message-forward-make-body): Don't use
+       `message-forward-ignored-headers' when doing a "raw" followup (it
+       is important to preserve e.g. CTE).
+
+       * flow-fill.el (fill-flowed): Disable filladapt-mode.
+
+       * gnus-sieve.el (gnus-sieve-guess-rule-for-article): Don't
+       regexp-quote, Cyrus Sieve is fixed.
+
+       * sieve-manage.el (sieve-manage-deletescript): New function.
+
+       * sieve.el (sieve-manage-mode-map): Fix down-mouse-2 and down-mouse-3.  
+       (sieve-manage-mode): Fix menubar.
+       (sieve-activate): Change some messages.
+       (sieve-deactivate-all): New function.
+       (sieve-deactivate): New alias.
+       (sieve-remove): New function.
+       (sieve-help): Fix help.
+       All suggested by Ned Ludd.
+
+2002-07-24  Katsumi Yamaoka <yamaoka@jpl.org>
+
+       * mm-decode.el (mm-inline-text-html-with-images): Doc fix.
+       (mm-w3m-safe-url-regexp): New user option.
+
+       * mm-view.el (mm-inline-text-html-render-with-w3m): Use
+       `mm-w3m-safe-url-regexp' to bind `w3m-safe-url-regexp'.
+
+2002-07-23  Karl Kleinpaste  <karl@charcoal.com>
+
+       * gnus-sum.el (gnus-summary-delete-article): Force
+       nnmail-expiry-target to 'delete, so that absolute deletion
+       happens when absolute deletion is requested.
+
+2002-07-21  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+       From Nevin Kapur <nevin@jhu.edu>.
+
+       * nnmail.el (nnmail-fancy-expiry-target): Treat nonexisting
+       headers as empty headers.
+
+2002-07-21  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+       From Jochen Hein <jochen@jochen.org>.
+
+       * gnus-art.el (gnus-emphasis-alist): Add strikethrough and
+       correct typo.
+       (gnus-emphasis-strikethru): New face.
+
+2002-07-20  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+       From Jason Merrill <jason@redhat.com>.
+
+       * nnfolder.el (nnfolder-retrieve-headers): Avoid searching the
+       entire file for each of a sequence of missing articles.
+
+       * gnus-salt.el (gnus-binary-display-article): Respect an existing
+       value for gnus-view-pseudos.
+
+       * gnus-sum.el (gnus-summary-insert-new-articles): Count down to
+       avoid nreverse.
+
+2002-07-14  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+       From Ted Zlatanov <teodor.zlatanov@divine.com>.
+
+       * gnus-sum.el (gnus-auto-expirable-marks): Remove `spam'.
+       (gnus-summary-mode-line-format-alist): Add %h for number of
+       spams.
+       (gnus-newsgroup-spam-marked): New variable.
+       (gnus-summary-local-variables): Add gnus-newsgroup-spam-marked.
+       (gnus-article-read-p, gnus-article-mark)
+       (gnus-set-global-variables, gnus-set-global-variables)
+       (gnus-article-marked-p, gnus-summary-mark-article-as-read)
+       (gnus-summary-mark-article-as-unread)
+       (gnus-summary-mark-article-as-unread, gnus-summary-mark-article)
+       (gnus-mark-article-as-read, gnus-mark-article-as-unread)
+       (gnus-mark-article-as-unread, gnus-summary-catchup): Grok spam.
+
+2002-07-10  Simon Josefsson  <jas@extundo.com>
+
+       * nnimap.el (nnimap-split-to-groups): Allow group string to be a
+       function.  From KANEMATSU Daiji <kdaiji@bea.com>.
+
+2002-07-09  Nevin Kapur  <Nevin Kapur <nevin@jhu.edu>
+
+       * gnus-sum.el (gnus-summary-delete-article): Respect group
+       parameters while expiring.
+
+2002-07-08  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-art.el (article-make-date-line): Fix string.  From Henrik
+       Enberg.
+
+2002-07-08  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus-art.el (article-unsplit-urls): Only display MIME when this
+       function is called interactively.  From Niklas Morberg.
+
+2002-07-06  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * gnus-topic.el (gnus-topic-indent, gnus-topic-unindent): Change
+       cdaar to cdar and car.
+
+       * nnsoup.el (nnsoup-retrieve-headers, nnsoup-request-type)
+       (nnsoup-read-active-file, nnsoup-article-to-area): Ditto.
+
+2002-07-05  Katsumi Yamaoka <yamaoka@jpl.org>
+
+       * gnus-sum.el (gnus-summary-toggle-header): Show headers anyway;
+       don't break a narrowed article.
+
+       * nntp.el (nntp-via-rlogin-command-switches): Doc fix.
+       (nntp-open-via-rlogin-and-telnet): Ditto.
+
+2002-07-02  Didier Verna  <didier@xemacs.org>
+
+       * nnmail.el (nnmail-split-methods): fix custom type.
+
+2002-07-02  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus-art.el (article-unsplit-urls): Keep URL buttonized after
+       unsplitting.  From Niklas Morberg <niklas.morberg@axis.com>.
+
+2002-07-01  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus-msg.el (gnus-summary-resend-default-address): New user option.
+       (gnus-summary-resend-message): Use it.
+
+2002-06-28  Katsumi Yamaoka <yamaoka@jpl.org>
+
+       * nntp.el (nntp-via-rlogin-command-switches): New variable.
+       (nntp-open-via-rlogin-and-telnet): Re-revert; use the var above.
+
+2002-06-28  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * message.el (message-font-lock-keywords): Don't fontify
+       headers in the message body, only in the header.
+       (message-font-lock-make-header-matcher): New function, used by
+       message-font-lock-keywords.
+       From Katsumi Yamaoka <yamaoka@jpl.org>.
+
+2002-06-28  Katsumi Yamaoka <yamaoka@jpl.org>
+
+       * nntp.el (nntp-open-via-rlogin-and-telnet): Revert last change.
+
+2002-06-28  Katsumi Yamaoka <yamaoka@jpl.org>
+
+       * nntp.el (nntp-open-via-rlogin-and-telnet): Hide commandline args.
+
+2002-06-26  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * message.el (message-font-lock-keywords): Revert 2002-06-22
+       change.
+
+2002-06-24  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * message.el (message-font-lock-keywords): Put colon in header
+       name match.
+
+2002-06-22  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * message.el (message-font-lock-keywords): Don't use header faces
+       in the body.  Thanks to Stefan Monnier for the hint on the
+       implementation.
+
+2002-05-09  Miles Bader  <miles@gnu.org>
+
+       * gnus-cite.el (gnus-cite-blank-line-after-header): New variable.
+       (gnus-article-hide-citation): Respect it.
+
+2002-04-12  Juanma Barranquero  <lektu@terra.es>
+
+       * pop3.el (pop3-open-server): Fix typo.
+
+2002-06-18  Josh Huber  <huber@alum.wpi.edu>
+
+       * gnus.el (gnus-find-subscribed-addresses): Use add-to-list
+       instead of push to ignore duplicate to-(list|address) values.
+       * nnmail.el (nnmail-cache-ignore-groups): New.
+       * nnmail.el (nnmail-cache-insert): Obey nnmail-cache-ignore-groups
+
+2002-06-18  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus-delay.el (gnus-delay-send-queue): Delete the delay header
+       before sending.  Suggested by Jan Rychter.
+
+2002-06-18  Katsumi Yamaoka <yamaoka@jpl.org>
+
+       * dgnushack.el (remove): New compiler macro.
+       (last, coerce, subseq): Remove compiler macros for those built-in
+       or unused functions.
+
+2002-06-17  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus-start.el (gnus-clear-system, gnus-read-newsrc-file): Make
+       sure to write byte-compiled versions of gnus-*-format-alist to
+       .newsrc.eld.  From Simon Josefsson.
+
+2002-06-16  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus-agent.el (gnus-agent-read-servers)
+       (gnus-agent-write-servers): Put server name (string like
+       "nnchoke:frumple") in the file instead of a server specification
+       (Lisp expression like (nnchoke "frumple" ...parameters...)).
+       From Bj\e,Ax\e(Brn Mork <bmork@dod.no>.
+
+2002-06-16  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-cache.el (gnus-cache-remove-article): n is &optional.  From
+       Reiner Steib <4uce.02.r.steib@gmx.net>.
+
+2002-06-15  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * nnheader.el (nnheader-file-name-translation-alist): Set the
+       default value for MS Windows systems.
+
+       * gnus-ems.el (nnheader-file-name-translation-alist): Removed.
+
+2002-06-14  Katsumi Yamaoka <yamaoka@jpl.org>
+
+       * message.el (message-beginning-of-line): Keep the region active
+       in XEmacs.  Suggested by TAKAHASHI Kaoru <kaoru@kaisei.org>.
+
+2002-06-13  Josh Huber  <huber@alum.wpi.edu>
+
+       * gnus-msg.el (gnus-summary-followup): Use g-s-handle-replysign.
+       * gnus-msg.el (gnus-summary-reply): Ditto.
+       * gnus-msg.el (gnus-summary-handle-replysign): New.
+
+2002-06-12  Katsumi Yamaoka <yamaoka@jpl.org>
+
+       * message.el (message-send-mail-with-sendmail): Kill errbuf even
+       if sending failed.
+
+2002-06-11  Josh Huber  <huber@alum.wpi.edu>
+
+       * gnus-start.el (gnus-dribble-enter): Don't call set-window-point anymore
+       * mml2015.el (mml2015-mailcrypt-encrypt): Accept optional argument
+       to sign while encrypting.
+
+2002-06-11  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-int.el (gnus-request-move-article): Agent expire article if
+       successfuly moved.
+
+       * nnweb.el (nnweb-google-create-mapping): Honors the value of
+       nnweb-max-hits.  From Niklas Morberg <niklas.morberg@axis.com>.
+
+2002-06-10  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-int.el (gnus-request-expire-articles): Fix last change?
+
+2002-06-09  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-sum.el (gnus-summary-delete-article): Don't agent expire here.
+
+       * gnus-int.el (gnus-request-expire-articles): Do it here instead.
+
+2002-06-08  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * flow-fill.el (fill-flowed): Ignore errors.
+
+2002-06-06  Simon Josefsson  <jas@extundo.com>
+
+       * message.el (message-send-mail-with-sendmail): Improve error message.
+
+2002-06-06  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * message.el (message-interactive): Change default from nil to t.
+       Better to be safe than to be fast.
+
+2002-06-05  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * message.el (message-send-mail-with-sendmail): Check return value
+       from call-process-region.
+
+2002-06-04  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-msg.el (gnus-group-mail, gnus-group-news)
+       (gnus-group-post-news, gnus-summary-mail-other-window)
+       (gnus-summary-news-other-window, gnus-summary-post-news): Bind
+       gnus-article-copy to nil, thereby inhibiting the `header' posting
+       style match to use data from last viewed article.
+       Suggested by Hrvoje Niksic.
+
+2002-06-04  Katsumi Yamaoka <yamaoka@jpl.org>
+
+       * spam.el (spam-point-at-eol): New alias.
+       (spam-parse-whitelist): Use it.
+
+2002-06-03  Simon Josefsson  <jas@extundo.com>
+
+       * nnmail.el (nnmail-mail-splitting-decodes): New variable.
+       (nnmail-article-group): Use it.
+
+2002-05-30  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus-msg.el (gnus-inews-yank-articles): Merge split header lines
+       so that code reading them won't be surprised.  From Jesper Harder
+       <harder@ifa.au.dk>.
+
+2002-05-29  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-sum.el (gnus-summary-delete-article): Agent expire deleted
+       articles.
+
+       * gnus.el (gnus-agent-cache): Doc fix.
+       (gnus-agent): Change default to t.
+
+       * gnus-agent.el (gnus-agent-expire): Make it accept optional
+       ARTICLES, GROUP and FORCE parameters.
+
+2002-05-28  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-group.el (gnus-group-line-format): Doc fix.
+
+2002-05-28  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus-msg.el (gnus-inews-yank-articles): Unfold headers of
+       original article before yanking.  From Jesper Harder
+       <harder@ifa.au.dk>.
+
+2002-05-26  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-sum.el (gnus-summary-menu-split): New function.
+       (gnus-summary-make-menu-bar): Split charset submenu.
+       (gnus-summary-menu-maxlen): New variable.
+       (gnus-summary-menu-split): Use it.
+
+2002-05-25  Simon Josefsson  <jas@extundo.com>
+
+       * mml.el (mml-preview): Generate some headers.
+
+       * gnus.el (gnus-large-newsgroup): Fix :type.
+
+       * nnimap.el (nnimap-nov-is-evil): Change default to t (because the
+       Agent cache NOV's by default now).
+       (nnimap-nov-is-evil): Make it default to `gnus-agent' instead.
+
+2002-05-18  Jesper Harder  <harder@ifa.au.dk>
+
+       * gnus-sum.el (gnus-dependencies-add-header): Avoid one unecessary
+       call to gnus-parent-id when we check for References loops.
+       (gnus-summary-prepare-threads): Avoid simplifying every Subject
+       twice by saving the simplified subject string in simp-subject.
+
+2002-05-23  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-msg.el (gnus-confirm-mail-reply-to-news): Typo.  Trivial
+       change from Benjamin Rutt <rutt+news@cis.ohio-state.edu>.
+
+       * nnweb.el (nnweb-type): Remove dejanewsold.  Trivial change from
+       Niklas Morberg <niklas.morberg@axis.com>.
+
+2002-05-22  Simon Josefsson  <jas@extundo.com>
+
+       * sieve.el (sieve-change-region): Define it before it is used.
+
+       * gnus-msg.el (gnus-confirm-mail-reply-to-news)
+       (gnus-summary-reply): Ask for confirmation when replying to news.
+       Defaults to not ask.  From Benjamin Rutt
+       <rutt+news@cis.ohio-state.edu>.
+
+       * nnimap.el (nnimap-nov-is-evil): Improve doc.
+
+2002-05-21  Simon Josefsson  <jas@extundo.com>
+
+       * sieve-mode.el (sieve-manage): Fix autoloads.
+
+       * sieve-manage.el (sieve-manage-cram-md5-auth): Just send the SASL
+       name (makes it work with recent Cyrus timsieved).
+
+2002-05-20  Jason  <jbaker@cs.utah.edu>
+
+       * gnus-art.el (gnus-request-article-this-buffer): Try
+       reconnecting if you don't get the message.
+
+2002-05-20  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-sum.el (gnus-summary-enter-digest-group): Only get
+       Reply-To headers from the headers.
+
+2002-05-18  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * mm-url.el (mm-url-insert): Remove junk message.
+
+2002-05-17  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * nnslashdot.el (nnslashdot-request-list): Parse new html.
+       (nnslashdot-use-front-page): New variable.
+       (nnslashdot-request-list): Use it.
+
+       * mm-url.el (mm-url-timeout): New variable.
+       (mm-url-retries): Ditto.
+       (mm-url-insert): Use it.
+
+2002-05-16  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-sum.el (gnus-simplify-all-whitespace): New function.
+       (gnus-simplify-subject-functions): Mention g-s-a-w.
+
+2002-05-15  Josh Huber  <huber@alum.wpi.edu>
+
+       * nnbabyl.el (nnbabyl-request-accept-article): Pass group to
+       nnmail-cache-insert.
+       * nndiary.el (nndiary-request-accept-article): Ditto.
+       * nnfolder.el (nnfolder-request-accept-article): Ditto.
+       * nnimap.el (nnimap-request-accept-article): Ditto.
+       * nnmail.el (nnmail-process-unix-mail-format): Ditto.
+       * nnmail.el (nnmail-check-duplication): Ditto. (from gnus-art)
+       * nnmbox.el (nnmbox-request-accept-article): Ditto.
+       * nnmh.el (nnmh-request-accept-article): Ditto.
+       * nnmail.el (nnmail-cache-insert): Change group to required,
+       removed code which tried to figure out the group.
+
+2002-05-13  Josh Huber  <huber@alum.wpi.edu>
+
+       * mml.el (mml-generate-mime-1): Fix mml generation for signed only
+       messages. From Hans de Graaff <hans@degraaff.org>.
+       * nnml.el (nnml-request-accept-article): Pass in the group name to
+       nnmail-cache-insert, since it's available.
+
+2002-05-10  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * nndoc.el (nndoc-mime-digest-type-p): Set proper file-end.
+
+2002-05-08  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+       From Florian Weimer <fw@deneb.enyo.de>.
+
+       * gnus.el (subscribed): New group parameter.
+       (gnus-find-subscribed-addresses): Use it.
+
+2002-05-08  Josh Huber  <huber@alum.wpi.edu>
+
+       * mml-sec.el (mml-signencrypt-style-alist): Rename.  Also, changed
+       the default for pgpmime to support pgp v2.
+       * mml-sec.el (mml-signencrypt-style): New accessor function to
+       allow users to get/set the signencrypt style more easily without
+       frobbing the alist directly.
+       * mml.el (mml-generate-mime-1): Use accessor function.
+
+2002-05-08  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus-art.el (gnus-article-mode-syntax-table): Specify matching
+       parenthesis for "<" and ">".  Suggested by Andreas Schwab
+       <schwab@suse.de>.
+
+2002-05-07  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * nnmail.el (nnmail-cache-insert): Prefer group-art over group
+       when intuiting the group the message is written to.  From Josh
+       Huber <huber@alum.wpi.edu>.
+
+2002-05-06  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-topic.el (gnus-group-topic-parameters): Work when group
+       buffer doesn't show group.  From Matt Armstrong <matt@lickey.com>.
+
+2002-05-06  Josh Huber  <huber@alum.wpi.edu>
+
+       * mml2015.el (mml2015-gpg-encrypt): Changed name of optional
+       argument, and fixed compiler warning. (added autoload for
+       gpg-encrypt).
+
+2002-05-04  Simon Josefsson  <jas@extundo.com>
+
+       * mml1991.el (mml1991-function-alist): Doc fix.
+
+       * mml.el (mml-preview): Bind gnus-newsrc-hashtb temporarily if it
+       doesn't exist (for previewing messages without having Gnus
+       started).
+
+       * mm-util.el (mm-coding-system-priorities): Defcustom.
+
+       * mm-encode.el (mm-content-transfer-encoding-defaults): Defcustom.
+
+2002-05-01  Josh Huber  <huber@alum.wpi.edu>
+
+       * gnus-msg.el (gnus-message-replysignencrypted): enabled by
+       default.
+       * mml-sec.el:
+       * mml-sec.el (mml-signencrypt-style): New.
+       * mml-sec.el (mml-pgpmime-encrypt-buffer): Accept optional
+       argument `sign'.
+       * mml-sec.el (mml-secure-message-encrypt-pgp): Changed default to
+       signencrypt.
+       * mml-sec.el (mml-secure-message-encrypt-pgpmime): Ditto.
+       * mml.el (mml-generate-mime-1): Changed logic so a part which is
+       both signed & encryped is processed in one operation. (rather than
+       two separate ops: sign, then encrypt)
+       * mml2015.el (mml2015-gpg-extract-signature-details): Give some
+       indication if a message is signed by an expired key.
+       * mml2015.el (mml2015-gpg-encrypt): Accept optional argument which
+       enables combined sign & encrypt operation. (this was always on
+       before).
+       * mml2015.el (mml2015-encrypt): Accept optional argument `sign'.
+
+2002-05-01  Simon Josefsson  <jas@extundo.com>
+
+       * nnimap.el (nnimap-retrieve-groups): Use separate data for each
+       server.
+       (nnimap-mailbox-info): defvar instead of defvoo.
+
 2002-05-01 20:09:21 Lars Magne Ingebrigtsen <lars@ingebrigtsen.no>
 
        * gnus.el: Oort Gnus v0.06 is released.
        Trivial change from Karl Pfl\e,Ad\e(Bsterer <sigurd@12move.de>.
 
 2002-04-27  Katsumi Yamaoka <yamaoka@jpl.org>
-       
+
        * dns.el (dns-make-network-process): New macro.
        (query-dns): Use it.
 
 2002-04-27  ShengHuo ZHU  <zsh@cs.rochester.edu>
-       
+
        * gnus-msg.el (gnus-summary-reply): Remove unbound variable
        article-buffer.
 
        problems.
        (nnkiboze-generate-group): Set newsrc to the *highest* article
        number kibozed, not the lowest.
-       
+
 2002-04-15  Jesper Harder  <harder@ifa.au.dk>
 
        * gnus-art.el (article-unsplit-urls): Allow trailing SPC.
 
-2002-04-24  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2002-04-24  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
        From Dan Christensen <jdc+news@uwo.ca>.
 
        * nndoc.el (nndoc-type-alist, nndoc-lanl-gov-announce-type-p)
        headers for message which are missing these headers.  Get rid
        of spurious \\ lines (purely cosmetic).  Extend body-end and
        file-end regexps, to exclude more garbage from the message.
-       Make URL rephrasing regexp more flexible, to match current 
+       Make URL rephrasing regexp more flexible, to match current
        format.
 
 2002-04-23  Simon Josefsson  <jas@extundo.com>
        (gnus-netrc-get, gnus-netrc-machine, gnus-parse-netrc): Aliased to
        new code in netrc.el.
 
-2002-04-23  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2002-04-23  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-msg.el (gnus-summary-resend-message-edit): Remove
        message-ignored-resent-headers, too.  From Matthieu Moy
        * message.el (message-gen-unsubscribed-mft): accept a prefix
        argument so CC can be included with C-u C-c C-f C-a
 
-2002-04-17  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2002-04-17  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
        From Ted Zlatanov <teodor.zlatanov@divine.com>.
 
        * spam.el (spam-whitelist, spam-blacklist, spam-enter-whitelist):
        * gnus.el (gnus-summary-line-format): Fixing links to Info.
        Trivial change from Bj\e,Av\e(Brn Torkelsson <torkel@pdc.kth.se>.
 
-2002-03-29  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2002-03-29  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-sum.el (gnus-summary-move-article)
        (gnus-summary-copy-article): Mention `gnus-move-split-methods' in
        (nnmaildir--edit-prep): New function.
        (Local Variables): Use it.
 
-2002-03-26  Pavel@Janik.cz (Pavel Jan\e,Bm\e(Bk)
+2002-03-26  Pavel@Janik.cz (Pavel Jan\e,Am\e(Bk)
 
        * gnus-sum.el (gnus-summary-make-menu-bar): Fix typo.
 
        tags.
 
        * gnus-sum.el (gnus-print-buffer): Remove gnus-decoration.
-       Trivial change from lorentey@elte.hu (L\e,Bu\e(Brentey K\e,Ba\e(Broly)
+       Trivial change from lorentey@elte.hu (L\e,Bu\e(Brentey K\e,Aa\e(Broly)
 
 2002-03-20  Katsumi Yamaoka  <yamaoka@jpl.org>
 
 
        * gnus-group.el (gnus-group-process-prefix): Make sure there is a mark.
 
-2002-03-19  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2002-03-19  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-sum.el (gnus-sum-thread-tree-root)
        (gnus-sum-thread-tree-single-indent)
 2002-03-13  Simon Josefsson  <jas@extundo.com>
 
        * pop3.el (pop3-open-server): Revert multibyte change.  From
-       Pavel@Janik.cz (Pavel Jan\e,Bm\e(Bk).
+       Pavel@Janik.cz (Pavel Jan\e,Am\e(Bk).
 
        * message.el (message-send-mail-with-qmail): Make it work.  From
-       Pavel@Janik.cz (Pavel Jan\e,Bm\e(Bk).
+       Pavel@Janik.cz (Pavel Jan\e,Am\e(Bk).
 
 2002-03-13  Josh Huber  <huber@alum.wpi.edu>
 
        (gnus-article-reply-with-original): Ditto.
 
        * binhex.el (binhex-decoder-switches): Fix doc.  From
-       Pavel@Janik.cz (Pavel Jan\e,Bm\e(Bk).
+       Pavel@Janik.cz (Pavel Jan\e,Am\e(Bk).
 
 2002-02-04  ShengHuo ZHU  <zsh@cs.rochester.edu>
 
 
        * flow-fill.el (fill-flowed-display-column)
        (fill-flowed-encode-columnq): New variables.  Suggested by
-       Kai.Grossjohann@CS.Uni-Dortmund.DE (Kai Gro\e,A_\e(Bjohann).
+       Kai.Grossjohann@CS.Uni-Dortmund.DE (Kai Gro\e,b_\e(Bjohann).
        (fill-flowed-encode, fill-flowed): Use them.
 
        * message.el (message-send-news, message-send-mail): Use
 
        * gnus-agent.el (gnus-agent-fetch-session): Run hook.
 
-2002-01-03  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2002-01-03  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-start.el (gnus-read-init-file): Don't force coding system
        for ~/.gnus.  From Dave Love <fx@gnu.org>.
        (gnus-picon-transform-address): Insert spec backward, due to the
        incompatibility of gnus-xmas-put-image.
 
-2002-01-02  Pavel Jan\e,Bm\e(Bk  <Pavel@Janik.cz>
+2002-01-02  Pavel Jan\e,Am\e(Bk  <Pavel@Janik.cz>
 
        * gnus-fun.el (gnus-convert-pbm-to-x-face-command): Doc fix.
 
        * gnus-art.el, gnus-picon.el, gnus-sieve.el, gnus-sum.el:
        * gnus-xmas.el, imap.el, mailcap.el, mm-util.el, nnfolder.el:
        * nnheader.el, nnmail.el: Nil/NIL vs. nil.
-       From  Pavel Jan\e,Bm\e(Bk  <Pavel@Janik.cz>
+       From  Pavel Jan\e,Am\e(Bk  <Pavel@Janik.cz>
 
 2001-12-20 15:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
 
 
        * mm-url.el (executable-find): autoload.
 
-2001-12-12  Pavel Jan\e,Bm\e(Bk  <Pavel@Janik.cz>
+2001-12-12  Pavel Jan\e,Am\e(Bk  <Pavel@Janik.cz>
 
        * gnus-mlspl.el (gnus-group-split-fancy): Doc fix (add reference
        to variable, follow doc-string conventions).
 
        * message.el (message-tab-body-function): Set to nil.
        (message-tab): Use text-mode-map or global-map.
-       Suggested by Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>.
+       Suggested by Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>.
 
 2001-11-30  Simon Josefsson  <jas@extundo.com>
 
        * gnus-agent.el (gnus-agent-write-active): Make sure sym is a cons
        of integers.
 
-2001-11-29  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-11-29  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * message.el (message-newgroups-header-regexp)
        (message-completion-alist, message-tab-body-function): Use
        (gnus-summary-limit-to-extra): Ditto.
        (gnus-summary-find-matching): Support not-matching argument.
 
-2001-11-25  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-11-25  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * message.el (message-wash-subject): Use `insert' rather than
        `insert-string', which is deprecated.
 
 2001-11-09  Simon Josefsson  <jas@extundo.com>
 
-       * gnus.el (gnus-local-domain): Fix doc.  From Pavel Jan\e,Bm\e(Bk
+       * gnus.el (gnus-local-domain): Fix doc.  From Pavel Jan\e,Am\e(Bk
        <Pavel@Janik.cz>.
 
-2001-11-09  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-11-09  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * message.el (message-point-in-header-p): New function.
        (message-do-auto-fill): Use it.
        (nnweb-type-definition): Add google as alias of dejanews.
        (nnweb-google-parse-1): Forward 1 line.
 
-2001-10-26  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-10-26  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-msg.el (gnus-summary-mail-forward): Doc fix: add pointer to
        variable `message-forward-ignored-headers'.
 
        * gnus-msg.el (gnus-extended-version): Include
        system-configuration.
-       Suggested by Kai.Grossjohann@CS.Uni-Dortmund.DE (Kai Gro\e,A_\e(Bjohann).
+       Suggested by Kai.Grossjohann@CS.Uni-Dortmund.DE (Kai Gro\e,b_\e(Bjohann).
 
 2001-10-22  Per Abrahamsen  <abraham@dina.kvl.dk>
 
        (nnimap-split-inbox, nnimap-expunge-search-string)
        (nnimap-importantize-dormant): Remove "*" from doc.
 
-2001-10-20  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-10-20  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-sum.el (gnus-summary-limit-to-score): Prompt for score if
        not supplied via prefix arg.  From Lisp, make arg mandatory.
        * message.el (message-do-auto-fill): Avoid calling
        'rfc822-goto-eoh'.
 
-2001-10-20  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-10-20  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
        From Paul Jarc <prj@po.cwru.edu>.
 
        * message.el (message-get-reply-headers): Restructure the logic
        * gnus-msg.el (gnus-post-method): Changed two instances of
        `active' to `current' and one `null' to `not'.
 
-2001-10-16  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-10-16  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
        From Katsumi Yamaoka  <yamaoka@jpl.org>.
 
        * message.el (message-setup-fill-variables): Use
        (mml2015-gpg-decrypt-1): Decanonicalize decrypted MIME
        body. (Mailcrypt seem to do this, but gpg.el doesn't.)
 
-2001-10-16  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-10-16  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
        Patch by Oliver Scholz <oscholz@my.gnus.org>.
 
        * gnus-draft.el (gnus-draft-edit-message): Add text property
        * message.el (message-do-auto-fill): Use gnus-point-at-bol.
        (autoload): Add some autoloads.
 
-2001-10-12  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-10-12  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
        Suggested by Oliver Scholz <epameinondas@gmx.de>.
 
        * message.el (message-do-auto-fill): New function.  Like
        * gnus-sum.el (gnus-summary-extract-address-component): New function.
        (gnus-summary-from-or-to-or-newsgroups): Optimize.
 
-2001-09-29  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-09-29  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * message.el (message-mode-map): Keybinding for `gnus-delay-article'.
        (message-mode-menu): Menu item for same.
        * gnus-group.el (gnus-group-catchup): Update expire marks in
        backend.  Also, if ALL also set expire marks on tick/dormant.
 
-2001-09-20  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-09-20  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * message.el (message-tab-body-function): New variable.
        * message.el (message-tab): Use it.
        * gnus-draft.el (gnus-draft-setup): Don't set mark when there
        isn't an article to set it on (e.g. when you `a' in a group).
 
-2001-09-12  Pavel Jan\e,Bm\e(Bk  <Pavel@Janik.cz>
+2001-09-12  Pavel Jan\e,Am\e(Bk  <Pavel@Janik.cz>
 
        * mm-util.el (mm-charset-synonym-alist): add windows-1250 so we
        can read e-mails from Microsoft Outlook users not using ISO
        * gnus-sum.el (gnus-summary-insert-line): Insert forwarded, recent
        and unseen marks.
 
-2001-09-05  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-09-05  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * nnmail.el (nnmail-split-fancy): Document `junk'.
 
        * gnus-spec.el (gnus-correct-substring): Stopped one character
        before we wanted.
 
-2001-08-19  Pavel Jan\e,Bm\e(Bk  <Pavel@Janik.cz>
+2001-08-19  Pavel Jan\e,Am\e(Bk  <Pavel@Janik.cz>
 
        * earcon.el (earcon-auto-play): Remove unused option.
 
        * gnus-srvr.el (gnus-server-browse-in-group-buffer): Default to
        nil.
 
-2001-08-15  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-08-15  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-delay.el (gnus-delay-article): Allow "01:23" time spec,
        which specifies a time today or tomorrow.
 
 2001-08-15  Simon Josefsson  <jas@extundo.com>
-       From Pavel@Janik.cz (Pavel Jan\e,Bm\e(Bk)
+       From Pavel@Janik.cz (Pavel Jan\e,Am\e(Bk)
 
        * gnus-agent.el (gnus-agent-make-mode-line-string)
        (gnus-agent-toggle-plugged): Use new API.
 
-2001-08-14  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-08-14  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-delay.el (gnus-delay-send-drafts): Fix check whether
        deadline has expired.
        * gnus-spec.el (gnus-format-specs): %n is 23 chars.
 
 2001-08-11 09:40:00  Karl Kleinpaste  <karl@charcoal.com>
-       Committed by Kai Gro\e,A_\e(Bjohann.
+       Committed by Kai Gro\e,b_\e(Bjohann.
 
        * gnus-score.el (gnus-score-string): Fix `match' regexp
        for `extra' header case.
        (nndoc-oe-dbx-dissection): New function.
        (nndoc-oe-dbx-generate-article): New function.
 
-2001-08-11  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-08-11  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-delay.el (gnus-delay-send-drafts): Cleaner way to check
        whether deadline has been reached.  Patch from Dan Nicolaescu
        before remove.
        (gnus-mime-security-show-details): Ditto.
 
-2001-08-04  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-08-04  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * nnmail.el (nnmail-split-fancy-with-parent): Correct `mapconcat'
        syntax.  Protect string-match against nil string and regexp.
        * gnus-msg.el (gnus-post-method): Refer to `gnus-parameters'.
 
 2001-07-31 17:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
-       Originally from Pavel Jan\e,Bm\e(Bk <Pavel@Janik.cz>
+       Originally from Pavel Jan\e,Am\e(Bk <Pavel@Janik.cz>
 
        * gnus-agent.el (gnus-agent-make-mode-line-string): New function.
        (gnus-agent-toggle-plugged): Use it.
        (gnus-read-newsrc-el-file, gnus-save-newsrc-file)
        (gnus-slave-save-newsrc): Use it.
 
-2001-07-31  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-07-31  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-delay.el (gnus-delay-initialize): Use standard define-key
        syntax.
        calls widen.  Thanks to Christoph Conrad
        <christoph.conrad@gmx.de>.
 
-2001-07-29  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-07-29  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus.el (gnus-summary-line-format): Mention `gnus-sum-thread-*'
        for %B spec.
        * nnheader.el (nnheader-translate-file-chars): cygwin32 is running
        in M$Windows too.
 
-2001-07-26  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-07-26  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-delay.el (gnus-delay-send-drafts): Don't `error'.
 
        * mm-decode.el (mm-remove-part): Don't murder the current window (nil).
        (mm-display-external): Use display-term configure.
 
-2001-07-24  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-07-24  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-delay.el (gnus-delay-default-hour): New variable.
        (gnus-delay-article): Allow specific date in YYYY-MM-DD format.
        `gnus-check-bogus-newsgroups' just after the native server is
        opened.
 
-2001-07-23  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-07-23  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * nnmail.el (nnmail-do-request-post): Util function to be used by
        `nnchoke-request-post' for all nnmail-derived backends.
 
        * gnus-msg.el (gnus-setup-message): make-local-hook.
 
-2001-07-22  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-07-22  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-delay.el (gnus-delay-article): Fix `read-string' for
        XEmacs.  Allow more units.  Submitted by Karl Kleinpaste
        whether the groups exist, check the right server based on
        `gnus-post-method'.
 
-2001-07-21  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-07-21  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-delay.el: New file.
 
        (article-de-base64-unreadable, article-wash-html):
        (gnus-mime-inline-part, gnus-mime-view-part-as-charset): Ditto.
 
-2001-07-21  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-07-21  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * nnml.el (nnml-request-post): New function.  Can be used for
        annotations in nnml groups.
 
        * gnus-art.el (gnus-article-edit-mode): Use define-derived-mode.
 
-2001-07-16  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-07-16  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * message.el (message-citation-line-function): Refer to
        gnus-cite-attribution-suffix.
 
-2001-07-15  Pavel Jan\e,Bm\e(Bk <Pavel@Janik.cz>
+2001-07-15  Pavel Jan\e,Am\e(Bk <Pavel@Janik.cz>
 
        * gnus-art.el,...: Error convention changes.
 
 
        * gnus-setup.el (gnus-use-installed-gnus): Typo.
        * Cleanup files.
-       From Pavel@Janik.cz (Pavel Jan\e,Bm\e(Bk).
+       From Pavel@Janik.cz (Pavel Jan\e,Am\e(Bk).
 
 2001-07-13 08:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
 
        * gnus-draft.el (gnus-draft-edit-message): Remove Date here.
        (gnus-draft-setup): Remove backlog.
 
-2001-07-10  Pavel Jan\e,Bm\e(Bk <Pavel@Janik.cz>
+2001-07-10  Pavel Jan\e,Am\e(Bk <Pavel@Janik.cz>
 
        * gnus-logic.el, gnus-srvr.el, gnus-vm.el, nnheaderxm.el, nnoo.el:
        Cleanup.
        * gnus-sum.el (gnus-summary-catchup): New argument.
        (gnus-summary-catchup-from-here): New function.
 
-2001-05-30  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-05-30  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * mm-view.el (mm-inline-image-xemacs): Insert newline, then move
        back, then insert glyph.  (Before, the glyph was inserted first,
        it is not possible to insert a character after a glyph which is at
        the end of a buffer.  Patch by Lloyd Zusman <ljz@asfast.com>.
 
-2001-05-28  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-05-28  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        From Jaap-Henk Hoepman (jhh@xs4all.nl).
 
        mm-destroy-postponed-undisplay-list): New functions.
        (mm-display-external): Use them.
 
-2001-05-27  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-05-27  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-salt.el (gnus-tree-highlight-node): Bind `default-high' and
        `default-low' when evaluating `gnus-summary-highlight'.
        as details.
        (mml2015-mailcrypt-clear-verify): Ditto.
 
-2001-05-24  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-05-24  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
        From Nevin Kapur <nevin@jhu.edu>.
 
        * gnus-sum.el (gnus-summary-default-high-score,
        matching subjects.
        (gnus-offer-save-summaries): Clean up.
 
-2001-04-13  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-04-13  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * nnmail.el (nnmail-split-fancy-with-parent): Add docstring.
 
        supported. Suggest by Jim Meyering <jim@meyering.net>.
 
 2001-04-02  Nevin Kapur  <nevin@jhu.edu>
-       Committed by Kai Gro\e,A_\e(Bjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>.
+       Committed by Kai Gro\e,b_\e(Bjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>.
 
        * nnmail.el (nnmail-split-it): Added check for .* at the end of
        regexp in nnmail-split-fancy.
        `nnimap-use-nov-p' (it really tested the negative).
        (nnimap-retrieve-headers): Use it.
 
-2001-03-11  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-03-11  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * message.el (message-generate-headers-first): Update doc.
 
 
        * gnus-draft.el (gnus-draft-reminder): "Confirm to exit?"
 
-2001-02-19  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-02-19  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-sum.el (gnus-thread-sort-functions): Doc fix.  Refer to
        gnus-article-sort-functions.
        (gnus-subscribe-hierarchically): Return gnus-subscribe-newsgroup's
        return .
 
-2001-02-12  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-02-12  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-cus.el (gnus-score-customize): Doc fix.
 
        * gnus-uu.el (gnus-uu-grab-articles): Shoot down original article
        buffer.
 
-2001-02-07  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2001-02-07  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * message.el (message-generate-headers-first): Doc fix.
 
 
        * message.el (message-forward): Save-restriction.
 
-2000-12-21  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2000-12-21  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-art.el (article-treat-dumbquotes): More doc, provided by
        Paul Stevenson <p.stevenson@surrey.ac.uk>
        * message.el (message-font-lock-keywords): use
        message-cite-prefix-regexp.
 
-2000-11-15  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2000-11-15  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-group.el (gnus-group-jump-to-group-prompt): New variable by
        Stein Arild Str\e,Ax\e(Bmme.
        * gnus-art.el (gnus-mime-display-alternative): Show button if no
        preferred part.
 
-2000-11-07  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+2000-11-07  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-sum.el (gnus-move-split-methods): Say that
        `gnus-split-methods' uses file names, whereas this uses group
index 475909a..76f6bb7 100644 (file)
@@ -287,7 +287,9 @@ If TCP-P, the first two bytes of the package with be the length field."
         (open-network-stream "dns" (current-buffer) ,server "domain" 'udp))
     `(let ((server ,server)
           (coding-system-for-read 'binary)
-          (coding-system-for-write 'binary))
+          (coding-system-for-write 'binary)
+          (default-process-coding-system '(binary . binary))
+          program-coding-system-alist)
        (if (fboundp 'make-network-process)
           (make-network-process
            :name "dns"
index dfe09c2..5dca163 100644 (file)
@@ -134,11 +134,14 @@ RFC 2646 suggests 66 characters for readability."
            (backward-delete-char -1)
            (end-of-line))
          (unless sig
-           (let ((fill-prefix (when quote (concat quote " ")))
-                 (fill-column (eval fill-flowed-display-column)))
-             (fill-region (fill-flowed-point-at-bol)
-                          (min (1+ (fill-flowed-point-at-eol)) (point-max))
-                          'left 'nosqueeze))))))))
+           (condition-case nil
+               (let ((fill-prefix (when quote (concat quote " ")))
+                     (fill-column (eval fill-flowed-display-column))
+                     filladapt-mode)
+                 (fill-region (fill-flowed-point-at-bol)
+                              (min (1+ (fill-flowed-point-at-eol)) (point-max))
+                              'left 'nosqueeze))
+             (error nil))))))))
 
 (provide 'flow-fill)
 
index d945cac..b864b27 100644 (file)
@@ -640,8 +640,12 @@ be a select method."
 (defun gnus-agent-read-servers ()
   "Read the alist of covered servers."
   (setq gnus-agent-covered-methods
-       (gnus-agent-read-file
-        (nnheader-concat gnus-agent-directory "lib/servers"))))
+       (mapcar (lambda (m)
+                 (gnus-server-get-method
+                  nil
+                  (or m "native")))
+               (gnus-agent-read-file
+                (nnheader-concat gnus-agent-directory "lib/servers")))))
 
 (defun gnus-agent-write-servers ()
   "Write the alist of covered servers."
@@ -651,7 +655,8 @@ be a select method."
        (file-name-coding-system nnmail-pathname-coding-system)
        (pathname-coding-system nnmail-pathname-coding-system))
     (with-temp-file (nnheader-concat gnus-agent-directory "lib/servers")
-      (prin1 gnus-agent-covered-methods (current-buffer)))))
+      (prin1 (mapcar 'gnus-method-simplify gnus-agent-covered-methods)
+            (current-buffer)))))
 
 ;;;
 ;;; Summary commands
@@ -1660,15 +1665,20 @@ The following commands are available:
   (or (gnus-gethash group gnus-category-group-cache)
       (assq 'default gnus-category-alist)))
 
-(defun gnus-agent-expire ()
-  "Expire all old articles."
+(defun gnus-agent-expire (&optional articles group force)
+  "Expire all old articles.
+If you want to force expiring of certain articles, this function can
+take ARTICLES, GROUP and FORCE parameters as well.  Setting ARTICLES
+and GROUP without FORCE is not supported."
   (interactive)
-  (let ((methods gnus-agent-covered-methods)
+  (let ((methods (if group
+                    (list (gnus-find-method-for-group group))
+                  gnus-agent-covered-methods))
        (day (if (numberp gnus-agent-expire-days)
                 (- (time-to-days (current-time)) gnus-agent-expire-days)
               nil))
        (current-day (time-to-days (current-time)))
-       gnus-command-method sym group articles
+       gnus-command-method sym arts pos
        history overview file histories elem art nov-file low info
        unreads marked article orig lowest highest found days)
     (save-excursion
@@ -1676,8 +1686,8 @@ The following commands are available:
       (while (setq gnus-command-method (pop methods))
        (when (file-exists-p (gnus-agent-lib-file "active"))
          (with-temp-buffer
-           (insert-file-contents-as-coding-system
-            gnus-agent-file-coding-system (gnus-agent-lib-file "active"))
+           (let ((nnheader-file-coding-system gnus-agent-file-coding-system))
+             (nnheader-insert-file-contents (gnus-agent-lib-file "active")))
            (gnus-active-to-gnus-format
             gnus-command-method
             (setq orig (gnus-make-hashtable
@@ -1688,174 +1698,196 @@ The following commands are available:
             (setq gnus-agent-current-history
                   (setq history (gnus-agent-history-buffer))))
            (goto-char (point-min))
-           (when (> (buffer-size) 1)
-             (goto-char (point-min))
-             (while (not (eobp))
-               (skip-chars-forward "^\t")
-               (if (let ((fetch-date (read (current-buffer))))
-                     (if (numberp fetch-date)
-                         ;; We now have the arrival day, so we see
-                         ;; whether it's old enough to be expired.
-                         (if (numberp day)
-                             (> fetch-date day)
-                           (skip-chars-forward "\t")
-                           (setq found nil
-                                 days gnus-agent-expire-days)
-                           (while (and (not found)
-                                       days)
-                             (when (looking-at (caar days))
-                               (setq found (cadar days)))
-                             (pop days))
-                           (> fetch-date (- current-day found)))
-                       ;; History file is corrupted.
-                       (gnus-message
-                        5
-                        (format "File %s is corrupted!"
-                                (gnus-agent-lib-file "history")))
-                       (sit-for 1)
-                       ;; Ignore it
-                       t))
-                   ;; New article; we don't expire it.
-                   (forward-line 1)
-                 ;; Old article.  Schedule it for possible nuking.
-                 (while (not (eolp))
-                   (setq sym (let ((obarray expiry-hashtb) s)
-                               (setq s (read (current-buffer)))
-                               (if (stringp s) (intern s) s)))
-                   (if (boundp sym)
-                       (set sym (cons (cons (read (current-buffer)) (point))
-                                      (symbol-value sym)))
-                     (set sym (list (cons (read (current-buffer)) (point)))))
-                   (skip-chars-forward " "))
-                 (forward-line 1)))
-             ;; We now have all articles that can possibly be expired.
-             (mapatoms
-              (lambda (sym)
-                (setq group (symbol-name sym)
-                      articles (sort (symbol-value sym) 'car-less-than-car)
-                      low (car (gnus-active group))
-                      info (gnus-get-info group)
-                      unreads (ignore-errors
-                                (gnus-list-of-unread-articles group))
-                      marked (nconc
-                              (gnus-uncompress-range
-                               (cdr (assq 'tick (gnus-info-marks info))))
-                              (gnus-uncompress-range
-                               (cdr (assq 'dormant (gnus-info-marks info))))
-                              (gnus-uncompress-range
-                               (cdr (assq 'save (gnus-info-marks info))))
-                              (gnus-uncompress-range
-                               (cdr (assq 'reply (gnus-info-marks info)))))
-                      nov-file (gnus-agent-article-name ".overview" group)
-                      lowest nil
-                      highest nil)
-                (gnus-agent-load-alist group)
-                (gnus-message 5 "Expiring articles in %s" group)
-                (set-buffer overview)
-                (erase-buffer)
-                (when (file-exists-p nov-file)
-                  (nnheader-insert-file-contents nov-file))
-                (goto-char (point-min))
-                (setq article 0)
-                (while (setq elem (pop articles))
-                  (setq article (car elem))
-                  (when (or (null low)
-                            (< article low)
-                            gnus-agent-expire-all
-                            (and (not (memq article unreads))
-                                 (not (memq article marked))))
-                    ;; Find and nuke the NOV line.
-                    (while (and (not (eobp))
-                                (or (not (numberp
-                                          (setq art (read (current-buffer)))))
-                                    (< art article)))
-                      (if (and (numberp art)
-                               (file-exists-p
-                                (gnus-agent-article-name
-                                 (number-to-string art) group)))
-                          (progn
-                            (unless lowest
-                              (setq lowest art))
-                            (setq highest art)
-                            (forward-line 1))
-                        ;; Remove old NOV lines that have no articles.
-                        (gnus-delete-line)))
-                    (if (or (eobp)
-                            (/= art article))
-                        (beginning-of-line)
-                      (gnus-delete-line))
-                    ;; Nuke the article.
-                    (when (file-exists-p
-                           (setq file (gnus-agent-article-name
-                                       (number-to-string article)
-                                       group)))
-                      (delete-file file))
-                    ;; Schedule the history line for nuking.
-                    (push (cdr elem) histories)))
-                (gnus-make-directory (file-name-directory nov-file))
-                (write-region-as-coding-system
-                 gnus-agent-file-coding-system
-                 (point-min) (point-max) nov-file nil 'silent)
-                ;; Delete the unwanted entries in the alist.
-                (setq gnus-agent-article-alist
-                      (sort gnus-agent-article-alist 'car-less-than-car))
-                (let* ((alist gnus-agent-article-alist)
-                       (prev (cons nil alist))
-                       (first prev)
-                       expired)
-                  (while (and alist
-                              (<= (caar alist) article))
-                    (if (or (not (cdar alist))
-                            (not (file-exists-p
-                                  (gnus-agent-article-name
-                                   (number-to-string
-                                    (caar alist))
-                                   group))))
+           (if (and articles group force) ;; point usless without art+group
+               (while (setq article (pop articles))
+                 ;; try to find history entries for articles
+                 (goto-char (point-min))
+                 (if (re-search-forward
+                      (concat "^[^\t]*\t[^\t]*\t\(.* ?\)"
+                              (format "%S" (gnus-group-prefixed-name
+                                            group gnus-command-method))
+                              " "
+                              (number-to-string article)
+                              " $")
+                      nil t)
+                     (setq pos (point))
+                   (setq pos nil))
+                 (setq sym (let ((obarray expiry-hashtb) s)
+                             (intern group)))
+                 (if (boundp sym)
+                     (set sym (cons (cons article pos)
+                                    (symbol-value sym)))
+                   (set sym (list (cons article pos)))))
+             ;; go through history file to find eligble articles
+             (when (> (buffer-size) 1)
+               (goto-char (point-min))
+               (while (not (eobp))
+                 (skip-chars-forward "^\t")
+                 (if (let ((fetch-date (read (current-buffer))))
+                       (if (numberp fetch-date)
+                           ;; We now have the arrival day, so we see
+                           ;; whether it's old enough to be expired.
+                           (if (numberp day)
+                               (> fetch-date day)
+                             (skip-chars-forward "\t")
+                             (setq found nil
+                                   days gnus-agent-expire-days)
+                             (while (and (not found)
+                                         days)
+                               (when (looking-at (caar days))
+                                 (setq found (cadar days)))
+                               (pop days))
+                             (> fetch-date (- current-day found)))
+                         ;; History file is corrupted.
+                         (gnus-message
+                          5
+                          (format "File %s is corrupted!"
+                                  (gnus-agent-lib-file "history")))
+                         (sit-for 1)
+                         ;; Ignore it
+                         t))
+                     ;; New article; we don't expire it.
+                     (forward-line 1)
+                   ;; Old article.  Schedule it for possible nuking.
+                   (while (not (eolp))
+                     (setq sym (let ((obarray expiry-hashtb) s)
+                                 (setq s (read (current-buffer)))
+                                 (if (stringp s) (intern s) s)))
+                     (if (boundp sym)
+                         (set sym (cons (cons (read (current-buffer)) (point))
+                                        (symbol-value sym)))
+                       (set sym (list (cons (read (current-buffer))
+                                            (point)))))
+                     (skip-chars-forward " "))
+                   (forward-line 1)))))
+           ;; We now have all articles that can possibly be expired.
+           (mapatoms
+            (lambda (sym)
+              (setq group (symbol-name sym)
+                    arts (sort (symbol-value sym) 'car-less-than-car)
+                    low (car (gnus-active group))
+                    info (gnus-get-info group)
+                    unreads (ignore-errors
+                              (gnus-list-of-unread-articles group))
+                    marked (nconc
+                            (gnus-uncompress-range
+                             (cdr (assq 'tick (gnus-info-marks info))))
+                            (gnus-uncompress-range
+                             (cdr (assq 'dormant
+                                        (gnus-info-marks info)))))
+                    nov-file (gnus-agent-article-name ".overview" group)
+                    lowest nil
+                    highest nil)
+              (gnus-agent-load-alist group)
+              (gnus-message 5 "Expiring articles in %s" group)
+              (set-buffer overview)
+              (erase-buffer)
+              (when (file-exists-p nov-file)
+                (nnheader-insert-file-contents nov-file))
+              (goto-char (point-min))
+              (setq article 0)
+              (while (setq elem (pop arts))
+                (setq article (car elem))
+                (when (or (null low)
+                          (< article low)
+                          gnus-agent-expire-all
+                          (and (not (memq article unreads))
+                               (not (memq article marked)))
+                          force)
+                  ;; Find and nuke the NOV line.
+                  (while (and (not (eobp))
+                              (or (not (numberp
+                                        (setq art (read (current-buffer)))))
+                                  (< art article)))
+                    (if (and (numberp art)
+                             (file-exists-p
+                              (gnus-agent-article-name
+                               (number-to-string art) group)))
                         (progn
-                          (push (caar alist) expired)
-                          (setcdr prev (setq alist (cdr alist))))
-                      (setq prev alist
-                            alist (cdr alist))))
-                  (setq gnus-agent-article-alist (cdr first))
-                  (gnus-agent-save-alist group)
-                  ;; Mark all articles up to the first article
-                  ;; in `gnus-article-alist' as read.
-                  (when (and info (caar gnus-agent-article-alist))
-                    (setcar (nthcdr 2 info)
-                            (gnus-range-add
-                             (nth 2 info)
-                             (cons 1 (- (caar gnus-agent-article-alist) 1)))))
-                  ;; Maybe everything has been expired from
-                  ;; `gnus-article-alist' and so the above marking as
-                  ;; read could not be conducted, or there are
-                  ;; expired article within the range of the alist.
-                  (when (and info
-                             expired
-                             (or (not (caar gnus-agent-article-alist))
-                                 (> (car expired)
-                                    (caar gnus-agent-article-alist))))
-                    (setcar (nthcdr 2 info)
-                            (gnus-add-to-range
-                             (nth 2 info)
-                             (nreverse expired))))
-                  (gnus-dribble-enter
-                   (concat "(gnus-group-set-info '"
-                           (gnus-prin1-to-string info)
-                           ")")))
-                (when lowest
-                  (if (gnus-gethash group orig)
-                      (setcar (gnus-gethash group orig) lowest)
-                    (gnus-sethash group (cons lowest highest) orig))))
-              expiry-hashtb)
-             (set-buffer history)
-             (setq histories (nreverse (sort histories '<)))
-             (while histories
-               (goto-char (pop histories))
-               (gnus-delete-line))
-             (gnus-agent-save-history)
-             (gnus-agent-close-history)
-             (gnus-write-active-file (gnus-agent-lib-file "active") orig))
-           (gnus-message 4 "Expiry...done")))))))
+                          (unless lowest
+                            (setq lowest art))
+                          (setq highest art)
+                          (forward-line 1))
+                      ;; Remove old NOV lines that have no articles.
+                      (gnus-delete-line)))
+                  (if (or (eobp)
+                          (/= art article))
+                      (beginning-of-line)
+                    (gnus-delete-line))
+                  ;; Nuke the article.
+                  (when (file-exists-p
+                         (setq file (gnus-agent-article-name
+                                     (number-to-string article)
+                                     group)))
+                    (delete-file file))
+                  ;; Schedule the history line for nuking.
+                  (if (cdr elem)
+                      (push (cdr elem) histories))))
+              (gnus-make-directory (file-name-directory nov-file))
+              (write-region-as-coding-system
+               gnus-agent-file-coding-system
+               (point-min) (point-max) nov-file nil 'silent)
+              ;; Delete the unwanted entries in the alist.
+              (setq gnus-agent-article-alist
+                    (sort gnus-agent-article-alist 'car-less-than-car))
+              (let* ((alist gnus-agent-article-alist)
+                     (prev (cons nil alist))
+                     (first prev)
+                     expired)
+                (while (and alist
+                            (<= (caar alist) article))
+                  (if (or (not (cdar alist))
+                          (not (file-exists-p
+                                (gnus-agent-article-name
+                                 (number-to-string
+                                  (caar alist))
+                                 group))))
+                      (progn
+                        (push (caar alist) expired)
+                        (setcdr prev (setq alist (cdr alist))))
+                    (setq prev alist
+                          alist (cdr alist))))
+                (setq gnus-agent-article-alist (cdr first))
+                (gnus-agent-save-alist group)
+                ;; Mark all articles up to the first article
+                ;; in `gnus-agent-article-alist' as read.
+                (when (and info (caar gnus-agent-article-alist))
+                  (setcar (nthcdr 2 info)
+                          (gnus-range-add
+                           (nth 2 info)
+                           (cons 1 (- (caar gnus-agent-article-alist) 1)))))
+                ;; Maybe everything has been expired from
+                ;; `gnus-agent-article-alist' and so the above marking as
+                ;; read could not be conducted, or there are
+                ;; expired article within the range of the alist.
+                (when (and info
+                           expired
+                           (or (not (caar gnus-agent-article-alist))
+                               (> (car expired)
+                                  (caar gnus-agent-article-alist))))
+                  (setcar (nthcdr 2 info)
+                          (gnus-add-to-range
+                           (nth 2 info)
+                           (nreverse expired))))
+                (gnus-dribble-enter
+                 (concat "(gnus-group-set-info '"
+                         (gnus-prin1-to-string info)
+                         ")")))
+              (when lowest
+                (if (gnus-gethash group orig)
+                    (setcar (gnus-gethash group orig) lowest)
+                  (gnus-sethash group (cons lowest highest) orig))))
+            expiry-hashtb)
+           (set-buffer history)
+           (setq histories (nreverse (sort histories '<)))
+           (while histories
+             (goto-char (pop histories))
+             (gnus-delete-line))
+           (gnus-agent-save-history)
+           (gnus-agent-close-history)
+           (gnus-write-active-file
+            (gnus-agent-lib-file "active") orig))
+         (gnus-message 4 "Expiry...done"))))))
 
 ;;;###autoload
 (defun gnus-agent-batch ()
index 7ab2441..163c87b 100644 (file)
@@ -322,6 +322,7 @@ directly.")
         '(("\\*" "\\*" bold)
           ("_" "_" underline)
           ("/" "/" italic)
+          ("-" "-" strikethru)
           ("_/" "/_" underline-italic)
           ("_\\*" "\\*_" underline-bold)
           ("\\*/" "/\\*" bold-italic)
@@ -387,7 +388,11 @@ and the latter avoids underlining any whitespace at all."
 (defface gnus-emphasis-underline-bold-italic
   '((t (:bold t :italic t :underline t)))
   "Face used for displaying underlined bold italic emphasized text.
-Esample: (_/*word*/_)."
+Example: (_/*word*/_)."
+  :group 'gnus-article-emphasis)
+
+(defface gnus-emphasis-strikethru '((t (:strikethru t)))
+  "Face used for displaying strike-through text (-word-)."
   :group 'gnus-article-emphasis)
 
 (defface gnus-emphasis-highlight-words
@@ -1388,8 +1393,8 @@ It is a string, such as \"PGP\". If nil, ask user."
   (let ((table (copy-syntax-table text-mode-syntax-table)))
     ;; This causes the citation match run O(2^n).
     ;; (modify-syntax-entry ?- "w" table)
-    (modify-syntax-entry ?> ")" table)
-    (modify-syntax-entry ?< "(" table)
+    (modify-syntax-entry ?> ")<" table)
+    (modify-syntax-entry ?< "(>" table)
     table)
   "Syntax table used in article mode buffers.
 Initialized from `text-mode-syntax-table.")
@@ -1695,91 +1700,6 @@ always hide."
           (point-max)))
        'boring-headers))))
 
-(defun article-toggle-headers (&optional arg)
-  "Toggle hiding of headers.  If given a negative prefix, always show;
-if given a positive prefix, always hide."
-  (interactive (gnus-article-hidden-arg))
-  (let ((force (when (numberp arg)
-                (cond ((> arg 0) 'always-hide)
-                      ((< arg 0) 'always-show))))
-       (window (get-buffer-window gnus-article-buffer))
-       (header-end (point-min))
-       header-start field-end field-start
-       (inhibit-point-motion-hooks t)
-       (inhibit-read-only t))
-    (save-restriction
-      (widen)
-      (while (and (setq header-start
-                       (text-property-any header-end (point-max)
-                                          'article-treated-header t))
-                 (setq header-end
-                       (text-property-not-all header-start (point-max)
-                                              'article-treated-header t)))
-       (setq field-end header-start)
-       (cond
-        (;; Hide exposed invisible fields.
-         (and (not (eq 'always-show force))
-              (setq field-start
-                    (text-property-any field-end header-end
-                                       'exposed-invisible-field t)))
-         (while (and field-start
-                     (setq field-end (text-property-not-all
-                                      field-start header-end
-                                      'exposed-invisible-field t)))
-           (add-text-properties field-start field-end gnus-hidden-properties)
-           (setq field-start (text-property-any field-end header-end
-                                                'exposed-invisible-field t)))
-         (put-text-property header-start header-end
-                            'exposed-invisible-field nil))
-        (;; Expose invisible fields.
-         (and (not (eq 'always-hide force))
-              (setq field-start
-                    (text-property-any field-end header-end 'invisible t)))
-         (while (and field-start
-                     (setq field-end (text-property-not-all
-                                      field-start header-end
-                                      'invisible t)))
-           ;; If the invisible text is not terminated with newline, we
-           ;; won't expose it.  Because it may be created by x-face-mule.
-           ;; BTW, XEmacs sometimes fail in putting an invisible text
-           ;; property with `gnus-article-hide-text' (really?).  In that
-           ;; case, the invisible text might be started from the middle of
-           ;; a line, so we will expose the sort of thing.
-           (when (or (not (or (eq header-start field-start)
-                              (eq ?\n (char-before field-start))))
-                     (eq ?\n (char-before field-end))
-                     ;; Expose a boundary line anyway.
-                     (string-equal
-                      "\nX-Boundary: "
-                      (buffer-substring (max (- field-end 13) header-start)
-                                        field-end)))
-             (remove-text-properties field-start field-end
-                                     gnus-hidden-properties)
-             (put-text-property field-start field-end
-                                'exposed-invisible-field t))
-           (setq field-start (text-property-any field-end header-end
-                                                'invisible t))))
-        (;; Hide fields.
-         (not (eq 'always-show force))
-         (narrow-to-region header-start header-end)
-         (article-hide-headers)
-         ;; Re-display X-Face image under XEmacs.
-         (when (and (featurep 'xemacs)
-                    (gnus-functionp gnus-article-x-face-command))
-           (let ((func (cadr (assq 'gnus-treat-display-xface
-                                   gnus-treatment-function-alist)))
-                 (condition 'head))
-             (when (and (not gnus-inhibit-treatment)
-                        func
-                        (gnus-treat-predicate gnus-treat-display-xface))
-               (funcall func)
-               (put-text-property header-start header-end 'read-only nil))))
-         (widen))
-        ))
-      (goto-char (point-min))
-      (when window
-       (set-window-start window (point-min))))))
-
 (defvar gnus-article-normalized-header-length 40
   "Length of normalized headers.")
 
@@ -2297,7 +2217,10 @@ If READ-CHARSET, ask for a coding system."
       (goto-char (point-min))
       (while (re-search-forward
              "^\\(\\(https?\\|ftp\\)://\\S-+\\) *\n\\(\\S-+\\)" nil t)
-       (replace-match "\\1\\3" t)))))
+       (replace-match "\\1\\3" t)))
+    (when (and gnus-display-mime-function (interactive-p))
+      (funcall gnus-display-mime-function))))
+
 
 (defun article-wash-html (&optional read-charset)
   "Format an html article.
@@ -2910,7 +2833,7 @@ should replace the \"Date:\" one, or should be added below it."
             ":"
             (format "%02d" (nth 1 dtime)))))))
     (error
-     (format "Date: %s (from Oort)" date))))
+     (format "Date: %s (from T-gnus)" date))))
 
 (defun article-date-local (&optional highlight)
   "Convert the current article date to the local timezone."
@@ -3481,7 +3404,6 @@ If variable `gnus-use-long-file-name' is non-nil, it is
      article-verify-cancel-lock
      article-monafy
      article-hide-boring-headers
-     article-toggle-headers
      article-treat-overstrike
      article-fill-long-lines
      article-capitalize-sentences
@@ -3591,7 +3513,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is
      gnus-article-treatment-menu gnus-article-mode-map ""
      ;; Fixme: this should use :active (and maybe :visible).
      '("Treatment"
-       ["Hide headers" gnus-article-toggle-headers t]
+       ["Hide headers" gnus-article-hide-headers t]
        ["Hide signature" gnus-article-hide-signature t]
        ["Hide citation" gnus-article-hide-citation t]
        ["Treat overstrike" gnus-article-treat-overstrike t]
@@ -5408,6 +5330,8 @@ If given a prefix, show the hidden text instead."
            (let ((gnus-override-method gnus-override-method)
                  (methods (and (stringp article)
                                gnus-refer-article-method))
+                 (backend (car (gnus-find-method-for-group
+                                gnus-newsgroup-name)))
                  result
                  (buffer-read-only nil))
              (if (or (not (listp methods))
@@ -5426,7 +5350,8 @@ If given a prefix, show the hidden text instead."
                (gnus-kill-all-overlays)
                (let ((gnus-newsgroup-name group))
                  (gnus-check-group-server))
-               (when (gnus-request-article article group (current-buffer))
+               (cond
+                ((gnus-request-article article group (current-buffer))
                  (when (numberp article)
                    (gnus-async-prefetch-next group article
                                              gnus-summary-buffer)
@@ -5434,10 +5359,13 @@ If given a prefix, show the hidden text instead."
                      (gnus-backlog-enter-article
                       group article (current-buffer))))
                  (setq result 'article))
-               (if (not result)
-                   (if methods
-                       (setq gnus-override-method (pop methods))
-                     (setq result 'done))))
+                (methods
+                 (setq gnus-override-method (pop methods)))
+                ((not (string-match "^400 "
+                                    (nnheader-get-report backend)))
+                 ;; If we get 400 server disconnect, reconnect and
+                 ;; retry; otherwise, assume the article has expired.
+                 (setq result 'done))))
              (and (eq result 'article) 'article)))
           ;; It was a pseudo.
           (t article)))
index 69dc0d7..207f096 100644 (file)
@@ -342,7 +342,7 @@ Returns the list of articles entered."
     (gnus-summary-position-point)
     (nreverse out)))
 
-(defun gnus-cache-remove-article (n)
+(defun gnus-cache-remove-article (&optional n)
   "Remove the next N articles from the cache.
 If not given a prefix, use the process marked articles instead.
 Returns the list of articles removed."
index 65ce313..927abba 100644 (file)
@@ -1,6 +1,6 @@
 ;;; gnus-cite.el --- parse citations in articles for Gnus
 
-;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Per Abhiddenware
@@ -260,6 +260,11 @@ This should make it easier to see who wrote what."
   :group 'gnus-cite
   :type 'integer)
 
+(defcustom gnus-cite-blank-line-after-header t
+  "If non-nil, put a blank line between the citation header and the button."
+  :group 'gnus-cite
+  :type 'boolean)
+
 ;;; Internal Variables:
 
 (defvar gnus-cite-article nil)
@@ -519,7 +524,8 @@ always hide."
                  end (set-marker (make-marker) end))
            (gnus-add-text-properties-when 'article-type nil beg end props)
            (goto-char beg)
-           (unless (save-excursion (search-backward "\n\n" nil t))
+           (when (and gnus-cite-blank-line-after-header
+                      (not (save-excursion (search-backward "\n\n" nil t))))
              (insert "\n"))
            (put-text-property
             (setq start (point-marker))
index 7e712b8..cb4fc91 100644 (file)
@@ -145,10 +145,14 @@ DELAY is a string, giving the length of the time.  Possible values are:
   (interactive)
   (save-excursion
     (let* ((group (format "nndraft:%s" gnus-delay-group))
+          (message-send-hook (copy-sequence message-send-hook))
           articles
           article deadline)
       (when (gnus-gethash group gnus-newsrc-hashtb)
        (gnus-activate-group group)
+       (add-hook 'message-send-hook
+                 '(lambda ()
+                    (message-remove-header gnus-delay-header)))
        (setq articles (nndraft-articles))
        (while (setq article (pop articles))
          (gnus-request-head article group)
index 8a4d70a..b06a122 100644 (file)
     (defvar gnus-mouse-face-prop 'mouse-face
       "Property used for highlighting mouse regions.")))
 
-(eval-and-compile
-  (let ((case-fold-search t))
-    (cond
-     ((string-match "windows-nt\\|os/2\\|emx\\|cygwin32"
-                   (symbol-name system-type))
-      (setq nnheader-file-name-translation-alist
-           (append nnheader-file-name-translation-alist
-                   (mapcar (lambda (c) (cons c ?_))
-                           '(?: ?* ?\" ?< ?> ??))
-                   (if (string-match "windows-nt\\|cygwin32"
-                                     (symbol-name system-type))
-                       nil
-                     '((?+ . ?-)))))))))
-
 (defvar gnus-tmp-unread)
 (defvar gnus-tmp-replied)
 (defvar gnus-tmp-score-char)
index 4589fd7..fa2b54f 100644 (file)
@@ -122,6 +122,8 @@ Output to the current buffer, replace text, and don't mingle error."
         (ok-p t)
         (coding-system-for-read 'binary)
         (coding-system-for-write 'binary)
+        (input-coding-system 'binary)
+        (output-coding-system 'binary)
         default-enable-multibyte-characters
         start bit-array bit-arrays pixel)
     (with-temp-buffer
index 10631dc..9e153b1 100644 (file)
@@ -175,10 +175,10 @@ with some simple extensions.
 %E    Icon as defined by `gnus-group-icon-list'.
 %u    User defined specifier.  The next character in the format string should
       be a letter.  Gnus will call the function gnus-user-format-function-X,
-      where X is the letter following %u.  The function will be passed the
-      current header as argument.  The function should return a string, which
-      will be inserted into the buffer just like information from any other
-      group specifier.
+      where X is the letter following %u.  The function will be passed a 
+      single dummy parameter as argument..  The function should return a
+      string, which will be inserted into the buffer just like information
+      from any other group specifier.
 
 Note that this format specification is not always respected.  For
 reasons of efficiency, when listing killed groups, this specification
index 330b300..fc8fc33 100644 (file)
@@ -398,6 +398,7 @@ If BUFFER, insert the article in that group."
           (gnus-cache-request-article article group))
       (setq res (cons group article)
            clean-up t))
+     ;; Check the agent cache.
      ((and gnus-agent gnus-agent-cache gnus-plugged
           (numberp article)
           (gnus-agent-request-article article group))
@@ -484,17 +485,26 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned."
             info (nth 1 gnus-command-method))))
 
 (defun gnus-request-expire-articles (articles group &optional force)
-  (let ((gnus-command-method (gnus-find-method-for-group group)))
-    (funcall (gnus-get-function gnus-command-method 'request-expire-articles)
-            articles (gnus-group-real-name group) (nth 1 gnus-command-method)
-            force)))
-
-(defun gnus-request-move-article
-  (article group server accept-function &optional last)
-  (let ((gnus-command-method (gnus-find-method-for-group group)))
-    (funcall (gnus-get-function gnus-command-method 'request-move-article)
-            article (gnus-group-real-name group)
-            (nth 1 gnus-command-method) accept-function last)))
+  (let* ((gnus-command-method (gnus-find-method-for-group group))
+        (not-deleted
+         (funcall
+          (gnus-get-function gnus-command-method 'request-expire-articles)
+          articles (gnus-group-real-name group) (nth 1 gnus-command-method)
+          force)))
+    (when (and gnus-agent gnus-agent-cache
+              (gnus-sorted-difference articles not-deleted))
+      (gnus-agent-expire (gnus-sorted-difference articles not-deleted)
+                        group 'force))
+    not-deleted))
+
+(defun gnus-request-move-article (article group server accept-function &optional last)
+  (let* ((gnus-command-method (gnus-find-method-for-group group))
+        (result (funcall (gnus-get-function gnus-command-method 'request-move-article)
+                         article (gnus-group-real-name group)
+                         (nth 1 gnus-command-method) accept-function last)))
+    (when (and result gnus-agent gnus-agent-cache)
+      (gnus-agent-expire (list article) group 'force))
+    result))
 
 (defun gnus-request-accept-article (group &optional gnus-command-method last
                                          no-encode)
index b9b7fbb..20fe9e0 100644 (file)
 (defun gnus-advanced-integer (index match type)
   (if (not (memq type '(< > <= >= =)))
       (error "No such integer score type: %s" type)
-    (funcall type match (or (aref gnus-advanced-headers index) 0))))
+    (funcall type (or (aref gnus-advanced-headers index) 0) match)))
 
 (defun gnus-advanced-date (index match type)
   (let ((date (apply 'encode-time (parse-time-string
index bcfedf6..6bf7aaf 100644 (file)
@@ -241,11 +241,25 @@ See also the `mml-default-encrypt-method' variable."
   :type 'boolean)
 
 (defcustom gnus-message-replysignencrypted
-  nil
+  t
   "Setting this causes automatically encryped messages to also be signed."
   :group 'gnus-message
   :type 'boolean)
 
+(defcustom gnus-confirm-mail-reply-to-news nil
+  "If non-nil, Gnus requests confirmation when replying to news.
+This is done because new users often reply by mistake when reading
+news."
+  :group 'gnus-message
+  :type 'boolean)
+
+(defcustom gnus-summary-resend-default-address t
+  "If non-nil, Gnus tries to suggest a default address to resend to.
+If nil, the address field will always be empty after invoking
+`gnus-summary-resend-message'."
+  :group 'gnus-message
+  :type 'boolean)
+
 ;;; Internal variables.
 
 (defvar gnus-inhibit-posting-styles nil
@@ -492,6 +506,8 @@ If ARG is 1, prompt for a group name to find the posting style."
   ;; We can't `let' gnus-newsgroup-name here, since that leads
   ;; to local variables leaking.
   (let ((group gnus-newsgroup-name)
+       ;; make sure last viewed article doesn't affect posting styles:
+       (gnus-article-copy)
        (buffer (current-buffer)))
     (unwind-protect
        (progn
@@ -521,6 +537,8 @@ network.  The corresponding backend must have a 'request-post method."
   ;; We can't `let' gnus-newsgroup-name here, since that leads
   ;; to local variables leaking.
   (let ((group gnus-newsgroup-name)
+       ;; make sure last viewed article doesn't affect posting styles:
+       (gnus-article-copy)
        (buffer (current-buffer)))
     (unwind-protect
        (progn
@@ -552,7 +570,9 @@ a news."
                 (completing-read "Newsgroup: " gnus-active-hashtb nil
                                  (gnus-read-active-file-p))
               (gnus-group-group-name))
-          "")))
+          ""))
+       ;; make sure last viewed article doesn't affect posting styles:
+       (gnus-article-copy))
     (gnus-post-news 'post gnus-newsgroup-name)))
 
 (defun gnus-summary-mail-other-window (&optional arg)
@@ -564,6 +584,8 @@ posting style."
   ;; We can't `let' gnus-newsgroup-name here, since that leads
   ;; to local variables leaking.
   (let ((group gnus-newsgroup-name)
+       ;; make sure last viewed article doesn't affect posting styles:
+       (gnus-article-copy)
        (buffer (current-buffer)))
     (unwind-protect
        (progn
@@ -593,6 +615,8 @@ network.  The corresponding backend must have a 'request-post method."
   ;; We can't `let' gnus-newsgroup-name here, since that leads
   ;; to local variables leaking.
   (let ((group gnus-newsgroup-name)
+       ;; make sure last viewed article doesn't affect posting styles:
+       (gnus-article-copy)
        (buffer (current-buffer)))
     (unwind-protect
        (progn
@@ -624,7 +648,9 @@ a news."
                 (completing-read "Newsgroup: " gnus-active-hashtb nil
                                  (gnus-read-active-file-p))
               "")
-          gnus-newsgroup-name)))
+          gnus-newsgroup-name))
+       ;; make sure last viewed article doesn't affect posting styles:
+       (gnus-article-copy))
     (gnus-post-news 'post gnus-newsgroup-name)))
 
 
@@ -650,7 +676,8 @@ yanked."
     ;; Send a followup.
     (gnus-post-news nil gnus-newsgroup-name
                    headers gnus-article-buffer
-                   yank nil force-news)))
+                   yank nil force-news)
+    (gnus-summary-handle-replysign)))
 
 (defun gnus-summary-followup-with-original (n &optional force-news)
   "Compose a followup to an article and include the original article."
@@ -699,7 +726,10 @@ yanked."
            (message-reply-headers
             ;; The headers are decoded.
             (with-current-buffer gnus-article-copy
-              (nnheader-parse-head t))))
+              (save-restriction
+                (nnheader-narrow-to-headers)
+                (ietf-drums-unfold-fws)
+                (nnheader-parse-head t)))))
        (message-yank-original)
        (setq beg (or beg (mark t))))
       (when articles
@@ -1091,51 +1121,59 @@ If VERY-WIDE, make a very wide reply."
   (interactive
    (list (and current-prefix-arg
              (gnus-summary-work-articles 1))))
-  (let* ((article
-         (if (listp (car yank))
-             (caar yank)
-           (car yank)))
-        (gnus-article-reply (or article (gnus-summary-article-number)))
-        (headers ""))
-    ;; Stripping headers should be specified with mail-yank-ignored-headers.
-    (when yank
-      (gnus-summary-goto-subject article))
-    (gnus-setup-message (if yank 'reply-yank 'reply)
-      (if (not very-wide)
-         (gnus-summary-select-article)
-       (dolist (article very-wide)
-         (gnus-summary-select-article nil nil nil article)
-         (save-excursion
-           (set-buffer (gnus-copy-article-buffer))
-           (gnus-msg-treat-broken-reply-to)
-           (save-restriction
-             (message-narrow-to-head)
-             (setq headers (concat headers (buffer-string)))))))
-      (set-buffer (gnus-copy-article-buffer))
-      (gnus-msg-treat-broken-reply-to gnus-msg-force-broken-reply-to)
-      (save-restriction
-       (message-narrow-to-head)
-       (when very-wide
-         (erase-buffer)
-         (insert headers))
-       (goto-char (point-max)))
-      (message-reply nil wide)
+  ;; Allow user to require confirmation before replying by mail to the
+  ;; author of a news article.
+  (when (or (not (gnus-news-group-p gnus-newsgroup-name))
+           (not gnus-confirm-mail-reply-to-news)
+           (y-or-n-p "Really reply by mail to article author? "))
+    (let* ((article
+           (if (listp (car yank))
+               (caar yank)
+             (car yank)))
+          (gnus-article-reply (or article (gnus-summary-article-number)))
+          (headers ""))
+      ;; Stripping headers should be specified with mail-yank-ignored-headers.
       (when yank
-       (gnus-inews-yank-articles yank))
-;;      (when (or gnus-message-replysign gnus-message-replyencrypt)
-;;     (let (signed encrypted)
-;;       (save-excursion
-;;         (set-buffer gnus-article-buffer)
-;;         (setq signed (memq 'signed gnus-article-wash-types))
-;;         (setq encrypted (memq 'encrypted gnus-article-wash-types)))
-;;       (cond ((and gnus-message-replysign signed)
-;;              (mml-secure-message mml-default-sign-method 'sign))
-;;             ((and gnus-message-replyencrypt encrypted)
-;;              (mml-secure-message mml-default-encrypt-method
-;;                                  (if gnus-message-replysignencrypted
-;;                                      'signencrypt
-;;                                    'encrypt))))))
-      )))
+       (gnus-summary-goto-subject article))
+      (gnus-setup-message (if yank 'reply-yank 'reply)
+       (if (not very-wide)
+           (gnus-summary-select-article)
+         (dolist (article very-wide)
+           (gnus-summary-select-article nil nil nil article)
+           (save-excursion
+             (set-buffer (gnus-copy-article-buffer))
+             (gnus-msg-treat-broken-reply-to)
+             (save-restriction
+               (message-narrow-to-head)
+               (setq headers (concat headers (buffer-string)))))))
+       (set-buffer (gnus-copy-article-buffer))
+       (gnus-msg-treat-broken-reply-to gnus-msg-force-broken-reply-to)
+       (save-restriction
+         (message-narrow-to-head)
+         (when very-wide
+           (erase-buffer)
+           (insert headers))
+         (goto-char (point-max)))
+       (message-reply nil wide)
+       (when yank
+         (gnus-inews-yank-articles yank))
+       (gnus-summary-handle-replysign)))))
+
+(defun gnus-summary-handle-replysign ()
+  "Check the various replysign variables and take action accordingly."
+  (when nil;;(or gnus-message-replysign gnus-message-replyencrypt)
+    (let (signed encrypted)
+      (save-excursion
+       (set-buffer gnus-article-buffer)
+       (setq signed (memq 'signed gnus-article-wash-types))
+       (setq encrypted (memq 'encrypted gnus-article-wash-types)))
+      (cond ((and gnus-message-replysign signed)
+            (mml-secure-message mml-default-sign-method 'sign))
+           ((and gnus-message-replyencrypt encrypted)
+            (mml-secure-message mml-default-encrypt-method
+                                (if gnus-message-replysignencrypted
+                                    'signencrypt
+                                  'encrypt)))))))
 
 (defun gnus-summary-reply-with-original (n &optional wide)
   "Start composing a reply mail to the current message.
@@ -1275,7 +1313,8 @@ forward those articles instead."
   (interactive
    (list (message-read-from-minibuffer
          "Resend message(s) to: "
-         (when (gnus-buffer-live-p gnus-original-article-buffer)
+         (when (and gnus-summary-resend-default-address
+                    (gnus-buffer-live-p gnus-original-article-buffer))
            ;; If some other article is currently selected, the
            ;; initial-contents is wrong. Whatever, it is just the
            ;; initial-contents.
index 6883870..4940d6c 100644 (file)
@@ -1,4 +1,4 @@
-;;; gnus-namazu.el --- Search mail with Namazu. -*- coding: iso-2022-7bit; -*-
+;;; gnus-namazu.el --- Search mail with Namazu -*- coding: iso-2022-7bit; -*-
 
 ;; Copyright (C) 2000,2001,2002 TSUCHIYA Masatoshi <tsuchiya@namazu.org>
 
 ;;; Commentary:
 
 ;; This file defines the command to search mails and persistent
-;; articles with Namazu and browse its results with Gnus.  This module
-;; requires the external command, Namazu.  Visit the following page
-;; for more information.
+;; articles with Namazu and to browse its results with Gnus.
+;;
+;; Namazu is a full-text search engine intended for easy use.  For
+;; more detail about Namazu, visit the following page:
 ;;
 ;;     http://namazu.org/
 
 
+;;; Quick Start:
+
+;; If this module has already been installed, only 3 steps are
+;; required to search articles with this module.
+;;
+;;   (1) Install Namazu.
+;;   (2) Start Gnus and type M-x gnus-namazu-create-index RET to make
+;;       index of articles.
+;;   (3) In group buffer or in summary buffer, type C-c C-n query RET.
+
+
 ;;; Install:
 
-;; Make index of articles with Namzu before using this module.
+;; Before installing this module, you must install Namazu.
+;;
+;; This file is a part of T-gnus but is not *YET* a part of Gnus.
+;; When you would like to use this module in Gnus (not T-gnus), put
+;; this file into the lisp/ directory in the Gnus source tree and run
+;; `make install'.  And then, put the following expression into your
+;; ~/.gnus.
+;;
+;;      (require 'gnus-namazu)
+;;      (gnus-namazu-insinuate)
 ;;
-;;      % mkdir ~/News/namazu
-;;       % mknmz -a -h -O ~/News/namazu ~/Mail ~/News/cache
+;; In order to make index of articles with Namazu before using this
+;; module, type M-x gnus-namazu-create-index RET.  Otherwise, you can
+;; create index by yourself with the following commands:
+;;
+;;      % mkdir ~/News/namazu
+;;      % mknmz -a -h -O ~/News/namazu ~/Mail ~/News/cache
 ;;
 ;; The first command makes the directory for index files, and the
 ;; second command generates index files of mails and persistent
 ;; articles.
 ;;
-;; When you put index files of Namazu into the directory other than
-;; the default one (~/News/namazu), it is necessary to put this
-;; expression to your ~/.gnus, in order to set the path of index files
-;; to `gnus-namazu-index-directories'.
+;; In order to update indices for incoming articles, this module
+;; automatically runs mknmz, the indexer of Namazu, at an interval of
+;; 3 days; this period is set to `gnus-namazu-index-update-interval'.
 ;;
-;;      (setq gnus-namazu-index-directories
-;;            (list (expand-file-name "~/namazu")))
+;; Indices will be updated when `gnus-namazu-search' is called.  If
+;; you want to update indices everywhen Gnus is started, you can put
+;; the following expression to your ~/.gnus.
 ;;
-;; If you would like to use this module in Gnus (not T-gnus), put this
-;; file into the lisp/ directory in the Gnus source tree and run `make
-;; install'.  And then, put the following expressions into your ~/.gnus.
+;;      (add-hook 'gnus-startup-hook 'gnus-namazu-update-all-indices)
 ;;
-;;      (require 'gnus-namazu)
-;;      (gnus-namazu-insinuate)
-
-
-;;; Usage:
-
-;; In group buffer or in summary buffer, type C-c C-n query RET.
+;; In order to control mknmz closely, disable the automatic updating
+;; feature and run mknmz by yourself.  In this case, set nil to the
+;; above option.
+;;
+;;      (setq gnus-namazu-index-update-interval nil)
+;;
+;; When your index is put into the directory other than the default
+;; one (~/News/namazu), it is necessary to set its place to
+;; `gnus-namazu-index-directories' as follows:
+;;
+;;      (setq gnus-namazu-index-directories
+;;            (list (expand-file-name "~/namazu")))
 
 
 ;;; Code:
 ;; To suppress byte-compile warning.
 (eval-when-compile
   (defvar nnml-directory)
-  (defvar nnml-group-alist)
-  (defvar nnmh-directory)
-  (defvar nnmh-group-alist))
+  (defvar nnmh-directory))
 
 
 (defgroup gnus-namazu nil
   :group 'gnus
   :prefix "gnus-namazu-")
 
+(defconst gnus-namazu-default-index-directory
+  (expand-file-name "namazu" gnus-directory)
+  "Default place of Namazu index files.")
+
 (defcustom gnus-namazu-index-directories
   (list
    (or (and (boundp 'gnus-namazu-index-directory)
            (symbol-value 'gnus-namazu-index-directory))
        (and (boundp 'nnir-namazu-index-directory)
            (symbol-value 'nnir-namazu-index-directory))
-       (expand-file-name "namazu" gnus-directory)))
-  "*Index directory of Namazu."
+       gnus-namazu-default-index-directory))
+  "*Places of Namazu index files."
   :type '(repeat directory)
   :group 'gnus-namazu)
 
           (symbol-value 'nnir-namazu-program))
       "namazu")
   "*Name of the executable file of Namazu."
-  :group 'gnus-namazu
-  :type 'string)
+  :type 'string
+  :group 'gnus-namazu)
 
 (defcustom gnus-namazu-additional-arguments nil
   "*Additional arguments of Namazu.
@@ -119,6 +149,30 @@ options make any sense in this context."
   :type '(repeat string)
   :group 'gnus-namazu)
 
+(defcustom gnus-namazu-index-update-interval
+  259200                               ; 3 days == 259200 seconds.
+  "*Number of seconds between running the indexer of Namazu."
+  :type '(choice (const :tag "Never run the indexer" nil)
+                (integer :tag "Number of seconds"))
+  :group 'gnus-namazu)
+
+(defcustom gnus-namazu-make-index-command "mknmz"
+  "*Name of the executable file of the indexer of Namazu."
+  :type 'string
+  :group 'gnus-namazu)
+
+(defcustom gnus-namazu-make-index-arguments
+  (nconc
+   (list "--all" "--mailnews" "--deny=^.*[^0-9].*$")
+   (when (or (and (boundp 'current-language-environment)
+                 (string= "Japanese"
+                          (symbol-value 'current-language-environment)))
+            (boundp 'MULE))
+     (list "--indexing-lang=ja")))
+  "*Arguments of the indexer of Namazu."
+  :type '(repeat string)
+  :group 'gnus-namazu)
+
 (defcustom gnus-namazu-field-keywords
   '("date" "from" "newsgroups" "size" "subject" "summary" "to" "uri")
   "*List of keywords to do field-search."
@@ -134,8 +188,8 @@ options make any sense in this context."
   :group 'gnus-namazu)
 
 (defcustom gnus-namazu-need-path-normalization
-  (eq system-type 'windows-nt)
-  "*Non-nil means that outputs of namazu may contain a not normalized path."
+  (and (memq system-type '(windows-nt OS/2 emx)) t)
+  "*Non-nil means that outputs of namazu may contain drive letters."
   :type 'boolean
   :group 'gnus-namazu)
 
@@ -194,6 +248,12 @@ options make any sense in this context."
    (gnus-servers-using-backend 'nnml)
    (gnus-servers-using-backend 'nnmh)))
 
+(defsubst gnus-namazu/default-index-directory ()
+  (if (member gnus-namazu-default-index-directory
+             gnus-namazu-index-directories)
+      gnus-namazu-default-index-directory
+    (car gnus-namazu-index-directories)))
+
 (defun gnus-namazu/setup ()
   (and (boundp 'gnus-group-name-charset-group-alist)
        (not (member (cons gnus-namazu/group-name-regexp
@@ -205,17 +265,8 @@ options make any sense in this context."
             (setcdr pair gnus-namazu-coding-system)
           (push (cons gnus-namazu/group-name-regexp
                       gnus-namazu-coding-system)
-                gnus-group-name-charset-group-alist)))))
-
-(defun gnus-namazu/request-list (server)
-  "Return groups of the server SERVER."
-  (and (memq (car server) '(nnml nnmh))
-       (nnoo-change-server (car server) (nth 1 server) (nthcdr 2 server))
-       (gnus-request-list server)
-       (mapcar (function car)
-              (if (eq 'nnml (car server))
-                  nnml-group-alist
-                nnmh-group-alist))))
+                gnus-group-name-charset-group-alist))))
+  (gnus-namazu-update-all-indices))
 
 (defun gnus-namazu/server-directory (server)
   "Return the top directory of the server SERVER."
@@ -231,6 +282,8 @@ options make any sense in this context."
   "Normalize file names returned by Namazu in this current buffer."
   (goto-char (point-min))
   (while (not (eobp))
+    (when (looking-at "file://")
+      (delete-region (point) (match-end 0)))
     (when (if gnus-namazu-need-path-normalization
              (or (not (looking-at "/\\(.\\)|/"))
                  (replace-match "\\1:/"))
@@ -243,8 +296,11 @@ options make any sense in this context."
 (defsubst gnus-namazu/call-namazu (query)
   (let ((coding-system-for-read gnus-namazu-coding-system)
        (coding-system-for-write gnus-namazu-coding-system)
+       (input-coding-system gnus-namazu-coding-system)
+       (output-coding-system gnus-namazu-coding-system)
        (default-process-coding-system
          (cons gnus-namazu-coding-system gnus-namazu-coding-system))
+       program-coding-system-alist
        (file-name-coding-system gnus-namazu-coding-system)
        (pathname-coding-system gnus-namazu-coding-system))
     (apply 'call-process
@@ -272,17 +328,17 @@ options make any sense in this context."
                  gnus-newsrc-hashtb)
        orig))))
 
-(defun gnus-namazu/check-cache-group (str)
-  "Get the news group from the partial path STR of the cached article."
-  (if (gnus-use-long-file-name 'not-cache)
+(defun gnus-namazu/real-group-name (cond str)
+  "Generate the real group name from the partial path, STR."
+  (if cond
       str
     (catch 'found-group
-      (dolist (group (gnus-namazu/cache-group-candidates
+      (dolist (group (gnus-namazu/possible-real-groups
                      (nnheader-replace-chars-in-string str ?/ ?.)))
        (when (gnus-gethash group gnus-newsrc-hashtb)
          (throw 'found-group group))))))
 
-(defun gnus-namazu/cache-group-candidates (str)
+(defun gnus-namazu/possible-real-groups (str)
   "Regard the string STR as the partial path of the cached article and
 generate possible group names from it."
   (if (string-match "_\\(_\\(_\\)?\\)?" str)
@@ -291,14 +347,14 @@ generate possible group names from it."
        (cond
         ((match-beginning 2) ;; The number of discoverd underscores = 3
          (nconc
-          (gnus-namazu/cache-group-candidates (concat prefix "/__" suffix))
-          (gnus-namazu/cache-group-candidates (concat prefix ".._" suffix))))
+          (gnus-namazu/possible-real-groups (concat prefix "/__" suffix))
+          (gnus-namazu/possible-real-groups (concat prefix ".._" suffix))))
         ((match-beginning 1) ;; The number of discoverd underscores = 2
          (nconc
-          (gnus-namazu/cache-group-candidates (concat prefix "//" suffix))
-          (gnus-namazu/cache-group-candidates (concat prefix ".." suffix))))
+          (gnus-namazu/possible-real-groups (concat prefix "//" suffix))
+          (gnus-namazu/possible-real-groups (concat prefix ".." suffix))))
         (t ;; The number of discoverd underscores = 1
-         (gnus-namazu/cache-group-candidates (concat prefix "/" suffix)))))
+         (gnus-namazu/possible-real-groups (concat prefix "/" suffix)))))
     (if (string-match "\\." str)
        ;; Handle the first occurence of period.
        (list (concat (substring str 0 (match-beginning 0))
@@ -326,6 +382,11 @@ generate possible group names from it."
                            (regexp-quote
                             (file-name-as-directory
                              (expand-file-name gnus-cache-directory)))
+                           "\\(.*\\)/\\([0-9]+\\)$"))
+            (agent-regexp (concat
+                           (regexp-quote
+                            (file-name-as-directory
+                             (expand-file-name gnus-agent-directory)))
                            "\\(.*\\)/\\([0-9]+\\)$")))
        (gnus-namazu/normalize-results)
        (goto-char (point-min))
@@ -335,7 +396,14 @@ generate possible group names from it."
                  ;; Check the discoverd file is the persistent article.
                  (and (looking-at cache-regexp)
                       (setq file (match-string-no-properties 2)
-                            group (gnus-namazu/check-cache-group
+                            group (gnus-namazu/real-group-name
+                                   (gnus-use-long-file-name 'not-cache)
+                                   (match-string-no-properties 1))))
+                 ;; Check the discoverd file is covered by the agent.
+                 (and (looking-at agent-regexp)
+                      (setq file (match-string-no-properties 2)
+                            group (gnus-namazu/real-group-name
+                                   nnmail-use-long-file-names
                                    (match-string-no-properties 1))))
                  ;; Check the discovered file is managed by Gnus servers.
                  (and (looking-at topdir-regexp)
@@ -350,7 +418,10 @@ generate possible group names from it."
                               file (match-string 1 file))
                         (setq group
                               (gnus-namazu/group-prefixed-name
-                               (nnheader-replace-chars-in-string group ?/ ?.)
+                               (if nnmail-use-long-file-names
+                                   group
+                                 (nnheader-replace-chars-in-string group
+                                                                   ?/ ?.))
                                server)))))
                 (or (not groups)
                     (member group groups))
@@ -418,6 +489,15 @@ generate possible group names from it."
                  (mail-header-from
                   (gnus-summary-article-header))))))))
 
+(defun gnus-namazu/get-current-to ()
+  (and gnus-namazu/read-query-original-buffer
+       (bufferp gnus-namazu/read-query-original-buffer)
+       (with-current-buffer gnus-namazu/read-query-original-buffer
+        (when (eq major-mode 'gnus-summary-mode)
+          (cadr (mail-extract-address-components
+                 (cdr (assq 'To (mail-header-extra
+                                 (gnus-summary-article-header))))))))))
+
 (defmacro gnus-namazu/minibuffer-prompt-end ()
   (if (fboundp 'minibuffer-prompt-end)
       '(minibuffer-prompt-end)
@@ -485,6 +565,13 @@ generate possible group names from it."
        (when f
          (goto-char pos)
          (insert "\"" f "\"")
+         (setq pos (point)))))
+     ((and (looking-at "\\+to:")
+          (= pos (match-end 0)))
+      (let ((to (gnus-namazu/get-current-to)))
+       (when to
+         (goto-char pos)
+         (insert "\"" to "\"")
          (setq pos (point))))))
     (goto-char pos)))
 
@@ -597,6 +684,186 @@ and make a virtual group contains its results."
                 '<)))
       (message "No entry."))))
 
+(defmacro gnus-namazu/lock-file-name (&optional directory)
+  `(expand-file-name "NMZ.lock2" ,directory))
+
+(defmacro gnus-namazu/status-file-name (&optional directory)
+  `(expand-file-name "NMZ.status" ,directory))
+
+(defmacro gnus-namazu/index-file-name (&optional directory)
+  `(expand-file-name "NMZ.i" ,directory))
+
+(defun gnus-namazu/mknmz-cleanup (directory)
+  (let ((lockfile (gnus-namazu/lock-file-name directory)))
+    (when (file-exists-p lockfile)
+      (delete-file lockfile)
+      (dolist (tmpfile (directory-files directory t "\\`NMZ\\..*\\.tmp\\'" t))
+       (delete-file tmpfile)))))
+
+;;;###autoload
+(defun gnus-namazu-create-index (directory &optional target-directories force)
+  "Create index under DIRECTORY."
+  (interactive
+   (list
+    (if (and current-prefix-arg (> (length gnus-namazu-index-directories) 1))
+       (completing-read "Directory: "
+                        (mapcar 'list gnus-namazu-index-directories) nil t)
+      (gnus-namazu/default-index-directory))
+    nil t))
+  (setq directory (file-name-as-directory (expand-file-name directory)))
+  (unless target-directories
+    (setq target-directories
+         (delq nil
+               (mapcar (lambda (dir)
+                         (when (file-directory-p dir) dir))
+                       (append
+                        (mapcar 'gnus-namazu/server-directory
+                                (gnus-namazu/indexed-servers))
+                        (list
+                         (expand-file-name gnus-cache-directory)
+                         (expand-file-name gnus-agent-directory)))))))
+  (if (file-exists-p (gnus-namazu/lock-file-name directory))
+      (when force
+       (error "Found lock file: %s" (gnus-namazu/lock-file-name directory)))
+    (with-current-buffer
+       (get-buffer-create (concat " *mknmz*" directory))
+      (erase-buffer)
+      (unless (file-directory-p directory)
+       (make-directory directory t))
+      (setq default-directory directory)
+      (let ((args (append gnus-namazu-make-index-arguments
+                         target-directories)))
+       (insert "% " gnus-namazu-make-index-command " "
+               (mapconcat 'identity args " ") "\n")
+       (goto-char (point-max))
+       (when force
+         (pop-to-buffer (current-buffer)))
+       (message "Make index at %s..." directory)
+       (unwind-protect
+           (apply 'call-process gnus-namazu-make-index-command nil t t args)
+         (gnus-namazu/mknmz-cleanup directory))
+       (message "Make index at %s...done" directory)
+       (unless force
+         (kill-buffer (current-buffer)))))))
+
+(defun gnus-namazu/lapse-seconds (start end)
+  "Return lapse seconds from START to END.
+START and END are lists which represent time in Emacs-style."
+  (+ (* (- (car end) (car start)) 65536)
+     (cadr end)
+     (- (cadr start))))
+
+(defun gnus-namazu/index-old-p (directory)
+  "Return non-nil value when the index under the DIRECTORY is older
+than the period that is set to `gnus-namazu-index-update-interval'"
+  (let ((file (gnus-namazu/index-file-name directory)))
+    (or (not (file-exists-p file))
+       (and (integerp gnus-namazu-index-update-interval)
+            (>= (gnus-namazu/lapse-seconds
+                 (nth 5 (file-attributes file))
+                 (current-time))
+                gnus-namazu-index-update-interval)))))
+
+(defvar gnus-namazu/update-directories nil)
+(defvar gnus-namazu/update-process nil)
+
+(defun gnus-namazu/update-p (directory &optional force)
+  "Return the DIRECTORY when the index undef the DIRECTORY should be updated."
+  (setq directory (file-name-as-directory (expand-file-name directory)))
+  (labels ((error-message (format &rest args)
+                         (apply (if force 'error 'message) format args)
+                         nil))
+    (if gnus-namazu/update-process
+       (error-message "%s" "Can not run two update processes simultaneously")
+      (and (or force
+              (gnus-namazu/index-old-p directory))
+          (let ((status-file (gnus-namazu/status-file-name directory)))
+            (or (file-exists-p status-file)
+                (error-message "Can not find status file: %s" status-file)))
+          (let ((lock-file (gnus-namazu/lock-file-name directory)))
+            (or (not (file-exists-p lock-file))
+                (error-message "Found lock file: %s" lock-file)))
+          directory))))
+
+;;;###autoload
+(defun gnus-namazu-update-index (directory &optional force)
+  "Update the index under the DIRECTORY."
+  (interactive
+   (list
+    (if (and current-prefix-arg (> (length gnus-namazu-index-directories) 1))
+       (completing-read "Directory: "
+                        (mapcar 'list gnus-namazu-index-directories) nil t)
+      (gnus-namazu/default-index-directory))
+    t))
+  (when (setq directory (gnus-namazu/update-p directory force))
+    (with-current-buffer (get-buffer-create (concat " *mknmz*" directory))
+      (buffer-disable-undo)
+      (erase-buffer)
+      (unless (file-directory-p directory)
+       (make-directory directory t))
+      (setq default-directory directory)
+      (let ((proc (start-process gnus-namazu-make-index-command
+                                (current-buffer)
+                                gnus-namazu-make-index-command
+                                (format "--update=%s" directory))))
+       (if (processp proc)
+           (prog1 (setq gnus-namazu/update-process proc)
+             (process-kill-without-query proc)
+             (set-process-sentinel proc 'gnus-namazu/update-sentinel)
+             (add-hook 'kill-emacs-hook 'gnus-namazu-stop-update)
+             (message "Update index at %s..." directory))
+         (goto-char (point-min))
+         (if (re-search-forward "^ERROR:.*$" nil t)
+             (progn
+               (pop-to-buffer (current-buffer))
+               (funcall (if force 'error 'message)
+                        "Update index at %s...%s" directory (match-string 0)))
+           (kill-buffer (current-buffer))
+           (funcall (if force 'error 'message)
+                    "Can not start %s" gnus-namazu-make-index-command))
+         nil)))))
+
+;;;###autoload
+(defun gnus-namazu-update-all-indices (&optional directories force)
+  "Update all indices which is set to `gnus-namazu-index-directories'."
+  (interactive (list nil t))
+  (when (setq directories
+             (delq nil (mapcar
+                        (lambda (d) (gnus-namazu/update-p d force))
+                        (or directories gnus-namazu-index-directories))))
+    (setq gnus-namazu/update-directories (cdr directories))
+    (gnus-namazu-update-index (car directories))))
+
+(defun gnus-namazu/update-sentinel (process event)
+  (let ((buffer (process-buffer process)))
+    (when (buffer-name buffer)
+      (with-current-buffer buffer
+       (gnus-namazu/mknmz-cleanup default-directory)
+       (goto-char (point-min))
+       (cond
+        ((re-search-forward "^ERROR:.*$" nil t)
+         (pop-to-buffer (current-buffer))
+         (message "Update index at %s...%s"
+                  default-directory (match-string 0))
+         (setq gnus-namazu/update-directories nil))
+        ((and (eq 'exit (process-status process))
+              (zerop (process-exit-status process)))
+         (message "Update index at %s...done" default-directory)
+         (unless (or debug-on-error debug-on-quit)
+           (kill-buffer buffer)))))))
+  (setq gnus-namazu/update-process nil)
+  (when gnus-namazu/update-directories
+    (gnus-namazu-update-all-indices gnus-namazu/update-directories)))
+
+;;;###autoload
+(defun gnus-namazu-stop-update ()
+  "Stop the running indexer of Namazu."
+  (interactive)
+  (setq gnus-namazu/update-directories nil)
+  (and gnus-namazu/update-process
+       (processp gnus-namazu/update-process)
+       (kill-process gnus-namazu/update-process)))
+
 (let (current-load-list)
   (defadvice gnus-offer-save-summaries
     (before gnus-namazu-kill-summary-buffers activate compile)
@@ -614,6 +881,7 @@ is called."
          (kill-buffer (car buffers)))
        (setq buffers (cdr buffers))))))
 
+;;;###autoload
 (defun gnus-namazu-insinuate ()
   (add-hook
    'gnus-group-mode-hook
index 15b6fb9..44f45f1 100644 (file)
@@ -368,7 +368,7 @@ This must be bound to a button-down mouse event."
 (defun gnus-binary-display-article (article &optional all-header)
   "Run ARTICLE through the binary decode functions."
   (when (gnus-summary-goto-subject article)
-    (let ((gnus-view-pseudos 'automatic))
+    (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic)))
       (gnus-uu-decode-uu))))
 
 (defun gnus-binary-show-article (&optional arg)
index 18300ed..2fb82f9 100644 (file)
@@ -118,7 +118,7 @@ See the documentation for these variables and functions for details."
   "Guess a sieve rule based on RFC822 article in buffer.
 Return nil if no rule could be guessed."
   (when (message-fetch-field "sender")
-    `(sieve address "sender" ,(regexp-quote (message-fetch-field "sender")))))
+    `(sieve address "sender" ,(message-fetch-field "sender"))))
 
 ;;;###autoload
 (defun gnus-sieve-article-add-rule ()
index cf4b856..14725c5 100644 (file)
@@ -812,7 +812,11 @@ cautiously -- unloading may cause trouble."
       (set-buffer gnus-dribble-buffer)
       (goto-char (point-max))
       (insert string "\n")
-      (set-window-point (get-buffer-window (current-buffer)) (point-max))
+      ;; This has been commented by Josh Huber <huber@alum.wpi.edu>
+      ;; It causes problems with both XEmacs and Emacs 21, and doesn't
+      ;; seem to be of much value. (FIXME: remove this after we make sure
+      ;; it's not needed).
+      ;; (set-window-point (get-buffer-window (current-buffer)) (point-max))
       (bury-buffer gnus-dribble-buffer)
       (save-excursion
        (set-buffer gnus-group-buffer)
index 9cfd3a7..3834da6 100644 (file)
@@ -54,7 +54,7 @@
 (autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t)
 (autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t)
 (autoload 'mm-uu-dissect "mm-uu")
-(autoload 'gnus-article-outlook-deuglify-article "deuglify" 
+(autoload 'gnus-article-outlook-deuglify-article "deuglify"
   "Deuglify broken Outlook (Express) articles and redisplay."
   t)
 
@@ -147,8 +147,9 @@ comparing subjects."
   "List of functions taking a string argument that simplify subjects.
 The functions are applied recursively.
 
-Useful functions to put in this list include: `gnus-simplify-subject-re',
-`gnus-simplify-subject-fuzzy' and `gnus-simplify-whitespace'."
+Useful functions to put in this list include:
+`gnus-simplify-subject-re', `gnus-simplify-subject-fuzzy',
+`gnus-simplify-whitespace', and `gnus-simplify-all-whitespace'."
   :group 'gnus-thread
   :type '(repeat function))
 
@@ -567,7 +568,7 @@ this variable specifies group names."
   :type 'boolean)
 
 (defcustom gnus-auto-expirable-marks
-  (list gnus-spam-mark gnus-killed-mark gnus-del-mark gnus-catchup-mark
+  (list gnus-killed-mark gnus-del-mark gnus-catchup-mark
        gnus-low-score-mark gnus-ancient-mark gnus-read-mark
        gnus-souped-mark gnus-duplicate-mark)
   "*The list of marks converted into expiration if a group is auto-expirable."
@@ -670,7 +671,8 @@ was sent, sorting by number means sorting by arrival time.)
 
 Ready-made functions include `gnus-article-sort-by-number',
 `gnus-article-sort-by-author', `gnus-article-sort-by-subject',
-`gnus-article-sort-by-date' and `gnus-article-sort-by-score'.
+`gnus-article-sort-by-date', `gnus-article-sort-by-random'
+and `gnus-article-sort-by-score'.
 
 When threading is turned on, the variable `gnus-thread-sort-functions'
 controls how articles are sorted."
@@ -680,6 +682,7 @@ controls how articles are sorted."
                         (function-item gnus-article-sort-by-subject)
                         (function-item gnus-article-sort-by-date)
                         (function-item gnus-article-sort-by-score)
+                        (function-item gnus-article-sort-by-random)
                         (function :tag "other"))))
 
 (defcustom gnus-thread-sort-functions '(gnus-thread-sort-by-number)
@@ -699,7 +702,8 @@ Ready-made functions include `gnus-thread-sort-by-number',
 `gnus-thread-sort-by-author', `gnus-thread-sort-by-subject',
 `gnus-thread-sort-by-date', `gnus-thread-sort-by-score',
 `gnus-thread-sort-by-most-recent-number',
-`gnus-thread-sort-by-most-recent-date', and
+`gnus-thread-sort-by-most-recent-date',
+`gnus-thread-sort-by-random', and
 `gnus-thread-sort-by-total-score' (see `gnus-thread-score-function').
 
 When threading is turned off, the variable
@@ -711,6 +715,7 @@ When threading is turned off, the variable
                         (function-item gnus-thread-sort-by-date)
                         (function-item gnus-thread-sort-by-score)
                         (function-item gnus-thread-sort-by-total-score)
+                        (function-item gnus-thread-sort-by-random)
                         (function :tag "other"))))
 
 (defcustom gnus-thread-score-function '+
@@ -1179,6 +1184,7 @@ the type of the variable (string, integer, character, etc).")
     (?u gnus-tmp-user-defined ?s)
     (?d (length gnus-newsgroup-dormant) ?d)
     (?t (length gnus-newsgroup-marked) ?d)
+    (?h (length gnus-newsgroup-spam-marked) ?d)
     (?r (length gnus-newsgroup-reads) ?d)
     (?z (gnus-summary-article-score gnus-tmp-article-number) ?d)
     (?E gnus-newsgroup-expunged-tally ?d)
@@ -1223,6 +1229,9 @@ end position and text.")
 (defvar gnus-newsgroup-marked nil
   "Sorted list of ticked articles in the current newsgroup (a subset of unread art).")
 
+(defvar gnus-newsgroup-spam-marked nil
+  "List of ranges of articles that have been marked as spam.")
+
 (defvar gnus-newsgroup-killed nil
   "List of ranges of articles that have been through the scoring process.")
 
@@ -1311,6 +1320,7 @@ end position and text.")
     gnus-newsgroup-last-folder gnus-newsgroup-last-file
     gnus-newsgroup-auto-expire gnus-newsgroup-unreads
     gnus-newsgroup-unselected gnus-newsgroup-marked
+    gnus-newsgroup-spam-marked
     gnus-newsgroup-reads gnus-newsgroup-saved
     gnus-newsgroup-replied gnus-newsgroup-forwarded
     gnus-newsgroup-recent
@@ -1380,6 +1390,13 @@ buffers. For example:
       (setq mystr (substring mystr 0 (match-beginning 0))))
     mystr))
 
+(defun gnus-simplify-all-whitespace (str)
+  "Remove all whitespace from STR."
+  (let ((mystr str))
+    (while (string-match "[ \t\n]+" mystr)
+      (setq mystr (replace-match "" nil nil mystr)))
+    mystr))
+
 (defsubst gnus-simplify-subject-re (subject)
   "Remove \"Re:\" from subject lines."
   (if (string-match message-subject-re-regexp subject)
@@ -1562,6 +1579,7 @@ increase the score of each group you read."
     "\C-c\C-s\C-d" gnus-summary-sort-by-date
     "\C-c\C-s\C-i" gnus-summary-sort-by-score
     "\C-c\C-s\C-o" gnus-summary-sort-by-original
+    "\C-c\C-s\C-r" gnus-summary-sort-by-random
     "=" gnus-summary-expand-window
     "\C-x\C-s" gnus-summary-reselect-current-group
     "\M-g" gnus-summary-rescan-group
@@ -1590,7 +1608,7 @@ increase the score of each group you read."
     "i" gnus-summary-news-other-window
     "x" gnus-summary-limit-to-unread
     "s" gnus-summary-isearch-article
-    "t" gnus-article-toggle-headers
+    "t" gnus-summary-toggle-header
     "g" gnus-summary-show-article
     "l" gnus-summary-goto-last-article
     "v" gnus-summary-preview-mime-message
@@ -1758,7 +1776,7 @@ increase the score of each group you read."
     "f" gnus-article-display-x-face
     "l" gnus-summary-stop-page-breaking
     "r" gnus-summary-caesar-message
-    "t" gnus-article-toggle-headers
+    "t" gnus-summary-toggle-header
     "g" gnus-treat-smiley
     "v" gnus-summary-verbose-headers
     "m" gnus-summary-toggle-mime
@@ -1769,7 +1787,7 @@ increase the score of each group you read."
 
   (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
     "a" gnus-article-hide
-    "h" gnus-article-toggle-headers
+    "h" gnus-article-hide-headers
     "b" gnus-article-hide-boring-headers
     "s" gnus-article-hide-signature
     "c" gnus-article-hide-citation
@@ -1917,6 +1935,30 @@ increase the score of each group you read."
 
 (defvar gnus-article-post-menu nil)
 
+(defconst gnus-summary-menu-maxlen 20)
+
+(defun gnus-summary-menu-split (menu)
+  ;; If we have lots of elements, divide them into groups of 20
+  ;; and make a pane (or submenu) for each one.
+  (if (> (length menu) (/ (* gnus-summary-menu-maxlen 3) 2))
+      (let ((menu menu) sublists next
+           (i 1))
+       (while menu
+         ;; Pull off the next gnus-summary-menu-maxlen elements
+         ;; and make them the next element of sublist.
+         (setq next (nthcdr gnus-summary-menu-maxlen menu))
+         (if next
+             (setcdr (nthcdr (1- gnus-summary-menu-maxlen) menu)
+                     nil))
+         (setq sublists (cons (cons (format "%s ... %s" (aref (car menu) 0)
+                                            (aref (car (last menu)) 0)) menu)
+                              sublists))
+         (setq i (1+ i))
+         (setq menu next))
+       (nreverse sublists))
+    ;; Few elements--put them all in one pane.
+    menu))
+
 (defun gnus-summary-make-menu-bar ()
   (gnus-turn-off-edit-menu 'summary)
 
@@ -1955,7 +1997,7 @@ increase the score of each group you read."
     (let ((innards
           `(("Hide"
              ["All" gnus-article-hide t]
-             ["Headers" gnus-article-toggle-headers t]
+             ["Headers" gnus-article-hide-headers t]
              ["Signature" gnus-article-hide-signature t]
              ["Citation" gnus-article-hide-citation t]
              ["List identifiers" gnus-article-hide-list-identifiers t]
@@ -1982,27 +2024,28 @@ increase the score of each group you read."
              ["Show picons in mail headers" gnus-treat-mail-picon t]
              ["Show picons in news headers" gnus-treat-newsgroups-picon t]
              ("View as different encoding"
-              ,@(mapcar
-                 (lambda (cs)
-                   ;; Since easymenu under FSF Emacs doesn't allow lambda
-                   ;; forms for menu commands, we should provide intern'ed
-                   ;; function symbols.
-                   (let ((command (intern (format "\
+              ,@(gnus-summary-menu-split
+                 (mapcar
+                  (lambda (cs)
+                    ;; Since easymenu under FSF Emacs doesn't allow lambda
+                    ;; forms for menu commands, we should provide intern'ed
+                    ;; function symbols.
+                    (let ((command (intern (format "\
 gnus-summary-show-article-from-menu-as-charset-%s" cs))))
-                     (fset command
-                           `(lambda ()
-                              (interactive)
-                              (let ((gnus-summary-show-article-charset-alist
-                                     '((1 . ,cs))))
-                                (gnus-summary-show-article 1))))
-                     `[,(symbol-name cs) ,command t]))
-                 (sort (if (fboundp 'coding-system-list)
-                           (coding-system-list)
-                         ;;(mapcar 'car mm-mime-mule-charset-alist)
-                         )
-                       (lambda (a b)
-                         (string< (symbol-name a)
-                                  (symbol-name b)))))))
+                      (fset command
+                            `(lambda ()
+                               (interactive)
+                               (let ((gnus-summary-show-article-charset-alist
+                                      '((1 . ,cs))))
+                                 (gnus-summary-show-article 1))))
+                      `[,(symbol-name cs) ,command t]))
+                  (sort (if (fboundp 'coding-system-list)
+                            (coding-system-list)
+                          ;;(mapcar 'car mm-mime-mule-charset-alist)
+                          )
+                        (lambda (a b)
+                          (string< (symbol-name a)
+                                   (symbol-name b))))))))
             ("Washing"
              ("Remove Blanks"
               ["Leading" gnus-article-strip-leading-blank-lines t]
@@ -2283,6 +2326,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs))))
        ["Sort by score" gnus-summary-sort-by-score t]
        ["Sort by lines" gnus-summary-sort-by-lines t]
        ["Sort by characters" gnus-summary-sort-by-chars t]
+       ["Randomize" gnus-summary-sort-by-random t]
        ["Original sort" gnus-summary-sort-by-original t])
        ("Help"
        ["Fetch group FAQ" gnus-summary-fetch-faq t]
@@ -2700,6 +2744,7 @@ The following commands are available:
 (defun gnus-article-read-p (article)
   "Say whether ARTICLE is read or not."
   (not (or (memq article gnus-newsgroup-marked)
+          (memq article gnus-newsgroup-spam-marked)
           (memq article gnus-newsgroup-unreads)
           (memq article gnus-newsgroup-unselected)
           (memq article gnus-newsgroup-dormant))))
@@ -2805,6 +2850,7 @@ marks of articles."
     ((memq ,number gnus-newsgroup-downloadable) gnus-downloadable-mark)
     ((memq ,number gnus-newsgroup-unreads) gnus-unread-mark)
     ((memq ,number gnus-newsgroup-marked) gnus-ticked-mark)
+    ((memq ,number gnus-newsgroup-spam-marked) gnus-spam-mark)
     ((memq ,number gnus-newsgroup-dormant) gnus-dormant-mark)
     ((memq ,number gnus-newsgroup-expirable) gnus-expirable-mark)
     (t (or (cdr (assq ,number gnus-newsgroup-reads))
@@ -2945,6 +2991,7 @@ buffer that was in action when the last article was fetched."
     (setq gnus-summary-buffer (current-buffer))
     (let ((name gnus-newsgroup-name)
          (marked gnus-newsgroup-marked)
+         (spam gnus-newsgroup-spam-marked)
          (unread gnus-newsgroup-unreads)
          (headers gnus-current-headers)
          (data gnus-newsgroup-data)
@@ -2967,6 +3014,7 @@ buffer that was in action when the last article was fetched."
        (set-buffer gnus-group-buffer)
        (setq gnus-newsgroup-name name
              gnus-newsgroup-marked marked
+             gnus-newsgroup-spam-marked spam
              gnus-newsgroup-unreads unread
              gnus-current-headers headers
              gnus-newsgroup-data data
@@ -3648,7 +3696,7 @@ entered.
 Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
   (let* ((id (mail-header-id header))
         (id-dep (and id (intern id dependencies)))
-        ref ref-dep ref-header replaced)
+        parent-id ref ref-dep ref-header replaced)
     ;; Enter this `header' in the `dependencies' table.
     (cond
      ((not id-dep)
@@ -3691,7 +3739,8 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
 
     (when (and header (not replaced))
       ;; First check that we are not creating a References loop.
-      (setq ref (gnus-parent-id (mail-header-references header)))
+      (setq parent-id (gnus-parent-id (mail-header-references header)))
+      (setq ref parent-id)
       (while (and ref
                  (setq ref-dep (intern-soft ref dependencies))
                  (boundp ref-dep)
@@ -3701,10 +3750,10 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
            ;; root article.
            (progn
              (mail-header-set-references (car (symbol-value id-dep)) "none")
-             (setq ref nil))
+             (setq ref nil)
+             (setq parent-id nil))
          (setq ref (gnus-parent-id (mail-header-references ref-header)))))
-      (setq ref (gnus-parent-id (mail-header-references header)))
-      (setq ref-dep (intern (or ref "none") dependencies))
+      (setq ref-dep (intern (or parent-id "none") dependencies))
       (if (boundp ref-dep)
          (setcdr (symbol-value ref-dep)
                  (nconc (cdr (symbol-value ref-dep))
@@ -4212,6 +4261,15 @@ using some other form will lead to serious barfage."
   (gnus-article-sort-by-number
    (gnus-thread-header h1) (gnus-thread-header h2)))
 
+(defsubst gnus-article-sort-by-random (h1 h2)
+  "Sort articles by article number."
+  (zerop (random 2)))
+
+(defun gnus-thread-sort-by-random (h1 h2)
+  "Sort threads by root article number."
+  (gnus-article-sort-by-random
+   (gnus-thread-header h1) (gnus-thread-header h2)))
+
 (defsubst gnus-article-sort-by-lines (h1 h2)
   "Sort articles by article Lines header."
   (< (mail-header-lines h1)
@@ -4404,7 +4462,7 @@ or a straight list of headers."
        (default-score (or gnus-summary-default-score 0))
        (gnus-visual-p (gnus-visual-p 'summary-highlight 'highlight))
        thread number subject stack state gnus-tmp-gathered beg-match
-       new-roots gnus-tmp-new-adopts thread-end
+       new-roots gnus-tmp-new-adopts thread-end simp-subject
        gnus-tmp-header gnus-tmp-unread
        gnus-tmp-replied gnus-tmp-subject-or-nil
        gnus-tmp-dummy gnus-tmp-indentation gnus-tmp-lines gnus-tmp-score
@@ -4493,7 +4551,8 @@ or a straight list of headers."
              (setq gnus-tmp-level -1)))
 
          (setq number (mail-header-number gnus-tmp-header)
-               subject (mail-header-subject gnus-tmp-header))
+               subject (mail-header-subject gnus-tmp-header)
+               simp-subject (gnus-simplify-subject-fully subject))
 
          (cond
           ;; If the thread has changed subject, we might want to make
@@ -4501,8 +4560,7 @@ or a straight list of headers."
           ((and (null gnus-thread-ignore-subject)
                 (not (zerop gnus-tmp-level))
                 gnus-tmp-prev-subject
-                (not (inline
-                       (gnus-subject-equal gnus-tmp-prev-subject subject))))
+                (not (string= gnus-tmp-prev-subject simp-subject)))
            (setq new-roots (nconc new-roots (list (car thread)))
                  thread-end t
                  gnus-tmp-header nil))
@@ -4563,15 +4621,13 @@ or a straight list of headers."
             (cond
              ((and gnus-thread-ignore-subject
                    gnus-tmp-prev-subject
-                   (not (inline (gnus-subject-equal
-                                 gnus-tmp-prev-subject subject))))
+                   (not (string= gnus-tmp-prev-subject simp-subject)))
               subject)
              ((zerop gnus-tmp-level)
               (if (and (eq gnus-summary-make-false-root 'empty)
                        (memq number gnus-tmp-gathered)
                        gnus-tmp-prev-subject
-                       (inline (gnus-subject-equal
-                                gnus-tmp-prev-subject subject)))
+                       (string= gnus-tmp-prev-subject simp-subject))
                   gnus-summary-same-subject
                 subject))
              (t gnus-summary-same-subject)))
@@ -4656,7 +4712,7 @@ or a straight list of headers."
              (gnus-run-hooks 'gnus-summary-update-hook)
              (forward-line 1))
 
-           (setq gnus-tmp-prev-subject subject)))
+           (setq gnus-tmp-prev-subject simp-subject)))
 
        (when (nth 1 thread)
          (push (list (max 0 gnus-tmp-level)
@@ -4941,6 +4997,8 @@ If SELECT-ARTICLES, only select those articles from GROUP."
     (cond
      ((eq type 'tick)
       (memq article gnus-newsgroup-marked))
+     ((eq type 'spam)
+      (memq article gnus-newsgroup-spam-marked))
      ((eq type 'unsend)
       (memq article gnus-newsgroup-unsendable))
      ((eq type 'undownload)
@@ -7835,8 +7893,8 @@ to guess what the document format is."
        (set-buffer gnus-original-article-buffer)
        ;; Have the digest group inherit the main mail address of
        ;; the parent article.
-       (when (setq to-address (or (message-fetch-field "reply-to")
-                                  (message-fetch-field "from")))
+       (when (setq to-address (or (gnus-fetch-field "reply-to")
+                                  (gnus-fetch-field "from")))
          (setq params (append
                        (list (cons 'to-address
                                    (funcall gnus-decode-encoded-word-function
@@ -8396,35 +8454,39 @@ If ARG is a negative number, turn header display off."
 If ARG is a positive number, show the entire header.
 If ARG is a negative number, hide the unwanted header lines."
   (interactive "P")
-  (save-excursion
-    (set-buffer gnus-article-buffer)
-    (save-restriction
-      (let* ((buffer-read-only nil)
-            (inhibit-point-motion-hooks t)
-            hidden s e)
-       (save-restriction
-         (article-narrow-to-head)
-         (setq e (point-max)
-               hidden (if (numberp arg)
+  (let ((window (and (gnus-buffer-live-p gnus-article-buffer)
+                    (get-buffer-window gnus-article-buffer t))))
+    (when window
+      (with-current-buffer gnus-article-buffer
+       (widen)
+       (article-narrow-to-head)
+       (let* ((buffer-read-only nil)
+              (inhibit-point-motion-hooks t)
+              (hidden (if (numberp arg)
                           (>= arg 0)
-                        (gnus-article-hidden-text-p 'headers))))
-       (delete-region (point-min) e)
-       (goto-char (point-min))
-       (with-current-buffer gnus-original-article-buffer
-         (goto-char (setq s (point-min)))
-         (setq e (search-forward "\n\n" nil t)
-               e (if e (1- e) (point-max))))
-       (insert-buffer-substring gnus-original-article-buffer s e)
-       (save-restriction
-         (narrow-to-region (point-min) (point))
+                        (gnus-article-hidden-text-p 'headers)))
+              s e)
+         (delete-region (point-min) (point-max))
+         (with-current-buffer gnus-original-article-buffer
+           (goto-char (setq s (point-min)))
+           (setq e (if (search-forward "\n\n" nil t)
+                       (1- (point))
+                     (point-max))))
+         (insert-buffer-substring gnus-original-article-buffer s e)
          (article-decode-encoded-words)
-         (if  hidden
+         (if hidden
              (let ((gnus-treat-hide-headers nil)
                    (gnus-treat-hide-boring-headers nil))
                (gnus-delete-wash-type 'headers)
                (gnus-treat-article 'head))
-           (gnus-treat-article 'head)))
-       (gnus-set-mode-line 'article)))))
+           (gnus-treat-article 'head))
+         (widen)
+         (set-window-start window (goto-char (point-min)))
+         (setq gnus-page-broken
+               (when gnus-break-pages
+                 (gnus-narrow-to-page)
+                 t))
+         (gnus-set-mode-line 'article))))))
 
 (defun gnus-summary-show-all-headers ()
   "Make all header lines visible."
@@ -8941,6 +9003,7 @@ delete these instead."
     (error "Couldn't open server"))
   ;; Compute the list of articles to delete.
   (let ((articles (sort (copy-sequence (gnus-summary-work-articles n)) '<))
+       (nnmail-expiry-target 'delete)
        not-deleted)
     (if (and gnus-novice-user
             (not (gnus-yes-or-no-p
@@ -9382,6 +9445,7 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
   (let ((article (gnus-summary-article-number)))
     (setq gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads))
     (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
+    (setq gnus-newsgroup-spam-marked (delq article gnus-newsgroup-spam-marked))
     (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))
     (push (cons article mark) gnus-newsgroup-reads)
     ;; Possibly remove from cache, if that is used.
@@ -9413,6 +9477,7 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
            (gnus-error 1 "Can't mark negative article numbers")
            nil)
        (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
+       (setq gnus-newsgroup-spam-marked (delq article gnus-newsgroup-spam-marked))
        (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))
        (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))
        (setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads))
@@ -9420,6 +9485,10 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
               (setq gnus-newsgroup-marked
                     (gnus-add-to-sorted-list gnus-newsgroup-marked
                                              article)))
+             ((= mark gnus-spam-mark)
+              (setq gnus-newsgroup-spam-marked
+                    (gnus-add-to-sorted-list gnus-newsgroup-spam-marked
+                                             article)))
              ((= mark gnus-dormant-mark)
               (setq gnus-newsgroup-dormant
                     (gnus-add-to-sorted-list gnus-newsgroup-dormant
@@ -9472,6 +9541,7 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
        (error "No article on current line"))
       (if (not (if (or (= mark gnus-unread-mark)
                       (= mark gnus-ticked-mark)
+                      (= mark gnus-spam-mark)
                       (= mark gnus-dormant-mark))
                   (gnus-mark-article-as-unread article mark)
                 (gnus-mark-article-as-read article mark)))
@@ -9546,6 +9616,7 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
     ;; Remove from unread and marked lists.
     (setq gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads))
     (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
+    (setq gnus-newsgroup-spam-marked (delq article gnus-newsgroup-spam-marked))
     (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))
     (push (cons article mark) gnus-newsgroup-reads)
     ;; Possibly remove from cache, if that is used.
@@ -9561,6 +9632,7 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
          (gnus-error 1 "Can't mark negative article numbers")
          nil)
       (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked)
+           gnus-newsgroup-spam-marked (delq article gnus-newsgroup-spam-marked)
            gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant)
            gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable)
            gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads))
@@ -9572,6 +9644,9 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
       (cond ((= mark gnus-ticked-mark)
             (setq gnus-newsgroup-marked
                   (gnus-add-to-sorted-list gnus-newsgroup-marked article)))
+           ((= mark gnus-spam-mark)
+            (setq gnus-newsgroup-spam-marked
+                  (gnus-add-to-sorted-list gnus-newsgroup-spam-marked article)))
            ((= mark gnus-dormant-mark)
             (setq gnus-newsgroup-dormant
                   (gnus-add-to-sorted-list gnus-newsgroup-dormant article)))
@@ -9785,6 +9860,7 @@ The number of articles marked as read is returned."
              (progn
                (when all
                  (setq gnus-newsgroup-marked nil
+                       gnus-newsgroup-spam-marked nil
                        gnus-newsgroup-dormant nil))
                (setq gnus-newsgroup-unreads gnus-newsgroup-downloadable))
            ;; We actually mark all articles as canceled, which we
@@ -10216,6 +10292,12 @@ Argument REVERSE means reverse order."
   (interactive "P")
   (gnus-summary-sort 'number reverse))
 
+(defun gnus-summary-sort-by-random (&optional reverse)
+  "Randomize the order in the summary buffer.
+Argument REVERSE means to randomize in reverse order."
+  (interactive "P")
+  (gnus-summary-sort 'random reverse))
+
 (defun gnus-summary-sort-by-author (&optional reverse)
   "Sort the summary buffer by author name alphabetically.
 If `case-fold-search' is non-nil, case of letters is ignored.
@@ -11317,7 +11399,7 @@ If ALL is a number, fetch this number of articles."
          (if (and (numberp gnus-large-newsgroup)
                   (> len gnus-large-newsgroup))
              (let* ((cursor-in-echo-area nil)
-                    (initial (gnus-parameter-large-newsgroup-initial 
+                    (initial (gnus-parameter-large-newsgroup-initial
                               gnus-newsgroup-name))
                     (input
                      (read-string
@@ -11350,13 +11432,12 @@ If ALL is a number, fetch this number of articles."
            i new)
        (setq gnus-newsgroup-active
              (gnus-activate-group gnus-newsgroup-name 'scan))
-       (setq i (1+ (cdr old-active)))
-       (while (<= i (cdr gnus-newsgroup-active))
+       (setq i (cdr gnus-newsgroup-active))
+       (while (> i (cdr old-active))
          (push i new)
-         (incf i))
+         (decf i))
        (if (not new)
            (message "No gnus is bad news.")
-         (setq new (nreverse new))
          (gnus-summary-insert-articles new)
          (setq gnus-newsgroup-unreads
                (gnus-sorted-nunion gnus-newsgroup-unreads new))
index b7d054d..d356c31 100644 (file)
@@ -381,9 +381,17 @@ If RECURSIVE is t, return groups in its subtopics too."
   "Compute the group parameters for GROUP taking into account inheritance from topics."
   (let ((params-list (copy-sequence (gnus-group-get-parameter group))))
     (save-excursion
-      (gnus-group-goto-group group)
       (nconc params-list
-            (gnus-topic-hierarchical-parameters (gnus-current-topic))))))
+            (gnus-topic-hierarchical-parameters
+             ;; First we try to go to the group within the group
+             ;; buffer and find the topic for the group that way.
+             ;; This hopefully copes well with groups that are in
+             ;; more than one topic.  Failing that (i.e. when the
+             ;; group isn't visible in the group buffer) we find a
+             ;; topic for the group via gnus-group-topic.
+             (or (and (gnus-group-goto-group group)
+                      (gnus-current-topic))
+                 (gnus-group-topic group)))))))
 
 (defun gnus-topic-hierarchical-parameters (topic)
   "Return a topic list computed for TOPIC."
@@ -1522,7 +1530,7 @@ If UNINDENT, remove an indentation."
        (gnus-topic-kill-group)
        (push (cdar gnus-topic-killed-topics) gnus-topic-alist)
        (gnus-topic-create-topic
-        topic parent nil (cdaar gnus-topic-killed-topics))
+        topic parent nil (cdar (car gnus-topic-killed-topics)))
        (pop gnus-topic-killed-topics)
        (or (gnus-topic-goto-topic topic)
            (gnus-topic-goto-topic parent))))))
@@ -1541,7 +1549,7 @@ If UNINDENT, remove an indentation."
       (push (cdar gnus-topic-killed-topics) gnus-topic-alist)
       (gnus-topic-create-topic
        topic grandparent (gnus-topic-next-topic parent)
-       (cdaar gnus-topic-killed-topics))
+       (cdar (car gnus-topic-killed-topics)))
       (pop gnus-topic-killed-topics)
       (gnus-topic-goto-topic topic))))
 
index d6bdf4a..117fcbe 100644 (file)
 (require 'product)
 (provide 'gnus-vers)
 
-(defconst gnus-revision-number "02"
+(defconst gnus-revision-number "00"
   "Revision number for this version of gnus.")
 
 ;; Product information of this gnus.
 (product-provide 'gnus-vers
   (product-define "T-gnus" nil
-                 (list 6 15 6
+                 (list 6 15 7
                        (string-to-number gnus-revision-number))))
 
-(defconst gnus-original-version-number "0.06"
+(defconst gnus-original-version-number "0.07"
   "Version number for this version of Gnus.")
 
 (provide 'running-pterodactyl-gnus-0_73-or-later)
index 8d323f7..b12d258 100644 (file)
@@ -1306,7 +1306,8 @@ If the number of articles in a newsgroup is greater than this value,
 confirmation is required for selecting the newsgroup.
 If it is `nil', no confirmation is required."
   :group 'gnus-group-select
-  :type 'integer)
+  :type '(choice (const :tag "No limit" nil)
+                integer))
 
 (defcustom gnus-use-long-file-name (not (memq system-type '(usg-unix-v xenix)))
   "*Non-nil means that the default name of a file to save articles in is the group name.
@@ -1590,6 +1591,21 @@ The gnus-group-split mail splitting mechanism will behave as if this
 address was listed in gnus-group-split Addresses (see below).")
 
 (gnus-define-group-parameter
+ subscribed
+ :type bool
+ :function-document
+ "Return GROUP's subscription status."
+ :variable-document
+ "*Groups which are automatically considered subscribed."
+ :parameter-type '(const :tag "Subscribed" t)
+ :parameter-document "\
+Gnus assumed that you are subscribed to the To/List address.
+
+When constructing a list of subscribed groups using
+`gnus-find-subscribed-addresses', Gnus includes the To address given
+above, or the list address (if the To address has not been set).")
+
+(gnus-define-group-parameter
  auto-expire
  :type bool
  :function gnus-group-auto-expirable-p
@@ -1821,7 +1837,8 @@ face."
   "Whether Gnus is plugged or not.")
 
 (defcustom gnus-agent-cache t
-  "Whether Gnus use agent cache."
+  "Whether Gnus use agent cache.
+You also need to enable `gnus-agent'."
   :version "21.3"
   :group 'gnus-agent
   :type 'boolean)
@@ -1834,7 +1851,7 @@ covered by that variable."
   :type 'symbol
   :group 'gnus-charset)
 
-(defcustom gnus-agent nil
+(defcustom gnus-agent t
   "Whether we want to use the Gnus agent or not.
 Putting (gnus-agentize) in ~/.gnus is obsolete by (setq gnus-agent t)."
   :version "21.3"
@@ -2218,8 +2235,7 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
       ;; gnus-article-show-all
       gnus-article-edit-mode gnus-article-edit-article
       gnus-article-edit-done article-decode-encoded-words
-      gnus-start-date-timer gnus-stop-date-timer
-      gnus-article-toggle-headers)
+      gnus-start-date-timer gnus-stop-date-timer)
      ("gnus-int" gnus-request-type)
      ("gnus-start" gnus-newsrc-parse-options gnus-1 gnus-no-server-1
       gnus-dribble-enter gnus-read-init-file gnus-dribble-touch)
@@ -2275,6 +2291,9 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
 
 ;; To search articles with Namazu.
 (autoload 'gnus-namazu-search "gnus-namazu" nil t)
+(autoload 'gnus-namazu-create-index "gnus-namazu" nil t)
+(autoload 'gnus-namazu-update-index "gnus-namazu" nil t)
+(autoload 'gnus-namazu-update-all-indices "gnus-namazu" nil t)
 
 ;; To make nnir groups.
 (autoload 'gnus-group-make-nnir-group "nnir" nil t)
@@ -2520,12 +2539,12 @@ with a `subscribed' parameter."
   (let (group address addresses)
     (dolist (entry (cdr gnus-newsrc-alist))
       (setq group (car entry))
-      (when (gnus-group-find-parameter group 'subscribed)
+      (when (gnus-parameter-subscribed group)
        (setq address (mail-strip-quoted-names
                       (or (gnus-group-fast-parameter group 'to-address)
                           (gnus-group-fast-parameter group 'to-list))))
        (when address
-         (push address addresses))))
+         (add-to-list 'addresses address))))
     (when addresses
       (list (mapconcat 'regexp-quote addresses "\\|")))))
 
index 5cf4016..e0fc8a5 100644 (file)
@@ -466,7 +466,8 @@ Return the number of files that were found."
                     (funcall function source callback)
                   (error
                    (unless (yes-or-no-p
-                            (format "Mail source error (%s).  Continue? "
+                            (format "Mail source %s error (%s).  Continue? "
+                                    source
                                     (cadr err)))
                      (error "Cannot get new mail"))
                    0)))))))))
index f87e0a4..fdfc1cb 100644 (file)
@@ -350,7 +350,7 @@ value may go against RFC-1036 and draft-ietf-usefor-article-05.txt. "
   :type 'string
   :group 'message-various)
 
-(defcustom message-interactive nil
+(defcustom message-interactive t
   "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
@@ -1167,27 +1167,51 @@ candidates:
   "Face used for displaying MML."
   :group 'message-faces)
 
+(defun message-font-lock-make-header-matcher (regexp)
+  (let ((form
+        `(lambda (limit)
+           (let ((start (point)))
+             (save-restriction
+               (widen)
+               (goto-char (point-min))
+               (if (re-search-forward
+                    (concat "^" (regexp-quote mail-header-separator) "$")
+                    nil t)
+                   (setq limit (min limit (match-beginning 0))))
+               (goto-char start))
+             (and (< start limit)
+                  (re-search-forward ,regexp limit t))))))
+    (if (featurep 'bytecomp)
+       (byte-compile form)
+      form)))
+
 (defvar message-font-lock-keywords
   (let ((content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)\n?"))
-    `((,(concat "^\\([Tt]o:\\)" content)
+    `((,(message-font-lock-make-header-matcher
+        (concat "^\\([Tt]o:\\)" content))
        (1 'message-header-name-face)
        (2 'message-header-to-face nil t))
-      (,(concat "^\\([GBF]?[Cc][Cc]:\\|[Rr]eply-[Tt]o:\\|"
-               "[Mm]ail-[Cc]opies-[Tt]o:\\|"
-               "[Mm]ail-[Rr]eply-[Tt]o:\\|"
-               "[Mm]ail-[Ff]ollowup-[Tt]o:\\)" content)
+      (,(message-font-lock-make-header-matcher
+        (concat "^\\([GBF]?[Cc][Cc]:\\|[Rr]eply-[Tt]o:\\|"
+                "[Mm]ail-[Cc]opies-[Tt]o:\\|"
+                "[Mm]ail-[Rr]eply-[Tt]o:\\|"
+                "[Mm]ail-[Ff]ollowup-[Tt]o:\\)" content))
        (1 'message-header-name-face)
        (2 'message-header-cc-face nil t))
-      (,(concat "^\\([Ss]ubject:\\)" content)
+      (,(message-font-lock-make-header-matcher
+        (concat "^\\([Ss]ubject:\\)" content))
        (1 'message-header-name-face)
        (2 'message-header-subject-face nil t))
-      (,(concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content)
+      (,(message-font-lock-make-header-matcher
+        (concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content))
        (1 'message-header-name-face)
        (2 'message-header-newsgroups-face nil t))
-      (,(concat "^\\([A-Z][^: \n\t]+:\\)" content)
+      (,(message-font-lock-make-header-matcher
+        (concat "^\\([A-Z][^: \n\t]+:\\)" content))
        (1 'message-header-name-face)
        (2 'message-header-other-face nil t))
-      (,(concat "^\\(X-[A-Za-z0-9-]+\\|In-Reply-To\\):" content)
+      (,(message-font-lock-make-header-matcher
+        (concat "^\\(X-[A-Za-z0-9-]+:\\|In-Reply-To:\\)" content))
        (1 'message-header-name-face)
        (2 'message-header-name-face))
       ,@(if (and mail-header-separator
@@ -3052,36 +3076,41 @@ It should typically alter the sending method in some way or other."
          (success t)
          elem sent dont-barf-on-no-method
          (message-options message-options))
-      (message-options-set-recipient)
-      (save-excursion
-       (set-buffer message-encoding-buffer)
-       (erase-buffer)
-       ;; ;; Avoid copying text props (except hard newlines).
-       ;; T-gnus change: copy all text props from the editing buffer
-       ;; into the encoding buffer.
-       (insert-buffer-substring message-edit-buffer)
-       (funcall message-encode-function)
-       (while (and success
-                   (setq elem (pop alist)))
-         (when (funcall (cadr elem))
-           (when (and (or (not (memq (car elem)
-                                     message-sent-message-via))
-                          (if (or (message-gnksa-enable-p 'multiple-copies)
-                                  (not (eq (car elem) 'news)))
-                              (y-or-n-p
-                               (format
-                                "Already sent message via %s; resend? "
-                                (car elem)))
-                            (error "Denied posting -- multiple copies")))
-                      (setq success (funcall (caddr elem) arg)))
-             (setq sent t)))))
-      (unless
-         (or sent
-             (not success)
-             (let ((fcc (message-fetch-field "Fcc"))
-                   (gcc (message-fetch-field "Gcc")))
-               (when (or fcc gcc)
-                 (or (eq message-allow-no-recipients 'always)
+      (unwind-protect
+         (progn
+           (message-options-set-recipient)
+           (save-excursion
+             (set-buffer message-encoding-buffer)
+             (erase-buffer)
+             ;; ;; Avoid copying text props (except hard newlines).
+             ;; T-gnus change: copy all text props from the editing buffer
+             ;; into the encoding buffer.
+             (insert-buffer-substring message-edit-buffer)
+             (funcall message-encode-function)
+             (while (and success
+                         (setq elem (pop alist)))
+               (when (funcall (cadr elem))
+                 (when (and
+                        (or (not (memq (car elem)
+                                       message-sent-message-via))
+                            (if (or (message-gnksa-enable-p 'multiple-copies)
+                                    (not (eq (car elem) 'news)))
+                                (y-or-n-p
+                                 (format
+                                  "Already sent message via %s; resend? "
+                                  (car elem)))
+                              (error "Denied posting -- multiple copies")))
+                        (setq success (funcall (caddr elem) arg)))
+                   (setq sent t)))))
+           (unless
+               (or
+                sent
+                (not success)
+                (let ((fcc (message-fetch-field "Fcc"))
+                      (gcc (message-fetch-field "Gcc")))
+                  (when (or fcc gcc)
+                    (or
+                     (eq message-allow-no-recipients 'always)
                      (and (not (eq message-allow-no-recipients 'never))
                           (setq dont-barf-on-no-method
                                 (gnus-y-or-n-p
@@ -3089,23 +3118,22 @@ It should typically alter the sending method in some way or other."
                                          (cond ((and fcc gcc) "Fcc and Gcc")
                                                (fcc "Fcc")
                                                (t "Gcc"))))))))))
-       (error "No methods specified to send by"))
-      (prog1
-         (when (or dont-barf-on-no-method
-                   (and success sent))
-           (message-do-fcc)
-           (save-excursion
-             (run-hooks 'message-sent-hook))
-           (message "Sending...done")
-           ;; Mark the buffer as unmodified and delete auto-save.
-           (set-buffer-modified-p nil)
-           (delete-auto-save-file-if-necessary t)
-           (message-disassociate-draft)
-           ;; Delete other mail buffers and stuff.
-           (message-do-send-housekeeping)
-           (message-do-actions message-send-actions)
-           ;; Return success.
-           t)
+             (error "No methods specified to send by"))
+           (when (or dont-barf-on-no-method
+                     (and success sent))
+             (message-do-fcc)
+             (save-excursion
+               (run-hooks 'message-sent-hook))
+             (message "Sending...done")
+             ;; Mark the buffer as unmodified and delete auto-save.
+             (set-buffer-modified-p nil)
+             (delete-auto-save-file-if-necessary t)
+             (message-disassociate-draft)
+             ;; Delete other mail buffers and stuff.
+             (message-do-send-housekeeping)
+             (message-do-actions message-send-actions)
+             ;; Return success.
+             t))
        (kill-buffer message-encoding-buffer)))))
 
 (defun message-send-via-mail (arg)
@@ -3457,61 +3485,67 @@ This sub function is for exclusive use of `message-send-mail'."
                     " sendmail errors")
                  0))
        resend-to-addresses delimline)
-    (let ((case-fold-search t))
-      (save-restriction
-       (message-narrow-to-headers)
-       (setq resend-to-addresses (message-fetch-field "resent-to")))
-      ;; Change header-delimiter to be what sendmail expects.
-      (goto-char (point-min))
-      (re-search-forward
-       (concat "^" (regexp-quote mail-header-separator) "\n"))
-      (replace-match "\n")
-      (backward-char 1)
-      (setq delimline (point-marker))
-      (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))
-      (when (eval message-mailer-swallows-blank-line)
-       (newline))
-      (when message-interactive
-       (save-excursion
-         (set-buffer errbuf)
-         (erase-buffer))))
-    (let ((default-directory "/"))
-      (as-binary-process
-       (apply 'call-process-region
-             (append (list (point-min) (point-max)
-                           (if (boundp 'sendmail-program)
-                               sendmail-program
-                             "/usr/lib/sendmail")
-                           nil errbuf nil "-oi")
-                     ;; Always specify who from,
-                     ;; since some systems have broken sendmails.
-                     ;; But some systems are more broken with -f, so
-                     ;; we'll let users override this.
-                     (if (null message-sendmail-f-is-evil)
-                         (list "-f" (message-make-address)))
-                     ;; These mean "report errors by mail"
-                     ;; and "deliver in background".
-                     (if (null message-interactive) '("-oem" "-odb"))
-                     ;; Get the addresses from the message
-                     ;; unless this is a resend.
-                     ;; We must not do that for a resend
-                     ;; because we would find the original addresses.
-                     ;; For a resend, include the specific addresses.
-                     (if resend-to-addresses
-                         (list resend-to-addresses)
-                       '("-t"))))))
-    (when message-interactive
-      (save-excursion
-       (set-buffer errbuf)
-       (goto-char (point-min))
-       (while (re-search-forward "\n\n* *" nil t)
-         (replace-match "; "))
-       (if (not (zerop (buffer-size)))
-           (error "Sending...failed to %s"
-                  (buffer-substring (point-min) (point-max)))))
+    (unwind-protect
+       (progn
+         (let ((case-fold-search t))
+           (save-restriction
+             (message-narrow-to-headers)
+             (setq resend-to-addresses (message-fetch-field "resent-to")))
+           ;; Change header-delimiter to be what sendmail expects.
+           (goto-char (point-min))
+           (re-search-forward
+            (concat "^" (regexp-quote mail-header-separator) "\n"))
+           (replace-match "\n")
+           (backward-char 1)
+           (setq delimline (point-marker))
+           (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))
+           (when (eval message-mailer-swallows-blank-line)
+             (newline))
+           (when message-interactive
+             (save-excursion
+               (set-buffer errbuf)
+               (erase-buffer))))
+         (let* ((default-directory "/")
+                (cpr (as-binary-process
+                      (apply
+                       'call-process-region
+                       (append
+                        (list (point-min) (point-max)
+                              (if (boundp 'sendmail-program)
+                                  sendmail-program
+                                "/usr/lib/sendmail")
+                              nil errbuf nil "-oi")
+                        ;; Always specify who from,
+                        ;; since some systems have broken sendmails.
+                        ;; But some systems are more broken with -f, so
+                        ;; we'll let users override this.
+                        (if (null message-sendmail-f-is-evil)
+                            (list "-f" (message-make-address)))
+                        ;; These mean "report errors by mail"
+                        ;; and "deliver in background".
+                        (if (null message-interactive) '("-oem" "-odb"))
+                        ;; Get the addresses from the message
+                        ;; unless this is a resend.
+                        ;; We must not do that for a resend
+                        ;; because we would find the original addresses.
+                        ;; For a resend, include the specific addresses.
+                        (if resend-to-addresses
+                            (list resend-to-addresses)
+                          '("-t")))))))
+           (unless (or (null cpr) (zerop cpr))
+             (error "Sending...failed with exit value %d" cpr)))
+         (when message-interactive
+           (save-excursion
+             (set-buffer errbuf)
+             (goto-char (point-min))
+             (while (re-search-forward "\n\n* *" nil t)
+               (replace-match "; "))
+             (if (not (zerop (buffer-size)))
+                 (error "Sending...failed to %s"
+                        (buffer-substring (point-min) (point-max)))))))
       (when (bufferp errbuf)
        (kill-buffer errbuf)))))
 
@@ -4921,6 +4955,9 @@ than 988 characters long, and if they are not, trim them until they are."
 (defun message-beginning-of-line (&optional n)
   "Move point to beginning of header value or to beginning of line."
   (interactive "p")
+  (let ((zrs 'zmacs-region-stays))
+    (when (and (interactive-p) (boundp zrs))
+      (set zrs t)))
   (if (message-point-in-header-p)
       (let* ((here (point))
             (bol (progn (beginning-of-line n) (point)))
index 32ee6e6..5f9cba6 100644 (file)
@@ -127,14 +127,23 @@ It is suggested to customize `mm-text-html-renderer' instead.")
 
 (defcustom mm-inline-text-html-with-images nil
   "If non-nil, Gnus will allow retrieving images in the HTML contents
-with <img> tags.  It has no effect on Emacs/w3.  For emacs-w3m, the
-value of the option `w3m-display-inline-images' will be bound with
-this value.  In addition, the variable `w3m-safe-url-regexp' will be
-bound with the value nil if it is non-nil to make emacs-w3m show all
-images, however this behavior may be changed in the future."
+with <img> tags.  It has no effect on Emacs/w3.  See also
+the documentation for the option `mm-w3m-safe-url-regexp'."
   :type 'boolean
   :group 'mime-display)
 
+(defcustom mm-w3m-safe-url-regexp "\\`cid:"
+  "Regexp that matches safe url names.  Some HTML mails might have a
+trick of spammers using <img> tags.  It is likely to be intended to
+verify whether you have read the mail.  You can prevent your personal
+informations from leaking by setting this to the regexp which matches
+the safe url names.  The value of the variable `w3m-safe-url-regexp'
+will be bound with this value.  You may set this value to nil if you
+consider all the urls to be safe."
+  :type '(choice (regexp :tag "Regexp")
+                (const :tag "All URLs are safe" nil)
+  :group 'mime-display))
+
 (defcustom mm-inline-text-html-with-w3m-keymap t
   "If non-nil, use emacs-w3m command keys in the article buffer."
   :type 'boolean
@@ -685,9 +694,9 @@ external if displayed external."
          ;; We create a private sub-directory where we store our files.
          (set-file-modes dir 448)
          (if filename
-             (setq file (expand-file-name 
+             (setq file (expand-file-name
                          (gnus-map-function mm-file-name-rewrite-functions
-                                             (file-name-nondirectory filename))
+                                            (file-name-nondirectory filename))
                          dir))
            (setq file (mm-make-temp-file (expand-file-name "mm." dir))))
          (let ((coding-system-for-write mm-binary-coding-system))
index fa44d45..48afccd 100644 (file)
@@ -30,7 +30,7 @@
 (eval-and-compile
   (autoload 'mm-body-7-or-8 "mm-bodies"))
 
-(defvar mm-content-transfer-encoding-defaults
+(defcustom mm-content-transfer-encoding-defaults
   '(("text/x-patch" 8bit)
     ("text/.*" qp-or-base64)
     ("message/rfc822" 8bit)
     (".*" base64))
   "Alist of regexps that match MIME types and their encodings.
 If the encoding is `qp-or-base64', then either quoted-printable
-or base64 will be used, depending on what is more efficient.")
+or base64 will be used, depending on what is more efficient."
+  :type '(repeat (list (regexp :tag "MIME type")
+                      (choice :tag "encoding"
+                              (const 7bit)
+                              (const 8bit)
+                              (const qp-or-base64)
+                              (const quoted-printable)
+                              (const base64))))
+  :group 'mime)
 
 (defvar mm-use-ultra-safe-encoding nil
   "If non-nil, use encodings aimed at Procrustean bed survival.
index 243e8c2..f1c032c 100644 (file)
@@ -297,20 +297,38 @@ This is taken from RFC 2396.")
            args (append mm-url-arguments (list url))))
     (apply 'call-process program nil t nil args)))
 
+(defvar mm-url-timeout 30
+  "The number of seconds before timing out an URL fetch.")
+
+(defvar mm-url-retries 10
+  "The number of retries after timing out when fetching an URL.")
+
 (defun mm-url-insert (url &optional follow-refresh)
   "Insert the contents from an URL in the current buffer.
 If FOLLOW-REFRESH is non-nil, redirect refresh url in META."
-  (if follow-refresh
-      (save-restriction
-       (narrow-to-region (point) (point))
-       (mm-url-insert-file-contents url)
-       (goto-char (point-min))
-       (when (re-search-forward
-              "<meta[ \t\r\n]*http-equiv=\"Refresh\"[^>]*URL=\\([^\"]+\\)\"" nil t)
-         (let ((url (match-string 1)))
-           (delete-region (point-min) (point-max))
-           (mm-url-insert url t))))
-    (mm-url-insert-file-contents url)))
+  (let ((times mm-url-retries)
+       (done nil)
+       (first t)
+       result)
+    (while (and (not (zerop (decf times)))
+               (not done))
+      (with-timeout (mm-url-timeout)
+       (unless first
+         (message "Trying again (%s)..." (- mm-url-retries times)))
+       (setq first nil)
+       (if follow-refresh
+           (save-restriction
+             (narrow-to-region (point) (point))
+             (mm-url-insert-file-contents url)
+             (goto-char (point-min))
+             (when (re-search-forward
+                    "<meta[ \t\r\n]*http-equiv=\"Refresh\"[^>]*URL=\\([^\"]+\\)\"" nil t)
+               (let ((url (match-string 1)))
+                 (delete-region (point-min) (point-max))
+                 (setq result (mm-url-insert url t)))))
+         (setq result (mm-url-insert-file-contents url)))
+       (setq done t)))
+    result))
 
 (defun mm-url-decode-entities ()
   "Decode all HTML entities."
index 93a595c..fe7afff 100644 (file)
@@ -271,7 +271,7 @@ Valid elements include:
        mm-iso-8859-15-compatible))
   "A table of the difference character between ISO-8859-X and ISO-8859-15.")
 
-(defvar mm-coding-system-priorities nil
+(defcustom mm-coding-system-priorities nil
   "Preferred coding systems for encoding outgoing mails.
 
 More than one suitable coding systems may be found for some texts.  By
@@ -281,8 +281,10 @@ it overrides the default priority.  For example, Japanese users may
 prefer iso-2022-jp to japanese-shift-jis:
 
 \(setq mm-coding-system-priorities
-  '(iso-2022-jp iso-2022-jp-2 japanese-shift-jis utf-8))
-")
+  '(iso-2022-jp iso-2022-jp-2 japanese-shift-jis iso-latin-1 utf-8))
+"
+  :type '(repeat (coding-system :tag "Coding system"))
+  :group 'mime)
 
 (defvar mm-use-find-coding-systems-region
   (fboundp 'find-coding-systems-region)
index 405b304..68aa8b3 100644 (file)
@@ -281,9 +281,7 @@ will not be substituted.")
        (when charset
          (delete-region (point-min) (point-max))
          (insert (mm-decode-string text charset)))
-       (let ((w3m-safe-url-regexp (if mm-inline-text-html-with-images
-                                      nil
-                                    "\\`cid:"))
+       (let ((w3m-safe-url-regexp mm-w3m-safe-url-regexp)
              (w3m-display-inline-images mm-inline-text-html-with-images)
              w3m-force-redisplay)
          (w3m-region (point-min) (point-max)))
index 09fec43..f0f6a64 100644 (file)
 (defvar mml-default-encrypt-method (caar mml-encrypt-alist)
   "Default encryption method.")
 
+(defvar mml-signencrypt-style-alist
+  '(("smime"   separate)
+    ("pgp"     separate)
+    ("pgpmime" separate))
+  "Alist specifying whether or not a single sign & encrypt
+operation should be perfomed when requesting signencrypt.
+Note that combined sign & encrypt is NOT supported by pgp v2!
+Also note that you should access this with mml-signencrypt-style")
+
+;;; Configuration/helper functions
+
+(defun mml-signencrypt-style (method &optional style)
+  "Function for setting/getting the signencrypt-style used.  Takes two
+arguments, the method (e.g. \"pgp\") and optionally the mode
+(e.g. combined).  If the mode is omitted, the current value is returned.
+
+For example, if you prefer to use combined sign & encrypt with
+smime, putting the following in your Gnus startup file will
+enable that behavior:
+
+ (mml-set-signencrypt-style \"smime\" combined)"
+  (let ((style-item (assoc method mml-signencrypt-style-alist)))
+    (if style-item
+       (if (or (eq style 'separate)
+               (eq style 'combined))
+           ;; valid style setting?
+           (setf (second style-item) style)
+         ;; otherwise, just return the current value
+         (second style-item))
+      (gnus-message 3 "Warning, attempt to set invalid signencrypt-style"))))
+
 ;;; Security functions
 
 (defun mml-smime-sign-buffer (cont)
@@ -68,8 +99,8 @@
   (or (mml2015-sign cont)
       (error "Signing failed... inspect message logs for errors")))
 
-(defun mml-pgpmime-encrypt-buffer (cont)
-  (or (mml2015-encrypt cont)
+(defun mml-pgpmime-encrypt-buffer (cont &optional sign)
+  (or (mml2015-encrypt cont sign)
       (error "Encryption failed... inspect message logs for errors")))
 
 (defun mml-secure-part (method &optional sign)
@@ -174,21 +205,17 @@ If called with a prefix argument, only encrypt (do NOT sign)."
   (interactive "P")
   (mml-secure-message "smime" (if dontsign 'encrypt 'signencrypt)))
 
-;;; NOTE: this should be switched to use signencrypt
-;;; once it does something sensible
 (defun mml-secure-message-encrypt-pgp (&optional dontsign)
   "Add MML tag to encrypt and sign the entire message.
 If called with a prefix argument, only encrypt (do NOT sign)."
   (interactive "P")
-  (mml-secure-message "pgp" (if dontsign 'encrypt 'encrypt)))
+  (mml-secure-message "pgp" (if dontsign 'encrypt 'signencrypt)))
 
-;;; NOTE: this should be switched to use signencrypt
-;;; once it does something sensible
 (defun mml-secure-message-encrypt-pgpmime (&optional dontsign)
   "Add MML tag to encrypt and sign the entire message.
 If called with a prefix argument, only encrypt (do NOT sign)."
   (interactive "P")
-  (mml-secure-message "pgpmime" (if dontsign 'encrypt 'encrypt)))
+  (mml-secure-message "pgpmime" (if dontsign 'encrypt 'signencrypt)))
 
 (provide 'mml-sec)
 
index 4eb71c2..6950d6c 100644 (file)
@@ -530,22 +530,29 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
              (insert "\n--" mml-boundary "--\n")))))
        (t
        (error "Invalid element: %S" cont)))
-      (let ((item (assoc (cdr (assq 'sign cont)) mml-sign-alist))
+      ;; handle sign & encrypt tags in a semi-smart way.
+      (let ((sign-item (assoc (cdr (assq 'sign cont)) mml-sign-alist))
+           (encrypt-item (assoc (cdr (assq 'encrypt cont))
+                                mml-encrypt-alist))
            sender recipients)
-       (when item
+       (when (or sign-item encrypt-item)
          (if (setq sender (cdr (assq 'sender cont)))
              (message-options-set 'message-sender sender))
          (if (setq recipients (cdr (assq 'recipients cont)))
              (message-options-set 'message-recipients recipients))
-         (funcall (nth 1 item) cont)))
-      (let ((item (assoc (cdr (assq 'encrypt cont)) mml-encrypt-alist))
-           sender recipients)
-       (when item
-         (if (setq sender (cdr (assq 'sender cont)))
-             (message-options-set 'message-sender sender))
-         (if (setq recipients (cdr (assq 'recipients cont)))
-             (message-options-set 'message-recipients recipients))
-         (funcall (nth 1 item) cont))))))
+         (let ((style (mml-signencrypt-style (first (or sign-item encrypt-item)))))
+           ;; check if: we're both signing & encrypting, both methods
+           ;; are the same (why would they be different?!), and that
+           ;; the signencrypt style allows for combined operation.
+           (if (and sign-item encrypt-item (equal (first sign-item)
+                                                  (first encrypt-item))
+                    (equal style 'combined))
+               (funcall (nth 1 encrypt-item) cont t)
+             ;; otherwise, revert to the old behavior.
+             (when sign-item
+               (funcall (nth 1 sign-item) cont))
+             (when encrypt-item
+               (funcall (nth 1 encrypt-item) cont)))))))))
 
 (defun mml-compute-boundary (cont)
   "Return a unique boundary that does not exist in CONT."
@@ -999,6 +1006,13 @@ If RAW, don't highlight the article."
                                   "*MIME preview of ") (buffer-name))))
       (erase-buffer)
       (insert-buffer buf)
+      (let ((message-deletable-headers (if (message-news-p)
+                                          nil
+                                        message-deletable-headers)))
+       (message-generate-headers
+        (copy-sequence (if (message-news-p)
+                           message-required-news-headers
+                         message-required-mail-headers))))
       (if (re-search-forward
           (concat "^" (regexp-quote mail-header-separator) "\n") nil t)
          (replace-match "\n"))
@@ -1014,7 +1028,9 @@ If RAW, don't highlight the article."
        (let ((gnus-newsgroup-charset (car message-posting-charset))
              gnus-article-prepare-hook gnus-original-article-buffer)
          (run-hooks 'gnus-article-decode-hook)
-         (let ((gnus-newsgroup-name "dummy"))
+         (let ((gnus-newsgroup-name "dummy")
+               (gnus-newsrc-hashtb (or gnus-newsrc-hashtb
+                                       (gnus-make-hashtable 5))))
            (gnus-article-prepare-display))))
       ;; Disable article-mode-map.
       (use-local-map nil)
index 49abfd6..a93f9d2 100644 (file)
@@ -34,7 +34,7 @@
               mml1991-mailcrypt-encrypt)
     (gpg mml1991-gpg-sign
         mml1991-gpg-encrypt))
-  "Alist of PGP/MIME functions.")
+  "Alist of PGP functions.")
 
 ;;; mailcrypt wrapper
 
index 75af79c..ff6c04d 100644 (file)
@@ -310,9 +310,10 @@ by you.")
     (insert (format "--%s--\n" boundary))
     (goto-char (point-max))))
 
-(defun mml2015-mailcrypt-encrypt (cont)
+(defun mml2015-mailcrypt-encrypt (cont &optional sign)
   (let ((mc-pgp-always-sign
         (or mc-pgp-always-sign
+            sign
             (eq t (or (message-options-get 'message-sign-encrypt)
                       (message-options-set
                        'message-sign-encrypt
@@ -352,6 +353,7 @@ by you.")
   (autoload 'gpg-verify-cleartext "gpg")
   (autoload 'gpg-sign-detached "gpg")
   (autoload 'gpg-sign-encrypt "gpg")
+  (autoload 'gpg-encrypt "gpg")
   (autoload 'gpg-passphrase-read "gpg"))
 
 (defun mml2015-gpg-passphrase ()
@@ -415,10 +417,13 @@ by you.")
 (defun mml2015-gpg-extract-signature-details ()
   (goto-char (point-min))
   (if (boundp 'gpg-unabbrev-trust-alist)
-      (let* ((signer (and (re-search-forward
-                          "^\\[GNUPG:\\] GOODSIG [0-9A-Za-z]* \\(.*\\)$"
+      (let* ((expired (re-search-forward
+                      "^\\[GNUPG:\\] SIGEXPIRED$"
+                      nil t))
+            (signer (and (re-search-forward
+                          "^\\[GNUPG:\\] GOODSIG \\([0-9A-Za-z]*\\) \\(.*\\)$"
                           nil t)
-                         (match-string 1)))
+                         (cons (match-string 1) (match-string 2))))
             (fprint (and (re-search-forward
                           "^\\[GNUPG:\\] VALIDSIG \\([0-9a-zA-Z]*\\) "
                       nil t)
@@ -428,12 +433,16 @@ by you.")
             (trust-good-enough-p
              (cdr (assoc (cdr (assoc trust gpg-unabbrev-trust-alist))
                      mml2015-trust-boundaries-alist))))
-       (if (and signer trust fprint)
-           (concat signer
-                   (unless trust-good-enough-p
-                     (concat "\nUntrusted, Fingerprint: "
-                             (mml2015-gpg-pretty-print-fpr fprint))))
-         "From unknown user"))
+       (cond ((and signer fprint)
+              (concat (cdr signer)
+                      (unless trust-good-enough-p
+                        (concat "\nUntrusted, Fingerprint: "
+                                (mml2015-gpg-pretty-print-fpr fprint)))
+                      (when expired
+                        (format "\nWARNING: Signature from expired key (%s)"
+                                (car signer)))))
+             (t
+              "From unknown user")))
     (if (re-search-forward "^gpg: Good signature from \"\\(.*\\)\"$" nil t)
        (match-string 1)
       "From unknown user")))
@@ -558,28 +567,42 @@ by you.")
       (insert (format "--%s--\n" boundary))
       (goto-char (point-max)))))
 
-(defun mml2015-gpg-encrypt (cont)
+(defun mml2015-gpg-encrypt (cont &optional sign)
   (let ((boundary
         (funcall mml-boundary-function (incf mml-multipart-number)))
        (text (current-buffer))
        cipher)
     (mm-with-unibyte-current-buffer-mule4
       (with-temp-buffer
-       (unless (gpg-sign-encrypt
-                text (setq cipher (current-buffer))
-                mml2015-result-buffer
-                (split-string
-                 (or
-                  (message-options-get 'message-recipients)
-                  (message-options-set 'message-recipients
-                                       (read-string "Recipients: ")))
-                 "[ \f\t\n\r\v,]+")
-                nil
-                (message-options-get 'message-sender)
-                t t) ; armor & textmode
-         (unless (> (point-max) (point-min))
-           (pop-to-buffer mml2015-result-buffer)
-           (error "Encrypt error")))
+       ;; set up a function to call the correct gpg encrypt routine
+       ;; with the right arguments. (FIXME: this should be done
+       ;; differently.)
+       (flet ((gpg-encrypt-func 
+                (sign plaintext ciphertext result recipients &optional
+                      passphrase sign-with-key armor textmode)
+                (if sign
+                    (gpg-sign-encrypt
+                     plaintext ciphertext result recipients passphrase
+                     sign-with-key armor textmode)
+                  (gpg-encrypt
+                   plaintext ciphertext result recipients passphrase
+                   armor textmode))))
+         (unless (gpg-encrypt-func
+                   sign ; passed in when using signencrypt
+                   text (setq cipher (current-buffer))
+                   mml2015-result-buffer
+                   (split-string
+                    (or
+                     (message-options-get 'message-recipients)
+                     (message-options-set 'message-recipients
+                                          (read-string "Recipients: ")))
+                    "[ \f\t\n\r\v,]+")
+                   nil
+                   (message-options-get 'message-sender)
+                   t t) ; armor & textmode
+           (unless (> (point-max) (point-min))
+             (pop-to-buffer mml2015-result-buffer)
+             (error "Encrypt error"))))
        (goto-char (point-min))
        (while (re-search-forward "\r+$" nil t)
          (replace-match "" t t))
@@ -640,11 +663,11 @@ by you.")
   mml2015-use)
 
 ;;;###autoload
-(defun mml2015-encrypt (cont)
+(defun mml2015-encrypt (cont &optional sign)
   (mml2015-clean-buffer)
   (let ((func (nth 2 (assq mml2015-use mml2015-function-alist))))
     (if func
-       (funcall func cont)
+       (funcall func cont sign)
       (error "Cannot find encrypt function"))))
 
 ;;;###autoload
index 78676fe..8cecb1e 100644 (file)
         (while (re-search-backward "^X-Gnus-Newsgroup: " beg t)
           (delete-region (point) (progn (forward-line 1) (point)))))
        (when nnmail-cache-accepted-message-ids
-        (nnmail-cache-insert (nnmail-fetch-field "message-id")))
+        (nnmail-cache-insert (nnmail-fetch-field "message-id") group))
        (setq result
             (if (stringp group)
                 (list (cons group (nnbabyl-active-number group)))
        (insert-buffer-substring buf)
        (when last
         (when nnmail-cache-accepted-message-ids
-          (nnmail-cache-insert (nnmail-fetch-field "message-id")))
+          (nnmail-cache-insert (nnmail-fetch-field "message-id") group))
         (save-buffer)
         (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file))
        result))))
index 45aac6c..b3b7cf3 100644 (file)
@@ -759,7 +759,7 @@ all.  This may very well take some time.")
   (when (nndiary-schedule)
     (let (result)
       (when nnmail-cache-accepted-message-ids
-       (nnmail-cache-insert (nnmail-fetch-field "message-id")))
+       (nnmail-cache-insert (nnmail-fetch-field "message-id") group))
       (if (stringp group)
          (and
           (nnmail-activate 'nndiary)
index 143b05e..b675e26 100644 (file)
@@ -579,7 +579,7 @@ from the document.")
               (cons 'body-begin "^ ?\n")
               (cons 'article-begin b-delimiter)
               (cons 'body-end-function 'nndoc-digest-body-end)
-              (cons 'file-end (concat "\n--" boundary-id "--[ \t]*$"))))
+              (cons 'file-end (concat "^--" boundary-id "--[ \t]*$"))))
       t)))
 
 (defun nndoc-standard-digest-type-p ()
index 591a0bd..013fb40 100644 (file)
@@ -160,7 +160,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
-    (let (article start stop)
+    (let (article start stop num)
       (nnfolder-possibly-change-group group server)
       (when nnfolder-current-buffer
        (set-buffer nnfolder-current-buffer)
@@ -175,16 +175,53 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
                            (nnfolder-existing-articles)))
            (while (setq article (pop articles))
              (set-buffer nnfolder-current-buffer)
-             (when (nnfolder-goto-article article)
-               (setq start (point))
-               (setq stop (if (search-forward "\n\n" nil t)
-                              (1- (point))
-                            (point-max)))
-               (set-buffer nntp-server-buffer)
-               (insert (format "221 %d Article retrieved.\n" article))
-               (insert-buffer-substring nnfolder-current-buffer start stop)
-               (goto-char (point-max))
-               (insert ".\n")))
+             (cond ((nnfolder-goto-article article)
+                    (setq start (point))
+                    (setq stop (if (search-forward "\n\n" nil t)
+                                   (1- (point))
+                                 (point-max)))
+                    (set-buffer nntp-server-buffer)
+                    (insert (format "221 %d Article retrieved.\n" article))
+                    (insert-buffer-substring nnfolder-current-buffer
+                                             start stop)
+                    (goto-char (point-max))
+                    (insert ".\n"))
+
+                   ;; If we couldn't find this article, skip over ranges
+                   ;; of missing articles so we don't search the whole file
+                   ;; for each of them.
+                   ((numberp article)
+                    (setq start (point))
+                    (and
+                     ;; Check that we are either at BOF or after an
+                     ;; article with a lower number.  We do this so we
+                     ;; won't be confused by out-of-order article numbers,
+                     ;; as caused by active file bogosity.
+                     (cond
+                      ((bobp))
+                      ((search-backward (concat "\n" nnfolder-article-marker)
+                                        nil t)
+                       (goto-char (match-end 0))
+                       (setq num (string-to-int
+                                  (buffer-substring
+                                   (point) (progn (end-of-line) (point)))))
+                       (goto-char start)
+                       (< num article)))
+                     ;; Check that we are before an article with a
+                     ;; higher number.
+                     (search-forward (concat "\n" nnfolder-article-marker)
+                                     nil t)
+                     (progn
+                       (setq num (string-to-int
+                                  (buffer-substring
+                                   (point) (progn (end-of-line) (point)))))
+                       (> num article))
+                     ;; Discard any article numbers before the one we're
+                     ;; now looking at.
+                     (while (and articles
+                                 (< (car articles) num))
+                       (setq articles (cdr articles))))
+                    (goto-char start))))
            (set-buffer nntp-server-buffer)
            (nnheader-fold-continuation-lines)
            'headers))))))
@@ -491,7 +528,7 @@ the group.  Then the marks file will be regenerated properly by Gnus.")
        (while (re-search-backward (concat "^" nnfolder-article-marker) nil t)
          (delete-region (point) (progn (forward-line 1) (point))))
        (when nnmail-cache-accepted-message-ids
-         (nnmail-cache-insert (nnmail-fetch-field "message-id")))
+         (nnmail-cache-insert (nnmail-fetch-field "message-id") group))
        (setq result (if (stringp group)
                         (list (cons group (nnfolder-active-number group)))
                       (setq art-group
index b6ca95c..312c274 100644 (file)
@@ -79,7 +79,18 @@ Integer values will in effect be rounded up to the nearest multiple of
 (defvar nnheader-head-chop-length 2048
   "*Length of each read operation when trying to fetch HEAD headers.")
 
-(defvar nnheader-file-name-translation-alist nil
+(defvar nnheader-file-name-translation-alist
+  (let ((case-fold-search t))
+    (cond
+     ((string-match "windows-nt\\|os/2\\|emx\\|cygwin32"
+                   (symbol-name system-type))
+      (append (mapcar (lambda (c) (cons c ?_))
+                     '(?: ?* ?\" ?< ?> ??))
+             (if (string-match "windows-nt\\|cygwin32"
+                               (symbol-name system-type))
+                 nil
+               '((?+ . ?-)))))
+     (t nil)))
   "*Alist that says how to translate characters in file names.
 For instance, if \":\" is invalid as a file character in file names
 on your system, you could say something like:
@@ -458,6 +469,18 @@ given, the return value will not contain the last newline."
 
   (defalias 'mail-header-field-value 'std11-field-value))
 
+;; ietf-drums stuff.
+(unless (featurep 'ietf-drums)
+  ;; Should keep track of `ietf-drums-unfold-fws' in ietf-drums.el.
+  (defun nnheader-unfold-fws ()
+    "Unfold folding white space in the current buffer."
+    (goto-char (point-min))
+    (while (re-search-forward "[ \t]*\n[ \t]+" nil t)
+      (replace-match " " t t))
+    (goto-char (point-min)))
+
+  (defalias 'ietf-drums-unfold-fws 'nnheader-unfold-fws))
+
 ;;; Header access macros.
 
 ;; These macros may look very much like the ones in GNUS 4.1.  They
index 3f39bb1..335cdcd 100644 (file)
@@ -55,6 +55,7 @@
 ;;   o What about Gnus's article editing, can we support it?  NO!
 ;;   o Use \Draft to support the draft group??
 ;;   o Duplicate suppression
+;;   o Rewrite UID SEARCH UID X as UID FETCH X (UID) for those with slow servers
 
 ;;; Code:
 
@@ -281,9 +282,12 @@ typical complete file name would be
 (defvoo nnimap-nov-file-name-suffix ".novcache"
   "Suffix for NOV cache base filename.")
 
-(defvoo nnimap-nov-is-evil nil
-  "If non-nil, nnimap will never generate or use a local nov database for this backend.
-Using nov databases will speed up header fetching considerably.
+(defvoo nnimap-nov-is-evil gnus-agent
+  "If non-nil, never generate or use a local nov database for this backend.
+Using nov databases should speed up header fetching considerably.
+However, it will invoke a UID SEARCH UID command on the server, and
+some servers implement this command inefficiently by opening each and
+every message in the group, thus making it quite slow.
 Unlike other backends, you do not need to take special care if you
 flip this variable.")
 
@@ -379,7 +383,7 @@ restrict visible folders.")
 
 ;; Internal variables:
 
-(defvoo nnimap-mailbox-info (gnus-make-hashtable 997))
+(defvar nnimap-mailbox-info (gnus-make-hashtable 997))
 (defvar nnimap-debug nil
   "Name of buffer to record debugging info.
 For example: (setq nnimap-debug \"*nnimap-debug*\")")
@@ -969,7 +973,8 @@ function is generally only called when Gnus is shutting down."
            (setq slowgroups groups)
          (dolist (group groups)
            (gnus-message 7 "nnimap: Checking mailbox %s" group)
-           (add-to-list (if (gnus-gethash-safe group nnimap-mailbox-info)
+           (add-to-list (if (gnus-gethash-safe (concat server group)
+                                               nnimap-mailbox-info)
                             'asyncgroups
                           'slowgroups)
                         (list group (imap-mailbox-status-asynch
@@ -980,10 +985,12 @@ function is generally only called when Gnus is shutting down."
                  new old)
              (when (imap-ok-p (imap-wait-for-tag tag nnimap-server-buffer))
                (if (nnimap-string-lessp-numerical
-                    (car (gnus-gethash group nnimap-mailbox-info))
+                    (car (gnus-gethash
+                          (concat server group) nnimap-mailbox-info))
                     (imap-mailbox-get 'uidnext group nnimap-server-buffer))
                    (push (list group) slowgroups)
-                 (insert (cdr (gnus-gethash group nnimap-mailbox-info))))))))
+                 (insert (cdr (gnus-gethash (concat server group)
+                                            nnimap-mailbox-info))))))))
        (dolist (group slowgroups)
          (if nnimap-retrieve-groups-asynchronous
              (setq group (car group)))
@@ -1002,7 +1009,7 @@ function is generally only called when Gnus is shutting down."
                (insert str)
                (when nnimap-retrieve-groups-asynchronous
                  (gnus-sethash
-                  group
+                  (concat server group)
                   (cons (or (imap-mailbox-get
                              'uidnext group nnimap-server-buffer)
                             (imap-mailbox-status
@@ -1150,7 +1157,10 @@ function is generally only called when Gnus is shutting down."
              (goto-char (point-min))
              (when (and (if (stringp regexp)
                             (progn
-                              (setq regrepp (string-match "\\\\[0-9&]" group))
+                              (if (not (stringp group))
+                                  (setq group (eval group))
+                                (setq regrepp
+                                      (string-match "\\\\[0-9&]" group)))
                               (re-search-forward regexp nil t))
                           (funcall regexp group))
                         ;; Don't enter the article into the same group twice.
@@ -1209,8 +1219,10 @@ function is generally only called when Gnus is shutting down."
                         (setq removeorig t)
                         (when nnmail-cache-accepted-message-ids
                           (with-current-buffer nntp-server-buffer
-                            (nnmail-cache-insert (nnmail-fetch-field
-                                                  "message-id") to-group)))
+                             (let (msgid)
+                               (and (setq msgid 
+                                         (nnmail-fetch-field "message-id"))
+                                    (nnmail-cache-insert msgid to-group)))))
                         ;; Add the group-art list to the history list.
                         (push (list (cons to-group 0)) nnmail-split-history))
                        (t
@@ -1381,7 +1393,8 @@ function is generally only called when Gnus is shutting down."
                    (while (search-forward "\n" nil t)
                      (replace-match "\r\n"))
                    (when nnmail-cache-accepted-message-ids
-                     (nnmail-cache-insert (nnmail-fetch-field "message-id"))))
+                     (nnmail-cache-insert (nnmail-fetch-field "message-id")
+                                          group)))
                  (when (and last nnmail-cache-accepted-message-ids)
                    (nnmail-cache-close))
                  ;; this 'or' is for Cyrus server bug
index a98a187..fafa6e2 100644 (file)
@@ -103,7 +103,8 @@ The last element should always have \"\" as the regexp.
 
 This variable can also have a function as its value."
   :group 'nnmail-split
-  :type '(choice (repeat :tag "Alist" (group (string :tag "Name") regexp))
+  :type '(choice (repeat :tag "Alist" (group (string :tag "Name")
+                                            (choice regexp function)))
                 (function-item nnmail-split-fancy)
                 (function :tag "Other")))
 
@@ -122,6 +123,15 @@ If nil, the first match found will be used."
                 (regexp :value ".*")
                 (repeat :value (".*") regexp)))
 
+(defcustom nnmail-cache-ignore-groups nil
+  "Regexp that matches group names to be ignored when inserting message
+ids into the cache (`nnmail-cache-insert').  This can also be a list
+of regexps."
+  :group 'nnmail-split
+  :type '(choice (const :tag "none" nil)
+                (regexp :value ".*")
+                (repeat :value (".*") regexp)))
+
 ;; Added by gord@enci.ucalgary.ca (Gordon Matzigkeit).
 (defcustom nnmail-keep-last-article nil
   "If non-nil, nnmail will never delete/move a group's last article.
@@ -483,6 +493,11 @@ parameter.  It should return nil, `warn' or `delete'."
   :group 'nnmail
   :type 'symbol)
 
+(defcustom nnmail-mail-splitting-decodes t
+  "Whether the nnmail splitting functionality should MIME decode headers."
+  :group 'nnmail
+  :type 'boolean)
+
 ;;; Internal variables.
 
 (defvar nnmail-article-buffer " *nnmail incoming*"
@@ -1001,8 +1016,9 @@ FUNC will be called with the group name to determine the article number."
        ;; Copy the headers into the work buffer.
        (insert-buffer-substring obuf beg end)
        ;; Decode MIME headers and charsets.
-       (mime-decode-header-in-region (point-min) (point-max)
-                                     nnmail-mail-splitting-charset)
+       (when nnmail-mail-splitting-decodes
+         (mime-decode-header-in-region (point-min) (point-max)
+                                       nnmail-mail-splitting-charset))
        ;; Fold continuation lines.
        (goto-char (point-min))
        (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
@@ -1457,37 +1473,28 @@ See the documentation for the variable `nnmail-split-fancy' for documentation."
 (defvar group)
 (defvar group-art-list)
 (defvar group-art)
-(defun nnmail-cache-insert (id &optional grp)
+(defun nnmail-cache-insert (id grp)
   (when nnmail-treat-duplicates
     ;; Store some information about the group this message is written
-    ;; to.  This function might have been called from various places.
-    ;; Sometimes, a function up in the calling sequence has an
-    ;; argument GROUP which is bound to a string, the group name.  At
-    ;; other times, there is a function up in the calling sequence
-    ;; which has an argument GROUP-ART which is a list of pairs, and
-    ;; the car of a pair is a group name.  Should we check that the
-    ;; length of the list is equal to 1? -- kai
-    (let ((g nil))
-      (cond (grp
-            (setq g grp))
-           ((and (boundp 'group) group)
-            (setq g group))
-           ((and (boundp 'group-art-list) group-art-list
-                 (listp group-art-list))
-            (setq g (caar group-art-list)))
-           ((and (boundp 'group-art) group-art (listp group-art))
-            (setq g (caar group-art)))
-           (t (setq g "")))
-      (unless (gnus-buffer-live-p nnmail-cache-buffer)
-       (nnmail-cache-open))
-      (save-excursion
-       (set-buffer nnmail-cache-buffer)
-       (goto-char (point-max))
-       (if (and g (not (string= "" g))
-                (gnus-methods-equal-p gnus-command-method
-                                      (nnmail-cache-primary-mail-backend)))
-           (insert id "\t" g "\n")
-         (insert id "\n"))))))
+    ;; to.  This is passed in as the grp argument -- all locations this
+    ;; has been called from have been checked and the group is available.
+    ;; The only ambiguous case is nnmail-check-duplication which will only
+    ;; pass the first (of possibly >1) group which matches. -Josh
+    (unless (gnus-buffer-live-p nnmail-cache-buffer)
+      (nnmail-cache-open))
+    (save-excursion
+      (set-buffer nnmail-cache-buffer)
+      (goto-char (point-max))
+      (if (and grp (not (string= "" grp))
+              (gnus-methods-equal-p gnus-command-method
+                                    (nnmail-cache-primary-mail-backend)))
+         (let ((regexp (if (consp nnmail-cache-ignore-groups)
+                           (mapconcat 'identity nnmail-cache-ignore-groups
+                                      "\\|")
+                         nnmail-cache-ignore-groups)))
+           (unless (and regexp (string-match regexp grp))
+             (insert id "\t" grp "\n")))
+       (insert id "\n")))))
 
 (defun nnmail-cache-primary-mail-backend ()
   (let ((be-list (cons gnus-select-method gnus-secondary-select-methods))
@@ -1589,7 +1596,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
      ((not duplication)
       (funcall func (setq group-art
                          (nreverse (nnmail-article-group artnum-func))))
-      (nnmail-cache-insert message-id))
+      (nnmail-cache-insert message-id (caar group-art)))
      ((eq action 'delete)
       (setq group-art nil))
      ((eq action 'warn)
@@ -1764,7 +1771,9 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
        (setq target (format-time-string (caddr regexp-target-pair) date)))
        ((and (not (equal header 'to-from))
             (string-match (cadr regexp-target-pair)
-                          (message-fetch-field header)))
+                          (or
+                           (message-fetch-field header)
+                           "")))
        (setq target
              (format-time-string (caddr regexp-target-pair) date)))))))
 
index 2c01d2b..e9d5ef5 100644 (file)
@@ -700,7 +700,9 @@ by nnmaildir-request-article.")
 
 (defun nnmaildir-request-scan (&optional scan-group server)
   (let ((coding-system-for-write nnheader-file-coding-system)
+       (output-coding-system nnheader-file-coding-system)
        (buffer-file-coding-system nil)
+       (file-coding-system nil)
        (file-coding-system-alist nil)
        (nnmaildir-get-new-mail t)
        (nnmaildir-group-alist nil)
@@ -934,7 +936,9 @@ by nnmaildir-request-article.")
 (defun nnmaildir-request-rename-group (gname new-name &optional server)
   (let ((group (nnmaildir--prepare server gname))
        (coding-system-for-write nnheader-file-coding-system)
+       (output-coding-system nnheader-file-coding-system)
        (buffer-file-coding-system nil)
+       (file-coding-system nil)
        (file-coding-system-alist nil)
        srv-dir x groups)
     (catch 'return
@@ -1201,7 +1205,9 @@ by nnmaildir-request-article.")
 (defun nnmaildir-request-replace-article (article gname buffer)
   (let ((group (nnmaildir--prepare nil gname))
        (coding-system-for-write nnheader-file-coding-system)
+       (output-coding-system nnheader-file-coding-system)
        (buffer-file-coding-system nil)
+       (file-coding-system nil)
        (file-coding-system-alist nil)
        file dir suffix tmpfile deactivate-mark)
     (catch 'return
@@ -1287,7 +1293,9 @@ by nnmaildir-request-article.")
 (defun nnmaildir-request-accept-article (gname &optional server last)
   (let ((group (nnmaildir--prepare server gname))
        (coding-system-for-write nnheader-file-coding-system)
+       (output-coding-system nnheader-file-coding-system)
        (buffer-file-coding-system nil)
+       (file-coding-system nil)
        (file-coding-system-alist nil)
        srv-dir dir file tmpfile curfile 24h num article)
     (catch 'return
@@ -1500,7 +1508,9 @@ by nnmaildir-request-article.")
 (defun nnmaildir-request-set-mark (gname actions &optional server)
   (let ((group (nnmaildir--prepare server gname))
        (coding-system-for-write nnheader-file-coding-system)
+       (output-coding-system nnheader-file-coding-system)
        (buffer-file-coding-system nil)
+       (file-coding-system nil)
        (file-coding-system-alist nil)
        del-mark add-marks marksdir markfile action group-nlist nlist ranges
        begin end article all-marks todo-marks did-marks marks form mdir mfile
index 8157bec..fe4a30b 100644 (file)
                       (1+ (- (cdr active) (car active)))
                       (car active) (cdr active) group)))))
 
-(static-if (boundp 'MULE)
-    (defun nnmbox-save-buffer ()
-      (let ((output-coding-system
-            (or nnmbox-file-coding-system-for-write
-                nnmbox-file-coding-system)))
-       (save-buffer)))
-  (defun nnmbox-save-buffer ()
-    (let ((coding-system-for-write
-          (or nnmbox-file-coding-system-for-write
-              nnmbox-file-coding-system)))
-      (save-buffer)))
-  )
+(defun nnmbox-save-buffer ()
+  (let* ((coding-system-for-write (or nnmbox-file-coding-system-for-write
+                                     nnmbox-file-coding-system))
+        (output-coding-system coding-system-for-write))
+    (save-buffer)))
 
 (defun nnmbox-save-active (group-alist active-file)
   (let ((nnmail-active-file-coding-system
        (while (re-search-backward "^X-Gnus-Newsgroup: " nil t)
         (delete-region (point) (progn (forward-line 1) (point))))
        (when nnmail-cache-accepted-message-ids
-        (nnmail-cache-insert (nnmail-fetch-field "message-id")))
+        (nnmail-cache-insert (nnmail-fetch-field "message-id") group))
        (setq result (if (stringp group)
                        (list (cons group (nnmbox-active-number group)))
                      (nnmail-article-group 'nnmbox-active-number)))
index 91fbcc0..e814774 100644 (file)
@@ -325,7 +325,7 @@ as unread by Gnus.")
           (not (equal group "draft")))
       (nnmail-check-syntax))
   (when nnmail-cache-accepted-message-ids
-    (nnmail-cache-insert (nnmail-fetch-field "message-id")))
+    (nnmail-cache-insert (nnmail-fetch-field "message-id") group))
   (nnheader-init-server-buffer)
   (prog1
       (if (stringp group)
index d27213f..7a1b531 100644 (file)
@@ -375,7 +375,7 @@ marks file will be regenerated properly by Gnus.")
   (nnmail-check-syntax)
   (let (result)
     (when nnmail-cache-accepted-message-ids
-      (nnmail-cache-insert (nnmail-fetch-field "message-id")))
+      (nnmail-cache-insert (nnmail-fetch-field "message-id") group))
     (if (stringp group)
        (and
         (nnmail-activate 'nnml)
index fd9ea8a..8f66d43 100644 (file)
@@ -378,6 +378,7 @@ ARTICLE is the article number of the current headline.")
     (when (file-exists-p file)
       (with-temp-buffer
        (let ((coding-system-for-read 'binary)
+             (input-coding-system 'binary)
              emacs-lisp-mode-hook)
          (insert-file-contents file)
          (emacs-lisp-mode)
@@ -394,6 +395,7 @@ ARTICLE is the article number of the current headline.")
                        server ".el"))
               nnrss-directory)))
     (let ((coding-system-for-write 'binary)
+         (output-coding-system 'binary)
          print-level print-length)
       (with-temp-file file
        (insert "(setq nnrss-server-data '"
@@ -416,6 +418,7 @@ ARTICLE is the article number of the current headline.")
     (when (file-exists-p file)
       (with-temp-buffer
        (let ((coding-system-for-read 'binary)
+             (input-coding-system 'binary)
              emacs-lisp-mode-hook)
          (insert-file-contents file)
          (emacs-lisp-mode)
@@ -438,6 +441,7 @@ ARTICLE is the article number of the current headline.")
                        server ".el"))
               nnrss-directory)))
     (let ((coding-system-for-write 'binary)
+         (output-coding-system 'binary)
          print-level print-length)
       (with-temp-file file
        (insert "(setq nnrss-group-data '"
index 5820103..45299f5 100644 (file)
@@ -54,6 +54,9 @@
 (defvoo nnslashdot-backslash-url "http://slashdot.org/slashdot.xml"
   "Where nnslashdot will fetch the stories from.")
 
+(defvoo nnslashdot-use-front-page nil
+  "Use the front page in addition to the backslash page.")
+
 (defvoo nnslashdot-threshold -1
   "The article threshold.")
 
 (deffoo nnslashdot-request-list (&optional server)
   (nnslashdot-possibly-change-server nil server)
   (let ((number 0)
+       (first nnslashdot-use-front-page)
        sid elem description articles gname)
     (condition-case why
        ;; First we do the Ultramode to get info on all the latest groups.
              (goto-char (point-max))
              (widen)))
          ;; Then do the older groups.
-         (while (> (- nnslashdot-group-number number) 0)
+         (while (or first
+                    (> (- nnslashdot-group-number number) 0))
+           (setq first nil)
            (mm-with-unibyte-buffer
              (let ((case-fold-search t))
                (mm-url-insert (format nnslashdot-active-url number) t)
                (goto-char (point-min))
                (while (re-search-forward
-                       "article.pl\\?sid=\\([^&]+\\).*<b>\\([^<]+\\)</b>"
+                       "article.pl\\?sid=\\([^&]+\\).*>\\([^<]+\\)</a>"
                        nil t)
                  (setq sid (match-string 1)
                        description
                        (mm-url-decode-entities-string (match-string 2)))
                  (forward-line 1)
-                 (when (re-search-forward "<b>\\([0-9]+\\)</b>" nil t)
-                   (setq articles (string-to-number (match-string 1))))
+                 (when (re-search-forward "with \\([0-9]+\\) comment" nil t)
+                   (setq articles (1+ (string-to-number (match-string 1)))))
                  (setq gname (concat description " (" sid ")"))
                  (if (setq elem (assoc gname nnslashdot-groups))
                      (setcar (cdr elem) articles)
index 0836590..e0bda9e 100644 (file)
@@ -115,7 +115,7 @@ backend for the messages.")
        ;; articles in SEQUENCE come from.
        (while (and areas sequence)
          ;; Peel off areas that are below sequence.
-         (while (and areas (< (cdaar areas) (car sequence)))
+         (while (and areas (< (cdar (car areas)) (car sequence)))
            (setq areas (cdr areas)))
          (when areas
            ;; This is a useful area.
@@ -131,7 +131,7 @@ backend for the messages.")
              (setq use-nov nil))
            ;; We assign the portion of `sequence' that is relevant to
            ;; this MSG packet to this packet.
-           (while (and sequence (<= (car sequence) (cdaar areas)))
+           (while (and sequence (<= (car sequence) (cdar (car areas))))
              (push (car sequence) this-area-seq)
              (setq sequence (cdr sequence)))
            (setcar useful-areas (cons (nreverse this-area-seq)
@@ -250,7 +250,7 @@ backend for the messages.")
   ;; Try to guess the type based on the first article in the group.
   (when (not article)
     (setq article
-         (cdaar (cddr (assoc group nnsoup-group-alist)))))
+         (cdar (car (cddr (assoc group nnsoup-group-alist))))))
   (if (not article)
       'unknown
     (let ((kind (gnus-soup-encoding-kind
@@ -372,7 +372,7 @@ backend for the messages.")
          (setq min (caaar e))
          (while (cdr e)
            (setq e (cdr e)))
-         (setq max (cdaar e))
+         (setq max (cdar (car e)))
          (setcdr entry (cons (cons min max) (cdr entry)))))
       (setq nnsoup-group-alist-touched t))
     nnsoup-group-alist))
@@ -652,7 +652,7 @@ backend for the messages.")
 (defun nnsoup-article-to-area (article group)
   "Return the area that ARTICLE in GROUP is located in."
   (let ((areas (cddr (assoc group nnsoup-group-alist))))
-    (while (and areas (< (cdaar areas) article))
+    (while (and areas (< (cdar (car areas)) article))
       (setq areas (cdr areas)))
     (and areas (car areas))))
 
index 8bbf408..047b8a5 100644 (file)
@@ -138,6 +138,13 @@ using and indirect connection method (nntp-open-via-*).")
 This command is used by the `nntp-open-via-rlogin-and-telnet' method.
 The default is \"rsh\", but \"ssh\" is a popular alternative.")
 
+(defvoo nntp-via-rlogin-command-switches nil
+  "*Switches given to the rlogin command `nntp-via-rlogin-command'.
+If you use \"ssh\" for `nntp-via-rlogin-command', you may set this to
+\(\"-C\") in order to compress all data connections, otherwise set this
+to \(\"-t\") or (\"-C\" \"-t\") if the telnet command requires a pseudo-tty
+allocation on an intermediate host.")
+
 (defvoo nntp-via-telnet-command "telnet"
   "*Telnet command used to connect to an intermediate host.
 This command is used by the `nntp-open-via-telnet-and-telnet' method.")
@@ -1664,6 +1671,7 @@ from there.
 Please refer to the following variables to customize the connection:
 - `nntp-pre-command',
 - `nntp-via-rlogin-command',
+- `nntp-via-rlogin-command-switches',
 - `nntp-via-user-name',
 - `nntp-via-address',
 - `nntp-telnet-command',
@@ -1673,11 +1681,12 @@ Please refer to the following variables to customize the connection:
 - `nntp-end-of-line'."
   (let ((command `(,nntp-via-address
                   ,nntp-telnet-command
-                  ,@nntp-telnet-switches
-                  ,nntp-address ,nntp-port-number))
+                  ,@nntp-telnet-switches))
        proc)
-    (and nntp-via-user-name
-        (setq command `("-l" ,nntp-via-user-name ,@command)))
+    (when nntp-via-user-name
+      (setq command `("-l" ,nntp-via-user-name ,@command)))
+    (when nntp-via-rlogin-command-switches
+      (setq command (append nntp-via-rlogin-command-switches command)))
     (push nntp-via-rlogin-command command)
     (and nntp-pre-command
         (push nntp-pre-command command))
@@ -1685,6 +1694,9 @@ Please refer to the following variables to customize the connection:
                (apply 'start-process "nntpd" buffer command)))
     (save-excursion
       (set-buffer buffer)
+      (nntp-wait-for-string "^r?telnet")
+      (process-send-string proc (concat "open " nntp-address
+                                       " " nntp-port-number "\n"))
       (nntp-wait-for-string "^\r*20[01]")
       (beginning-of-line)
       (delete-region (point-min) (point))
index 9ae4303..ece9640 100644 (file)
@@ -50,8 +50,7 @@
 
 (defvoo nnweb-type 'google
   "What search engine type is being used.
-Valid types include `google', `dejanews', `dejanewsold', `reference',
-and `altavista'.")
+Valid types include `google', `dejanews', and `gmane'.")
 
 (defvar nnweb-type-definition
   '((google
@@ -63,33 +62,25 @@ and `altavista'.")
      (address . "http://groups.google.com/groups")
      (identifier . nnweb-google-identity))
     (dejanews ;; alias of google
-     ;;(article . nnweb-google-wash-article)
-     ;;(id . "http://groups.google.com/groups?as_umsgid=%s")
      (article . ignore)
      (id . "http://groups.google.com/groups?selm=%s&output=gplain")
-     ;;(reference . nnweb-google-reference)
      (reference . identity)
      (map . nnweb-google-create-mapping)
      (search . nnweb-google-search)
      (address . "http://groups.google.com/groups")
      (identifier . nnweb-google-identity))
-    (reference
-     (article . nnweb-reference-wash-article)
-     (map . nnweb-reference-create-mapping)
-     (search . nnweb-reference-search)
-     (address . "http://www.reference.com/cgi-bin/pn/go")
-     (identifier . identity))
-    (altavista
-     (article . nnweb-altavista-wash-article)
-     (map . nnweb-altavista-create-mapping)
-     (search . nnweb-altavista-search)
-     (address . "http://www.altavista.digital.com/cgi-bin/query")
-     (id . "/cgi-bin/news?id@%s")
-     (identifier . identity)))
+    (gmane
+     (article . nnweb-gmane-wash-article)
+     (id . "http://gmane.org/view.php?group=%s")
+     (reference . identity)
+     (map . nnweb-gmane-create-mapping)
+     (search . nnweb-gmane-search)
+     (address . "http://gmane.org/")
+     (identifier . nnweb-gmane-identity)))
   "Type-definition alist.")
 
 (defvoo nnweb-search nil
-  "Search string to feed to DejaNews.")
+  "Search string to feed to Google.")
 
 (defvoo nnweb-max-hits 999
   "Maximum number of hits to display.")
@@ -312,385 +303,6 @@ and `altavista'.")
                       nnweb-type nnweb-search server))
              (current-buffer))))))
 
-;; (defun nnweb-fetch-url (url)
-;;   (let (buf)
-;;     (save-excursion
-;;       (if (not nnheader-callback-function)
-;;       (progn
-;;         (with-temp-buffer
-;;           (mm-enable-multibyte)
-;;           (let ((coding-system-for-read 'binary)
-;;                 (coding-system-for-write 'binary)
-;;                 (input-coding-system 'binary)
-;;                 (output-coding-system 'binary)
-;;                 (default-process-coding-system 'binary))
-;;             (nnweb-insert url))
-;;           (setq buf (buffer-string)))
-;;         (erase-buffer)
-;;         (insert buf)
-;;         t)
-;;     (nnweb-url-retrieve-asynch
-;;      url 'nnweb-callback (current-buffer) nnheader-callback-function)
-;;     t))))
-
-;; (defun nnweb-callback (buffer callback)
-;;   (when (gnus-buffer-live-p url-working-buffer)
-;;     (save-excursion
-;;       (set-buffer url-working-buffer)
-;;       (funcall (nnweb-definition 'article))
-;;       (nnweb-decode-entities)
-;;       (set-buffer buffer)
-;;       (goto-char (point-max))
-;;       (insert-buffer-substring url-working-buffer))
-;;     (funcall callback t)
-;;     (gnus-kill-buffer url-working-buffer)))
-
-;; (defun nnweb-url-retrieve-asynch (url callback &rest data)
-;;   (let ((url-request-method "GET")
-;;     (old-asynch url-be-asynchronous)
-;;     (url-request-data nil)
-;;     (url-request-extra-headers nil)
-;;     (url-working-buffer (generate-new-buffer-name " *nnweb*")))
-;;     (setq-default url-be-asynchronous t)
-;;     (save-excursion
-;;       (set-buffer (get-buffer-create url-working-buffer))
-;;       (setq url-current-callback-data data
-;;         url-be-asynchronous t
-;;         url-current-callback-func callback)
-;;       (url-retrieve url nil))
-;;     (setq-default url-be-asynchronous old-asynch)))
-
-;; (if (fboundp 'url-retrieve-synchronously)
-;;     (defun nnweb-url-retrieve-asynch (url callback &rest data)
-;;       (url-retrieve url callback data)))
-
-;;;
-;;; DejaNews functions.
-;;;
-
-(defun nnweb-dejanews-create-mapping ()
-  "Perform the search and create an number-to-url alist."
-  (save-excursion
-    (set-buffer nnweb-buffer)
-    (erase-buffer)
-    (when (funcall (nnweb-definition 'search) nnweb-search)
-      (let ((i 0)
-           (more t)
-           (case-fold-search t)
-           (active (or (cadr (assoc nnweb-group nnweb-group-alist))
-                       (cons 1 0)))
-           subject date from
-           map url parse a table group text)
-       (while more
-         ;; Go through all the article hits on this page.
-         (goto-char (point-min))
-         (setq parse (w3-parse-buffer (current-buffer))
-               table (nth 1 (nnweb-parse-find-all 'table parse)))
-         (dolist (row (nth 2 (car (nth 2 table))))
-           (setq a (nnweb-parse-find 'a row)
-                 url (cdr (assq 'href (nth 1 a)))
-                 text (nreverse (nnweb-text row)))
-           (when a
-             (setq subject (nth 4 text)
-                   group (nth 2 text)
-                   date (nth 1 text)
-                   from (nth 0 text))
-             (if (string-match "\\([0-9]+\\)/\\([0-9]+\\)/\\([0-9]+\\)" date)
-                 (setq date (format "%s %s 00:00:00 %s"
-                                    (car (rassq (string-to-number
-                                                 (match-string 2 date))
-                                                parse-time-months))
-                                    (match-string 3 date)
-                                    (match-string 1 date)))
-               (setq date "Jan 1 00:00:00 0000"))
-             (incf i)
-             (setq url (concat url "&fmt=text"))
-             (when (string-match "&context=[^&]+" url)
-               (setq url (replace-match "" t t url)))
-             (unless (nnweb-get-hashtb url)
-               (push
-                (list
-                 (incf (cdr active))
-                 (make-full-mail-header
-                  (cdr active) (concat subject " (" group ")") from date
-                  (concat "<" (nnweb-identifier url) "@dejanews>")
-                  nil 0 0 url))
-                map)
-               (nnweb-set-hashtb (cadar map) (car map)))))
-         ;; See whether there is a "Get next 20 hits" button here.
-         (goto-char (point-min))
-         (if (or (not (re-search-forward
-                       "HREF=\"\\([^\"]+\\)\"[<>b]+Next result" nil t))
-                 (>= i nnweb-max-hits))
-             (setq more nil)
-           ;; Yup -- fetch it.
-           (setq more (match-string 1))
-           (erase-buffer)
-           (mm-url-insert more)))
-       ;; Return the articles in the right order.
-       (setq nnweb-articles
-             (sort (nconc nnweb-articles map) 'car-less-than-car))))))
-
-(defun nnweb-dejanews-search (search)
-  (mm-url-insert
-   (concat
-    (nnweb-definition 'address)
-    "?"
-    (mm-url-encode-www-form-urlencoded
-     `(("ST" . "PS")
-       ("svcclass" . "dnyr")
-       ("QRY" . ,search)
-       ("defaultOp" . "AND")
-       ("DBS" . "1")
-       ("OP" . "dnquery.xp")
-       ("LNG" . "ALL")
-       ("maxhits" . "100")
-       ("threaded" . "0")
-       ("format" . "verbose2")
-       ("showsort" . "date")
-       ("agesign" . "1")
-       ("ageweight" . "1")))))
-  t)
-
-;; (defun nnweb-dejanewsold-search (search)
-;;   (nnweb-fetch-form
-;;    (nnweb-definition 'address)
-;;    `(("query" . ,search)
-;;      ("defaultOp" . "AND")
-;;      ("svcclass" . "dnold")
-;;      ("maxhits" . "100")
-;;      ("format" . "verbose2")
-;;      ("threaded" . "0")
-;;      ("showsort" . "date")
-;;      ("agesign" . "1")
-;;      ("ageweight" . "1")))
-;;   t)
-
-(defun nnweb-dejanews-identity (url)
-  "Return an unique identifier based on URL."
-  (if (string-match "AN=\\([0-9]+\\)" url)
-      (match-string 1 url)
-    url))
-
-;;;
-;;; InReference
-;;;
-
-(defun nnweb-reference-create-mapping ()
-  "Perform the search and create an number-to-url alist."
-  (save-excursion
-    (set-buffer nnweb-buffer)
-    (erase-buffer)
-    (when (funcall (nnweb-definition 'search) nnweb-search)
-      (let ((i 0)
-           (more t)
-           (case-fold-search t)
-           (active (or (cadr (assoc nnweb-group nnweb-group-alist))
-                       (cons 1 0)))
-           Subject Score Date Newsgroups From Message-ID
-           map url)
-       (while more
-         ;; Go through all the article hits on this page.
-         (goto-char (point-min))
-         (search-forward "</pre><hr>" nil t)
-         (delete-region (point-min) (point))
-         (goto-char (point-min))
-         (while (re-search-forward "^ +[0-9]+\\." nil t)
-           (narrow-to-region
-            (point)
-            (if (re-search-forward "^$" nil t)
-                (match-beginning 0)
-              (point-max)))
-           (goto-char (point-min))
-           (when (looking-at ".*href=\"\\([^\"]+\\)\"")
-             (setq url (match-string 1)))
-           (mm-url-remove-markup)
-           (goto-char (point-min))
-           (while (search-forward "\t" nil t)
-             (replace-match " "))
-           (goto-char (point-min))
-           (while (re-search-forward "^\\([^:]+\\): \\(.*\\)$" nil t)
-             (set (intern (match-string 1)) (match-string 2)))
-           (widen)
-           (search-forward "</pre>" nil t)
-           (incf i)
-           (unless (nnweb-get-hashtb url)
-             (push
-              (list
-               (incf (cdr active))
-               (make-full-mail-header
-                (cdr active) (concat  "(" Newsgroups ") " Subject) From Date
-                Message-ID
-                nil 0 (string-to-int Score) url))
-              map)
-             (nnweb-set-hashtb (cadar map) (car map))))
-         (setq more nil))
-       ;; Return the articles in the right order.
-       (setq nnweb-articles
-             (sort (nconc nnweb-articles map) 'car-less-than-car))))))
-
-(defun nnweb-reference-wash-article ()
-  (let ((case-fold-search t))
-    (goto-char (point-min))
-    (re-search-forward "^</center><hr>" nil t)
-    (delete-region (point-min) (point))
-    (search-forward "<pre>" nil t)
-    (forward-line -1)
-    (let ((body (point-marker)))
-      (search-forward "</pre>" nil t)
-      (delete-region (point) (point-max))
-      (mm-url-remove-markup)
-      (goto-char (point-min))
-      (while (looking-at " *$")
-       (gnus-delete-line))
-      (narrow-to-region (point-min) body)
-      (while (and (re-search-forward "^$" nil t)
-                 (not (eobp)))
-       (gnus-delete-line))
-      (goto-char (point-min))
-      (while (looking-at "\\(^[^ ]+:\\) *")
-       (replace-match "\\1 " t)
-       (forward-line 1))
-      (goto-char (point-min))
-      (when (re-search-forward "^References:" nil t)
-       (narrow-to-region
-        (point) (if (re-search-forward "^$\\|^[^:]+:" nil t)
-                    (match-beginning 0)
-                  (point-max)))
-       (goto-char (point-min))
-       (while (not (eobp))
-         (unless (looking-at "References")
-           (insert "\t")
-           (forward-line 1)))
-       (goto-char (point-min))
-       (while (search-forward "," nil t)
-         (replace-match " " t t)))
-      (widen)
-      (mm-url-decode-entities)
-      (set-marker body nil))))
-
-(defun nnweb-reference-search (search)
-  (mm-url-insert
-   (concat
-    (nnweb-definition 'address)
-    "?"
-    (mm-url-encode-www-form-urlencoded
-     `(("search" . "advanced")
-       ("querytext" . ,search)
-       ("subj" . "")
-       ("name" . "")
-       ("login" . "")
-       ("host" . "")
-       ("organization" . "")
-       ("groups" . "")
-       ("keywords" . "")
-       ("choice" . "Search")
-       ("startmonth" . "Jul")
-       ("startday" . "25")
-       ("startyear" . "1996")
-       ("endmonth" . "Aug")
-       ("endday" . "24")
-       ("endyear" . "1996")
-       ("mode" . "Quick")
-       ("verbosity" . "Verbose")
-       ("ranking" . "Relevance")
-       ("first" . "1")
-       ("last" . "25")
-       ("score" . "50")))))
-  (setq buffer-file-name nil)
-  t)
-
-;;;
-;;; Alta Vista
-;;;
-
-(defun nnweb-altavista-create-mapping ()
-  "Perform the search and create an number-to-url alist."
-  (save-excursion
-    (set-buffer nnweb-buffer)
-    (erase-buffer)
-    (let ((part 0))
-      (when (funcall (nnweb-definition 'search) nnweb-search part)
-       (let ((i 0)
-             (more t)
-             (case-fold-search t)
-             (active (or (cadr (assoc nnweb-group nnweb-group-alist))
-                         (cons 1 0)))
-             subject date from id group
-             map url)
-         (while more
-           ;; Go through all the article hits on this page.
-           (goto-char (point-min))
-           (search-forward "<dt>" nil t)
-           (delete-region (point-min) (match-beginning 0))
-           (goto-char (point-min))
-           (while (search-forward "<dt>" nil t)
-             (replace-match "\n<blubb>"))
-           (mm-url-decode-entities)
-           (goto-char (point-min))
-           (while (re-search-forward "<blubb>.*href=\"\\([^\"]+\\)\"><strong>\\([^>]*\\)</strong></a><dd>\\([^-]+\\)- <b>\\([^<]+\\)<.*href=\"news:\\([^\"]+\\)\">.*\">\\(.+\\)</a><P>"
-                                     nil t)
-             (setq url (match-string 1)
-                   subject (match-string 2)
-                   date (match-string 3)
-                   group (match-string 4)
-                   id (concat "<" (match-string 5) ">")
-                   from (match-string 6))
-             (incf i)
-             (unless (nnweb-get-hashtb url)
-               (push
-                (list
-                 (incf (cdr active))
-                 (make-full-mail-header
-                  (cdr active) (concat  "(" group ") " subject) from date
-                  id nil 0 0 url))
-                map)
-               (nnweb-set-hashtb (cadar map) (car map))))
-           ;; See if we want more.
-           (when (or (not nnweb-articles)
-                     (>= i nnweb-max-hits)
-                     (not (funcall (nnweb-definition 'search)
-                                   nnweb-search (incf part))))
-             (setq more nil)))
-         ;; Return the articles in the right order.
-         (setq nnweb-articles
-               (sort (nconc nnweb-articles map) 'car-less-than-car)))))))
-
-(defun nnweb-altavista-wash-article ()
-  (goto-char (point-min))
-  (let ((case-fold-search t))
-    (when (re-search-forward "^<strong>" nil t)
-      (delete-region (point-min) (match-beginning 0)))
-    (goto-char (point-min))
-    (while (looking-at "<strong>\\([^ ]+\\) +</strong> +\\(.*\\)$")
-      (replace-match "\\1: \\2" t)
-      (forward-line 1))
-    (when (re-search-backward "^References:" nil t)
-      (narrow-to-region (point) (progn (forward-line 1) (point)))
-      (goto-char (point-min))
-      (while (re-search-forward "<A.*\\?id@\\([^\"]+\\)\">[0-9]+</A>" nil t)
-       (replace-match "&lt;\\1&gt; " t)))
-    (widen)
-    (mm-url-remove-markup)
-    (mm-url-decode-entities)))
-
-(defun nnweb-altavista-search (search &optional part)
-  (mm-url-insert
-   (concat
-    (nnweb-definition 'address)
-    "?"
-    (mm-url-encode-www-form-urlencoded
-     `(("pg" . "aq")
-       ("what" . "news")
-       ,@(when part `(("stq" . ,(int-to-string (* part 30)))))
-       ("fmt" . "d")
-       ("q" . ,search)
-       ("r" . "")
-       ("d0" . "")
-       ("d1" . "")))))
-  (setq buffer-file-name nil)
-  t)
-
 ;;;
 ;;; Deja bought by google.com
 ;;;
@@ -796,12 +408,23 @@ and `altavista'.")
     (set-buffer nnweb-buffer)
     (erase-buffer)
     (when (funcall (nnweb-definition 'search) nnweb-search)
-      (let ((more t))
+      (let ((more t)
+           (i 0))
        (while more
          (setq nnweb-articles
                (nconc nnweb-articles (nnweb-google-parse-1)))
-         ;; FIXME: There is more.
-         (setq more nil))
+         ;; Check if there are more articles to fetch
+         (goto-char (point-min))
+         (incf i 100)
+         (if (or (not (re-search-forward
+                       "<td nowrap><a href=\\([^>]+\\).*<span class=b>Next</span>" nil t))
+                 (>= i nnweb-max-hits))
+             (setq more nil)
+           ;; Yup, there are more articles
+           (setq more (concat "http://groups.google.com" (match-string 1)))
+           (when more
+             (erase-buffer)
+             (mm-url-insert more))))
        ;; Return the articles in the right order.
        (setq nnweb-articles
              (sort nnweb-articles 'car-less-than-car))))))
@@ -828,6 +451,71 @@ and `altavista'.")
     url))
 
 ;;;
+;;; gmane.org
+;;;
+(defun nnweb-gmane-create-mapping ()
+  "Perform the search and create a number-to-url alist."
+  (save-excursion
+    (set-buffer nnweb-buffer)
+    (erase-buffer)
+    (when (funcall (nnweb-definition 'search) nnweb-search)
+      (let ((more t)
+           (case-fold-search t)
+           (active (or (cadr (assoc nnweb-group nnweb-group-alist))
+                       (cons 1 0)))
+           subject group url
+           map)
+         ;; Remove stuff from the beginning of results
+       (goto-char (point-min))
+       (search-forward "Search Results</h1><ul>" nil t)
+       (delete-region (point-min) (point))
+       (goto-char (point-min))
+       ;; Iterate over the actual hits
+       (while (re-search-forward ".*href=\"\\([^\"]+\\)\">\\(.*\\)" nil t)
+           (setq url (concat "http://gmane.org/" (match-string 1)))
+           (setq subject (match-string 2))
+         (unless (nnweb-get-hashtb url)
+           (push
+            (list
+             (incf (cdr active))
+             (make-full-mail-header
+              (cdr active) (concat  "(" group ") " subject) nil nil
+              nil nil 0 0 url))
+            map)
+           (nnweb-set-hashtb (cadar map) (car map))))
+       ;; Return the articles in the right order.
+       (setq nnweb-articles
+             (sort (nconc nnweb-articles map) 'car-less-than-car))))))
+
+(defun nnweb-gmane-wash-article ()
+  (let ((case-fold-search t))
+    (goto-char (point-min))
+    (re-search-forward "<!--X-Head-of-Message-->" nil t)
+    (delete-region (point-min) (point))
+    (goto-char (point-min))
+    (while (looking-at "^<li><em>\\([^ ]+\\)</em>.*</li>")
+      (replace-match "\\1\\2" t)
+      (forward-line 1))
+    (mm-url-remove-markup)))
+
+(defun nnweb-gmane-search (search)
+  (mm-url-insert
+   (concat
+    (nnweb-definition 'address)
+    "?"
+    (mm-url-encode-www-form-urlencoded
+     `(("query" . ,search)))))
+  (setq buffer-file-name nil)
+  t)
+
+
+(defun nnweb-gmane-identity (url)
+  "Return a unique identifier based on URL."
+  (if (string-match "group=\\(.+\\)" url)
+      (match-string 1 url)
+    url))
+
+;;;
 ;;; General web/w3 interface utility functions
 ;;;
 
index 3070b45..967c721 100644 (file)
@@ -42,6 +42,8 @@
 ;;
 ;; `sieve-manage-authenticate'
 ;; `sieve-manage-listscripts'
+;; `sieve-manage-deletescript'
+;; `sieve-manage-getscript'
 ;; performs managesieve protocol actions
 ;;
 ;; and that's it.  Example of a managesieve session in *scratch*:
@@ -64,6 +66,7 @@
 ;; Release history:
 ;;
 ;; 2001-10-31 Committed to Oort Gnus.
+;; 2002-07-27 Added DELETESCRIPT.  Suggested by Ned Ludd.
 
 ;;; Code:
 
@@ -339,7 +342,7 @@ Returns t if login was successful, nil otherwise."
   (let* ((done (sieve-manage-interactive-login
                buffer
                (lambda (user passwd)
-                 (sieve-manage-send "AUTHENTICATE \"CRAM-MD5\" \"\"")
+                 (sieve-manage-send "AUTHENTICATE \"CRAM-MD5\"")
                  (sieve-manage-send
                   (concat
                    "\""
@@ -501,6 +504,11 @@ password is remembered in the buffer."
                               sieve-manage-client-eol content))
     (sieve-manage-parse-okno)))
 
+(defun sieve-manage-deletescript (name &optional buffer)
+  (with-current-buffer (or buffer (current-buffer))
+    (sieve-manage-send (format "DELETESCRIPT \"%s\"" name))
+    (sieve-manage-parse-okno)))
+
 (defun sieve-manage-getscript (name output-buffer &optional buffer)
   (with-current-buffer (or buffer (current-buffer))
     (sieve-manage-send (format "GETSCRIPT \"%s\"" name))
index 8aa4d27..d86ea87 100644 (file)
@@ -47,8 +47,8 @@
 
 ;;; Code:
 
-(autoload 'sieve-manage "sieve-manage")
-(autoload 'sieve-upload "sieve-manage")
+(autoload 'sieve-manage "sieve")
+(autoload 'sieve-upload "sieve")
 (require 'easymenu)
 (eval-when-compile
   (require 'font-lock))
index 0b4aa35..f41fa7c 100644 (file)
 ;; Release history:
 ;;
 ;; 2001-10-31 Committed to Oort Gnus.
+;; 2002-07-27 Fix down-mouse-2 and down-mouse-3 in manage-mode.  Fix menubar
+;;            in manage-mode.  Change some messages.  Added sieve-deactivate*,
+;;            sieve-remove.  Fixed help text in manage-mode.  Suggested by
+;;            Ned Ludd.
 ;;
 ;; Todo:
 ;;
@@ -124,14 +128,15 @@ require \"fileinto\";
   (define-key sieve-manage-mode-map "f" 'sieve-edit-script)
   (define-key sieve-manage-mode-map "o" 'sieve-edit-script-other-window)
   (define-key sieve-manage-mode-map "r" 'sieve-remove)
-  (define-key sieve-manage-mode-map [mouse-2] 'sieve-edit-script)
-  (define-key sieve-manage-mode-map [(down-mouse-3)] 'sieve-menu))
+  (define-key sieve-manage-mode-map [(down-mouse-2)] 'sieve-edit-script)
+  (define-key sieve-manage-mode-map [(down-mouse-3)] 'sieve-manage-mode-menu))
 
 (define-derived-mode sieve-manage-mode fundamental-mode "SIEVE"
   "Mode used for sieve script management."
   (setq mode-name "SIEVE")
   (buffer-disable-undo (current-buffer))
-  (setq truncate-lines t))
+  (setq truncate-lines t)
+  (easy-menu-add-item nil nil sieve-manage-mode-menu))
 
 (put 'sieve-manage-mode 'mode-class 'special)
 
@@ -151,13 +156,38 @@ require \"fileinto\";
 (defun sieve-activate (&optional pos)
   (interactive "d")
   (let ((name (sieve-script-at-point)) err)
-    (unless name
+    (when (or (null name) (string-equal name sieve-new-script))
       (error "No sieve script at point"))
+    (message "Activating script %s..." name)
     (setq err (sieve-manage-setactive name sieve-manage-buffer))
+    (sieve-refresh-scriptlist)
     (if (sieve-manage-ok-p err)
-       (message "Script %s activated." name)
-      (message "Failed to activate script %s: %s" name (nth 2 err)))
-    (sieve-refresh-scriptlist)))
+       (message "Activating script %s...done" name)
+      (message "Activating script %s...failed: %s" name (nth 2 err)))))
+
+(defun sieve-deactivate-all (&optional pos)
+  (interactive "d")
+  (let ((name (sieve-script-at-point)) err)
+    (message "Deactivating scripts...")
+    (setq err (sieve-manage-setactive "" sieve-manage-buffer))
+    (sieve-refresh-scriptlist)
+    (if (sieve-manage-ok-p err)
+       (message "Deactivating scripts...done")
+      (message "Deactivating scripts...failed" (nth 2 err)))))
+
+(defalias 'sieve-deactivate 'sieve-deactivate-all)
+
+(defun sieve-remove (&optional pos)
+  (interactive "d")
+  (let ((name (sieve-script-at-point)) err)
+    (when (or (null name) (string-equal name sieve-new-script))
+      (error "No sieve script at point"))
+    (message "Removing sieve script %s..." name)
+    (setq err (sieve-manage-deletescript name sieve-manage-buffer))
+    (unless (sieve-manage-ok-p err)
+      (error "Removing sieve script %s...failed: " err))
+    (sieve-refresh-scriptlist)
+    (message "Removing sieve script %s...done" name)))
 
 (defun sieve-edit-script (&optional pos)
   (interactive "d")
@@ -176,6 +206,15 @@ require \"fileinto\";
     (sieve-mode)
     (message "Press C-c C-l to upload script to server.")))
 
+(defmacro sieve-change-region (&rest body)
+  "Turns off sieve-region before executing BODY, then re-enables it after.
+Used to bracket operations which move point in the sieve-buffer."
+  `(progn
+     (sieve-highlight nil)
+     ,@body
+     (sieve-highlight t)))
+(put 'sieve-change-region 'lisp-indent-function 0)
+
 (defun sieve-next-line (&optional arg)
   (interactive)
   (unless arg
@@ -205,7 +244,7 @@ require \"fileinto\";
       ;; would need minor-mode for log-edit-mode
       (describe-function 'sieve-mode)
     (message (substitute-command-keys
-             "`\\[sieve-help]':help `\\[cvs-mode-add]':add `\\[sieve-remove]':remove"))))
+             "`\\[sieve-edit-script]':edit `\\[sieve-activate]':activate `\\[sieve-deactivate]':deactivate `\\[sieve-remove]':remove"))))
 
 (defun sieve-bury-buffer (buf &optional mainbuf)
   "Hide the buffer BUF that was temporarily popped up.
@@ -248,15 +287,6 @@ Server  : " server ":" (or port "2000") "
   (interactive "d")
   (get-char-property (or pos (point)) 'script-name))
 
-(defmacro sieve-change-region (&rest body)
-  "Turns off sieve-region before executing BODY, then re-enables it after.
-Used to bracket operations which move point in the sieve-buffer."
-  `(progn
-     (sieve-highlight nil)
-     ,@body
-     (sieve-highlight t)))
-(put 'sieve-change-region 'lisp-indent-function 0)
-
 (eval-and-compile
   (defalias 'sieve-make-overlay (if (fboundp 'make-overlay)
                                    'make-overlay
index 98a4151..9d42176 100644 (file)
     "relays.visi.com" "rbl.maps.vix.com")
   "List of blackhole servers.")
 
+(defvar spam-split-group "spam" "Default group name for spam-split.")
+
 (defun spam-check-blackholes ()
-  "Check the Recevieved headers for blackholed relays."
+  "Check the Receieved headers for blackholed relays."
   (let ((headers (message-fetch-field "received"))
        ips matches)
-    (with-temp-buffer
-      (insert headers)
-      (goto-char (point-min))
-      (while (re-search-forward
-             "\\[\\([0-9]+.[0-9]+.[0-9]+.[0-9]+\\)\\]" nil t)
-       (push (mapconcat 'identity
-                        (nreverse (split-string (match-string 1) "\\."))
-                        ".")
-             ips)))
-    (dolist (server spam-blackhole-servers)
-      (dolist (ip ips)
-       (when (query-dns (concat ip "." server))
-         (push (list ip server (query-dns (concat ip "." server) 'TXT))
-               matches))))
-    matches))
+    (when headers
+      (with-temp-buffer
+       (insert headers)
+       (goto-char (point-min))
+       (while (re-search-forward
+               "\\[\\([0-9]+.[0-9]+.[0-9]+.[0-9]+\\)\\]" nil t)
+         (message "blackhole search found host IP %s" (match-string 1))
+         (push (mapconcat 'identity
+                          (nreverse (split-string (match-string 1) "\\."))
+                          ".")
+               ips)))
+      (dolist (server spam-blackhole-servers)
+       (dolist (ip ips)
+         (when (query-dns (concat ip "." server))
+           (push (list ip server (query-dns (concat ip "." server) 'TXT))
+                 matches))))
+      matches)))
 
 ;;; Black- and white-lists
 
@@ -64,7 +68,7 @@
   "The location of the whitelist.
 The file format is one regular expression per line.
 The regular expression is matched against the address.")
-                                        
+
 (defvar spam-blacklist (expand-file-name "blacklist" spam-directory)
   "The location of the blacklist.
 The file format is one regular expression per line.
@@ -87,13 +91,19 @@ Optional arg BLACKLIST, if non-nil, means to enter in the blacklist instead."
       (unless (bobp)
        (insert "\n"))
       (insert address "\n")
-      (save-buffer))))
+      (save-buffer)
+      (spam-refresh-list-cache))))
 
 (defun spam-enter-blacklist (address)
   "Enter ADDRESS into the blacklist."
   (interactive "sAddress: ")
   (spam-enter-whitelist address t))
 
+(eval-and-compile
+  (defalias 'spam-point-at-eol (if (fboundp 'point-at-eol)
+                                  'point-at-eol
+                                'line-end-position)))
+
 (defun spam-parse-whitelist (&optional blacklist)
   (let ((file (if blacklist spam-blacklist spam-whitelist))
        contents address)
@@ -101,7 +111,7 @@ Optional arg BLACKLIST, if non-nil, means to enter in the blacklist instead."
       (with-temp-buffer
        (insert-file-contents file)
        (while (not (eobp))
-         (setq address (buffer-substring (point) (point-at-eol)))
+         (setq address (buffer-substring (point) (spam-point-at-eol)))
          (forward-line 1)
          (unless (zerop (length address))
            (setq address (regexp-quote address))
@@ -123,6 +133,33 @@ Optional arg BLACKLIST, if non-nil, means to enter in the blacklist instead."
        (setq found t)))
     found))
 
+(defun spam-address-blacklisted-p (address &optional blacklist)
+  (if address
+      (spam-address-whitelisted-p address t)
+    nil))
+
+;; Function for nnmail-split-fancy: returns 'spam' if an article is deemed to be spam
+(defun spam-split ()
+  "Split this message into the `spam' group if it is spam.
+This function can be used as an entry in `nnmail-split-fancy', for
+example like this: (: spam-split)
+
+See the Info node `(gnus)Fancy Mail Splitting' for more details."
+  (interactive)
+
+  ;; refresh the cache if it's necessary
+  (unless spam-whitelist-cache (spam-refresh-list-cache))
+  (unless spam-blacklist-cache (spam-refresh-list-cache))
+
+  (let* ((from (message-fetch-field "from"))
+        (group nil))
+    (when (spam-check-blackholes)
+      (setq group spam-split-group))
+    (unless (spam-address-whitelisted-p from)  ; unless the address is whitelisted,
+      (when (spam-address-blacklisted-p from) ; check if it's blacklisted,
+       (setq group spam-split-group))  ; and if so, set the group to spam-split-group
+      group)))
+
 (provide 'spam)
 
 ;;; spam.el ends here
index 3c65e5d..85bb10d 100644 (file)
@@ -27,6 +27,8 @@
 
 ;; This module defines some utility functions for STARTTLS profiles.
 
+;; Get "starttls" from ftp://ftp.opaopa.org/pub/elisp/.
+
 ;; [RFC 2595] "Using TLS with IMAP, POP3 and ACAP"
 ;;     by Chris Newman <chris.newman@innosoft.com> (1999/06)
 
index b30398c..4b51606 100644 (file)
@@ -1,3 +1,129 @@
+2002-08-04  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus.texi (Summary Sorting): Document randomization.
+
+2002-07-28  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus.texi (Web Searches): Added gmane and removed old
+       non-functioning search engines.  From Niklas Morberg
+       <niklas.morberg@axis.com>.
+
+2002-05-14  Jesper Harder  <harder@ifa.au.dk>
+
+       * gnus.texi (Summary Buffer Lines): Fix typo.
+
+2002-07-27  Simon Josefsson  <jas@extundo.com>
+
+       * gnus.texi (Summary Mail Commands): Trivial fix from Reiner Steib
+       <4uce.02.r.steib@gmx.net>.
+
+2002-07-18  Karl Kleinpaste  <karl@charcoal.com>
+
+       * gnus.texi (To From Newsgroups): Additional text regarding how to
+       regenerate overviews via server buffer, and note to news admins
+       about overview.fmt.
+
+2002-07-14  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus.texi (Posting Styles): Fix example (it was using the To
+       header instead of the From header).  From Christopher Splinter
+       <cs@splinter.inka.de>.
+
+2002-07-07  Simon Josefsson  <jas@extundo.com>
+
+       * gnus.texi (Top): Move hashcash down into spam chapter.
+       (Top): New spam menu.
+       (Various): Remove hashcash.
+       (Thwarting Email Spam): Split into introduction and "Anti-Spam
+       Basics" node.
+       (SpamAssassin): Add.
+       (Hashcash): Add.
+
+2002-06-28  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * gnus.texi (NNTP): Doc fix.
+
+2002-07-02  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus.texi (Washing Mail): Document the shortcoming of
+       nnmail-remove-leading-whitespace.
+
+2002-06-30  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * message.texi (News Headers): Include example for removing an
+       entry from message-required-news-headers.
+
+2002-06-28  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * gnus.texi (NNTP): Add nntp-via-rlogin-command-switches.
+
+2002-06-27  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus.texi (Mail Back End Variables): Document
+       nnmail-cache-ignore-groups.  Xref Fancy Mail Splitting.
+       (Fancy Mail Splitting): Mention nnmail-cache-ignore-groups and
+       why it is useful.
+
+2002-06-25  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus.texi (Fancy Mail Splitting): Include all necessary
+       variables in the Lisp example.
+
+2002-06-22  Simon Josefsson  <jas@extundo.com>
+
+       * gnus.texi (Pay Hashcash): Add.
+
+2002-06-03  Simon Josefsson  <jas@extundo.com>
+
+       * gnus.texi (Splitting Mail): Add.
+
+2002-05-23  Simon Josefsson  <jas@extundo.com>
+
+       * gnus.texi (Web Searches): Fix.  Trivial change from Niklas
+       Morberg <niklas.morberg@axis.com>.
+
+2002-05-22  Simon Josefsson  <jas@extundo.com>
+
+       * gnus.texi (Mail): Add variable.
+
+2002-05-16  Simon Josefsson  <jas@extundo.com>
+
+       * gnus.texi (Loose Threads): Add gnus-simplify-all-whitespace.
+
+2002-05-08  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+       * gnus.texi (Mail-To-News Gateways): The default
+       nngateway-header-transformation function inserts a "To" header,
+       not a "From" header.  From Jesper Harder <harder@ifa.au.dk>.
+
+2002-05-08  Josh Huber  <huber@alum.wpi.edu>
+
+       * message.texi (Security): Added a note about the signencrypt
+       style, and how to change it using `mml-signencrypt-style.'
+
+2002-05-04  Simon Josefsson  <jas@extundo.com>
+
+       * emacs-mime.texi (Encoding Customization): Fix.
+
+2002-05-04  Simon Josefsson  <jas@extundo.com>
+
+       * emacs-mime.texi: Move two chapters "Interface Functions" and
+       "Basic Functions" after the Decoding and Encoding chapters.  (No
+       text modified.)
+
+2002-05-04  Simon Josefsson  <jas@extundo.com>
+
+       * emacs-mime.texi (Top): Change scope of manual to include users.
+       (Customization): Rename to Display Customization.
+       (MML Definition): Add cross references.
+       (Encoding Customization): New section.
+       (Charset Translation): More info and cross references.
+
+2002-05-01  Josh Huber  <huber@alum.wpi.edu>
+
+       * gnus.texi (Signing and encrypting): Fix doc.  Also, add a
+       paragraph about replysign/replyencrypt/replysignencryped use.
+
 2002-05-01  Lars Magne Ingebrigtsen  <larsi@quimbies.gnus.org>
 
        * message.texi (Message Headers): Remove colon from index
index 6d06e4e..06b8989 100644 (file)
@@ -121,7 +121,7 @@ clean:
        *.tmplatexi *.toc *.tp *.vr gnus.*.bak gnus.[cgk]ind gnus.idx   \
        gnus.ilg gnus.ind gnus.latexi*~* gnus.out gnus.tmplatexi1       \
        gnustmp.texi picons.tex smiley.tex texput.log thumb*.png        \
-       thumbdta.tex xface.tex
+       thumbdta.tex xface.tex *.tpt gnus-manual-*.pdf gnus-manual-*.ps.gz
 
 makeinfo:
        makeinfo -o gnus gnus.texi
@@ -204,12 +204,8 @@ psout: latexboth out
 latexboth: gnus-manual-a4.ps.gz gnus-manual-standard.ps.gz
 
 out:
-       cp gnus-manual-standard.ps.gz \
-       gnus-manual-a4.ps.gz \
-       /local/ftp/pub/emacs/gnus/manual
-       mv gnus-manual-standard.ps.gz \
-       gnus-manual-a4.ps.gz \
-       /hom/larsi/www_docs/www.gnus.org/documents
+       scp gnus-manual-*.ps.gz gnus-manual-*.pdf 
+       www@quimby:html/gnus/documents
 
 veryclean: clean
        rm -f gnus.dvi gnus.ps texi2latex.elc
index 1283422..0ddf342 100644 (file)
@@ -77,9 +77,10 @@ license to the document, as described in section 6 of the license.
 This manual documents the libraries used to compose and display
 @sc{mime} messages.
 
-This is not a manual meant for users; it's a manual directed at people
-who want to write functions and commands that manipulate @sc{mime}
-elements.
+This manual is directed at users who want to modify the behaviour of
+the MIME encoding/decoding process or want a more detailed picture of
+how the Emacs MIME library works, and people who want to write
+functions and commands that manipulate @sc{mime} elements.
 
 @sc{mime} is short for @dfn{Multipurpose Internet Mail Extensions}.
 This standard is documented in a number of RFCs; mainly RFC2045 (Format
@@ -90,1395 +91,1466 @@ recommended that anyone who intends writing @sc{mime}-compliant software
 read at least RFC2045 and RFC2047.
 
 @menu
-* Interface Functions::   An abstraction over the basic functions.
-* Basic Functions::       Utility and basic parsing functions.
 * Decoding and Viewing::  A framework for decoding and viewing.
 * Composing::             MML; a language for describing @sc{mime} parts.
+* Interface Functions::   An abstraction over the basic functions.
+* Basic Functions::       Utility and basic parsing functions.
 * Standards::             A summary of RFCs and working documents used.
 * Index::                 Function and variable index.
 @end menu
 
 
-@node Interface Functions
-@chapter Interface Functions
-@cindex interface functions
-@cindex mail-parse
+@node Decoding and Viewing
+@chapter Decoding and Viewing
 
-The @code{mail-parse} library is an abstraction over the actual
-low-level libraries that are described in the next chapter.
+This chapter deals with decoding and viewing @sc{mime} messages on a
+higher level.
 
-Standards change, and so programs have to change to fit in the new
-mold.  For instance, RFC2045 describes a syntax for the
-@code{Content-Type} header that only allows ASCII characters in the
-parameter list.  RFC2231 expands on RFC2045 syntax to provide a scheme
-for continuation headers and non-ASCII characters.
+The main idea is to first analyze a @sc{mime} article, and then allow
+other programs to do things based on the list of @dfn{handles} that are
+returned as a result of this analysis.
 
-The traditional way to deal with this is just to update the library
-functions to parse the new syntax.  However, this is sometimes the wrong
-thing to do.  In some instances it may be vital to be able to understand
-both the old syntax as well as the new syntax, and if there is only one
-library, one must choose between the old version of the library and the
-new version of the library.
+@menu
+* Dissection::             Analyzing a @sc{mime} message.
+* Non-MIME::               Analyzing a non-@sc{mime} message.
+* Handles::                Handle manipulations.
+* Display::                Displaying handles.
+* Display Customization::  Variables that affect display.
+* New Viewers::            How to write your own viewers.
+@end menu
 
-The Emacs @sc{mime} library takes a different tack.  It defines a
-series of low-level libraries (@file{rfc2047.el}, @file{rfc2231.el}
-and so on) that parses strictly according to the corresponding
-standard.  However, normal programs would not use the functions
-provided by these libraries directly, but instead use the functions
-provided by the @code{mail-parse} library.  The functions in this
-library are just aliases to the corresponding functions in the latest
-low-level libraries.  Using this scheme, programs get a consistent
-interface they can use, and library developers are free to create
-write code that handles new standards.
 
-The following functions are defined by this library:
+@node Dissection
+@section Dissection
 
-@table @code
-@item mail-header-parse-content-type
-@findex mail-header-parse-content-type
-Parse a @code{Content-Type} header and return a list on the following
-format:
+The @code{mm-dissect-buffer} is the function responsible for dissecting
+a @sc{mime} article.  If given a multipart message, it will recursively
+descend the message, following the structure, and return a tree of
+@sc{mime} handles that describes the structure of the message.
+
+@node Non-MIME
+@section Non-MIME
+
+Gnus also understands some non-@sc{mime} attachments, such as
+postscript, uuencode, binhex, shar, forward, gnatsweb, pgp.  Each of
+these features can be disabled by add an item into
+@code{mm-uu-configure-list}.  For example,
 
 @lisp
-("type/subtype"
- (attribute1 . value1)
- (attribute2 . value2)
- ...)
+(require 'mm-uu)
+(add-to-list 'mm-uu-configure-list '(pgp-signed . disabled))
 @end lisp
 
-Here's an example:
+@table @code
+@item postscript
+@findex postscript
+Postscript file.
 
-@example
-(mail-header-parse-content-type
- "image/gif; name=\"b980912.gif\"")
-@result{} ("image/gif" (name . "b980912.gif"))
-@end example
+@item uu
+@findex uu
+Uuencoded file.
 
-@item mail-header-parse-content-disposition
-@findex mail-header-parse-content-disposition
-Parse a @code{Content-Disposition} header and return a list on the same
-format as the function above.
+@item binhex
+@findex binhex
+Binhex encoded file.
 
-@item mail-content-type-get
-@findex mail-content-type-get
-Takes two parameters---a list on the format above, and an attribute.
-Returns the value of the attribute.
+@item shar
+@findex shar
+Shar archive file.
 
-@example
-(mail-content-type-get
- '("image/gif" (name . "b980912.gif")) 'name)
-@result{} "b980912.gif"
-@end example
+@item forward
+@findex forward
+Non-@sc{mime} forwarded message.
 
-@item mail-header-encode-parameter
-@findex mail-header-encode-parameter
-Takes a parameter string and returns an encoded version of the string.
-This is used for parameters in headers like @code{Content-Type} and
-@code{Content-Disposition}.
+@item gnatsweb
+@findex gnatsweb
+Gnatsweb attachment.
 
-@item mail-header-remove-comments
-@findex mail-header-remove-comments
-Return a comment-free version of a header.
+@item pgp-signed
+@findex pgp-signed
+PGP signed clear text.
 
-@example
-(mail-header-remove-comments
- "Gnus/5.070027 (Pterodactyl Gnus v0.27) (Finnish Landrace)")
-@result{} "Gnus/5.070027  "
-@end example
+@item pgp-encrypted
+@findex pgp-encrypted
+PGP encrypted clear text.
 
-@item mail-header-remove-whitespace
-@findex mail-header-remove-whitespace
-Remove linear white space from a header.  Space inside quoted strings
-and comments is preserved.
+@item pgp-key
+@findex pgp-key
+PGP public keys.
 
-@example
-(mail-header-remove-whitespace
- "image/gif; name=\"Name with spaces\"")
-@result{} "image/gif;name=\"Name with spaces\""
-@end example
+@item emacs-sources
+@findex emacs-sources
+Emacs source code.  This item works only in the groups matching
+@code{mm-uu-emacs-sources-regexp}.
 
-@item mail-header-get-comment
-@findex mail-header-get-comment
-Return the last comment in a header.
+@end table
 
-@example
-(mail-header-get-comment
- "Gnus/5.070027 (Pterodactyl Gnus v0.27) (Finnish Landrace)")
-@result{} "Finnish Landrace"
-@end example
+@node Handles
+@section Handles
 
-@item mail-header-parse-address
-@findex mail-header-parse-address
-Parse an address and return a list containing the mailbox and the
-plaintext name.
+A @sc{mime} handle is a list that fully describes a @sc{mime}
+component.
 
-@example
-(mail-header-parse-address
- "Hrvoje Niksic <hniksic@@srce.hr>")
-@result{} ("hniksic@@srce.hr" . "Hrvoje Niksic")
-@end example
+The following macros can be used to access elements in a handle:
 
-@item mail-header-parse-addresses
-@findex mail-header-parse-addresses
-Parse a string with list of addresses and return a list of elements like
-the one described above.
+@table @code
+@item mm-handle-buffer
+@findex mm-handle-buffer
+Return the buffer that holds the contents of the undecoded @sc{mime}
+part.
 
-@example
-(mail-header-parse-addresses
- "Hrvoje Niksic <hniksic@@srce.hr>, Steinar Bang <sb@@metis.no>")
-@result{} (("hniksic@@srce.hr" . "Hrvoje Niksic")
-     ("sb@@metis.no" . "Steinar Bang"))
-@end example
+@item mm-handle-type
+@findex mm-handle-type
+Return the parsed @code{Content-Type} of the part.
 
-@item mail-header-parse-date
-@findex mail-header-parse-date
-Parse a date string and return an Emacs time structure.
+@item mm-handle-encoding
+@findex mm-handle-encoding
+Return the @code{Content-Transfer-Encoding} of the part.
 
-@item mail-narrow-to-head
-@findex mail-narrow-to-head
-Narrow the buffer to the header section of the buffer.  Point is placed
-at the beginning of the narrowed buffer.
+@item mm-handle-undisplayer
+@findex mm-handle-undisplayer
+Return the object that can be used to remove the displayed part (if it
+has been displayed).
 
-@item mail-header-narrow-to-field
-@findex mail-header-narrow-to-field
-Narrow the buffer to the header under point.  Understands continuation
-headers.
+@item mm-handle-set-undisplayer
+@findex mm-handle-set-undisplayer
+Set the undisplayer object.
 
-@item mail-header-fold-field
-@findex mail-header-fold-field
-Fold the header under point.
+@item mm-handle-disposition
+@findex mm-handle-disposition
+Return the parsed @code{Content-Disposition} of the part.
 
-@item mail-header-unfold-field
-@findex mail-header-unfold-field
-Unfold the header under point.
+@item mm-handle-disposition
+@findex mm-handle-disposition
+Return the description of the part.
 
-@item mail-header-field-value
-@findex mail-header-field-value
-Return the value of the field under point.
+@item mm-get-content-id
+Returns the handle(s) referred to by @code{Content-ID}.
 
-@item mail-encode-encoded-word-region
-@findex mail-encode-encoded-word-region
-Encode the non-ASCII words in the region.  For instance,
-@samp{Naïve} is encoded as @samp{=?iso-8859-1?q?Na=EFve?=}.
+@end table
 
-@item mail-encode-encoded-word-buffer
-@findex mail-encode-encoded-word-buffer
-Encode the non-ASCII words in the current buffer.  This function is
-meant to be called narrowed to the headers of a message.
 
-@item mail-encode-encoded-word-string
-@findex mail-encode-encoded-word-string
-Encode the words that need encoding in a string, and return the result.
+@node Display
+@section Display
 
-@example
-(mail-encode-encoded-word-string
- "This is naïve, baby")
-@result{} "This is =?iso-8859-1?q?na=EFve,?= baby"
-@end example
+Functions for displaying, removing and saving.
 
-@item mail-decode-encoded-word-region
-@findex mail-decode-encoded-word-region
-Decode the encoded words in the region.
+@table @code
+@item mm-display-part
+@findex mm-display-part
+Display the part.
 
-@item mail-decode-encoded-word-string
-@findex mail-decode-encoded-word-string
-Decode the encoded words in the string and return the result.
+@item mm-remove-part
+@findex mm-remove-part
+Remove the part (if it has been displayed).
 
-@example
-(mail-decode-encoded-word-string
- "This is =?iso-8859-1?q?na=EFve,?= baby")
-@result{} "This is naïve, baby"
-@end example
+@item mm-inlinable-p
+@findex mm-inlinable-p
+Say whether a @sc{mime} type can be displayed inline.
 
-@end table
+@item mm-automatic-display-p
+@findex mm-automatic-display-p
+Say whether a @sc{mime} type should be displayed automatically.
 
-Currently, @code{mail-parse} is an abstraction over @code{ietf-drums},
-@code{rfc2047}, @code{rfc2045} and @code{rfc2231}.  These are documented
-in the subsequent sections.
+@item mm-destroy-part
+@findex mm-destroy-part
+Free all resources occupied by a part.
 
+@item mm-save-part
+@findex mm-save-part
+Offer to save the part in a file.
 
+@item mm-pipe-part
+@findex mm-pipe-part
+Offer to pipe the part to some process.
 
-@node Basic Functions
-@chapter Basic Functions
+@item mm-interactively-view-part
+@findex mm-interactively-view-part
+Prompt for a mailcap method to use to view the part.
 
-This chapter describes the basic, ground-level functions for parsing and
-handling.  Covered here is parsing @code{From} lines, removing comments
-from header lines, decoding encoded words, parsing date headers and so
-on.  High-level functionality is dealt with in the next chapter
-(@pxref{Decoding and Viewing}).
+@end table
 
-@menu
-* rfc2045::      Encoding @code{Content-Type} headers.
-* rfc2231::      Parsing @code{Content-Type} headers.
-* ietf-drums::   Handling mail headers defined by RFC822bis.
-* rfc2047::      En/decoding encoded words in headers.
-* time-date::    Functions for parsing dates and manipulating time.
-* qp::           Quoted-Printable en/decoding.
-* base64::       Base64 en/decoding.
-* binhex::       Binhex decoding.
-* uudecode::     Uuencode decoding.
-* rfc1843::      Decoding HZ-encoded text.
-* mailcap::      How parts are displayed is specified by the @file{.mailcap} file
-@end menu
 
+@node Display Customization
+@section Display Customization
 
-@node rfc2045
-@section rfc2045
+@table @code
 
-RFC2045 is the ``main'' @sc{mime} document, and as such, one would
-imagine that there would be a lot to implement.  But there isn't, since
-most of the implementation details are delegated to the subsequent
-RFCs.
+@item mm-inline-media-tests
+This is an alist where the key is a @sc{mime} type, the second element
+is a function to display the part @dfn{inline} (i.e., inside Emacs), and
+the third element is a form to be @code{eval}ed to say whether the part
+can be displayed inline.
 
-So @file{rfc2045.el} has only a single function:
+This variable specifies whether a part @emph{can} be displayed inline,
+and, if so, how to do it.  It does not say whether parts are
+@emph{actually} displayed inline.
 
-@table @code
-@item rfc2045-encode-string
-@findex rfc2045-encode-string
-Takes a parameter and a value and returns a @samp{PARAM=VALUE} string.
-@var{value} will be quoted if there are non-safe characters in it.
-@end table
+@item mm-inlined-types
+This, on the other hand, says what types are to be displayed inline, if
+they satisfy the conditions set by the variable above.  It's a list of
+@sc{mime} media types.
 
+@item mm-automatic-display
+This is a list of types that are to be displayed ``automatically'', but
+only if the above variable allows it.  That is, only inlinable parts can
+be displayed automatically.
 
-@node rfc2231
-@section rfc2231
+@item mm-attachment-override-types
+Some @sc{mime} agents create parts that have a content-disposition of
+@samp{attachment}.  This variable allows overriding that disposition and
+displaying the part inline.  (Note that the disposition is only
+overridden if we are able to, and want to, display the part inline.)
 
-RFC2231 defines a syntax for the @code{Content-Type} and
-@code{Content-Disposition} headers.  Its snappy name is @dfn{MIME
-Parameter Value and Encoded Word Extensions: Character Sets, Languages,
-and Continuations}.
+@item mm-discouraged-alternatives
+List of @sc{mime} types that are discouraged when viewing
+@samp{multipart/alternative}.  Viewing agents are supposed to view the
+last possible part of a message, as that is supposed to be the richest.
+However, users may prefer other types instead, and this list says what
+types are most unwanted.  If, for instance, @samp{text/html} parts are
+very unwanted, and @samp{text/richtech} parts are somewhat unwanted,
+you could say something like:
 
-In short, these headers look something like this:
+@lisp
+(setq mm-discouraged-alternatives
+      '("text/html" "text/richtext")
+      mm-automatic-display
+      (remove "text/html" mm-automatic-display))
+@end lisp
 
-@example
-Content-Type: application/x-stuff;
- title*0*=us-ascii'en'This%20is%20even%20more%20;
- title*1*=%2A%2A%2Afun%2A%2A%2A%20;
- title*2="isn't it!"
-@end example
+@item mm-inline-large-images-p
+When displaying inline images that are larger than the window, XEmacs
+does not enable scrolling, which means that you cannot see the whole
+image.  To prevent this, the library tries to determine the image size
+before displaying it inline, and if it doesn't fit the window, the
+library will display it externally (e.g. with @samp{ImageMagick} or
+@samp{xv}).  Setting this variable to @code{t} disables this check and
+makes the library display all inline images as inline, regardless of
+their size.
 
-They usually aren't this bad, though.
+@item mm-inline-override-type
+@code{mm-inlined-types} may include regular expressions, for example to
+specify that all @samp{text/.*} parts be displayed inline.  If a user
+prefers to have a type that matches such a regular expression be treated
+as an attachment, that can be accomplished by setting this variable to a
+list containing that type.  For example assuming @code{mm-inlined-types}
+includes @samp{text/.*}, then including @samp{text/html} in this
+variable will cause @samp{text/html} parts to be treated as attachments.
 
-The following functions are defined by this library:
+@item mm-inline-text-html-renderer
+This selects the function used to render @sc{html}.  The predefined
+renderers are selected by the symbols @code{w3},
+@code{w3m}@footnote{See @uref{http://emacs-w3m.namazu.org/} for more
+information about emacs-w3m}, @code{links}, @code{lynx} or
+@code{html2text}.  You can also specify a function, which will be
+called with a @sc{mime} handle as the argument.
 
-@table @code
-@item rfc2231-parse-string
-@findex rfc2231-parse-string
-Parse a @code{Content-Type} header and return a list describing its
-elements.
+@item mm-inline-text-html-with-images
+Some @sc{html} mails might have the trick of spammers using
+@samp{<img>} tags.  It is likely to be intended to verify whether you
+have read the mail.  You can prevent your personal informations from
+leaking by setting this option to @code{nil} (which is the default).
+It is currently ignored by Emacs/w3.  For emacs-w3m, you may use the
+command @kbd{t} on the image anchor to show an image even if it is
+@code{nil}.@footnote{The command @kbd{T} will load all images.  If you
+have set the option @code{w3m-key-binding} to @code{info}, use @kbd{i}
+or @kbd{I} instead.}
 
-@example
-(rfc2231-parse-string
- "application/x-stuff;
- title*0*=us-ascii'en'This%20is%20even%20more%20;
- title*1*=%2A%2A%2Afun%2A%2A%2A%20;
- title*2=\"isn't it!\"")
-@result{} ("application/x-stuff"
-    (title . "This is even more ***fun*** isn't it!"))
-@end example
+@item mm-inline-text-html-with-w3m-keymap
+You can use emacs-w3m command keys in the inlined text/html part by
+setting this option to non-@code{nil}.  The default value is @code{t}.
 
-@item rfc2231-get-value
-@findex rfc2231-get-value
-Takes one of the lists on the format above and returns
-the value of the specified attribute.
+@end table
 
-@item rfc2231-encode-string
-@findex rfc2231-encode-string
-Encode a parameter in headers likes @code{Content-Type} and
-@code{Content-Disposition}.
 
-@end table
+@node New Viewers
+@section New Viewers
 
+Here's an example viewer for displaying @code{text/enriched} inline:
 
-@node ietf-drums
-@section ietf-drums
+@lisp
+(defun mm-display-enriched-inline (handle)
+  (let (text)
+    (with-temp-buffer
+      (mm-insert-part handle)
+      (save-window-excursion
+        (enriched-decode (point-min) (point-max))
+        (setq text (buffer-string))))
+    (mm-insert-inline handle text)))
+@end lisp
 
-@dfn{drums} is an IETF working group that is working on the replacement
-for RFC822.
+We see that the function takes a @sc{mime} handle as its parameter.  It
+then goes to a temporary buffer, inserts the text of the part, does some
+work on the text, stores the result, goes back to the buffer it was
+called from and inserts the result.
 
-The functions provided by this library include:
+The two important helper functions here are @code{mm-insert-part} and
+@code{mm-insert-inline}.  The first function inserts the text of the
+handle in the current buffer.  It handles charset and/or content
+transfer decoding.  The second function just inserts whatever text you
+tell it to insert, but it also sets things up so that the text can be
+``undisplayed' in a convenient manner.
 
-@table @code
-@item ietf-drums-remove-comments
-@findex ietf-drums-remove-comments
-Remove the comments from the argument and return the results.
 
-@item ietf-drums-remove-whitespace
-@findex ietf-drums-remove-whitespace
-Remove linear white space from the string and return the results.
-Spaces inside quoted strings and comments are left untouched.
+@node Composing
+@chapter Composing
+@cindex Composing
+@cindex MIME Composing
+@cindex MML
+@cindex MIME Meta Language
 
-@item ietf-drums-get-comment
-@findex ietf-drums-get-comment
-Return the last most comment from the string.
+Creating a @sc{mime} message is boring and non-trivial.  Therefore, a
+library called @code{mml} has been defined that parses a language called
+MML (@sc{mime} Meta Language) and generates @sc{mime} messages.
 
-@item ietf-drums-parse-address
-@findex ietf-drums-parse-address
-Parse an address string and return a list that contains the mailbox and
-the plain text name.
+@findex mml-generate-mime
+The main interface function is @code{mml-generate-mime}.  It will
+examine the contents of the current (narrowed-to) buffer and return a
+string containing the @sc{mime} message.
 
-@item ietf-drums-parse-addresses
-@findex ietf-drums-parse-addresses
-Parse a string that contains any number of comma-separated addresses and
-return a list that contains mailbox/plain text pairs.
+@menu
+* Simple MML Example::             An example MML document.
+* MML Definition::                 All valid MML elements.
+* Advanced MML Example::           Another example MML document.
+* Encoding Customization::         Variables that affect encoding.
+* Charset Translation::            How charsets are mapped from @sc{mule} to @sc{mime}.
+* Conversion::                     Going from @sc{mime} to MML and vice versa.
+* Flowed text::                    Soft and hard newlines.
+@end menu
 
-@item ietf-drums-parse-date
-@findex ietf-drums-parse-date
-Parse a date string and return an Emacs time structure.
 
-@item ietf-drums-narrow-to-header
-@findex ietf-drums-narrow-to-header
-Narrow the buffer to the header section of the current buffer.
+@node Simple MML Example
+@section Simple MML Example
 
-@end table
+Here's a simple @samp{multipart/alternative}:
 
+@example
+<#multipart type=alternative>
+This is a plain text part.
+<#part type=text/enriched>
+<center>This is a centered enriched part</center>
+<#/multipart>
+@end example
 
-@node rfc2047
-@section rfc2047
+After running this through @code{mml-generate-mime}, we get this:
 
-RFC2047 (Message Header Extensions for Non-ASCII Text) specifies how
-non-ASCII text in headers are to be encoded.  This is actually rather
-complicated, so a number of variables are necessary to tweak what this
-library does.
+@example
+Content-Type: multipart/alternative; boundary="=-=-="
 
-The following variables are tweakable:
 
-@table @code
-@item rfc2047-default-charset
-@vindex rfc2047-default-charset
-Characters in this charset should not be decoded by this library.
-This defaults to @code{iso-8859-1}.
+--=-=-=
 
-@item rfc2047-header-encoding-list
-@vindex rfc2047-header-encoding-list
-This is an alist of header / encoding-type pairs.  Its main purpose is
-to prevent encoding of certain headers.
 
-The keys can either be header regexps, or @code{t}.
+This is a plain text part.
 
-The values can be either @code{nil}, in which case the header(s) in
-question won't be encoded, or @code{mime}, which means that they will be
-encoded.
+--=-=-=
+Content-Type: text/enriched
 
-@item rfc2047-charset-encoding-alist
-@vindex rfc2047-charset-encoding-alist
-RFC2047 specifies two forms of encoding---@code{Q} (a
-Quoted-Printable-like encoding) and @code{B} (base64).  This alist
-specifies which charset should use which encoding.
 
-@item rfc2047-encoding-function-alist
-@vindex rfc2047-encoding-function-alist
-This is an alist of encoding / function pairs.  The encodings are
-@code{Q}, @code{B} and @code{nil}.
+<center>This is a centered enriched part</center>
 
-@item rfc2047-q-encoding-alist
-@vindex rfc2047-q-encoding-alist
-The @code{Q} encoding isn't quite the same for all headers.  Some
-headers allow a narrower range of characters, and that is what this
-variable is for.  It's an alist of header regexps / allowable character
-ranges.
+--=-=-=--
+@end example
 
-@item rfc2047-encoded-word-regexp
-@vindex rfc2047-encoded-word-regexp
-When decoding words, this library looks for matches to this regexp.
 
-@end table
+@node MML Definition
+@section MML Definition
 
-Those were the variables, and these are this functions:
+The MML language is very simple.  It looks a bit like an SGML
+application, but it's not.
 
-@table @code
-@item rfc2047-narrow-to-field
-@findex rfc2047-narrow-to-field
-Narrow the buffer to the header on the current line.
+The main concept of MML is the @dfn{part}.  Each part can be of a
+different type or use a different charset.  The way to delineate a part
+is with a @samp{<#part ...>} tag.  Multipart parts can be introduced
+with the @samp{<#multipart ...>} tag.  Parts are ended by the
+@samp{<#/part>} or @samp{<#/multipart>} tags.  Parts started with the
+@samp{<#part ...>} tags are also closed by the next open tag.
 
-@item rfc2047-encode-message-header
-@findex rfc2047-encode-message-header
-Should be called narrowed to the header of a message.  Encodes according
-to @code{rfc2047-header-encoding-alist}.
+There's also the @samp{<#external ...>} tag.  These introduce
+@samp{external/message-body} parts.
 
-@item rfc2047-encode-region
-@findex rfc2047-encode-region
-Encodes all encodable words in the region specified.
+Each tag can contain zero or more parameters on the form
+@samp{parameter=value}.  The values may be enclosed in quotation marks,
+but that's not necessary unless the value contains white space.  So
+@samp{filename=/home/user/#hello$^yes} is perfectly valid.
 
-@item rfc2047-encode-string
-@findex rfc2047-encode-string
-Encode a string and return the results.
+The following parameters have meaning in MML; parameters that have no
+meaning are ignored.  The MML parameter names are the same as the
+@sc{mime} parameter names; the things in the parentheses say which
+header it will be used in.
 
-@item rfc2047-decode-region
-@findex rfc2047-decode-region
-Decode the encoded words in the region.
+@table @samp
+@item type
+The @sc{mime} type of the part (@code{Content-Type}).
 
-@item rfc2047-decode-string
-@findex rfc2047-decode-string
-Decode a string and return the results.
+@item filename
+Use the contents of the file in the body of the part
+(@code{Content-Disposition}).
 
-@end table
+@item charset
+The contents of the body of the part are to be encoded in the character
+set speficied (@code{Content-Type}). @xref{Charset Translation}.
 
+@item name
+Might be used to suggest a file name if the part is to be saved
+to a file (@code{Content-Type}).
 
-@node time-date
-@section time-date
+@item disposition
+Valid values are @samp{inline} and @samp{attachment}
+(@code{Content-Disposition}).
 
-While not really a part of the @sc{mime} library, it is convenient to
-document this library here.  It deals with parsing @code{Date} headers
-and manipulating time.  (Not by using tesseracts, though, I'm sorry to
-say.)
+@item encoding
+Valid values are @samp{7bit}, @samp{8bit}, @samp{quoted-printable} and
+@samp{base64} (@code{Content-Transfer-Encoding}). @xref{Charset
+Translation}.
 
-These functions convert between five formats: A date string, an Emacs
-time structure, a decoded time list, a second number, and a day number.
+@item description
+A description of the part (@code{Content-Description}).
 
-Here's a bunch of time/date/second/day examples:
+@item creation-date
+RFC822 date when the part was created (@code{Content-Disposition}).
 
-@example
-(parse-time-string "Sat Sep 12 12:21:54 1998 +0200")
-@result{} (54 21 12 12 9 1998 6 nil 7200)
+@item modification-date
+RFC822 date when the part was modified (@code{Content-Disposition}).
 
-(date-to-time "Sat Sep 12 12:21:54 1998 +0200")
-@result{} (13818 19266)
+@item read-date
+RFC822 date when the part was read (@code{Content-Disposition}).
 
-(time-to-seconds '(13818 19266))
-@result{} 905595714.0
+@item recipients
+Who to encrypt/sign the part to.  This field is used to override any
+auto-detection based on the To/CC headers.
 
-(seconds-to-time 905595714.0)
-@result{} (13818 19266 0)
+@item size
+The size (in octets) of the part (@code{Content-Disposition}).
 
-(time-to-days '(13818 19266))
-@result{} 729644
+@item sign
+What technology to sign this MML part with (@code{smime}, @code{pgp}
+or @code{pgpmime})
 
-(days-to-time 729644)
-@result{} (961933 65536)
+@item encrypt
+What technology to encrypt this MML part with (@code{smime},
+@code{pgp} or @code{pgpmime})
 
-(time-since '(13818 19266))
-@result{} (0 430)
+@end table
 
-(time-less-p '(13818 19266) '(13818 19145))
-@result{} nil
+Parameters for @samp{application/octet-stream}:
 
-(subtract-time '(13818 19266) '(13818 19145))
-@result{} (0 121)
+@table @samp
+@item type
+Type of the part; informal---meant for human readers
+(@code{Content-Type}).
+@end table
 
-(days-between "Sat Sep 12 12:21:54 1998 +0200"
-              "Sat Sep 07 12:21:54 1998 +0200")
-@result{} 5
+Parameters for @samp{message/external-body}:
 
-(date-leap-year-p 2000)
-@result{} t
+@table @samp
+@item access-type
+A word indicating the supported access mechanism by which the file may
+be obtained.  Values include @samp{ftp}, @samp{anon-ftp}, @samp{tftp},
+@samp{localfile}, and @samp{mailserver}.  (@code{Content-Type}.)
 
-(time-to-day-in-year '(13818 19266))
-@result{} 255
+@item expiration
+The RFC822 date after which the file may no longer be fetched.
+(@code{Content-Type}.)
 
-(time-to-number-of-days
- (time-since
-  (date-to-time "Mon, 01 Jan 2001 02:22:26 GMT")))
-@result{} 4.146122685185185
-@end example
+@item size
+The size (in octets) of the file.  (@code{Content-Type}.)
 
-And finally, we have @code{safe-date-to-time}, which does the same as
-@code{date-to-time}, but returns a zero time if the date is
-syntactically malformed.
+@item permission
+Valid values are @samp{read} and @samp{read-write}
+(@code{Content-Type}).
 
-The five data representations used are the following:
+@end table
 
-@table @var
-@item date
-An RFC822 (or similar) date string.  For instance: @code{"Sat Sep 12
-12:21:54 1998 +0200"}.
+Parameters for @samp{sign=smime}:
 
-@item time
-An internal Emacs time.  For instance: @code{(13818 26466)}.
+@table @samp
 
-@item seconds
-A floating point representation of the internal Emacs time.  For
-instance: @code{905595714.0}.
+@item keyfile
+File containing key and certificate for signer.
 
-@item days
-An integer number representing the number of days since 00000101.  For
-instance: @code{729644}.
+@end table
+
+Parameters for @samp{encrypt=smime}:
+
+@table @samp
+
+@item certfile
+File containing certificate for recipient.
 
-@item decoded time
-A list of decoded time.  For instance: @code{(54 21 12 12 9 1998 6 t
-7200)}.
 @end table
 
-All the examples above represent the same moment.
 
-These are the functions available:
+@node Advanced MML Example
+@section Advanced MML Example
+
+Here's a complex multipart message.  It's a @samp{multipart/mixed} that
+contains many parts, one of which is a @samp{multipart/alternative}.
+
+@example
+<#multipart type=mixed>
+<#part type=image/jpeg filename=~/rms.jpg disposition=inline>
+<#multipart type=alternative>
+This is a plain text part.
+<#part type=text/enriched name=enriched.txt>
+<center>This is a centered enriched part</center>
+<#/multipart>
+This is a new plain text part.
+<#part disposition=attachment>
+This plain text part is an attachment.
+<#/multipart>
+@end example
+
+And this is the resulting @sc{mime} message:
+
+@example
+Content-Type: multipart/mixed; boundary="=-=-="
+
+
+--=-=-=
 
-@table @code
-@item date-to-time
-Take a date and return a time.
 
-@item time-to-seconds
-Take a time and return seconds.
 
-@item seconds-to-time
-Take seconds and return a time.
+--=-=-=
+Content-Type: image/jpeg;
+ filename="~/rms.jpg"
+Content-Disposition: inline;
+ filename="~/rms.jpg"
+Content-Transfer-Encoding: base64
 
-@item time-to-days
-Take a time and return days.
+/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRof
+Hh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAAwADABAREA/8QAHwAA
+AQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQR
+BRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RF
+RkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ip
+qrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEB
+AAA/AO/rifFHjldNuGsrDa0qcSSHkA+gHrXKw+LtWLrMb+RgTyhbr+HSug07xNqV9fQtZrNI
+AyiaE/NuBPOOOP0rvRNE880KOC8TbXXGCv1FPqjrF4LDR7u5L7SkTFT/ALWOP1xXgTuXfc7E
+sx6nua6rwp4IvvEM8chCxWxOdzn7wz6V9AaB4S07w9p5itow0rDLSY5Pt9K43xO66P4xs71m
+2QXiGCbA4yOVJ9+1aYORkdK434lyNH4ahCnG66VT9Nj15JFbPdX0MS43M4VQf5/yr2vSpLnw
+5ZW8dlCZ8KFXjOPX0/mK6rSPEGt3Angu44fNEReHYNvIH3TzXDeKNO8RX+kSX2ouZkicTIOc
+L+g7E810ulFjpVtv3bwgB3HJyK5L4quY/C9sVxk3ij/xx6850u7t1mtp/wDlpEw3An3Jr3Dw
+34gsbWza4nBlhC5LDsaW6+IFgupQyCF3iHH7gA7c9R9ay7zx6t7aX9jHC4smhfBkGCvHGfrm
+tLQ7hbnRrV1GPkAP1x1/Hr+Ncr8Vzjwrbf8AX6v/AKA9eQRyYlQk8Yx9K6XTNbkgia2ciSIn
+7p5Ga9Atte0LTLKO6it4i7dVRFJDcZ4PvXN+JvEMF9bILVGXJLSZ4zkjivRPDaeX4b08HOTC
+pOffmua+KkbS+GLVUGT9tT/0B68eeIpIFYjB70+OOVXyoOM9+M1eaWeCLzHPyHGO/NVWvJJm
+jQ8KGH1NfQWhXSXmh2c8eArRLwO3HSv/2Q==
 
-@item days-to-time
-Take days and return a time.
+--=-=-=
+Content-Type: multipart/alternative; boundary="==-=-="
 
-@item date-to-day
-Take a date and return days.
 
-@item time-to-number-of-days
-Take a time and return the number of days that represents.
+--==-=-=
 
-@item safe-date-to-time
-Take a date and return a time.  If the date is not syntactically valid,
-return a "zero" date.
 
-@item time-less-p
-Take two times and say whether the first time is less (i. e., earlier)
-than the second time.
+This is a plain text part.
 
-@item time-since
-Take a time and return a time saying how long it was since that time.
+--==-=-=
+Content-Type: text/enriched;
+ name="enriched.txt"
 
-@item subtract-time
-Take two times and subtract the second from the first.  I. e., return
-the time between the two times.
 
-@item days-between
-Take two days and return the number of days between those two days.
+<center>This is a centered enriched part</center>
 
-@item date-leap-year-p
-Take a year number and say whether it's a leap year.
+--==-=-=--
 
-@item time-to-day-in-year
-Take a time and return the day number within the year that the time is
-in.
+--=-=-=
 
-@end table
+This is a new plain text part.
 
+--=-=-=
+Content-Disposition: attachment
 
-@node qp
-@section qp
 
-This library deals with decoding and encoding Quoted-Printable text.
+This plain text part is an attachment.
 
-Very briefly explained, qp encoding means translating all 8-bit
-characters (and lots of control characters) into things that look like
-@samp{=EF}; that is, an equal sign followed by the byte encoded as a hex
-string.
+--=-=-=--
+@end example
 
-The following functions are defined by the library:
+@node Encoding Customization
+@section Encoding Customization
 
 @table @code
-@item quoted-printable-decode-region
-@findex quoted-printable-decode-region
-QP-decode all the encoded text in the specified region.
 
-@item quoted-printable-decode-string
-@findex quoted-printable-decode-string
-Decode the QP-encoded text in a string and return the results.
+@item mm-body-charset-encoding-alist
+@vindex mm-body-charset-encoding-alist
+Mapping from MIME charset to encoding to use.  This variable is
+usually used except, e.g., when other requirements force a specific
+encoding (digitally signed messages require 7bit encodings).  The
+default is @code{((iso-2022-jp . 7bit) (iso-2022-jp-2 . 7bit))}.  As
+an example, if you do not want to have ISO-8859-1 characters
+quoted-printable encoded, you may add @code{(iso-8859-1 . 8bit)} to
+this variable.  You can override this setting on a per-message basis
+by using the @code{encoding} MML tag (@pxref{MML Definition}).
+
+@item mm-coding-system-priorities
+@vindex mm-coding-system-priorities
+Prioritize coding systems to use for outgoing messages.  The default
+is nil, which means to use the defaults in Emacs.  It is a list of
+coding system symbols (aliases of coding systems does not work, use
+@kbd{M-x describe-coding-system} to make sure you are not specifying
+an alias in this variable).  For example, if you have configured Emacs
+to use prefer UTF-8, but wish that outgoing messages should be sent in
+ISO-8859-1 if possible, you can set this variable to
+@code{(iso-latin-1)}. You can override this setting on a per-message
+basis by using the @code{charset} MML tag (@pxref{MML Definition}).
+
+@item mm-content-transfer-encoding-defaults
+@vindex mm-content-transfer-encoding-defaults
+Mapping from MIME types to encoding to use.  This variable is usually
+used except, e.g., when other requirements force a safer encoding
+(digitally signed messages require 7bit encoding). Besides the normal
+MIME encodings, @code{qp-or-base64} may be used to indicate that for
+each case the most efficient of quoted-printable and base64 should be
+used.  You can override this setting on a per-message basis by using
+the @code{encoding} MML tag (@pxref{MML Definition}).
+
+@item mm-use-ultra-safe-encoding
+@vindex mm-use-ultra-safe-encoding
+When this is non-nil, it means that textual parts are encoded as
+quoted-printable if they contain lines longer than 76 characters or
+starting with "From " in the body.  Non-7bit encodings (8bit, binary)
+are generally disallowed.  This reduce the probability that a non-8bit
+clean MTA or MDA changes the message.  This should never be set
+directly, but bound by other functions when necessary (e.g., when
+encoding messages that are to be digitally signed).
 
-@item quoted-printable-encode-region
-@findex quoted-printable-encode-region
-QP-encode all the encodable characters in the specified region.  The third
-optional parameter @var{fold} specifies whether to fold long lines.
-(Long here means 72.)
+@end table
 
-@item quoted-printable-encode-string
-@findex quoted-printable-encode-string
-QP-encode all the encodable characters in a string and return the
-results.
+@node Charset Translation
+@section Charset Translation
+@cindex charsets
 
-@end table
+During translation from MML to @sc{mime}, for each @sc{mime} part which
+has been composed inside Emacs, an appropriate charset has to be chosen.
 
+@vindex mail-parse-charset
+If you are running a non-@sc{mule} Emacs, this process is simple: If the
+part contains any non-ASCII (8-bit) characters, the @sc{mime} charset
+given by @code{mail-parse-charset} (a symbol) is used.  (Never set this
+variable directly, though.  If you want to change the default charset,
+please consult the documentation of the package which you use to process
+@sc{mime} messages.
+@xref{Various Message Variables, , Various Message Variables, message,
+      Message Manual}, for example.)
+If there are only ASCII characters, the @sc{mime} charset US-ASCII is
+used, of course.
 
-@node base64
-@section base64
-@cindex base64
+@cindex MULE
+@cindex UTF-8
+@cindex Unicode
+@vindex mm-mime-mule-charset-alist
+Things are slightly more complicated when running Emacs with @sc{mule}
+support.  In this case, a list of the @sc{mule} charsets used in the
+part is obtained, and the @sc{mule} charsets are translated to @sc{mime}
+charsets by consulting the variable @code{mm-mime-mule-charset-alist}.
+If this results in a single @sc{mime} charset, this is used to encode
+the part.  But if the resulting list of @sc{mime} charsets contains more
+than one element, two things can happen: If it is possible to encode the
+part via UTF-8, this charset is used.  (For this, Emacs must support
+the @code{utf-8} coding system, and the part must consist entirely of
+characters which have Unicode counterparts.)  If UTF-8 is not available
+for some reason, the part is split into several ones, so that each one
+can be encoded with a single @sc{mime} charset.  The part can only be
+split at line boundaries, though---if more than one @sc{mime} charset is
+required to encode a single line, it is not possible to encode the part.
 
-Base64 is an encoding that encodes three bytes into four characters,
-thereby increasing the size by about 33%.  The alphabet used for
-encoding is very resistant to mangling during transit.
+When running Emacs with @sc{mule} support, the preferences for which
+coding system to use is inherited from Emacs itself.  This means that
+if Emacs is set up to prefer UTF-8, it will be used when encoding
+messages.  You can modify this by altering the
+@code{mm-coding-system-priorities} variable though (@pxref{Encoding
+Customization}).
 
-The following functions are defined by this library:
+The charset to be used can be overriden by setting the @code{charset}
+MML tag (@pxref{MML Definition}) when composing the message.
 
-@table @code
-@item base64-encode-region
-@findex base64-encode-region
-base64 encode the selected region.  Return the length of the encoded
-text.  Optional third argument @var{no-line-break} means do not break
-long lines into shorter lines.
+The encoding of characters (quoted-printable, 8bit etc) is orthogonal
+to the discussion here, and is controlled by the variables
+@code{mm-body-charset-encoding-alist} and
+@code{mm-content-transfer-encoding-defaults} (@pxref{Encoding
+Customization}).
 
-@item base64-encode-string
-@findex base64-encode-string
-base64 encode a string and return the result.
+@node Conversion
+@section Conversion
 
-@item base64-decode-region
-@findex base64-decode-region
-base64 decode the selected region.  Return the length of the decoded
-text.  If the region can't be decoded, return @code{nil} and don't
-modify the buffer.
+@findex mime-to-mml
+A (multipart) @sc{mime} message can be converted to MML with the
+@code{mime-to-mml} function.  It works on the message in the current
+buffer, and substitutes MML markup for @sc{mime} boundaries.
+Non-textual parts do not have their contents in the buffer, but instead
+have the contents in separate buffers that are referred to from the MML
+tags.
 
-@item base64-decode-string
-@findex base64-decode-string
-base64 decode a string and return the result.  If the string can't be
-decoded, @code{nil} is returned.
+@findex mml-to-mime
+An MML message can be converted back to @sc{mime} by the
+@code{mml-to-mime} function.
 
-@end table
+These functions are in certain senses ``lossy''---you will not get back
+an identical message if you run @sc{mime-to-mml} and then
+@sc{mml-to-mime}.  Not only will trivial things like the order of the
+headers differ, but the contents of the headers may also be different.
+For instance, the original message may use base64 encoding on text,
+while @sc{mml-to-mime} may decide to use quoted-printable encoding, and
+so on.
 
+In essence, however, these two functions should be the inverse of each
+other.  The resulting contents of the message should remain equivalent,
+if not identical.
 
-@node binhex
-@section binhex
-@cindex binhex
-@cindex Apple
-@cindex Macintosh
 
-@code{binhex} is an encoding that originated in Macintosh environments.
-The following function is supplied to deal with these:
+@node Flowed text
+@section Flowed text
+@cindex format=flowed
 
-@table @code
-@item binhex-decode-region
-@findex binhex-decode-region
-Decode the encoded text in the region.  If given a third parameter, only
-decode the @code{binhex} header and return the filename.
+The Emacs @sc{mime} library will respect the @code{use-hard-newlines}
+variable (@pxref{Hard and Soft Newlines, ,Hard and Soft Newlines,
+emacs, Emacs Manual}) when encoding a message, and the
+``format=flowed'' Content-Type parameter when decoding a message.
 
-@end table
+On encoding text, lines terminated by soft newline characters are
+filled together and wrapped after the column decided by
+@code{fill-flowed-encode-column}.  This variable controls how the text
+will look in a client that does not support flowed text, the default
+is to wrap after 66 characters.  If hard newline characters are not
+present in the buffer, no flow encoding occurs.
 
+On decoding flowed text, lines with soft newline characters are filled
+together and wrapped after the column decided by
+@code{fill-flowed-display-column}.  The default is to wrap after
+@code{fill-column}.
 
-@node uudecode
-@section uudecode
-@cindex uuencode
-@cindex uudecode
 
-@code{uuencode} is probably still the most popular encoding of binaries
-used on Usenet, although @code{base64} rules the mail world.
 
-The following function is supplied by this package:
 
-@table @code
-@item uudecode-decode-region
-@findex uudecode-decode-region
-Decode the text in the region.
-@end table
+@node Interface Functions
+@chapter Interface Functions
+@cindex interface functions
+@cindex mail-parse
+
+The @code{mail-parse} library is an abstraction over the actual
+low-level libraries that are described in the next chapter.
+
+Standards change, and so programs have to change to fit in the new
+mold.  For instance, RFC2045 describes a syntax for the
+@code{Content-Type} header that only allows ASCII characters in the
+parameter list.  RFC2231 expands on RFC2045 syntax to provide a scheme
+for continuation headers and non-ASCII characters.
+
+The traditional way to deal with this is just to update the library
+functions to parse the new syntax.  However, this is sometimes the wrong
+thing to do.  In some instances it may be vital to be able to understand
+both the old syntax as well as the new syntax, and if there is only one
+library, one must choose between the old version of the library and the
+new version of the library.
+
+The Emacs @sc{mime} library takes a different tack.  It defines a
+series of low-level libraries (@file{rfc2047.el}, @file{rfc2231.el}
+and so on) that parses strictly according to the corresponding
+standard.  However, normal programs would not use the functions
+provided by these libraries directly, but instead use the functions
+provided by the @code{mail-parse} library.  The functions in this
+library are just aliases to the corresponding functions in the latest
+low-level libraries.  Using this scheme, programs get a consistent
+interface they can use, and library developers are free to create
+write code that handles new standards.
 
+The following functions are defined by this library:
 
-@node rfc1843
-@section rfc1843
-@cindex rfc1843
-@cindex HZ
-@cindex Chinese
+@table @code
+@item mail-header-parse-content-type
+@findex mail-header-parse-content-type
+Parse a @code{Content-Type} header and return a list on the following
+format:
 
-RFC1843 deals with mixing Chinese and ASCII characters in messages.  In
-essence, RFC1843 switches between ASCII and Chinese by doing this:
+@lisp
+("type/subtype"
+ (attribute1 . value1)
+ (attribute2 . value2)
+ ...)
+@end lisp
+
+Here's an example:
 
 @example
-This sentence is in ASCII.
-The next sentence is in GB.~@{<:Ky2;S@{#,NpJ)l6HK!#~@}Bye.
+(mail-header-parse-content-type
+ "image/gif; name=\"b980912.gif\"")
+@result{} ("image/gif" (name . "b980912.gif"))
 @end example
 
-Simple enough, and widely used in China.
-
-The following functions are available to handle this encoding:
+@item mail-header-parse-content-disposition
+@findex mail-header-parse-content-disposition
+Parse a @code{Content-Disposition} header and return a list on the same
+format as the function above.
 
-@table @code
-@item rfc1843-decode-region
-Decode HZ-encoded text in the region.
+@item mail-content-type-get
+@findex mail-content-type-get
+Takes two parameters---a list on the format above, and an attribute.
+Returns the value of the attribute.
 
-@item rfc1843-decode-string
-Decode a HZ-encoded string and return the result.
+@example
+(mail-content-type-get
+ '("image/gif" (name . "b980912.gif")) 'name)
+@result{} "b980912.gif"
+@end example
 
-@end table
+@item mail-header-encode-parameter
+@findex mail-header-encode-parameter
+Takes a parameter string and returns an encoded version of the string.
+This is used for parameters in headers like @code{Content-Type} and
+@code{Content-Disposition}.
 
+@item mail-header-remove-comments
+@findex mail-header-remove-comments
+Return a comment-free version of a header.
 
-@node mailcap
-@section mailcap
+@example
+(mail-header-remove-comments
+ "Gnus/5.070027 (Pterodactyl Gnus v0.27) (Finnish Landrace)")
+@result{} "Gnus/5.070027  "
+@end example
 
-The @file{~/.mailcap} file is parsed by most @sc{mime}-aware message
-handlers and describes how elements are supposed to be displayed.
-Here's an example file:
+@item mail-header-remove-whitespace
+@findex mail-header-remove-whitespace
+Remove linear white space from a header.  Space inside quoted strings
+and comments is preserved.
 
 @example
-image/*; gimp -8 %s
-audio/wav; wavplayer %s
-application/msword; catdoc %s ; copiousoutput ; nametemplate=%s.doc
+(mail-header-remove-whitespace
+ "image/gif; name=\"Name with spaces\"")
+@result{} "image/gif;name=\"Name with spaces\""
 @end example
 
-This says that all image files should be displayed with @code{gimp},
-that WAVE audio files should be played by @code{wavplayer}, and that
-MS-WORD files should be inlined by @code{catdoc}.
-
-The @code{mailcap} library parses this file, and provides functions for
-matching types.
+@item mail-header-get-comment
+@findex mail-header-get-comment
+Return the last comment in a header.
 
-@table @code
-@item mailcap-mime-data
-@vindex mailcap-mime-data
-This variable is an alist of alists containing backup viewing rules.
+@example
+(mail-header-get-comment
+ "Gnus/5.070027 (Pterodactyl Gnus v0.27) (Finnish Landrace)")
+@result{} "Finnish Landrace"
+@end example
 
-@end table
+@item mail-header-parse-address
+@findex mail-header-parse-address
+Parse an address and return a list containing the mailbox and the
+plaintext name.
 
-Interface functions:
+@example
+(mail-header-parse-address
+ "Hrvoje Niksic <hniksic@@srce.hr>")
+@result{} ("hniksic@@srce.hr" . "Hrvoje Niksic")
+@end example
 
-@table @code
-@item mailcap-parse-mailcaps
-@findex mailcap-parse-mailcaps
-Parse the @code{~/.mailcap} file.
+@item mail-header-parse-addresses
+@findex mail-header-parse-addresses
+Parse a string with list of addresses and return a list of elements like
+the one described above.
 
-@item mailcap-mime-info
-Takes a @sc{mime} type as its argument and returns the matching viewer.
+@example
+(mail-header-parse-addresses
+ "Hrvoje Niksic <hniksic@@srce.hr>, Steinar Bang <sb@@metis.no>")
+@result{} (("hniksic@@srce.hr" . "Hrvoje Niksic")
+     ("sb@@metis.no" . "Steinar Bang"))
+@end example
 
-@end table
+@item mail-header-parse-date
+@findex mail-header-parse-date
+Parse a date string and return an Emacs time structure.
 
+@item mail-narrow-to-head
+@findex mail-narrow-to-head
+Narrow the buffer to the header section of the buffer.  Point is placed
+at the beginning of the narrowed buffer.
 
+@item mail-header-narrow-to-field
+@findex mail-header-narrow-to-field
+Narrow the buffer to the header under point.  Understands continuation
+headers.
 
+@item mail-header-fold-field
+@findex mail-header-fold-field
+Fold the header under point.
 
-@node Decoding and Viewing
-@chapter Decoding and Viewing
+@item mail-header-unfold-field
+@findex mail-header-unfold-field
+Unfold the header under point.
 
-This chapter deals with decoding and viewing @sc{mime} messages on a
-higher level.
+@item mail-header-field-value
+@findex mail-header-field-value
+Return the value of the field under point.
 
-The main idea is to first analyze a @sc{mime} article, and then allow
-other programs to do things based on the list of @dfn{handles} that are
-returned as a result of this analysis.
+@item mail-encode-encoded-word-region
+@findex mail-encode-encoded-word-region
+Encode the non-ASCII words in the region.  For instance,
+@samp{Naïve} is encoded as @samp{=?iso-8859-1?q?Na=EFve?=}.
 
-@menu
-* Dissection::     Analyzing a @sc{mime} message.
-* Non-MIME::       Analyzing a non-@sc{mime} message.
-* Handles::        Handle manipulations.
-* Display::        Displaying handles.
-* Customization::  Variables that affect display.
-* New Viewers::    How to write your own viewers.
-@end menu
+@item mail-encode-encoded-word-buffer
+@findex mail-encode-encoded-word-buffer
+Encode the non-ASCII words in the current buffer.  This function is
+meant to be called narrowed to the headers of a message.
 
+@item mail-encode-encoded-word-string
+@findex mail-encode-encoded-word-string
+Encode the words that need encoding in a string, and return the result.
 
-@node Dissection
-@section Dissection
+@example
+(mail-encode-encoded-word-string
+ "This is naïve, baby")
+@result{} "This is =?iso-8859-1?q?na=EFve,?= baby"
+@end example
 
-The @code{mm-dissect-buffer} is the function responsible for dissecting
-a @sc{mime} article.  If given a multipart message, it will recursively
-descend the message, following the structure, and return a tree of
-@sc{mime} handles that describes the structure of the message.
+@item mail-decode-encoded-word-region
+@findex mail-decode-encoded-word-region
+Decode the encoded words in the region.
 
-@node Non-MIME
-@section Non-MIME
+@item mail-decode-encoded-word-string
+@findex mail-decode-encoded-word-string
+Decode the encoded words in the string and return the result.
 
-Gnus also understands some non-@sc{mime} attachments, such as
-postscript, uuencode, binhex, shar, forward, gnatsweb, pgp.  Each of
-these features can be disabled by add an item into
-@code{mm-uu-configure-list}.  For example,
+@example
+(mail-decode-encoded-word-string
+ "This is =?iso-8859-1?q?na=EFve,?= baby")
+@result{} "This is naïve, baby"
+@end example
 
-@lisp
-(require 'mm-uu)
-(add-to-list 'mm-uu-configure-list '(pgp-signed . disabled))
-@end lisp
+@end table
 
-@table @code
-@item postscript
-@findex postscript
-Postscript file.
+Currently, @code{mail-parse} is an abstraction over @code{ietf-drums},
+@code{rfc2047}, @code{rfc2045} and @code{rfc2231}.  These are documented
+in the subsequent sections.
 
-@item uu
-@findex uu
-Uuencoded file.
 
-@item binhex
-@findex binhex
-Binhex encoded file.
 
-@item shar
-@findex shar
-Shar archive file.
+@node Basic Functions
+@chapter Basic Functions
 
-@item forward
-@findex forward
-Non-@sc{mime} forwarded message.
+This chapter describes the basic, ground-level functions for parsing and
+handling.  Covered here is parsing @code{From} lines, removing comments
+from header lines, decoding encoded words, parsing date headers and so
+on.  High-level functionality is dealt with in the next chapter
+(@pxref{Decoding and Viewing}).
 
-@item gnatsweb
-@findex gnatsweb
-Gnatsweb attachment.
+@menu
+* rfc2045::      Encoding @code{Content-Type} headers.
+* rfc2231::      Parsing @code{Content-Type} headers.
+* ietf-drums::   Handling mail headers defined by RFC822bis.
+* rfc2047::      En/decoding encoded words in headers.
+* time-date::    Functions for parsing dates and manipulating time.
+* qp::           Quoted-Printable en/decoding.
+* base64::       Base64 en/decoding.
+* binhex::       Binhex decoding.
+* uudecode::     Uuencode decoding.
+* rfc1843::      Decoding HZ-encoded text.
+* mailcap::      How parts are displayed is specified by the @file{.mailcap} file
+@end menu
 
-@item pgp-signed
-@findex pgp-signed
-PGP signed clear text.
 
-@item pgp-encrypted
-@findex pgp-encrypted
-PGP encrypted clear text.
+@node rfc2045
+@section rfc2045
 
-@item pgp-key
-@findex pgp-key
-PGP public keys.
+RFC2045 is the ``main'' @sc{mime} document, and as such, one would
+imagine that there would be a lot to implement.  But there isn't, since
+most of the implementation details are delegated to the subsequent
+RFCs.
 
-@item emacs-sources
-@findex emacs-sources
-Emacs source code.  This item works only in the groups matching
-@code{mm-uu-emacs-sources-regexp}.
+So @file{rfc2045.el} has only a single function:
 
+@table @code
+@item rfc2045-encode-string
+@findex rfc2045-encode-string
+Takes a parameter and a value and returns a @samp{PARAM=VALUE} string.
+@var{value} will be quoted if there are non-safe characters in it.
 @end table
 
-@node Handles
-@section Handles
 
-A @sc{mime} handle is a list that fully describes a @sc{mime}
-component.
+@node rfc2231
+@section rfc2231
 
-The following macros can be used to access elements in a handle:
+RFC2231 defines a syntax for the @code{Content-Type} and
+@code{Content-Disposition} headers.  Its snappy name is @dfn{MIME
+Parameter Value and Encoded Word Extensions: Character Sets, Languages,
+and Continuations}.
 
-@table @code
-@item mm-handle-buffer
-@findex mm-handle-buffer
-Return the buffer that holds the contents of the undecoded @sc{mime}
-part.
+In short, these headers look something like this:
 
-@item mm-handle-type
-@findex mm-handle-type
-Return the parsed @code{Content-Type} of the part.
+@example
+Content-Type: application/x-stuff;
+ title*0*=us-ascii'en'This%20is%20even%20more%20;
+ title*1*=%2A%2A%2Afun%2A%2A%2A%20;
+ title*2="isn't it!"
+@end example
 
-@item mm-handle-encoding
-@findex mm-handle-encoding
-Return the @code{Content-Transfer-Encoding} of the part.
+They usually aren't this bad, though.
 
-@item mm-handle-undisplayer
-@findex mm-handle-undisplayer
-Return the object that can be used to remove the displayed part (if it
-has been displayed).
+The following functions are defined by this library:
 
-@item mm-handle-set-undisplayer
-@findex mm-handle-set-undisplayer
-Set the undisplayer object.
+@table @code
+@item rfc2231-parse-string
+@findex rfc2231-parse-string
+Parse a @code{Content-Type} header and return a list describing its
+elements.
 
-@item mm-handle-disposition
-@findex mm-handle-disposition
-Return the parsed @code{Content-Disposition} of the part.
+@example
+(rfc2231-parse-string
+ "application/x-stuff;
+ title*0*=us-ascii'en'This%20is%20even%20more%20;
+ title*1*=%2A%2A%2Afun%2A%2A%2A%20;
+ title*2=\"isn't it!\"")
+@result{} ("application/x-stuff"
+    (title . "This is even more ***fun*** isn't it!"))
+@end example
 
-@item mm-handle-disposition
-@findex mm-handle-disposition
-Return the description of the part.
+@item rfc2231-get-value
+@findex rfc2231-get-value
+Takes one of the lists on the format above and returns
+the value of the specified attribute.
 
-@item mm-get-content-id
-Returns the handle(s) referred to by @code{Content-ID}.
+@item rfc2231-encode-string
+@findex rfc2231-encode-string
+Encode a parameter in headers likes @code{Content-Type} and
+@code{Content-Disposition}.
 
 @end table
 
 
-@node Display
-@section Display
+@node ietf-drums
+@section ietf-drums
 
-Functions for displaying, removing and saving.
+@dfn{drums} is an IETF working group that is working on the replacement
+for RFC822.
 
-@table @code
-@item mm-display-part
-@findex mm-display-part
-Display the part.
+The functions provided by this library include:
 
-@item mm-remove-part
-@findex mm-remove-part
-Remove the part (if it has been displayed).
+@table @code
+@item ietf-drums-remove-comments
+@findex ietf-drums-remove-comments
+Remove the comments from the argument and return the results.
 
-@item mm-inlinable-p
-@findex mm-inlinable-p
-Say whether a @sc{mime} type can be displayed inline.
+@item ietf-drums-remove-whitespace
+@findex ietf-drums-remove-whitespace
+Remove linear white space from the string and return the results.
+Spaces inside quoted strings and comments are left untouched.
 
-@item mm-automatic-display-p
-@findex mm-automatic-display-p
-Say whether a @sc{mime} type should be displayed automatically.
+@item ietf-drums-get-comment
+@findex ietf-drums-get-comment
+Return the last most comment from the string.
 
-@item mm-destroy-part
-@findex mm-destroy-part
-Free all resources occupied by a part.
+@item ietf-drums-parse-address
+@findex ietf-drums-parse-address
+Parse an address string and return a list that contains the mailbox and
+the plain text name.
 
-@item mm-save-part
-@findex mm-save-part
-Offer to save the part in a file.
+@item ietf-drums-parse-addresses
+@findex ietf-drums-parse-addresses
+Parse a string that contains any number of comma-separated addresses and
+return a list that contains mailbox/plain text pairs.
 
-@item mm-pipe-part
-@findex mm-pipe-part
-Offer to pipe the part to some process.
+@item ietf-drums-parse-date
+@findex ietf-drums-parse-date
+Parse a date string and return an Emacs time structure.
 
-@item mm-interactively-view-part
-@findex mm-interactively-view-part
-Prompt for a mailcap method to use to view the part.
+@item ietf-drums-narrow-to-header
+@findex ietf-drums-narrow-to-header
+Narrow the buffer to the header section of the current buffer.
 
 @end table
 
 
-@node Customization
-@section Customization
-
-@table @code
-
-@item mm-inline-media-tests
-This is an alist where the key is a @sc{mime} type, the second element
-is a function to display the part @dfn{inline} (i.e., inside Emacs), and
-the third element is a form to be @code{eval}ed to say whether the part
-can be displayed inline.
-
-This variable specifies whether a part @emph{can} be displayed inline,
-and, if so, how to do it.  It does not say whether parts are
-@emph{actually} displayed inline.
+@node rfc2047
+@section rfc2047
 
-@item mm-inlined-types
-This, on the other hand, says what types are to be displayed inline, if
-they satisfy the conditions set by the variable above.  It's a list of
-@sc{mime} media types.
+RFC2047 (Message Header Extensions for Non-ASCII Text) specifies how
+non-ASCII text in headers are to be encoded.  This is actually rather
+complicated, so a number of variables are necessary to tweak what this
+library does.
 
-@item mm-automatic-display
-This is a list of types that are to be displayed ``automatically'', but
-only if the above variable allows it.  That is, only inlinable parts can
-be displayed automatically.
+The following variables are tweakable:
 
-@item mm-attachment-override-types
-Some @sc{mime} agents create parts that have a content-disposition of
-@samp{attachment}.  This variable allows overriding that disposition and
-displaying the part inline.  (Note that the disposition is only
-overridden if we are able to, and want to, display the part inline.)
+@table @code
+@item rfc2047-default-charset
+@vindex rfc2047-default-charset
+Characters in this charset should not be decoded by this library.
+This defaults to @code{iso-8859-1}.
 
-@item mm-discouraged-alternatives
-List of @sc{mime} types that are discouraged when viewing
-@samp{multipart/alternative}.  Viewing agents are supposed to view the
-last possible part of a message, as that is supposed to be the richest.
-However, users may prefer other types instead, and this list says what
-types are most unwanted.  If, for instance, @samp{text/html} parts are
-very unwanted, and @samp{text/richtech} parts are somewhat unwanted,
-you could say something like:
+@item rfc2047-header-encoding-list
+@vindex rfc2047-header-encoding-list
+This is an alist of header / encoding-type pairs.  Its main purpose is
+to prevent encoding of certain headers.
 
-@lisp
-(setq mm-discouraged-alternatives
-      '("text/html" "text/richtext")
-      mm-automatic-display
-      (remove "text/html" mm-automatic-display))
-@end lisp
+The keys can either be header regexps, or @code{t}.
 
-@item mm-inline-large-images-p
-When displaying inline images that are larger than the window, XEmacs
-does not enable scrolling, which means that you cannot see the whole
-image.  To prevent this, the library tries to determine the image size
-before displaying it inline, and if it doesn't fit the window, the
-library will display it externally (e.g. with @samp{ImageMagick} or
-@samp{xv}).  Setting this variable to @code{t} disables this check and
-makes the library display all inline images as inline, regardless of
-their size.
+The values can be either @code{nil}, in which case the header(s) in
+question won't be encoded, or @code{mime}, which means that they will be
+encoded.
 
-@item mm-inline-override-type
-@code{mm-inlined-types} may include regular expressions, for example to
-specify that all @samp{text/.*} parts be displayed inline.  If a user
-prefers to have a type that matches such a regular expression be treated
-as an attachment, that can be accomplished by setting this variable to a
-list containing that type.  For example assuming @code{mm-inlined-types}
-includes @samp{text/.*}, then including @samp{text/html} in this
-variable will cause @samp{text/html} parts to be treated as attachments.
+@item rfc2047-charset-encoding-alist
+@vindex rfc2047-charset-encoding-alist
+RFC2047 specifies two forms of encoding---@code{Q} (a
+Quoted-Printable-like encoding) and @code{B} (base64).  This alist
+specifies which charset should use which encoding.
 
-@item mm-inline-text-html-renderer
-This selects the function used to render @sc{html}.  The predefined
-renderers are selected by the symbols @code{w3},
-@code{w3m}@footnote{See @uref{http://emacs-w3m.namazu.org/} for more
-information about emacs-w3m}, @code{links}, @code{lynx} or
-@code{html2text}.  You can also specify a function, which will be
-called with a @sc{mime} handle as the argument.
+@item rfc2047-encoding-function-alist
+@vindex rfc2047-encoding-function-alist
+This is an alist of encoding / function pairs.  The encodings are
+@code{Q}, @code{B} and @code{nil}.
 
-@item mm-inline-text-html-with-images
-Some @sc{html} mails might have the trick of spammers using
-@samp{<img>} tags.  It is likely to be intended to verify whether you
-have read the mail.  You can prevent your personal informations from
-leaking by setting this option to @code{nil} (which is the default).
-It is currently ignored by Emacs/w3.  For emacs-w3m, you may use the
-command @kbd{t} on the image anchor to show an image even if it is
-@code{nil}.@footnote{The command @kbd{T} will load all images.  If you
-have set the option @code{w3m-key-binding} to @code{info}, use @kbd{i}
-or @kbd{I} instead.}
+@item rfc2047-q-encoding-alist
+@vindex rfc2047-q-encoding-alist
+The @code{Q} encoding isn't quite the same for all headers.  Some
+headers allow a narrower range of characters, and that is what this
+variable is for.  It's an alist of header regexps / allowable character
+ranges.
 
-@item mm-inline-text-html-with-w3m-keymap
-You can use emacs-w3m command keys in the inlined text/html part by
-setting this option to non-@code{nil}.  The default value is @code{t}.
+@item rfc2047-encoded-word-regexp
+@vindex rfc2047-encoded-word-regexp
+When decoding words, this library looks for matches to this regexp.
 
 @end table
 
+Those were the variables, and these are this functions:
 
-@node New Viewers
-@section New Viewers
+@table @code
+@item rfc2047-narrow-to-field
+@findex rfc2047-narrow-to-field
+Narrow the buffer to the header on the current line.
+
+@item rfc2047-encode-message-header
+@findex rfc2047-encode-message-header
+Should be called narrowed to the header of a message.  Encodes according
+to @code{rfc2047-header-encoding-alist}.
 
-Here's an example viewer for displaying @code{text/enriched} inline:
+@item rfc2047-encode-region
+@findex rfc2047-encode-region
+Encodes all encodable words in the region specified.
 
-@lisp
-(defun mm-display-enriched-inline (handle)
-  (let (text)
-    (with-temp-buffer
-      (mm-insert-part handle)
-      (save-window-excursion
-        (enriched-decode (point-min) (point-max))
-        (setq text (buffer-string))))
-    (mm-insert-inline handle text)))
-@end lisp
+@item rfc2047-encode-string
+@findex rfc2047-encode-string
+Encode a string and return the results.
 
-We see that the function takes a @sc{mime} handle as its parameter.  It
-then goes to a temporary buffer, inserts the text of the part, does some
-work on the text, stores the result, goes back to the buffer it was
-called from and inserts the result.
+@item rfc2047-decode-region
+@findex rfc2047-decode-region
+Decode the encoded words in the region.
 
-The two important helper functions here are @code{mm-insert-part} and
-@code{mm-insert-inline}.  The first function inserts the text of the
-handle in the current buffer.  It handles charset and/or content
-transfer decoding.  The second function just inserts whatever text you
-tell it to insert, but it also sets things up so that the text can be
-``undisplayed' in a convenient manner.
+@item rfc2047-decode-string
+@findex rfc2047-decode-string
+Decode a string and return the results.
 
+@end table
 
-@node Composing
-@chapter Composing
-@cindex Composing
-@cindex MIME Composing
-@cindex MML
-@cindex MIME Meta Language
 
-Creating a @sc{mime} message is boring and non-trivial.  Therefore, a
-library called @code{mml} has been defined that parses a language called
-MML (@sc{mime} Meta Language) and generates @sc{mime} messages.
+@node time-date
+@section time-date
 
-@findex mml-generate-mime
-The main interface function is @code{mml-generate-mime}.  It will
-examine the contents of the current (narrowed-to) buffer and return a
-string containing the @sc{mime} message.
+While not really a part of the @sc{mime} library, it is convenient to
+document this library here.  It deals with parsing @code{Date} headers
+and manipulating time.  (Not by using tesseracts, though, I'm sorry to
+say.)
 
-@menu
-* Simple MML Example::             An example MML document.
-* MML Definition::                 All valid MML elements.
-* Advanced MML Example::           Another example MML document.
-* Charset Translation::            How charsets are mapped from @sc{mule} to @sc{mime}.
-* Conversion::                     Going from @sc{mime} to MML and vice versa.
-* Flowed text::                    Soft and hard newlines.
-@end menu
+These functions convert between five formats: A date string, an Emacs
+time structure, a decoded time list, a second number, and a day number.
 
+Here's a bunch of time/date/second/day examples:
 
-@node Simple MML Example
-@section Simple MML Example
+@example
+(parse-time-string "Sat Sep 12 12:21:54 1998 +0200")
+@result{} (54 21 12 12 9 1998 6 nil 7200)
 
-Here's a simple @samp{multipart/alternative}:
+(date-to-time "Sat Sep 12 12:21:54 1998 +0200")
+@result{} (13818 19266)
 
-@example
-<#multipart type=alternative>
-This is a plain text part.
-<#part type=text/enriched>
-<center>This is a centered enriched part</center>
-<#/multipart>
-@end example
+(time-to-seconds '(13818 19266))
+@result{} 905595714.0
 
-After running this through @code{mml-generate-mime}, we get this:
+(seconds-to-time 905595714.0)
+@result{} (13818 19266 0)
 
-@example
-Content-Type: multipart/alternative; boundary="=-=-="
+(time-to-days '(13818 19266))
+@result{} 729644
 
+(days-to-time 729644)
+@result{} (961933 65536)
 
---=-=-=
+(time-since '(13818 19266))
+@result{} (0 430)
 
+(time-less-p '(13818 19266) '(13818 19145))
+@result{} nil
 
-This is a plain text part.
+(subtract-time '(13818 19266) '(13818 19145))
+@result{} (0 121)
 
---=-=-=
-Content-Type: text/enriched
+(days-between "Sat Sep 12 12:21:54 1998 +0200"
+              "Sat Sep 07 12:21:54 1998 +0200")
+@result{} 5
 
+(date-leap-year-p 2000)
+@result{} t
 
-<center>This is a centered enriched part</center>
+(time-to-day-in-year '(13818 19266))
+@result{} 255
 
---=-=-=--
+(time-to-number-of-days
+ (time-since
+  (date-to-time "Mon, 01 Jan 2001 02:22:26 GMT")))
+@result{} 4.146122685185185
 @end example
 
+And finally, we have @code{safe-date-to-time}, which does the same as
+@code{date-to-time}, but returns a zero time if the date is
+syntactically malformed.
 
-@node MML Definition
-@section MML Definition
+The five data representations used are the following:
 
-The MML language is very simple.  It looks a bit like an SGML
-application, but it's not.
+@table @var
+@item date
+An RFC822 (or similar) date string.  For instance: @code{"Sat Sep 12
+12:21:54 1998 +0200"}.
 
-The main concept of MML is the @dfn{part}.  Each part can be of a
-different type or use a different charset.  The way to delineate a part
-is with a @samp{<#part ...>} tag.  Multipart parts can be introduced
-with the @samp{<#multipart ...>} tag.  Parts are ended by the
-@samp{<#/part>} or @samp{<#/multipart>} tags.  Parts started with the
-@samp{<#part ...>} tags are also closed by the next open tag.
+@item time
+An internal Emacs time.  For instance: @code{(13818 26466)}.
 
-There's also the @samp{<#external ...>} tag.  These introduce
-@samp{external/message-body} parts.
+@item seconds
+A floating point representation of the internal Emacs time.  For
+instance: @code{905595714.0}.
 
-Each tag can contain zero or more parameters on the form
-@samp{parameter=value}.  The values may be enclosed in quotation marks,
-but that's not necessary unless the value contains white space.  So
-@samp{filename=/home/user/#hello$^yes} is perfectly valid.
+@item days
+An integer number representing the number of days since 00000101.  For
+instance: @code{729644}.
 
-The following parameters have meaning in MML; parameters that have no
-meaning are ignored.  The MML parameter names are the same as the
-@sc{mime} parameter names; the things in the parentheses say which
-header it will be used in.
+@item decoded time
+A list of decoded time.  For instance: @code{(54 21 12 12 9 1998 6 t
+7200)}.
+@end table
 
-@table @samp
-@item type
-The @sc{mime} type of the part (@code{Content-Type}).
+All the examples above represent the same moment.
 
-@item filename
-Use the contents of the file in the body of the part
-(@code{Content-Disposition}).
+These are the functions available:
 
-@item charset
-The contents of the body of the part are to be encoded in the character
-set speficied (@code{Content-Type}).
+@table @code
+@item date-to-time
+Take a date and return a time.
 
-@item name
-Might be used to suggest a file name if the part is to be saved
-to a file (@code{Content-Type}).
+@item time-to-seconds
+Take a time and return seconds.
 
-@item disposition
-Valid values are @samp{inline} and @samp{attachment}
-(@code{Content-Disposition}).
+@item seconds-to-time
+Take seconds and return a time.
 
-@item encoding
-Valid values are @samp{7bit}, @samp{8bit}, @samp{quoted-printable} and
-@samp{base64} (@code{Content-Transfer-Encoding}).
+@item time-to-days
+Take a time and return days.
 
-@item description
-A description of the part (@code{Content-Description}).
+@item days-to-time
+Take days and return a time.
 
-@item creation-date
-RFC822 date when the part was created (@code{Content-Disposition}).
+@item date-to-day
+Take a date and return days.
 
-@item modification-date
-RFC822 date when the part was modified (@code{Content-Disposition}).
+@item time-to-number-of-days
+Take a time and return the number of days that represents.
 
-@item read-date
-RFC822 date when the part was read (@code{Content-Disposition}).
+@item safe-date-to-time
+Take a date and return a time.  If the date is not syntactically valid,
+return a "zero" date.
 
-@item recipients
-Who to encrypt/sign the part to.  This field is used to override any
-auto-detection based on the To/CC headers.
+@item time-less-p
+Take two times and say whether the first time is less (i. e., earlier)
+than the second time.
 
-@item size
-The size (in octets) of the part (@code{Content-Disposition}).
+@item time-since
+Take a time and return a time saying how long it was since that time.
 
-@item sign
-What technology to sign this MML part with (@code{smime}, @code{pgp}
-or @code{pgpmime})
+@item subtract-time
+Take two times and subtract the second from the first.  I. e., return
+the time between the two times.
 
-@item encrypt
-What technology to encrypt this MML part with (@code{smime},
-@code{pgp} or @code{pgpmime})
+@item days-between
+Take two days and return the number of days between those two days.
 
-@end table
+@item date-leap-year-p
+Take a year number and say whether it's a leap year.
 
-Parameters for @samp{application/octet-stream}:
+@item time-to-day-in-year
+Take a time and return the day number within the year that the time is
+in.
 
-@table @samp
-@item type
-Type of the part; informal---meant for human readers
-(@code{Content-Type}).
 @end table
 
-Parameters for @samp{message/external-body}:
 
-@table @samp
-@item access-type
-A word indicating the supported access mechanism by which the file may
-be obtained.  Values include @samp{ftp}, @samp{anon-ftp}, @samp{tftp},
-@samp{localfile}, and @samp{mailserver}.  (@code{Content-Type}.)
+@node qp
+@section qp
 
-@item expiration
-The RFC822 date after which the file may no longer be fetched.
-(@code{Content-Type}.)
+This library deals with decoding and encoding Quoted-Printable text.
 
-@item size
-The size (in octets) of the file.  (@code{Content-Type}.)
+Very briefly explained, qp encoding means translating all 8-bit
+characters (and lots of control characters) into things that look like
+@samp{=EF}; that is, an equal sign followed by the byte encoded as a hex
+string.
 
-@item permission
-Valid values are @samp{read} and @samp{read-write}
-(@code{Content-Type}).
+The following functions are defined by the library:
 
-@end table
+@table @code
+@item quoted-printable-decode-region
+@findex quoted-printable-decode-region
+QP-decode all the encoded text in the specified region.
 
-Parameters for @samp{sign=smime}:
+@item quoted-printable-decode-string
+@findex quoted-printable-decode-string
+Decode the QP-encoded text in a string and return the results.
 
-@table @samp
+@item quoted-printable-encode-region
+@findex quoted-printable-encode-region
+QP-encode all the encodable characters in the specified region.  The third
+optional parameter @var{fold} specifies whether to fold long lines.
+(Long here means 72.)
 
-@item keyfile
-File containing key and certificate for signer.
+@item quoted-printable-encode-string
+@findex quoted-printable-encode-string
+QP-encode all the encodable characters in a string and return the
+results.
 
 @end table
 
-Parameters for @samp{encrypt=smime}:
-
-@table @samp
-
-@item certfile
-File containing certificate for recipient.
 
-@end table
+@node base64
+@section base64
+@cindex base64
 
+Base64 is an encoding that encodes three bytes into four characters,
+thereby increasing the size by about 33%.  The alphabet used for
+encoding is very resistant to mangling during transit.
 
-@node Advanced MML Example
-@section Advanced MML Example
+The following functions are defined by this library:
 
-Here's a complex multipart message.  It's a @samp{multipart/mixed} that
-contains many parts, one of which is a @samp{multipart/alternative}.
+@table @code
+@item base64-encode-region
+@findex base64-encode-region
+base64 encode the selected region.  Return the length of the encoded
+text.  Optional third argument @var{no-line-break} means do not break
+long lines into shorter lines.
 
-@example
-<#multipart type=mixed>
-<#part type=image/jpeg filename=~/rms.jpg disposition=inline>
-<#multipart type=alternative>
-This is a plain text part.
-<#part type=text/enriched name=enriched.txt>
-<center>This is a centered enriched part</center>
-<#/multipart>
-This is a new plain text part.
-<#part disposition=attachment>
-This plain text part is an attachment.
-<#/multipart>
-@end example
+@item base64-encode-string
+@findex base64-encode-string
+base64 encode a string and return the result.
 
-And this is the resulting @sc{mime} message:
+@item base64-decode-region
+@findex base64-decode-region
+base64 decode the selected region.  Return the length of the decoded
+text.  If the region can't be decoded, return @code{nil} and don't
+modify the buffer.
 
-@example
-Content-Type: multipart/mixed; boundary="=-=-="
+@item base64-decode-string
+@findex base64-decode-string
+base64 decode a string and return the result.  If the string can't be
+decoded, @code{nil} is returned.
 
+@end table
 
---=-=-=
 
+@node binhex
+@section binhex
+@cindex binhex
+@cindex Apple
+@cindex Macintosh
 
+@code{binhex} is an encoding that originated in Macintosh environments.
+The following function is supplied to deal with these:
 
---=-=-=
-Content-Type: image/jpeg;
- filename="~/rms.jpg"
-Content-Disposition: inline;
- filename="~/rms.jpg"
-Content-Transfer-Encoding: base64
+@table @code
+@item binhex-decode-region
+@findex binhex-decode-region
+Decode the encoded text in the region.  If given a third parameter, only
+decode the @code{binhex} header and return the filename.
 
-/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRof
-Hh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAAwADABAREA/8QAHwAA
-AQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQR
-BRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RF
-RkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ip
-qrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEB
-AAA/AO/rifFHjldNuGsrDa0qcSSHkA+gHrXKw+LtWLrMb+RgTyhbr+HSug07xNqV9fQtZrNI
-AyiaE/NuBPOOOP0rvRNE880KOC8TbXXGCv1FPqjrF4LDR7u5L7SkTFT/ALWOP1xXgTuXfc7E
-sx6nua6rwp4IvvEM8chCxWxOdzn7wz6V9AaB4S07w9p5itow0rDLSY5Pt9K43xO66P4xs71m
-2QXiGCbA4yOVJ9+1aYORkdK434lyNH4ahCnG66VT9Nj15JFbPdX0MS43M4VQf5/yr2vSpLnw
-5ZW8dlCZ8KFXjOPX0/mK6rSPEGt3Angu44fNEReHYNvIH3TzXDeKNO8RX+kSX2ouZkicTIOc
-L+g7E810ulFjpVtv3bwgB3HJyK5L4quY/C9sVxk3ij/xx6850u7t1mtp/wDlpEw3An3Jr3Dw
-34gsbWza4nBlhC5LDsaW6+IFgupQyCF3iHH7gA7c9R9ay7zx6t7aX9jHC4smhfBkGCvHGfrm
-tLQ7hbnRrV1GPkAP1x1/Hr+Ncr8Vzjwrbf8AX6v/AKA9eQRyYlQk8Yx9K6XTNbkgia2ciSIn
-7p5Ga9Atte0LTLKO6it4i7dVRFJDcZ4PvXN+JvEMF9bILVGXJLSZ4zkjivRPDaeX4b08HOTC
-pOffmua+KkbS+GLVUGT9tT/0B68eeIpIFYjB70+OOVXyoOM9+M1eaWeCLzHPyHGO/NVWvJJm
-jQ8KGH1NfQWhXSXmh2c8eArRLwO3HSv/2Q==
+@end table
 
---=-=-=
-Content-Type: multipart/alternative; boundary="==-=-="
 
+@node uudecode
+@section uudecode
+@cindex uuencode
+@cindex uudecode
 
---==-=-=
+@code{uuencode} is probably still the most popular encoding of binaries
+used on Usenet, although @code{base64} rules the mail world.
 
+The following function is supplied by this package:
 
-This is a plain text part.
+@table @code
+@item uudecode-decode-region
+@findex uudecode-decode-region
+Decode the text in the region.
+@end table
 
---==-=-=
-Content-Type: text/enriched;
- name="enriched.txt"
 
+@node rfc1843
+@section rfc1843
+@cindex rfc1843
+@cindex HZ
+@cindex Chinese
 
-<center>This is a centered enriched part</center>
+RFC1843 deals with mixing Chinese and ASCII characters in messages.  In
+essence, RFC1843 switches between ASCII and Chinese by doing this:
 
---==-=-=--
+@example
+This sentence is in ASCII.
+The next sentence is in GB.~@{<:Ky2;S@{#,NpJ)l6HK!#~@}Bye.
+@end example
 
---=-=-=
+Simple enough, and widely used in China.
 
-This is a new plain text part.
+The following functions are available to handle this encoding:
 
---=-=-=
-Content-Disposition: attachment
+@table @code
+@item rfc1843-decode-region
+Decode HZ-encoded text in the region.
 
+@item rfc1843-decode-string
+Decode a HZ-encoded string and return the result.
 
-This plain text part is an attachment.
+@end table
 
---=-=-=--
-@end example
 
-@node Charset Translation
-@section Charset Translation
-@cindex charsets
+@node mailcap
+@section mailcap
 
-During translation from MML to @sc{mime}, for each @sc{mime} part which
-has been composed inside Emacs, an appropriate charset has to be chosen.
+The @file{~/.mailcap} file is parsed by most @sc{mime}-aware message
+handlers and describes how elements are supposed to be displayed.
+Here's an example file:
 
-@vindex mail-parse-charset
-If you are running a non-@sc{mule} Emacs, this process is simple: If the
-part contains any non-ASCII (8-bit) characters, the @sc{mime} charset
-given by @code{mail-parse-charset} (a symbol) is used.  (Never set this
-variable directly, though.  If you want to change the default charset,
-please consult the documentation of the package which you use to process
-@sc{mime} messages.
-@xref{Various Message Variables, , Various Message Variables, message,
-      Message Manual}, for example.)
-If there are only ASCII characters, the @sc{mime} charset US-ASCII is
-used, of course.
+@example
+image/*; gimp -8 %s
+audio/wav; wavplayer %s
+application/msword; catdoc %s ; copiousoutput ; nametemplate=%s.doc
+@end example
 
-@cindex MULE
-@cindex UTF-8
-@cindex Unicode
-@vindex mm-mime-mule-charset-alist
-Things are slightly more complicated when running Emacs with @sc{mule}
-support.  In this case, a list of the @sc{mule} charsets used in the
-part is obtained, and the @sc{mule} charsets are translated to @sc{mime}
-charsets by consulting the variable @code{mm-mime-mule-charset-alist}.
-If this results in a single @sc{mime} charset, this is used to encode
-the part.  But if the resulting list of @sc{mime} charsets contains more
-than one element, two things can happen: If it is possible to encode the
-part via UTF-8, this charset is used.  (For this, Emacs must support
-the @code{utf-8} coding system, and the part must consist entirely of
-characters which have Unicode counterparts.)  If UTF-8 is not available
-for some reason, the part is split into several ones, so that each one
-can be encoded with a single @sc{mime} charset.  The part can only be
-split at line boundaries, though---if more than one @sc{mime} charset is
-required to encode a single line, it is not possible to encode the part.
+This says that all image files should be displayed with @code{gimp},
+that WAVE audio files should be played by @code{wavplayer}, and that
+MS-WORD files should be inlined by @code{catdoc}.
 
-@node Conversion
-@section Conversion
+The @code{mailcap} library parses this file, and provides functions for
+matching types.
 
-@findex mime-to-mml
-A (multipart) @sc{mime} message can be converted to MML with the
-@code{mime-to-mml} function.  It works on the message in the current
-buffer, and substitutes MML markup for @sc{mime} boundaries.
-Non-textual parts do not have their contents in the buffer, but instead
-have the contents in separate buffers that are referred to from the MML
-tags.
+@table @code
+@item mailcap-mime-data
+@vindex mailcap-mime-data
+This variable is an alist of alists containing backup viewing rules.
 
-@findex mml-to-mime
-An MML message can be converted back to @sc{mime} by the
-@code{mml-to-mime} function.
+@end table
 
-These functions are in certain senses ``lossy''---you will not get back
-an identical message if you run @sc{mime-to-mml} and then
-@sc{mml-to-mime}.  Not only will trivial things like the order of the
-headers differ, but the contents of the headers may also be different.
-For instance, the original message may use base64 encoding on text,
-while @sc{mml-to-mime} may decide to use quoted-printable encoding, and
-so on.
+Interface functions:
 
-In essence, however, these two functions should be the inverse of each
-other.  The resulting contents of the message should remain equivalent,
-if not identical.
+@table @code
+@item mailcap-parse-mailcaps
+@findex mailcap-parse-mailcaps
+Parse the @code{~/.mailcap} file.
 
+@item mailcap-mime-info
+Takes a @sc{mime} type as its argument and returns the matching viewer.
 
-@node Flowed text
-@section Flowed text
-@cindex format=flowed
+@end table
 
-The Emacs @sc{mime} library will respect the @code{use-hard-newlines}
-variable (@pxref{Hard and Soft Newlines, ,Hard and Soft Newlines,
-emacs, Emacs Manual}) when encoding a message, and the
-``format=flowed'' Content-Type parameter when decoding a message.
 
-On encoding text, lines terminated by soft newline characters are
-filled together and wrapped after the column decided by
-@code{fill-flowed-encode-column}.  This variable controls how the text
-will look in a client that does not support flowed text, the default
-is to wrap after 66 characters.  If hard newline characters are not
-present in the buffer, no flow encoding occurs.
 
-On decoding flowed text, lines with soft newline characters are filled
-together and wrapped after the column decided by
-@code{fill-flowed-display-column}.  The default is to wrap after
-@code{fill-column}.
 
 @node Standards
 @chapter Standards
index 03569e9..d8234ad 100644 (file)
@@ -767,8 +767,8 @@ Getting Mail
 * Mail Sources::                Gnus \e$B$K$I$3$+$i%a!<%k$r<h$C$F$/$k$+$rCN\e(B
                                 \e$B$i$;$k\e(B
 * Mail Back End Variables::     \e$B%a!<%k$N07$$$r%+%9%?%^%$%:$9$k$?$a$NJQ?t\e(B
-* Fancy Mail Splitting::        Gnus \e$B$OF~$C$FMh$?%a!<%k$NLS$N$h$&$JJ,N%\e(B
-                                \e$B$r$9$k$3$H$,$G$-$k\e(B
+* Fancy Mail Splitting::        Gnus \e$B$OF~$C$FMh$?%a!<%k$r!"?H$NLS$N$h$@\e(B
+                                \e$B$D$h$&$JJ,3d$r$9$k$3$H$,$G$-$k\e(B
 * Group Mail Splitting::        \e$B%a!<%kJ,3d$r6nF0$9$k$?$a$K%0%k!<%W%+%9%?\e(B
                                 \e$B%^%$%:$r;H$&\e(B
 * Incorporating Old Mail::      \e$B$"$J$?$,;}$C$F$$$k8E$$%a!<%k$r$I$&$9$k$+\e(B?
@@ -970,6 +970,12 @@ Picons
 * Picon Useless Configuration::  \e$B$=$NB>$N$V$C2u$7$?$j$R$M$C$?$j$$$8$C$?\e(B
                                 \e$B$jM7$s$@$j$9$kJQ?t\e(B
 
+Thwarting Email Spam
+
+* Anti-Spam Basics::            \e$B$?$/$5$s$N\e(B spam \e$B$r8:$i$94JC1$JJ}K!\e(B
+* SpamAssassin::                Spam \e$BBP:v%D!<%k$N;H$$J}\e(B
+* Hashcash::                    CPU \e$B;~4V$rHq$d$7$F\e(B spam \e$BB`<#$9$k\e(B
+
 Appendices
 
 * XEmacs::                      XEmacs \e$B$G%$%s%9%H!<%k$9$k$?$a$NMW7o\e(B
@@ -2009,22 +2015,22 @@ Gnus \e$B$O\e(B @code{gnus-user-format-function-}@samp{X} \e$B4X?t$r8F$S=P$7$^$9!#$
 (cond (window-system
        (setq custom-background-mode 'light)
        (defface my-group-face-1
-        '((t (:foreground "Red" :bold t))) "First group face")
+         '((t (:foreground "Red" :bold t))) "First group face")
        (defface my-group-face-2
-        '((t (:foreground "DarkSeaGreen4" :bold t))) "Second group face")
+         '((t (:foreground "DarkSeaGreen4" :bold t))) "Second group face")
        (defface my-group-face-3
-        '((t (:foreground "Green4" :bold t))) "Third group face")
+         '((t (:foreground "Green4" :bold t))) "Third group face")
        (defface my-group-face-4
-        '((t (:foreground "SteelBlue" :bold t))) "Fourth group face")
+         '((t (:foreground "SteelBlue" :bold t))) "Fourth group face")
        (defface my-group-face-5
-        '((t (:foreground "Blue" :bold t))) "Fifth group face")))
+         '((t (:foreground "Blue" :bold t))) "Fifth group face")))
 
 (setq gnus-group-highlight
       '(((> unread 200) . my-group-face-1)
-       ((and (< level 3) (zerop unread)) . my-group-face-2)
-       ((< level 3) . my-group-face-3)
-       ((zerop unread) . my-group-face-4)
-       (t . my-group-face-5)))
+        ((and (< level 3) (zerop unread)) . my-group-face-2)
+        ((< level 3) . my-group-face-3)
+        ((zerop unread) . my-group-face-4)
+        (t . my-group-face-5)))
 @end lisp
 
 @pxref{Faces and Fonts} \e$B$b;2>H$7$F$/$@$5$$!#\e(B
@@ -2668,20 +2674,19 @@ kiboze \e$B%0%k!<%W$r:n@.$7$^$9!#%W%m%s%W%H$GL>A0$H!"\e(Bkiboze \e$B%0%k!<%W$K!V4^$
 @item G w
 @kindex G w (\e$B%0%k!<%W\e(B)
 @findex gnus-group-make-web-group
-@cindex DejaNews
-@cindex Alta Vista
-@cindex InReference
+@cindex Google
 @cindex nnweb
+@cindex gmane
 \e$B%&%'%V8!:w7k2L$r$b$H$K0l;~E*$J%0%k!<%W$r:n@.$7$^\e(B
 \e$B$9\e(B (@code{gnus-group-make-web-group})\e$B!#$3$N%3%^%s%I$K@\F,<-$rM?$($k$H!"\e(B
-\e$B0l;~E*$G$O$J$/8GDj$7$?%0%k!<%W$r:n@.$7$^$9!#%W%m%s%W%H$G8!:w5!4X$N<o\e(B
-\e$BN`\e(B (search engine type) \e$B$H8!:wJ8;zNs$rF~NO$7$^$9!#M-8z$J8!:w5!4X$N<oN`$K\e(B
-\e$B$O\e(B @code{dejanews}, @code{altavista}, @code{reference} \e$B$,$"$j$^$9!#\e(B
+\e$B0l;~E*$G$O$J$/8GDj$7$?%0%k!<%W$r:n@.$7$^$9!#%W%m%s%W%H$G8!:w%(%s%8%s$N<o\e(B
+\e$BN`\e(B (search engine type) \e$B$H8!:wJ8;zNs$rF~NO$7$^$9!#M-8z$J8!:w%(%s%8%s$N<o\e(B
+\e$BN`$K$O\e(B @code{google}, @code{dejanews}, @code{gmane} \e$B$,$"$j$^$9!#\e(B
 @xref{Web Searches}.
 
-\e$B$b$7!"\e(B@code{dejanews} \e$B8!:w5!4X$rMQ$$$k>l9g$K$O!"\e(B
-@samp{~g alt.sysadmin.recovery shaving} \e$B$N$h$&$J9gCW$9$kJ8;zNs$rMQ$$$k$3\e(B
-\e$B$H$K$h$C$F!"8!:wBP>]$rFCDj$N%0%k!<%W$K8BDj$9$k$3$H$,2DG=$G$9!#\e(B
+\e$B$b$7!"\e(B@code{google} \e$B8!:w%(%s%8%s$rMQ$$$k>l9g$K$O!"\e(B
+@samp{shaving group:alt.sysadmin.recovery} \e$B$N$h$&$J9gCW$9$kJ8;zNs$rMQ$$\e(B
+\e$B$k$3$H$K$h$C$F!"8!:wBP>]$rFCDj$N%0%k!<%W$K8BDj$9$k$3$H$,2DG=$G$9!#\e(B
 
 @item G DEL
 @kindex G DEL (\e$B%0%k!<%W\e(B)
@@ -4284,8 +4289,8 @@ address "sender" "owner-ding@@hpc.uh.edu")} \e$B$O!"\e(B
 
 @example
 if address "sender" "owner-ding@@hpc.uh.edu" @{
-       fileinto "INBOX.ding";
-       stop;
+        fileinto "INBOX.ding";
+        stop;
 @}
 @end example
 
@@ -4589,7 +4594,8 @@ Gnus \e$B$OJQ?t\e(B @code{gnus-extract-address-components} \e$B$NCM$r\e(B @code{From
 @vindex nnmail-extra-headers
 \e$B4XO"$7$?JQ?t$O\e(B @code{nnmail-extra-headers} \e$B$G!"\e(Boverview (@sc{nov}) \e$B%U%!\e(B
 \e$B%$%k$K$$$DDI2C$N%X%C%@!<$r4^$a$k$+$r@)8f$7$^$9!#8E$$\e(B overview \e$B%U%!%$%k$,\e(B
-\e$B$"$l$P!"$3$NJQ?t$rJQ99$7$?8e$K$O:F@8@.$9$kI,MW$,$"$j$^$9!#\e(B
+\e$B$"$k>l9g$O!"$3$NJQ?t$rJQ99$7$?8e$K%5!<%P!<%P%C%U%!$K\e(B `^' \e$B$GF~$C$FE,@Z$J\e(B
+\e$B%a!<%k%5!<%P!<\e(B (\e$BNc$($P\e(B nnml) \e$B$G\e(B `g' \e$B$r2!$7!":F@8@.$9$kI,MW$,$"$j$^$9!#\e(B
 
 @vindex gnus-summary-line-format
 gnus \e$B$K!"\e(B@code{gnus-summary-line-format} \e$BJQ?t$N\e(B @code{%n} \e$B;EMM\e(B
@@ -4611,15 +4617,19 @@ gnus \e$B$K!"\e(B@code{gnus-summary-line-format} \e$BJQ?t$N\e(B @code{%n} \e$B;EMM\e(B
 (\e$B>e5-$NCM$O\e(B gnus \e$B$N%G%#%U%)%k%HCM$G$9!#$"$J$?$NLr$KN)$D$h$&$KJQ$($F2<$5\e(B
 \e$B$$!#\e(B)
 
-\e$B$5$F!"$3$l$O:n@.$5$l$k\e(B @sc{nov} \e$B%U%!%$%k$rA`:n$G$-$k%a!<%k%0%k!<%W$G$O$?\e(B
-\e$B$$$F$$$N>l9gLrN)$A$^$9!#$7$+$7!"0J2<$N$b$N$r\e(B @file{overview.fmt} \e$B%U%!%$\e(B
-\e$B%k$N:G8e$KDI2C$9$k$h$&$K\e(B nntp \e$B4IM}<T$r@bF@$9$k$3$H$,$G$-$l$P\e(B:
+\e$B%K%e!<%94IM}?M!"$^$?$O%K%e!<%94IM}?M$r@bF@$7$F%5%]!<%H$NDI2C$r$7$F$b$i$*\e(B
+\e$B$&$H;W$C$F$$$k%f!<%6!<$N$_$J$5$s$X$N$4Cm0U\e(B:
+
+\e$B>e5-$N$3$H$O!":n@.$5$l$k\e(B @sc{nov} \e$B%U%!%$%k$rA`:n$G$-$k%a!<%k%0%k!<%W$G$O\e(B
+\e$B$?$$$F$$$N>l9gLrN)$A$^$9!#$7$+$7!"4IM}?M$r@bF@$7$F\e(B (\e$BFC$K\e(B INN \e$B$NIaDL$N<B\e(B
+\e$BAu$K$*$$$F\e(B) \e$B0J2<$N$b$N$r\e(B
 
 @example
 Newsgroups:full
 @end example
 
-\e$B%a!<%k%0%k!<%W$G$NDI2C%X%C%@!<$N$h$&$K$=$l$r;H$&$3$H$,$G$-$^$9!#\e(B
+@file{overview.fmt} \e$B%U%!%$%k$N:G8e$KDI2C$7$F$b$&$i$&$3$H$,$G$-$l$P!"%a!<\e(B
+\e$B%k%0%k!<%W$G$NDI2C%X%C%@!<$N$h$&$K$=$l$r;H$&$3$H$,$G$-$^$9!#\e(B
 
 @node Summary Buffer Mode Line
 @subsection \e$B35N,%P%C%U%!$N%b!<%I9T\e(B
@@ -6240,6 +6250,10 @@ Gnus \e$B$O<B:]$K$O$I$N5-;v$b?F$K$O$;$:!"C1$K:G=i$N8I;y$r=|$$$F$9$Y$F$N8I;y\e(B
 @item gnus-simplify-whitespace
 @findex gnus-simplify-whitespace
 \e$BM>J,$J6uGr\e(B (whitespace) \e$B$r<h$j=|$-$^$9!#\e(B
+
+@item gnus-simplify-all-whitespace
+@findex gnus-simplify-all-whitespace
+\e$B$9$Y$F$N6uGr\e(B (whitespace) \e$B$r<h$j=|$-$^$9!#\e(B
 @end table
 
 \e$B$b$A$m$s!"$"$J$?<+?H$N4X?t$r=q$/$3$H$b$G$-$^$9!#\e(B
@@ -6564,6 +6578,7 @@ gnus \e$B$OA4$F$N5-;v$N40A4$J\e(B @code{References} \e$BMs$r8+$F!"F1$8%9%l%C%I$KB0$
 @findex gnus-thread-sort-by-subject
 @findex gnus-thread-sort-by-author
 @findex gnus-thread-sort-by-number
+@findex gnus-thread-sort-by-random
 @vindex gnus-thread-sort-functions
 @findex gnus-thread-sort-by-most-recent-thread
 \e$B$b$7%9%l%C%I$N35N,I=<($r;H$C$F$$$k$N$G$"$l$P!"\e(B
@@ -6575,8 +6590,9 @@ gnus \e$B$OA4$F$N5-;v$N40A4$J\e(B @code{References} \e$BMs$r8+$F!"F1$8%9%l%C%I$KB0$
 @code{gnus-thread-sort-by-subject}, @code{gnus-thread-sort-by-date},
 @code{gnus-thread-sort-by-score},
 @code{gnus-thread-sort-by-most-recent-number},
-@code{gnus-thread-sort-by-most-recent-date} \e$B$*$h$S\e(B
-@code{gnus-thread-sort-by-total-score} \e$B$G$9!#\e(B
+@code{gnus-thread-sort-by-most-recent-date},
+@code{gnus-thread-sort-by-random} \e$B$*$h\e(B
+\e$B$S\e(B @code{gnus-thread-sort-by-total-score} \e$B$G$9!#\e(B
 
 \e$B3F4X?t$OFs$D$N%9%l%C%I$r$H$j!":G=i$N%9%l%C%I$,B>$N%9%l%C%I$h$j@h$KJB$SBX\e(B
 \e$B$($i$l$k$Y$-$G$"$l$P!"\e(B@code{nil} \e$B$G$J$$CM$r$+$($7$^$9!#IaDL!"JB$SBX$($O\e(B
@@ -6621,13 +6637,17 @@ gnus \e$B$OA4$F$N5-;v$N40A4$J\e(B @code{References} \e$BMs$r8+$F!"F1$8%9%l%C%I$KB0$
 @findex gnus-article-sort-by-score
 @findex gnus-article-sort-by-subject
 @findex gnus-article-sort-by-author
+@findex gnus-article-sort-by-random
 @findex gnus-article-sort-by-number
 \e$B2?$+4qL/$JM}M3$J$I$G%9%l%C%II=<($r;H$C$F$$$J$$$N$J$i!"JQ\e(B
 \e$B?t\e(B @code{gnus-article-sort-functions} \e$B$r$$$8$/$kI,MW$,$"$j$^$9!#$3$l\e(B
 \e$B$O\e(B @code{gnus-thread-sort-functions} \e$B$HHs>o$K;w$F$$$^$9$,!"5-;v$NHf3S$K\e(B
 \e$B$O>/!90c$C$?4X?t$r;H$$$^$9!#;HMQ2DG=$JJB$SBX$(=R8l4X?t\e(B
-\e$B$O\e(B @code{gnus-article-sort-by-number}, @code{gnus-article-sort-by-author}, @code{gnus-article-sort-by-subject}, @code{gnus-article-sort-by-date} \e$B$*\e(B
-\e$B$h$S\e(B @code{gnus-article-sort-by-score} \e$B$G$9!#\e(B
+\e$B$O\e(B @code{gnus-article-sort-by-number},
+@code{gnus-article-sort-by-author},
+@code{gnus-article-sort-by-subject}, @code{gnus-article-sort-by-date},
+@code{gnus-article-sort-by-random} \e$B$*$h\e(B
+\e$B$S\e(B @code{gnus-article-sort-by-score} \e$B$G$9!#\e(B
 
 \e$B%9%l%C%I$r;H$C$F$$$J$$I=Bj$N35N,I=<($rJB$SBX$($?$$$N$G$"$l$P!"<!$N$h$&$J\e(B
 \e$B$3$H$r$9$k$3$H$,$G$-$^$9\e(B:
@@ -7729,8 +7749,8 @@ Fonts})\e$B!#F1$8%a%C%;!<%8$NCf$KJ#?t$N5-;v$+$i$N0zMQ$,$"$k$H!"\e(Bgnus \e$B$O$=$l$
 
 @item W W h
 @kindex W W h (\e$B35N,\e(B)
-@findex gnus-article-toggle-headers
-\e$B%X%C%@!<$r1#$7$^$9\e(B (@code{gnus-article-toggle-headers})\e$B!#\e(B
+@findex gnus-article-hide-headers
+\e$B%X%C%@!<$r1#$7$^$9\e(B (@code{gnus-article-hide-headers})\e$B!#\e(B
 @xref{Hiding Headers}.
 
 @item W W b
@@ -7926,9 +7946,9 @@ gnus \e$B$,5-;v$rI=<($9$k4{Dj$N$d$jJ}$rJQ$($?$$$H$-\e(B
 @item t
 @kindex W t (\e$B35N,\e(B)
 @kindex t (\e$B35N,\e(B)
-@findex gnus-article-toggle-headers
+@findex gnus-summary-toggle-header
 \e$B5-;v%P%C%U%!$K$9$Y$F$N%X%C%@!<$rI=<($9$k$+$I$&$+$r@Z$jBX$($^\e(B
-\e$B$9\e(B (@code{gnus-article-toggle-headers})\e$B!#\e(B
+\e$B$9\e(B (@code{gnus-summary-toggle-header})\e$B!#\e(B
 
 @item W v
 @kindex W v (\e$B35N,\e(B)
@@ -8525,13 +8545,18 @@ gnus \e$B$G%a!<%k$rFI$`$3$H$NM-Mx$JE@$O!"C1=c$J%P%0$rAG@2$i$7$$IT>rM}$KCV$-\e(B
 @item C-c C-s C-c
 @kindex C-c C-s C-c (\e$B35N,\e(B)
 @findex gnus-summary-sort-by-chars
-\e$B5-;v$ND9$5$GJB$S49$($^$9\e(B (@code{gnus-summary-sort-by-chars})\e$B!#\e(B
+\e$B5-;v$ND9$5$GJB$SBX$($^$9\e(B (@code{gnus-summary-sort-by-chars})\e$B!#\e(B
 
 @item C-c C-s C-i
 @kindex C-c C-s C-i (\e$B35N,\e(B)
 @findex gnus-summary-sort-by-score
 \e$B%9%3%"$K$h$C$FJB$SBX$($^$9\e(B (@code{gnus-summary-sort-by-score})\e$B!#\e(B
 
+@item C-c C-s C-r
+@kindex C-c C-s C-r (Summary)
+@findex gnus-summary-sort-by-random
+\e$B%i%s%@%`$KJB$SBX$($^$9\e(B (@code{gnus-summary-sort-by-random})\e$B!#\e(B
+
 @item C-c C-s C-o
 @kindex C-c C-s C-o (\e$B35N,\e(B)
 @findex gnus-summary-sort-by-original
@@ -8622,12 +8647,13 @@ gnus \e$B$G%a!<%k$rFI$`$3$H$NM-Mx$JE@$O!"C1=c$J%P%0$rAG@2$i$7$$IT>rM}$KCV$-\e(B
 \e$B$"$k$3$H$b$G$-$^$9!#8e<T$O!"8=:_$NA*BrJ}K!$r;H$&$H$$$&0UL#$G$9!#%j%9%H$N\e(B
 \e$B>l9g$O!"\e(Bgnus \e$B$O9g$&$b$N$rH/8+$9$k$^$G%j%9%H$NA4$F$NJ}K!$r;n$7$^$9!#\e(B
 
-\e$B$3$l$O8=:_$NJ}K!$r;n$7$F!"$=$l$,<:GT$7$?>l9g$K$O\e(B Deja \e$B$K?V$/@_Dj$NNc$G$9\e(B:
+\e$B$3$l$O8=:_$NJ}K!$r;n$7$F!"$=$l$,<:GT$7$?>l9g$K$O\e(B Google \e$B$K?V$/@_Dj$NNc$G\e(B
+\e$B$9\e(B:
 
 @lisp
 (setq gnus-refer-article-method
       '(current
-        (nnweb "refer" (nnweb-type dejanews))))
+        (nnweb "refer" (nnweb-type google))))
 @end lisp
 
 \e$B$[$H$s$I$N%a!<%k%P%C%/%(%s%I$O\e(B @code{Message-ID} \e$B$G$N<hF@$,2DG=$G$9$,!"\e(B
@@ -9114,9 +9140,9 @@ Gnus \e$B$,F1$8\e(B @code{Message-ID} \e$B$r;}$DFs$D$N5-;v$rH/8+$7$?$H$-$O!"2?$+;W$
 
 @lisp
 (setq gnus-newsgroup-variables
-      '(message-use-followup-to
-        (gnus-visible-headers
-         . "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^To:")))
+     '(message-use-followup-to
+       (gnus-visible-headers .
+         "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^To:")))
 @end lisp
 @end table
 
@@ -10145,6 +10171,12 @@ Superseding} \e$B$r;2>H$7$F$/$@$5$$!#\e(B
 @vindex gnus-add-to-list
 @code{nil} \e$B$G$J$1$l$P!"\e(B@kbd{a} \e$B$r$7$?$H$-$K!"\e(B@code{to-list} \e$B%0%k!<%W%Q%i\e(B
 \e$B%a!<%?$r$=$l$N$J$$%a!<%k%0%k!<%W$KIU$12C$($^$9!#\e(B
+
+@item gnus-confirm-mail-reply-to-news
+@vindex gnus-confirm-mail-reply-to-news
+\e$BHs\e(B-@code{nil}\e$B$@$C$?$i!"%K%e!<%95-;v$KJV?.$9$k$H$-$K\e(B gnus \e$B$O3NG'$r5a$a$^\e(B
+\e$B$9!#%a!<%k$GJV?.$9$k5$$OL5$$$N$K;~$?$^$>$s$6$$$K\e(B R \e$B$r2!$7$F$7$^$&JJ$,$"\e(B
+\e$B$k$J$i$P!"$3$NJQ?t$O$=$s$J$"$J$?$N$?$a$K$"$j$^$9!#\e(B
 @end table
 
 @node Posting Server
@@ -10244,13 +10276,13 @@ gnus \e$B$O>o$KEj9F$K$I$NJ}K!$r;H$&$+$r$"$J$?$K?R$M$^$9!#\e(B
 
 @lisp
 (add-hook 'gnus-select-group-hook
-         (lambda ()
-           (cond
-            ((string-match
-              "^de\\." (gnus-group-real-name gnus-newsgroup-name))
-             (ispell-change-dictionary "deutsch"))
-            (t
-             (ispell-change-dictionary "english")))))
+          (lambda ()
+            (cond
+             ((string-match
+               "^de\\." (gnus-group-real-name gnus-newsgroup-name))
+              (ispell-change-dictionary "deutsch"))
+             (t
+              (ispell-change-dictionary "english")))))
 @end lisp
 
 \e$B$"$J$?$NI,MW$K1~$8$FJQ99$7$F2<$5$$!#\e(B
@@ -10366,7 +10398,7 @@ Gnus \e$B$O30$X=P$F9T$/A4$F$N%a%C%;!<%8$K!"0l$D$+$=$l0J>e$N$=$N%5!<%P!<$N%0\e(B
       '((if (message-news-p)
             "misc-news"
           (concat "mail." (format-time-string
-                          "%Y-%m" (current-time))))))
+                           "%Y-%m" (current-time))))))
 @end lisp
 
 @c (XEmacs 19.13 \e$B$K$O\e(B @code{format-time-string} \e$B$O$"$j$^$;$s$N$G!"$=\e(B
@@ -10632,6 +10664,14 @@ For PGP, Gnus supports two external libraries, @sc{gpg.el} and
 @sc{Mailcrypt}, you need to install at least one of them.  The
 @sc{s/mime} support in Gnus requires the external program OpenSSL.
 
+Often, you would like to sign replies to people who send you signed
+messages.  Even more often, you might want to encrypt messages which
+are in reply to encrypted messages.  Gnus offers
+@code{gnus-message-replysign} to enable the former, and
+@code{gnus-message-replyencrypt} for the latter.  In addition, setting
+@code{gnus-message-replysignencrypted} (on by default) will sign
+automatically encrypted messages.
+
 Instructing MML to perform security operations on a @sc{mime} part is
 done using the @kbd{C-c C-m s} key map for signing and the @kbd{C-c
 C-m c} key map for encryption, as follows.
@@ -10640,39 +10680,39 @@ C-m c} key map for encryption, as follows.
 
 @item C-c C-m s s
 @kindex C-c C-m s s
-@findex mml-secure-sign-smime
+@findex mml-secure-message-sign-smime
 
-Digitally sign current @sc{mime} part using @sc{s/mime}.
+Digitally sign current message using @sc{s/mime}.
 
 @item C-c C-m s o
 @kindex C-c C-m s o
-@findex mml-secure-sign-pgp
+@findex mml-secure-message-sign-pgp
 
-Digitally sign current @sc{mime} part using PGP.
+Digitally sign current message using PGP.
 
 @item C-c C-m s p
 @kindex C-c C-m s p
-@findex mml-secure-sign-pgp
+@findex mml-secure-message-sign-pgp
 
-Digitally sign current @sc{mime} part using @sc{pgp/mime}.
+Digitally sign current message using @sc{pgp/mime}.
 
 @item C-c C-m c s
 @kindex C-c C-m c s
-@findex mml-secure-encrypt-smime
+@findex mml-secure-message-encrypt-smime
 
-Digitally encrypt current @sc{mime} part using @sc{s/mime}.
+Digitally encrypt current message using @sc{s/mime}.
 
 @item C-c C-m c o
 @kindex C-c C-m c o
-@findex mml-secure-encrypt-pgp
+@findex mml-secure-message-encrypt-pgp
 
-Digitally encrypt current @sc{mime} part using PGP.
+Digitally encrypt current message using PGP.
 
 @item C-c C-m c p
 @kindex C-c C-m c p
-@findex mml-secure-encrypt-pgpmime
+@findex mml-secure-message-encrypt-pgpmime
 
-Digitally encrypt current @sc{mime} part using @sc{pgp/mime}.
+Digitally encrypt current message using @sc{pgp/mime}.
 
 @item C-c C-m C-n
 @kindex C-c C-m C-n
@@ -10944,6 +10984,8 @@ Also @xref{Security, ,Security, message, Message Manual}.
       (nntp-via-rlogin-command "ssh")
 @end lisp
 
+@code{nntp-via-rlogin-command-switches} \e$B$b;2>H$7$F2<$5$$!#\e(B
+
 \e$B$b$7$"$J$?$,KIJI$NCf$K$$$?$H$7$F$b!"\e(B"runsocks" \e$B$N$h$&$J%i%C%Q!<%3%^%s%I\e(B
 \e$B$rDL$7$F30$N@$3&$rD>@\%"%/%;%9$G$-$k$N$J$i$P!"0J2<$N$h$&$K\e(B socks \e$B$rDL$7\e(B
 \e$B$F%K%e!<%9%5!<%P!<$H\e(B telnet \e$B@\B3$9$k$3$H$,$G$-$^$9\e(B:
@@ -11348,7 +11390,7 @@ LIST \e$B%3%^%s%I$N%*%W%7%g%s$K;H$C$F!"\e(B(\e$B%5!<%P!<$N\e(B) \e$B%j%9%H=PNO$r@_Dj$
 @lisp
 (setq gnus-select-method
       '(nntp "news.somewhere.edu"
-            (nntp-list-options ("fj.*" "japan.*"))))
+             (nntp-list-options ("fj.*" "japan.*"))))
 @end lisp
 
 @item nntp-options-subscribe
@@ -11362,7 +11404,7 @@ LIST \e$B%3%^%s%I$N%*%W%7%g%s$K;H$C$F!"\e(B(\e$B%5!<%P!<$N\e(B) \e$B%j%9%H=PNO$r@_Dj$
 @lisp
 (setq gnus-select-method
       '(nntp "news.somewhere.edu"
-            (nntp-options-subscribe "^fj\\.\\|^japan\\.")))
+             (nntp-options-subscribe "^fj\\.\\|^japan\\.")))
 @end lisp
 
 @item nntp-options-not-subscribe
@@ -11376,7 +11418,7 @@ LIST \e$B%3%^%s%I$N%*%W%7%g%s$K;H$C$F!"\e(B(\e$B%5!<%P!<$N\e(B) \e$B%j%9%H=PNO$r@_Dj$
 @lisp
 (setq gnus-select-method
       '(nntp "news.somewhere.edu"
-            (nntp-options-not-subscribe "\\.binaries\\.")))
+             (nntp-options-not-subscribe "\\.binaries\\.")))
 @end lisp
 @end table
 
@@ -11462,6 +11504,15 @@ Emacs \e$B$N%;%C%7%g%sA4BN$r%i%C%W$7$F!"%G%#%U%)%k%H$N%a%=%C%I$r;H$&$H$$$&$N\e(B
 @vindex nntp-via-rlogin-command
 \e$BCf4V$N%[%9%H$K%m%0%$%s$9$k$?$a$K;H$o$l$k%3%^%s%I$G$9!#%G%#%U%)%k%H\e(B
 \e$B$O\e(B @samp{rsh} \e$B$G$9$,!"\e(B@samp{ssh} \e$B$,?M5$$N$"$kBeBX<jCJ$G$9!#\e(B
+
+@item nntp-via-rlogin-command-switches
+@vindex nntp-via-rlogin-command-switches
+@code{nntp-via-rlogin-command} \e$B$N%3%^%s%I$N%9%$%C%A$H$7$F;H$o$l$kJ8;zNs\e(B
+\e$B$N%j%9%H$G$9!#%G%#%U%)%k%H$O\e(B @code{nil} \e$B$G$9!#$b\e(B
+\e$B$7\e(B @samp{ssh} \e$B$r\e(B @code{nntp-via-rlogin-command} \e$B$NCM$H$7$F;H$&$J$i$P!"%G!<\e(B
+\e$B%?@\B3$r05=L$9$k$?$a$K\e(B @samp{("-C")} \e$B$r;H$&$3$H$,$G$-$^$9!#$"$k$$$O!"$b\e(B
+\e$B$7Cf4V$N%[%9%H$G\e(B telnet \e$B%3%^%s%I$,5?;wC<Kv$rI,MW$H$9$k$J$i$P!"$3$l\e(B
+\e$B$r\e(B @samp{("-t")} \e$B$^$?$O\e(B @samp{("-C" "-t")} \e$B$K$7$F2<$5$$!#\e(B
 @end table
 
 @item nntp-open-via-telnet-and-telnet
@@ -11638,8 +11689,8 @@ Emacs \e$B$N%;%C%7%g%sA4BN$r%i%C%W$7$F!"%G%#%U%)%k%H$N%a%=%C%I$r;H$&$H$$$&$N\e(B
 * Mail Sources::                Gnus \e$B$K$I$3$+$i%a!<%k$r<h$C$F$/$k$+$rCN\e(B
                                 \e$B$i$;$k\e(B
 * Mail Back End Variables::     \e$B%a!<%k$N07$$$r%+%9%?%^%$%:$9$k$?$a$NJQ?t\e(B
-* Fancy Mail Splitting::        Gnus \e$B$OF~$C$FMh$?%a!<%k$NLS$N$h$&$JJ,N%\e(B
-                                \e$B$r$9$k$3$H$,$G$-$k\e(B
+* Fancy Mail Splitting::        Gnus \e$B$OF~$C$FMh$?%a!<%k$r!"?H$NLS$N$h$@\e(B
+                                \e$B$D$h$&$JJ,3d$r$9$k$3$H$,$G$-$k\e(B
 * Group Mail Splitting::        \e$B%a!<%kJ,3d$r6nF0$9$k$?$a$K%0%k!<%W%+%9%?\e(B
                                 \e$B%^%$%:$r;H$&\e(B
 * Incorporating Old Mail::      \e$B$"$J$?$,;}$C$F$$$k8E$$%a!<%k$r$I$&$9$k$+\e(B?
@@ -11825,6 +11876,19 @@ nnmail-split-history} \e$B$r;H$&;v$,$G$-$^$9!#$3$l$+$i%9%W!<%k$7D>$=$&$H$9$k\e(B
 @code{nnmail-split-header-length-limit} \e$B$N@)8B$h$jD9$$%X%C%@!<9T$O!"J,3d\e(B
 \e$B4X?t$N=hM}BP>]$+$i=|30$5$l$^$9!#\e(B
 
+@vindex nnmail-mail-splitting-charset
+@vindex nnmail-mail-splitting-decodes
+(\e$BLuCm\e(B: \e$B%*%j%8%J%k$N\e(B Gnus \e$B$H$O;EMM$,HyL/$K0[$J$k$3$H$KCm0U$7$F2<$5$$\e(B) \e$B%G%#\e(B
+\e$B%U%)%k%H$G$OJ,3d%3!<%I$O\e(B @sc{mime} \e$B%(%s%3!<%I$5$l$?%X%C%@!<$r%G%3!<%I$9\e(B
+\e$B$k$N$G!"Hs\e(B-ASCII \e$BJ8;zNs$K%^%C%A$5$;$k$3$H$,$G$-$^$9!#JQ\e(B
+\e$B?t\e(B @code{nnmail-mail-splitting-charset} \e$B$,\e(B @sc{mime} \e$BJ8;z=8\e(B
+\e$B9g\e(B (mime-charset) \e$B$G$"$C$?$i$=$l!"\e(B@sc{mime} \e$BJ8;z=89g$G$O$J$$\e(B
+\e$BHs\e(B-@code{nil} \e$B$JCM$@$C$?$i$=$N$H$-$N\e(B @code{default-mime-charset} \e$B$NCM$G!"\e(B
+(@sc{mime} \e$B%(%s%3!<%I$5$l$?$b$N$G$O$J$$\e(B) \e$BHs\e(B-ASCII \e$B%S%C%H%Q%?!<%s$b%G%3!<\e(B
+\e$B%I$7$^$9!#$3$NF0:n$O\e(B @code{nnmail-mail-splitting-decodes} \e$B$r\e(B nil \e$B$K$9$k\e(B
+\e$B$3$H$K$h$C$F40A4$K;_$a$k$3$H$,$G$-!"@8$N%X%C%@!<$N%G!<%?$r85$K5-;v$K%^%C\e(B
+\e$B%A$5$;$?$$>l9g$K$OM-8z$G$7$g$&!#\e(B
+
 Gnus \e$B$O$"$J$?$K<+J,<+?H$KD7$MJV$C$F$/$k$h$&$J2DG=@-$N$"$kA4$F$N5!2q$rDs\e(B
 \e$B6!$7$^$9!#Nc$($P!"$"$J$?$N>e;J$+$i$/$kA4$F$N%a!<%k$r4^$s$@%0%k!<%W$r:n$C\e(B
 \e$B$?$H$7$^$7$g$&!#$=$l$+$i!"6vH/E*$K$=$N%0%k!<%W$N9XFI<h$j;_$a$,5/$3$C$?$H\e(B
@@ -12202,11 +12266,8 @@ UNDELETED} \e$B$O$*$=$i$/$?$$$F$$$N?M$K$O:GNI$NA*Br$G$7$g$&$,!"$H$-$I\e(B
 
 @item webmail
 @uref{www.hotmail.com}, @uref{webmail.netscape.com},
-@uref{www.netaddress.com}, @uref{www.my-deja.com} \e$B$J$I$N%&%'%V%a!<%k%5!<\e(B
-\e$B%P!<$+$i%a!<%k$r<hF@$7$^$9!#\e(B
-
-\e$BCm\e(B: \e$B8=:_\e(B @uref{mail.yahoo.com} \e$B$O\e(B POP3 \e$B%5!<%S%9$rDs6!$7$F$$$^$9$N$G!"\e(B
-@sc{pop} \e$B%a!<%k%=!<%9$r;H$&$N$,NI$$$N$G$O$J$$$G$7$g$&$+!#\e(B
+@uref{www.netaddress.com}, @uref{www.yahoo.com} \e$B$J$I$N%&%'%V%a!<%k%5!<%P!<\e(B
+\e$B$+$i%a!<%k$r<hF@$7$^$9!#\e(B
 
 \e$BCm\e(B: \e$B%&%'%V%a!<%k$O%/%C%-!<$KBg$-$/0MB8$7$^$9!#\e(Burl "4.0pre.46" \e$B$r;H$&>l9g\e(B
 \e$B$O\e(B "one-line-cookie" \e$B%Q%C%A$rEv$F$kI,MW$,$"$j$^$9!#\e(B
@@ -12431,6 +12492,15 @@ UNDELETED} \e$B$O$*$=$i$/$?$$$F$$$N?M$K$O:GNI$NA*Br$G$7$g$&$,!"$H$-$I\e(B
 @code{nil} \e$B$G$J$$$H!"%P%C%/%(%s%I$KF~$C$FMh$?5-;v\e(B (\e$BNc$($P!"\e(B@code{Gcc} \e$B$K\e(B
 \e$B$h$C$F\e(B) \e$B$N\e(B @code{Message-ID} \e$B$r%a!<%k=EJ#H/8+%U%!%$%k$KF~$l$^$9!#%G%#%U%)\e(B
 \e$B%k%H$O\e(B @code{nil} \e$B$G$9!#\e(B
+
+@item nnmail-cache-ignore-groups
+@vindex nnmail-cache-ignore-groups
+\e$B@55,I=8=$+@55,I=8=$N%j%9%H$G$9!#@55,I=8=$K%0%k!<%WL>$,%^%C%A$9$k\e(B
+\e$B$H\e(B @code{Message-ID} \e$B%-%c%C%7%e$K5-O?$5$l$^$;$s!#\e(B
+
+\e$BNc$($PFC5iJ,3d\e(B (@pxref{Fancy Mail Splitting}) \e$B$r4X\e(B
+\e$B?t\e(B @code{nnmail-split-fancy-with-parent} \e$B$H$H$b$K;H$C$F$$$k>l9g$KLrN)$D\e(B
+\e$B$G$7$g$&!#\e(B
 @end table
 
 @node Fancy Mail Splitting
@@ -12578,18 +12648,20 @@ table) \e$B$K=>$C$F40A4$K9gCW$7$J$1$l$P$J$j$^$;$s!#@55,I=8=$G%U%#!<%k%IL>$+\e(B
 
 \e$B$3$N5!G=$rMxMQ$9$k$?$a$K$O!"$^$:JQ\e(B
 \e$B?t\e(B @code{nnmail-treat-duplicates} \e$B$H\e(B @code{nnmail-cache-accepted-message-ids} \e$B$N\e(B
-\e$BCM$rHs\e(B nil \e$B$K@_Dj$9$kI,MW$,$"$j$^$9!#$=$l$,$G$-$?\e(B
+\e$BCM$rHs\e(B-nil \e$B$K@_Dj$9$kI,MW$,$"$j$^$9!#$=$l$,$G$-$?\e(B
 \e$B$i\e(B @code{nnmail-split-fancy-with-parent} \e$B$r;H$C$F$_$F$/$@$5$$!#%3%m%s$r\e(B
 \e$B;H$C$F$3$s$JIw$K=q$-$^$9\e(B:
 @lisp
-(setq nnmail-split-fancy
+(setq nnmail-treat-duplicates 'warn     ; \e$B$^$?$O\e(B 'delete
+      nnmail-cache-accepted-message-ids t
+      nnmail-split-fancy
       '(| (: nnmail-split-fancy-with-parent)
           ;; \e$B;D$j$N?6$jJ,$1J}$O$3$3$K=q$/\e(B
         ))
 @end lisp
 
 \e$B$3$N5!G=$O<B:]!"<!$NMM$KF/$$$F$$$^$9\e(B: \e$BJQ?t\e(B
-@code{nnmail-treat-duplicates} \e$B$NCM$,Hs\e(B nil \e$B$N>l9g!"\e(BGnus \e$B$O8+$D$1$?A45-\e(B
+@code{nnmail-treat-duplicates} \e$B$NCM$,Hs\e(B-nil \e$B$N>l9g!"\e(BGnus \e$B$O8+$D$1$?A45-\e(B
 \e$B;v$N%a%C%;!<%8\e(B ID \e$B$r\e(B \e$BJQ?t\e(B @code{nnmail-message-id-cache-file} \e$B$,;XDj$9$k\e(B
 \e$B%U%!%$%k$K5-O?$7$^$9!#$3$N$H$-!"$=$l$>$l$N5-;v$,B8:_$9$k%0%k!<%W$NL>A0$r\e(B
 \e$BJ;5-$7$^$9\e(B (\e$B$?$@$7%a!<%k$N>l9g$@$1!"$5$b$J$1$l$P%0%k!<%WL>$OD4$Y$^$;$s\e(B)\e$B!#\e(B
@@ -12606,10 +12678,17 @@ table) \e$B$K=>$C$F40A4$K9gCW$7$J$1$l$P$J$j$^$;$s!#@55,I=8=$G%U%#!<%k%IL>$+\e(B
 \e$B%$%k$NBg$-$5$O$@$$$?$$\e(B 300 \e$B%-%m%P%$%H$0$i$$$K$J$k$_$?$$$G$9\e(B)\e$B!#\e(B
 @vindex nnmail-cache-accepted-message-ids
 \e$B$5$i$K!"JQ?t\e(B @code{nnmail-cache-accepted-message-ids} \e$B$NCM$r\e(B
-\e$BHs\e(B @code{nil} \e$B$K@_Dj$9$l$P!"\e(Bgnus \e$B$O0\F0$5$l$?5-;v$N%a%C%;!<%8\e(B ID \e$B$r$b5-\e(B
+\e$BHs\e(B-@code{nil} \e$B$K@_Dj$9$l$P!"\e(Bgnus \e$B$O0\F0$5$l$?5-;v$N%a%C%;!<%8\e(B ID \e$B$r$b5-\e(B
 \e$BO?$9$k$N$G!"%U%)%m!<%"%C%W5-;v$O?F5-;v$N0\F0@h$HF1$8%0%k!<%W$KF~$k$h$&$K\e(B
 \e$B$J$j$^$9!#\e(B
 
+\e$B$"$k%0%k!<%W$r%-%c%C%7%e$K5-O?$7$?$/$J$$>l9g$O!"JQ\e(B
+\e$B?t\e(B @code{nnmail-cache-ignore-groups} \e$B$b;2>H$7$F2<$5$$!#Nc$($P!"30$K=P$9\e(B
+\e$B$9$Y$F$N%a%C%;!<%8$,\e(B `outgoing' \e$B%0%k!<%W$G=q$+$l$F$$$k$J$i$P!"\e(B
+@code{nnmail-cache-ignore-groups} \e$B$r$=$N%0%k!<%WL>$K%^%C%A$9$k$h$&$K@_Dj\e(B
+\e$B$9$k$N$,NI$$$G$9!#$5$b$J$$$H$"$J$?$N$9$Y$F$N%a%C%;!<%8$KBP$9$kJV;v$,!":G\e(B
+\e$B8e$O\e(B `outgoing' \e$B%0%k!<%W$KF~$C$F$7$^$&$G$7$g$&!#\e(B
+
 @node Group Mail Splitting
 @subsection \e$B%0%k!<%W%a!<%kJ,3d\e(B
 @cindex mail splitting
@@ -12998,6 +13077,11 @@ Gnus \e$B$O5-;v$rI=<($9$k$H$-$K$=$l$r@vBu$9$k$?$a$K2aEY$N4X?t$rDs6!$7$F$$$^\e(B
 \e$B%X%C%@!<$K$=$l$,NI$/8+$($k$h$&$K\e(B ``\e$BM-MQ$J\e(B'' \e$B%j%9%H%5!<%P!<$,A0$NJ}$KIU$1\e(B
 \e$B2C$($?6uGr$rL5$/$7$^$9!#$"$!$!!#\e(B
 
+(\e$B$3$N4X?t$O$9$Y$F$N%a%C%;!<%8$N%\%G%#Cf$K$"$k%X%C%@!<\e(B (\e$B%\%G%#Cf$N%a%C%;!<\e(B
+\e$B%8$,;}$C$F$$$k%X%C%@!<9T$N$h$&$J$b$N\e(B) \e$B$KBP$7$F$bF0:n$9$k$N$G!";HMQ$K:]$7\e(B
+\e$B$F$O@x:_E*$J4m81$rUT$s$G$$$^$9!#$7$?$,$C$F%P%0$r=$@5$9$k$h$j$O!"J8=q$GFC\e(B
+\e$BD'$r<($9$N$,!"$b$A$m$s@5$7$$2r7h$NF;$G$9!#\e(B)
+
 @item nnmail-remove-list-identifiers
 @findex nnmail-remove-list-identifiers
 \e$B$$$/$D$+$N%j%9%H%5!<%P!<$OF10l<1JL;R$rIU$12C$($^$9\e(B---\e$BNc$($P!"\e(B
@@ -13701,9 +13785,9 @@ gnus \e$B$r=*N;$7$?$$$+$b$7$l$^$;$s!#\e(B
 @node Web Searches
 @subsection \e$B%&%'%V8!:w\e(B
 @cindex nnweb
-@cindex DejaNews
-@cindex Alta Vista
-@cindex InReference
+@cindex Google
+@cindex dejanews
+@cindex gmane
 @cindex Usenet searches
 @cindex searching the Usenet
 
@@ -13724,11 +13808,11 @@ gnus \e$B$r=*N;$7$?$$$+$b$7$l$^$;$s!#\e(B
 \e$B%k!<%W$KF~$k$?$S$K\e(B(\e$B$?$H$(8!:w%Q%?!<%s$rJQ99$7$F$$$J$/$H$b\e(B)\e$B!"5-;v$N=g=x$,\e(B
 \e$B0c$C$F$$$k$+$b$7$l$^$;$s!#$^$?!"=EJ#M^\e(B
 \e$B@)\e(B (@pxref{Duplicate Suppression}) \e$B$r;H$C$F$b$&$^$/F/$+$J$$$G$7$g$&!#$H\e(B
-\e$B$$$&$N$O!"\e(B@code{nnweb} \e$B$O8!:w%(%s%8%s\e(B (\e$BNc$($P\e(B DejaNews) \e$B$r;H$C$F5-;v$rFI\e(B
-\e$B$_9~$`$^$G$O!"\e(B@code{Message-ID} \e$B$rCN$k$3$H$O$G$-$J$$$+$i$G$9!#$"$J$?$,FI\e(B
-\e$B$s$@5-;v$r21$($F$*$/$?$a$NM#0l$NJ}K!$O!"\e(B@code{Date} \e$B%X%C%@!<$r$b$H$K%9%3\e(B
-\e$B%"$rIU$1$k$3$H$@$1$G$9\e(B --- \e$B$D$^$j$"$J$?$,$=$N%0%k!<%W$r:G8e$KFI$s$@F|IU\e(B
-\e$B$h$j!"A0$KEj9F$5$l$?5-;v$rA4$F4{FI$K$9$k!"$H$$$&$3$H$G$9!#\e(B
+\e$B$$$&$N$O!"\e(B@code{nnweb} \e$B$O8!:w%(%s%8%s\e(B (\e$BNc$($P\e(B Google) \e$B$r;H$C$F5-;v$rFI$_\e(B
+\e$B9~$`$^$G$O!"\e(B@code{Message-ID} \e$B$rCN$k$3$H$O$G$-$J$$$+$i$G$9!#$"$J$?$,FI$s\e(B
+\e$B$@5-;v$r21$($F$*$/$?$a$NM#0l$NJ}K!$O!"\e(B@code{Date} \e$B%X%C%@!<$r$b$H$K%9%3%"\e(B
+\e$B$rIU$1$k$3$H$@$1$G$9\e(B --- \e$B$D$^$j$"$J$?$,$=$N%0%k!<%W$r:G8e$KFI$s$@F|IU$h\e(B
+\e$B$j!"A0$KEj9F$5$l$?5-;v$rA4$F4{FI$K$9$k!"$H$$$&$3$H$G$9!#\e(B
 
 \e$B$b$78!:w%(%s%8%s$N=PNO7A<0$,JQ99$5$l$k$H!"\e(B@code{nnweb} \e$B$O$=$l$r$&$^$/2r\e(B
 \e$B<a$G$-$:!"=hM}$O<:GT$9$k$G$7$g$&!#$b$7%&%'%VDs6!<TC#$,$=$s$J$3$H$r$7$?$i!"\e(B
@@ -13746,8 +13830,8 @@ gnus \e$B$r=*N;$7$?$$$+$b$7$l$^$;$s!#\e(B
 @item nnweb-type
 @vindex nnweb-type
 \e$B$I$N8!:w%(%s%8%s$r;H$C$F$$$k$+!#8=:_%5%]!<%H$5$l$F$$$k<oN`$O!"\e(B
-@code{dejanews}, @code{dejanewsold}, @code{altavista}, @code{reference} \e$B$G\e(B
-\e$B$9!#\e(B
+@code{google}, @code{dejanews} \e$B$=$7$F\e(B @code{gmane} \e$B$G$9!#\e(B
+@code{dejanews} \e$B$O\e(B @code{google} \e$B$NJLL>$K$J$C$F$$$k$3$H$KCm0U$7$F2<$5$$!#\e(B
 
 @item nnweb-search
 @vindex nnweb-search
@@ -13755,7 +13839,7 @@ gnus \e$B$r=*N;$7$?$$$+$b$7$l$^$;$s!#\e(B
 
 @item nnweb-max-hits
 @vindex nnweb-max-hits
-\e$BI=<($9$k8!:w7k2L$N:GBg?t!#=i4|CM$O\e(B 100 \e$B$G$9!#\e(B
+\e$BI=<($9$k8!:w7k2L$N:GBg?t!#=i4|CM$O\e(B 999 \e$B$G$9!#\e(B
 
 @item nnweb-type-definition
 @vindex nnweb-type-definition
@@ -13942,7 +14026,7 @@ an_egroup RET egroups RET www.egroups.comRET your@@email.address RET}\e$B!#\e(B
 
 @example
   @uref{http://emacs-w3m.namazu.org/}
-  @uref{http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/}
+  @uref{http://w3m.sourceforge.net/}
 @end example
 
 @findex gnus-group-make-shimbun-group
@@ -14196,7 +14280,7 @@ Web Newspaper \e$B$K4X$9$k0J2<$N\e(B @code{nnshimbun} \e$BJQ?t$rJQ$($k$3$H$,2DG=$G$
 
 (defun gnus-user-format-function-X (header)
   (let ((descr
-        (assq nnrss-description-field (mail-header-extra header))))
+         (assq nnrss-description-field (mail-header-extra header))))
     (if descr (concat "\n\t" (cdr descr)) "")))
 @end lisp
 
@@ -14456,7 +14540,7 @@ nnimap \e$B$O$=$l$b%5%]!<%H$7$^$9!#$7$+$7!"\e(BSSLeay \e$B$N:G?7HG$G$"$k\e(B 0.9.x \e
 \e$B$OB8:_$7$F$$$k$H7h$a$^$7$?!#$b$C$H>\$7$/@bL@$9$k$H!"\e(B@sc{imap} \e$B$O<B:]$K$O\e(B
 \e$B5-;v$r>C5n$7$J$$!"5-;v$K\e(B @code{Deleted} \e$B$H$$$&0u$rIU$1$k35G0$,$"$j!"$3\e(B
 \e$B$l\e(B (\e$B$($C$H!"\e(B@code{Deleted} \e$B$H$$$&0u$rIU$1$k$3$H$G\e(B
-\e$B$9\e(B) \e$B$,\e(B nnimap \e$B$,\e(B Gnus \e$B$G5-;v$r>C5n$9$k$H$-$K$9$k$3$H$G$9\e(B (@kbd{G DEL} \e$B$J\e(B
+\e$B$9\e(B) \e$B$,\e(B nnimap \e$B$,\e(B Gnus \e$B$G5-;v$r>C5n$9$k$H$-$K$9$k$3$H$G$9\e(B (@kbd{B DEL} \e$B$J\e(B
 \e$B$I$G\e(B)\e$B!#\e(B
 (\e$BLuCm\e(B: \e$B%Q%k%a%K%G%9$O5*85A0\e(B 5 \e$B@$5*$N%.%j%7%"$N\e(B Elea \e$BGI$NE/3X<T\e(B)
 
@@ -14486,11 +14570,12 @@ nnimap \e$B$O$=$l$b%5%]!<%H$7$^$9!#$7$+$7!"\e(BSSLeay \e$B$N:G?7HG$G$"$k\e(B 0.9.x \e
 @item nnimap-importantize-dormant
 @vindex nnimap-importantize-dormant
 
-\e$BHs\e(B nil \e$B$@$C$?$i!"B>$N\e(B @sc{imap} \e$B%/%i%$%"%s%H$N$?$a$KJ]N15-;v$r0uIU$-$H$7\e(B
-\e$B$F$b0u$rIU$1$^$9!#\e(Bgnus \e$B$NFbIt$G$O!"J]N15-;v$O85!9$9$G$K0uIU$-$H$7$F$N$_\e(B
-\e$B0u$,IU$1$i$l$F$$$^$9!#$3$l$O!"B>$N\e(B @sc{imap} \e$B%/%i%$%"%s%H$K$*$1$kJ]N15-\e(B
-\e$B;v$r!"$"$?$+$b0uIU$-$N$h$&$K$-$oN)$?$;$^$9!#\e(B(\e$BJL$N8@$$J}$r$9$k$H!"\e(Bgnus \e$B$O\e(B
-\e$BFs$D$N0u$rIU$1!"\e(B@sc{imap} \e$B$O$?$C$?0l$D$@$H$$$&$3$H$G$9!#\e(B)
+\e$BHs\e(B-nil (\e$B%G%#%U%)%k%H\e(B) \e$B$@$C$?$i!"B>$N\e(B @sc{imap} \e$B%/%i%$%"%s%H$N$?$a$KJ]N1\e(B
+\e$B5-;v$r0uIU$-$H$7$F$b0u$rIU$1$^$9!#\e(Bgnus \e$B$NFbIt$G$O!"J]N15-;v$O85!9$9$G$K\e(B
+\e$BJ]N15-;v$H$7$F$N$_0u$,IU$1$i$l$F$$$^$9!#$3$l$O!"B>$N\e(B @sc{imap} \e$B%/%i%$%"\e(B
+\e$B%s%H$K$*$1$kJ]N15-;v$r!"$"$?$+$b0uIU$-$N$h$&$K$-$oN)$?$;$^$9!#\e(B(\e$BJL$N8@$$\e(B
+\e$BJ}$r$9$k$H!"\e(Bgnus \e$B$OFs$D$N0u$rIU$1!"\e(B@sc{imap} \e$B$O$?$C$?0l$D$@$H$$$&$3$H$G\e(B
+\e$B$9!#\e(B)
 
 \e$B$?$V$s$3$l$r$$$8$j$^$o$9$N$O!"$"$J$?$,%f!<%6C10L$NJ]N1%U%i%0$rIU$1$h$&$H\e(B
 \e$B$9$k$@$1$NM}M3$K$h$k$G$7$g$&!#$3$s$J46$8$G\e(B:
@@ -15605,20 +15690,10 @@ Namazu \e$B$r;H$C$F!"%a!<%k$N;3$+$i$"$J$?$N9%$-$J%-!<%o!<%I$r4^$`5-;v$r8+\e(B
   @uref{http://namazu.org/}
 @end example
 
-\e$B<!$K!"$"$J$?$NHkB"$N%a!<%k$H1JB35-;v$N;3$N:w0z$r:n$j$^$9!#$=$N$?$a$K$O!"\e(B
-\e$B0J2<$N\e(B2\e$B$D$N%3%^%s%I$r<B9T$9$kI,MW$,$"$k$G$7$g$&!#\e(B
-
-@example
-  % mkdir ~/News/namazu
-  % mknmz -a -h -O ~/News/namazu ~/Mail ~/News/cache
-@end example
-
-\e$B$3$N%3%^%s%I$O!"\e(B(1) @file{~/News/namazu/} \e$B$H$$$&%G%#%l%/%H%j$r:n@.$9$k!"\e(B
-(2) \e$B$=$N%G%#%l%/%H%j$K\e(B @file{~/Mail/} \e$B0J2<$KJ]B8$5$l$F$$$k%a!<%k$H\e(B 
-@file{~/News/cache/} \e$B0J2<$KJ]B8$5$l$F$$$k1JB35-;v$N:w0z$r:n@.$9$k!"$H\e(B
-\e$B$$$&0UL#$G$9!#\e(B
-
-\e$B$5$"!"$3$l$G=`Hw$,$G$-$^$7$?!#\e(B
+@findex gnus-namazu-create-index
+\e$B<!$K!"$"$J$?$NHkB"$N%a!<%k$H1JB35-;v$N;3$N:w0z$r:n$k$?$a$K!"\e(B
+@kbd{M-x gnus-namazu-create-index} \e$B$H$7$F$/$@$5$$!#$5$"!"$3$l$G=`Hw$,\e(B
+\e$B$G$-$?$O$:$G$9!#\e(B
 
 @kindex C-c C-n (\e$B%0%k!<%W\e(B)
 @kindex C-c C-n (\e$B35N,\e(B)
@@ -15640,7 +15715,7 @@ gnus \e$B$NDL>o$N?t;z@\F,<-$d!"%W%m%;%9@\F,<-$rM}2r$7$^$9!#$G$9$+$i!"$"$J\e(B
 \e$B$N9T$K0\F0$7$F!"<!$N$h$&$K8!:w$9$k$3$H$,$G$-$^$9!#\e(B
 
 @example
-  @kbd{M-1 C-c C-n namazu RET}
+  @kbd{1 C-c C-n namazu RET}
 @end example
 
 \e$B$^$?!"35N,%P%C%U%!$+$i!"$$$-$J$j8!:w$9$k$3$H$b$G$-$^$9!#$3$N>l9g!"8!:w\e(B
@@ -15652,11 +15727,31 @@ gnus \e$B$NDL>o$N?t;z@\F,<-$d!"%W%m%;%9@\F,<-$rM}2r$7$^$9!#$G$9$+$i!"$"$J\e(B
   @kbd{C-c C-n +from:"Your E-Mail Address" RET}
 @end example
 
-\e$B:G8e$K!"\e(BNamazu \e$B$r$h$/J,$+$C$F$$$k?M$K$O!"ITMW$JCm0U$r0l$D!#\e(BNamazu \e$B$O!"\e(B
-\e$B;vA0$K:n@.$5$l$?:w0z$rMQ$$$F8!:w$r9T$$!":w0z$K$N$C$F$$$J$$%U%!%$%k$K$O\e(B
-\e$BL\$b$/$l$^$;$s!#$@$+$i!"Dj4|E*$K\e(B @code{mknmz} \e$B$r8F$S=P$7$F!"?7$?$J%a!<\e(B
-\e$B%k$N:w0z$rDI2C$7$J$$$H!"?7$7$$%a!<%k$O$$$D$^$G$?$C$F$b8!:w$5$l$J$$$3$H\e(B
-\e$B$K$J$j$^$9$+$i!"$"$7$+$i$:!#\e(B
+@vindex gnus-namazu-index-update-interval
+Namazu \e$B$O!";vA0$K=`Hw$5$l$?:w0z$rMQ$$$F8!:w$r9T$&$h$&$K@_7W$5$l$?8!:w\e(B
+\e$B%(%s%8%s$J$N$G!":w0z$KEPO?$5$l$F$$$J$$%U%!%$%k$O40A4$KL5;k$5$l$^$9!#$D\e(B
+\e$B$^$j!"Dj4|E*$K\e(B @code{mknmz} \e$B$r8F$S=P$7$F!"?7$?$J%a!<%k$N:w0z$rDI2C$7$J\e(B
+\e$B$$$H!"?7$7$$%a!<%k$O$$$D$^$G$?$C$F$b8!:wBP>]$K$J$i$J$$$3$H$K$J$j$^$9!#\e(B
+@file{gnus-namazu.el} \e$B$O!"\e(B@code{gnus-namazu-index-update-interval} \e$B$K\e(B
+\e$B;XDj$5$l$?4|4VKh$K<+F0E*$K:w0z$r99?7$9$k5!G=$rDs6!$7$F$$$^$9!#%G%U%)%k\e(B
+\e$B%H$N@_Dj$G$O!"\e(B3\e$BF|$*$-$K:w0z$r99?7$9$k$h$&$K$J$C$F$$$^$9$,!"$b$C$HIQHK\e(B
+\e$B$K\e(B(\e$BNc$($P\e(B1\e$BF|$*$-\e(B)\e$B$K99?7$9$k$h$&$K$7$?$$$J$i$P!"0J2<$N@_Dj$r\e(B 
+@file{~/.gnus} \e$B$KDI2C$7$F$/$@$5$$!#\e(B
+
+@example
+(setq gnus-namazu-index-update-interval 86400)
+@end example
+
+\e$B5U$K!":w0z$N99?7$r<+F0E*$K9T$$$?$/$J$$$J$i$P!"0J2<$N;XDj$r\e(B 
+@file{~/.gnus} \e$B$KDI2C$7$F$/$@$5$$!#\e(B
+
+@example
+(setq gnus-namazu-index-update-interval nil)
+@end example
+
+@findex{gnus-namazu-update-all-indices}
+\e$B$3$N>l9g!":w0z$r<jF0$G99?7$9$k$?$a$K\e(B @kbd{M-x
+gnus-namazu-update-all-indices} \e$B$H$9$kI,MW$,$"$k$+$b$7$l$^$;$s!#\e(B
 
 @node Gnus Unplugged
 @section Gnus \e$B$N@Z$jN%$7\e(B
@@ -15930,7 +16025,7 @@ gnus \e$B%(!<%8%'%s%H$,$=$N5-;v$r\e(B SPAM \e$B$@$H8+Pv$7$?$i??!#$3$NH/8+E*<jK!$O!"
 (require 'gnus-agent)
 (setq gnus-category-predicate-alist
       (append gnus-category-predicate-alist
-             '((old . my-article-old-p))))
+              '((old . my-article-old-p))))
 @end lisp
 
 \e$B$=$7$F!"C1$K<!$N$h$&$K=R8l$r;XDj$7$^$9\e(B:
@@ -17422,16 +17517,16 @@ gnus \e$B$K$O$3$l$i$rA4$F<+F0E*$K\e(B --- \e$B$^$k$GKbK!$G$b;H$C$?$h$&$K:n@.\e(B
 @lisp
 (setq gnus-default-adaptive-score-alist
       '((gnus-unread-mark)
-       (gnus-ticked-mark (from 4))
-       (gnus-dormant-mark (from 5))
-       (gnus-del-mark (from -4) (subject -1))
-       (gnus-read-mark (from 4) (subject 2))
-       (gnus-expirable-mark (from -1) (subject -1))
-       (gnus-killed-mark (from -1) (subject -3))
-       (gnus-kill-file-mark)
-       (gnus-ancient-mark)
-       (gnus-low-score-mark)
-       (gnus-catchup-mark (from -1) (subject -1))))
+        (gnus-ticked-mark (from 4))
+        (gnus-dormant-mark (from 5))
+        (gnus-del-mark (from -4) (subject -1))
+        (gnus-read-mark (from 4) (subject 2))
+        (gnus-expirable-mark (from -1) (subject -1))
+        (gnus-killed-mark (from -1) (subject -3))
+        (gnus-kill-file-mark)
+        (gnus-ancient-mark)
+        (gnus-low-score-mark)
+        (gnus-catchup-mark (from -1) (subject -1))))
 @end lisp
 
 \e$B8+$F$*J,$+$j$N$h$&$K!"$3$NO"A[%j%9%H$N3FMWAG$O!"%-!<$H$7$F0u\e(B (\e$BJQ?tL>$+$b\e(B
@@ -19000,7 +19095,7 @@ The GNU Emacs Lisp Reference Manual}. XEmacs \e$B$G$O!"%U%l!<%`%W%m%Q%F%#%j\e(B
                      (vertical 0.24
                                (if (buffer-live-p gnus-summary-buffer)
                                    '(summary 0.5))
-                               (group 1.0)))))
+                               (group 1.0))))
 @end lisp
 
 \e$BJ#?t$N%U%l!<%`$X$NNI$/$"$kMWK>$O!"%a!<%k$H%K%e!<%9$N:n@.$K$OJL$N%U%l!<%`\e(B
@@ -20158,8 +20253,21 @@ Gnus \e$B$O!"%9%3%"IU$1!"%9%l%C%I$N7A@.!"%9%l%C%IHf3S$J$I$r9T$&$H$-$K!"\e(B
 
 \e$B$3$l$OITL{2w$G$9!#\e(B
 
-\e$B$3$l$KBP=h$9$kJ}K!$O!"\e(Bgnus \e$B$KA4$F$N\e(B spam \e$B$r\e(B @samp{spam} \e$B%a!<%k%0%k!<%W$K\e(B
-\e$BJ,N%$5$;$F$7$^$&$3$H$G$9\e(B (@pxref{Splitting Mail})\e$B!#\e(B
+@menu
+* Anti-Spam Basics::            \e$B$?$/$5$s$N\e(B spam \e$B$r8:$i$94JC1$JJ}K!\e(B
+* SpamAssassin::                Spam \e$BBP:v%D!<%k$N;H$$J}\e(B
+* Hashcash::                    CPU \e$B;~4V$rHq$d$7$F\e(B spam \e$BB`<#$9$k\e(B
+@end menu
+
+@node Anti-Spam Basics
+@subsection Spam \e$BB`<#$N4pAC\e(B
+@cindex email spam
+@cindex spam
+@cindex UCE
+@cindex unsolicited commercial email
+
+Spam \e$B$KBP=h$9$k0l$D$NJ}K!$O!"\e(Bgnus \e$B$KA4$F$N\e(B spam \e$B$r\e(B @samp{spam} \e$B%a!<%k%0\e(B
+\e$B%k!<%W$KJ,N%$5$;$F$7$^$&$3$H$G$9\e(B (@pxref{Splitting Mail})\e$B!#\e(B
 
 \e$B:G=i$K!"$"$J$?$KE~C#@-$N$"$k@5$7$$%a!<%k%"%I%l%9$r0l$DA*$S!"$=$l$rA4$F$N\e(B
 \e$B$"$J$?$N%K%e!<%95-;v$N\e(B @code{From} \e$B%X%C%@!<$KF~$l$^$9!#\e(B(\e$B$3$3$G$O\e(B
@@ -20224,7 +20332,152 @@ Gnus \e$B$O!"%9%3%"IU$1!"%9%l%C%I$N7A@.!"%9%l%C%IHf3S$J$I$r9T$&$H$-$K!"\e(B
 \e$B$3$l$G;d$N$H$3$m$G$OF0$$$F$$$^$9!#$3$l$G$_$s$J$O4JC1$JJ}K!$G;d$KO"Mm$r<h\e(B
 \e$B$k$3$H$,$G$-\e(B (\e$BIaDL$K\e(B @kbd{r} \e$B$r2!$9$@$1$G$G$-$k\e(B)\e$B!";d$O\e(B spam \e$B$KHQ$o$5$l$k\e(B
 \e$B$3$H$OA4$/$"$j$^$;$s!#F@!9>uBV$G$9!#;d$N0U8+$H$7$F$O!"\e(B@code{From} \e$B%X%C%@!<\e(B
-\e$B$K56B$$7$FB8:_$7$J$$%I%a%$%s$KAw$i$;$k$N$O%-%?%J%$$G$9!#\e(B
+\e$B$r56B$$7$FB8:_$7$J$$%I%a%$%s$KAw$i$;$k$N$O%-%?%J%$$G$9!#\e(B
+
+@node SpamAssassin
+@subsection SpamAssassin, Vipul's Razor, DCC, etc
+@cindex SpamAssassin
+@cindex Vipul's Razor
+@cindex DCC
+
+Spam \e$B$rHr$1$k$?$a$NA09`$N%R%s%H$,==J,$@$C$?F|!9$O2a$.5n$j$^$7$?!#:#$G$O\e(B
+\e$B<u$1<h$C$?$?$/$5$s$N\e(B spam \e$B$r8:$i$9$?$a$NB?$/$NF;6q$,$"$j$^$9!#$3$N9`$O?7\e(B
+\e$B5lCV$-49$($K$h$C$F$9$0$K;~BeCY$l$K$J$C$F$7$^$&$G$7$g$&$,!"9,$$$J$3$H$K$[\e(B
+\e$B$H$s$I$NF;6q$ON`;w$N%$%s%?!<%U%'!<%9$r;}$C$F$$$^$9!#$3$N9`$ONc$H$7\e(B
+\e$B$F\e(B SpamAssassin \e$B$r;H$C$F$$$^$9$,!"B>$N$[$H$s$I$NF;6q$K$b4JC1$KE,9g$9$k$O\e(B
+\e$B$:$G$9!#\e(B
+
+\e$B$b$7$"$J$?$,;H$&F;6q$,%a!<%k%5!<%P!<$K%$%s%9%H!<%k$5$l$F$$$J$$$J$i$P!"$"\e(B
+\e$B$J$?<+?H$,$=$l$r8F$S=P$9I,MW$,$"$j$^$9!#0J2<$K\e(B @code{:postscript} \e$B%a!<%k\e(B
+\e$B%=!<%9;X<(;R\e(B (@pxref{Mail Source Specifiers}) \e$B$r;H$&>l9g$N9M$(J}$r<($7$^\e(B
+\e$B$9!#\e(B
+
+@lisp
+(setq mail-sources
+      '((file :prescript "formail -bs spamassassin < /var/mail/%u")
+        (pop :user "jrl"
+             :server "pophost" 
+             :postscript "mv %t /tmp/foo; formail -bs spamc < /tmp/foo > %t")))
+@end lisp
+
+\e$B$$$C$?$s%a!<%k$r<u$1$k%9%W!<%k$G!"Nc$($P\e(B spam \e$B$G$"$k$3$H$rI=<($9$k%X%C%@!<\e(B
+\e$B$r%a!<%k$K4^$a$k$h$&$K$7$F!"$=$l$r$U$k$$Mn$H$9=`Hw$r$7$^$9!#;H$&$N$OIaDL\e(B
+\e$B$NJ,3dJ}<0\e(B (@pxref{Splitting Mail}) \e$B$G$9\e(B:
+
+@lisp
+(setq nnmail-split-methods '(("spam"  "^X-Spam-Flag: YES")
+                             ...))
+@end lisp
+
+\e$B$^$?$OFC5iJ,3dJ}<0\e(B (@pxref{Fancy Mail Splitting}) \e$B$G$9\e(B:
+
+@lisp
+(setq nnmail-split-methods 'nnmail-split-fancy
+      nnmail-split-fancy '(| ("X-Spam-Flag" "YES" "spam")
+                             ...))
+@end lisp
+
+\e$B$$$/$i$+$N?M$?$A$O\e(B @code{:prescript} \e$B$r;H$C$F%a!<%k$r$$$m$s$J%W%m%0%i%`\e(B
+\e$B$K%Q%$%W$9$k$3$H$r7y$&$+$b$7$l$^$;$s\e(B (\e$B$b$72?$+$N%W%m%0%i%`$K%P%0$,$"$C$?\e(B
+\e$B$i!"$9$Y$F$N%a!<%k$r<:$C$F$7$^$&$+$b$7$l$^$;$s\e(B)\e$B!#$"$J$?$,$=$l$i$N0l?M$J\e(B
+\e$B$i$P!"JL$N2r$OJ,3d$9$k$H$-$K30It$NF;6q$r8F$V$3$H$G$9!#FC5iJ,3dJ}<0$NNc$G\e(B
+\e$B$9\e(B:
+
+@lisp
+(setq nnmail-split-fancy '(| (: kevin-spamassassin)
+                             ...))
+(defun kevin-spamassassin ()
+  (save-excursion
+    (let ((buf (or (get-buffer " *nnmail incoming*")
+                   (get-buffer " *nnml move*"))))
+      (if (not buf)
+          (progn (message "Oops, cannot find message buffer") nil)
+        (set-buffer buf)
+        (if (eq 1 (call-process-region (point-min) (point-max)
+                                       "spamc" nil nil nil "-c"))
+            "spam")))))
+@end lisp
+
+\e$B0J>e$,$3$l$K4X$9$k$3$H$G$9!#$$$/$D$+$N\e(B spam \e$B$O$I$&$7$F$bAGDL$j$7$F$7$^$&\e(B
+\e$B$N$G!"\e(Bspam \e$B$rFI$`$O$a$K$J$C$?$H$-$K8F$V$?$a$N5$$NMx$$$?4X?t$,M_$7$$$G$7$g\e(B
+\e$B$&!#$3$l$,$=$N5$$NMx$$$?4X?t$G$9\e(B:
+
+@lisp
+ (defun my-gnus-raze-spam ()
+  "Submit SPAM to Vipul's Razor, then mark it as expirable."
+  (interactive)
+  (gnus-summary-show-raw-article)
+  (gnus-summary-save-in-pipe "razor-report -f -d")
+  (gnus-summary-mark-as-expirable 1))
+@end lisp
+
+@node Hashcash
+@subsection Hashcash
+@cindex hashcash
+
+Spam \e$B$H@o$&$?$a$N?7$7$$5;K!$O!"%a%C%;!<%8$rAw?.$9$k:]$K$$$/$P$/$+$NIiC4\e(B
+\e$B$rAw?.<T$K6/$$$^$9!#$3$l$O%$%s%?!<%M%C%HI8=`$N0lIt$G$O$J$$$N$G!"@$3&Cf$N\e(B
+\e$B$9$Y$F$N?M$,$3$N5;K!$r;H$&$3$H$OEv$F$K$G$-$J$$$H$$$&L@$i$+$J7gE@$,$"$j$^\e(B
+\e$B$9$,!">.5,LO$J6&F1BN$G$OLr$KN)$D$G$7$g$&!#\e(B
+
+\e$BA09`$NF;6qN`$,<B:]$K$&$^$/F/$$$?$H$7$F$b!"$=$l$i$O?7$7$$7A<0$N\e(B spam \e$B$,8=\e(B
+\e$B$l$k$?$S$K$7$g$C$A$e$&99?7$+$D@0Hw$5$l$k$3$H$K$h$C$F$N$_F0:n$7$^$9!#$3$N\e(B
+\e$B$3$H$O!">.$5$J%Q!<%;%s%F!<%8$N\e(B spam \e$B$,$$$D$bAGDL$j$7$F$7$^$&$3$H$r0UL#$7\e(B
+\e$B$^$9!#$=$l$O$^$?!"$I$3$+$G$@$l$+$,$=$l$i$NF;6q$r99?7$9$k$?$a$K!"$?$/$5$s\e(B
+\e$B$N\e(B spam \e$B$rFI$^$J$1$l$P$J$i$J$$$3$H$r$b0UL#$7$^$9!#\e(BHashcash \e$B$O$=$l$r2sHr\e(B
+\e$B$7$^$9$,!"Be$o$j$K$"$J$?$,DL?.$9$k$9$Y$F$N?M$?$A$,!"$=$N;EAH$_$r;H$C$F$$\e(B
+\e$B$k$3$H$,I,MW$G$9!#$"$J$?$O<BMQ\e(B (pragmatic) \e$B$H65>r\e(B (dogmatic) \e$B$NFs$D$N<h\e(B
+\e$B$jAH$_$r9M$($k$3$H$,$G$-$^$9!#$=$l$i$N<h$jAH$_$K$OMxE@$b$"$l$PITMx$JE@$b\e(B
+\e$B$"$j$^$9$,!"$=$l$O@$$NCf$G$OIaDL$N$3$H$G!"$=$l$i$rO"78$5$;$?$b$N$,B>$N$P\e(B
+\e$B$i$P$i$J$b$N$h$j6/NO$J$N$G$9!#\e(B
+
+@cindex X-Hashcash
+\e$B!V$$$/$P$/$+$NIiC4!W$H$O\e(B CPU \e$B;~4V$r>CHq$9$k$3$H$G!"6qBNE*$K$O0lDj?t$N%S%C\e(B
+\e$B%H$^$G%O%C%7%e$N>WFM\e(B (hash collision) \e$B$r7W;;$9$k$3$H$G$9!#$=$N7k2L$H$7$F\e(B
+\e$B$N\e(B hashcash \e$B%/%C%-!<$O\e(B @samp{X-Hashcash:} \e$B%X%C%@!<$KA^F~$5$l$^$9!#$b$C$H\e(B
+\e$B>\$7$$$3$H!"$=$7$F$3$N5!G=$r;H$&$?$a$K%$%s%9%H!<%k$9$kI,MW$,$"$k30It%"%W\e(B
+\e$B%j%1!<%7%g%s$N\e(B @code{hashcash} \e$B$K$D$$$F\e(B
+\e$B$O\e(B @uref{http://www.cypherspace.org/~adam/hashcash/} \e$B$r;2>H$7$F2<$5$$!#\e(B
+\e$B$5$i$J$k>pJs$,\e(B @uref{http://www.camram.org/} \e$B$G8+$D$+$k$G$7$g$&!#\e(B
+
+\e$BAw?.$9$k%a%C%;!<%8$N$=$l$>$l$K$D$$$F\e(B hashcash \e$B$r8F$\$&$H;W$&$J$i!"$3$s$J\e(B
+\e$B$U$&$K$7$F2<$5$$\e(B:
+
+@lisp
+(require 'hashcash)
+(add-hook 'message-send-hook 'mail-add-payment)
+@end lisp
+
+@code{hashcash.el} \e$B%i%$%V%i%j\e(B
+\e$B$O\e(B @uref{http://users.actrix.gen.nz/mycroft/hashcash.el} \e$B$+3+H/HG\e(B
+\e$B$N\e(B gnus \e$B$N\e(B contrib \e$B%G%#%l%/%H%j$K$"$j$^$9!#\e(B
+
+\e$B$$$/$D$+$NDI2C$NJQ?t$N@_Dj$b$7$J$1$l$P$J$j$^$;$s\e(B:
+
+@table @code
+@item hashcash-default-payment
+@vindex hashcash-default-payment
+\e$B$3$NJQ?t$O%O%C%7%e$N>WFM$r@.$9%G%#%U%)%k%H$N%S%C%H?t$r<($7$^$9!#5,DjCM\e(B
+\e$B$O\e(B 0 \e$B$G!"2?$b9T$J$o$l$J$$$3$H$r0UL#$7$^$9!#Ds0F$5$l$F$$$kM-8z$JCM\e(B
+\e$B$O\e(B 17 \e$B$+$i\e(B 29 \e$B$^$G$N?t$G$9!#\e(B
+
+@item hashcash-payment-alist
+@vindex hashcash-payment-alist
+\e$B2??M$+$N<u<h?M$O!"$"$J$?$K%G%#%U%)%k%H$h$jB?$/$N\e(B CPU \e$B;~4V$rHq$d$9$3$H$r\e(B
+\e$BMW5a$9$k$+$b$7$l$^$;$s!#$3$NJQ?t$O\e(B @samp{(ADDR AMOUNT)} \e$B$N7A<0$NMWAG$N%j\e(B
+\e$B%9%H$G!"\e(BADDR \e$B$O<u<h?M\e(B (\e$B%a!<%k%"%I%l%9$+%K%e!<%9%0%k!<%W\e(B)\e$B!"\e(BAMOUNT \e$B$OI,MW\e(B
+\e$B$H$5$l$k>WFM$N%S%C%H?t$G$9!#$3$l$O$^$?\e(B @samp{(ADDR STRING AMOUNT)} \e$B$NMW\e(B
+\e$BAG$r;}$D$3$H$b2DG=$G!"\e(BSTRING \e$B$OJ8;zNs\e(B (\e$BDL>o$O%a!<%k%"%I%l%9$+%K%e!<%9%0\e(B
+\e$B%k!<%WL>\e(B) \e$B$H$7$F;H$o$l$^$9!#\e(B
+
+@item hashcash
+@vindex hashcash
+@code{hashcash} \e$B%P%$%J%j$,%$%s%9%H!<%k$5$l$F$$$k>l=j$r<($7$^$9!#\e(B
+@end table
+
+\e$B:#$N$H$3$m\e(B gnus \e$B$K\e(B hashcash \e$B%/%C%-!<$rG'>Z$9$k<jCJ$O$"$j$^$;$s!#$"$J$?$,\e(B
+\e$B<j:n6H$G%a!<%k$r$U$k$$$K$+$1$k%9%/%j%W%H$r%+%9%?%^%$%:$9$k$3$H$,5a$a$i$l\e(B
+\e$B$F$$$^$9!#$7$+$7!"$3$NJ,Ln$K$*$1$k2~NI$OM-MQ$J9W8%$K$J$k$G$7$g$&!#\e(B
 
 @node Various Various
 @section \e$B$$$m$$$m$N$$$m$$$m\e(B
@@ -21745,7 +21998,7 @@ Gnus 5.8 \e$B$N?7$7$$5!G=\e(B:
 @lisp
 (setq mail-sources
       '((directory :path "~/mail/incoming/"
-                  :suffix ".in")))
+                   :suffix ".in")))
 @end lisp
 
 \e$B$b$C$H>\$7$$>pJs$O\e(B info \e$B$N\e(B Select Methods -> Getting Mail -> Mail
index f0d7274..818500e 100644 (file)
@@ -33,7 +33,7 @@
 \makeindex
 \begin{document}
 
-\newcommand{\gnusversionname}{Oort Gnus v0.06}
+\newcommand{\gnusversionname}{Oort Gnus v0.07}
 \newcommand{\gnuschaptername}{}
 \newcommand{\gnussectionname}{}
 
@@ -848,6 +848,12 @@ Picons
 * Hard Picons::                 The way you should do it.  You'll learn something.
 * Picon Useless Configuration::  Other variables you can trash/tweak/munge/play with.
 
+Thwarting Email Spam
+
+* Anti-Spam Basics::            Simple steps to reduce the amount of spam.
+* SpamAssassin::                How to use external anti-spam tools.
+* Hashcash::                    Reduce spam by burning CPU time.
+
 Appendices
 
 * XEmacs::                      Requirements for installing under XEmacs.
@@ -1883,15 +1889,15 @@ background is dark:
 (cond (window-system
        (setq custom-background-mode 'light)
        (defface my-group-face-1
-        '((t (:foreground "Red" :bold t))) "First group face")
+         '((t (:foreground "Red" :bold t))) "First group face")
        (defface my-group-face-2
-        '((t (:foreground "DarkSeaGreen4" :bold t))) "Second group face")
+         '((t (:foreground "DarkSeaGreen4" :bold t))) "Second group face")
        (defface my-group-face-3
-        '((t (:foreground "Green4" :bold t))) "Third group face")
+         '((t (:foreground "Green4" :bold t))) "Third group face")
        (defface my-group-face-4
-        '((t (:foreground "SteelBlue" :bold t))) "Fourth group face")
+         '((t (:foreground "SteelBlue" :bold t))) "Fourth group face")
        (defface my-group-face-5
-        '((t (:foreground "Blue" :bold t))) "Fifth group face")))
+         '((t (:foreground "Blue" :bold t))) "Fifth group face")))
 
 (setq gnus-group-highlight
       '(((> unread 200) . my-group-face-1)
@@ -2566,20 +2572,19 @@ Create one of the groups mentioned in @code{gnus-useful-groups}
 @item G w
 @kindex G w (Group)
 @findex gnus-group-make-web-group
-@cindex DejaNews
-@cindex Alta Vista
-@cindex InReference
+@cindex Google
 @cindex nnweb
+@cindex gmane
 Make an ephemeral group based on a web search
 (@code{gnus-group-make-web-group}).  If you give a prefix to this
 command, make a solid group instead.  You will be prompted for the
 search engine type and the search string.  Valid search engine types
-include @code{dejanews}, @code{altavista} and @code{reference}.
+include @code{google}, @code{dejanews}, and @code{gmane}.
 @xref{Web Searches}.
 
-If you use the @code{dejanews} search engine, you can limit the search
+If you use the @code{google} search engine, you can limit the search
 to a particular group by using a match string like
-@samp{~g alt.sysadmin.recovery shaving}.
+@samp{shaving group:alt.sysadmin.recovery}.
 
 @item G DEL
 @kindex G DEL (Group)
@@ -4235,8 +4240,8 @@ the line containing the call to @code{stop} is removed.)
 
 @example
 if address "sender" "owner-ding@@hpc.uh.edu" @{
-       fileinto "INBOX.ding";
-       stop;
+        fileinto "INBOX.ding";
+        stop;
 @}
 @end example
 
@@ -4393,8 +4398,8 @@ Full @code{From} header.
 @item n
 The name (from the @code{From} header).
 @item f
-The name, code @code{To} header or the @code{Newsgroups} header
-(@pxref{To From Newsgroups}).
+The name, @code{To} header or the @code{Newsgroups} header (@pxref{To
+From Newsgroups}).
 @item a
 The name (from the @code{From} header).  This differs from the @code{n}
 spec in that it uses the function designated by the
@@ -4545,7 +4550,8 @@ headers are used instead.
 A related variable is @code{nnmail-extra-headers}, which controls when
 to include extra headers when generating overview (@sc{nov}) files.  If
 you have old overview files, you should regenerate them after changing
-this variable.
+this variable, by entering the server buffer using `^', and then `g' on
+the appropriate mail server (e.g. nnml) to cause regeneration.
 
 @vindex gnus-summary-line-format
 You also have to instruct Gnus to display the data by changing the
@@ -4568,9 +4574,13 @@ In summary, you'd typically put something like the following in
 (The values listed above are the default values in Gnus.  Alter them
 to fit your needs.)
 
-Now, this is mostly useful for mail groups, where you have control over
+A note for news server administrators, or for users who wish to try to
+convince their news server administrator to provide some additional
+support:
+
+The above is mostly useful for mail groups, where you have control over
 the @sc{nov} files that are created.  However, if you can persuade your
-nntp admin to add:
+nntp admin to add (in the usual implementation, notably INN):
 
 @example
 Newsgroups:full
@@ -5055,6 +5065,13 @@ that goes out to all people listed in the @code{To}, @code{From} (or
 @code{Reply-to}) and @code{Cc} headers in all the process/prefixed
 articles.  This command uses the process/prefix convention.
 
+@item S V
+@kindex S V (Summary)
+@findex gnus-summary-very-wide-reply-with-original
+Mail a very wide reply to the author of the current article and include the
+original message (@code{gnus-summary-very-wide-reply-with-original}).  This
+command uses the process/prefix convention.
+
 @item S o m
 @itemx C-c C-f
 @kindex S o m (Summary)
@@ -6275,6 +6292,10 @@ Simplify fuzzily.
 @item gnus-simplify-whitespace
 @findex gnus-simplify-whitespace
 Remove excessive whitespace.
+
+@item gnus-simplify-all-whitespace
+@findex gnus-simplify-all-whitespace
+Remove all whitespace.
 @end table
 
 You may also write your own functions, of course.
@@ -6628,6 +6649,7 @@ Matching}).
 @findex gnus-thread-sort-by-subject
 @findex gnus-thread-sort-by-author
 @findex gnus-thread-sort-by-number
+@findex gnus-thread-sort-by-random
 @vindex gnus-thread-sort-functions
 @findex gnus-thread-sort-by-most-recent-thread
 If you are using a threaded summary display, you can sort the threads by
@@ -6640,7 +6662,8 @@ predicate functions include @code{gnus-thread-sort-by-number},
 @code{gnus-thread-sort-by-author}, @code{gnus-thread-sort-by-subject},
 @code{gnus-thread-sort-by-date}, @code{gnus-thread-sort-by-score},
 @code{gnus-thread-sort-by-most-recent-number},
-@code{gnus-thread-sort-by-most-recent-date} and
+@code{gnus-thread-sort-by-most-recent-date},
+@code{gnus-thread-sort-by-random} and
 @code{gnus-thread-sort-by-total-score}.
 
 Each function takes two threads and returns non-@code{nil} if the first
@@ -6691,14 +6714,18 @@ tickles your fancy.
 @findex gnus-article-sort-by-score
 @findex gnus-article-sort-by-subject
 @findex gnus-article-sort-by-author
+@findex gnus-article-sort-by-random
 @findex gnus-article-sort-by-number
-If you are using an unthreaded display for some strange reason or other,
-you have to fiddle with the @code{gnus-article-sort-functions} variable.
-It is very similar to the @code{gnus-thread-sort-functions}, except that
-it uses slightly different functions for article comparison.  Available
-sorting predicate functions are @code{gnus-article-sort-by-number},
-@code{gnus-article-sort-by-author}, @code{gnus-article-sort-by-subject},
-@code{gnus-article-sort-by-date}, and @code{gnus-article-sort-by-score}.
+If you are using an unthreaded display for some strange reason or
+other, you have to fiddle with the @code{gnus-article-sort-functions}
+variable.  It is very similar to the
+@code{gnus-thread-sort-functions}, except that it uses slightly
+different functions for article comparison.  Available sorting
+predicate functions are @code{gnus-article-sort-by-number},
+@code{gnus-article-sort-by-author},
+@code{gnus-article-sort-by-subject}, @code{gnus-article-sort-by-date},
+@code{gnus-article-sort-by-random}, and
+@code{gnus-article-sort-by-score}.
 
 If you want to sort an unthreaded summary display by subject, you could
 say something like:
@@ -7861,8 +7888,8 @@ headers, PGP, cited text and the signature.
 
 @item W W h
 @kindex W W h (Summary)
-@findex gnus-article-toggle-headers
-Toggle hiding of headers (@code{gnus-article-toggle-headers}).  @xref{Hiding
+@findex gnus-article-hide-headers
+Hide headers (@code{gnus-article-hide-headers}).  @xref{Hiding
 Headers}.
 
 @item W W b
@@ -8067,9 +8094,9 @@ is rumored to have employed this form of, uh, somewhat weak encryption.
 @item t
 @kindex W t (Summary)
 @kindex t (Summary)
-@findex gnus-article-toggle-headers
+@findex gnus-summary-toggle-header
 Toggle whether to display all headers in the article buffer
-(@code{gnus-article-toggle-headers}).
+(@code{gnus-summary-toggle-header}).
 
 @item W v
 @kindex W v (Summary)
@@ -8966,6 +8993,11 @@ Sort by article length (@code{gnus-summary-sort-by-chars}).
 @findex gnus-summary-sort-by-score
 Sort by score (@code{gnus-summary-sort-by-score}).
 
+@item C-c C-s C-r
+@kindex C-c C-s C-r (Summary)
+@findex gnus-summary-sort-by-random
+Randomize (@code{gnus-summary-sort-by-random}).
+
 @item C-c C-s C-o
 @kindex C-c C-s C-o (Summary)
 @findex gnus-summary-sort-by-original
@@ -9061,12 +9093,12 @@ is a list, Gnus will try all the methods in the list until it finds a
 match.
 
 Here's an example setting that will first try the current method, and
-then ask Deja if that fails:
+then ask Google if that fails:
 
 @lisp
 (setq gnus-refer-article-method
       '(current
-        (nnweb "refer" (nnweb-type dejanews))))
+        (nnweb "refer" (nnweb-type google))))
 @end lisp
 
 Most of the mail back ends support fetching by @code{Message-ID}, but
@@ -9571,7 +9603,7 @@ buffers. For example:
 (setq gnus-newsgroup-variables
      '(message-use-followup-to
        (gnus-visible-headers .
-        "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^To:")))
+         "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^To:")))
 @end lisp
 
 @end table
@@ -10639,6 +10671,12 @@ headers will be included in the sequence they are matched.
 If non-@code{nil}, add a @code{to-list} group parameter to mail groups
 that have none when you do a @kbd{a}.
 
+@item gnus-confirm-mail-reply-to-news
+@vindex gnus-confirm-mail-reply-to-news
+If non-@code{nil}, Gnus requests confirmation when replying to news.
+If you find yourself never wanting to reply to mail, but occasionally
+press R anyway, this variable might be for you.
+
 @end table
 
 
@@ -11007,7 +11045,7 @@ So here's a new example:
         (window-system         ;; A value symbol
          ("X-Window-System" (format "%s" window-system)))
         ;; If I'm replying to Larsi, set the Organization header.
-        ((header "to" "larsi.*org")
+        ((header "from" "larsi.*org")
          (Organization "Somewhere, Inc."))
         ((posting-from-work-p) ;; A user defined function
          (signature-file "~/.work-signature")
@@ -11133,6 +11171,14 @@ For PGP, Gnus supports two external libraries, @sc{gpg.el} and
 @sc{Mailcrypt}, you need to install at least one of them.  The
 @sc{s/mime} support in Gnus requires the external program OpenSSL.
 
+Often, you would like to sign replies to people who send you signed
+messages.  Even more often, you might want to encrypt messages which
+are in reply to encrypted messages.  Gnus offers
+@code{gnus-message-replysign} to enable the former, and
+@code{gnus-message-replyencrypt} for the latter.  In addition, setting
+@code{gnus-message-replysignencrypted} (on by default) will sign
+automatically encrypted messages.
+
 Instructing MML to perform security operations on a @sc{mime} part is
 done using the @kbd{C-c C-m s} key map for signing and the @kbd{C-c
 C-m c} key map for encryption, as follows.
@@ -11141,39 +11187,39 @@ C-m c} key map for encryption, as follows.
 
 @item C-c C-m s s
 @kindex C-c C-m s s
-@findex mml-secure-sign-smime
+@findex mml-secure-message-sign-smime
 
-Digitally sign current @sc{mime} part using @sc{s/mime}.
+Digitally sign current message using @sc{s/mime}.
 
 @item C-c C-m s o
 @kindex C-c C-m s o
-@findex mml-secure-sign-pgp
+@findex mml-secure-message-sign-pgp
 
-Digitally sign current @sc{mime} part using PGP.
+Digitally sign current message using PGP.
 
 @item C-c C-m s p
 @kindex C-c C-m s p
-@findex mml-secure-sign-pgp
+@findex mml-secure-message-sign-pgp
 
-Digitally sign current @sc{mime} part using @sc{pgp/mime}.
+Digitally sign current message using @sc{pgp/mime}.
 
 @item C-c C-m c s
 @kindex C-c C-m c s
-@findex mml-secure-encrypt-smime
+@findex mml-secure-message-encrypt-smime
 
-Digitally encrypt current @sc{mime} part using @sc{s/mime}.
+Digitally encrypt current message using @sc{s/mime}.
 
 @item C-c C-m c o
 @kindex C-c C-m c o
-@findex mml-secure-encrypt-pgp
+@findex mml-secure-message-encrypt-pgp
 
-Digitally encrypt current @sc{mime} part using PGP.
+Digitally encrypt current message using PGP.
 
 @item C-c C-m c p
 @kindex C-c C-m c p
-@findex mml-secure-encrypt-pgpmime
+@findex mml-secure-message-encrypt-pgpmime
 
-Digitally encrypt current @sc{mime} part using @sc{pgp/mime}.
+Digitally encrypt current message using @sc{pgp/mime}.
 
 @item C-c C-m C-n
 @kindex C-c C-m C-n
@@ -11448,6 +11494,8 @@ configuration to the example above:
       (nntp-via-rlogin-command "ssh")
 @end lisp
 
+See also @code{nntp-via-rlogin-command-switches}.
+
 If you're behind a firewall, but have direct access to the outside world
 through a wrapper command like "runsocks", you could open a socksified
 telnet connection to the news server as follows:
@@ -11990,6 +12038,15 @@ you need to connect to a firewall machine first.
 @vindex nntp-via-rlogin-command
 Command used to log in on the intermediate host.  The default is
 @samp{rsh}, but @samp{ssh} is a popular alternative.
+
+@item nntp-via-rlogin-command-switches
+@vindex nntp-via-rlogin-command-switches
+List of strings to be used as the switches to
+@code{nntp-via-rlogin-command}.  The default is @code{nil}.  If you use
+@samp{ssh} for `nntp-via-rlogin-command', you may set this to
+@samp{("-C")} in order to compress all data connections, otherwise set
+this to @samp{("-t")} or @samp{("-C" "-t")} if the telnet command
+requires a pseudo-tty allocation on an intermediate host.
 @end table
 
 @item nntp-open-via-telnet-and-telnet
@@ -12371,6 +12428,15 @@ Header lines longer than the value of
 @code{nnmail-split-header-length-limit} are excluded from the split
 function.
 
+@vindex nnmail-mail-splitting-charset
+@vindex nnmail-mail-splitting-decodes
+By default the splitting codes MIME decodes headers so you can match
+on non-ASCII strings.  The @code{nnmail-mail-splitting-charset}
+variable specifies the default charset for decoding.  The behaviour
+can be turned off completely by binding
+@code{nnmail-mail-splitting-decodes} to nil, which is useful if you
+want to match articles based on the raw header data.
+
 Gnus gives you all the opportunity you could possibly want for shooting
 yourself in the foot.  Let's say you create a group that will contain
 all the mail you get from your boss.  And then you accidentally
@@ -12770,15 +12836,12 @@ An example @sc{imap} mail source:
 @item webmail
 Get mail from a webmail server, such as @uref{www.hotmail.com},
 @uref{webmail.netscape.com}, @uref{www.netaddress.com},
-@uref{www.my-deja.com}.
-
-NOTE: Now @uref{mail.yahoo.com} provides POP3 service, so @sc{pop} mail source
-is suggested.
+@uref{mail.yahoo..com}.
 
 NOTE: Webmail largely depends cookies. A "one-line-cookie" patch is
 required for url "4.0pre.46".
 
-WARNING: Mails may lost.  NO WARRANTY.
+WARNING: Mails may be lost.  NO WARRANTY.
 
 Keywords:
 
@@ -13005,6 +13068,16 @@ If non-@code{nil}, put the @code{Message-ID}s of articles imported into
 the back end (via @code{Gcc}, for instance) into the mail duplication
 discovery cache.  The default is @code{nil}.
 
+@item nnmail-cache-ignore-groups
+@vindex nnmail-cache-ignore-groups
+This can be a regular expression or a list of regular expressions.
+Group names that match any of the regular expressions will never be
+recorded in the @code{Message-ID} cache.
+
+This can be useful, for example, when using Fancy Splitting
+(@pxref{Fancy Mail Splitting}) together with the function
+@code{nnmail-split-fancy-with-parent}.
+
 @end table
 
 
@@ -13164,7 +13237,9 @@ To use this feature, you have to set @code{nnmail-treat-duplicates} and
 you can include @code{nnmail-split-fancy-with-parent} using the colon
 feature, like so:
 @lisp
-(setq nnmail-split-fancy
+(setq nnmail-treat-duplicates 'warn     ; or 'delete
+      nnmail-cache-accepted-message-ids t
+      nnmail-split-fancy
       '(| (: nnmail-split-fancy-with-parent)
           ;; other splits go here
         ))
@@ -13189,6 +13264,13 @@ When @code{nnmail-cache-accepted-message-ids} is non-@code{nil}, Gnus
 also records the message ids of moved articles, so that the followup
 messages goes into the new group.
 
+Also see the variable @code{nnmail-cache-ignore-groups} if you don't
+want certain groups to be recorded in the cache.  For example, if all
+outgoing messages are written to an `outgoing' group, you could set
+@code{nnmail-cache-ignore-groups} to match that group name.
+Otherwise, answers to all your messages would end up in the
+`outgoing' group.
+
 
 @node Group Mail Splitting
 @subsection Group Mail Splitting
@@ -13502,7 +13584,7 @@ expire mail to groups according to the variable
  (setq nnmail-expiry-target 'nnmail-fancy-expiry-target
        nnmail-fancy-expiry-targets
        '((to-from "boss" "nnfolder:Work")
-        ("subject" "IMPORTANT" "nnfolder:IMPORTANT.%Y.%b")
+         ("subject" "IMPORTANT" "nnfolder:IMPORTANT.%Y.%b")
          ("from" ".*" "nnfolder:Archive-%Y")))
 @end lisp
 
@@ -13590,6 +13672,12 @@ cleaning up the headers.  Functions that can be used include:
 Clear leading white space that ``helpful'' listservs have added to the
 headers to make them look nice.  Aaah.
 
+(Note that this function works on both the header on the body of all
+messages, so it is a potentially dangerous function to use (if a body
+of a message contains something that looks like a header line).  So
+rather than fix the bug, it is of course the right solution to make it
+into a feature by documenting it.)
+
 @item nnmail-remove-list-identifiers
 @findex nnmail-remove-list-identifiers
 Some list servers add an identifier---for example, @samp{(idm)}---to the
@@ -14325,9 +14413,9 @@ is unnecessary in that case.
 @node Web Searches
 @subsection Web Searches
 @cindex nnweb
-@cindex DejaNews
-@cindex Alta Vista
-@cindex InReference
+@cindex Google
+@cindex dejanews
+@cindex gmane
 @cindex Usenet searches
 @cindex searching the Usenet
 
@@ -14350,7 +14438,7 @@ pattern), you are likely to get the articles ordered in a different
 manner.  Not even using duplicate suppression (@pxref{Duplicate
 Suppression}) will help, since @code{nnweb} doesn't even know the
 @code{Message-ID} of the articles before reading them using some search
-engines (DejaNews, for instance).  The only possible way to keep track
+engines (Google, for instance).  The only possible way to keep track
 of which articles you've read is by scoring on the @code{Date}
 header---mark all articles posted before the last date you read the
 group as read.
@@ -14371,8 +14459,8 @@ Virtual server variables:
 @item nnweb-type
 @vindex nnweb-type
 What search engine type is being used.  The currently supported types
-are @code{dejanews}, @code{dejanewsold}, @code{altavista} and
-@code{reference}.
+are @code{google}, @code{dejanews}, and @code{gmane}. Note that
+@code{dejanews} is an alias to @code{google}.
 
 @item nnweb-search
 @vindex nnweb-search
@@ -14381,7 +14469,7 @@ The search string to feed to the search engine.
 @item nnweb-max-hits
 @vindex nnweb-max-hits
 Advisory maximum number of hits per search to display.  The default is
-100.
+999.
 
 @item nnweb-type-definition
 @vindex nnweb-type-definition
@@ -14598,7 +14686,7 @@ the summary buffer.
 
 (defun gnus-user-format-function-X (header)
   (let ((descr
-        (assq nnrss-description-field (mail-header-extra header))))
+         (assq nnrss-description-field (mail-header-extra header))))
     (if descr (concat "\n\t" (cdr descr)) "")))
 @end lisp
 
@@ -14854,7 +14942,7 @@ Unlike Parmenides the @sc{imap} designers has decided that things that
 doesn't exist actually does exist.  More specifically, @sc{imap} has
 this concept of marking articles @code{Deleted} which doesn't actually
 delete them, and this (marking them @code{Deleted}, that is) is what
-nnimap does when you delete a article in Gnus (with @kbd{G DEL} or
+nnimap does when you delete a article in Gnus (with @kbd{B DEL} or
 similar).
 
 Since the articles aren't really removed when we mark them with the
@@ -14886,11 +14974,12 @@ articles or not.
 @item nnimap-importantize-dormant
 @vindex nnimap-importantize-dormant
 
-If non-nil, marks dormant articles as ticked (as well), for other
-@sc{imap} clients. Within Gnus, dormant articles will naturally still
-(only) be marked as ticked.  This is to make dormant articles stand
-out, just like ticked articles, in other @sc{imap} clients. (In other
-words, Gnus has two ``Tick'' marks and @sc{imap} has only one.)
+If non-nil (the default), marks dormant articles as ticked (as well),
+for other @sc{imap} clients. Within Gnus, dormant articles will
+naturally still (only) be marked as dormant.  This is to make dormant
+articles stand out, just like ticked articles, in other @sc{imap}
+clients. (In other words, Gnus has two ``Tick'' marks and @sc{imap}
+has only one.)
 
 Probably the only reason for frobing this would be if you're trying
 enable per-user persistant dormant flags, using something like:
@@ -15815,7 +15904,7 @@ For instance, an article with this @code{Newsgroups} header:
 Newsgroups: alt.religion.emacs
 @end example
 
-will get this @code{From} header inserted:
+will get this @code{To} header inserted:
 
 @example
 To: alt-religion-emacs@@GATEWAY
@@ -16282,7 +16371,7 @@ wherever.
 (require 'gnus-agent)
 (setq  gnus-category-predicate-alist
   (append gnus-category-predicate-alist
-        '((old . my-article-old-p))))
+         '((old . my-article-old-p))))
 @end lisp
 
 and simply specify your predicate as:
@@ -20609,7 +20698,20 @@ and one mail asking me to repent and find some god.
 
 This is annoying.
 
-The way to deal with this is having Gnus split out all spam into a
+@menu
+* Anti-Spam Basics::            Simple steps to reduce the amount of spam.
+* SpamAssassin::                How to use external anti-spam tools.
+* Hashcash::                    Reduce spam by burning CPU time.
+@end menu
+
+@node Anti-Spam Basics
+@subsection Anti-Spam Basics
+@cindex email spam
+@cindex spam
+@cindex UCE
+@cindex unsolicited commercial email
+
+One way of dealing with spam is having Gnus split out all spam into a
 @samp{spam} mail group (@pxref{Splitting Mail}).
 
 First, pick one (1) valid mail address that you can be reached at, and
@@ -20675,6 +20777,156 @@ spam.  It's a win-win situation.  Forging @code{From} headers to point
 to non-existent domains is yucky, in my opinion.
 
 
+
+@node SpamAssassin
+@subsection SpamAssassin, Vipul's Razor, DCC, etc
+@cindex SpamAssassin
+@cindex Vipul's Razor
+@cindex DCC
+
+The days where the hints in the previous section was sufficient in
+avoiding spam is coming to an end.  There are many tools out there
+that claim to reduce the amount of spam you get.  This section could
+easily become outdated fast, as new products replace old, but
+fortunately most of these tools seem to have similar interfaces.  Even
+though this section will use SpamAssassin as an example, it should be
+easy to adapt it to most other tools.
+
+If the tool you are using is not installed on the mail server, you
+need to invoke it yourself.  Ideas on how to use the
+@code{:postscript} mail source parameter (@pxref{Mail Source
+Specifiers}) follows.
+
+@lisp
+(setq mail-sources
+      '((file :prescript "formail -bs spamassassin < /var/mail/%u")
+        (pop :user "jrl"
+             :server "pophost" 
+             :postscript "mv %t /tmp/foo; formail -bs spamc < /tmp/foo > %t")))
+@end lisp
+
+Once you managed to process your incoming spool somehow, thus making
+the mail contain e.g. a header indicating it is spam, you are ready to
+filter it out.  Using normal split methods (@pxref{Splitting Mail}):
+
+@lisp
+(setq nnmail-split-methods '(("spam"  "^X-Spam-Flag: YES")
+                             ...))
+@end lisp
+
+Or using fancy split methods (@pxref{Fancy Mail Splitting}):
+
+@lisp
+(setq nnmail-split-methods 'nnmail-split-fancy
+      nnmail-split-fancy '(| ("X-Spam-Flag" "YES" "spam")
+                             ...))
+@end lisp
+
+Some people might not like the idea of piping the mail through various
+programs using a @code{:prescript} (if some program is buggy, you
+might lose all mail).  If you are one of them, another solution is to
+call the external tools during splitting.  Example fancy split method:
+
+@lisp
+(setq nnmail-split-fancy '(| (: kevin-spamassassin)
+                             ...))
+(defun kevin-spamassassin ()
+  (save-excursion
+    (let ((buf (or (get-buffer " *nnmail incoming*")
+                   (get-buffer " *nnml move*"))))
+      (if (not buf)
+          (progn (message "Oops, cannot find message buffer") nil)
+        (set-buffer buf)
+        (if (eq 1 (call-process-region (point-min) (point-max)
+                                       "spamc" nil nil nil "-c"))
+            "spam")))))
+@end lisp
+
+That is about it.  As some spam is likely to get through anyway, you
+might want to have a nifty function to call when you happen to read
+spam.  And here is the nifty function:
+
+@lisp
+ (defun my-gnus-raze-spam ()
+  "Submit SPAM to Vipul's Razor, then mark it as expirable."
+  (interactive)
+  (gnus-summary-show-raw-article)
+  (gnus-summary-save-in-pipe "razor-report -f -d")
+  (gnus-summary-mark-as-expirable 1))
+@end lisp
+
+@node Hashcash
+@subsection Hashcash
+@cindex hashcash
+
+A novel technique to fight spam is to require senders to do something
+costly for each message they send.  This has the obvious drawback that
+you cannot rely on that everyone in the world uses this technique,
+since it is not part of the internet standards, but it may be useful
+in smaller communities.
+
+While the tools in the previous section work well in practice, they
+work only because the tools are constantly maintained and updated as
+new form of spam appears.  This means that a small percentage of spam
+will always get through.  It also means that somewhere, someone needs
+to read lots of spam to update these tools.  Hashcash avoids that, but
+instead requires that everyone you communicate with supports the
+scheme.  You can view the two approaches as pragmatic vs dogmatic.
+The approaches have their own advantages and disadvantages, but as
+often in the real world, a combination of them is stronger than either
+one of them separately.
+
+@cindex X-Hashcash
+The ``something costly'' is to burn CPU time, more specifically to
+compute a hash collision up to a certain number of bits.  The
+resulting hashcash cookie is inserted in a @samp{X-Hashcash:}
+header. For more details, and for the external application
+@code{hashcash} you need to install to use this feature, see
+@uref{http://www.cypherspace.org/~adam/hashcash/}.  Even more
+information can be found at @uref{http://www.camram.org/}.
+
+If you wish to call hashcash for each message you send, say something
+like:
+
+@lisp
+(require 'hashcash)
+(add-hook 'message-send-hook 'mail-add-payment)
+@end lisp
+
+The @code{hashcash.el} library can be found at
+@uref{http://users.actrix.gen.nz/mycroft/hashcash.el}, or in the Gnus
+development contrib directory.
+
+You will need to set up some additional variables as well:
+
+@table @code
+
+@item hashcash-default-payment
+@vindex hashcash-default-payment
+This variable indicates the default number of bits the hash collision
+should consist of.  By default this is 0, meaning nothing will be
+done.  Suggested useful values include 17 to 29.
+
+@item hashcash-payment-alist
+@vindex hashcash-payment-alist
+Some receivers may require you to spend burn more CPU time than the
+default.  This variable contains a list of @samp{(ADDR AMOUNT)} cells,
+where ADDR is the receiver (email address or newsgroup) and AMOUNT is
+the number of bits in the collision that is needed.  It can also
+contain @samp{(ADDR STRING AMOUNT)} cells, where the STRING is the
+string to use (normally the email address or newsgroup name is used).
+
+@item hashcash
+@vindex hashcash
+Where the @code{hashcash} binary is installed.
+
+@end table
+
+Currently there is no built in functionality in Gnus to verify
+hashcash cookies, it is expected that this is performed by your hand
+customized mail filtering scripts.  Improvements in this area would be
+a useful contribution, however.
+
 @node Various Various
 @section Various Various
 @cindex mode lines
@@ -22184,7 +22436,7 @@ this now has changed to
 @lisp
 (setq mail-sources
       '((directory :path "~/mail/incoming/"
-                  :suffix ".in")))
+                   :suffix ".in")))
 @end lisp
 
 More information is available in the info doc at Select Methods ->
index d17fe3a..1a41171 100644 (file)
@@ -788,6 +788,19 @@ a multipart tag will be used; if no other parts are present in your
 message a single part tag will be used.  This way, message mode will
 do the Right Thing (TM) with signed/encrypted multipart messages.
 
+By default, when encrypting a message, Gnus will use the "signencrypt"
+mode.  If you would like to disable this for a particular message,
+give the mml-secure-message-encrypt-* command a prefix argument. (for
+example, C-u C-c C-m c p).  Additionally, by default Gnus will
+separately sign, then encrypt a message which has the mode
+signencrypt.  If you would like to change this behavior use the
+@code{mml-signencrypt-style} function.  For example
+
+@code{(mml-signencrypt-style "pgpmime" 'combined)}
+
+Will cause Gnus to sign and encrypt in one pass, thus generating a
+single signed and encrypted part.
+
 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
@@ -1359,6 +1372,14 @@ Message \e$B$O\e(B @code{system-name} \e$B$r%7%9%F%`L>$r7h$a$k$?$a$K;H$$$^$9!#$b$7$
 \e$B$b$7%j%9%H$,\e(B cons \e$B$N\e(B car \e$B$,\e(B @code{optional} \e$B$G$"$k\e(B cons \e$B$r4^$s$G$$$k$J$i!"\e(B
 \e$B$3$N\e(B cons \e$B$N\e(B cdr \e$B$O\e(B @code{nil} \e$B$G$J$$$H$-$@$1A^F~$5$l$^$9!#\e(B
 
+\e$B$3$N%j%9%H$+$i$"$k9`L\$r>C$7$?$$$J$i$P!"0J2<$N\e(B Lisp \e$B$N@Z$lC<$,Lr$KN)$D$G\e(B
+\e$B$7$g$&!#B>$NMWAG$r:o=|$7$?$$$H$-$O$=$l$K9g$o$;$F2<$5$$!#\e(B
+
+@lisp
+(setq message-required-news-headers
+      (delq 'Message-ID message-required-news-headers))
+@end lisp
+
 \e$B=P$F9T$/%K%e!<%95-;v$r%+%9%?%^%$%:$9$k$?$a$NB>$NJQ?t\e(B:
 
 @table @code
index 3bca7a5..516ecdf 100644 (file)
@@ -776,6 +776,19 @@ a multipart tag will be used; if no other parts are present in your
 message a single part tag will be used.  This way, message mode will
 do the Right Thing (TM) with signed/encrypted multipart messages.
 
+By default, when encrypting a message, Gnus will use the "signencrypt"
+mode.  If you would like to disable this for a particular message,
+give the mml-secure-message-encrypt-* command a prefix argument. (for
+example, C-u C-c C-m c p).  Additionally, by default Gnus will
+separately sign, then encrypt a message which has the mode
+signencrypt.  If you would like to change this behavior use the
+@code{mml-signencrypt-style} function.  For example
+
+@code{(mml-signencrypt-style "pgpmime" 'combined)}
+
+Will cause Gnus to sign and encrypt in one pass, thus generating a
+single signed and encrypted part.
+
 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
@@ -1366,6 +1379,15 @@ If the list contains a cons where the car of the cons is
 @code{optional}, the cdr of this cons will only be inserted if it is
 non-@code{nil}.
 
+If you want to delete an entry from this list, the following Lisp
+snippet might be useful.  Adjust accordingly if you want to remove
+another element.
+
+@lisp
+(setq message-required-news-headers
+      (delq 'Message-ID message-required-news-headers))
+@end lisp
+
 Other variables for customizing outgoing news articles:
 
 @table @code
index a2bfd7e..99be2da 100644 (file)
@@ -129,7 +129,7 @@ runs the hook @code{sieve-mode-hook}.
 @vindex sieve-mode-syntax-table
 Sieve mode is derived from @code{c-mode}, and is very similar except
 for the syntax of comments.  The keymap (@code{sieve-mode-map}) is
-inherited from @code{c-mode}, as are the the variables for customizing
+inherited from @code{c-mode}, as are the variables for customizing
 indentation.  Sieve mode has its own abbrev table
 (@code{sieve-mode-abbrev-table}) and syntax table
 (@code{sieve-mode-syntax-table}).