+@lisp
+(gnus-demon-scan-pgp 60 t)
+@end lisp
+
+This @var{time} parameter and that @var{idle} parameter work together
+in a strange, but wonderful fashion. Basically, if @var{idle} is
+@code{nil}, then the function will be called every @var{time} minutes.
+
+If @var{idle} is @code{t}, then the function will be called after
+@var{time} minutes only if Emacs is idle. So if Emacs is never idle,
+the function will never be called. But once Emacs goes idle, the
+function will be called every @var{time} minutes.
+
+If @var{idle} is a number and @var{time} is a number, the function will
+be called every @var{time} minutes only when Emacs has been idle for
+@var{idle} minutes.
+
+If @var{idle} is a number and @var{time} is @code{nil}, the function
+will be called once every time Emacs has been idle for @var{idle}
+minutes.
+
+And if @var{time} is a string, it should look like @samp{07:31}, and
+the function will then be called once every day somewhere near that
+time. Modified by the @var{idle} parameter, of course.
+
+@vindex gnus-demon-timestep
+(When I say ``minute'' here, I really mean @code{gnus-demon-timestep}
+seconds. This is 60 by default. If you change that variable,
+all the timings in the handlers will be affected.)
+
+So, if you want to add a handler, you could put something like this in
+your @file{~/.gnus.el} file:
+
+@findex gnus-demon-add-handler
+@lisp
+(gnus-demon-add-handler 'gnus-demon-close-connections 30 t)
+@end lisp
+
+@findex gnus-demon-add-nocem
+@findex gnus-demon-add-scanmail
+@findex gnus-demon-add-rescan
+@findex gnus-demon-add-scan-timestamps
+@findex gnus-demon-add-disconnection
+Some ready-made functions to do this have been created:
+@code{gnus-demon-add-nocem}, @code{gnus-demon-add-disconnection},
+@code{gnus-demon-add-nntp-close-connection},
+@code{gnus-demon-add-scan-timestamps}, @code{gnus-demon-add-rescan}, and
+@code{gnus-demon-add-scanmail}. Just put those functions in your
+@file{~/.gnus.el} if you want those abilities.
+
+@findex gnus-demon-init
+@findex gnus-demon-cancel
+@vindex gnus-demon-handlers
+If you add handlers to @code{gnus-demon-handlers} directly, you should
+run @code{gnus-demon-init} to make the changes take hold. To cancel all
+daemons, you can use the @code{gnus-demon-cancel} function.
+
+Note that adding daemons can be pretty naughty if you over do it. Adding
+functions that scan all news and mail from all servers every two seconds
+is a sure-fire way of getting booted off any respectable system. So
+behave.
+
+
+@node NoCeM
+@section NoCeM
+@cindex nocem
+@cindex spam
+
+@dfn{Spamming} is posting the same article lots and lots of times.
+Spamming is bad. Spamming is evil.
+
+Spamming is usually canceled within a day or so by various anti-spamming
+agencies. These agencies usually also send out @dfn{NoCeM} messages.
+NoCeM is pronounced ``no see-'em'', and means what the name
+implies---these are messages that make the offending articles, like, go
+away.
+
+What use are these NoCeM messages if the articles are canceled anyway?
+Some sites do not honor cancel messages and some sites just honor cancels
+from a select few people. Then you may wish to make use of the NoCeM
+messages, which are distributed in the @samp{alt.nocem.misc} newsgroup.
+
+Gnus can read and parse the messages in this group automatically, and
+this will make spam disappear.
+
+There are some variables to customize, of course:
+
+@table @code
+@item gnus-use-nocem
+@vindex gnus-use-nocem
+Set this variable to @code{t} to set the ball rolling. It is @code{nil}
+by default.
+
+@item gnus-nocem-groups
+@vindex gnus-nocem-groups
+Gnus will look for NoCeM messages in the groups in this list. The
+default is
+@lisp
+("news.lists.filters" "news.admin.net-abuse.bulletins"
+ "alt.nocem.misc" "news.admin.net-abuse.announce")
+@end lisp
+
+@item gnus-nocem-issuers
+@vindex gnus-nocem-issuers
+There are many people issuing NoCeM messages. This list says what
+people you want to listen to. The default is
+@lisp
+("Automoose-1" "clewis@@ferret.ocunix.on.ca"
+ "cosmo.roadkill" "SpamHippo" "hweede@@snafu.de")
+@end lisp
+fine, upstanding citizens all of them.
+
+Known despammers that you can put in this list are listed at@*
+@uref{http://www.xs4all.nl/~rosalind/nocemreg/nocemreg.html}.
+
+You do not have to heed NoCeM messages from all these people---just the
+ones you want to listen to. You also don't have to accept all NoCeM
+messages from the people you like. Each NoCeM message has a @dfn{type}
+header that gives the message a (more or less, usually less) rigorous
+definition. Common types are @samp{spam}, @samp{spew}, @samp{mmf},
+@samp{binary}, and @samp{troll}. To specify this, you have to use
+@code{(@var{issuer} @var{conditions} @dots{})} elements in the list.
+Each condition is either a string (which is a regexp that matches types
+you want to use) or a list on the form @code{(not @var{string})}, where
+@var{string} is a regexp that matches types you don't want to use.
+
+For instance, if you want all NoCeM messages from Chris Lewis except his
+@samp{troll} messages, you'd say:
+
+@lisp
+("clewis@@ferret.ocunix.on.ca" ".*" (not "troll"))
+@end lisp
+
+On the other hand, if you just want nothing but his @samp{spam} and
+@samp{spew} messages, you'd say:
+
+@lisp
+("clewis@@ferret.ocunix.on.ca" (not ".*") "spew" "spam")
+@end lisp
+
+The specs are applied left-to-right.
+
+
+@item gnus-nocem-verifyer
+@vindex gnus-nocem-verifyer
+@findex mc-verify
+This should be a function for verifying that the NoCeM issuer is who she
+says she is. The default is @code{mc-verify}, which is a Mailcrypt
+function. If this is too slow and you don't care for verification
+(which may be dangerous), you can set this variable to @code{nil}.
+
+If you want signed NoCeM messages to be verified and unsigned messages
+not to be verified (but used anyway), you could do something like:
+
+@lisp
+(setq gnus-nocem-verifyer 'my-gnus-mc-verify)
+
+(defun my-gnus-mc-verify ()
+ (not (eq 'forged
+ (ignore-errors
+ (if (mc-verify)
+ t
+ 'forged)))))
+@end lisp
+
+This might be dangerous, though.
+
+@item gnus-nocem-directory
+@vindex gnus-nocem-directory
+This is where Gnus will store its NoCeM cache files. The default is@*
+@file{~/News/NoCeM/}.
+
+@item gnus-nocem-expiry-wait
+@vindex gnus-nocem-expiry-wait
+The number of days before removing old NoCeM entries from the cache.
+The default is 15. If you make it shorter Gnus will be faster, but you
+might then see old spam.
+
+@item gnus-nocem-check-from
+@vindex gnus-nocem-check-from
+Non-@code{nil} means check for valid issuers in message bodies.
+Otherwise don't bother fetching articles unless their author matches a
+valid issuer; that is much faster if you are selective about the
+issuers.
+
+@item gnus-nocem-check-article-limit
+@vindex gnus-nocem-check-article-limit
+If non-@code{nil}, the maximum number of articles to check in any NoCeM
+group. NoCeM groups can be huge and very slow to process.
+
+@end table
+
+Using NoCeM could potentially be a memory hog. If you have many living
+(i. e., subscribed or unsubscribed groups), your Emacs process will grow
+big. If this is a problem, you should kill off all (or most) of your
+unsubscribed groups (@pxref{Subscription Commands}).
+
+
+@node Undo
+@section Undo
+@cindex undo
+
+It is very useful to be able to undo actions one has done. In normal
+Emacs buffers, it's easy enough---you just push the @code{undo} button.
+In Gnus buffers, however, it isn't that simple.
+
+The things Gnus displays in its buffer is of no value whatsoever to
+Gnus---it's all just data designed to look nice to the user.
+Killing a group in the group buffer with @kbd{C-k} makes the line
+disappear, but that's just a side-effect of the real action---the
+removal of the group in question from the internal Gnus structures.
+Undoing something like that can't be done by the normal Emacs
+@code{undo} function.
+
+Gnus tries to remedy this somewhat by keeping track of what the user
+does and coming up with actions that would reverse the actions the user
+takes. When the user then presses the @code{undo} key, Gnus will run
+the code to reverse the previous action, or the previous actions.
+However, not all actions are easily reversible, so Gnus currently offers
+a few key functions to be undoable. These include killing groups,
+yanking groups, and changing the list of read articles of groups.
+That's it, really. More functions may be added in the future, but each
+added function means an increase in data to be stored, so Gnus will
+never be totally undoable.
+
+@findex gnus-undo-mode
+@vindex gnus-use-undo
+@findex gnus-undo
+The undoability is provided by the @code{gnus-undo-mode} minor mode. It
+is used if @code{gnus-use-undo} is non-@code{nil}, which is the
+default. The @kbd{C-M-_} key performs the @code{gnus-undo}
+command, which should feel kinda like the normal Emacs @code{undo}
+command.
+
+
+@node Predicate Specifiers
+@section Predicate Specifiers
+@cindex predicate specifiers
+
+Some Gnus variables are @dfn{predicate specifiers}. This is a special
+form that allows flexible specification of predicates without having
+to type all that much.
+
+These specifiers are lists consisting of functions, symbols and lists.
+
+Here's an example:
+
+@lisp
+(or gnus-article-unseen-p
+ gnus-article-unread-p)
+@end lisp
+
+The available symbols are @code{or}, @code{and} and @code{not}. The
+functions all take one parameter.
+
+@findex gnus-make-predicate
+Internally, Gnus calls @code{gnus-make-predicate} on these specifiers
+to create a function that can be called. This input parameter to this
+function will be passed along to all the functions in the predicate
+specifier.
+
+
+@node Moderation
+@section Moderation
+@cindex moderation
+
+If you are a moderator, you can use the @file{gnus-mdrtn.el} package.
+It is not included in the standard Gnus package. Write a mail to
+@samp{larsi@@gnus.org} and state what group you moderate, and you'll
+get a copy.
+
+The moderation package is implemented as a minor mode for summary
+buffers. Put
+
+@lisp
+(add-hook 'gnus-summary-mode-hook 'gnus-moderate)
+@end lisp
+
+in your @file{~/.gnus.el} file.
+
+If you are the moderator of @samp{rec.zoofle}, this is how it's
+supposed to work:
+
+@enumerate
+@item
+You split your incoming mail by matching on
+@samp{Newsgroups:.*rec.zoofle}, which will put all the to-be-posted
+articles in some mail group---for instance, @samp{nnml:rec.zoofle}.
+
+@item
+You enter that group once in a while and post articles using the @kbd{e}
+(edit-and-post) or @kbd{s} (just send unedited) commands.
+
+@item
+If, while reading the @samp{rec.zoofle} newsgroup, you happen upon some
+articles that weren't approved by you, you can cancel them with the
+@kbd{c} command.
+@end enumerate
+
+To use moderation mode in these two groups, say:
+
+@lisp
+(setq gnus-moderated-list
+ "^nnml:rec.zoofle$\\|^rec.zoofle$")
+@end lisp
+
+
+@node Image Enhancements
+@section Image Enhancements
+
+XEmacs, as well as Emacs 21@footnote{Emacs 21 on MS Windows doesn't
+support images yet.}, is able to display pictures and stuff, so Gnus has
+taken advantage of that.
+
+@menu
+* X-Face:: Display a funky, teensy black-and-white image.
+* Face:: Display a funkier, teensier colored image.
+* Smileys:: Show all those happy faces the way they were meant to be shown.
+* Picons:: How to display pictures of what you're reading.
+* XVarious:: Other XEmacsy Gnusey variables.
+@end menu
+
+
+@node X-Face
+@subsection X-Face
+@cindex x-face
+
+@code{X-Face} headers describe a 48x48 pixel black-and-white (1 bit
+depth) image that's supposed to represent the author of the message.
+It seems to be supported by an ever-growing number of mail and news
+readers.
+
+@cindex x-face
+@findex gnus-article-display-x-face
+@vindex gnus-article-x-face-command
+@vindex gnus-article-x-face-too-ugly
+@iftex
+@iflatex
+\include{xface}
+@end iflatex
+@end iftex
+@c @anchor{X-Face}
+
+Decoding an @code{X-Face} header either requires an Emacs that has
+@samp{compface} support (which most XEmacs versions has), or that you
+have @samp{compface} installed on your system. If either is true,
+Gnus will default to displaying @code{X-Face} headers.
+
+The variable that controls this is the
+@code{gnus-article-x-face-command} variable. If this variable is a
+string, this string will be executed in a sub-shell. If it is a
+function, this function will be called with the face as the argument.
+If the @code{gnus-article-x-face-too-ugly} (which is a regexp) matches
+the @code{From} header, the face will not be shown.
+
+The default action under Emacs 20 is to fork off the @code{display}
+program@footnote{@code{display} is from the ImageMagick package. For
+the @code{uncompface} and @code{icontopbm} programs look for a package
+like @code{compface} or @code{faces-xface} on a GNU/Linux system.} to
+view the face.
+
+Under XEmacs or Emacs 21+ with suitable image support, the default
+action is to display the face before the @code{From} header. (It's
+nicer if XEmacs has been compiled with @code{X-Face} support---that
+will make display somewhat faster. If there's no native @code{X-Face}
+support, Gnus will try to convert the @code{X-Face} header using
+external programs from the @code{pbmplus} package and
+friends.@footnote{On a GNU/Linux system look for packages with names
+like @code{netpbm}, @code{libgr-progs} and @code{compface}.})
+
+(Note: @code{x-face} is used in the variable/function names, not
+@code{xface}).
+
+Gnus provides a few convenience functions and variables to allow
+easier insertion of X-Face headers in outgoing messages.
+
+@findex gnus-random-x-face
+@vindex gnus-convert-pbm-to-x-face-command
+@vindex gnus-x-face-directory
+@code{gnus-random-x-face} goes through all the @samp{pbm} files in
+@code{gnus-x-face-directory} and picks one at random, and then
+converts it to the X-Face format by using the
+@code{gnus-convert-pbm-to-x-face-command} shell command. The
+@samp{pbm} files should be 48x48 pixels big. It returns the X-Face
+header data as a string.
+
+@findex gnus-insert-random-x-face-header
+@code{gnus-insert-random-x-face-header} calls
+@code{gnus-random-x-face} and inserts a @samp{X-Face} header with the
+randomly generated data.
+
+@findex gnus-x-face-from-file
+@vindex gnus-convert-image-to-x-face-command
+@code{gnus-x-face-from-file} takes a GIF file as the parameter, and then
+converts the file to X-Face format by using the
+@code{gnus-convert-image-to-x-face-command} shell command.
+
+Here's how you would typically use the first function. Put something
+like the following in your @file{~/.gnus.el} file:
+
+@lisp
+(setq message-required-news-headers
+ (nconc message-required-news-headers
+ (list '(X-Face . gnus-random-x-face))))
+@end lisp
+
+Using the last function would be something like this:
+
+@lisp
+(setq message-required-news-headers
+ (nconc message-required-news-headers
+ (list '(X-Face . (lambda ()
+ (gnus-x-face-from-file
+ "~/My-face.gif"))))))
+@end lisp
+
+
+@node Face
+@subsection Face
+@cindex face
+
+@c #### FIXME: faces and x-faces'implementations should really be harmonized.
+
+@code{Face} headers are essentially a funkier version of @code{X-Face}
+ones. They describe a 48x48 pixel colored image that's supposed to
+represent the author of the message.
+
+@cindex face
+@findex gnus-article-display-face
+The contents of a @code{Face} header must be a base64 encoded PNG image.
+See @uref{http://quimby.gnus.org/circus/face/} for the precise
+specifications.
+
+Gnus provides a few convenience functions and variables to allow
+easier insertion of Face headers in outgoing messages.
+
+@findex gnus-convert-png-to-face
+@code{gnus-convert-png-to-face} takes a 48x48 PNG image, no longer than
+726 bytes long, and converts it to a face.
+
+@findex gnus-face-from-file
+@vindex gnus-convert-image-to-face-command
+@code{gnus-face-from-file} takes a JPEG file as the parameter, and then
+converts the file to Face format by using the
+@code{gnus-convert-image-to-face-command} shell command.
+
+Here's how you would typically use this function. Put something like the
+following in your @file{~/.gnus.el} file:
+
+@lisp
+(setq message-required-news-headers
+ (nconc message-required-news-headers
+ (list '(Face . (lambda ()
+ (gnus-face-from-file "~/face.jpg"))))))
+@end lisp
+
+
+@node Smileys
+@subsection Smileys
+@cindex smileys
+
+@iftex
+@iflatex
+\gnusfig{-3cm}{0.5cm}{\epsfig{figure=ps/BigFace,height=20cm}}
+\input{smiley}
+@end iflatex
+@end iftex
+
+@dfn{Smiley} is a package separate from Gnus, but since Gnus is
+currently the only package that uses Smiley, it is documented here.
+
+In short---to use Smiley in Gnus, put the following in your
+@file{~/.gnus.el} file:
+
+@lisp
+(setq gnus-treat-display-smileys t)
+@end lisp
+
+Smiley maps text smiley faces---@samp{:-)}, @samp{8-)}, @samp{:-(} and
+the like---to pictures and displays those instead of the text smiley
+faces. The conversion is controlled by a list of regexps that matches
+text and maps that to file names.
+
+@vindex smiley-regexp-alist
+The alist used is specified by the @code{smiley-regexp-alist}
+variable. The first item in each element is the regexp to be matched;
+the second element is the regexp match group that is to be replaced by
+the picture; and the third element is the name of the file to be
+displayed.
+
+The following variables customize where Smiley will look for these
+files:
+
+@table @code
+
+@item smiley-data-directory
+@vindex smiley-data-directory
+Where Smiley will look for smiley faces files.
+
+@item gnus-smiley-file-types
+@vindex gnus-smiley-file-types
+List of suffixes on smiley file names to try.
+
+@end table
+
+
+@node Picons
+@subsection Picons
+
+@iftex
+@iflatex
+\include{picons}
+@end iflatex
+@end iftex
+
+So@dots{} You want to slow down your news reader even more! This is a
+good way to do so. It's also a great way to impress people staring
+over your shoulder as you read news.
+
+What are Picons? To quote directly from the Picons Web site:
+
+@iftex
+@iflatex
+\margindex{}
+@end iflatex
+@end iftex
+
+@quotation
+@dfn{Picons} is short for ``personal icons''. They're small,
+constrained images used to represent users and domains on the net,
+organized into databases so that the appropriate image for a given
+e-mail address can be found. Besides users and domains, there are picon
+databases for Usenet newsgroups and weather forecasts. The picons are
+in either monochrome @code{XBM} format or color @code{XPM} and
+@code{GIF} formats.
+@end quotation
+
+@vindex gnus-picon-databases
+For instructions on obtaining and installing the picons databases,
+point your Web browser at
+@uref{http://www.cs.indiana.edu/picons/ftp/index.html}.
+
+If you are using Debian GNU/Linux, saying @samp{apt-get install
+picons.*} will install the picons where Gnus can find them.
+
+To enable displaying picons, simply make sure that
+@code{gnus-picon-databases} points to the directory containing the
+Picons databases.
+
+The following variables offer control over where things are located.
+
+@table @code
+
+@item gnus-picon-databases
+@vindex gnus-picon-databases
+The location of the picons database. This is a list of directories
+containing the @file{news}, @file{domains}, @file{users} (and so on)
+subdirectories. Defaults to @code{("/usr/lib/picon"
+"/usr/local/faces")}.
+
+@item gnus-picon-news-directories
+@vindex gnus-picon-news-directories
+List of subdirectories to search in @code{gnus-picon-databases} for
+newsgroups faces. @code{("news")} is the default.
+
+@item gnus-picon-user-directories
+@vindex gnus-picon-user-directories
+List of subdirectories to search in @code{gnus-picon-databases} for user
+faces. @code{("users" "usenix" "local" "misc")} is the default.
+
+@item gnus-picon-domain-directories
+@vindex gnus-picon-domain-directories
+List of subdirectories to search in @code{gnus-picon-databases} for
+domain name faces. Defaults to @code{("domains")}. Some people may
+want to add @samp{"unknown"} to this list.
+
+@item gnus-picon-file-types
+@vindex gnus-picon-file-types
+Ordered list of suffixes on picon file names to try. Defaults to
+@code{("xpm" "gif" "xbm")} minus those not built-in your Emacs.
+
+@end table
+
+
+@node XVarious
+@subsection Various XEmacs Variables
+
+@table @code
+@item gnus-xmas-glyph-directory
+@vindex gnus-xmas-glyph-directory
+This is where Gnus will look for pictures. Gnus will normally
+auto-detect this directory, but you may set it manually if you have an
+unusual directory structure.
+
+@item gnus-xmas-logo-color-alist
+@vindex gnus-xmas-logo-color-alist
+This is an alist where the key is a type symbol and the values are the
+foreground and background color of the splash page glyph.
+
+@item gnus-xmas-logo-color-style
+@vindex gnus-xmas-logo-color-style
+This is the key used to look up the color in the alist described above.
+Valid values include @code{flame}, @code{pine}, @code{moss},
+@code{irish}, @code{sky}, @code{tin}, @code{velvet}, @code{grape},
+@code{labia}, @code{berry}, @code{neutral}, and @code{september}.
+
+@item gnus-xmas-modeline-glyph
+@vindex gnus-xmas-modeline-glyph
+A glyph displayed in all Gnus mode lines. It is a tiny gnu head by
+default.
+
+@end table
+
+@subsubsection Toolbar
+
+@table @code
+
+@item gnus-use-toolbar
+@vindex gnus-use-toolbar
+If @code{nil}, don't display toolbars. If non-@code{nil}, it should be
+one of @code{default-toolbar}, @code{top-toolbar}, @code{bottom-toolbar},
+@code{right-toolbar}, or @code{left-toolbar}.
+
+@item gnus-group-toolbar
+@vindex gnus-group-toolbar
+The toolbar in the group buffer.
+
+@item gnus-summary-toolbar
+@vindex gnus-summary-toolbar
+The toolbar in the summary buffer.
+
+@item gnus-summary-mail-toolbar
+@vindex gnus-summary-mail-toolbar
+The toolbar in the summary buffer of mail groups.
+
+@end table
+
+@iftex
+@iflatex
+\margindex{}
+@end iflatex
+@end iftex
+
+
+@node Fuzzy Matching
+@section Fuzzy Matching
+@cindex fuzzy matching
+
+Gnus provides @dfn{fuzzy matching} of @code{Subject} lines when doing
+things like scoring, thread gathering and thread comparison.
+
+As opposed to regular expression matching, fuzzy matching is very fuzzy.
+It's so fuzzy that there's not even a definition of what @dfn{fuzziness}
+means, and the implementation has changed over time.
+
+Basically, it tries to remove all noise from lines before comparing.
+@samp{Re: }, parenthetical remarks, white space, and so on, are filtered
+out of the strings before comparing the results. This often leads to
+adequate results---even when faced with strings generated by text
+manglers masquerading as newsreaders.
+
+
+@node Thwarting Email Spam
+@section Thwarting Email Spam
+@cindex email spam
+@cindex spam
+@cindex UCE
+@cindex unsolicited commercial email
+
+In these last days of the Usenet, commercial vultures are hanging about
+and grepping through news like crazy to find email addresses they can
+foist off their scams and products to. As a reaction to this, many
+people have started putting nonsense addresses into their @code{From}
+lines. I think this is counterproductive---it makes it difficult for
+people to send you legitimate mail in response to things you write, as
+well as making it difficult to see who wrote what. This rewriting may
+perhaps be a bigger menace than the unsolicited commercial email itself
+in the end.
+
+The biggest problem I have with email spam is that it comes in under
+false pretenses. I press @kbd{g} and Gnus merrily informs me that I
+have 10 new emails. I say ``Golly gee! Happy is me!'' and select the
+mail group, only to find two pyramid schemes, seven advertisements
+(``New! Miracle tonic for growing full, lustrous hair on your toes!'')
+and one mail asking me to repent and find some god.
+
+This is annoying. Here's what you can do about it.
+
+@menu
+* The problem of spam:: Some background, and some solutions
+* 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.
+* Filtering Spam Using The Spam ELisp Package::
+* Filtering Spam Using Statistics with spam-stat::
+@end menu
+
+@node The problem of spam
+@subsection The problem of spam
+@cindex email spam
+@cindex spam filtering approaches
+@cindex filtering approaches, spam
+@cindex UCE
+@cindex unsolicited commercial email
+
+First, some background on spam.
+
+If you have access to e-mail, you are familiar with spam (technically
+termed @acronym{UCE}, Unsolicited Commercial E-mail). Simply put, it
+exists because e-mail delivery is very cheap compared to paper mail,
+so only a very small percentage of people need to respond to an UCE to
+make it worthwhile to the advertiser. Ironically, one of the most
+common spams is the one offering a database of e-mail addresses for
+further spamming. Senders of spam are usually called @emph{spammers},
+but terms like @emph{vermin}, @emph{scum}, @emph{sociopaths}, and
+@emph{morons} are in common use as well.
+
+Spam comes from a wide variety of sources. It is simply impossible to
+dispose of all spam without discarding useful messages. A good
+example is the TMDA system, which requires senders
+unknown to you to confirm themselves as legitimate senders before
+their e-mail can reach you. Without getting into the technical side
+of TMDA, a downside is clearly that e-mail from legitimate sources may
+be discarded if those sources can't or won't confirm themselves
+through the TMDA system. Another problem with TMDA is that it
+requires its users to have a basic understanding of e-mail delivery
+and processing.
+
+The simplest approach to filtering spam is filtering, at the mail
+server or when you sort through incoming mail. If you get 200 spam
+messages per day from @samp{random-address@@vmadmin.com}, you block
+@samp{vmadmin.com}. If you get 200 messages about @samp{VIAGRA}, you
+discard all messages with @samp{VIAGRA} in the message. If you get
+lots of spam from Bulgaria, for example, you try to filter all mail
+from Bulgarian IPs.
+
+This, unfortunately, is a great way to discard legitimate e-mail. The
+risks of blocking a whole country (Bulgaria, Norway, Nigeria, China,
+etc.) or even a continent (Asia, Africa, Europe, etc.) from contacting
+you should be obvious, so don't do it if you have the choice.
+
+In another instance, the very informative and useful RISKS digest has
+been blocked by overzealous mail filters because it @strong{contained}
+words that were common in spam messages. Nevertheless, in isolated
+cases, with great care, direct filtering of mail can be useful.
+
+Another approach to filtering e-mail is the distributed spam
+processing, for instance DCC implements such a system. In essence,
+@var{N} systems around the world agree that a machine @var{X} in
+Ghana, Estonia, or California is sending out spam e-mail, and these
+@var{N} systems enter @var{X} or the spam e-mail from @var{X} into a
+database. The criteria for spam detection vary---it may be the number
+of messages sent, the content of the messages, and so on. When a user
+of the distributed processing system wants to find out if a message is
+spam, he consults one of those @var{N} systems.
+
+Distributed spam processing works very well against spammers that send
+a large number of messages at once, but it requires the user to set up
+fairly complicated checks. There are commercial and free distributed
+spam processing systems. Distributed spam processing has its risks as
+well. For instance legitimate e-mail senders have been accused of
+sending spam, and their web sites and mailing lists have been shut
+down for some time because of the incident.
+
+The statistical approach to spam filtering is also popular. It is
+based on a statistical analysis of previous spam messages. Usually
+the analysis is a simple word frequency count, with perhaps pairs of
+words or 3-word combinations thrown into the mix. Statistical
+analysis of spam works very well in most of the cases, but it can
+classify legitimate e-mail as spam in some cases. It takes time to
+run the analysis, the full message must be analyzed, and the user has
+to store the database of spam analyses. Statistical analysis on the
+server is gaining popularity. This has the advantage of letting the
+user Just Read Mail, but has the disadvantage that it's harder to tell
+the server that it has misclassified mail.
+
+Fighting spam is not easy, no matter what anyone says. There is no
+magic switch that will distinguish Viagra ads from Mom's e-mails.
+Even people are having a hard time telling spam apart from non-spam,
+because spammers are actively looking to fool us into thinking they
+are Mom, essentially. Spamming is irritating, irresponsible, and
+idiotic behavior from a bunch of people who think the world owes them
+a favor. We hope the following sections will help you in fighting the
+spam plague.
+
+@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
+put it in your @code{From} header of all your news articles. (I've
+chosen @samp{larsi@@trym.ifi.uio.no}, but for many addresses on the form
+@samp{larsi+usenet@@ifi.uio.no} will be a better choice. Ask your
+sysadmin whether your sendmail installation accepts keywords in the local
+part of the mail address.)
+
+@lisp
+(setq message-default-news-headers
+ "From: Lars Magne Ingebrigtsen <larsi@@trym.ifi.uio.no>\n")
+@end lisp
+
+Then put the following split rule in @code{nnmail-split-fancy}
+(@pxref{Fancy Mail Splitting}):
+
+@lisp
+(...
+ (to "larsi@@trym.ifi.uio.no"
+ (| ("subject" "re:.*" "misc")
+ ("references" ".*@@.*" "misc")
+ "spam"))
+ ...)
+@end lisp
+
+This says that all mail to this address is suspect, but if it has a
+@code{Subject} that starts with a @samp{Re:} or has a @code{References}
+header, it's probably ok. All the rest goes to the @samp{spam} group.
+(This idea probably comes from Tim Pierce.)
+
+In addition, many mail spammers talk directly to your @acronym{SMTP} server
+and do not include your email address explicitly in the @code{To}
+header. Why they do this is unknown---perhaps it's to thwart this
+thwarting scheme? In any case, this is trivial to deal with---you just
+put anything not addressed to you in the @samp{spam} group by ending
+your fancy split rule in this way:
+
+@lisp
+(
+ ...
+ (to "larsi" "misc")
+ "spam")
+@end lisp
+
+In my experience, this will sort virtually everything into the right
+group. You still have to check the @samp{spam} group from time to time to
+check for legitimate mail, though. If you feel like being a good net
+citizen, you can even send off complaints to the proper authorities on
+each unsolicited commercial email---at your leisure.
+
+This works for me. It allows people an easy way to contact me (they can
+just press @kbd{r} in the usual way), and I'm not bothered at all with
+spam. It's a win-win situation. Forging @code{From} headers to point
+to non-existent domains is yucky, in my opinion.
+
+Be careful with this approach. Spammers are wise to it.
+
+
+@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 were sufficient in
+avoiding spam are 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.
+
+Note that this section does not involve the @code{spam.el} package,
+which is discussed in the next section. If you don't care for all
+the features of @code{spam.el}, you can make do with these simple
+recipes.
+
+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}) follow.
+
+@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 manage 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
+ (save-restriction
+ (widen)
+ (if (eq 1 (call-process-region (point-min) (point-max)
+ "spamc" nil nil nil "-c"))
+ "spam"))))
+@end lisp
+
+Note that with the nnimap backend, message bodies will not be
+downloaded by default. You need to set
+@code{nnimap-split-download-body} to @code{t} to do that
+(@pxref{Splitting in IMAP}).
+
+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 everyone in the world using 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 prefers that everyone you contact through e-mail 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 @file{hashcash.el} library can be found in the Gnus development
+contrib directory or at
+@uref{http://users.actrix.gen.nz/mycroft/hashcash.el}.
+
+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{(@var{addr}
+@var{amount})} cells, where @var{addr} is the receiver (email address
+or newsgroup) and @var{amount} is the number of bits in the collision
+that is needed. It can also contain @samp{(@var{addr} @var{string}
+@var{amount})} cells, where the @var{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 Filtering Spam Using The Spam ELisp Package
+@subsection Filtering Spam Using The Spam ELisp Package
+@cindex spam filtering
+@cindex spam
+
+The idea behind @file{spam.el} is to have a control center for spam detection
+and filtering in Gnus. To that end, @file{spam.el} does two things: it
+filters new mail, and it analyzes mail known to be spam or ham.
+@dfn{Ham} is the name used throughout @file{spam.el} to indicate
+non-spam messages.
+
+First of all, you @strong{must} run the function
+@code{spam-initialize} to autoload @code{spam.el} and to install the
+@code{spam.el} hooks. There is one exception: if you use the
+@code{spam-use-stat} (@pxref{spam-stat spam filtering}) setting, you
+should turn it on before @code{spam-initialize}:
+
+@example
+(setq spam-use-stat t) ;; if needed
+(spam-initialize)
+@end example
+
+So, what happens when you load @file{spam.el}?
+
+First, some hooks will get installed by @code{spam-initialize}. There
+are some hooks for @code{spam-stat} so it can save its databases, and
+there are hooks so interesting things will happen when you enter and
+leave a group. More on the sequence of events later (@pxref{Spam
+ELisp Package Sequence of Events}).
+
+You get the following keyboard commands:
+
+@table @kbd
+
+@item M-d
+@itemx M s x
+@itemx S x
+@kindex M-d
+@kindex S x
+@kindex M s x
+@findex gnus-summary-mark-as-spam
+@code{gnus-summary-mark-as-spam}.
+
+Mark current article as spam, showing it with the @samp{$} mark.
+Whenever you see a spam article, make sure to mark its summary line
+with @kbd{M-d} before leaving the group. This is done automatically
+for unread articles in @emph{spam} groups.
+
+@item M s t
+@itemx S t
+@kindex M s t
+@kindex S t
+@findex spam-bogofilter-score
+@code{spam-bogofilter-score}.
+
+You must have Bogofilter installed for that command to work properly.
+
+@xref{Bogofilter}.
+
+@end table