Go to the first, previous, next, last section, table of contents.


Select Methods

A foreign group is a group not read by the usual (or default) means. It could be, for instance, a group from a different NNTP server, it could be a virtual group, or it could be your own personal mail group.

A foreign group (or any group, really) is specified by a name and a select method. To take the latter first, a select method is a list where the first element says what backend to use (e.g. nntp, nnspool, nnml) and the second element is the server name. There may be additional elements in the select method, where the value may have special meaning for the backend in question.

One could say that a select method defines a virtual server---so we do just that (see section The Server Buffer).

The name of the group is the name the backend will recognize the group as.

For instance, the group `soc.motss' on the NNTP server `some.where.edu' will have the name `soc.motss' and select method (nntp "some.where.edu"). Gnus will call this group `nntp+some.where.edu:soc.motss', even though the nntp backend just knows this group as `soc.motss'.

The different methods all have their peculiarities, of course.

The Server Buffer

Traditionally, a server is a machine or a piece of software that one connects to, and then requests information from. Gnus does not connect directly to any real servers, but does all transactions through one backend or other. But that's just putting one layer more between the actual media and Gnus, so we might just as well say that each backend represents a virtual server.

For instance, the nntp backend may be used to connect to several different actual NNTP servers, or, perhaps, to many different ports on the same actual NNTP server. You tell Gnus which backend to use, and what parameters to set by specifying a select method.

These select method specifications can sometimes become quite complicated--say, for instance, that you want to read from the NNTP server `news.funet.fi' on port number 13, which hangs if queried for NOV headers and has a buggy select. Ahem. Anyways, if you had to specify that for each group that used this server, that would be too much work, so Gnus offers a way of naming select methods, which is what you do in the server buffer.

To enter the server buffer, use the ^ (gnus-group-enter-server-mode) command in the group buffer.

gnus-server-mode-hook is run when creating the server buffer.

Server Buffer Format

You can change the look of the server buffer lines by changing the gnus-server-line-format variable. This is a format-like variable, with some simple extensions:

`h'
How the news is fetched--the backend name.
`n'
The name of this server.
`w'
Where the news is to be fetched from--the address.
`s'
The opened/closed/denied status of the server.

The mode line can also be customized by using the gnus-server-mode-line-format variable (see section Mode Line Formatting). The following specs are understood:

`S'
Server name.
`M'
Server method.

Also see section Formatting Variables.

Server Commands

a
Add a new server (gnus-server-add-server).
e
Edit a server (gnus-server-edit-server).
SPACE
Browse the current server (gnus-server-read-server).
q
Return to the group buffer (gnus-server-exit).
k
Kill the current server (gnus-server-kill-server).
y
Yank the previously killed server (gnus-server-yank-server).
c
Copy the current server (gnus-server-copy-server).
l
List all servers (gnus-server-list-servers).
s
Request that the server scan its sources for new articles (gnus-server-scan-server). This is mainly sensible with mail servers.
g
Request that the server regenerate all its data structures (gnus-server-regenerate-server). This can be useful if you have a mail backend that has gotten out of synch.

Example Methods

Most select methods are pretty simple and self-explanatory:

(nntp "news.funet.fi")

Reading directly from the spool is even simpler:

(nnspool "")

As you can see, the first element in a select method is the name of the backend, and the second is the address, or name, if you will.

After these two elements, there may be an arbitrary number of (variable form) pairs.

To go back to the first example--imagine that you want to read from port 15 on that machine. This is what the select method should look like then:

(nntp "news.funet.fi" (nntp-port-number 15))

You should read the documentation to each backend to find out what variables are relevant, but here's an nnmh example:

nnmh is a mail backend that reads a spool-like structure. Say you have two structures that you wish to access: One is your private mail spool, and the other is a public one. Here's the possible spec for your private mail:

(nnmh "private" (nnmh-directory "~/private/mail/"))

(This server is then called `private', but you may have guessed that.)

Here's the method for a public spool:

(nnmh "public"
      (nnmh-directory "/usr/information/spool/")
      (nnmh-get-new-mail nil))

If you are behind a firewall and only have access to the NNTP server from the firewall machine, you can instruct Gnus to rlogin on the firewall machine and telnet from there to the NNTP server. Doing this can be rather fiddly, but your virtual server definition should probably look something like this:

(nntp "firewall"
      (nntp-address "the.firewall.machine")
      (nntp-open-connection-function nntp-open-rlogin)
      (nntp-end-of-line "\n")
      (nntp-rlogin-parameters
       ("telnet" "the.real.nntp.host" "nntp")))

If you want to use the wonderful ssh program to provide a compressed connection over the modem line, you could create a virtual server that would look something like this:

(nntp "news"
       (nntp-address "copper.uio.no")
       (nntp-rlogin-program "ssh")
       (nntp-open-connection-function nntp-open-rlogin)
       (nntp-end-of-line "\n")
       (nntp-rlogin-parameters
        ("telnet" "news.uio.no" "nntp")))

This means that you have to have set up ssh-agent correctly to provide automatic authorization, of course. And to get a compressed connection, you have to have the `Compression' option in the ssh `config' file.

Creating a Virtual Server

If you're saving lots of articles in the cache by using persistent articles, you may want to create a virtual server to read the cache.

First you need to add a new server. The a command does that. It would probably be best to use nnspool to read the cache. You could also use nnml or nnmh, though.

Type a nnspool RET cache RET.

You should now have a brand new nnspool virtual server called `cache'. You now need to edit it to have the right definitions. Type e to edit the server. You'll be entered into a buffer that will contain the following:

(nnspool "cache")

Change that to:

(nnspool "cache"
         (nnspool-spool-directory "~/News/cache/")
         (nnspool-nov-directory "~/News/cache/")
         (nnspool-active-file "~/News/cache/active"))

Type C-c C-c to return to the server buffer. If you now press RET over this virtual server, you should be entered into a browse buffer, and you should be able to enter any of the groups displayed.

Server Variables

One sticky point when defining variables (both on backends and in Emacs in general) is that some variables are typically initialized from other variables when the definition of the variables is being loaded. If you change the "base" variable after the variables have been loaded, you won't change the "derived" variables.

This typically affects directory and file variables. For instance, nnml-directory is `~/Mail/' by default, and all nnml directory variables are initialized from that variable, so nnml-active-file will be `~/Mail/active'. If you define a new virtual nnml server, it will not suffice to set just nnml-directory---you have to explicitly set all the file variables to be what you want them to be. For a complete list of variables for each backend, see each backend's section later in this manual, but here's an example nnml definition:

(nnml "public"
      (nnml-directory "~/my-mail/")
      (nnml-active-file "~/my-mail/active")
      (nnml-newsgroups-file "~/my-mail/newsgroups"))

Servers and Methods

Wherever you would normally use a select method (e.g. gnus-secondary-select-method, in the group select method, when browsing a foreign server) you can use a virtual server name instead. This could potentially save lots of typing. And it's nice all over.

Unavailable Servers

If a server seems to be unreachable, Gnus will mark that server as denied. That means that any subsequent attempt to make contact with that server will just be ignored. "It can't be opened," Gnus will tell you, without making the least effort to see whether that is actually the case or not.

That might seem quite naughty, but it does make sense most of the time. Let's say you have 10 groups subscribed to on server `nephelococcygia.com'. This server is located somewhere quite far away from you and the machine is quite slow, so it takes 1 minute just to find out that it refuses connection to you today. If Gnus were to attempt to do that 10 times, you'd be quite annoyed, so Gnus won't attempt to do that. Once it has gotten a single "connection refused", it will regard that server as "down".

So, what happens if the machine was only feeling unwell temporarily? How do you test to see whether the machine has come up again?

You jump to the server buffer (see section The Server Buffer) and poke it with the following commands:

O
Try to establish connection to the server on the current line (gnus-server-open-server).
C
Close the connection (if any) to the server (gnus-server-close-server).
D
Mark the current server as unreachable (gnus-server-deny-server).
M-o
Open the connections to all servers in the buffer (gnus-server-open-all-servers).
M-c
Close the connections to all servers in the buffer (gnus-server-close-all-servers).
R
Remove all marks to whether Gnus was denied connection from any servers (gnus-server-remove-denials).

Getting News

A newsreader is normally used for reading news. Gnus currently provides only two methods of getting news--it can read from an NNTP server, or it can read from a local spool.

NNTP

Subscribing to a foreign group from an NNTP server is rather easy. You just specify nntp as method and the address of the NNTP server as the, uhm, address.

If the NNTP server is located at a non-standard port, setting the third element of the select method to this port number should allow you to connect to the right port. You'll have to edit the group info for that (see section Foreign Groups).

The name of the foreign group can be the same as a native group. In fact, you can subscribe to the same group from as many different servers you feel like. There will be no name collisions.

The following variables can be used to create a virtual nntp server:

nntp-server-opened-hook
is run after a connection has been made. It can be used to send commands to the NNTP server after it has been contacted. By default it sends the command MODE READER to the server with the nntp-send-mode-reader function. This function should always be present in this hook.
nntp-authinfo-function
This function will be used to send `AUTHINFO' to the NNTP server. The default function is nntp-send-authinfo, which looks through your `~/.authinfo' (or whatever you've set the nntp-authinfo-file variable to) for applicable entries. If none are found, it will prompt you for a login name and a password. The format of the `~/.authinfo' file is (almost) the same as the ftp `~/.netrc' file, which is defined in the ftp manual page, but here are the salient facts:
  1. The file contains one or more line, each of which define one server.
  2. Each line may contain an arbitrary number of token/value pairs. The valid tokens include `machine', `login', `password', `default' and `force'. (The latter is not a valid `.netrc'/ftp token, which is the only way the `.authinfo' file format deviates from the `.netrc' file format.)
Here's an example file:
machine news.uio.no login larsi password geheimnis
machine nntp.ifi.uio.no login larsi force yes
The token/value pairs may appear in any order; `machine' doesn't have to be first, for instance. In this example, both login name and password have been supplied for the former server, while the latter has only the login name listed, and the user will be prompted for the password. The latter also has the `force' tag, which means that the authinfo will be sent to the nntp server upon connection; the default (i.e., when there is not `force' tag) is to not send authinfo to the nntp server until the nntp server asks for it. You can also add `default' lines that will apply to all servers that don't have matching `machine' lines.
default force yes
This will force sending `AUTHINFO' commands to all servers not previously mentioned. Remember to not leave the `~/.authinfo' file world-readable.
nntp-server-action-alist
This is a list of regexps to match on server types and actions to be taken when matches are made. For instance, if you want Gnus to beep every time you connect to innd, you could say something like:
(setq nntp-server-action-alist
      '(("innd" (ding))))
You probably don't want to do that, though. The default value is
'(("nntpd 1\\.5\\.11t"
   (remove-hook 'nntp-server-opened-hook 'nntp-send-mode-reader)))
This ensures that Gnus doesn't send the MODE READER command to nntpd 1.5.11t, since that command chokes that server, I've been told.
nntp-maximum-request
If the NNTP server doesn't support NOV headers, this backend will collect headers by sending a series of head commands. To speed things up, the backend sends lots of these commands without waiting for reply, and then reads all the replies. This is controlled by the nntp-maximum-request variable, and is 400 by default. If your network is buggy, you should set this to 1.
nntp-connection-timeout
If you have lots of foreign nntp groups that you connect to regularly, you're sure to have problems with NNTP servers not responding properly, or being too loaded to reply within reasonable time. This is can lead to awkward problems, which can be helped somewhat by setting nntp-connection-timeout. This is an integer that says how many seconds the nntp backend should wait for a connection before giving up. If it is nil, which is the default, no timeouts are done.
nntp-server-hook
This hook is run as the last step when connecting to an NNTP server.
nntp-open-connection-function
This function is used to connect to the remote system. Four pre-made functions are supplied:
nntp-open-network-stream
This is the default, and simply connects to some port or other on the remote system.
nntp-open-rlogin
Does an `rlogin' on the remote system, and then does a `telnet' to the NNTP server available there. nntp-open-rlogin-related variables:
nntp-rlogin-program
Program used to log in on remote machines. The default is `rsh', but `ssh' is a popular alternative.
nntp-rlogin-parameters
This list will be used as the parameter list given to rsh.
nntp-rlogin-user-name
User name on the remote system.
nntp-open-telnet
Does a `telnet' to the remote system and then another `telnet' to get to the NNTP server. nntp-open-telnet-related variables:
nntp-telnet-command
Command used to start telnet.
nntp-telnet-switches
List of strings to be used as the switches to the telnet command.
nntp-telnet-user-name
User name for log in on the remote system.
nntp-telnet-passwd
Password to use when logging in.
nntp-telnet-parameters
A list of strings executed as a command after logging in via telnet.
nntp-telnet-shell-prompt
Regexp matching the shell prompt on the remote machine. The default is `bash\\|\$ *\r?$\\|> *\r?'.
nntp-open-telnet-envuser
If non-nil, the telnet session (client and server both) will support the ENVIRON option and not prompt for login name. This works for Solaris telnet, for instance.
nntp-open-ssl-stream
Opens a connection to a server over a secure channel. To use this you must have SSLay installed (`ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL', and you also need `ssl.el' (from the W3 distributeion, for instance). You then define a server as follows:
;; Type `C-c C-c' after you've finished editing.
;;
;; "snews" is port 563 and is predefined in our /etc/services
;;
(nntp "snews.bar.com"
      (nntp-open-connection-function nntp-open-ssl-stream)
      (nntp-port-number "snews")
      (nntp-address "snews.bar.com"))
nntp-end-of-line
String to use as end-of-line marker when talking to the NNTP server. This is `\r\n' by default, but should be `\n' when using rlogin to talk to the server.
nntp-rlogin-user-name
User name on the remote system when using the rlogin connect function.
nntp-address
The address of the remote system running the NNTP server.
nntp-port-number
Port number to connect to when using the nntp-open-network-stream connect function.
nntp-buggy-select
Set this to non-nil if your select routine is buggy.
nntp-nov-is-evil
If the NNTP server does not support NOV, you could set this variable to t, but nntp usually checks automatically whether NOV can be used.
nntp-xover-commands
List of strings used as commands to fetch NOV lines from a server. The default value of this variable is ("XOVER" "XOVERVIEW").
nntp-nov-gap
nntp normally sends just one big request for NOV lines to the server. The server responds with one huge list of lines. However, if you have read articles 2-5000 in the group, and only want to read article 1 and 5001, that means that nntp will fetch 4999 NOV lines that you will not need. This variable says how big a gap between two consecutive articles is allowed to be before the XOVER request is split into several request. Note that if your network is fast, setting this variable to a really small number means that fetching will probably be slower. If this variable is nil, nntp will never split requests. The default is 5.
nntp-prepare-server-hook
A hook run before attempting to connect to an NNTP server.
nntp-warn-about-losing-connection
If this variable is non-nil, some noise will be made when a server closes connection.
nntp-record-commands
If non-nil, nntp will log all commands it sends to the NNTP server (along with a timestep) in the `*nntp-log*' buffer. This is useful if you are debugging a Gnus/NNTP connection that doesn't seem to work.

News Spool

Subscribing to a foreign group from the local spool is extremely easy, and might be useful, for instance, to speed up reading groups that contain very big articles---`alt.binaries.pictures.furniture', for instance.

Anyways, you just specify nnspool as the method and "" (or anything else) as the address.

If you have access to a local spool, you should probably use that as the native select method (see section Finding the News). It is normally faster than using an nntp select method, but might not be. It depends. You just have to try to find out what's best at your site.

nnspool-inews-program
Program used to post an article.
nnspool-inews-switches
Parameters given to the inews program when posting an article.
nnspool-spool-directory
Where nnspool looks for the articles. This is normally `/usr/spool/news/'.
nnspool-nov-directory
Where nnspool will look for NOV files. This is normally `/usr/spool/news/over.view/'.
nnspool-lib-dir
Where the news lib dir is (`/usr/lib/news/' by default).
nnspool-active-file
The path to the active file.
nnspool-newsgroups-file
The path to the group descriptions file.
nnspool-history-file
The path to the news history file.
nnspool-active-times-file
The path to the active date file.
nnspool-nov-is-evil
If non-nil, nnspool won't try to use any NOV files that it finds.
nnspool-sift-nov-with-sed
If non-nil, which is the default, use sed to get the relevant portion from the overview file. If nil, nnspool will load the entire file into a buffer and process it there.

Getting Mail

Reading mail with a newsreader--isn't that just plain WeIrD? But of course.

Mail in a Newsreader

If you are used to traditional mail readers, but have decided to switch to reading mail with Gnus, you may find yourself experiencing something of a culture shock.

Gnus does not behave like traditional mail readers. If you want to make it behave that way, you can, but it's an uphill battle.

Gnus, by default, handles all its groups using the same approach. This approach is very newsreaderly--you enter a group, see the new/unread messages, and when you read the messages, they get marked as read, and you don't see them any more. (Unless you explicitly ask for them.)

In particular, you do not do anything explicitly to delete messages.

Does this mean that all the messages that have been marked as read are deleted? How awful!

But, no, it means that old messages are expired according to some scheme or other. For news messages, the expire process is controlled by the news administrator; for mail, the expire process is controlled by you. The expire process for mail is covered in depth in see section Expiring Mail.

What many Gnus users find, after using it a while for both news and mail, is that the transport mechanism has very little to do with how they want to treat a message.

Many people subscribe to several mailing lists. These are transported via SMTP, and are therefore mail. But we might go for weeks without answering, or even reading these messages very carefully. We may not need to save them because if we should need to read one again, they are archived somewhere else.

Some people have local news groups which have only a handful of readers. These are transported via NNTP, and are therefore news. But we may need to read and answer a large fraction of the messages very carefully in order to do our work. And there may not be an archive, so we may need to save the interesting messages the same way we would personal mail.

The important distinction turns out to be not the transport mechanism, but other factors such as how interested we are in the subject matter, or how easy it is to retrieve the message if we need to read it again.

Gnus provides many options for sorting mail into "groups" which behave like newsgroups, and for treating each group (whether mail or news) differently.

Some users never get comfortable using the Gnus (ahem) paradigm and wish that Gnus should grow up and be a male, er, mail reader. It is possible to whip Gnus into a more mailreaderly being, but, as said before, it's not easy. People who prefer proper mail readers should try VM instead, which is an excellent, and proper, mail reader.

I don't mean to scare anybody off, but I want to make it clear that you may be required to learn a new way of thinking about messages. After you've been subjected to The Gnus Way, you will come to love it. I can guarantee it. (At least the guy who sold me the Emacs Subliminal Brain-Washing Functions that I've put into Gnus did guarantee it. You Will Be Assimilated. You Love Gnus. You Love The Gnus Mail Way. You Do.)

Getting Started Reading Mail

It's quite easy to use Gnus to read your new mail. You just plonk the mail backend of your choice into gnus-secondary-select-methods, and things will happen automatically.

For instance, if you want to use nnml (which is a "one file per mail" backend), you could put the following in your `.gnus' file:

(setq gnus-secondary-select-methods
      '((nnml "private")))

Now, the next time you start Gnus, this backend will be queried for new articles, and it will move all the messages in your spool file to its directory, which is ~/Mail/ by default. The new group that will be created (`mail.misc') will be subscribed, and you can read it like any other group.

You will probably want to split the mail into several groups, though:

(setq nnmail-split-methods
      '(("junk" "^From:.*Lars Ingebrigtsen")
        ("crazy" "^Subject:.*die\\|^Organization:.*flabby")
        ("other" "")))

This will result in three new nnml mail groups being created: `nnml:junk', `nnml:crazy', and `nnml:other'. All the mail that doesn't fit into the first two groups will be placed in the last group.

This should be sufficient for reading mail with Gnus. You might want to give the other sections in this part of the manual a perusal, though. Especially see section Choosing a Mail Backend and see section Expiring Mail.

Splitting Mail

The nnmail-split-methods variable says how the incoming mail is to be split into groups.

(setq nnmail-split-methods
  '(("mail.junk" "^From:.*Lars Ingebrigtsen")
    ("mail.crazy" "^Subject:.*die\\|^Organization:.*flabby")
    ("mail.other" "")))

This variable is a list of lists, where the first element of each of these lists is the name of the mail group (they do not have to be called something beginning with `mail', by the way), and the second element is a regular expression used on the header of each mail to determine if it belongs in this mail group. The first string may contain `\\1' forms, like the ones used by replace-match to insert sub-expressions from the matched text. For instance:

("list.\\1" "From:.* \\(.*\\)-list@majordomo.com")

The second element can also be a function. In that case, it will be called narrowed to the headers with the first element of the rule as the argument. It should return a non-nil value if it thinks that the mail belongs in that group.

The last of these groups should always be a general one, and the regular expression should always be `' so that it matches any mails that haven't been matched by any of the other regexps. (These rules are processed from the beginning of the alist toward the end. The first rule to make a match will "win", unless you have crossposting enabled. In that case, all matching rules will "win".)

If you like to tinker with this yourself, you can set this variable to a function of your choice. This function will be called without any arguments in a buffer narrowed to the headers of an incoming mail message. The function should return a list of group names that it thinks should carry this mail message.

Note that the mail backends are free to maul the poor, innocent, incoming headers all they want to. They all add Lines headers; some add X-Gnus-Group headers; most rename the Unix mbox From<SPACE> line to something else.

The mail backends all support cross-posting. If several regexps match, the mail will be "cross-posted" to all those groups. nnmail-crosspost says whether to use this mechanism or not. Note that no articles are crossposted to the general (`') group.

nnmh and nnml makes crossposts by creating hard links to the crossposted articles. However, not all file systems support hard links. If that's the case for you, set nnmail-crosspost-link-function to copy-file. (This variable is add-name-to-file by default.)

If you wish to see where the previous mail split put the messages, you can use the M-x nnmail-split-history command.

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 unsubscribe from the group. Gnus will still put all the mail from your boss in the unsubscribed group, and so, when your boss mails you "Have that report ready by Monday or you're fired!", you'll never see it and, come Tuesday, you'll still believe that you're gainfully employed while you really should be out collecting empty bottles to save up for next month's rent money.

Mail Sources

Mail can be gotten from many different sources--the mail spool, from a POP mail server, from a procmail directory, or from a maildir, for instance.

Mail Source Specifiers

You tell Gnus how to fetch mail by setting mail-sources (see section Fetching Mail) to a mail source specifier.

Here's an example:

(pop :server "pop3.mailserver.com" :user "myname")

As can be observed, a mail source specifier is a list where the first element is a mail source type, followed by an arbitrary number of keywords. Keywords that are not explicitly specified are given default values.

The following mail source types are available:

file
Get mail from a single file; typically from the mail spool. Keywords:
:path
The path of the file. Defaults to the value of the MAIL environment variable or `/usr/mail/spool/user-name'.
An example file mail source:
(file :path "/usr/spool/mail/user-name")
Or using the default path:
(file)
If the mail spool file is not located on the local machine, it's best to use POP or IMAP or the like to fetch the mail. You can not you ange-ftp file names here--it has no way to lock the mail spool while moving the mail. If it's impossible to set up a proper server, you can use ssh instead.
(setq mail-sources
      '((file :prescript "ssh host bin/getmail >%t")))
The `getmail' script would look something like the following:
#!/bin/sh
#  getmail - move mail from spool to stdout
#  flu@iki.fi

MOVEMAIL=/usr/lib/emacs/20.3/i386-redhat-linux/movemail
TMP=~/Mail/tmp
rm -f $TMP; $MOVEMAIL $MAIL $TMP >/dev/null && cat $TMP
Alter this script to fit find the `movemail' you want to use.
directory
Get mail from several files in a directory. This is typically used when you have procmail split the incoming mail into several files. Keywords:
:path
The path of the directory where the files are. There is no default value.
:suffix
Only files ending with this suffix are used. The default is `.spool'.
:predicate
Only files that have this predicate return non-nil are returned. The default is identity. This is used as an additional filter--only files that have the right suffix and satisfy this predicate are considered.
:prescript
:postscript
Script run before/after fetching mail.
An example directory mail source:
(directory :path "/home/user-name/procmail-dir/"
           :suffix ".prcml")
pop
Get mail from a POP server. Keywords:
:server
The name of the POP server. The default is taken from the MAILHOST environment variable.
:port
The port number of the POP server. The default is `pop3'.
:user
The user name to give to the POP server. The default is the login name.
:password
The password to give to the POP server. If not specified, the user is prompted.
:program
The program to use to fetch mail from the POP server. This is should be a format-like string. Here's an example:
fetchmail %u@%s -P %p %t
The valid format specifier characters are:
`t'
The name of the file the mail is to be moved to. This must always be included in this string.
`s'
The name of the server.
`P'
The port number of the server.
`u'
The user name to use.
`p'
The password to use.
The values used for these specs are taken from the values you give the corresponding keywords.
:prescript
A script to be run before fetching the mail. The syntax is the same as the :program keyword. This can also be a function to be run.
:postscript
A script to be run after fetching the mail. The syntax is the same as the :program keyword. This can also be a function to be run.
:function
The function to use to fetch mail from the POP server. The function is called with one parameter--the name of the file where the mail should be moved to.
:authentication
This can be either the symbol password or the symbol apop and says what authentication scheme to use. The default is password.
If the :program and :function keywords aren't specified, pop3-movemail will be used. Here are some examples. Fetch from the default POP server, using the default user name, and default fetcher:
(pop)
Fetch from a named server with a named user and password:
(pop :server "my.pop.server"
     :user "user-name" :password "secret")
Use `movemail' to move the mail:
(pop :program "movemail po:%u %t %p")
maildir
Get mail from a maildir. This is a type of mailbox that is supported by at least qmail and postfix, where each file in a special directory contains exactly one mail. Keywords:
:path
The path of the directory where the mails are stored. The default is `~/Maildir/new'. If you sometimes look at your mail through a pop3 daemon before fetching them with Gnus, you may also have to fetch your mails from the cur directory inside the maildir, like in the first example below. You can also get mails from remote hosts (because maildirs don't suffer from locking problems).
Two example maildir mail sources:
(maildir :path "/home/user-name/Maildir/cur")
(maildir :path "/user@remotehost.org:~/Maildir/new")
imap
Get mail from a IMAP server. If you don't want to use IMAP as intended, as a network mail reading protocol (ie with nnimap), for some reason or other, Gnus let you treat it similar to a POP server and fetches articles from a given IMAP mailbox. Keywords:
:server
The name of the IMAP server. The default is taken from the MAILHOST environment variable.
:port
The port number of the IMAP server. The default is `143', or `993' for SSL connections.
:user
The user name to give to the IMAP server. The default is the login name.
:password
The password to give to the IMAP server. If not specified, the user is prompted.
:stream
What stream to use for connecting to the server, this is one of the symbols in imap-stream-alist. Right now, this means `kerberos4', `ssl' or the default `network'.
:authenticator
Which authenticator to use for authenticating to the server, this is one of the symbols in imap-authenticator-alist. Right now, this means `kerberos4', `cram-md5', `anonymous' or the default `login'.
:mailbox
The name of the mailbox to get mail from. The default is `INBOX' which normally is the mailbox which receive incoming mail.
:predicate
The predicate used to find articles to fetch. The default, `UNSEEN UNDELETED', is probably the best choice for most people, but if you sometimes peek in your mailbox with a IMAP client and mark some articles as read (or; SEEN) you might want to set this to `nil'. Then all articles in the mailbox is fetched, no matter what. For a complete list of predicates, see RFC2060 §6.4.4.
:fetchflag
How to flag fetched articles on the server, the default `Deleted' will mark them as deleted, an alternative would be `Seen' which would simply mark them as read. These are the two most likely choices, but more flags are defined in RFC2060 §2.3.2.
:dontexpunge
If non-nil, don't remove all articles marked as deleted in the mailbox after finishing the fetch.
An example IMAP mail source:
(imap :server "mail.mycorp.com" :stream kerberos4)
webmail
Get mail from a webmail server, such as www.hotmail.com, mail.yahoo.com, www.netaddress.com and www.my-deja.com. NOTE: Webmail largely depends on w3 (url) package, whose version of "WWW 4.0pre.46 1999/10/01" or previous ones may not work. WARNING: Mails may lost. NO WARRANTY. Keywords:
:subtype
The type of the webmail server. The default is hotmail. The alternatives are yahoo, netaddress, my-deja.
:user
The user name to give to the webmail server. The default is the login name.
:password
The password to give to the webmail server. If not specified, the user is prompted.
:dontexpunge
If non-nil, only fetch unread articles and don't move them to trash folder after finishing the fetch.
An example webmail source:
(webmail :subtype 'yahoo :user "user-name" :password "secret")
Common Keywords
Common keywords can be used in any type of mail source. Keywords:
:plugged
If non-nil, fetch the mail even when Gnus is unplugged.

Mail Source Customization

The following is a list of variables that influence how the mail is fetched. You would normally not need to set or change any of these variables.

mail-source-crash-box
File where mail will be stored while processing it. The default is `~/.emacs-mail-crash-box'.
mail-source-delete-incoming
If non-nil, delete incoming files after handling them.
mail-source-directory
Directory where files (if any) will be stored. The default is `~/Mail/'. At present, the only thing this is used for is to say where the incoming files will be stored if the previous variable is nil.
mail-source-default-file-modes
All new mail files will get this file mode. The default is 384.

Fetching Mail

The way to actually tell Gnus where to get new mail from is to set mail-sources to a list of mail source specifiers (see section Mail Source Specifiers).

If this variable (and the obsolescent nnmail-spool-file) is nil, the mail backends will never attempt to fetch mail by themselves.

If you want to fetch mail both from your local spool as well as a POP mail server, you'd say something like:

(setq mail-sources
      '((file)
        (pop :server "pop3.mail.server"
             :password "secret")))

Or, if you don't want to use any of the keyword defaults:

(setq mail-sources
      '((file :path "/var/spool/mail/user-name")
        (pop :server "pop3.mail.server"
             :user "user-name"
             :port "pop3"
             :password "secret")))

When you use a mail backend, Gnus will slurp all your mail from your inbox and plonk it down in your home directory. Gnus doesn't move any mail if you're not using a mail backend--you have to do a lot of magic invocations first. At the time when you have finished drawing the pentagram, lightened the candles, and sacrificed the goat, you really shouldn't be too surprised when Gnus moves your mail.

Mail Backend Variables

These variables are (for the most part) pertinent to all the various mail backends.

nnmail-read-incoming-hook
The mail backends all call this hook after reading new mail. You can use this hook to notify any mail watch programs, if you want to.
nnmail-split-hook
Hook run in the buffer where the mail headers of each message is kept just before the splitting based on these headers is done. The hook is free to modify the buffer contents in any way it sees fit--the buffer is discarded after the splitting has been done, and no changes performed in the buffer will show up in any files. gnus-article-decode-encoded-words is one likely function to add to this hook.
nnmail-pre-get-new-mail-hook
nnmail-post-get-new-mail-hook
These are two useful hooks executed when treating new incoming mail---nnmail-pre-get-new-mail-hook (is called just before starting to handle the new mail) and nnmail-post-get-new-mail-hook (is called when the mail handling is done). Here's and example of using these two hooks to change the default file modes the new mail files get:
(add-hook 'gnus-pre-get-new-mail-hook
          (lambda () (set-default-file-modes 511)))

(add-hook 'gnus-post-get-new-mail-hook
          (lambda () (set-default-file-modes 551)))
nnmail-use-long-file-names
If non-nil, the mail backends will use long file and directory names. Groups like `mail.misc' will end up in directories (assuming use of nnml backend) or files (assuming use of nnfolder backend) like `mail.misc'. If it is nil, the same group will end up in `mail/misc'.
nnmail-delete-file-function
Function called to delete files. It is delete-file by default.
nnmail-cache-accepted-message-ids
If non-nil, put the Message-IDs of articles imported into the backend (via Gcc, for instance) into the mail duplication discovery cache. The default is nil.

Fancy Mail Splitting

If the rather simple, standard method for specifying how to split mail doesn't allow you to do what you want, you can set nnmail-split-methods to nnmail-split-fancy. Then you can play with the nnmail-split-fancy variable.

Let's look at an example value of this variable first:

;; Messages from the mailer daemon are not crossposted to any of
;; the ordinary groups.  Warnings are put in a separate group
;; from real errors.
(| ("from" mail (| ("subject" "warn.*" "mail.warning")
                   "mail.misc"))
   ;; Non-error messages are crossposted to all relevant
   ;; groups, but we don't crosspost between the group for the
   ;; (ding) list and the group for other (ding) related mail.
   (& (| (any "ding@ifi\\.uio\\.no" "ding.list")
         ("subject" "ding" "ding.misc"))
      ;; Other mailing lists...
      (any "procmail@informatik\\.rwth-aachen\\.de" "procmail.list")
      (any "SmartList@informatik\\.rwth-aachen\\.de" "SmartList.list")
      ;; Both lists below have the same suffix, so prevent
      ;; cross-posting to mkpkg.list of messages posted only to 
      ;; the bugs- list, but allow cross-posting when the
      ;; message was really cross-posted.
      (any "bugs-mypackage@somewhere" "mypkg.bugs")
      (any "mypackage@somewhere\" - "bugs-mypackage" "mypkg.list")
      ;; People...
      (any "larsi@ifi\\.uio\\.no" "people.Lars_Magne_Ingebrigtsen"))
   ;; Unmatched mail goes to the catch all group.
   "misc.misc")

This variable has the format of a split. A split is a (possibly) recursive structure where each split may contain other splits. Here are the five possible split syntaxes:

  1. `group': If the split is a string, that will be taken as a group name. Normal regexp match expansion will be done. See below for examples.
  2. (field value [- restrict [...]] split): If the split is a list, the first element of which is a string, then store the message as specified by split, if header field (a regexp) contains value (also a regexp). If restrict (yet another regexp) matches some string after field and before the end of the matched value, the split is ignored. If none of the restrict clauses match, split is processed.
  3. (| split...): If the split is a list, and the first element is | (vertical bar), then process each split until one of them matches. A split is said to match if it will cause the mail message to be stored in one or more groups.
  4. (& split...): If the split is a list, and the first element is &, then process all splits in the list.
  5. junk: If the split is the symbol junk, then don't save this message. Use with extreme caution.
  6. (: function arg1 arg2 ...): If the split is a list, and the first element is :, then the second element will be called as a function with args given as arguments. The function should return a split.
  7. (! func split): If the split is a list, and the first element is !, then SPLIT will be processed, and FUNC will be called as a function with the result of SPLIT as argument. FUNC should return a split.
  8. nil: If the split is nil, it is ignored.

In these splits, field must match a complete field name. value must match a complete word according to the fundamental mode syntax table. You can use .* in the regexps to match partial field names or words. In other words, all value's are wrapped in `\<' and `\>' pairs.

field and value can also be lisp symbols, in that case they are expanded as specified by the variable nnmail-split-abbrev-alist. This is an alist of cons cells, where the car of a cell contains the key, and the cdr contains the associated value.

nnmail-split-fancy-syntax-table is the syntax table in effect when all this splitting is performed.

If you want to have Gnus create groups dynamically based on some information in the headers (i.e., do replace-match-like substitutions in the group names), you can say things like:

(any "debian-\\b\\(\\w+\\)@lists.debian.org" "mail.debian.\\1")

In this example, messages sent to `debian-foo@lists.debian.org' will be filed in `mail.debian.foo'.

If the string contains the element `\&', then the previously matched string will be substituted. Similarly, the elements `\\1' up to `\\9' will be substituted with the text matched by the groupings 1 through 9.

Group Mail Splitting

If you subscribe to dozens of mailing lists but you don't want to maintain mail splitting rules manually, group mail splitting is for you. You just have to set to-list and/or to-address in group parameters or group customization and set nnmail-split-methods to gnus-group-split. This splitting function will scan all groups for those parameters and split mail accordingly, i.e., messages posted from or to the addresses specified in the parameters to-list or to-address of a mail group will be stored in that group.

Sometimes, mailing lists have multiple addresses, and you may want mail splitting to recognize them all: just set the extra-aliases group parameter to the list of additional addresses and it's done. If you'd rather use a regular expression, set split-regexp.

All these parameters in a group will be used to create an nnmail-split-fancy split, in which the field is `any', the value is a single regular expression that matches to-list, to-address, all of extra-aliases and all matches of split-regexp, and the split is the name of the group. restricts are also supported: just set the split-exclude parameter to a list of regular expressions.

If you can't get the right split to be generated using all these parameters, or you just need something fancier, you can set the parameter split-spec to an nnmail-split-fancy split. In this case, all other aforementioned parameters will be ignored by gnus-group-split. In particular, split-spec may be set to nil, in which case the group will be ignored by gnus-group-split.

gnus-group-split will do cross-posting on all groups that match, by defining a single & fancy split containing one split for each group. If a message doesn't match any split, it will be stored in the group named in gnus-group-split-default-catch-all-group, unless some group has split-spec set to catch-all, in which case that group is used as the catch-all group. Note that, in this case, there's no cross-posting, as a | fancy split encloses the & split and the catch-all group.

It's time for an example. Assume the following group parameters have been defined:

nnml:mail.bar:
((to-address . "bar@femail.com")
 (split-regexp . ".*@femail\\.com"))
nnml:mail.foo:
((to-list . "foo@nowhere.gov")
 (extra-aliases "foo@localhost" "foo-redist@home")
 (split-exclude "bugs-foo" "rambling-foo")
 (admin-address . "foo-request@nowhere.gov"))
nnml:mail.others:
((split-spec . catch-all))

Setting nnmail-split-methods to gnus-group-split will behave as if nnmail-split-fancy had been selected and variable nnmail-split-fancy had been set as follows:

(| (& (any "\\(bar@femail\\.com\\|.*@femail\\.com\\)" "mail.bar")
      (any "\\(foo@nowhere\\.gov\\|foo@localhost\\|foo-redist@home\\)"
           - "bugs-foo" - "rambling-foo" "mail.foo"))
   "mail.others")

If you'd rather not use group splitting for all your mail groups, you may use it for only some of them, by using nnmail-split-fancy splits like this:

(: gnus-mlsplt-fancy GROUPS NO-CROSSPOST CATCH-ALL)

groups may be a regular expression or a list of group names whose parameters will be scanned to generate the output split. no-crosspost can be used to disable cross-posting; in this case, a single | split will be output. catch-all may be the name of a group to be used as the default catch-all group. If catch-all is nil, or if split-regexp matches the empty string in any selected group, no catch-all split will be issued. Otherwise, if some group has split-spec set to catch-all, this group will override the value of the catch-all argument.

Unfortunately, scanning all groups and their parameters can be quite slow, especially considering that it has to be done for every message. But don't despair! The function gnus-group-split-setup can be used to select gnus-group-split in a much more efficient way. It sets nnmail-split-methods to nnmail-split-fancy and sets nnmail-split-fancy to the split produced by gnus-group-split-fancy. Thus, the group parameters are only scanned once, no matter how many messages are split.

However, if you change group parameters, you have to update nnmail-split-fancy manually. You can do it by running gnus-group-split-update. If you'd rather have it updated automatically, just tell gnus-group-split-setup to do it for you. For example, add to your `.gnus':

(gnus-group-split-setup AUTO-UPDATE CATCH-ALL)

If auto-update is non-nil, gnus-group-split-update will be added to nnmail-pre-get-new-mail-hook, so you won't ever have to worry about updating nnmail-split-fancy again. If you don't omit catch-all (it's optional), gnus-group-split-default-catch-all-group will be set to its value.

Because you may want to change nnmail-split-fancy after it is set by gnus-group-split-update, this function will run gnus-group-split-updated-hook just before finishing.

Incorporating Old Mail

Most people have lots of old mail stored in various file formats. If you have set up Gnus to read mail using one of the spiffy Gnus mail backends, you'll probably wish to have that old mail incorporated into your mail groups.

Doing so can be quite easy.

To take an example: You're reading mail using nnml (see section Mail Spool), and have set nnmail-split-methods to a satisfactory value (see section Splitting Mail). You have an old Unix mbox file filled with important, but old, mail. You want to move it into your nnml groups.

Here's how:

  1. Go to the group buffer.
  2. Type `G f' and give the path to the mbox file when prompted to create an nndoc group from the mbox file (see section Foreign Groups).
  3. Type `SPACE' to enter the newly created group.
  4. Type `M P b' to process-mark all articles in this group's buffer (see section Setting Process Marks).
  5. Type `B r' to respool all the process-marked articles, and answer `nnml' when prompted (see section Mail Group Commands).

All the mail messages in the mbox file will now also be spread out over all your nnml groups. Try entering them and check whether things have gone without a glitch. If things look ok, you may consider deleting the mbox file, but I wouldn't do that unless I was absolutely sure that all the mail has ended up where it should be.

Respooling is also a handy thing to do if you're switching from one mail backend to another. Just respool all the mail in the old mail groups using the new mail backend.

Expiring Mail

Traditional mail readers have a tendency to remove mail articles when you mark them as read, in some way. Gnus takes a fundamentally different approach to mail reading.

Gnus basically considers mail just to be news that has been received in a rather peculiar manner. It does not think that it has the power to actually change the mail, or delete any mail messages. If you enter a mail group, and mark articles as "read", or kill them in some other fashion, the mail articles will still exist on the system. I repeat: Gnus will not delete your old, read mail. Unless you ask it to, of course.

To make Gnus get rid of your unwanted mail, you have to mark the articles as expirable. This does not mean that the articles will disappear right away, however. In general, a mail article will be deleted from your system if, 1) it is marked as expirable, AND 2) it is more than one week old. If you do not mark an article as expirable, it will remain on your system until hell freezes over. This bears repeating one more time, with some spurious capitalizations: IF you do NOT mark articles as EXPIRABLE, Gnus will NEVER delete those ARTICLES.

You do not have to mark articles as expirable by hand. Groups that match the regular expression gnus-auto-expirable-newsgroups will have all articles that you read marked as expirable automatically. All articles marked as expirable have an `E' in the first column in the summary buffer.

By default, if you have auto expiry switched on, Gnus will mark all the articles you read as expirable, no matter if they were read or unread before. To avoid having articles marked as read marked as expirable automatically, you can put something like the following in your `.gnus' file:

(remove-hook 'gnus-mark-article-hook
             'gnus-summary-mark-read-and-unread-as-read)
(add-hook 'gnus-mark-article-hook 'gnus-summary-mark-unread-as-read)

Note that making a group auto-expirable doesn't mean that all read articles are expired--only the articles marked as expirable will be expired. Also note that using the d command won't make groups expirable--only semi-automatic marking of articles as read will mark the articles as expirable in auto-expirable groups.

Let's say you subscribe to a couple of mailing lists, and you want the articles you have read to disappear after a while:

(setq gnus-auto-expirable-newsgroups
      "mail.nonsense-list\\|mail.nice-list")

Another way to have auto-expiry happen is to have the element auto-expire in the group parameters of the group.

If you use adaptive scoring (see section Adaptive Scoring) and auto-expiring, you'll have problems. Auto-expiring and adaptive scoring don't really mix very well.

The nnmail-expiry-wait variable supplies the default time an expirable article has to live. Gnus starts counting days from when the message arrived, not from when it was sent. The default is seven days.

Gnus also supplies a function that lets you fine-tune how long articles are to live, based on what group they are in. Let's say you want to have one month expiry period in the `mail.private' group, a one day expiry period in the `mail.junk' group, and a six day expiry period everywhere else:

(setq nnmail-expiry-wait-function
      (lambda (group)
       (cond ((string= group "mail.private")
               31)
             ((string= group "mail.junk")
               1)
             ((string= group "important")
               'never)
             (t
               6))))

The group names this function is fed are "unadorned" group names--no `nnml:' prefixes and the like.

The nnmail-expiry-wait variable and nnmail-expiry-wait-function function can either be a number (not necessarily an integer) or one of the symbols immediate or never.

You can also use the expiry-wait group parameter to selectively change the expiry period (see section Group Parameters).

If nnmail-keep-last-article is non-nil, Gnus will never expire the final article in a mail newsgroup. This is to make life easier for procmail users.

By the way: That line up there, about Gnus never expiring non-expirable articles, is a lie. If you put total-expire in the group parameters, articles will not be marked as expirable, but all read articles will be put through the expiry process. Use with extreme caution. Even more dangerous is the gnus-total-expirable-newsgroups variable. All groups that match this regexp will have all read articles put through the expiry process, which means that all old mail articles in the groups in question will be deleted after a while. Use with extreme caution, and don't come crying to me when you discover that the regexp you used matched the wrong group and all your important mail has disappeared. Be a man! Or a woman! Whatever you feel more comfortable with! So there!

Most people make most of their mail groups total-expirable, though.

If gnus-inhibit-user-auto-expire is non-nil, user marking commands will not mark an article as expirable, even if the group has auto-expire turned on.

Washing Mail

Mailers and list servers are notorious for doing all sorts of really, really stupid things with mail. "Hey, RFC822 doesn't explicitly prohibit us from adding the string wE aRe ElItE!!!!!1!! to the end of all lines passing through our server, so let's do that!!!!1!" Yes, but RFC822 wasn't designed to be read by morons. Things that were considered to be self-evident were not discussed. So. Here we are.

Case in point: The German version of Microsoft Exchange adds `AW: ' to the subjects of replies instead of `Re: '. I could pretend to be shocked and dismayed by this, but I haven't got the energy. It is to laugh.

Gnus provides a plethora of functions for washing articles while displaying them, but it might be nicer to do the filtering before storing the mail to disc. For that purpose, we have three hooks and various functions that can be put in these hooks.

nnmail-prepare-incoming-hook
This hook is called before doing anything with the mail and is meant for grand, sweeping gestures. It is called in a buffer that contains all the new, incoming mail. Functions to be used include:
nnheader-ms-strip-cr
Remove trailing carriage returns from each line. This is default on Emacs running on MS machines.
nnmail-prepare-incoming-header-hook
This hook is called narrowed to each header. It can be used when cleaning up the headers. Functions that can be used include:
nnmail-remove-leading-whitespace
Clear leading white space that "helpful" listservs have added to the headers to make them look nice. Aaah.
nnmail-remove-list-identifiers
Some list servers add an identifier--for example, `(idm)'---to the beginning of all Subject headers. I'm sure that's nice for people who use stone age mail readers. This function will remove strings that match the nnmail-list-identifiers regexp, which can also be a list of regexp. For instance, if you want to remove the `(idm)' and the `nagnagnag' identifiers:
(setq nnmail-list-identifiers
      '("(idm)" "nagnagnag"))
This can also be done non-destructively with gnus-list-identifiers, See section Article Hiding.
nnmail-remove-tabs
Translate all `TAB' characters into `SPACE' characters.
nnmail-fix-eudora-headers
Eudora produces broken References headers, but OK In-Reply-To headers. This function will get rid of the References headers.
nnmail-prepare-incoming-message-hook
This hook is called narrowed to each message. Functions to be used include:
article-de-quoted-unreadable
Decode Quoted Readable encoding.

Duplicates

If you are a member of a couple of mailing lists, you will sometimes receive two copies of the same mail. This can be quite annoying, so nnmail checks for and treats any duplicates it might find. To do this, it keeps a cache of old Message-IDs--- nnmail-message-id-cache-file, which is `~/.nnmail-cache' by default. The approximate maximum number of Message-IDs stored there is controlled by the nnmail-message-id-cache-length variable, which is 1000 by default. (So 1000 Message-IDs will be stored.) If all this sounds scary to you, you can set nnmail-treat-duplicates to warn (which is what it is by default), and nnmail won't delete duplicate mails. Instead it will insert a warning into the head of the mail saying that it thinks that this is a duplicate of a different message.

This variable can also be a function. If that's the case, the function will be called from a buffer narrowed to the message in question with the Message-ID as a parameter. The function must return either nil, warn, or delete.

You can turn this feature off completely by setting the variable to nil.

If you want all the duplicate mails to be put into a special duplicates group, you could do that using the normal mail split methods:

(setq nnmail-split-fancy
      '(| ;; Messages duplicates go to a separate group.
          ("gnus-warning" "duplication of message" "duplicate")
          ;; Message from daemons, postmaster, and the like to another.
          (any mail "mail.misc")
          ;; Other rules.
          [ ... ] ))

Or something like:

(setq nnmail-split-methods
      '(("duplicates" "^Gnus-Warning:")
        ;; Other rules.
        [...]))

Here's a neat feature: If you know that the recipient reads her mail with Gnus, and that she has nnmail-treat-duplicates set to delete, you can send her as many insults as you like, just by using a Message-ID of a mail that you know that she's already received. Think of all the fun! She'll never see any of it! Whee!

Not Reading Mail

If you start using any of the mail backends, they have the annoying habit of assuming that you want to read mail with them. This might not be unreasonable, but it might not be what you want.

If you set mail-sources and nnmail-spool-file to nil, none of the backends will ever attempt to read incoming mail, which should help.

This might be too much, if, for instance, you are reading mail quite happily with nnml and just want to peek at some old RMAIL file you have stashed away with nnbabyl. All backends have variables called backend-get-new-mail. If you want to disable the nnbabyl mail reading, you edit the virtual server for the group to have a setting where nnbabyl-get-new-mail to nil.

All the mail backends will call nn*-prepare-save-mail-hook narrowed to the article to be saved before saving it when reading incoming mail.

Choosing a Mail Backend

Gnus will read the mail spool when you activate a mail group. The mail file is first copied to your home directory. What happens after that depends on what format you want to store your mail in.

There are five different mail backends in the standard Gnus, and more backends are available separately. The mail backend most people use (because it is the fastest and most flexible) is nnml (see section Mail Spool).

Unix Mail Box

The nnmbox backend will use the standard Un*x mbox file to store mail. nnmbox will add extra headers to each mail article to say which group it belongs in.

Virtual server settings:

nnmbox-mbox-file
The name of the mail box in the user's home directory.
nnmbox-active-file
The name of the active file for the mail box.
nnmbox-get-new-mail
If non-nil, nnmbox will read incoming mail and split it into groups.

Rmail Babyl

The nnbabyl backend will use a babyl mail box (aka. rmail mbox) to store mail. nnbabyl will add extra headers to each mail article to say which group it belongs in.

Virtual server settings:

nnbabyl-mbox-file
The name of the rmail mbox file.
nnbabyl-active-file
The name of the active file for the rmail box.
nnbabyl-get-new-mail
If non-nil, nnbabyl will read incoming mail.

Mail Spool

The nnml spool mail format isn't compatible with any other known format. It should be used with some caution.

If you use this backend, Gnus will split all incoming mail into files, one file for each mail, and put the articles into the corresponding directories under the directory specified by the nnml-directory variable. The default value is `~/Mail/'.

You do not have to create any directories beforehand; Gnus will take care of all that.

If you have a strict limit as to how many files you are allowed to store in your account, you should not use this backend. As each mail gets its own file, you might very well occupy thousands of inodes within a few weeks. If this is no problem for you, and it isn't a problem for you having your friendly systems administrator walking around, madly, shouting "Who is eating all my inodes?! Who? Who!?!", then you should know that this is probably the fastest format to use. You do not have to trudge through a big mbox file just to read your new mail.

nnml is probably the slowest backend when it comes to article splitting. It has to create lots of files, and it also generates NOV databases for the incoming mails. This makes it the fastest backend when it comes to reading mail.

Virtual server settings:

nnml-directory
All nnml directories will be placed under this directory.
nnml-active-file
The active file for the nnml server.
nnml-newsgroups-file
The nnml group descriptions file. See section Newsgroups File Format.
nnml-get-new-mail
If non-nil, nnml will read incoming mail.
nnml-nov-is-evil
If non-nil, this backend will ignore any NOV files.
nnml-nov-file-name
The name of the NOV files. The default is `.overview'.
nnml-prepare-save-mail-hook
Hook run narrowed to an article before saving.

If your nnml groups and NOV files get totally out of whack, you can do a complete update by typing M-x nnml-generate-nov-databases. This command will trawl through the entire nnml hierarchy, looking at each and every article, so it might take a while to complete. A better interface to this functionality can be found in the server buffer (see section Server Commands).

MH Spool

nnmh is just like nnml, except that is doesn't generate NOV databases and it doesn't keep an active file. This makes nnmh a much slower backend than nnml, but it also makes it easier to write procmail scripts for.

Virtual server settings:

nnmh-directory
All nnmh directories will be located under this directory.
nnmh-get-new-mail
If non-nil, nnmh will read incoming mail.
nnmh-be-safe
If non-nil, nnmh will go to ridiculous lengths to make sure that the articles in the folder are actually what Gnus thinks they are. It will check date stamps and stat everything in sight, so setting this to t will mean a serious slow-down. If you never use anything but Gnus to read the nnmh articles, you do not have to set this variable to t.

Mail Folders

nnfolder is a backend for storing each mail group in a separate file. Each file is in the standard Un*x mbox format. nnfolder will add extra headers to keep track of article numbers and arrival dates.

Virtual server settings:

nnfolder-directory
All the nnfolder mail boxes will be stored under this directory.
nnfolder-active-file
The name of the active file.
nnfolder-newsgroups-file
The name of the group descriptions file. See section Newsgroups File Format.
nnfolder-get-new-mail
If non-nil, nnfolder will read incoming mail.
nnfolder-save-buffer-hook
Hook run before saving the folders. Note that Emacs does the normal backup renaming of files even with the nnfolder buffers. If you wish to switch this off, you could say something like the following in your `.emacs' file:
(defun turn-off-backup ()
  (set (make-local-variable 'backup-inhibited) t))

(add-hook 'nnfolder-save-buffer-hook 'turn-off-backup)
nnfolder-delete-mail-hook
Hook run in a buffer narrowed to the message that is to be deleted. This function can be used to copy the message to somewhere else, or to extract some information from it before removing it.

If you have lots of nnfolder-like files you'd like to read with nnfolder, you can use the M-x nnfolder-generate-active-file command to make nnfolder aware of all likely files in nnfolder-directory. This only works if you use long file names, though.

Comparing Mail Backends

First, just for terminology, the backend is the common word for a low-level access method--a transport, if you will, by which something is acquired. The sense is that one's mail has to come from somewhere, and so selection of a suitable backend is required in order to get that mail within spitting distance of Gnus.

The same concept exists for Usenet itself: Though access to articles is typically done by NNTP these days, once upon a midnight dreary, everyone in the world got at Usenet by running a reader on the machine where the articles lay (the machine which today we call an NNTP server), and access was by the reader stepping into the articles' directory spool area directly. One can still select between either the nntp or nnspool backends, to select between these methods, if one happens actually to live on the server (or can see its spool directly, anyway, via NFS).

The goal in selecting a mail backend is to pick one which simultaneously represents a suitable way of dealing with the original format plus leaving mail in a form that is convenient to use in the future. Here are some high and low points on each:

nnmbox
UNIX systems have historically had a single, very common, and well- defined format. All messages arrive in a single spool file, and they are delineated by a line whose regular expression matches `^From_'. (My notational use of `_' is to indicate a space, to make it clear in this instance that this is not the RFC-specified `From:' header.) Because Emacs and therefore Gnus emanate historically from the Unix environment, it is simplest if one does not mess a great deal with the original mailbox format, so if one chooses this backend, Gnus' primary activity in getting mail from the real spool area to Gnus' preferred directory is simply to copy it, with no (appreciable) format change in the process. It is the "dumbest" way to move mail into availability in the Gnus environment. This makes it fast to move into place, but slow to parse, when Gnus has to look at what's where.
nnbabyl
Once upon a time, there was the DEC-10 and DEC-20, running operating systems called TOPS and related things, and the usual (only?) mail reading environment was a thing called Babyl. I don't know what format was used for mail landing on the system, but Babyl had its own internal format to which mail was converted, primarily involving creating a spool-file-like entity with a scheme for inserting Babyl-specific headers and status bits above the top of each message in the file. RMAIL was Emacs' first mail reader, it was written by Richard Stallman, and Stallman came out of that TOPS/Babyl environment, so he wrote RMAIL to understand the mail files folks already had in existence. Gnus (and VM, for that matter) continue to support this format because it's perceived as having some good qualities in those mailer-specific headers/status bits stuff. RMAIL itself still exists as well, of course, and is still maintained by Stallman. Both of the above forms leave your mail in a single file on your filesystem, and they must parse that entire file each time you take a look at your mail.
nnml
nnml is the backend which smells the most as though you were actually operating with an nnspool-accessed Usenet system. (In fact, I believe nnml actually derived from nnspool code, lo these years ago.) One's mail is taken from the original spool file, and is then cut up into individual message files, 1:1. It maintains a Usenet-style active file (analogous to what one finds in an INN- or CNews-based news system in (for instance) `/var/lib/news/active', or what is returned via the `NNTP LIST' verb) and also creates overview files for efficient group entry, as has been defined for NNTP servers for some years now. It is slower in mail-splitting, due to the creation of lots of files, updates to the nnml active file, and additions to overview files on a per-message basis, but it is extremely fast on access because of what amounts to the indexing support provided by the active file and overviews. nnml costs inodes in a big way; that is, it soaks up the resource which defines available places in the filesystem to put new files. Sysadmins take a dim view of heavy inode occupation within tight, shared filesystems. But if you live on a personal machine where the filesystem is your own and space is not at a premium, nnml wins big. It is also problematic using this backend if you are living in a FAT16-based Windows world, since much space will be wasted on all these tiny files.
nnmh
The Rand MH mail-reading system has been around UNIX systems for a very long time; it operates by splitting one's spool file of messages into individual files, but with little or no indexing support -- nnmh is considered to be semantically equivalent to "nnml without active file or overviews". This is arguably the worst choice, because one gets the slowness of individual file creation married to the slowness of access parsing when learning what's new in one's groups.
nnfolder
Basically the effect of nnfolder is nnmbox (the first method described above) on a per-group basis. That is, nnmbox itself puts *all* one's mail in one file; nnfolder provides a little bit of optimization to this so that each of one's mail groups has a Unix mail box file. It's faster than nnmbox because each group can be parsed separately, and still provides the simple Unix mail box format requiring minimal effort in moving the mail around. In addition, it maintains an "active" file making it much faster for Gnus to figure out how many messages there are in each separate group. If you have groups that are expected to have a massive amount of messages, nnfolder is not the best choice, but if you receive only a moderate amount of mail, nnfolder is probably the most friendly mail backend all over.

Browsing the Web

Web-based discussion forums are getting more and more popular. On many subjects, the web-based forums have become the most important forums, eclipsing the importance of mailing lists and news groups. The reason is easy to understand--they are friendly to new users; you just point and click, and there's the discussion. With mailing lists, you have to go through a cumbersome subscription procedure, and most people don't even know what a news group is.

The problem with this scenario is that web browsers are not very good at being newsreaders. They do not keep track of what articles you've read; they do not allow you to score on subjects you're interested in; they do not allow off-line browsing; they require you to click around and drive you mad in the end.

So--if web browsers suck at reading discussion forums, why not use Gnus to do it instead?

Gnus has been getting a bit of a collection of backends for providing interfaces to these sources.

The main caveat with all these web sources is that they probably won't work for a very long time. Gleaning information from the HTML data is guesswork at best, and when the layout is altered, the Gnus backend will fail. If you have reasonably new versions of these backends, though, you should be ok.

One thing all these Web methods have in common is that the Web sources are often down, unavailable or just plain too slow to be fun. In those cases, it makes a lot of sense to let the Gnus Agent (see section Gnus Unplugged) handle downloading articles, and then you can read them at leisure from your local disk. No more World Wide Wait for you.

Web Searches

It's, like, too neat to search the Usenet for articles that match a string, but it, like, totally sucks, like, totally, to use one of those, like, Web browsers, and you, like, have to, rilly, like, look at the commercials, so, like, with Gnus you can do rad, rilly, searches without having to use a browser.

The nnweb backend allows an easy interface to the mighty search engine. You create an nnweb group, enter a search pattern, and then enter the group and read the articles like you would any normal group. The G w command in the group buffer (see section Foreign Groups) will do this in an easy-to-use fashion.

nnweb groups don't really lend themselves to being solid groups--they have a very fleeting idea of article numbers. In fact, each time you enter an nnweb group (not even changing the search pattern), you are likely to get the articles ordered in a different manner. Not even using duplicate suppression (see section Duplicate Suppression) will help, since nnweb doesn't even know the Message-ID of the articles before reading them using some search engines (DejaNews, for instance). The only possible way to keep track of which articles you've read is by scoring on the Date header--mark all articles posted before the last date you read the group as read.

If the search engine changes its output substantially, nnweb won't be able to parse it and will fail. One could hardly fault the Web providers if they were to do this--their raison d'être is to make money off of advertisements, not to provide services to the community. Since nnweb washes the ads off all the articles, one might think that the providers might be somewhat miffed. We'll see.

You must have the url and w3 package installed to be able to use nnweb.

Virtual server variables:

nnweb-type
What search engine type is being used. The currently supported types are dejanews, dejanewsold, altavista and reference.
nnweb-search
The search string to feed to the search engine.
nnweb-max-hits
Advisory maximum number of hits per search to display. The default is 100.
nnweb-type-definition
Type-to-definition alist. This alist says what nnweb should do with the various search engine types. The following elements must be present:
article
Function to decode the article and provide something that Gnus understands.
map
Function to create an article number to message header and URL alist.
search
Function to send the search string to the search engine.
address
The address the aforementioned function should send the search string to.
id
Format string URL to fetch an article by Message-ID.

Slashdot

Slashdot (`http://slashdot.org/') is a popular news site, with lively discussion following the news articles. nnslashdot will let you read this forum in a convenient manner.

The easiest way to read this source is to put something like the following in your `.gnus.el' file:

(setq gnus-secondary-select-methods
      '((nnslashdot "")))

This will make Gnus query the nnslashdot backend for new comments and groups. The F command will subscribe each new news article as a new Gnus group, and you can read the comments by entering these groups. (Note that the default subscription method is to subscribe new groups as zombies. Other methods are available (see section Subscription Methods).

If you want to remove an old nnslashdot group, the G DEL command is the most handy tool (see section Foreign Groups).

When following up to nnslashdot comments (or posting new comments), some light HTMLizations will be performed. In particular, text quoted with `> ' will be quoted with blockquote instead, and signatures will have br added to the end of each line. Other than that, you can just write HTML directly into the message buffer. Note that Slashdot filters out some HTML forms.

The following variables can be altered to change its behavior:

nnslashdot-threaded
Whether nnslashdot should display threaded groups or not. The default is t. To be able to display threads, nnslashdot has to retrieve absolutely all comments in a group upon entry. If a threaded display is not required, nnslashdot will only retrieve the comments that are actually wanted by the user. Threading is nicer, but much, much slower than untreaded.
nnslashdot-login-name
The login name to use when posting.
nnslashdot-password
The password to use when posting.
nnslashdot-directory
Where nnslashdot will store its files. The default value is `~/News/slashdot/'.
nnslashdot-active-url
The URL format string that will be used to fetch the information on news articles and comments. The default is `http://slashdot.org/search.pl?section=&min=%d'.
nnslashdot-comments-url
The URL format string that will be used to fetch comments. The default is `http://slashdot.org/comments.pl?sid=%s&threshold=%d&commentsort=%d&mode=flat&startat=%d'.
nnslashdot-article-url
The URL format string that will be used to fetch the news article. The default is `http://slashdot.org/article.pl?sid=%s&mode=nocomment'.
nnslashdot-threshold
The score threshold. The default is -1.
nnslashdot-group-number
The number of old groups, in addition to the ten latest, to keep updated. The default is 0.

Ultimate

The Ultimate Bulletin Board (`http://www.ultimatebb.com/') is probably the most popular Web bulletin board system used. It has a quite regular and nice interface, and it's possible to get the information Gnus needs to keep groups updated.

The easiest way to get started with nnultimate is to say something like the following in the group buffer: B nnultimate RET http://www.tcj.com/messboard/ubbcgi/ RET. (Substitute the URL (not including `Ultimate.cgi' or the like at the end) for a forum you're interested in; there's quite a list of them on the Ultimate web site.) Then subscribe to the groups you're interested in from the server buffer, and read them from the group buffer.

The following nnultimate variables can be altered:

nnultimate-directory
The directory where nnultimate stores its files. The default is `~/News/ultimate/'.

Web Archive

Some mailing lists only have archives on Web servers, such as `http://www.egroups.com/' and `http://www.mail-archive.com/'. It has a quite regular and nice interface, and it's possible to get the information Gnus needs to keep groups updated.

The easiest way to get started with nnwarchive is to say something like the following in the group buffer: M-x gnus-group-make-nnwarchive-group RET an_egroup RET egroups RET www.egroups.com RET your@email.address RET. (Substitute the AN_EGROUP with the mailing list you subscribed, the YOUR@EMAIL.ADDRESS with your email address.), or to browse the backend by B nnwarchive RET mail-archive RET.

The following nnwarchive variables can be altered:

nnwarchive-directory
The directory where nnwarchive stores its files. The default is `~/News/warchive/'.
nnwarchive-login
The account name on the web server.
nnwarchive-passwd
The password for your account on the web server.

Other Sources

Gnus can do more than just read news or mail. The methods described below allow Gnus to view directories and files as if they were newsgroups.

Directory Groups

If you have a directory that has lots of articles in separate files in it, you might treat it as a newsgroup. The files have to have numerical names, of course.

This might be an opportune moment to mention ange-ftp (and its successor efs), that most wonderful of all wonderful Emacs packages. When I wrote nndir, I didn't think much about it--a backend to read directories. Big deal.

ange-ftp changes that picture dramatically. For instance, if you enter the ange-ftp file name `/ftp.hpc.uh.edu:/pub/emacs/ding-list/' as the directory name, ange-ftp or efs will actually allow you to read this directory over at `sina' as a newsgroup. Distributed news ahoy!

nndir will use NOV files if they are present.

nndir is a "read-only" backend--you can't delete or expire articles with this method. You can use nnmh or nnml for whatever you use nndir for, so you could switch to any of those methods if you feel the need to have a non-read-only nndir.

Anything Groups

From the nndir backend (which reads a single spool-like directory), it's just a hop and a skip to nneething, which pretends that any arbitrary directory is a newsgroup. Strange, but true.

When nneething is presented with a directory, it will scan this directory and assign article numbers to each file. When you enter such a group, nneething must create "headers" that Gnus can use. After all, Gnus is a newsreader, in case you're forgetting. nneething does this in a two-step process. First, it snoops each file in question. If the file looks like an article (i.e., the first few lines look like headers), it will use this as the head. If this is just some arbitrary file without a head (e.g. a C source file), nneething will cobble up a header out of thin air. It will use file ownership, name and date and do whatever it can with these elements.

All this should happen automatically for you, and you will be presented with something that looks very much like a newsgroup. Totally like a newsgroup, to be precise. If you select an article, it will be displayed in the article buffer, just as usual.

If you select a line that represents a directory, Gnus will pop you into a new summary buffer for this nneething group. And so on. You can traverse the entire disk this way, if you feel like, but remember that Gnus is not dired, really, and does not intend to be, either.

There are two overall modes to this action--ephemeral or solid. When doing the ephemeral thing (i.e., G D from the group buffer), Gnus will not store information on what files you have read, and what files are new, and so on. If you create a solid nneething group the normal way with G m, Gnus will store a mapping table between article numbers and file names, and you can treat this group like any other groups. When you activate a solid nneething group, you will be told how many unread articles it contains, etc., etc.

Some variables:

nneething-map-file-directory
All the mapping files for solid nneething groups will be stored in this directory, which defaults to `~/.nneething/'.
nneething-exclude-files
All files that match this regexp will be ignored. Nice to use to exclude auto-save files and the like, which is what it does by default.
nneething-include-files
Regexp saying what files to include in the group. If this variable is non-nil, only files matching this regexp will be included.
nneething-map-file
Name of the map files.

Document Groups

nndoc is a cute little thing that will let you read a single file as a newsgroup. Several files types are supported:

babyl
The babyl (rmail) mail box.
mbox
The standard Unix mbox file.
mmdf
The MMDF mail box format.
news
Several news articles appended into a file.
rnews
The rnews batch transport format.
forward
Forwarded articles.
nsmail
Netscape mail boxes.
mime-parts
MIME multipart messages.
standard-digest
The standard (RFC 1153) digest format.
slack-digest
Non-standard digest format--matches most things, but does it badly.

You can also use the special "file type" guess, which means that nndoc will try to guess what file type it is looking at. digest means that nndoc should guess what digest type the file is.

nndoc will not try to change the file or insert any extra headers into it--it will simply, like, let you use the file as the basis for a group. And that's it.

If you have some old archived articles that you want to insert into your new & spiffy Gnus mail backend, nndoc can probably help you with that. Say you have an old `RMAIL' file with mail that you now want to split into your new nnml groups. You look at that file using nndoc (using the G f command in the group buffer (see section Foreign Groups)), set the process mark on all the articles in the buffer (M P b, for instance), and then re-spool (B r) using nnml. If all goes well, all the mail in the `RMAIL' file is now also stored in lots of nnml directories, and you can delete that pesky `RMAIL' file. If you have the guts!

Virtual server variables:

nndoc-article-type
This should be one of mbox, babyl, digest, news, rnews, mmdf, forward, rfc934, rfc822-forward, mime-parts, standard-digest, slack-digest, clari-briefs, nsmail or guess.
nndoc-post-type
This variable says whether Gnus is to consider the group a news group or a mail group. There are two valid values: mail (the default) and news.

Document Server Internals

Adding new document types to be recognized by nndoc isn't difficult. You just have to whip up a definition of what the document looks like, write a predicate function to recognize that document type, and then hook into nndoc.

First, here's an example document type definition:

(mmdf
 (article-begin .  "^\^A\^A\^A\^A\n")
 (body-end .  "^\^A\^A\^A\^A\n"))

The definition is simply a unique name followed by a series of regexp pseudo-variable settings. Below are the possible variables--don't be daunted by the number of variables; most document types can be defined with very few settings:

first-article
If present, nndoc will skip past all text until it finds something that match this regexp. All text before this will be totally ignored.
article-begin
This setting has to be present in all document type definitions. It says what the beginning of each article looks like.
head-begin-function
If present, this should be a function that moves point to the head of the article.
nndoc-head-begin
If present, this should be a regexp that matches the head of the article.
nndoc-head-end
This should match the end of the head of the article. It defaults to `^$'---the empty line.
body-begin-function
If present, this function should move point to the beginning of the body of the article.
body-begin
This should match the beginning of the body of the article. It defaults to `^\n'.
body-end-function
If present, this function should move point to the end of the body of the article.
body-end
If present, this should match the end of the body of the article.
file-end
If present, this should match the end of the file. All text after this regexp will be totally ignored.

So, using these variables nndoc is able to dissect a document file into a series of articles, each with a head and a body. However, a few more variables are needed since not all document types are all that news-like--variables needed to transform the head or the body into something that's palatable for Gnus:

prepare-body-function
If present, this function will be called when requesting an article. It will be called with point at the start of the body, and is useful if the document has encoded some parts of its contents.
article-transform-function
If present, this function is called when requesting an article. It's meant to be used for more wide-ranging transformation of both head and body of the article.
generate-head-function
If present, this function is called to generate a head that Gnus can understand. It is called with the article number as a parameter, and is expected to generate a nice head for the article in question. It is called when requesting the headers of all articles.

Let's look at the most complicated example I can come up with--standard digests:

(standard-digest
 (first-article . ,(concat "^" (make-string 70 ?-) "\n\n+"))
 (article-begin . ,(concat "\n\n" (make-string 30 ?-) "\n\n+"))
 (prepare-body-function . nndoc-unquote-dashes)
 (body-end-function . nndoc-digest-body-end)
 (head-end . "^ ?$")
 (body-begin . "^ ?\n")
 (file-end . "^End of .*digest.*[0-9].*\n\\*\\*\\|^End of.*Digest *$")
 (subtype digest guess))

We see that all text before a 70-width line of dashes is ignored; all text after a line that starts with that `^End of' is also ignored; each article begins with a 30-width line of dashes; the line separating the head from the body may contain a single space; and that the body is run through nndoc-unquote-dashes before being delivered.

To hook your own document definition into nndoc, use the nndoc-add-type function. It takes two parameters--the first is the definition itself and the second (optional) parameter says where in the document type definition alist to put this definition. The alist is traversed sequentially, and nndoc-TYPE-type-p is called for a given type TYPE. So nndoc-mmdf-type-p is called to see whether a document is of mmdf type, and so on. These type predicates should return nil if the document is not of the correct type; t if it is of the correct type; and a number if the document might be of the correct type. A high number means high probability; a low number means low probability with `0' being the lowest valid number.

SOUP

In the PC world people often talk about "offline" newsreaders. These are thingies that are combined reader/news transport monstrosities. With built-in modem programs. Yecchh!

Of course, us Unix Weenie types of human beans use things like uucp and, like, nntpd and set up proper news and mail transport things like Ghod intended. And then we just use normal newsreaders.

However, it can sometimes be convenient to do something that's a bit easier on the brain if you have a very slow modem, and you're not really that interested in doing things properly.

A file format called SOUP has been developed for transporting news and mail from servers to home machines and back again. It can be a bit fiddly.

First some terminology:

server
This is the machine that is connected to the outside world and where you get news and/or mail from.
home machine
This is the machine that you want to do the actual reading and responding on. It is typically not connected to the rest of the world in any way.
packet
Something that contains messages and/or commands. There are two kinds of packets:
message packets
These are packets made at the server, and typically contain lots of messages for you to read. These are called `SoupoutX.tgz' by default, where x is a number.
response packets
These are packets made at the home machine, and typically contains replies that you've written. These are called `SoupinX.tgz' by default, where x is a number.
  1. You log in on the server and create a SOUP packet. You can either use a dedicated SOUP thingie (like the awk program), or you can use Gnus to create the packet with its SOUP commands (O s and/or G s b; and then G s p) (see section SOUP Commands).
  2. You transfer the packet home. Rail, boat, car or modem will do fine.
  3. You put the packet in your home directory.
  4. You fire up Gnus on your home machine using the nnsoup backend as the native or secondary server.
  5. You read articles and mail and answer and followup to the things you want (see section SOUP Replies).
  6. You do the G s r command to pack these replies into a SOUP packet.
  7. You transfer this packet to the server.
  8. You use Gnus to mail this packet out with the G s s command.
  9. You then repeat until you die.

So you basically have a bipartite system--you use nnsoup for reading and Gnus for packing/sending these SOUP packets.

SOUP Commands

These are commands for creating and manipulating SOUP packets.

G s b
Pack all unread articles in the current group (gnus-group-brew-soup). This command understands the process/prefix convention.
G s w
Save all SOUP data files (gnus-soup-save-areas).
G s s
Send all replies from the replies packet (gnus-soup-send-replies).
G s p
Pack all files into a SOUP packet (gnus-soup-pack-packet).
G s r
Pack all replies into a replies packet (nnsoup-pack-replies).
O s
This summary-mode command adds the current article to a SOUP packet (gnus-soup-add-article). It understands the process/prefix convention (see section Process/Prefix).

There are a few variables to customize where Gnus will put all these thingies:

gnus-soup-directory
Directory where Gnus will save intermediate files while composing SOUP packets. The default is `~/SoupBrew/'.
gnus-soup-replies-directory
This is what Gnus will use as a temporary directory while sending our reply packets. `~/SoupBrew/SoupReplies/' is the default.
gnus-soup-prefix-file
Name of the file where Gnus stores the last used prefix. The default is `gnus-prefix'.
gnus-soup-packer
A format string command for packing a SOUP packet. The default is `tar cf - %s | gzip > $HOME/Soupout%d.tgz'.
gnus-soup-unpacker
Format string command for unpacking a SOUP packet. The default is `gunzip -c %s | tar xvf -'.
gnus-soup-packet-directory
Where Gnus will look for reply packets. The default is `~/'.
gnus-soup-packet-regexp
Regular expression matching SOUP reply packets in gnus-soup-packet-directory.

SOUP Groups

nnsoup is the backend for reading SOUP packets. It will read incoming packets, unpack them, and put them in a directory where you can read them at leisure.

These are the variables you can use to customize its behavior:

nnsoup-tmp-directory
When nnsoup unpacks a SOUP packet, it does it in this directory. (`/tmp/' by default.)
nnsoup-directory
nnsoup then moves each message and index file to this directory. The default is `~/SOUP/'.
nnsoup-replies-directory
All replies will be stored in this directory before being packed into a reply packet. The default is `~/SOUP/replies/"'.
nnsoup-replies-format-type
The SOUP format of the replies packets. The default is `?n' (rnews), and I don't think you should touch that variable. I probably shouldn't even have documented it. Drats! Too late!
nnsoup-replies-index-type
The index type of the replies packet. The default is `?n', which means "none". Don't fiddle with this one either!
nnsoup-active-file
Where nnsoup stores lots of information. This is not an "active file" in the nntp sense; it's an Emacs Lisp file. If you lose this file or mess it up in any way, you're dead. The default is `~/SOUP/active'.
nnsoup-packer
Format string command for packing a reply SOUP packet. The default is `tar cf - %s | gzip > $HOME/Soupin%d.tgz'.
nnsoup-unpacker
Format string command for unpacking incoming SOUP packets. The default is `gunzip -c %s | tar xvf -'.
nnsoup-packet-directory
Where nnsoup will look for incoming packets. The default is `~/'.
nnsoup-packet-regexp
Regular expression matching incoming SOUP packets. The default is `Soupout'.
nnsoup-always-save
If non-nil, save the replies buffer after each posted message.

SOUP Replies

Just using nnsoup won't mean that your postings and mailings end up in SOUP reply packets automagically. You have to work a bit more for that to happen.

The nnsoup-set-variables command will set the appropriate variables to ensure that all your followups and replies end up in the SOUP system.

In specific, this is what it does:

(setq message-send-news-function 'nnsoup-request-post)
(setq message-send-mail-function 'nnsoup-request-mail)

And that's it, really. If you only want news to go into the SOUP system you just use the first line. If you only want mail to be SOUPed you use the second.

Mail-To-News Gateways

If your local nntp server doesn't allow posting, for some reason or other, you can post using one of the numerous mail-to-news gateways. The nngateway backend provides the interface.

Note that you can't read anything from this backend--it can only be used to post with.

Server variables:

nngateway-address
This is the address of the mail-to-news gateway.
nngateway-header-transformation
News headers often have to be transformed in some odd way or other for the mail-to-news gateway to accept it. This variable says what transformation should be called, and defaults to nngateway-simple-header-transformation. The function is called narrowed to the headers to be transformed and with one parameter--the gateway address. This default function just inserts a new To header based on the Newsgroups header and the gateway address. For instance, an article with this Newsgroups header:
Newsgroups: alt.religion.emacs
will get this From header inserted:
To: alt-religion-emacs@GATEWAY
The following pre-defined functions exist:
nngateway-simple-header-transformation
Creates a To header that looks like newsgroup@nngateway-address.
nngateway-mail2news-header-transformation
Creates a To header that looks like nngateway-address. Here's an example:
(setq gnus-post-method
      '(nngateway "mail2news@replay.com"
                  (nngateway-header-transformation
                   nngateway-mail2news-header-transformation)))

So, to use this, simply say something like:

(setq gnus-post-method '(nngateway "GATEWAY.ADDRESS"))

IMAP

IMAP is a network protocol for reading mail (or news, or ...), think of it as a modernized NNTP. Connecting to a IMAP server is much similar to connecting to a news server, you just specify the network address of the server.

The following variables can be used to create a virtual nnimap server:

nnimap-address
The address of the remote IMAP server. Defaults to the virtual server name if not specified.
nnimap-server-port
Port on server to contact. Defaults to port 143, or 993 for SSL.
nnimap-list-pattern
String or list of strings of mailboxes to limit available groups to. This is used when the server has very many mailboxes and you're only interested in a few -- some servers export your home directory via IMAP, you'll probably want to limit the mailboxes to those in `~/Mail/*' then. The string can also be a cons of REFERENCE and the string as above, what REFERENCE is used for is server specific, but on the University of Washington server it's a directory that will be concatenated with the mailbox. Example:
("INBOX" "Mail/*" "alt.sex.*" ("~friend/Mail/" . "list/*"))
nnimap-stream
The type of stream used to connect to your server. By default, nnimap will use the most secure stream your server is capable of.
nnimap-authenticator
The authenticator used to connect to the server. By default, nnimap will use the most secure authenticator your server is capable of.
nnimap-expunge-on-close
Unlike Parmenides the IMAP designers has decided that things that doesn't exist actually does exist. More specifically, IMAP has this concept of marking articles Deleted which doesn't actually delete them, and this (marking them Deleted, that is) is what nnimap does when you delete a article in Gnus (with G DEL or similair). Since the articles aren't really removed when we mark them with the Deleted flag we'll need a way to actually delete them. Feel like running in circles yet? Traditionally, nnimap has removed all articles marked as Deleted when closing a mailbox but this is now configurable by this server variable. The possible options are:
always
The default behaviour, delete all articles marked as "Deleted" when closing a mailbox.
never
Never actually delete articles. Currently there is no way of showing the articles marked for deletion in nnimap, but other IMAP clients may allow you to do this. If you ever want to run the EXPUNGE command manually, See section Expunging mailboxes.
ask
When closing mailboxes, nnimap will ask if you wish to expunge deleted articles or not.

Splitting in IMAP

Splitting is something Gnus users has loved and used for years, and now the rest of the world is catching up. Yeah, dream on, not many IMAP server has server side splitting and those that have splitting seem to use some non-standard protocol. This means that IMAP support for Gnus has to do it's own splitting.

And it does.

Here are the variables of interest:

nnimap-split-crosspost
If non-nil, do crossposting if several split methods match the mail. If nil, the first match in nnimap-split-rule found will be used. Nnmail equivalent: nnmail-crosspost.
nnimap-split-inbox
A string or a list of strings that gives the name(s) of IMAP mailboxes to split from. Defaults to nil, which means that splitting is disabled!
(setq nnimap-split-inbox '("INBOX" ("~/friend/Mail" . "lists/*") "lists.imap"))
No nnmail equivalent.
nnimap-split-rule
New mail found in nnimap-split-inbox will be split according to this variable. This variable contains a list of lists, where the first element in the sublist gives the name of the IMAP mailbox to move articles matching the regexp in the second element in the sublist. Got that? Neither did I, we need examples.
(setq nnimap-split-rule
        '(("INBOX.nnimap"        "^Sender: owner-nnimap@vic20.globalcom.se")
          ("INBOX.junk"          "^Subject:.*MAKE MONEY")
          ("INBOX.private"       "")))
This will put all articles from the nnimap mailing list into mailbox INBOX.nnimap, all articles containing MAKE MONEY in the Subject: line into INBOX.spam and everything else in INBOX.private. The first string may contain `\\1' forms, like the ones used by replace-match to insert sub-expressions from the matched text. For instance:
("INBOX.lists.\\1"     "^Sender: owner-\\([a-z-]+\\)@")
The second element can also be a function. In that case, it will be called with the first element of the rule as the argument, in a buffer containing the headers of the article. It should return a non-nil value if it thinks that the mail belongs in that group. Nnmail users might recollect that the last regexp had to be empty to match all articles (like in the example above). This is not required in nnimap. Articles not matching any of the regexps will not be moved out of your inbox. (This might might affect performance if you keep lots of unread articles in your inbox, since the splitting code would go over them every time you fetch new mail.) These rules are processed from the beginning of the alist toward the end. The first rule to make a match will "win", unless you have crossposting enabled. In that case, all matching rules will "win". This variable can also have a function as its value, the function will be called with the headers narrowed and should return a group where it thinks the article should be splitted to. The splitting code tries to create mailboxes if it need too. Nnmail equivalent: nnmail-split-methods.
nnimap-split-fancy
It's possible to set nnimap-split-rule to nnmail-split-fancy if you want to use fancy splitting. See section Fancy Mail Splitting. However, to be able to have different fancy split rules for nnmail and nnimap backends you can set nnimap-split-rule to nnimap-split-fancy and define the nnimap specific fancy split rule in nnimap-split-fancy. Example:
(setq nnimap-split-rule 'nnimap-split-fancy
      nnimap-split-fancy ...)
Nnmail equivalent: nnmail-split-fancy.

Editing IMAP ACLs

ACL stands for Access Control List. ACLs are used in IMAP for limiting (or enabling) other users access to your mail boxes. Not all IMAP servers support this, this function will give an error if it doesn't.

To edit a ACL for a mailbox, type G l (gnus-group-edit-nnimap-acl) and you'll be presented with a ACL editing window with detailed instructions.

Some possible uses:

Expunging mailboxes

If you're using the never setting of nnimap-expunge-close, you may want the option of expunging all deleted articles in a mailbox manually. This is exactly what G x does.

Currently there is no way of showing deleted articles, you can just delete them.

Combined Groups

Gnus allows combining a mixture of all the other group types into bigger groups.

Virtual Groups

An nnvirtual group is really nothing more than a collection of other groups.

For instance, if you are tired of reading many small groups, you can put them all in one big group, and then grow tired of reading one big, unwieldy group. The joys of computing!

You specify nnvirtual as the method. The address should be a regexp to match component groups.

All marks in the virtual group will stick to the articles in the component groups. So if you tick an article in a virtual group, the article will also be ticked in the component group from whence it came. (And vice versa--marks from the component groups will also be shown in the virtual group.)

Here's an example nnvirtual method that collects all Andrea Dworkin newsgroups into one, big, happy newsgroup:

(nnvirtual "^alt\\.fan\\.andrea-dworkin$\\|^rec\\.dworkin.*")

The component groups can be native or foreign; everything should work smoothly, but if your computer explodes, it was probably my fault.

Collecting the same group from several servers might actually be a good idea if users have set the Distribution header to limit distribution. If you would like to read `soc.motss' both from a server in Japan and a server in Norway, you could use the following as the group regexp:

"^nntp\\+server\\.jp:soc\\.motss$\\|^nntp\\+server\\.no:soc\\.motss$"

(Remember, though, that if you're creating the group with G m, you shouldn't double the backslashes, and you should leave off the quote characters at the beginning and the end of the string.)

This should work kinda smoothly--all articles from both groups should end up in this one, and there should be no duplicates. Threading (and the rest) will still work as usual, but there might be problems with the sequence of articles. Sorting on date might be an option here (see section Selecting a Group).

One limitation, however--all groups included in a virtual group have to be alive (i.e., subscribed or unsubscribed). Killed or zombie groups can't be component groups for nnvirtual groups.

If the nnvirtual-always-rescan is non-nil, nnvirtual will always scan groups for unread articles when entering a virtual group. If this variable is nil (which is the default) and you read articles in a component group after the virtual group has been activated, the read articles from the component group will show up when you enter the virtual group. You'll also see this effect if you have two virtual groups that have a component group in common. If that's the case, you should set this variable to t. Or you can just tap M-g on the virtual group every time before you enter it--it'll have much the same effect.

nnvirtual can have both mail and news groups as component groups. When responding to articles in nnvirtual groups, nnvirtual has to ask the backend of the component group the article comes from whether it is a news or mail backend. However, when you do a ^, there is typically no sure way for the component backend to know this, and in that case nnvirtual tells Gnus that the article came from a not-news backend. (Just to be on the safe side.)

C-c C-t in the message buffer will insert the Newsgroups line from the article you respond to in these cases.

Kibozed Groups

Kibozing is defined by OED as "grepping through (parts of) the news feed". nnkiboze is a backend that will do this for you. Oh joy! Now you can grind any NNTP server down to a halt with useless requests! Oh happiness!

To create a kibozed group, use the G k command in the group buffer.

The address field of the nnkiboze method is, as with nnvirtual, a regexp to match groups to be "included" in the nnkiboze group. That's where most similarities between nnkiboze and nnvirtual end.

In addition to this regexp detailing component groups, an nnkiboze group must have a score file to say what articles are to be included in the group (see section Scoring).

You must run M-x nnkiboze-generate-groups after creating the nnkiboze groups you want to have. This command will take time. Lots of time. Oodles and oodles of time. Gnus has to fetch the headers from all the articles in all the component groups and run them through the scoring process to determine if there are any articles in the groups that are to be part of the nnkiboze groups.

Please limit the number of component groups by using restrictive regexps. Otherwise your sysadmin may become annoyed with you, and the NNTP site may throw you off and never let you back in again. Stranger things have happened.

nnkiboze component groups do not have to be alive--they can be dead, and they can be foreign. No restrictions.

The generation of an nnkiboze group means writing two files in nnkiboze-directory, which is `~/News/' by default. One contains the NOV header lines for all the articles in the group, and the other is an additional `.newsrc' file to store information on what groups have been searched through to find component articles.

Articles marked as read in the nnkiboze group will have their NOV lines removed from the NOV file.

Gnus Unplugged

In olden times (ca. February '88), people used to run their newsreaders on big machines with permanent connections to the net. News transport was dealt with by news servers, and all the newsreaders had to do was to read news. Believe it or not.

Nowadays most people read news and mail at home, and use some sort of modem to connect to the net. To avoid running up huge phone bills, it would be nice to have a way to slurp down all the news and mail, hang up the phone, read for several hours, and then upload any responses you have to make. And then you repeat the procedure.

Of course, you can use news servers for doing this as well. I've used inn together with slurp, pop and sendmail for some years, but doing that's a bore. Moving the news server functionality up to the newsreader makes sense if you're the only person reading news on a machine.

Using Gnus as an "offline" newsreader is quite simple.

That's it. Gnus is now an "offline" newsreader.

Of course, to use it as such, you have to learn a few new commands.

Agent Basics

First, let's get some terminology out of the way.

The Gnus Agent is said to be unplugged when you have severed the connection to the net (and notified the Agent that this is the case). When the connection to the net is up again (and Gnus knows this), the Agent is plugged.

The local machine is the one you're running on, and which isn't connected to the net continuously.

Downloading means fetching things from the net to your local machine. Uploading is doing the opposite.

Let's take a typical Gnus session using the Agent.

Here are some things you should do the first time (or so) that you use the Agent.

Agent Categories

One of the main reasons to integrate the news transport layer into the newsreader is to allow greater control over what articles to download. There's not much point in downloading huge amounts of articles, just to find out that you're not interested in reading any of them. It's better to be somewhat more conservative in choosing what to download, and then mark the articles for downloading manually if it should turn out that you're interested in the articles anyway.

The main way to control what is to be downloaded is to create a category and then assign some (or all) groups to this category. Groups that do not belong in any other category belong to the default category. Gnus has its own buffer for creating and managing categories.

Category Syntax

A category consists of two things.

  1. A predicate which (generally) gives a rough outline of which articles are eligible for downloading; and
  2. a score rule which (generally) gives you a finer granularity when deciding what articles to download. (Note that this download score is not necessarily related to normal scores.)

A predicate in its simplest form can be a single predicate such as true or false. These two will download every available article or nothing respectively. In the case of these two special predicates an additional score rule is superfluous.

Predicates of high or low download articles in respect of their scores in relationship to gnus-agent-high-score and gnus-agent-low-score as descibed below.

To gain even finer control of what is to be regarded eligible for download a predicate can consist of a number of predicates with logical operators sprinkled in between.

Perhaps some examples are in order.

Here's a simple predicate. (It's the default predicate, in fact, used for all groups that don't belong to any other category.)

short

Quite simple, eh? This predicate is true if and only if the article is short (for some value of "short").

Here's a more complex predicate:

(or high
    (and
     (not low)
     (not long)))

This means that an article should be downloaded if it has a high score, or if the score is not low and the article is not long. You get the drift.

The available logical operators are or, and and not. (If you prefer, you can use the more "C"-ish operators `|', & and ! instead.)

The following predicates are pre-defined, but if none of these fit what you want to do, you can write your own.

short
True iff the article is shorter than gnus-agent-short-article lines; default 100.
long
True iff the article is longer than gnus-agent-long-article lines; default 200.
low
True iff the article has a download score less than gnus-agent-low-score; default 0.
high
True iff the article has a download score greater than gnus-agent-high-score; default 0.
spam
True iff the Gnus Agent guesses that the article is spam. The heuristics may change over time, but at present it just computes a checksum and sees whether articles match.
true
Always true.
false
Always false.

If you want to create your own predicate function, here's what you have to know: The functions are called with no parameters, but the gnus-headers and gnus-score dynamic variables are bound to useful values.

For example, you could decide that you don't want to download articles that were posted more than a certain number of days ago (e.g. posted more than gnus-agent-expire-days ago) you might write a function something along the lines of the following:

(defun my-article-old-p ()
  "Say whether an article is old."
  (< (time-to-days (date-to-time (mail-header-date gnus-headers)))
     (- (time-to-days (current-time)) gnus-agent-expire-days)))

with the predicate then defined as:

(not my-article-old-p)

or you could append your predicate to the predefined gnus-category-predicate-alist in your `~/.gnus.el' or wherever. (Note: this would have to be at a point *after* gnus-agent has been loaded via (gnus-agentize))

(defvar  gnus-category-predicate-alist
  (append gnus-category-predicate-alist
	 '((old . my-article-old-p))))

and simply specify your predicate as:

(not old)

If/when using something like the above, be aware that there are many misconfigured systems/mailers out there and so an article's date is not always a reliable indication of when it was posted. Hell, some people just don't give a damm.

The above predicates apply to *all* the groups which belong to the category. However, if you wish to have a specific predicate for an individual group within a category, or you're just too lazy to set up a new category, you can enter a group's individual predicate in it's group parameters like so:

(agent-predicate . short)

This is the group parameter equivalent of the agent category default. Note that when specifying a single word predicate like this, the agent-predicate specification must be in dotted pair notation.

The equivalent of the longer example from above would be:

(agent-predicate or high (and (not low) (not long)))

The outer parenthesis required in the category specification are not entered here as, not being in dotted pair notation, the value of the predicate is assumed to be a list.

Now, the syntax of the download score is the same as the syntax of normal score files, except that all elements that require actually seeing the article itself are verboten. This means that only the following headers can be scored on: Subject, From, Date, Message-ID, References, Chars, Lines, and Xref.

As with predicates, the specification of the download score rule to use in respect of a group can be in either the category definition if it's to be applicable to all groups in therein, or a group's parameters if it's to be specific to that group.

In both of these places the download score rule can take one of three forms:

  1. Score rule This has the same syntax as a normal gnus score file except only a subset of scoring keywords are available as mentioned above. example:
  2. Agent score file These score files must *only* contain the permitted scoring keywords stated above. example:
  3. Use normal score files If you dont want to maintain two sets of scoring rules for a group, and your desired downloading criteria for a group are the same as your reading criteria then you can tell the agent to refer to your normal score files when deciding what to download. These directives in either the category definition or a group's parameters will cause the agent to read in all the applicable score files for a group, *filtering out* those those sections that do not relate to one of the permitted subset of scoring keywords.

The Category Buffer

You'd normally do all category maintenance from the category buffer. When you enter it for the first time (with the J c command from the group buffer), you'll only see the default category.

The following commands are available in this buffer:

q
Return to the group buffer (gnus-category-exit).
k
Kill the current category (gnus-category-kill).
c
Copy the current category (gnus-category-copy).
a
Add a new category (gnus-category-add).
p
Edit the predicate of the current category (gnus-category-edit-predicate).
g
Edit the list of groups belonging to the current category (gnus-category-edit-groups).
s
Edit the download score rule of the current category (gnus-category-edit-score).
l
List all the categories (gnus-category-list).

Category Variables

gnus-category-mode-hook
Hook run in category buffers.
gnus-category-line-format
Format of the lines in the category buffer (see section Formatting Variables). Valid elements are:
`c'
The name of the category.
`g'
The number of groups in the category.
gnus-category-mode-line-format
Format of the category mode line (see section Mode Line Formatting).
gnus-agent-short-article
Articles that have fewer lines than this are short. Default 100.
gnus-agent-long-article
Articles that have more lines than this are long. Default 200.
gnus-agent-low-score
Articles that have a score lower than this have a low score. Default 0.
gnus-agent-high-score
Articles that have a score higher than this have a high score. Default 0.

Agent Commands

All the Gnus Agent commands are on the J submap. The J j (gnus-agent-toggle-plugged command works in all modes, and toggles the plugged/unplugged state of the Gnus Agent.

You can run a complete batch fetch from the command line with the following incantation:

$ emacs -batch -l ~/.gnus.el -f gnus-agent-batch-fetch

Group Agent Commands

J u
Fetch all eligible articles in the current group (gnus-agent-fetch-groups).
J c
Enter the Agent category buffer (gnus-enter-category-buffer).
J s
Fetch all eligible articles in all groups (gnus-agent-fetch-session).
J S
Send all sendable messages in the draft group (gnus-group-send-drafts). See section Drafts.
J a
Add the current group to an Agent category (gnus-agent-add-group). This command understands the process/prefix convention (see section Process/Prefix).
J r
Remove the current group from its category, if any (gnus-agent-remove-group). This command understands the process/prefix convention (see section Process/Prefix).

Summary Agent Commands

J #
Mark the article for downloading (gnus-agent-mark-article).
J M-#
Remove the downloading mark from the article (gnus-agent-unmark-article).
@
Toggle whether to download the article (gnus-agent-toggle-mark).
J c
Mark all undownloaded articles as read (gnus-agent-catchup).

Server Agent Commands

J a
Add the current server to the list of servers covered by the Gnus Agent (gnus-agent-add-server).
J r
Remove the current server from the list of servers covered by the Gnus Agent (gnus-agent-remove-server).

Agent Expiry

nnagent doesn't handle expiry. Instead, there's a special gnus-agent-expire command that will expire all read articles that are older than gnus-agent-expire-days days. It can be run whenever you feel that you're running out of space. It's not particularly fast or efficient, and it's not a particularly good idea to interrupt it (with C-g or anything else) once you've started it.

if gnus-agent-expire-all is non-nil, this command will expire all articles--unread, read, ticked and dormant. If nil (which is the default), only read articles are eligible for expiry, and unread, ticked and dormant articles will be kept indefinitely.

Outgoing Messages

When Gnus is unplugged, all outgoing messages (both mail and news) are stored in the draft groups (see section Drafts). You can view them there after posting, and edit them at will.

When Gnus is plugged again, you can send the messages either from the draft group with the special commands available there, or you can use the J S command in the group buffer to send all the sendable messages in the draft group.

Agent Variables

gnus-agent-directory
Where the Gnus Agent will store its files. The default is `~/News/agent/'.
gnus-agent-handle-level
Groups on levels (see section Group Levels) higher than this variable will be ignored by the Agent. The default is gnus-level-subscribed, which means that only subscribed group will be considered by the Agent by default.
gnus-agent-plugged-hook
Hook run when connecting to the network.
gnus-agent-unplugged-hook
Hook run when disconnecting from the network.

Example Setup

If you don't want to read this manual, and you have a fairly standard setup, you may be able to use something like the following as your `.gnus.el' file to get started.

;;; Define how Gnus is to fetch news.  We do this over NNTP
;;; from your ISP's server.
(setq gnus-select-method '(nntp "news.your-isp.com"))

;;; Define how Gnus is to read your mail.  We read mail from
;;; your ISP's POP server.
(setq mail-sources '((pop :server "pop.your-isp.com")))

;;; Say how Gnus is to store the mail.  We use nnml groups.
(setq gnus-secondary-select-methods '((nnml "")))

;;; Make Gnus into an offline newsreader.
(gnus-agentize)

That should be it, basically. Put that in your `~/.gnus.el' file, edit to suit your needs, start up PPP (or whatever), and type M-x gnus.

If this is the first time you've run Gnus, you will be subscribed automatically to a few default newsgroups. You'll probably want to subscribe to more groups, and to do that, you have to query the NNTP server for a complete list of groups with the A A command. This usually takes quite a while, but you only have to do it once.

After reading and parsing a while, you'll be presented with a list of groups. Subscribe to the ones you want to read with the u command. l to make all the killed groups disappear after you've subscribe to all the groups you want to read. (A k will bring back all the killed groups.)

You can now read the groups at once, or you can download the articles with the J s command. And then read the rest of this manual to find out which of the other gazillion things you want to customize.

Batching Agents

Having the Gnus Agent fetch articles (and post whatever messages you've written) is quite easy once you've gotten things set up properly. The following shell script will do everything that is necessary:

#!/bin/sh
emacs -batch -l ~/.emacs -f gnus-agent-batch >/dev/null

Agent Caveats

The Gnus Agent doesn't seem to work like most other offline newsreaders. Here are some common questions that some imaginary people may ask:

If I read an article while plugged, do they get entered into the
Agent? No.
If I read an article while plugged, and the article already exists
in the Agent, will it get downloaded once more? Yes.

In short, when Gnus is unplugged, it only looks into the locally stored articles; when it's plugged, it only talks to your ISP.


Go to the first, previous, next, last section, table of contents.